原文链接:http://blog.csdn.net/ywhfdl/article/details/7495615
1、学verilog 一个月了,在开发板上面写了很多代码,但是始终对一些问题理解的不够透彻,这里我们来写几个例子仿真出阻塞和非阻塞的区别,我们先上代码
module LED
(
CLK, RSTn,
scan,
flag ,
c,
,one,two,three,four
);
input CLK;
input RSTn;
input scan;
output flag,c;
output [3:0] one,two,three,four;
/***********************************************************/
reg F1,F2;
reg a,b;
reg [3:0] one,two,three,four;
/********************信号传递之间的非阻塞赋值***************************************/
always @ ( posedge CLK or negedge RSTn ) //
if( !RSTn )
begin
F1 <= 1'b1;
F2 <= 1'b1;
end
else
begin
F1 <= scan;
F2 <= F1;
end
/*******************信号传递之间的阻塞赋值****************************************/
always @ ( posedge CLK or negedge RSTn ) //
if( !RSTn )
begin
a = 1'b1;
b = 1'b1;
end
else
begin
a = scan;
b = a;
end
/******************数据加 非阻塞赋值 先判断后计数*****************************************/
always @ ( posedge CLK or negedge RSTn ) //one <=
if( !RSTn )
begin
one<=0;
end
else
begin
if(one==14)
one<=0;
else
one<=one+1;
end
/***************数据加 非阻塞赋值 先计数后判断********************************************/
always @ ( posedge CLK or negedge RSTn ) // two<=
if( !RSTn )
begin
two<=0;
end
else
begin
two<=two+1;
if(two==14)
two<=0;
end
/**************数据加 阻塞赋值 先判断后计数*********************************************/
always @ ( posedge CLK or negedge RSTn ) //three =
if( !RSTn )
begin
three=0;
end
else
begin
if(three==14)
three=0;
else
three=three+1;
end
/*************数据加 阻塞赋值 先计数后判断**********************************************/
always @ ( posedge CLK or negedge RSTn ) //four =
if( !RSTn )
begin
four=0;
end
else
begin
four=four+1;
if(four==14)
four=0;
end
/****************信号之间传递***********************/
assign flag = F2 & !F1;
assign c = b & !a;
/***************************************/
endmodule
2、我使用modesim 仿真,下面为我的 test bench
`timescale 1 ps/ 1 ps
module LED_vlg_tst();
// constants
// general purpose registers
reg eachvec;
// test vector input registers
reg CLK;
reg RSTn;
reg scan;
// wires
wire c;
wire flag;
wire [3:0] four;
wire [3:0] one;
wire [3:0] three;
wire [3:0] two;
// assign statements (if any)
LED i1 (
// port map - connection between master ports and signals/registers
.CLK(CLK),
.RSTn(RSTn),
.c(c),
.flag(flag),
.four(four),
.one(one),
.scan(scan),
.three(three),
.two(two)
);
/*
initial
begin
// code that executes only once
// insert code here --> begin
// --> end
$display("Running testbench");
end
always
// optional sensitivity list
// @(event1 or event2 or .... eventn)
begin
// code executes for every event on sensitivity list
// insert code here --> begin
@eachvec;
// --> end
end
endmodule
*/
initial begin
CLK = 0;
forever
#10 CLK = ~CLK;
end
initial begin
scan = 0;
forever
#100 scan = ~scan;
end
initial begin
RSTn = 0;
#1000 RSTn = 1;
#1000;
#1000;
#1000;
#1000;
#1000;
#1000;
#1000;
#1000;
$stop;
end
endmodule
主要就是初始化一个CLK 和scan的信号,然后就是初始化一下复位,最后就是设置仿真时间,这样modesim 就不会一直处于仿真状态,消耗资源,也可以方便仿真。
其中quartus 与modesim 互相调用调试,可以关注我的博客,这里我就不具体讲解了!
3、modesim 波形图

大家注意到红线框内的数据变化,就能很清楚的理解 阻塞与非阻塞了!
微观分析 阻塞与非阻塞
1、上代码,具体观察,a,b,c与F1,F2,flage 的变化
module LED
(
CLK, RSTn,
scan,
flag ,
a,b,c,F1,F2,
);
input CLK;
input RSTn;
input scan;
output flag,a,b,c;
output F1,F2;
/***********************************************************/
reg F1,F2;
reg a,b;
/***********************************************************/
always @ ( posedge CLK or negedge RSTn ) //
if( !RSTn )
begin
F1 <= 1'b1;
F2 <= 1'b1;
end
else
begin
F1 <= scan;
F2 <= F1;
end
/***********************************************************/
always @ ( posedge CLK or negedge RSTn ) //
if( !RSTn )
begin
a = 1'b1;
b = 1'b1;
end
else
begin
a = scan;
b = a;
end
/***********************************************************/
assign flag = F2 & !F1;
assign c = b & !a;
/***************************************/
endmodule
代码涵义就不讲解了
2、test bench 代码,与上面相同,这里不重复了
3、上图 看波形
 |