zhliao2

风雨兼程,一路向北-------fpga (Keep a quiet heart study)
【笔记】精密计数

参考<<verilog那些事儿-时序篇>>

module counter_module 
(
    input CLK,
    input RSTn,
     
     output _1US,
     output _3US,
     output _is1US,
     output _is3US,
     output [4:0]C1,
     output [5:0]C2
);

    /*******************************/
     
     parameter T1US = 5'd20;
     
     /*******************************/

    reg [4:0]Count_1US;
     reg is1US;
     
    always @ ( posedge CLK or negedge RSTn )
        if( !RSTn )
              begin Count_1US <= 5'd0; is1US <= 1'b0; end
          else if( Count_1US == T1US )
              begin Count_1US <= 5'd0; is1US <= 1'b1; end
          else 
              begin Count_1US <= Count_1US + 1'b1; is1US = 1'b0; end
                
     /*******************************/
     
     parameter T3US = 6'd60;
     
     /*******************************/
                
    reg [5:0]Count_3US;
     reg is3US;
                
    always @ ( posedge CLK or negedge RSTn )
        if( !RSTn )
              begin Count_3US <= 6'd0; is3US <= 1'b0; end
          else if( Count_3US == T3US )
              begin Count_3US <= 6'd0; is3US <= 1'b1; end
          else 
              begin Count_3US <= Count_3US + 1'b1; is3US <= 1'b0; end
                
    /*******************************/
                          
    assign _1US = ( Count_1US == T1US ) ? 1'b1 : 1'b0;
   assign _3US = ( Count_3US == T3US ) ? 1'b1 : 1'b0;
    assign _is1US = is1US;
    assign _is3US = is3US;
    assign C1 = Count_1US;
    assign C2 = Count_3US;

   /*******************************/
    
endmodule

 

仿真源代码

`timescale 1 ns/ 1 ps
module counter_module_simulation();

    reg CLK;
    reg RSTn;
                                                                
    wire _1US;
    wire _3US;
    
    wire _is1US;
    wire _is3US;
    
    wire [4:0]C1;
    wire [5:0]C2;

   
    /************************/
                         
    counter_module i1 
    (  
        .CLK(CLK),
        .RSTn(RSTn),
        ._1US(_1US),
        ._3US(_3US),
        ._is1US( _is1US ),
        ._is3US( _is3US ),
        .C1( C1 ),
        .C2( C2 )
    );
    
    /************************/
    
    initial                                                
    begin                                                  
        RSTn = 0; #1000; RSTn = 1;
       CLK = 0; forever #25 CLK = ~CLK;         
    end                                 
 
   /************************/ 
                                                
                                               
endmodule

 

在quartusII里面setting -- simulation

 在Test Benches里面添加所写的仿真代码,设置完成后点击ok

 

 

仿真结果

可以发现_1US用了0.95us,is_1US用了1us

这里强调的是 

1:assign _1US = ( Count_1US == T1US ) ? 1'b1 : 1'b0;  

 

2:  else if( Count_1US == T1US )    //T1US定义的常量是20哦,why?1us / 50ns = 20 (这里50位一个时钟周期)
        begin Count_1US <= 5'd0; is1US <= 1'b1; end

  assign _is1US = is1US;   //上面的is1US一变化这里的_is1US就马上就变化了,实际上就是起到连线的作用而已

不一样的,两者相差一个时钟,切记切记。

 

 

下面的例子理解到模块的沟通要用到一个时钟的

 

modulecounter
(
......
output_1US, // 由组合逻辑驱动
output_is1US // 有寄存器驱动
);
parameterT1US=5'd20; // 时钟频率20Mhz
......

assign_1US=(Count_US==T1US) ?1'b1:1'b0;
assign_is1US=is1US;
endmodule

 

moduleled
(
......
input_1US,
input_is1US
);
case(i)
0,1,2,3,4,5,6,7:
if(_1US)beginLED_A<=(4'h01<<i);i<=i+1'b1;end
......
case(j)
0,1,2,3,4,5,6,7:
if(_is1US)beginLED_B<=(4'h01<<j );j<=j+1'b1;end
......
endmodule

如果根据“模块之间沟通”的规则,由寄存器驱动的1us定时信号_is1US,是满1us
之后就产生定时信号,然而模块的沟通需要至少一个时钟,所以LED_B的流水灯效果,
实际上是1.00us+0.05us。反之,由组合逻辑驱动的1us定时信号_1US,在满1us前
一个时钟就产生定时信号了,然而模块的沟通至少需要一个时钟,所以LED_A的流水
灯效果是0.95us+0.05us,亦即准1us。

 

posted on 2012-12-23 14:53  zhliao  阅读(297)  评论(0编辑  收藏  举报