終於邁向了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
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
仿真波形:
過程中遇到的問題及解決方法:
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的賦值完成慢一拍的原因。)