目錄
一、實驗目的
二、實驗環境
三、實驗任務
四、實驗原理與實驗步驟
1. 實驗原理
2. 實驗步驟
五、實驗思考
代碼
TOP.v
trafic2_2.v
shumaguan.v
clk_div.v
一、實驗目的
1. 掌握同步有限狀態機的設計方法。
2. 采用狀態機的設計方法,設計實現帶倒計時的交通燈控制電路。
二、實驗環境
1. 裝有ModelSim和Vivado的計算機。
2. Sword實驗系統。
三、實驗任務
1. 理解交通燈控制系統的應用要求,采用狀態機設計方法,實現帶倒計時的交通燈控制系統設計,并在ModelSim上實現功能仿真。
2. 生成FPGA設計文件,下載到Sword實驗系統上驗證電路功能。
四、實驗原理與實驗步驟
1. 實驗原理
有限狀態機是時序電路的通用模型,任何時序電路都可以表示為有限狀態機。?
狀態機的基本結構如下圖所示。
在一些應用中,通常希望產生任意的狀態序列,并且每個狀態停留任意時間。采用狀態機的設計思想實現。交通燈控制系統就是其中的一個實例。
現要求東西大街和南北大街的交通燈亮滅狀態如下表所示。?各個狀態的延時時間如表1所示。
狀態 | 南北大街 | 東西大街 | 時延(s) |
0 | 綠 | 紅 | 9 |
1 | 黃 | 紅 | 3 |
2 | 紅 | 綠 | 9 |
4 | 紅 | 黃 | 3 |
表1 交通燈狀態表
2. 實驗步驟
??(1)根據表1,確定交通燈狀態轉移圖,采用可綜合設計風格設計狀態機代碼。
如果倒計時9~1,就把count初值設置為1
如果倒計時8~0,就把count初值設置為0,count<8,count<2
(2)編寫測試模塊,完成modelsim下電路的功能仿真,驗證電路功能。
100001(21h)
100010(22h)
001100(0ch)
010100(14h)
?(3)建立完成I/O引腳分配。
系統時鐘為100MHz,從提供的clkdiv引出clkdiv[24](頻率為6Hz)狀態機的輸入時鐘。
用SW[0]做為clr信號。
用LED[5:3]做為東西大街紅黃綠燈,以LED[2:0]做為南北大街紅黃綠燈。
下板的是將分成C1和狀態寄存器兩個模塊
(3)生成FPGA文檔,并下載到實驗板上物理運行,檢查設計結果。在Led等狀態修改的同時,數碼管可以顯示倒計時時間。
五、實驗思考
1、總結自己設計中,倒計時時間輸出的實現方法。
用counter=sec-count來實現倒計時
2、課堂給出的交通燈例子是將生成下一個狀態的組合邏輯C1與狀態寄存器寫在一個always塊中,試將其分成C1和狀態寄存器兩個模塊。并嘗試下板。
(提示:由于狀態轉移是在C1中通過判斷對時鐘的計數個數count來確實是否轉移,如果要轉移到下一個狀態,count需要清零。但同時在狀態寄存器模塊中,每次來一個clock上升沿,需要對count進行加1的操作。此時就會出現在C1和狀態存儲器中都對count賦值,如果下板會出現類似multi-driven的提示。該如何處理,可以想一想試一試。)
代碼
TOP.v
`timescale 1ns / 1ps
module TOP(input wire clk_100mhz,// I/O:input wire[15:0]SW,output wire led_clk,output wire led_clrn,output wire led_sout,output wire LED_PEN,output wire seg_clk,output wire seg_clrn,output wire seg_sout,output wire SEG_PEN );wire[31:0]Div;wire[15:0]LED_DATA;wire CK;wire[63:0] disp_data; wire[5:0] out;wire[3:0] counter;traffic2_2 U1(Div[24],SW[0],out,counter);shumaguan U3(disp_data[63:56],counter); clk_div U8(clk_100mhz,1'b0,SW[2],Div,CK);assign disp_data[55:0]=56'hffffffffffffff;P2S #(.DATA_BITS(64),.DATA_COUNT_BITS(6)) P7SEG (clk_100mhz,1'b0,Div[20],disp_data,seg_clk,seg_clrn,seg_sout,SEG_PEN);LED_P2S #(.DATA_BITS(16),.DATA_COUNT_BITS(4)) PLED (clk_100mhz,1'b0,Div[20],LED_DATA,led_clk,led_clrn,led_sout,LED_PEN);assign LED_DATA = ~{out[0],out[1],out[2],out[3],out[4],out[5],1'b0,1'b0,1'b0,1'b0,1'b0,1'b0,1'b0,1'b0,1'b0,1'b0}; endmodule
trafic2_2.v
module traffic2_2(input wire clk, input wire clr,output reg [5:0]lights,output reg [3:0]counter);reg[1:0] pstate,nstate;reg [4:0]count;parameter s0=2'b00,s1=2'b01,s2=2'b10,s3=2'b11;parameter sec9=8,sec3=2;always @(posedge clk or posedge clr)beginif(clr==1)begin//state<=s0;pstate<=s0;count<=0;endelsebeginif(pstate==s0 | pstate==s2)if(count<sec9)count<=count+1;elsebeginpstate<=nstate;count<=0;endelse if(pstate==s1 | pstate==s3)if(count<sec3)count<=count+1;elsebeginpstate<=nstate;count<=0;endendend//C1always@(*)begincase(pstate)s0: nstate=s1;s1: nstate=s2;s2: nstate=s3;s3: nstate=s0;default nstate<=s0;endcaseend//C2always @(*)begincase (pstate)s0: begin lights=6'b100001;counter=sec9-count;ends1: begin lights=6'b100010;counter=sec3-count;ends2: begin lights=6'b001100;counter=sec9-count;ends3: begin lights=6'b010100;counter=sec3-count;enddefault begin lights=6'b100001;counter=sec9-count;endendcaseendendmodule
shumaguan.v
module shumaguan(out,in);output[7:0] out;input[3:0] in;reg[7:0] out;always@(in)begincase(in)4'b0000: out=8'b00000011;4'b0001: out=8'b10011111;4'b0010: out=8'b00100101;4'b0011: out=8'b00001101;4'b0100: out=8'b10011001;4'b0101: out=8'b01001001;4'b0110: out=8'b01000001;4'b0111: out=8'b00011111;4'b1000: out=8'b00000001;4'b1001: out=8'b00001001;4'b1010: out=8'b00010001;4'b1011: out=8'b11000001;4'b1100: out=8'b01100011;4'b1101: out=8'b10000101;4'b1110: out=8'b01100001;4'b1111: out=8'b01110001;default: out=8'b0;endcaseend
endmodule
clk_div.v
`timescale 1ns / 1ps
//
// Company:
// Engineer:
//
// Create Date: 17:19:38 07/17/2012
// Design Name:
// Module Name: clk_div
// Project Name:
// Target Devices:
// Tool versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//
module clk_div(input clk,input rst,input SW2,output reg[31:0]clkdiv,output Clk_CPU);// Clock divider-時鐘分頻器always @ (posedge clk or posedge rst) begin if (rst) clkdiv <= 0; else clkdiv <= clkdiv + 1'b1; endassign Clk_CPU = (SW2)? clkdiv[24] : clkdiv[0];endmodule