FPGA综合设计实例.ppt

上传人:小飞机 文档编号:5574952 上传时间:2023-07-29 格式:PPT 页数:130 大小:5.11MB
返回 下载 相关 举报
FPGA综合设计实例.ppt_第1页
第1页 / 共130页
FPGA综合设计实例.ppt_第2页
第2页 / 共130页
FPGA综合设计实例.ppt_第3页
第3页 / 共130页
FPGA综合设计实例.ppt_第4页
第4页 / 共130页
FPGA综合设计实例.ppt_第5页
第5页 / 共130页
点击查看更多>>
资源描述

《FPGA综合设计实例.ppt》由会员分享,可在线阅读,更多相关《FPGA综合设计实例.ppt(130页珍藏版)》请在三一办公上搜索。

1、第十章综合设计实例,1 键盘扫描与显示,矩阵式键盘:行,列,矩阵是键盘以行列形式排列,键盘上每个按键其实是一个开关电路,当某键被按下时,该按键对应的位置就呈现逻辑0状态.,行扫描方式:逐行送0电平,读取列的状态,以判断按下的键号.列扫描方式:逐列送0电平,读取行的状态,以判断按下的键号.,以行扫描为例:,1给行依次送0111,1011,1101,1110信号;,2读取列电平状态,数码管显示,library ieee;use ieee.std_logic_1164.all;use ieee.std_logic_unsigned.all;entity key_scan is port(column

2、:in std_logic_vector(3 downto 0);-列状态 scan_cnt:in std_logic_vector(3 downto 0);-扫描字 row:out std_logic_vector(3 downto 0);-行状态 key_pressed:out std_logic);-按键有效与否,后续判断为零则为有键按下end;architecture rtl of key_scan isbegin row=1110 when scan_cnt(3 downto 2)=00 else 1101 when scan_cnt(3 downto 2)=01 else 1011

3、 when scan_cnt(3 downto 2)=10 else 0111;key_pressed=column(0)when scan_cnt(1 downto 0)=00 else column(1)when scan_cnt(1 downto 0)=01 else column(2)when scan_cnt(1 downto 0)=“10 else column(3);end rtl;,按键扫描控制程序,按键处理控制模块,library ieee;use ieee.std_logic_1164.all;use ieee.std_logic_unsigned.all;use ieee

