/////////////////////////////////////////////////////////////////////// // // // Description: General Binary Rate Multiplier (BRM) Circuit // // // /////////////////////////////////////////////////////////////////////// // // // Overview: // // // This is a behavioral model of a Binary Rate Multiplier circuit. // // It is fully synchronous, synthesizable, and parameterizable. // // // // The circuit consists of two, dual modulus counters. One counter // // is used to divide the clock by the two different divisors. The // // other counter is used to keep track of how many times each of the // // two dividers are enabled. // // // The average frequency of the BRM output is given by: // // Fclkout = Fclkin * (rep1 + rep2)/(rep1*div1 + rep2*div2) // // Note that the instantaneous frequency is not the same as the // // average. // // /////////////////////////////////////////////////////////////////////// // // Ports: // // clkin: Clock input to be divided down. // rsb: Reset, active Low input. // clkout: Binary Rate Multiplied clock signal output. // module brm (clkin, rstb, clkout); // // Change parameters below to yield the desired BRM. // // You can do this from the module which instanciates the BRM by: // inst_brm #(div1, rep1, div2, rep2) brm; // // The divide ratio is equal to: // (rep1 + rep2)/(rep1*div1 + rep2*div2) // // The default parameters give a 7/18 divide ratio. // parameter div1 = 2; // Divider one parameter rep1 = 3; // Number of times to repeat divider 1 parameter div2 = 3; // Divider two parameter rep2 = 4; // Number of times to repeat divider 2 // // These parameters must be chosen so that synthesis will create a // large enough counter. The mbit parameter is chosen so that two raised // to the power of mbit is equal to or greater than the max of (div1, div2). // The sbit parameter is chosen so that two raised to the power // of sbit is equal to or greater than the max of (div1*rep1, div2*rep2). // parameter mbit = 2; // Number of bits needed for main counter parameter sbit = 4; // Number of bits needed for state counter input clkin, rstb; output clkout; reg [(mbit - 1):0] mcnt; reg [(sbit - 1):0] scnt; reg clkout, state, rst_mcnt, rst_scnt; wire rst; assign rst = ~rstb; // // Main Counter. // always @(posedge clkin or posedge rst) if (rst == 1'b1) mcnt = 0; else if (rst_mcnt == 1'b1) mcnt = 0; else mcnt = mcnt + 1; // // Main Counter reset generation. // This is used to switch the modulus of the Main Counter. // always @(mcnt) case (state) 1'b0 : rst_mcnt = (mcnt == (div1 - 1)) ? 1'b1 : 1'b0; 1'b1 : rst_mcnt = (mcnt == (div2 - 1)) ? 1'b1 : 1'b0; endcase // // Output Register // always @(posedge clkin or posedge rst) if (rst == 1'b1) clkout = 1'b0; else clkout = rst_mcnt; // // State Counter and State Flag generation. // When State Flag is Low, the BRM is using the first divide ratio, // when State Flag is High, the BRM is using the second divide ratio. // always @(posedge clkin or posedge rst) if (rst == 1'b1) begin scnt = 0; state = 1'b0; end else if (rst_scnt == 1'b1) begin scnt = 0; state = ~state; end else scnt = scnt + 1; // // State Counter reset generation. // This is used to switch the modulus of the State Counter. // always @(scnt) case (state) 1'b0 : rst_scnt = (scnt == ((div1 * rep1) - 1)) ? 1'b1 : 1'b0; 1'b1 : rst_scnt = (scnt == ((div2 * rep2) - 1)) ? 1'b1 : 1'b0; endcase endmodule