首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

深入分析verilog阻塞和非阻塞赋值

深入分析verilog阻塞和非阻塞赋值

原文链接: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、上图   看波形

记录学习中的点点滴滴,让每一天过的更加有意义!
返回列表