一共6种组合:
verilog有3种类型的赋值: 阻塞赋值、非阻塞赋值和连续赋值。
延时(#1)写的位置有2种:2*3=6
当延时(#1)写在整个表达式最前面时,
三种类型的赋值,延时结果一致是:等待_忽略中间变化再计算
当延时(= #1)写在等于号(=)后面时:
1.连续赋值语法错误排除。
2.阻塞赋值是:先计算后延时再赋值
3.非阻塞赋值是:直接跟随
reg A,B;
wire C1,C2;
reg C3,C4,C5,C6;
initial begin
A = 0; B = 0;
C3 = 0; C4 = 0; C5 = 0; C6 = 0;
#100;
#6 A = 1;
#2 A = 0;
#1 A = 1;
#1 A = 0;
#2 A = 1;
#6 A = 0;
end
// 先等待后计算
// 先计算后等待
// 忽略等待内的变化
// 不忽略等待内的变化
// 三种写法1个意思。
//1.先等待5周期,后计算。
// 1.1等待中的变化忽略。再取延时5周期后此时的A\B
assign #5 C1 = A +B;
always @(*) begin
#5 C3 = A +B;
end
always @(*) begin
#5 C5 <= A +B;
end
// 1.2等待中的变化不忽略。
assign C2 = #5 A +B;//非法 涉及存储
//2.后等待,先计算A+B
// 2.1等待中的变化忽略。
always @(*) begin
C4 = #5 A +B;
end
// 2.2等待中的变化不忽略。
// 时刻跟踪原始信号,延时固定的值。是我们理想中的线路延时。不会过滤。
always @(*) begin
C6 <= #5 A +B;
end
错误写法
//错误写法,编译不会报错,运行会卡死。因为一直在0ns处迭代。
// always clk90 <=#200 clk0;
// always clk180 <=#400 clk0;
// always clk270 <=#600 clk0;
//错误写法
// always(*) clk90 <=#200 clk0;
// always(*) clk180 <=#400 clk0;
// always(*) clk270 <=#600 clk0;
//正确写法
always@(*) clk90 <=#200 clk0;
always@(*) clk180 <=#400 clk0;
always@(*) clk270 <=#600 clk0;
参考
https://blog.csdn.net/qq_43214511/article/details/111874481
当延时用错了会报下面错误:
Error (suppressible): (vsim-3601) Iteration limit reached at time 0 ns.