4、.std_logic_arith.all;entity scan_count isport(clk:in std_logic;-clockscan_clk:in std_logic;-1khz clkkey_pressed:in std_logic;-检测按键有效与否,停止计数.scan_cnt:out std_logic_vector(3 downto 0);-计数end;architecture behav of scan_count issignal qscan:std_logic_vector(3 downto 0);begin scan_1:process(clk,scan_clk,

5、key_pressed)begin if(clkevent and clk=1)then if(scan_clk=1 and key_pressed=1)then qscan=qscan+1;end if;end if;end process;scan_cnt=qscan;end;,按键消抖控制模块,library ieee;use ieee.std_logic_1164.all;use ieee.std_logic_unsigned.all;use ieee.std_logic_arith.all;entity debounce isport(key_pressed:in std_logic

6、;clk:in std_logic;-同步时钟 scan_clk:in std_logic;-1khz clock key_valid:out std_logic);end;architecture behav of debounce isbegin,debounce:process(clk,scan_clk,key_pressed)variable dbnq:std_logic_vector(5 downto 0);begin if(key_pressed=1)then dbnq:=111111;-unkey_pressed,count reset at 63 elsif(clkevent

7、and clk=1)then if scan_clk=1 then if dbnq/=1 then dbnq:=dbnq-1;-key_pressed not enough long time end if;end if;end if;if dbnq=2 then key_valid=1;-key_valid after key_pressed 1/63k second else key_valid=0;end if;end process;end;,键盘译码及按键存储模块,library ieee;use ieee.std_logic_1164.all;use ieee.std_logic_

8、unsigned.all;use ieee.std_logic_arith.all;entity code_tran isport(clk:in std_logic;-clock for synchrony scan_cnt:in std_logic_vector(3 downto 0);-1khz clock key_valid:in std_logic;butt_code:out std_logic_vector(3 downto 0);end;architecture bb of code_tran isbegin process(clk)begin if(clkevent and cl

9、k=1)then if key_valid=1 then case scan_cnt is,when0000=butt_codebutt_codebutt_codebutt_codebutt_codebutt_codebutt_codebutt_codebutt_codebutt_codebutt_codebutt_codebutt_codebutt_codebutt_codebutt_code=1111;-fend case;end if;end if;end process;end;,电锁控制模块,library ieee;use ieee.std_logic_1164.all;use i

10、eee.std_logic_unsigned.all;entity ctrl is port(data_n:in std_logic_vector(3 downto 0);key_valid,clk:in std_logic;enlock:out std_logic;d,c,b,a:out std_logic_vector(3 downto 0);end;architecture aaa of ctrl is signal acc,reg:std_logic_vector(15 downto 0);signal nc:std_logic_vector(2 downto 0);signal qa

11、,qb:std_logic;beginkeyin:block is begin process(data_n,key_valid),begin if data_n=1101 then acc=0000000000000000;nc=000;elsif key_validevent and key_valid=1 then if data_n1101 then if nc=4 then acc=acc(11 downto 0),enlock=qa and not qb;d=acc(15 downto 12);c=acc(11 downto 8);b=acc(7 downto 4);a=acc(3

12、 downto 0);end aaa;,动态扫描显示控制模块,library ieee;use ieee.std_logic_1164.all;use ieee.std_logic_arith.all;use ieee.std_logic_unsigned.all;entity sel_display isport(clk:in std_logic;d,c,b,a:in std_logic_vector(3 downto 0);db_out:out std_logic_vector(3 downto 0);dis_out:out std_logic_vector(3 downto 0);end

13、 entity;architecture rtl of sel_display is signal sel:std_logic_vector(1 downto 0);signal dis:std_logic_vector(3 downto 0);signal db:std_logic_vector(3 downto 0);begin,counter:block is signal q:std_logic_vector(6 downto 0);begin process(clk)begin if clkevent and clk=1 then q=q+1;end if;end process;s

14、el=q(1 downto 0);end block counter;,multiplexer:block is begin process(sel)begin if sel=0 then db=d;dis=0111;elsif sel=1 then db=c;dis=1011;elsif sel=2 then db=b;dis=1101;elsif sel=3 then db=a;dis=1110;end if;end process;end block multiplexer;db_out=db;dis_out=dis;end rtl;,实例1 数字钟设计,实时显示时、分、秒,分析:1、最

15、小计时单位:秒。因此,首先要由时钟产生1HZ的信号;2、对秒进行0-59的计数,并且有进位功能,且显示;3、对分进行0-59的计数,并且有进位功能,且显示;4、对时进行0-59的计数,且显示;,library ieee;use ieee.std_logic_1164.all;entity second is port(clk,clr:in std_logic;-clk=1Hz sec1,sec0:out std_logic_vector(3 downto 0);co:out std_logic);end second;architecture arch of second isbegin,pr

16、ocess(clk,clr)variable cnt1,cnt0:std_logic_vector(3 downto 0);begin if clr=0 then cnt1:=0000;cnt0:=0000;elsif clkevent and clk=1 then if cnt1=0101 and cnt0=1000 then co=1;cnt0:=1001;elsif cnt01001 then cnt0:=cnt0+1;,else cnt0:=0000;if cnt10101 then cnt1:=cnt1+1;else cnt1:=0000;co=0;end if;end if;end

17、 if;sec1=cnt1;sec0=cnt0;end process;end arch;,实例2 出租车计费器设计,功能:(1)实现计费功能。车起步开始计费,首先显示起步价,设起步费为8.00元,车在行驶3 km以内,只收起步价8.00元。车行驶超过3 km后,每公里2元,车费依次累加。当总费用达到或超过40元时,每公里收费4元。当遇到红灯或客户需要停车等待时,则按时间计费,计费单价为每20S收费1元。(2)实现预置功能:预置起步费、每公里收费、车行加费里程、计时收费。(3)实现模拟功能:模拟汽车行驶、停止、暂停等状态。(4)实现显示功能:将路程与车费显示出来,以十进制显示。,系统流程如下:

18、,(1)系统接收到reset信号后,总费用变为8元,同时其他计数器,寄存器等全部清零。(2)系统接收到start信号后,首先把部分寄存器赋值,总费用不变,单价price寄存器通过对总费用的判断后赋为2元。其他寄存器和计数器等继续保持为0。(3)speed进程:通过对速度信号sp的判断,决定变量kinside的值。kinside即是行进100m所需要的时钟周期数,然后每行进100m,则产生一个脉冲clkout。(4)kilometers进程:由于一个clkout信号代表行进100m,故通过对clkout计数,可以获得共行进的距离kmcount。(5)time进程:在汽车启动后,当遇到顾客等人或红

19、灯时,出租车采用计时收费的方式。通过对速度信号sp的判断决定是否开始记录时间。当sp=0时,开始记录时间。当时间达到足够长时则产生timecount脉冲,并重新计时。一个timecount脉冲相当于等待的时间达到了时间计费的长度。这里选择系统时钟频率为500Hz,20s即计数值为1000。(6)kmmoney可分为kmmoney1和kmmoney2两个进程。kmmoney1进程:根据条件对enable和price赋值。当记录的距离达到3公里后enable变为1,开始进行每公里收费,当总费用大于40元后,则单价price由原来的2元每公里变为4元每公里。kmmoney2进程:在每个时钟周期判断t

20、imecount和clkout的值。当其为1时,则在总费用上加上相应的费用。,speed模块speed进程首先根据start信号判断是否开始计费,然后根据输入的速度档位sp2.0的判断,确定行驶100M所需要的时钟数,每前进100M,输出一个clkout信号。同时由cnt对clk进行计数,当cnt=kinside时,把clkout信号置1,cnt清0。,Library ieee;Use ieee.std_logic_1164.all;Use ieee.std_logic_unsigned.all;Entity feesystem is Port(clk:in std_logic;reset:i

21、n std_logic;start:in std_logic;stop:in std_logic;sp:in std_logic_vector(2 downto 0);clkout:out std_logic);end feesystem;architecture behav of feesystem isbegin process(clk,reset,stop,start,sp)type state_type is(s0,s1);variable s_state:state_type;variable cnt:integer range 0 to 28;variable kinside:in

22、teger range 0 to 30;begin case sp is-7档速度选择,具体每档kinside的值可根据实际情况设定 when 000=kinside:=0;-停止状态或空挡,when 001=kinside:=28;-第一档,慢速行驶状态,行驶100m需要28个时钟周期 when 010=kinside:=24;-第二档 when 011=kinside:=20;-第三档 when 100=kinside:=16;-第四档 when 101=kinside:=12;-第五档 when 110=kinside:=8;-第六档 when 111=kinside:=4;-第七档,也

23、是速度最大的档 end case;if reset=1then s_state:=s0;elsif clkevent and clk=1then case s_state is when s0=cnt:=0;clkout=0;if start=1then s_state:=s1;else s_state:=s0;end if;,when s1=clkout=0;if stop=1 then s_state:=s0;-相当于无客户上车 elsif sp=000 then s_state:=s1;-有客户上车,但车速位0,即客户刚上车还未起步 elsif cnt=kinside then cnt:

24、=0;clkout=1;s_state:=s1;else cnt:=cnt+1;s_state:=s1;end if;end case;end if;end process;end behav;,kilometers模块此模块主要用于记录行进的距离。通过对clkout信号的计数,可以计算行驶的距离kmcount。一个clkout脉冲相当于行进100m,所以只要记录clkout的脉冲数目即可确定共行进的距离。kmcount1为十分位,kmcount2为个位,kmcount3为十位,分别为十进制数。,Library ieee;Use ieee.std_logic_1164.all;Use ieee

25、.std_logic_unsigned.all;Entity kilometers is Port(clkout,reset:in std_logic;kmcnt1:out std_logic_vector(3 downto 0);kmcnt2:out std_logic_vector(3 downto 0);kmcnt3:out std_logic_vector(3 downto 0);end kilometers;architecture behav of kilometers isbegin process(clkout,reset)variable km_reg:std_logic_v

26、ector(11 downto 0);begin if reset=1then km_reg:=000000000000;elsif clkoutevent and clkout=1then-km_reg(3 downto 0)对应里程十分位,if km_reg(3 downto 0)=1001then km_reg:=km_reg+0111;-十分位向个位的进位处理 else km_reg(3 downto 0):=km_reg(3 downto 0)+0001;end if;if km_reg(7 downto 4)=1010then km_reg:=km_reg+01100000;-个位

27、向十位的进位处理 end if;end if;kmcnt1=km_reg(3 downto 0);kmcnt2=km_reg(7 downto 4);kmcnt3=km_reg(11 downto 8);end process;end behav;,time模块time模块主要用于计时收费。记录计程车速度为0的时间(如等待红灯)。通过对sp信号的判断,当sp=0,开始记录时间。当时间达到足够长时,产生timecount脉冲,并重新计时。time进程,产生时间计费脉冲timecount,单位计费时间可设定,这里选为20s,Library ieee;Use ieee.std_logic_1164.

28、all;Use ieee.std_logic_unsigned.all;Entity time is Port(clk,reset,start,stop:in std_logic;Sp:in std_logic_vector(2 downto 0);Timecount:out std_logic);End time;architecture behav of time isbegin process(reset,clk,sp,stop,start)type state_type is(t0,t1,t2);variable t_state:state_type;variable waittime

29、:integer range 0 to 1000;begin if reset=1then t_state:=t0;elsif(clkevent and clk=1)then,case t_state is when t0=waittime:=0;timecount if sp=000then t_state:=t2;else waittime:=0;t_state:=t1;end if;when t2=waittime:=waittime+1;timecount=0;if waittime=1000 then timecount=1;-20s,即1000个clk,产生一个时间计费脉冲 wai

30、ttime:=0;elsif stop=1then t_state:=t0;elsif sp=000then t_state:=t2;else timecount=0;t_state:=t1;end if;end case;end if;end process;end behav;,kmmoney模块kmmoney可分为kmmoney1和kmmoney2两个模块。kmmoney1用于产生enable和price 信号。当记录距离达到3公里后,enable信号为1,开始进行每公里的收费。当总费用大于40元后,单价price由原来的2元变为4元。用作计时收费。通过对sp信号的判断,当sp=0,开始

31、记录时间。当时间达到足够长时,产生timecount脉冲,并重新计时。kmmoney2用于判断timecount和clkout的值,当其为1时,总费用加1。最终输出为总费用。,计费采用两个进程kmmoney1和kmmoney2实现;总费用上限位999元,一旦超过上限,显示会出现不正常现象,Library ieee;Use ieee.std_logic_1164.all;Use ieee.std_logic_unsigned.all;Entity kmmoney is Port(clk,reset,timecount,clkout:in std_logic;Kmcnt2:in std_logic

32、_vector(3 downto 0);Kmcnt3:in std_logic_vector(3 downto 0);Count1:out std_logic_vector(3 downto 0);Count2:out std_logic_vector(3 downto 0);Count3:out std_logic_vector(3 downto 0);End kmmoney;Architecture behav of kmmoney isSignal cash:std_logic_vector(11 downto 0);Signal price:std_logic_vector(3 dow

33、nto 0);Signal enable:std_logic;Begin Process(cash,kmcnt2)Begin If cash=000001000000then price=0100;Else price=0010;End if;,If(kmcnt2=0011)or(kmcnt3=0001)then enable1001 then reg2(7 downto 0):=reg2(7 downto 0)+00000111;if reg2(7 downto 4)1001 then cash=reg2+000001100000;else cash=reg2;end if;else cas

34、h=reg2+0001;end if;elsif clkout=1 and enable=1 then-里程计费,if clkout_cnt=9 then clkout_cnt:=0;reg2:=cash;if0000,分频模块对系统的时钟进行分频,以模拟轮胎的滚动。(a)100分频(b)10分频,Library ieee;Use ieee.std_logic_1164.all;entity fp is port(clr,clk:in std_logic;newclk:out std_logic);end fp;architecture behav of fp issignal tem:int

35、eger range 0 to 99;begin process(clk,clr)begin if(clr=1)then tem=0;newclk=0;elsif(clkevent and clk=1)then if(tem=99)then tem=0;newclk=1;else tem=tem+1;newclk=0;end if;end if;end process;end behav;,Library ieee;Use ieee.std_logic_1164.all;entity fp10 is port(clr,clk:in std_logic;newclk:out std_logic)

36、;end fp10;architecture behav of fp10 issignal tem:integer range 0 to 9;begin process(clk,clr)begin if(clr=1)then tem=0;newclk=0;elsif(clkevent and clk=1)then if(tem=9)then tem=0;newclk=1;else tem=tem+1;newclk=0;end if;end if;end process;end behav;,显示模块,library ieee;use ieee.std_logic_1164.all;entity

37、 sev_yima isport(s:in std_logic_vector(3 downto 0);q:out std_logic_vector(6 downto 0);end sev_yima;architecture rtl of sev_yima isbegin with s select q=1000000when 0000,1111001when 0001,0100100when 0010,0110000when 0011,0011001when 0100,0010010when 0101,0000010when 0110,1111000when 0111,0000000when

38、1000,0010000when 1001,1111111when others;end rtl;,实例3 频率计设计,要求:对输入信号进行频率的测量并实时显示。,分频器模块时钟信号源输出的时钟信号频率高达50MHz,经过分频器将其分频为1Hz、4Hz、500Hz和1000Hz时钟信号。这四种信号再经过1/2分频,得到时间基准信号,其中1000Hz的时钟基准信号用于动态扫描译码电路,1Hz的时钟基准信号用于计数器的始能信号。,library ieee;use ieee.std_logic_1164.all;entity fenpin is port(clk:in std_logic;-50MH

39、z clk1:out std_logic;-1Hz clk2:out std_logic;-4Hz clk3:out std_logic;-500hz clk4:out std_logic-1khz);end fenpin;architecture arch of fenpin isbeginprocess(clk)variable cnt1:integer range 0 to 49999999;variable cnt2:integer range 0 to 12499999;variable cnt3:integer range 0 to 99999;variable cnt4:inte

40、ger range 0 to 49999;variable x1,x2,x3,x4:std_logic:=0;begin if clkevent and clk=1 then if cnt149999999 then,cnt1:=cnt1+1;else cnt1:=0;x1:=not x1;end if;if cnt212499999 then cnt2:=cnt2+1;else cnt2:=0;x2:=not x2;end if;if cnt299999 then cnt3:=cnt3+1;else cnt3:=0;x3:=not x3;end if;if cnt449999 then cn

41、t4:=cnt4+1;else cnt4:=0;x4:=not x4;end if;end if;clk1=x1;clk2=x2;clk3=x3;clk4=x4;end process;end arch;,计数器模块计数器模块始能端door输入分频器模块分频出的0.5Hz为基准时钟信号频率。计数器sig输入待测信号与基准时钟信号进行比较,并且计数。q03.0对应的是个位输出,q13.0对应的是十位输出,q23.0对应的是百位输出,q33.0对应的是千位输出。,library ieee;use ieee.std_logic_1164.all;use ieee.std_logic_unsigned

42、.all;entity measure is port(sig,door:in std_logic;q3,q2,q1,q0,dang:out std_logic_vector(3 downto 0);end measure;architecture arch of measure is signal c0,c1,c2,c3,c4,c5,c6:std_logic_vector(3 downto 0):=0000;signal suo:std_logic;-lock the count numberbeginprocess(door,sig)begin,if sigevent and sig=1

43、then if door=1 then suo=1;if c01001 then c0=c0+1;else c0=0000;if c11001 then c1=c1+1;else c1=0000;if c21001 then c2=c2+1;else c2=0000;if c31001 then c3=c3+1;else c3=0000;if c41001 then c4=c4+1;else c4=0000;if c51001 then c5=c5+1;else c5=0000;if c61001 then c6=c6+1;else,c6=0000;end if;end if;end if;e

44、nd if;end if;end if;end if;else-to if door=1 c0=0000;c1=0000;c2=0000;c3=0000;c4=0000;c5=0000;c6=0000;suo=0;if suo=1 then if c6/=0000 then,q3=c6;q2=c5;q1=c4;q0=c3;dang=0100;elsif c5/=0000 then q3=c5;q2=c4;q1=c3;q0=c2;dang=0010;elsif c4/=0000 then q3=c4;q2=c3;q1=c2;q0=c1;dang=0010;else q3=c3;q2=c2;q1=

45、c1;q0=c0;dang=0001;end if;else null;end if;end if;-to if door=1 else null;-to if sigevent and sig=1 then end if;end process;end arch;,锁存器模块锁存器模块主要由1个锁存器组成,主要作用是锁存计数器的计数值。设置锁存器可以使数据显示稳定可靠,不会由于周期性的清零信号而使数码管不断闪烁。锁存信号由控制电路产生,在1个周期的计数时间结束时,锁存器立即锁存计数值。锁存器的数据输入端与计数器数据输出端连接,数据输出与动态扫描译码电路中的显示译码电路连接,时钟输入端与基准时

46、钟电路端连接。在信号的上升沿,将计数器中的测量数据存入锁存器。,a23.0对应的是个位输入,a33.0对应的是十位输入,a43.0对应的是百位输入,a53.0对应的是千位输入,q23.0对应的是个位输出,q33.0对应的是十位输出,q43.0对应的是百位输出,q53.0对应的是千位输出锁存,clk连接的是分频器分频出的1000HZ的信号。,library ieee;use ieee.std_logic_1164.all;entity lock is port(clk:in std_logic;a5,a4,a3,a2,a1,a0:in std_logic_vector(3 downto 0);q

47、5,q4,q3,q2,q1,q0:out std_logic_vector(3 downto 0);end lock;architecture arch of lock issignal aa5,aa4,aa3,aa2,aa1,aa0:std_logic_vector(3 downto 0);beginprocess(clk)begin if clkevent and clk=0 then aa5=a5;aa4=a4;aa3=a3;aa2=a2;aa1=a1;aa0=a0;end if;q5=aa5;q4=aa4;q3=aa3;q2=aa2;q1=aa1;q0=aa0;end process;

48、end arch;,译码器模块译码器模块主要由4个显示模块组成。主要功能是将锁存器保存的4位二进制计数值转换成相应的数码管显示代码,显示模块输出端与4个7段数码管相连,可以在数码管上显示所测频率的十进制输出值。d3.0对应的是译码信号的输入,q6.0对应的是译码信号的输出。,实例4 交通灯模拟系统设计,结合DEII实际,拟用不同颜色发光二极管模拟南北方向和东西方向的红绿灯;每个方向有红、绿、黄三个灯,并能对绿灯放行时间进行设置和调整。,控制模块设计 本模块主要实现对两个方向红绿灯的交替显示控制。,其中Clock是时钟源,为分频模块的输出信号;hold是控制信号,起保持功能;countnum是计

49、数模块的输出信号,为一个周期的循环计数值;numa是a组交通灯输出;numb是b组交通灯输出;reda是a组红灯输出;greenda是a组绿灯输出;yellowa是a组黄灯输出;redb是b组红灯输出;greendb是b组绿灯输出;yellowb是a组黄灯输出;flash是闪烁输出,library ieee;use ieee.std_logic_1164.all;entity controller isport(clock:in std_logic;hold:in std_logic;countnum:in integer range 0 to 49;numa,numb:out integer

50、 range 0 to 25;reda,greena,yellowa:out std_logic;redb,greenb,yellowb:out std_logic;flash:out std_logic);end controller;architecture arch of controller isbegin process(clock)begin if falling_edge(clock)then if hold=0 then,reda=0;redb=0;greena=1;greenb=1;yellowa=1;yellowb=1;flash=1;else flash=0;-if co

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 生活休闲 > 在线阅读


备案号:宁ICP备20000045号-2

经营许可证:宁B2-20210002

宁公网安备 64010402000987号