实验一:五人表决器
一、程序清单
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity vote5 is
port(v_in:in std_logic_vector(4 downto 0);
lock,clr:in std_logic;
v_over:out std_logic_vector(2 downto 0);
num_agr,num_opp:out std_logic_vector(3 downto 0);
v_out:out std_logic_vector(4 downto 0);
led_agr,led_opp:out std_logic);
end entity vote5;
architecture one of vote5 is
begin
process(clr,v_in,lock)
variable agr,opp: std_logic_vector(3 downto 0);
begin
if(clr='1')then
led_agr<='0';
led_opp<='0';
agr:="0000";
opp:="0000";
if agr="0000" then
num_agr<="0000";
end if;
if opp="0000"then
num_opp<="0000";
end if;
v_out<="00000";
v_over<="000";
elsif(lock'event and lock='1')then
v_out<=v_in;
v_over<="111";
agr:="0000";
opp:="0000";
for i in 0 to 4 loop
if (v_in(i)<='0') then opp:=opp+1;
end if;
agr:=5-opp;
end loop;
num_agr<=agr;
num_opp<=opp;
if(agr>opp)then
led_agr<='1';
led_opp<='0';
else
led_agr<='0';
led_opp<='1';
end if;
end if;
end process;
end architecture one;
三.仿真
1. 功能仿真波形
2. 时序仿真波形
实验二:九九乘法表系统的设计
一、程序清单
library ieee;
use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all;
entity multiply is --构造体描述4位乘法器
port( clk:in std_logic;
a,b:in std_logic_vector(3 downto 0);
led_data:out std_logic_vector(7 downto 0);
seg_sel:out std_logic_vector(2 downto 0) );
end multiply;
architecture rtl of multiply is
signal led_data2,led_data1,led_data0: std_logic_vector(7 downto 0);--LED显示代码,寄存十位个位的数
signal displayclk: std_logic;
begin
process(a,b)
variable s: std_logic_vector(7 downto 0);--乘积
variable bai,shiwei,gewei: std_logic_vector(3 downto 0);--乘积的十位个位
begin
s(7 downto 0):=a(3 downto 0)*b(3 downto 0);
if s>="11001000" then bai:="0010";
s:=s-"11001000";
elsif s>="01100100" then bai:="0001";
s:=s-"01100100";
else bai:="0000";
end if;
if s>="01011010" then shiwei:="1001";s:=s-"01011010";gewei:=s(3 downto 0);--90以上 elsif s>="01010000" then shiwei:="1000";s:=s-"01010000";gewei:=s(3 downto 0);--80以上 elsif s>="01000110" then shiwei:="0111";s:=s-"01000110";gewei:=s(3 downto 0); --70以上 elsif s>="00111100" then shiwei:="0110";s:=s-"00111100";gewei:=s(3 downto 0);--60以上 elsif s>="00110010" then shiwei:="0101";s:=s-"00110010";gewei:=s(3 downto 0);--50以上 elsif s>="00101000" then shiwei:="0100";s:=s-"00101000";gewei:=s(3 downto 0);--40以上 elsif s>="00011110" then shiwei:="0011";s:=s-"00011110";gewei:=s(3 downto 0);--30以上 elsif s>="00010100" then shiwei:="0010";s:=s-"00010100";gewei:=s(3 downto 0);--20以上 elsif s>="00001010" then shiwei:="0001";s:=s-"00001010";gewei:=s(3 downto 0);--10以上 else gewei:=s(3 downto 0);shiwei:="0000";
end if;
case bai is
when "0001" => led_data2<="11111001";
when "0010" => led_data2<="10100100";
when others => led_data2<="11111111";
end case;
case shiwei is
when "0000" => led_data1<="11000000";
when "0001" => led_data1<="11111001";
when "0010" => led_data1<="10100100";
when "0011" => led_data1<="10110000";
when "0100" => led_data1<="10011001";
when "0101" => led_data1<="10010010";
when "0110" => led_data1<="10000010";
when "0111" => led_data1<="11111000";
when "1000" => led_data1<="10000000";
when "1001" => led_data1<="10010000";
when others => led_data1<="11111111";
end case;
case gewei is
when "0000" => led_data0<="11000000";
when "0001" => led_data0<="11111001";
when "0010" => led_data0<="10100100";
when "0011" => led_data0<="10110000";
when "0100" => led_data0<="10011001";
when "0101" => led_data0<="10010010";
when "0110" => led_data0<="10000010";
when "0111" => led_data0<="11111000";
when "1000" => led_data0<="10000000";
when "1001" => led_data0<="10010000";
when others => led_data0<="11111111";
end case;
end process;
process(clk)
variable cnt:integer range 0 to 20000; --1KHZ扫描显示时钟 begin
if clk'event and clk='1' then cnt:=cnt+1;
if cnt<10000 then displayclk<='1';
elsif cnt<20000 then displayclk<='0';
else cnt:=0;displayclk<='0';
end if;
end if;
end process;
process (displayclk) --显示两位
variable cnt2: std_logic_vector(1 downto 0);
begin
if displayclk'event and displayclk='1' then cnt2:=cnt2+1;
if cnt2="01" then seg_sel<="001";
led_data<=led_data0;
elsif cnt2="010" then seg_sel<="010";
led_data<=led_data1;
elsif cnt2="11" then cnt2:="00"; seg_sel<="100";
led_data<=led_data2;
end if;
end if;
end process;
end rtl;
二、仿真
设计输入文件经maxplus软件开发系统编译、处理,由功能仿真器进行模拟,获得仿真波形如图6所示。其中输入用1位十进制数表示,输出乘积已用2位十进制数表示,BD2位高位,BD1是低位。
例如,模拟开始时,ARH=0,系统执行手动功能,输入被乘数AA和乘数BB有效:7×8=56。在200.0ns以后,ARH=1,系统执行自动功能,被乘数和乘数按九九乘法表要求自动产生,则乘积BD2、BD1输出相应的数值。
三.实验心得
经过EDA实验增强了我对EDA设计的兴趣,更掌握了基本的电路设计流程、方法以及技巧。具备了这些基本知识,为今后的自主学习奠定了良好的基础。在编写时可以相互借鉴,这样可以节省一定的时间,尤其是24进制的处理上,我们采用了简单的方法即可完成多个功能的顺利实现。此次设计不足之处是不能进行定时闹钟,这是有待改进的地方,当然我们也可以在闹钟的时候采用音乐提醒,可以和乐曲硬件演奏电路设计相结合,这样数字钟的功能才算是完美。
在设计中还是需要注意一些常见的问题,比如实体名、项目名等,还有在编写VHDL文件时,一些文件名也是需要注意的。通过本次实验使我更进一步地熟悉了VHDL硬件描述语言的设计思想,也锻炼了自己独立思考问题的能力,同时通过对程序的调试也使自己对VHDL语言的语法,结构和基本语句有了更深刻的了解。
实验三:交通灯
一、程序清单:
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY traffic IS
PORT (clk:in std_logic;
led7s1:out std_logic_vector(6 downto 0);
led7s2:out std_logic_vector(6 downto 0);
comb_out:out std_logic_vector(5 downto 0));
END;
ARCHITECTURE one OF traffic IS
TYPE dm IS (s0,s1,s2,s3);
SIgnal current_state,next_state:dm;
SIGNAL FULL : STD_LOGIC;
SIGNAL tl :STD_LOGIC_VECTOR(6 DOWNTO 0);
SIGNAL th:STD_LOGIC_VECTOR(1 DOWNTO 0);
SIGNAL tm :STD_LOGIC_VECTOR(6 DOWNTO 0);
SIGNAL TIME :STD_LOGIC_VECTOR(6 DOWNTO 0);
BEGIN
P_REG: PROCESS(CLK)
VARIABLE CNT8:STD_LOGIC_VECTOR(7 DOWNTO 0);
BEGIN
IF CLK'EVENT AND CLK='1' THEN
IF CNT8 = "11111111" THEN
CNT8:="01111111";
FULL<='1';
ELSE CNT8 := CNT8+1;
FULL <= '0';
END IF; END IF;
END PROCESS P_REG;
PROCESS(full)
BEGIN
IF full'EVENT AND full='1' THEN
IF TIME<"1000011" THEN
TIME<=TIME+1;
ELSe TIME <="0000000";
END IF;
END IF;
END PROCESS;
REG:process( full,current_state)
BEGIN
IF full='1' AND full'EVENT THEN
current_state<=next_state;
END IF;
END process;
COM:process(current_state, time)
begin
case current_state is
when s0=>comb_out<="001100";tm<=39-time;
if time=39 then next_state<=s1;
else next_state<=s0;
end if;
when s1=>comb_out<="010100";tm<=43-time;
if time=43 then next_state<=s2;
else next_state<=s1;
end if;
when s2=>comb_out<="100010";tm<=63-time;
if time=63 then next_state<=s3;
else next_state<=s2;
end if;
when s3=>comb_out<="100001";tm<=67-time;
if time=67 then next_state<=s0;
else next_state<=s3;
end if;
end case;
end process;
PROCESS(tm)
BEGIN
IF tm>=30 THEN th<="11";tl<=tm-30;
ELSIF tm>=20 THEN th<="10";tl<=tm-20;
ELSIF tm>=10 THEN th<="01";tl<=tm-10;
ELSE th<="00";tl<=tm;
END IF;
END PROCESS;
process(th,tl)
begin
case th is
when"00"=>led7s1<="0111111";
when"01"=>led7s1<="0000110";
when"10"=>led7s1<="1011011";
when"11"=>led7s1<="1001111";
when others=>null;
end case;
case tl is
when "0000000"=>led7s2<="0111111";
when"0000001"=>led7s2<="0000110";
when "0000010"=>led7s2<="1011011";
when"0000011"=>led7s2<="1001111";
when"0000100"=>led7s2<="1100110";
when "0000101"=>led7s2<="1101101";
when "0000110"=>led7s2<="1111101";
when"0000111"=>led7s2<="0000111";
when "0001000"=>led7s2<="1111111";
when "0001001"=>led7s2<="1101111";
when others=>null;
end case;
end process;
end;
二、仿真结果
三、实验心得体会
通过这次实验,我进一步加深了对电子设计自动化的了解。并进一步熟练了对QuartusII软件的操作。在编写程序的过程中,遇到了很多问题,使我发现自己以前学习上存在的不足。通过与同学探讨,终于把问题都解决了,并加深了对交通灯原理和设计思路的了解。同时也掌握了做课程设计的一般流程,为以后的设计积累了一定的经验。做实验时,先查阅相关知识,把原理吃透,确定一个大的设计方向,在按照这个方向分模块的把要实现的功能用流程图的形式展示。最后参照每个模块把输入和输出引脚设定,运用我们所学的VHDL语言进行编程。总之,通过这次实验,进一步了解了EDA技术,收获很大,对软件编程、排错调试、相关仪器设备的使用技能等方面得到较全面的锻炼和提高。