如何在verilog中拆分顺序和组合

How to split the sequential and the combinational in verilog

我想在 verilog 中制作一个计数器,我想知道如何将顺序部分与组合部分分开。

我有这个模块,很好用,但不知道怎么拆分?

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

一种方法是使用阻塞赋值 (=) 为组合部分制作 always @(*) 块,并使用非阻塞赋值 (<=) 到简​​单的 reg.

组合中的阻塞分配 (=) 提供更快的模拟和可预测的行为,即使使用显式敏感列表行 @(rst_n_i or enable_i or ...) 而不是 @(*) 也是如此。顺序逻辑中的非阻塞赋值 (<=) 给出了预期的触发器行为,其中下一个值取决于前一个值。

代码将如下所示:

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

为什么要拆分组合逻辑和时序逻辑。 您编写的代码是电源优化的良好风格。 使用您的代码风格,该工具可以理解触发器值将在 enable_i 上发生变化,因此该工具足够智能,可以使用 enable_i 为触发器放置一个时钟门,这将降低功耗。