Synthesizable Verilog Coding Style
(Credit to Justin Patel)
always @(*)block for combinational logic only. The reg types that you assign to in an
always @(*)block are simply wires driven by the output of combinational logic blocks (i.e. although declared as
regin Verilog, they are coerced to behave like wires and will be synthesized as wires.
Do not assign to registers (i.e.
assign var_register = value) in an
always @(posedge clk)block for sequential logic only when you mean to create an edge-triggered register.
The edge-triggered registers should be implemented using the
regtype and assignment to these registers should be performed in one sequential block in the datatype, i.e.
always @(posedge clk). Do not attempt to assign to an element that is not meant to be edge-triggered within an
always @(posedge clk)block. Instead, reg types that are meant to be coerced and synthesized as wires should be in an
If you assign to a reg in one always block, do not assign to it in another
alwaysblock. All reg types should be either combinational logic outputs, which must be produced from a single
always @(*)block, or edge-triggered registers, which should be assigned to in a single
always @(posedge clk)block.
always @(*)block, use ONLY blocking assignment (
always @(posedge clk)block, use ONLY non-blocking assignment (
Set a default value for each signal you assign to within an
always @(*)block. For every signal that is assigned to within an
always @(*)block, you should set a default value at the top of the block before any other logic. This is done to avoid implicit latching. You can sometimes get away without it (if the signal is assigned to in all possible branches), but doing it anyways ensures you won’t see certain errors. For example:
reg x; always @( * ) begin x = 0; // default value // other logic if (y) begin x = z; end end
Ensure that each register assigned to within an
always @(posedge clk)block is assigned to only once. This is different from an
always @(*)block, where you may (and probably should) assign to a variable multiple times during one execution of a block. To ensure this, it is recommended that the assignments to the same register are grouped to a if-else-if-…-else statement, for example:
reg[5:0] count; always @(posedge clk) begin if(count_clear) count <= 0; else if(count_inc) count <= count + 1; else if(count_dec) count <= count + 1; // maybe you don't need the else-statement // it is the same as having // else // count <= count;
For the testbench, for the wires that are connected to the output of the module-under-test, they should not be assigned an initial value.
// in Testbench module SimonDatapathTest; reg [3:0] pattern; // this should be reg, because it feeds the input wire pattern_legal; // this should be wire, and NOTE: do not assign any value here !!! ! SimonDatapath dpath ( .clk (clk), .pattern(pattern), // this is the input // ... .pattern_legal(pattern_legal), // this is the output // ... );