flama
flama

Reputation: 73

How to split the sequential and the combinational in verilog

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

Answers (2)

user2209660
user2209660

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

Morten Zilmer
Morten Zilmer

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

Related Questions