名稱:交通燈圖像VGA顯示DE1-SoC開發(fā)板紅綠燈(代碼在文末下載)
軟件:Quartus II
語言:VHDL
代碼功能:
本設(shè)計(jì)使用VHDL語言設(shè)計(jì)VGA顯示的交通燈,VGA顯示屏上顯示主干道和支干道,道路用白色線條描繪,每個(gè)道路中間用黃色線條隔開分為左右兩個(gè)車道。每條主干道和支干道都對(duì)應(yīng)有3個(gè)紅綠燈,分別為紅色、黃色、綠色。紅黃綠三色交通燈指揮車輛的通行,紅燈停,綠燈行,黃燈為綠燈到紅燈的過渡。其中左轉(zhuǎn)和直行都按紅綠燈的指示通行,右轉(zhuǎn)的話不需要看紅綠燈,在任何時(shí)刻均可右轉(zhuǎn)。
本代碼已在DE1-SoC開發(fā)板驗(yàn)證,其他開發(fā)板可以修改管腳適配,開發(fā)板如下:
實(shí)際上板驗(yàn)證效果如下:
FPGA代碼Verilog/VHDL代碼資源下載:www.hdlcode.com
部分代碼展示:
LIBRARY?ieee; ???USE?ieee.std_logic_1164.all; ENTITY?vga_controller_top?IS ???PORT?(?????? ??????clk_50M???:?IN?STD_LOGIC; ??????rst???????:?IN?STD_LOGIC; ??????hsync?????:?OUT?STD_LOGIC; ??????vsync?????:?OUT?STD_LOGIC; key_1?????:?IN?STD_LOGIC; key_2?????:?IN?STD_LOGIC; key_3?????:?IN?STD_LOGIC; key_4?????:?IN?STD_LOGIC; key_5?????:?IN?STD_LOGIC; key_6?????:?IN?STD_LOGIC; key_7?????:?IN?STD_LOGIC; key_8?????:?IN?STD_LOGIC; VGA_CLK???????:?OUT?STD_LOGIC; VGA_BLANK_N???:?OUT?STD_LOGIC; ??????main_green_add?????:?IN?STD_LOGIC;--主路綠燈加 ??????main_green_sub?????:?IN?STD_LOGIC;--主路綠燈減 ??????branch_green_add???:?IN?STD_LOGIC;--支路綠燈加 ??????branch_green_sub???:?IN?STD_LOGIC;--支路綠燈減 ??????HEX0??:?OUT?STD_LOGIC_VECTOR(6?DOWNTO?0);--數(shù)碼管段選 HEX1??:?OUT?STD_LOGIC_VECTOR(6?DOWNTO?0);--數(shù)碼管段選 HEX2??:?OUT?STD_LOGIC_VECTOR(6?DOWNTO?0);--數(shù)碼管段選 HEX3??:?OUT?STD_LOGIC_VECTOR(6?DOWNTO?0);--數(shù)碼管段選 ??????rgb???????:?OUT?STD_LOGIC_VECTOR(11?DOWNTO?0) ???); END?vga_controller_top; ARCHITECTURE?behave?OF?vga_controller_top?IS --???COMPONENT?clk_PLL?IS --??????PORT?( --?????????refclk???????:?IN?STD_LOGIC; --?????????rst?????:?IN?STD_LOGIC; --?????????outclk_0???:?OUT?STD_LOGIC --??????); --???END?COMPONENT; --交通燈控制 COMPONENT?Traffic_Light_Control?IS ???PORT?( ??????clk?????:?IN?STD_LOGIC;--50Mhz reset?:?IN?STD_LOGIC;--復(fù)位 main_key?:?IN?STD_LOGIC; ??????branch_key?:?IN?STD_LOGIC; ??????main_green_add?????:?IN?STD_LOGIC;--主路綠燈加 ??????main_green_sub?????:?IN?STD_LOGIC;--主路綠燈減 ??????branch_green_add???:?IN?STD_LOGIC;--支路綠燈加 ??????branch_green_sub???:?IN?STD_LOGIC;--支路綠燈減 ??????R1??????:?OUT?STD_LOGIC;--高電平亮,主路紅燈 ??????G1??????:?OUT?STD_LOGIC;--高電平亮,主路綠燈 ??????Y1??????:?OUT?STD_LOGIC;--高電平亮,主路黃燈 ??????R2??????:?OUT?STD_LOGIC;--高電平亮,支路紅燈 ??????G2??????:?OUT?STD_LOGIC;--高電平亮,支路綠燈 ??????Y2??????:?OUT?STD_LOGIC;--高電平亮,支路黃燈 ??????HEX0??:?OUT?STD_LOGIC_VECTOR(6?DOWNTO?0);--數(shù)碼管段選 HEX1??:?OUT?STD_LOGIC_VECTOR(6?DOWNTO?0);--數(shù)碼管段選 HEX2??:?OUT?STD_LOGIC_VECTOR(6?DOWNTO?0);--數(shù)碼管段選 HEX3??:?OUT?STD_LOGIC_VECTOR(6?DOWNTO?0)--數(shù)碼管段選 ???); END?COMPONENT; ???COMPONENT?aiso_rst?IS ??????PORT?( ?????????clk???????:?IN?STD_LOGIC; ?????????reset?????:?IN?STD_LOGIC; ?????????reset_s???:?OUT?STD_LOGIC ??????); ???END?COMPONENT; ??? ???COMPONENT?vga_sync?IS ??????PORT?( ?????????clk???????:?IN?STD_LOGIC; ?????????rst???????:?IN?STD_LOGIC; VGA_CLK???????:?OUT?STD_LOGIC; VGA_BLANK_N???:?OUT?STD_LOGIC; ?????????hsync?????:?OUT?STD_LOGIC; ?????????vsync?????:?OUT?STD_LOGIC; ?????????pixel_x???:?OUT?STD_LOGIC_VECTOR(9?DOWNTO?0); ?????????pixel_y???:?OUT?STD_LOGIC_VECTOR(9?DOWNTO?0); ?????????video_on??:?OUT?STD_LOGIC ??????); ???END?COMPONENT; ??? ???COMPONENT?debounce?IS ??????PORT?( ?????????clk???????:?IN?STD_LOGIC; ?????????reset?????:?IN?STD_LOGIC; ?????????sw????????:?IN?STD_LOGIC; ?????????db????????:?OUT?STD_LOGIC ??????); ???END?COMPONENT; ??? ???COMPONENT?graphic_generator?IS ??????PORT?( ?????????clk???????:?IN?STD_LOGIC; ?????????rst???????:?IN?STD_LOGIC; ??????R1??????:?IN?STD_LOGIC;--高電平亮,主路紅燈 ??????G1??????:?IN?STD_LOGIC;--高電平亮,主路綠燈 ??????Y1??????:?IN?STD_LOGIC;--高電平亮,主路黃燈 ??????R2??????:?IN?STD_LOGIC;--高電平亮,支路紅燈 ??????G2??????:?IN?STD_LOGIC;--高電平亮,支路綠燈 ??????Y2??????:?IN?STD_LOGIC;--高電平亮,支路黃燈 ?????????pixel_x???:?IN?STD_LOGIC_VECTOR(9?DOWNTO?0); ?????????pixel_y???:?IN?STD_LOGIC_VECTOR(9?DOWNTO?0); ?????????video_on??:?IN?STD_LOGIC; ?????????rgb???????:?OUT?STD_LOGIC_VECTOR(11?DOWNTO?0) ??????); ???END?COMPONENT; COMPONENT?display?is ??PORT( ?score:IN?STD_LOGIC_VECTOR(3?DOWNTO?0); ???????HEX:out?STD_LOGIC_VECTOR(6?DOWNTO?0) ?); end?COMPONENT; ??? SIGNAL?clk?????????:?STD_LOGIC:='0'; ???SIGNAL?video_on????:?STD_LOGIC; ???SIGNAL?rst_s???????:?STD_LOGIC; ???SIGNAL?pixel_x?????:?STD_LOGIC_VECTOR(9?DOWNTO?0); ???SIGNAL?pixel_y?????:?STD_LOGIC_VECTOR(9?DOWNTO?0); ???--?Declare?intermediate?signals?for?referenced?outputs ???SIGNAL?hsync_buf?:?STD_LOGIC; ???SIGNAL?vsync_buf?:?STD_LOGIC; ???SIGNAL?rgb_buf???:?STD_LOGIC_VECTOR(11?DOWNTO?0); ???SIGNAL???R1??????:??STD_LOGIC;--高電平亮,主路紅燈 ???SIGNAL???G1??????:??STD_LOGIC;--高電平亮,主路綠燈 ???SIGNAL???Y1??????:??STD_LOGIC;--高電平亮,主路黃燈 ???SIGNAL???R2??????:??STD_LOGIC;--高電平亮,支路紅燈 ???SIGNAL???G2??????:??STD_LOGIC;--高電平亮,支路綠燈 ???SIGNAL???Y2??????:??STD_LOGIC;--高電平亮,支路黃燈 ???SIGNAL?main_key?:?STD_LOGIC; ???SIGNAL?branch_key?:?STD_LOGIC; BEGIN ???--?Drive?referenced?outputs ???hsync?<=?hsync_buf; ???vsync?<=?vsync_buf; ???rgb?<=?rgb_buf; main_key<=key_1?or?key_2?or?key_3?or?key_4; branch_key<=key_5?or?key_6?or?key_7?or?key_8; ??? --???u_clk_PLL:?clk_PLL --??????PORT?MAP??( --?????????refclk??=>?clk_50M, --?????????rst?????=>?rst_s, --?????????outclk_0?=>?clk --??????);? clk?<=?clk_50M; --交通燈控制 U_Traffic_Light_Control:?Traffic_Light_Control ???PORT?MAP( ??????clk????=>?clk,--50Mhz reset?=>?rst_s,--復(fù)位 main_key=>main_key, branch_key=>branch_key, ??????main_green_add?????=>?main_green_add,--主路綠燈加 ??????main_green_sub?????=>?main_green_sub,--主路綠燈減 ??????branch_green_add???=>?branch_green_add,--支路綠燈加 ??????branch_green_sub???=>?branch_green_sub,--支路綠燈減 ??????R1??????=>?R1,--高電平亮,主路紅燈 ??????G1??????=>?G1,--高電平亮,主路綠燈 ??????Y1??????=>?Y1,--高電平亮,主路黃燈 ??????R2??????=>?R2,--高電平亮,支路紅燈 ??????G2??????=>?G2,--高電平亮,支路綠燈 ??????Y2??????=>?Y2,--高電平亮,支路黃燈 ??????HEX0???=>?HEX0,-- ??????HEX1???=>?HEX1,-- HEX2???=>?HEX2,-- HEX3???=>?HEX3 ???); ??? ???u0?:?aiso_rst ??????PORT?MAP?( ?????????clk??????=>?clk, ?????????reset????=>?rst, ?????????reset_s??=>?rst_s ??????); ? ??? ???u1?:?vga_sync ??????PORT?MAP?( ?????????clk???????=>?clk, ?????????rst???????=>?rst_s, VGA_CLK???=>?VGA_CLK, VGA_BLANK_N?=>?VGA_BLANK_N, ?????????hsync?????=>?hsync_buf, ?????????vsync?????=>?vsync_buf, ?????????pixel_x???=>?pixel_x, ?????????pixel_y???=>?pixel_y, ?????????video_on??=>?video_on ??????); ??? ??? ???u4?:?graphic_generator ??????PORT?MAP?( ?????????clk???????=>?clk, ?????????rst???????=>?rst_s, ?????????pixel_x???=>?pixel_x, ?????????pixel_y???=>?pixel_y, ??????R1??????=>?R1,--高電平亮,主路紅燈 ??????G1??????=>?G1,--高電平亮,主路綠燈 ??????Y1??????=>?Y1,--高電平亮,主路黃燈 ??????R2??????=>?R2,--高電平亮,支路紅燈 ??????G2??????=>?G2,--高電平亮,支路綠燈 ??????Y2??????=>?Y2,--高電平亮,支路黃燈 ?????????video_on??=>?video_on, ?????????rgb???????=>?rgb_buf ??????); END?behave;
1.?導(dǎo)言
本設(shè)計(jì)使用VHDL語言設(shè)計(jì)VGA顯示的交通燈,VGA顯示屏上顯示主干道和支干道,道路用白色線條描繪,每個(gè)道路中間用黃色線條隔開分為左右兩個(gè)車道。每條主干道和支干道都對(duì)應(yīng)有3個(gè)紅綠燈,分別為紅色、黃色、綠色。紅黃綠三色交通燈指揮車輛的通行,紅燈停,綠燈行,黃燈為綠燈到紅燈的過渡。其中左轉(zhuǎn)和直行都按紅綠燈的指示通行,右轉(zhuǎn)的話不需要看紅綠燈,在任何時(shí)刻均可右轉(zhuǎn)。
2.?背景
2.1 VGA顯示原理
顯示器掃描方式分為逐行掃描和隔行掃描:逐行掃描是掃描從屏幕左上角一點(diǎn)開始,從左向右逐點(diǎn)掃描,每掃描完一行,電子束回到屏幕的左邊下一行的起始位置,在這期間,CRT對(duì)電子束進(jìn)行消隱,每行結(jié)束時(shí),用行同步信號(hào)進(jìn)行同步;當(dāng)掃描完所有的行,形成一幀,用場(chǎng)同步信號(hào)進(jìn)行場(chǎng)同步,并使掃描回到屏幕左上方,同時(shí)進(jìn)行場(chǎng)消隱,開始下一幀。隔行掃描是指電子束掃描時(shí)每隔一行掃一行,完成一屏后再返回來掃描剩下的行,隔行掃描的顯示器閃爍的厲害,會(huì)讓使用者的眼睛疲勞。
完成一行掃描的時(shí)間稱為水平掃描時(shí)間,其倒數(shù)稱為行頻率;完成一幀(整屏)掃描的時(shí)間稱為垂直掃描時(shí)間,其倒數(shù)稱為場(chǎng)頻率,即刷新一屏的頻率,常見的有60Hz,75Hz等等。標(biāo)準(zhǔn)的VGA顯示的場(chǎng)頻60Hz,行頻31.5KHz。
行場(chǎng)消隱信號(hào):是針對(duì)老式顯像管的成像掃描電路而言的。電子槍所發(fā)出的電子束從屏幕的左上角開始向右掃描,一行掃完需將電子束從右邊移回到左邊以便掃描第二行。在移動(dòng)期間就必須有一個(gè)信號(hào)加到電路上,使得電子束不能發(fā)出。不然這個(gè)回掃線會(huì)破壞屏幕圖像的。這個(gè)阻止回掃線產(chǎn)生的信號(hào)就叫作消隱信號(hào),場(chǎng)信號(hào)的消隱也是一個(gè)道理。
顯示帶寬指的顯示器可以處理的頻率范圍。如果是60Hz刷新頻率的VGA,其帶寬達(dá)640x480x60=18.4MHz,70Hz的刷新頻率1024x768分辨率的SVGA,其帶寬達(dá)1024x768x70=55.1MHz。
VGA時(shí)序圖
VESA中定義行時(shí)序和場(chǎng)時(shí)序都需要同步脈沖(Sync a)、顯示后沿(Back porch b)、顯示時(shí)序段(Display interval c)和顯示前沿(Front porch d)四部分。VGA工業(yè)標(biāo)準(zhǔn)顯示模式要求:行同步,場(chǎng)同步都為負(fù)極性,即同步脈沖要求是負(fù)脈沖。
由VGA的行時(shí)序可知:每一行都有一個(gè)負(fù)極性行同步脈沖(Sync a),是數(shù)據(jù)行的結(jié)束標(biāo)志,同時(shí)也是下一行的開始標(biāo)志。在同步脈沖之后為顯示后沿(Back porch b),在顯示時(shí)序段(Display interval c)顯示器為亮的過程,RGB數(shù)據(jù)驅(qū)動(dòng)一行上的每一個(gè)像素點(diǎn),從而顯示一行。在一行的最后為顯示前沿(Front porch d)。在顯示時(shí)間段(Display interval c)之外沒有圖像投射到屏幕是插入消隱信號(hào)。同步脈沖(Sync a)、顯示后沿(Back porch b)和顯示前沿(Front porch d)都是在行消隱間隔內(nèi)(Horizontal Blanking Interval),當(dāng)消隱有效時(shí),RGB信號(hào)無效,屏幕不顯示數(shù)據(jù)。
VGA的場(chǎng)時(shí)序與行時(shí)序基本一樣,每一幀的負(fù)極性脈沖(Sync a)是一幀的結(jié)束標(biāo)志,同時(shí)也是下一幀的開始標(biāo)志。而顯示數(shù)據(jù)是一幀的所有行數(shù)據(jù)。
2.2 交通燈原理
道路交通信號(hào)燈是用于給互相沖突的交通流分配有效的通行權(quán),以提高道路交通安全和道路容量的一類交通燈。當(dāng)今,紅綠燈安裝在各個(gè)道口上,已經(jīng)成為疏導(dǎo)交通車輛最常見和最有效的手段,這一技術(shù)已經(jīng)有相當(dāng)長(zhǎng)的發(fā)展歷史了。
1858年,在英國(guó)倫敦主要街頭安裝了以燃煤氣為光源的紅,藍(lán)兩色的機(jī)械扳手式信號(hào)燈,用以指揮馬車通行。這是世界上最早的交通信號(hào)燈。1868年,英國(guó)機(jī)械工程師納伊特在倫敦威斯敏斯特區(qū)的議會(huì)大廈前的廣場(chǎng)上,安裝了世界上最早的煤氣紅綠燈。它由紅綠兩以旋轉(zhuǎn)式方形玻璃提燈組成,紅色表示“停止”,綠色表示“注意”。1869年1月2日,煤氣燈爆炸,使警察受傷,遂被取消。
電氣啟動(dòng)的紅綠燈出現(xiàn)在美國(guó),這種紅綠燈由紅綠黃三色圓形的投光器組成,1914年始安裝于紐約市5號(hào)大街的一座高塔上。紅燈亮表示“停止”,綠燈亮表示“通行”。
1918年,又出現(xiàn)了帶控制的紅綠燈和紅外線紅綠燈。帶控制的紅綠燈,一種是把壓力探測(cè)器安在地下,車輛一接近紅燈便變?yōu)榫G燈;另一種是用擴(kuò)音器來啟動(dòng)紅綠燈,司機(jī)遇紅燈時(shí)按一下嗽叭,就使紅燈變?yōu)榫G燈。紅外線紅綠燈當(dāng)行人踏上對(duì)壓力敏感的路面時(shí),它就能察覺到有人要過馬路。紅外光束能把信號(hào)燈的紅燈延長(zhǎng)一段時(shí)間,推遲汽車放行,以免發(fā)生交通事故。
又經(jīng)過前人的設(shè)計(jì)和改造,交通信號(hào)燈終于普及整個(gè)城市的十字路口。
交通信號(hào)燈的出現(xiàn),使交通得以有效管制,對(duì)于疏導(dǎo)交通流量、提高道路通行能力,減少交通事故有明顯效果,更改變了交警輪流指揮和疏散交通擁擠的現(xiàn)狀,實(shí)現(xiàn)了人,車,路三者的同步協(xié)調(diào)?,F(xiàn)階段,許多設(shè)計(jì)工作者又設(shè)計(jì)出許多智能化,自動(dòng)化,數(shù)字化等更先進(jìn)的交通燈控制方案,這更方便于維護(hù)管理,給人們提供了更加便利的交通環(huán)境。
目前,城市規(guī)模還在不斷的擴(kuò)大,人們對(duì)交通信號(hào)燈的控制也越來越高,我們需要更高層次的去了解交通信號(hào)燈,結(jié)合城市十字路口交通的需要,不斷地去創(chuàng)新,才能達(dá)到發(fā)展的需求,所以研究交通信號(hào)燈的極為重要。
3.?工作章節(jié)
本設(shè)計(jì)主要分為兩大部分,一部分是VGA顯示的控制,另一部分是交通燈的控制。系統(tǒng)的整體框圖如下所示。
上圖中,aiso_rst、vga_sync、vga_sync這三個(gè)模塊實(shí)現(xiàn)VGA顯示的控制,Traffic_Light_Control模塊實(shí)現(xiàn)交通燈的控制。其中Traffic_Light_Control模塊內(nèi)部又分為RGY、SMG、display、CLOCK、time_ctrl等模塊,具體內(nèi)部框圖如下所示:
3.1?VGA顯示控制部分
aiso_rst模塊
該模塊實(shí)現(xiàn)復(fù)位的同步控制,將系統(tǒng)外部的異步復(fù)位信號(hào)轉(zhuǎn)換為同步復(fù)位信號(hào),外部輸入信號(hào)為開發(fā)板上的按鍵,低電平有效。將該信號(hào)通過兩級(jí)觸發(fā)器進(jìn)行同步,然后再通過一個(gè)非門實(shí)現(xiàn)低電平復(fù)位到高電平復(fù)位的轉(zhuǎn)換。內(nèi)部電路如下圖所示:
vga_sync模塊
該模塊實(shí)現(xiàn)VGA時(shí)序的控制,用于產(chǎn)生VGA的CLK信號(hào),BLANK信號(hào),hsync信號(hào)和vsync信號(hào),模塊框圖如下圖所示。
本設(shè)計(jì)使用25MHz的時(shí)鐘,屏幕分辨率為640x480,刷新頻率60Hz,每場(chǎng)對(duì)應(yīng)525個(gè)行周期(525=10+2+480+33),其中480為顯示行。每場(chǎng)有場(chǎng)同步信號(hào),該脈沖寬度為2個(gè)行周期的負(fù)脈沖,每顯示行包括800點(diǎn)時(shí)鐘,其中640點(diǎn)為有效顯示區(qū),每一行有一個(gè)行同步信號(hào),該脈沖寬度為96個(gè)點(diǎn)時(shí)鐘。由此可知:行頻為525*59.94=31469Hz,需要的時(shí)鐘頻率:525*800*59.94約25MHz。25MHz的時(shí)鐘通過50MHz的系統(tǒng)時(shí)鐘分頻得到,hsync信號(hào)和vsync信號(hào)通過計(jì)數(shù)器計(jì)數(shù)控制,其中hcount計(jì)數(shù)到最大799,vcount計(jì)數(shù)最大到524,再通過對(duì)計(jì)數(shù)器計(jì)數(shù)區(qū)域的選擇控制輸出hsync信號(hào)和vsync信號(hào)。下圖為本模塊實(shí)現(xiàn)的VGA時(shí)序圖,
本模塊還輸出pixel_x、pixel_y用于指示當(dāng)前屏幕上的坐標(biāo)。其中pixel_x=hcount(橫坐標(biāo)),pixel_y=vcount(縱坐標(biāo))。video_on信號(hào)指示當(dāng)前區(qū)域?yàn)橛行э@示區(qū),范圍為640*480,即hcount<640,vcount<480.
graphic_generator模塊
該模塊控制顯示器顯示交通燈的圖案,包括道路、斑馬線、紅綠燈等部分。模塊框圖如下圖所示。
該模塊接收vga_sync模塊輸出的pixel_x、pixel_y信息和Traffic_Light_Control模塊輸出的紅綠燈控制信息,其中pixel_x、pixel_y信息用于在顯示器繪制道路和紅綠燈,Traffic_Light_Control模塊輸出的紅綠燈控制信息用于控制對(duì)應(yīng)的紅綠燈什么時(shí)候亮滅。對(duì)應(yīng)的圖案如下圖所示,其中左下角為坐標(biāo)原點(diǎn),X軸最大值為640,Y軸坐標(biāo)最大值為480。
圖中上下方向的車道為主路,左右方向的車道為支路,下面以圖中用紅色框標(biāo)識(shí)的主路道路線為例,說明如何繪制該線條,該段代碼對(duì)應(yīng)如下:
road1_on <= '1' when ((pixel_x >= 220) AND (pixel_x <= 223) AND (pixel_y >= 0) AND (pixel_y <= 143)) else '0';--定義線條的位置
road1_rgb <= "111111111111";--顯示白色
將該段線條命名為road1_on,其范圍為X坐標(biāo)的(220~223),即從X軸的220到223,共占4個(gè)橫坐標(biāo)像素;Y坐標(biāo)為(0~143),即從Y軸的0到143,共占144個(gè)縱坐標(biāo)像素。該段線條根據(jù)XY軸的范圍定義即對(duì)應(yīng)圖中的位置。road1_rgb表示該段線條的顏色,111111111111表示紅色、綠色、藍(lán)色三色的混合,混合色為白色。至此該段線條的位置和顏色均通過代碼進(jìn)行了規(guī)定,其他圖案的設(shè)計(jì)以此類推。
3.2?交通燈控制部分
交通燈控制部分用于實(shí)現(xiàn)紅、黃、綠三種信號(hào)燈的控制及對(duì)應(yīng)數(shù)碼管的顯示,其中主路和支路的綠燈時(shí)間可以通過板子外部的按鍵增加或者減小。內(nèi)部具體包含RGY、SMG、display、CLOCK、time_ctrl等模塊。
RGY模塊
該模塊根據(jù)輸入的主路、支路時(shí)間,實(shí)現(xiàn)紅、黃、綠三種信號(hào)燈的控制,使用狀態(tài)機(jī)進(jìn)行控制。模塊框圖如下圖所示:
狀態(tài)機(jī)一共分為4個(gè)狀態(tài),分別用001、010、011、100表示。狀態(tài)轉(zhuǎn)移順序?yàn)椋?/p>
001->010->011->100->001
其中001表示主路綠燈狀態(tài),010表示主路黃燈黃燈狀態(tài),011表示支路綠燈狀態(tài),100表示支路黃燈狀態(tài)。每個(gè)狀態(tài)下通過計(jì)數(shù)器來控制對(duì)應(yīng)燈的時(shí)間,當(dāng)計(jì)數(shù)達(dá)到設(shè)置的時(shí)間后,切換到下一個(gè)狀態(tài)。主路綠燈狀態(tài)和主路黃燈狀態(tài)下支路為紅燈,支路綠燈狀態(tài)和支路黃燈狀態(tài)下主路為紅燈。將紅黃綠三色燈對(duì)應(yīng)的計(jì)數(shù)值輸出到SMG模塊。
本模塊還有行人按鍵控制功能,分主路控制信號(hào)main_key和支路控制信號(hào)branch_key。main_key由主路4個(gè)行人斑馬線位置的控制按鍵進(jìn)行或運(yùn)算得到,branch_key由支路4個(gè)行人斑馬線位置的控制按鍵進(jìn)行或運(yùn)算得到,當(dāng)main_key為1時(shí)表示主路有人按下,則狀態(tài)機(jī)狀態(tài)先轉(zhuǎn)換到主路黃燈狀態(tài)(010),然后自動(dòng)進(jìn)入到主路紅燈狀態(tài)。當(dāng)branch_key為1時(shí)表示支路有人按下,則狀態(tài)機(jī)狀態(tài)先轉(zhuǎn)換到支路黃燈狀態(tài)(100),然后自動(dòng)進(jìn)入到支路紅燈狀態(tài)。
SMG模塊
該模塊接收主路和支路紅黃綠三種燈的控制信號(hào)和對(duì)應(yīng)燈計(jì)數(shù)計(jì)數(shù)信號(hào),再將其轉(zhuǎn)換為倒計(jì)時(shí)。模塊框圖如下圖所示:
由于RGY模塊內(nèi)是按加法計(jì)數(shù),因而所得的計(jì)數(shù)信號(hào)為正計(jì)數(shù),故需要將正計(jì)數(shù)轉(zhuǎn)換為倒計(jì)數(shù)。轉(zhuǎn)換原理為將總時(shí)間減去正計(jì)時(shí)的時(shí)間,例如主路綠燈時(shí)間為20秒,正計(jì)數(shù)的順序?yàn)?~20,將20減去正計(jì)數(shù)即可以得到19~0的倒計(jì)數(shù)。
Display模塊
該模塊用于控制數(shù)碼管顯示倒計(jì)時(shí),模塊輸入主路和支路的倒計(jì)時(shí)信號(hào),再通過數(shù)碼管顯示出來。首先需要將輸入的倒計(jì)時(shí)信號(hào)轉(zhuǎn)換為十位和個(gè)位,再將十位個(gè)位分別通過數(shù)碼管顯示。模塊框圖如下圖所示:
先將輸入的倒計(jì)時(shí)信號(hào)轉(zhuǎn)換為int類型,便于使用乘法和除法運(yùn)算。將倒計(jì)時(shí)除以10得到的商即為十位,再用倒計(jì)時(shí)信號(hào)減去十位乘以10得到的差即為個(gè)位。倒計(jì)時(shí)使用開發(fā)板的7段數(shù)碼管顯示,每個(gè)數(shù)碼管輸入為7位,對(duì)應(yīng)下圖中的abcdefg7段,當(dāng)輸入0時(shí)對(duì)應(yīng)的段點(diǎn)亮,當(dāng)輸入為1時(shí),對(duì)應(yīng)的段滅。
根據(jù)上圖可以觀察到,若要顯示數(shù)字0,需要G滅,ABCDEF亮,也就是對(duì)應(yīng)編碼為“1000000”,其中從左到右依次對(duì)應(yīng)GFEDCBA。以此類推可以得到0~9的所有編碼。
CLOCK模塊
分頻模塊的功能是將系統(tǒng)數(shù)字50MHz分頻為1Hz,1Hz對(duì)應(yīng)周期為1秒,用分頻后的1Hz信號(hào)控制秒計(jì)時(shí)。分頻方法使用計(jì)數(shù)器實(shí)現(xiàn),原理為將50MHz信號(hào)計(jì)數(shù)50000000次就是1秒,將50000000計(jì)數(shù)分為0~25000000和25000000~50000000兩段,計(jì)數(shù)值在0~25000000時(shí)輸出低電平,25000000~50000000時(shí)輸出高電平,得到的信號(hào)就是1Hz的信號(hào)。模塊框圖如下圖所示
time_ctrl模塊
該模塊功能為通過外部的時(shí)間控制按鍵控制主路綠燈和支路綠燈的時(shí)間。外部按鍵首先通過按鍵消抖模塊消抖,然后使用消抖后的按鍵控制綠燈時(shí)間。模塊框圖如下圖所示:
消抖模塊一方面將按鍵的機(jī)械抖動(dòng)消除,另一方面將按鍵信號(hào)轉(zhuǎn)換為一個(gè)時(shí)鐘周期的高電平時(shí)間。按鍵包括主路綠燈加鍵、主路綠燈減鍵、支路綠燈加鍵、支路綠燈減鍵。當(dāng)加鍵按下時(shí),綠燈時(shí)間加1,當(dāng)加到99時(shí)不再響應(yīng)按鍵。當(dāng)按下減按鍵時(shí),綠燈時(shí)間減1,當(dāng)減到5時(shí),不再響應(yīng)按鍵按下。主路支路都有對(duì)應(yīng)按鍵,一共4個(gè)按鍵,分別對(duì)應(yīng)主路加減和支路加減。
4.?仿真圖
代碼設(shè)計(jì)完成后,編寫testbench對(duì)代碼進(jìn)行仿真,仿真工具為Modelsim,對(duì)應(yīng)不同模塊的仿真圖如下:
4.1 VGA時(shí)序控制部分仿真圖
aiso_rst模塊仿真圖如下圖所示,圖中可以看到,輸入的reset信號(hào)為低電平有效,且輸入與時(shí)鐘clk的上升沿不對(duì)齊,經(jīng)過時(shí)鐘同步后,輸出的reset_s信號(hào)與clk信號(hào)的時(shí)鐘上升沿對(duì)齊,即將異步的復(fù)位信號(hào)轉(zhuǎn)換為同步復(fù)位信號(hào)。
vga_sync模塊仿真圖如下圖所示,圖中可以看到25MHz的時(shí)鐘通過50MHz的系統(tǒng)時(shí)鐘分頻得到,即VGA_CLK頻率為系統(tǒng)時(shí)鐘clk的一半。
hsync信號(hào)和vsync信號(hào)通過計(jì)數(shù)器計(jì)數(shù)控制,其中hcount從0開始計(jì)數(shù),計(jì)數(shù)到最大799,vcount從零開始計(jì)數(shù),計(jì)數(shù)最大到524。
下圖為完整的一行數(shù)據(jù)時(shí)序圖,圖中可以看到,在hcount從0計(jì)數(shù)到799后,第0行掃描完成,Vcount加1,開始掃描第1行。以此類推一直掃描到第479行。
下圖為完整的行掃描時(shí)序,可以看到VGA_BLANK_N信號(hào)、Video_on信號(hào)、hsync信號(hào)和vsync信號(hào)的時(shí)序關(guān)系。
下圖可以看到VGA_BLANK_N信號(hào)在hcount計(jì)數(shù)到639時(shí)變?yōu)榈碗娖健?/p>
下圖可以看到VGA_BLANK_N信號(hào)在hcount計(jì)數(shù)到799時(shí)變?yōu)楦唠娖健?/p>
graphic_generator模塊仿真圖如下所示,可以看到程序中描述的XY軸范圍內(nèi)的線條對(duì)應(yīng)與圖中的_on信號(hào),下圖中_on信號(hào)為高電平時(shí),表示顯示對(duì)應(yīng)的線條。與_on對(duì)應(yīng)的_rgb信號(hào)表示該線條的顏色。
4.2 交通燈控制模塊部分仿真圖
RGY模塊仿真圖如下圖所示,圖中默認(rèn)的主路綠燈時(shí)間為30s,主路黃燈時(shí)間為5s,支路綠燈為20s,黃燈為5s。R1,G1,Y1對(duì)應(yīng)主路的紅燈、綠燈、黃燈信號(hào),高電平表示對(duì)應(yīng)的燈亮。R2,G2,Y2對(duì)應(yīng)支路的紅燈、綠燈、黃燈信號(hào),高電平表示對(duì)應(yīng)的燈亮。R1_BCD,G1_BCD,Y1_BCD對(duì)應(yīng)主路的紅燈、綠燈、黃燈的正計(jì)時(shí)時(shí)間。R2_BCD,G2_BCD,Y2_BCD對(duì)應(yīng)支路的紅燈、綠燈、黃燈的正計(jì)時(shí)時(shí)間。可以看到,主路支路的紅綠燈亮滅變化正確,且對(duì)應(yīng)的亮燈時(shí)間也正確。
下圖為SMG模塊的仿真圖,該模塊接收主路和支路紅黃綠三種燈的控制信號(hào)和對(duì)應(yīng)燈計(jì)數(shù)計(jì)數(shù)信號(hào),再將其轉(zhuǎn)換為倒計(jì)時(shí)。圖中R1,G1,Y1對(duì)應(yīng)主路的紅燈、綠燈、黃燈信號(hào)。R2,G2,Y2對(duì)應(yīng)支路的紅燈、綠燈、黃燈信號(hào)。R1_BCD,G1_BCD,Y1_BCD對(duì)應(yīng)主路的紅燈、綠燈、黃燈的正計(jì)時(shí)時(shí)間。R2_BCD,G2_BCD,Y2_BCD對(duì)應(yīng)支路的紅燈、綠燈、黃燈的正計(jì)時(shí)時(shí)間。最終計(jì)算得到的倒計(jì)時(shí)時(shí)間分別為主路倒計(jì)時(shí)SMG1和支路倒計(jì)時(shí)SMG2。圖中可以看到,倒計(jì)時(shí)與對(duì)應(yīng)的紅綠燈匹配,計(jì)時(shí)正確。
Display模塊仿真圖如下圖所示,以主路倒計(jì)時(shí)為29,舉例說明,圖中主路十位為2,個(gè)位為9,根據(jù)數(shù)碼管顯示原理,2對(duì)應(yīng)的編碼為0100100,9對(duì)應(yīng)的編碼為0010000,對(duì)應(yīng)仿真圖的HEX3和HEX2,可以看到仿真圖的編碼正確。
Clock模塊通過計(jì)時(shí)分頻得到1Hz信號(hào),分頻截圖如下所示??梢钥吹捷敵龅?Hz信號(hào)低電平時(shí)間和高電平時(shí)間分別占一半,即占空比為50%。
time_ctrl模塊用于調(diào)整交通燈的時(shí)間,按鍵分為主路綠燈加、減按鍵和支路綠燈加、減按鍵。下圖可以看到,主路綠燈加按下后,主路綠燈時(shí)間由30變?yōu)?1,按下主路綠燈減按鍵,又從31變?yōu)?0。同理可以看到支路綠燈在加減按鍵的控制下,從20變?yōu)?1,22,又變?yōu)?1。因此按鍵控制模塊仿真正確。
5. 結(jié)論
經(jīng)過對(duì)代碼的仿真調(diào)試后,對(duì)代碼進(jìn)行管腳分配后實(shí)際下載到開發(fā)板驗(yàn)證,驗(yàn)證經(jīng)過如下圖所示,圖中完整的顯示了主路、支路的位置,并且在每個(gè)路口有對(duì)應(yīng)的紅黃綠三色信號(hào)燈指示車輛的通行和停止,并且每個(gè)路口有供行人通行的斑馬線。經(jīng)過實(shí)際測(cè)試,交通燈信號(hào)變化符合設(shè)計(jì)要求,每個(gè)燈對(duì)應(yīng)的倒計(jì)時(shí)在數(shù)碼管顯示正確,且可以通過開發(fā)板按鍵控制主路和支路的通行時(shí)間。
點(diǎn)擊鏈接獲取代碼文件:http://www.hdlcode.com/index.php?m=home&c=View&a=index&aid=247