码迷,mamicode.com
首页 > 其他好文 > 详细

仿真子模块时start信号的激励别写错啦!

时间:2017-12-31 10:48:22      阅读:136      评论:0      收藏:0      [点我收藏+]

标签:.com   问题   gpo   http   子模块   star   开始   验证   科学   

1.笔者最近在仿真验证Verilog模块时遇到了有关start激励的一个困惑。先说说这个困惑吧,请看下面一个简单的counter模块:

 

`timescale 1ns / 1ps

module counter(
    clk,rst_n,
    counter_start,
    count,count_done
    );
     input clk,rst_n;
     input counter_start;
     output reg [2:0] count;
     output reg count_done;
     
     parameter St0=3b001,
                  St1=3b010,
                  St2=3b100,
                  Stx=3bxxx;
        
     reg [2:0] current_state;
     reg [2:0] next_state;
     always @(posedge clk or negedge rst_n)
     begin
        if(!rst_n) current_state<=St0;
        else current_state<=next_state;
     end
     
     always @(counter_start or current_state or count)
     begin
     next_state=Stx;
     case(current_state)
     St0:
     begin
     if(counter_start) next_state=St1;
     else next_state=St0;
     end
     
     St1:
     begin
     if(count==3d7) next_state=St2;
     else next_state=St1;
     end
     
     St2:
     begin
     next_state=St0;
     end
     
     default: next_state=St0;
     endcase
     end
     
     always @(posedge clk or negedge rst_n)
     begin
     if(!rst_n)
     begin
        count_done<=1b0;
        count<=3b0;
     end
     else 
     case(next_state)
     St0:
     begin
        count_done<=1b0;
        count<=3b0;     
     end
     
     St1:
     begin
        count<=count+1b1;
     end
     
     St2:
     begin
        count_done<=1b1;    
     end
     
     default:
     begin
        count_done<=1b0;
        count<=3b0; 
     end
     endcase
     end
     


endmodule

 

这是用三段式状态机编写的8位计数器,然后我在写tb给counter_start信号时采用了两种方式:a、在clk上升沿时给;b、在clk上升沿后一瞬间给。那么这两种写法会有什么不同呢?请看如下波形:

a、在clk上升沿时给

技术分享图片

b、在clk上升沿后一瞬间给

技术分享图片

想必看官也早已猜到,这两种给法产生的结果完全是不用的:a中counter_start跳边到1时,count马上开始了计数;而b中counter_start跳边到1时,count是在下一个clk上升沿才开始计数的。千万别小看这么点不同,数字电路中的节拍可是至关重要的!那么问题来了,到底哪种给法会更加科学合理呢?

2.为了说明这个问题,我又给这个计数器添加了一个控制模块counter_control,让它产生counter_start信号:

 1 `timescale 1ns / 1ps
 2 
 3 module counter_control(
 4     clk,rst_n,
 5     start,counter_start
 6     );
 7      
 8      input clk,rst_n;
 9      input start;
10      output reg counter_start;
11      
12      always @(posedge clk or negedge rst_n)
13      if(!rst_n) counter_start<=1b0;
14      else if(start) counter_start<=1b1;
15      else counter_start<=1b0;
16     
17 endmodule

 

控制模块相当简单,就是当外围start信号到来时,让counter_start有效。

下面将两个模块组成顶层:

 1 `timescale 1ns / 1ps
 2 
 3 module counter_top(
 4     clk,rst_n,
 5     start,counter_start,count,count_done
 6     );
 7      input clk,rst_n;
 8      input start;
 9      output [2:0] count;
10      output count_done,counter_start;
11      
12      wire counter_start;
13      counter_control U1(
14         .clk(clk),
15         .rst_n(rst_n),
16         .start(start),
17         .counter_start(counter_start)
18     );
19      
20       counter U2(
21         .clk(clk),
22         .rst_n(rst_n),
23         .counter_start(counter_start),
24         .count(count),
25         .count_done(count_done)
26     );
27 
28 
29 endmodule

 

start信号由于是外围用户给的,因此tb中它的使能应该是任意的,下面请看该顶层模块的仿真波形:

技术分享图片

 

仿真子模块时start信号的激励别写错啦!

标签:.com   问题   gpo   http   子模块   star   开始   验证   科学   

原文地址:https://www.cnblogs.com/wt-seu/p/8157132.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!