如何在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 为触发器放置一个时钟门,这将降低功耗。
我想在 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 为触发器放置一个时钟门,这将降低功耗。