理论学习
阻塞赋值 用 = 表示 ,这种对应的电路结构常常与触发器没有关系,只与输入电平的变化有关系。可以将阻塞赋值的操作看作只有一个步骤的操作,即将计算赋值符号的右边赋值给左边,在未执行完之前,不允许其他verilog语句执行。
非阻塞赋值 用 <= 表示,这种对应的电路结构常常与触发沿有关系,只有在触发沿才能执行。非阻塞逻辑开始时 先计算式子右边的语句,赋值操作结束时才更行式子左边的语句,可以认为需要两个步骤来完成赋值。非阻塞赋值执行的时候,其他verilog语句都能同时计算。
阻塞赋值
module blocking
(input wire sys_clk ,input wire sus_rst_n ,input wire [1:0] in ,output reg [1:0] out
);reg [1:0] in_reg ;//给out延迟 1 clkalways(posedge sys_clk or negedge sys_rst_n )beginif(sys_rst_n == 1'b0)beginin_reg = 2'b0 ;out = 2'b0 ;endelsebeginin_reg = in ;out = in_reg ;endendendmodule
阻塞赋值对应的tb
`timescale 1ns/1nsmodule tb_blocking();reg sys_clk ;reg sys_rst_n ;reg [1:0] in ;wire [1:0] out ;initialbeginsys_clk = 1'b0 ;sys_rst_n <= 1'b0 ;int <= 2'b0 ;#20 ;sys_rst_n <= 1'b1 ;endalways #10 sys_clk <= ~sys_clk ;always #20 in <= {$random}%4 ;blocking blocking_inst(.sys_clk (sys_clk) ,.sys_rst_n (sys_rst_n) ,.in (in) ,.out (out));endmodule
非阻塞赋值,可以看到这样子有两组寄存器。
module non_blocking
(input wire sys_clk ,input wire sys_rst_n ,input wire [1:0] in ,output reg [1:0] out
);reg [1:0] in_reg ;always@(posedge sys_clk or negedge sys_rst_n)beginif(sys_rst_n == 1'b0)beginin_reg <= 2'b0 ;out <= 2'b0 ;endelsebeginin_reg <= in ;out <= in_reg ;endendendmodule
非阻塞赋值对应的tb,结果发现,in和in_reg有一个clk延时,in_reg和out有一个延时,也就是in和out有两个延时。
module tb_non_blocking();reg sys_clk ;reg sys_rst_n ;reg [1:0] in ;wire [1:0] out ;initialbeginsys_clk = 1'b1 ;sys_rst_n <= 1'b1 ;in <= 2'b0 ;#20 ;sys_rst_n <= 1'b1 ;endalways #10 sys_clk = ~sys_clk ;always #20 in <= {$random}%4 ;non_block non_block_inst(.sys_clk (sys_clk) ,.sys_rst_n (sys_rst_n) ,.in (in) ,.out (out));endmodule