1. 程式人生 > >仿真子模塊時start信號的激勵別寫錯啦!

仿真子模塊時start信號的激勵別寫錯啦!

rst 驗證 color 9.png inpu blog 簡單 count stat

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=3
b001, 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信號的激勵別寫錯啦!