您的当前位置:首页VHDL实验报告

VHDL实验报告

来源:小侦探旅游网


VHDL实验报告

5080309563 李斌

实验三. 4位可逆计数器,4位可逆二进制代码-格雷码转换器设计

[设计思路及步骤]: 一.需求:

设计4位可逆计数器,及4位可逆二进制代码-格雷码转换器,并仿真,下载。 [具体要求]

1. 4位可逆计数器

a) 使用CLOCK_50作为输入时钟,其频率为50MHz(对于频率大于50Hz的闪烁,

25

人眼会看到连续的光),因而,对其进行2的分频后,再用于时钟控制。(可利用实验一)

b) 使用拨码开关SW17作为模式控制,置‘1’时为加法计数器,置‘0’时为减

法计数器,同时使用LEDR17显示SW17的值。

c) 使用KEY3作为异步复位开关(按下时为0,不按为1),当为加法计数器时,

置“0000”,当为减法计数器时,置“1111”。

d) 使用LEDR3,LEDR2,LEDR1,LEDR0作为转换后的输出结果显示,LEDR3为高

位,LEDR0为低位。

2. 4位可逆二进制代码――格雷码转换器

a) 使用拨码开关SW17作为模式控制,置‘1’时为二进制代码―>格雷码转换,

置‘0’时为格雷码―>二进制代码,同时使用LEDR17显示SW17的值。 b) 使用拨码开关SW3, SW2, SW1, SW0作为输入的被转换数,SW3为高位,SW0

为低位。

使用LEDR3,LEDR2,LEDR1,LEDR0作为转换后的输出结果显示,LEDR3为高位,LEDR0为低位。

二.变量解释:

4位可逆计数器:

1. clk为时钟输入,clkout为分频后的时钟,cnt为分频计数,ctr为SW17模式

控制,rst为KEY3异步复位开关,tem为输出结果的中间变量;

2. 本实验的时钟输入为50MHz,定义为clk,为此设计时需要将其分频为50Hz,

25

需2分频,因此,代码中,需要有一个cnt作为一个225计数器,同时,定义分频后的时钟为clkout;

3. 建立process,检测key是否为0,为0则复位。否则,检测clkout,触发上升

沿则检测模式控制,对tem加1或减1,同时应检测是否达到最大或最小值,达到最值则直接返回到最初值,否则继续操作;

4. 最后,转换tem的值为相应的4位二进制数,并于LED上反映出来。 四位可逆二进制代码-格雷码转换器: 1. 检测模式,进行相应的操作;

2.ctr为0则格雷码转换成二进制码;ctr为1则为二进制码转换为格雷码 [源代码]:

1) 4位可逆计数器:

library ieee;

use ieee.std_logic_1164.all; entity cnt is

1

port(clk,ctr,rst: in bit;

clkout: buffer bit;

led:out std_logic_vector(3 downto 0)); end cnt;

architecture arch_cnt of cnt is begin

process(clk)

variable cnt: integer; begin

if (clk'event and clk='1')then cnt:=cnt+1;

if(cnt=16777216)then clkout<=not clkout; cnt:=0; end if; end if; end process;

process(clkout,ctr)

variable tem:integer range 0 to 15; begin

if(rst='0') then

if (ctr='1') then tem:=0; end if; if (ctr='0') then tem:=15;end if; elsif(clkout'event and clkout='1') then if(ctr='1') then

if (tem=15)then tem:=0; end if; tem:=tem+1; end if;

if(ctr='0') then

if (tem=0)then tem:=15; end if; tem:=tem-1; end if; end if; --end if; case tem is

when 0=>led<=\"0000\"; when 1=>led<=\"0001\"; when 2=>led<=\"0010\"; when 3=>led<=\"0011\"; when 4=>led<=\"0100\"; when 5=>led<=\"0101\"; when 6=>led<=\"0110\"; when 7=>led<=\"0111\"; when 8=>led<=\"1000\"; when 9=>led<=\"1001\"; when 10=>led<=\"1010\"; when 11=>led<=\"1011\"; when 12=>led<=\"1100\"; when 13=>led<=\"1101\"; when 14=>led<=\"1110\"; when 15=>led<=\"1111\"; when others=>null; end case; end process; end arch_cnt;

2) 4位可逆二进制代码-格雷码转换器:

library ieee;

2

using ieee.std_logic_1164.all; entity graycode is port(ctr:in std_logic; sw:buffer std_logic_vector(3 downto 0); led:buffer std_logic_vector(3 downto 0)); end graycode;

architecture garycoder of graycode is begin process(ctr,sw) begin if(ctr='0') then led[3]<=sw[3]; for i in 2 downto 0 loop led[i]<=led[i+1] xor sw[i]; end loop; elsif(ctr='1') then led[3]=sw[3]; for i in 2 downto 0 loop led[i]=sw[i+1] xor sw[i]; end loop; else null; end if; end process; end garycoder;

[实验心得]: 本次实验让我了解了基本的时序电路设计,仿真和测试,也进一步加深对VHDL语言的理解。同时我也进行了4位二进制可逆计数的设计和格雷码转换器的设计,对其原理和工作方式有了进一步的熟悉。本次实验给了我从理论性的VHDL设计向实践和操作的过程的体验。

3

实验六. 序列检测器的设计

[设计思路及步骤]: 一. 需求:

使用状态机设计一个5位序列检测器。从一串二进制码中检测出一个已预置的5位二进制码”10110” [具体要求] 1.画出状态转换图。(每增加一位二进制码相当于增加一个状态,再加上一个初始态,用6个状态可以实现.)

2.写出状态机的源程序,编译。要求当检测到预置序列时,输出一个脉冲的高电平,其余时候输出为低电平。

3.进行仿真,看结果是否正确。

二. 思路:

用一个6状态实现,特别考虑了当出现“10110110”这类前一个正确序列为结束,后一个正确序列已开始的情况。 三.定义各量:clk为时钟输入,d为数据输入,res为复位信号,res为检测结果输出,pstate为现态,nstate为下一状态,同时,自定义数据类型state,取值从one到six,表示6个状态,pstate和nstate为state类型;检测复位信号rst,若为1则复位为寝状态one,否则,检测时钟输入,若时钟触发上升沿,则pstate取得nstate的值,这步为时序逻辑部分;

[源程序]:

library ieee;

use ieee.std_logic_1164.all; entity seriescheck is port(clk,d,rst:in bit; res:out bit); end seriescheck;

architecture serieschecker of seriescheck is type state is (one,two,three,four,five,six); signal pstate,nstate:state; begin process(rst,clk) begin if(rst='1') then pstate<=one; elsif(clk'event and clk='1') then pstate<=nstate; end if; end process; process(d,pstate) begin case pstate is when one => res<='0'; if(d='1') then nstate<=two; else nstate<=one; end if; when two => res<='0'; if(d='0') then nstate<=three; else nstate<=two;

4

end if; when three => res<='0'; if(d='1') then nstate<=four; else nstate<=one; end if; when four => res<='0'; if(d='1') then nstate<=five; else nstate<=three; end if; when five => res<='0'; if(d='0') then nstate<=six; else nstate<=two; end if; when six => res<='1'; if(d='0') then nstate<=one; else nstate<=two; end if; end case; end process; end serieschecker;

[实验心得]: 实验之后,我学会了使用VHDL实现状态机的基本方法,实验中要求利用状态机实现序列检测器,我联系到以前编程的经验使用VHDL来完成了目的。过程中我了解了序列检测器的基本工作原理,并得知其在通信中的广泛应用和巨大作用。

5

实验七. 基于ROM的正弦波发生器的设计

[设计思路及步骤]: 一. 需求:

设计基于ROM的正弦波发生器,对其编译,仿真。

具体要求:

1.正弦发生器由波形数据存储模块(ROM),波形发生器控制模块及锁存模块组成

2.波形数据存储模块(ROM)定制数据宽度为8,地址宽度为6,可存储 64点正弦波形数据,用MATLAB求出波形数据。

3.将50MHz作为输入时钟。

二. 原理图:

波形发生器控制模块 波形数据存储模块(rom) CLK 锁存模块 输出 三. 由于地址宽度为6,最多存64个数据,因此,在一个周期2π内,等间隔取64个采样

点;同时,由于数据的宽度为8,因此数据值的范围可以为0到256,使用MATLAB得到这64个波形数据,如下:

\"10000000\11010001\111110\001\01\1\\\"00000010\00101111\

[源代码]: library ieee;

use ieee.std_logic_1164.all; entity sevent is

generic (bits: integer :=8;

words: integer := 64);

port (addr : buffer integer range 0 to words-1;

data: buffer std_logic_vector(bits-1 downto 0); clk : in bit;

wave: buffer std_logic_vector(7 downto 0) );

end sevent;

architecture arch_sevent of sevent is

type vector_array is array(0 to words-1) of std_logic_vector (bits-1 downto 0); signal cnt: integer range 0 to 63; constant memory: vector_array :=( \"10000000\\"10001101\\"10011001\\"10100101\

6

\"10110001\\"10111100\\"11000111\\"11010001\\"11011011\\"11100011\\"11101010\\"11110001\\"11110110\\"11111010\\"11111110\\"11111111\\"11111111\\"11111111\\"11111110\\"11111010\\"11110110\\"11110001\\"10000000\\"01110011\\"01100111\\"01011011\\"01100111\\"01011011\\"01001111\\"01000100\\"00111001\\"00101111\\"00100101\\"00011101\\"00010110\\"00001111\\"00001010\\"00000110\\"00000010\\"00000001\\"00000000\\"00000001\\"00000010\\"00000110\\"00001010\\"00001111\\"00010110\\"00011101\\"00100101\\"00101111\\"00111001\\"01000100\\"01001111\\"01011011\\"01100111\\"01110011\"); begin process begin

--data <= memory(addr);

7

wait until(clk' event and clk ='1'); case cnt is

when 0 => wave <= memory(0); when 1 => wave <= memory(1); when 2 => wave <= memory(2); when 3 => wave <= memory(3); when 4 => wave <= memory(4); when 5 => wave <= memory(5); when 6 => wave <= memory(6); when 7 => wave <= memory(7); when 8 => wave <= memory(8); when 9 => wave <= memory(9); when 10 => wave <= memory(10); when 11 => wave <= memory(11); when 12 => wave <= memory(12); when 13 => wave <= memory(13); when 14 => wave <= memory(14); when 15 => wave <= memory(15); when 16 => wave <= memory(16); when 17 => wave <= memory(17); when 18 => wave <= memory(18); when 19 => wave <= memory(19); when 20 => wave <= memory(20); when 21 => wave <= memory(21); when 22 => wave <= memory(22); when 23 => wave <= memory(23); when 24 => wave <= memory(24); when 25 => wave <= memory(25); when 26 => wave <= memory(26); when 27 => wave <= memory(27); when 28 => wave <= memory(28); when 29 => wave <= memory(29); when 30 => wave <= memory(30); when 31 => wave <= memory(31); when 32 => wave <= memory(32); when 33 => wave <= memory(33); when 34 => wave <= memory(34); when 35 => wave <= memory(35); when 36 => wave <= memory(36); when 37 => wave <= memory(37); when 38 => wave <= memory(38); when 39 => wave <= memory(39); when 40 => wave <= memory(40); when 41 => wave <= memory(41);

8

when 42 => wave <= memory(42); when 43 => wave <= memory(43); when 44 => wave <= memory(44); when 45 => wave <= memory(45); when 46 => wave <= memory(46); when 47 => wave <= memory(47); when 48 => wave <= memory(48); when 49 => wave <= memory(49); when 50 => wave <= memory(50); when 51 => wave <= memory(51); when 52 => wave <= memory(52); when 53 => wave <= memory(53); when 54 => wave <= memory(54); when 55 => wave <= memory(55); when 56 => wave <= memory(56); when 57 => wave <= memory(57); when 58 => wave <= memory(58); when 59 => wave <= memory(59); when 60 => wave <= memory(60); when 61 => wave <= memory(61); when 62 => wave <= memory(62); when 63 => wave <= memory(63); end case; cnt<=cnt+1; end process; end arch_sevent;

[实验心得]: 通过本次实验我学习了基于ROM的正弦波发生器的设计,并且,通过实验知道了波形发生器对波形的近似模拟,在将来接触到此类问题时我借助本次的经验更好的解决问题。

9

实验八. 数字密码锁的设计与实现

[设计思路及步骤]: 一. 需求:

设计一个数字密码锁,对其编译,仿真,下载。

数字密码锁具体要求如下:

1.系统具有预置的初始密码“00000001”。

2.输入密码与预存密码相同时,开锁成功,显示绿灯,否则开锁失败,显示红灯。 3.具有修改密码功能。修改密码时,先开锁,开锁成功才可以修改。 4.系统同时具有关锁功能。关锁后,显示红灯。 5.密码由拔码开关表示,开锁由按键表示。 6具有一个复位按键。按键后,回到初始状态。

[源程序]: library ieee;

use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; use ieee.std_logic_arith.all;

entity codelock is

port( codeinput: in std_logic_vector(7 downto 0); rst,open,close,set: in std_logic; redon,greenon: out std_logic); end codelock;

architecture codelock_body of codelock is

signal code: std_logic_vector(7 downto 0):= \"00000001\"; signal setcode_flag: std_logic:='0'; begin

process(rst,codeinput,open,close) begin

if(rst = '0') then redon <= '0'; greenon <= '0'; setcode_flag <= '0'; elsif(open = '0') then

if(code = codeinput) then redon <= '0'; greenon <= '1'; setcode_flag <= '1'; else

redon <= '1'; greenon <= '0'; setcode_flag <= '0'; end if;

10

elsif(close = '0') then redon <='1'; greenon <= '0'; setcode_flag <= '0'; end if; end process;

process(rst,set,setcode_flag) begin

if(rst = '0') then

code <= \"00000001\";

elsif(setcode_flag = '1') then if(set = '0') then

code <= codeinput; end if; end if; end process;

end codelock_body;

[实验心得]: 本次实验让我设计了密码锁,我由此学习密码锁的工作方式,并通过VHDL来实现了功能,将来接触到密码锁时我将会更熟练地解决问题并有自己独特的简介。

11

因篇幅问题不能全部显示,请点此查看更多更全内容