仿真子模塊時start信號的激勵別寫錯啦!
阿新 • • 發佈:2017-12-31
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=3‘b010, St2=3‘b100, Stx=3‘bxxx; 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; endalways @(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==3‘d7) 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<=1‘b0; count<=3‘b0; end else case(next_state) St0: begin count_done<=1‘b0; count<=3‘b0; end St1: begin count<=count+1‘b1; end St2: begin count_done<=1‘b1; end default: begin count_done<=1‘b0; count<=3‘b0; 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<=1‘b0; 14 else if(start) counter_start<=1‘b1; 15 else counter_start<=1‘b0; 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信號的激勵別寫錯啦!