logo资料库

FPGA课程设计——模拟掷骰子.docx

第1页 / 共8页
第2页 / 共8页
第3页 / 共8页
第4页 / 共8页
第5页 / 共8页
第6页 / 共8页
第7页 / 共8页
第8页 / 共8页
资料共8页,全文预览结束
设计效果
设计方案
程序模块原理介绍:
分频器
数字扫描模块
按键暂停模块
比较模块
反思
附录(完整程序):
FPGA 课程设计 模拟掷骰子游戏
设计效果 每按同一个按键时会随机得到一个 1—6 中的一个随机数字,并用数码管显 示得到的数值。对两次按键得到的数值进行比较,若前者大,则最低两位 LED 显 示为“亮”、“灭”,后者较大,则最后两位 LED 显示状态改为“灭”、“亮”。 设计方案 本次课程设计的实质是使数码管随机显示一个数字,以达掷骰子时随机出数 的效果,因此在小组讨论并查阅资料后我们总结出以下两种方案: 1. 查找 FPGA 中是否含有类似于 C 语言中 rand()的随机函数,并搞清楚其 用法和效果,弄清楚后进行实验,并在按下按键后使随机函数发生作用, 并显示该数据,再将数据存入内部变量,并在其内部进行比较,将比较 结果映射到 LED 最后两位进行显示。 2. 类似于老虎机一样,让数码管显示 1~6 六个数字,并高速滚动,然后通 过按键暂停并显示,由于数码管显示数字在高速滚动状态下,人眼无法 准确分清楚此时是什么数字,所以根据概率学来说六个数字每个具有等 可能性,这样就能保证暂停的数字具有随机性,存储和比较模块原理与 方案 1 相似。 方案选择 由于第一种方案在实施起来时没有像第二种的老虎机一样,使人感觉有互动 性,并且用函数随机显示数字会让人感觉突兀,并像是在“出千”。因此我们选 用第二种方案进行本次课程设计 程序模块原理介绍: 分频器 由于 cyclone IV 板载系统时钟为 50MHz,时钟频率过大,无法表现出程序效果(或 者效果不明显),所以我们需要分频。 分频器原理:以系统时钟上升沿为标准,对系统时钟的上升沿计数,并给出一个 信号变量(或普通变量)给出初值,计够一定次数以后对其变量电平反转,即通 过电平反转重新造出来一个方波,以达到分频的目的。例如:对 50MHz 时钟二 分频,就是对系统时钟上升沿计数,当机构 2499999 个数时对电平变量 chz1 进 行反转,即可得到一个以 0.5ms 为周期的方波,则分频计算公式: f 分频后的频率 = 分频器程序: (系统时钟) 数上升沿数出来的数字
ck:PROCESS(CLK) BEGIN IF RISING_EDGE(CLK) THEN --分频器程序 IF T="0000011010111100000111111" THEN—此处数值没有具体计算 T<="0000000000000000000000000"; CLK1HZ<=NOT CLK1HZ; ELSE T<=T+1; END IF; END IF; END PROCESS CK; 数字扫描模块 结构体中数字扫描:将数字扫描模块写在结构体中,使 FPGA 在运行程序时能够 循环扫描数字,使数码管高速滚动数字。达到每个在暂停时,停止的每个数字具 有等可能性。 结构体中数字扫描: OUTPUT<="1111001"WHEN INPUT="0001"ELSE—本程序写在结构体的 begin 下 进程中数字扫描:定义中间变量,对其进行 1-6 的循环加一计数,然后再将其送 到数码管显示。 "0100100"WHEN INPUT="0010"ELSE "0110000"WHEN INPUT="0011"ELSE "0011001"WHEN INPUT="0100"ELSE "0010010"WHEN INPUT="0101"ELSE "0000011"WHEN INPUT="0110"; 进程中数字扫描: IF (CLK1HZ'EVENT AND CLK1HZ='1')THEN IF (A='1' AND B='1') THEN TMP:=TMP+1; IF (TMP=7) THEN TMP:=1; END IF; CASE TMP IS WHEN 1=> INPUT <="0001"; WHEN 2=> INPUT <="0010"; WHEN 3=> INPUT <="0011"; WHEN 4=> INPUT <="0100"; WHEN 5=> INPUT <="0101"; WHEN 6=> INPUT <="0110"; WHEN OTHERS => INPUT <="0000"; END CASE; END IF; END IF;
按键暂停模块 本次课程设计我们想用拨码开关以代替按键,本以为拨码开关不需要按键消抖但 最终的实验效果却不尽如人意,仍需要按键消抖,所以本次设计时我们改了一下, 利用两个按键对其进行暂停。如果用一个按键或拨码开关,必须要加按键消抖, 否则会有一定干扰。 消抖原理:类似于 51 单片机按键消抖,先检验其是否按下,若被按下则延时一 定时间,将其电平振荡的时间“滤”掉(在 FPGA 则数 5ms 的系统时钟过滤掉电 平振荡的时间)。 按键暂停以及存储程序: IF (A='0') THEN TIM:=TIM+1; IF (TIM=1) THEN RAN1<=TMP; ELSIF (TIM=2) THEN RAN2<=TMP; END IF; END IF; 注意:本模块程序未加按键消抖程序,如用单一按键需对按键加消抖程序。 一个按键的暂停草稿程序(加有消抖,但并未实践) IF (A='0') THEN IF RISING_EDGE(CLK) THEN IF T="0010011010111100000111111" THEN--此处数值没有具体计算 T<="0000000000000000000000000"; ELSE T<=T+1; END IF; END IF; WAIT UNTIL(T=”0010011010111100000111111”); IF(A=”0”)THEN TIM:=TIM+1; IF (TIM=1) THEN RAN1<=TMP; ELSIF (TIM=2) THEN RAN2<=TMP; END IF; END IF; END IF 比较模块 在程序内部定义两个变量(由于总开关为闭合状态所以不用考虑掉电保护问题),
用于存储先后两次按键按下的数字,然后对其变量进行比较若前者较大映射到 LED 则最后两个灯显示为“亮”、“灭”,反之后者大则 LED 显示为“灭”、“亮”。 比较模块程序: compare:PROCESS(RAN1,RAN2) BEGIN IF (RAN1>RAN2) THEN LED<="01"; ELSIF (RAN1
附录(完整程序): LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.STD_LOGIC_UNSIGNED.ALL; ENTITY test IS PORT(CLK,A,B: IN STD_LOGIC; OUTPUT: OUT STD_LOGIC_VECTOR(6 DOWNTO 0); WEI:OUT STD_LOGIC_VECTOR(1 DOWNTO 0); LED: OUT STD_LOGIC_VECTOR(1 DOWNTO 0)); END test; ARCHITECTURE behave OF test IS SIGNAL T:STD_LOGIC_VECTOR(24 DOWNTO 0); SIGNAL INPUT:STD_LOGIC_VECTOR(3 DOWNTO 0); SIGNAL CLK1HZ:STD_LOGIC; --SIGNAL LED1:STD_LOGIC_VECTOR(1 DOWNTO 0); SIGNAL RAN1:INTEGER:=0; SIGNAL RAN2:INTEGER:=0; --SIGNAL FLAG:INTEGER RANGE 1 TO 3; BEGIN WEI<="01"; OUTPUT<="1111001"WHEN INPUT="0001"ELSE "0100100"WHEN INPUT="0010"ELSE "0110000"WHEN INPUT="0011"ELSE "0011001"WHEN INPUT="0100"ELSE "0010010"WHEN INPUT="0101"ELSE "0000011"WHEN INPUT="0110"; (CLK1HZ,A,RAN1,RAN2,B) chouyang:PROCESS VARIABLE TMP:INTEGER:=0; --VARIABLE RAN1:INTEGER:=0; --VARIABLE RAN2:INTEGER:=0; VARIABLE TIM:INTEGER:=0; BEGIN IF (CLK1HZ'EVENT AND CLK1HZ='1')THEN IF (A='1' AND B='1') THEN TMP:=TMP+1; IF (TMP=7) THEN TMP:=1; END IF; CASE TMP IS
WHEN 1=> INPUT <="0001"; WHEN 2=> INPUT <="0010"; WHEN 3=> INPUT <="0011"; WHEN 4=> INPUT <="0100"; WHEN 5=> INPUT <="0101"; WHEN 6=> INPUT <="0110"; WHEN OTHERS => INPUT <="0000"; END CASE; END IF; END IF; IF (A='0') THEN TIM:=TIM+1; IF (TIM=1) THEN RAN1<=TMP; ELSIF (TIM=2) THEN RAN2<=TMP; END IF; END IF; --END IF; END PROCESS chouyang; compare:PROCESS(RAN1,RAN2) BEGIN IF (RAN1>RAN2) THEN ELSIF (RAN1
分享到:
收藏