Verilog的序列信號檢測器實現及其testbench仿真


  終於邁向了testbench的學習,第一個就拿簡單的練練手,沒想這都遇到了好幾個問題,在一番折騰下,終於把問題調試完畢,趁熱乎過來寫下本人的第一篇博客。。序列信號檢測器對串行輸出進行檢測,如果檢測到連續的1001,則輸出1,否則輸出0。

  程序采用兩段式狀態機寫法。兩段式狀態機即:用兩個always模塊來描述狀態機,其中一個always模塊采用同步時序描述狀態轉移,另外一個模塊采用組合邏輯判斷狀態轉移條件,描述狀態轉移規律以及輸出。狀態機編碼方式采用獨熱碼方式,《Verilog數字系統設計與FPGA應用》【趙倩、林麗萍】一書中說:“CPLD器件更多地提供組合邏輯資源,而FPGA器件更多的提供觸發器資源,所以對於CPLD的數字系統設計多使用格雷碼編碼,而基於FPGA的數字系統設計多使用獨熱碼編碼。”代碼如下:

  Detected_1001.v

 1 module Detected_1001(Data_in,Clock,Reset,Detected);
 2 
 3 input Data_in,Clock,Reset;
 4 output Detected;
 5 reg Detected;
 6 reg [4:0]state;
 7 parameter s0=5'b10000,
 8           s1=5'b01000,
 9           s2=5'b00100,
10           s3=5'b00010,
11           s4=5'b00001;
12 always@(state)
13 begin
14 case(state)
15 s0:
16   Detected=1'b0;
17 s1:
18   Detected=1'b0;
19 s2:
20   Detected=1'b0;
21 s3:
22   Detected=1'b0;
23 s4:
24   Detected=1'b1;
25   
26 default:Detected=1'b0;
27 endcase
28 end
29 /*assign Detected=(state==s4)?1:0;*/
30 always@(posedge Clock or negedge Reset)
31 begin
32 if(!Reset)
33   begin
34   state<=s0;
35   end
36 else
37   case(state)
38     s0:if(Data_in==1'b0)state<=s0;
39        else state<=s1;
40        
41     s1:if(Data_in==1'b0)state<=s2;
42        else state<=s0;
43        
44     s2:if(Data_in==1'b0)state<=s3;
45        else state<=s0;
46        
47     s3:if(Data_in==1'b0)state<=s0;
48        else state<=s4;
49        
50     s4:if(Data_in==1'b0)state<=s0;
51        else state<=s1;
52     
53     default:state<=s0;
54   endcase
55   end
56 endmodule
View Code

   Detected_1001_tb.v

 1 `timescale 1ns/1ps
 2 module Detected_1001_tb;
 3 reg Clock,Reset,Data_in;
 4 wire Detected;
 5 reg [4:0] i;
 6 parameter sequence=18'b001_00100100_1101001;
 7 
 8 Detected_1001 U(
 9 .Clock(Clock),
10 .Reset(Reset),
11 .Data_in(Data_in),
12 .Detected(Detected)
13 );
14 
15 initial 
16 begin
17   i=0;Data_in=0;
18   Reset=0;Clock=0; #4 Reset=1;#4 Clock=0;
19   forever #2 Clock=~Clock;
20 end
21 
22 always@(posedge Clock or negedge Reset)
23 begin
24   if(~Reset)
25     begin
26     i<=5'b0;
27     end
28   else if(i<=5'd17)
29     begin
30       Data_in<=sequence[i];
31       i<=i+5'd1;
32     end
33   else
34     i<=5'b0;
35 end    
36 
37 endmodule    
38         
39   
View Code

  仿真波形:

  過程中遇到的問題及解決方法:

  1、輸出Detected始終為0。

  解決方法及出現原因:在Detected_1001.v中對時鍾沿的檢測處,改錯之前是always@(Clock),指生成組合邏輯電路,改正為always@(posedge Clock)后錯誤消除,指觸發器的狀態僅在時鍾上升沿或下降沿發生跳變的同步時序邏輯電路。

  2、輸出Detected初始狀態不定。

  解決方法及出現原因:Detected_1001.v中對時鍾沿的檢測處,改錯之前是always@(posedge Clock),改錯后為always@(posedge Clock or negedge Reset),在Reset里把初始狀態設置為s0,而一開始在測試文件里Clock是保持0值的,因此此條always語句未動作,所以Detected出現不定狀態。

  3、高電平出現時刻分析:

  以時間點的概念來理解。在T4時刻,狀態機模塊檢測到的輸入是T4時刻以前的值,即Data_in=0,故在T4的將來時刻,state決定跳轉到狀態s3,也即Detected=0。同樣的道理,在T5時刻,狀態機模塊檢測到的輸入是T5時刻以前的值,即Data_in=1,故在T5的將來時刻,state決定跳轉到狀態s4,也即Detected=1。

  (詳細說來:該實驗當中,TB作為激勵給.v文件Data_in輸入。當上升沿來臨時,TB賦值給Data_in,同一時刻的上升沿狀態機對Data_in的值進行判斷,但是判斷的是此時刻以前的值。這就是為什么檢測輸出要比Data_in的賦值完成慢一拍的原因。)

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM