Use the $clog2() system task instead of a BUS_SIZE parameter

Post Reply
russm
Posts: 18
Joined: May 5th, 2013, 2:32 am

Use the $clog2() system task instead of a BUS_SIZE parameter

Post by russm » July 17th, 2013, 8:50 pm

I just noticed the Mojo-Base serial modules take 2 parameters - one for the number of clocks per bit, and one to size the register that will count clocks per bit.

Code: Select all

module serial_tx #(
        parameter CLK_PER_BIT = 50,
        parameter CTR_SIZE = 6
        ) (
...
        );

...

reg [CTR_SIZE-1:0] ctr_d, ctr_q;
where CTR_SIZE is "enough bits to hold a count up to CLK_PER_BIT", or ceil(log2(CLK_PER_BIT)). The Verilog $clog2() system task calculates this value for you, so in the case of modules that take a count parameter that needs to fit into a bus/register you can just pass the count.

Code: Select all

module serial_tx #(
        parameter CLK_PER_BIT = 50
        ) (
...
        );

...

parameter CTR_SIZE = $clog2(CLK_PER_BIT);
reg [CTR_SIZE-1:0] ctr_d, ctr_q;
This removes the possibility of some particularly annoying bugs, where you eg. increase the count maximum but forget to widen the bus to suit.

MacAttak
Posts: 72
Joined: April 28th, 2013, 1:27 am
Location: Atlanta, GA
Contact:

Re: Use the $clog2() system task instead of a BUS_SIZE param

Post by MacAttak » July 28th, 2013, 5:28 pm

I took it one step further than this, and made the following changes to avr_interface module instead (left serial_tx and serial_rx alone)

Added two parameters to avr_interface:

Code: Select all

module avr_interface #(
   parameter MOJO_CLK_RATE = 50000000,
   parameter SERIAL_BAUD_RATE = 19200
   )(
   input clk,
   input rst,
   input cclk,
......
Added two defines in the body of the module:

Code: Select all

......
`define CLK_PER_BIT $rtoi($ceil(MOJO_CLK_RATE / SERIAL_BAUD_RATE))
`define CTR_SIZE $clog2(`CLK_PER_BIT)
......
Changed the instances for serial_rx and serial_tx:

Code: Select all

......
serial_rx #(.CLK_PER_BIT(`CLK_PER_BIT), .CTR_SIZE(`CTR_SIZE)) serial_rx (
	.clk(clk),
	.rst(n_rdy),
	.rx(rx),
	.data(rx_data),
	.new_data(new_rx_data)
);

serial_tx #(.CLK_PER_BIT(`CLK_PER_BIT), .CTR_SIZE(`CTR_SIZE)) serial_tx (
	.clk(clk),
	.rst(n_rdy),
	.tx(tx_m),
	.block(tx_block),
	.busy(tx_busy),
	.data(tx_data),
	.new_data(new_tx_data)
);
......

This makes it MUCH easier to deal with changes to both the Mojo clock rate as well as the desired serial baud rate. When avr_Interface is instantiated its very easy to tweak the speeds without doing any math:

Code: Select all

......
avr_interface #(.MOJO_CLK_RATE(50000000), .SERIAL_BAUD_RATE(19200)) avr_interface (
    .clk(clk),
    .rst(rst),
......
It appears to synthesize fine, and sims fine too.

Post Reply