23213131
設(shè)計(jì)一個序列檢測器,檢測序列1101,檢測到輸出1,否則輸出0.
用狀態(tài)機(jī)來實(shí)現(xiàn)序列檢測器是非常合適的,下面先給出狀態(tài)轉(zhuǎn)移圖,之后用Moore狀態(tài)機(jī)來實(shí)現(xiàn)這個序列檢測器:
(注:此處所畫為無重疊檢測,有重疊檢測只需要改變最后一個狀態(tài)即可,例如本例里,有重疊檢測,如果S4狀態(tài)下輸入為1,則需要轉(zhuǎn)向S2狀態(tài),其他不變。)
圖1:Moore狀態(tài)機(jī)狀態(tài)轉(zhuǎn)移圖
先給出行為仿真示意圖,示例代碼后面貼出:
可見,每經(jīng)歷一個1101,輸出就會是一個高脈沖,持續(xù)一個周期,也即輸出是一個1.
該狀態(tài)機(jī)的Verilog HDL描述為:
`timescale 1ns / 1ps// Company: // Engineer: // // Create Date: 2019/01/04 11:16:29 // Design Name: // Module Name: seq_det_moore // Project Name: // Target Devices: // Tool Versions: // Description: // // Dependencies: // // Revision: // Revision 0.01 - File Created // Additional Comments:module seq_det_moore(input clk,input reset,input din,output reg dout);//狀態(tài)聲明localparam [2:0]s0 = 3'b000,s1 = 3'b001,s2 = 3'b010,s3 = 3'b011,s4 = 3'b100;reg [2:0] current_state,next_state;always @(posedge clk, posedge reset)beginif(reset)current_state <= s0;elsecurrent_state <= next_state;endalways @ *begincase(current_state)s0:if(din == 1'b1) next_state = s1;else next_state = s0;s1:if(din == 1'b1) next_state = s2;else next_state = s0;s2:if(din == 1'b0) next_state = s3;else next_state = s2;s3:if(din == 1'b1) next_state = s4;else next_state = s0;s4:if(din == 1'b1) next_state = s1;else next_state = s0;default: next_state = s0;endcaseendalways @*beginif(current_state == s4) dout = 1;else dout = 0;endendmoduleRTL電路:
行為仿真代碼:
`timescale 1ns / 1ps // Company: // Engineer: // // Create Date: 2019/01/04 15:24:59 // Design Name: // Module Name: seq_det_moore_tb // Project Name: // Target Devices: // Tool Versions: // Description: // // Dependencies: // // Revision: // Revision 0.01 - File Created // Additional Comments: // module seq_det_moore_tb;reg clk,reset;reg din;wire dout;reg [20:0] din_mid;integer i;// Note: CLK must be defined as a reg when using this methodparameter PERIOD = 10;always beginclk = 1'b0;#(PERIOD/2) clk = 1'b1;#(PERIOD/2);end initial beginreset = 1'b1;din_mid = 21'b110111010110100101101;# 20reset = 1'b0;din = 1'b0;for(i = 0;i < 21;i = i + 1)begin#PERIODdin = din_mid[i];endendseq_det_moore uu1(.clk(clk),.reset(reset),.din(din),.dout(dout));endmodule編寫這個簡單的程序,并非毫無意義的,包括這個Testbench文件,自己動手編寫往往能發(fā)現(xiàn)一些小的細(xì)節(jié)問題,你可能并不懂,例如,在測試文件(testbench)中,我使用到了for循環(huán),出現(xiàn)了如下問題,首先我嘗試使用了generate for循環(huán)語法,可是Vivado軟件總是報錯!!!
之后,我直接使用for循環(huán),可是變量i的類型是什么呢?
reg,real都不對,最后使用了integer才成功,這說明了什么問題,當(dāng)然是基礎(chǔ)知識不牢固導(dǎo)致的,基礎(chǔ)知識為什么不牢固,往往是因?yàn)榫毩?xí)的不多,語法書讀的次數(shù)再多,往往很枯燥無味,問題還是需要在實(shí)踐中去尋找,Verilog語言很類似C,這導(dǎo)致我們往往很不情愿去仔仔細(xì)細(xì)地去學(xué),稍微關(guān)注些可綜合的語法,之后拿來就用。至今我仍不愿意去細(xì)看所有的語法。解決的辦法就是實(shí)踐。
第二個問題就是在測試文件中,定義了參數(shù)parameter PERIOD,可是后面為什么不能對此參數(shù)進(jìn)行運(yùn)算呢?例如我想延時2 * PERIOD,Vivado仍然報錯。讓我郁悶!
上述這些問題都出現(xiàn)在我的初次表寫測試文件的代碼中,這里給出錯誤的初稿代碼:(供大家發(fā)現(xiàn)問題)
`timescale 1ns / 1ps// Company: // Engineer: // // Create Date: 2019/01/04 15:24:59 // Design Name: // Module Name: seq_det_moore_tb // Project Name: // Target Devices: // Tool Versions: // Description: // // Dependencies: // // Revision: // Revision 0.01 - File Created // Additional Comments: // module seq_det_moore_tb;reg clk,reset;reg din;wire dout;reg [20:0] din_mid;// Note: CLK must be defined as a reg when using this methodparameter PERIOD = 10;always beginclk = 1'b0;#(PERIOD/2) clk = 1'b1;#(PERIOD/2);end initial beginreset = 1'b1;din_mid = 21'b110111010110100101101;#2*PERIODreset = 1'b0;generate genvar i;for(i = 0;i < 21;i ++)begin#PERIODdin = din_mid[i];endendgenerateendseq_det_moore uu1(.clk(clk),.reset(reset),.din(din),.dout(dout));endmodule總結(jié)
- 上一篇: Zigbee Direct 新标准功能发
- 下一篇: 正常的测试文章