Verilog 的阻塞赋值与非阻塞赋值(一)
- 文件代码
module block_nonblock(Clk,Rst_n,a,b,c,out);
input Clk;
input Rst_n;
input a,b,c;
output reg [1:0]out;
//因为out 是在always@ 中进行赋值的,所以要将out定义为reg类型
// out = a + b + c; //把该算式分解为两步
// d = a + b;
// out = d + c;
reg [1:0]d;
always @(posedge Clk or negedge Rst_n) begin
if(!Rst_n)
out = 2'b0;
else begin
out = d + c;
d = a + b;
end
end
endmodule
阻塞赋值:
- 第一种情况:
always @(posedge Clk or negedge Rst_n) begin
if(!Rst_n)
out = 2'b0;
else begin
d = a + b;
out = d + c;
end
end
- 第二种情况
always @(posedge Clk or negedge Rst_n) begin
if(!Rst_n)
out = 2'b0;
else begin
out = d + c;
d = a + b;
end
end
由以上可知,阻塞赋值的程序执行情况,与编写顺序是密切相关的;
即阻塞赋值是顺序执行的;
非阻塞赋值:
- 第一种情况:
always @(posedge Clk or negedge Rst_n) begin
if(!Rst_n)
out = 2'b0;
else begin
d <= a + b;
out <= d + c;
end
end
- 第二种情况
always @(posedge Clk or negedge Rst_n) begin
if(!Rst_n)
out = 2'b0;
else begin
out <= d + c;
d <= a + b;
end
end
- 编写"testbench"的一个小技巧
// d <=#`tp a + b;
//程序中的这种写法,在testbench写的比较好的书里面
//都会看到一个实际的设计逻辑里面有"#`tp",这句话是不会被综合为我们的实际电路的
//也就是说,在我们生成最终电路的时候,这句话"#`tp" 是被忽略掉了的,但是在仿真的
//时候这句话很有用,在仿真的时候这句话("#`tp")能够直接模拟电路延迟;
//即通过这样一个延迟,能够更加方便我们在看波形的时候理解波形
//但这种写法不被国内一些保守的企业所接受
`timescale 1ns/1ns
`define tp 1
module block_nonblock(Clk,Rst_n,a,b,c,out);
input Clk;
input Rst_n;
input a,b,c;
output reg [1:0]out;
//因为out 是在always@ 中进行赋值的,所以要将out定义为reg类型
// out = a + b + c; //把该算式分解为两步
// d = a + b;
// out = d + c;
reg [1:0]d;
always @(posedge Clk or negedge Rst_n) begin
if(!Rst_n)
out <=#`tp 2'b0;
else begin
d <=#`tp a + b;
out <=#`tp d + c;
end
end
endmodule