Reputation: 73
I am trying to make a counter in verilog and I want to know how to split the sequential part from the combinational one.
I have this module, it works fine, but I don't know how to split it?
module counter4bits(
input clk_i,
input rst_n_i,
input enable_i,
input up_down_i,
output reg[3:0] val_o);
always@(posedge clk_i) begin
if (rst_n_i == 1)
val_o <= 0;
else if(enable_i == 1)
val_o <= val_o + 1;
end
endmodule
Upvotes: 0
Views: 1492
Reputation: 11
Why do you want to split the combinational and sequential logic. The code you have written is good style for the power optimization. With your style of code the tool can understand the flip flop value will change on enable_i hence the tools are intelligent enough to put a clock gate for flop using enable_i which will reduce the power.
Upvotes: 0
Reputation: 15924
One way is to make always @(*)
blocks for the combinational parts using blocking assignments (=
), and make always @(posedge clk_i)
blocks for the sequential parts using non-blocking assignments (<=
) to simple reg.
The blocking assignment (=
) in combinational gives faster simulation and predictable behavior even if explicit sensitivity lists line @(rst_n_i or enable_i or ...)
are used instead of @(*)
. The non-blocking assignment (<=
) in sequential logic gives the expected flip-flop behavior where the next value depends on the previous value.
The code will then look like:
module counter4bits(
... input/output with no change
reg [3:0] val_nxt; // Not flip-flop but used in always @(*) thus reg
always @(*) begin
if (rst_n_i == 1)
val_nxt = 0;
else if(enable_i == 1)
val_nxt = val_o + 1;
end
always @(posedge clk_i)
val_o <= val_nxt;
endmodule
Upvotes: 5