EDA_多模式流水灯设计)
EDA课程设计
课题名称:多模式流水灯设计
评语:
审阅
指导老师:姓名:专业:电子信息工程班级:日期:成绩
2011年05月16日
时间
多模式的流水灯的设计
()
Multi-mode design of water lamp
(Department of Electronic Engineering of University, China) Phone: Instructor:
Abstract: EDA technology refers to the computer as the working platform, the integration of the application of electronic technology, computer technology, information processing and intelligent
technology to the latest results, the automatic design of electronic products. This paper describes the design process of multi-mode water, simulation, debugging results, and summed up our feelings and experiences.
Keywords: EDA technology, VHDL language, multi-mode water lamp
摘要:EDA技术是指以计算机为工作平台,融合了应用电子技术、计算机技术、
信息处理及智能化技术的最新成果,进行电子产品的自动设计。本文详细介绍了多模式流水的设计过程,仿真、调试结果,并总结出了我们的心得体会。
关键字:EDA技术、VHDL语言、多模式的流水灯
1、引言:EDA技术就是以计算机为工具,设计者在EDA软件平台上,用硬件描
述语言VHDL完成设计文件,然后由计算机自动地完成逻辑编译、化简、分割、综合、优化、布局、布线和仿真,直至对于特定目标芯片的适配编译、逻辑映射和编程下载等工作。EDA技术的出现,极大地提高了电路设计的效率和可操作性,减轻了设计者的劳动强度。
在本次设计过程中,我们主要用到了quartus软件、modelsim软件、DE2学习开发板。
2、设计内容
设计可以多模式控制的流水灯,并用quartus 、modelsim进行编译和仿真,可以在DE2板上实现自己的需求功能。
• • • •
设计要求
、可以进行模式选择 、必须有手动/自动CLK 、至少4种流水灯方式 、数显管的显示
3、设计原理图
4、设计方案的选择
设计流水灯可以采用状态机来实现不同的LED显示方式从而实现流水效果,1Hz、2Hz信号可以将DE2板上的50MHZ的有源晶体作为时钟源,通过50000000、25000000分频得到1Hz,2Hz信号,多模式的选择可以采用设计多进制计数器的方法,控制输出从而实现多模式的控制。
(1)、顶层设计
从原理图我们可以看到主要有6个模块,包括1hz分频器、2hz分频器、时钟选择器、模块选择器、流水灯实现、数显管实现六个模块。 程序如下: library ieee;
use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all;
entity liushui is --顶层文件
port(clk_50m:in std_logic; --DE2开发板上的50Mhz的时钟 clr:in std_logic; --清零信号( 开关 ) mode_select:in std_logic; --模式选择 clk_hand:in std_logic; --手动时钟
clk_select:in std_logic; --自动/手动时钟选择信号
y1,y2,y3,y4,y5,y6,y7,y8:out std_logic_vector(6 downto 0); --数显管的输出
led:out std_logic_vector(17 downto 0)); --流水灯的 显示 end liushui;
architecture a of liushui is
signal clk:std_logic; --时钟选择的输出 signal flash :std_logic; -- 数显管的闪烁信号
signal a1,a2,a3,a4,a5,a6,a7,a8:std_logic_vector(3 downto 0); -- 数显管的驱动信号
signal clk_1hz:std_logic; -- 1HZ时钟信号
signal mode:std_logic_vector(1 downto 0); --模式选择信号的输出
component clock_1hz
port(clk_in :in std_logic; --50MHZ的DE2系统的主时钟输入信号
clk_out :out std_logic); --1hz的方波信号 end component;
component clock_2hz
port( clk_in:in std_logic; --50MHZ的DE2系统的主时钟输入信号
clk_out :out std_Logic); --2hz的方波信号 end component;
component clk_selection
port(clk_select:in std_logic; --自动/手动时钟选择信号 clk_1hz:in std_logic; --1hz的方波信号 clk_hand:in std_logic; --手动时钟 clk:out std_logic); -- 时钟输出 end component; component led7s
port(a:in std_logic_vector(3 downto 0); -- 数显管的驱动信号 flash :in std_logic; --数显管的闪烁信号 y:out std_Logic_vector(6 downto 0)); --数显管的输出 end component;
component mode_selection
port(mode_select:in std_logic; --模式选择
mode:buffer std_logic_vector(1 downto 0)); end component ;
component mode_led
port(clr :in std_logic; -- 清零信号( 开关 ) clk :in std_logic; --时钟信号
mode:in std_logic_vector(1 downto 0); --模式选择信号
led:out std_logic_vector(0 to 17); --流水灯的 显示
a1,a2,a3,a4,a5,a6,a7,a8: out std_logic_vector(3 downto 0)); --数显管的闪烁信号
end component ; begin
--设置由50MHZ分频得到1HZ时钟的映射 u1:clock_1hz
port map (clk_in=>clk_50m, clk_out=>clk_1hz); --设置由50MHZ分频得到125HZ时钟的映射 u2:clock_2hz
port map (clk_in=>clk_50m, clk_out=>flash); --设置自动/手动时钟选择的映射 u3:clk_selection
port map (clk_select =>clk_select,clk_1hz=>clk_1hz,clk_hand=>clk_hand,clk=>clk); -- 设置流水灯效果的映射 u4:mode_selection
port map(mode_select =>mode_select, mode=>mode); --设置流水灯模式选择的映射 u5:mode_led port
map(clr=>clr,clk=>clk,mode=>mode,led=>led,a1=>a1,a2=>a2,a3=>a3,a4=>a4,a5=>a5,a6=>a6,a7=>a7,a8=>a8); --设置数显管显示的映射 u6:led7s
port map(a=>a1,flash=>flash, y=>y1); --设置数显管显示的映射 u7:led7s
port map (a=>a2,y=>y2,flash=>flash); --设置数显管显示的映射 u8:led7s
port map (a=>a3,y=>y3,flash=>flash); --设置数显管显示的映射 u9:led7s
port map (a=>a4,y=>y4,flash=>flash); --设置数显管显示的映射 u10:led7s
port map (a=>a5,y=>y5,flash=>flash); --设置数显管显示的映射 u11:led7s
port map (a=>a6,y=>y6,flash=>flash); u12:led7s
port map (a=>a7,y=>y7,flash=>flash); --设置数显管显示的映射
u13:led7s
port map (a=>a8,y=>y8,flash=>flash); --u14:clock_125hz
--port map (clk_in =>clk_50m,clk_out =>clk_125hz);
end a;
(2)模块设计
1、1hz,2hz分频器的设计
本方案的设计思路是:设计一个计数器,其阀值为分频数的一半,每记到规定阀值的时候就溢出一个信号,再对此信号进行采集,当此信号处于上升沿触发时,就把输出信号翻转一次,从而达到设计的目的。 1hz分频器的程序: library ieee;
use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; entity clock_1hz is
port (clk_in:in std_logic; --50Mhz的时钟信号 clk_out:out std_logic); --1hz的方波信号 end clock_1hz;
architecture a of clock_1hz is signal full :std_logic;
signal cp1:integer range 0 to 25000000; begin
p1:process(clk_in) --此进程进行25000000分频 begin
if clk_in 'event and clk_in ='1' then if cp1<25000000 then cp1<=cp1+1; else cp1<=0; end if; end if;
if cp1=25000000 then full<='1'; else full<='0'; end if;
end process p1;
p2:process (full) -- 此进程设定了一个T触发器,对上一个进程的信号再进行2分频,得到1hz的时钟信号 variable cp2:std_logic; begin
if (full'event and full='1')then cp2:=not cp2; if (cp2='1')then clk_out<='1';
else
clk_out<='0'; end if ; end if ;
end process p2; end a;
2hz分频器的程序 library ieee;
use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; entity clock_2hz is
port( clk_in:in std_logic; --50Mhz的时钟信号 clk_out :out std_Logic); --2hz的方波信号 end clock_2hz;
architecture behave of clock_2hz is signal full :std_logic;
signal cp1:integer range 0 to 12500000; begin
p1:process(clk_in) --此进程进12500000分频
begin
if clk_in 'event and clk_in ='1' then if cp1<12500000 then cp1<=cp1+1; else cp1<=0; end if; end if;
if cp1=12500000 then full<='1'; else full<='0'; end if;
end process p1;
p2:process (full) -- -- 此进程设定了一个T触发器,对上一个进程的信号再进行2分频,得到2hz的时钟信号 variable cp2:std_logic; begin
if (full'event and full='1')then cp2:=not cp2; if (cp2='1')then clk_out<='1'; else
clk_out<='0'; end if ;
end if ;
end process p2; end behave;
2、时钟选择 设计方案:定义一个选通信号clk_select,当clk_select为高电平时,选通1hz的信号,当clk_select为低电平时,选通手动信号。 library ieee;
use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; entity clk_selection is
port(clk_select:in std_logic; --自动/手动时钟选择信号 clk_1hz:in std_logic; --1hz的方波信号 clk_hand:in std_logic; --手动时钟 clk:out std_logic); -- 时钟输出 end clk_selection;
architecture b of clk_selection is begin
process(clk_1hz,clk_select,clk_hand) --此进程是通过控制信号来选择手动/自
动的时钟信号
begin
if (clk_select='1')then clk<=clk_1hz; else
clk<=clk_hand; end if; end process; end b;
3、模式选择器
设计方案:设计一4进制计数器,分别对应着4种不同的流水灯方式,采用手动的信号控制,当检测到信号处于上升沿状态时,就执行程序,即加1. 模式控制器的程序: library ieee;
use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; entity mode_selection is
port(mode_select:in std_logic;
mode:out std_logic_vector(1 downto 0)); end mode_selection;
architecture c of mode_selection is
signal state :std_logic_vector(1 downto 0); begin
process(mode_select) --此进程为4种模式的选择 begin
if mode_select'event and mode_select ='1'then
state<=state+1; --mode_select 上升沿到来时,实现加1
end if;
end process; mode<=state; end c;
4、流水灯的实现
方案:采用状态机的方式,当处于某个状态时,对应于某个状态的输出,当加入时钟信号之后,状态机开始运行,这时就可以根据不同的状态的转换实现流水效果。
流水灯程序: library ieee;
use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; entity mode_led is
port(clr :in std_logic; --清零信号( 开关 ) clk :in std_logic; --时钟选择的输出
mode:in std_logic_vector(1 downto 0); --模式选择信号 led:out std_logic_vector(0 to 17); --流水灯的 显示
a1,a2,a3,a4,a5,a6,a7,a8: out std_logic_vector(3 downto 0) -- 数显管的驱动信号
); end mode_led;
architecture a of mode_led is
type states1 is (s0,s1,s2,s3,s4,s5); -- 自定义了四种枚举类型states1、states2、states3、states4
type states2 is (s0,s1,s2,s3,s4,s5);
type states3 is (s0,s1,s2,s3,s4,s5,s6,s7,s8,s9,s10,s11, s12,s13,s14,s15,s16,s17); type states4 is (s0,s1,s2,s3,s4,s5,s6,s7,s8,s9,s10,s11, s12,s13,s14,s15,s16,s17 ); signal state1 :states1; --状态机 signal state2 :states2; signal state3 :states3; signal state4 :states4;
begin
process(mode,clk,clr)
begin
if mode=\"00\" then --模式1 的状态机设置 if (clr='0')then --初始化状态 state1<=s0;
elsif(clk'event and clk='1')then
case state1 is
when s0 =>state1 <= s1; when s1 =>state1 <= s2; when s2 =>state1 <= s3; when s3 =>state1 <= s4; when s4 =>state1 <= s5; when s5 =>state1 <= s0; when others => state1 <=s0; end case; end if;
elsif mode=\"01\"then --模式2 的状态机设置
if (clr='0')then --初始化状态 state2<=s0;
elsif(clk'event and clk='1')then
case state2 is
when s0 =>state2 <= s1; when s1 =>state2 <= s2; when s2 =>state2 <= s3; when s3 =>state2 <= s4; when s4 =>state2 <= s5; when s5 =>state2 <= s0; when others => state2 <=s0; end case; end if;
elsif mode=\"10\"then --模式3 的状态机设置 if (clr='0')then --初始化状态 state3<=s0;
elsif (clk'event and clk ='1')then
case state3 is
when s0 =>state3 <= s1; when s1 =>state3 <= s2; when s2 =>state3 <= s3; when s3 =>state3 <= s4;
when s4 =>state3 <= s5; when s5 =>state3 <= s6; when s6 =>state3 <= s7; when s7 =>state3 <= s8; when s8 =>state3 <= s9; when s9 =>state3 <= s10; when s10 =>state3 <= s11; when s11 =>state3 <= s12; when s12 =>state3 <= s13; when s13 =>state3 <= s14; when s14 =>state3 <= s15; when s15 =>state3 <= s16; when s16 =>state3 <= s17; when s17 =>state3 <= s0; when others => state2 <=s0; end case ; end if;
elsif mode=\"11\" then if (clr='0')then state4<=s0;
elsif (clk'event and clk ='1')then
case state4 is
when s0 =>state4 <= s1; when s1 =>state4 <= s2; when s2 =>state4 <= s3; when s3 =>state4 <= s4; when s4 =>state4 <= s5; when s5 =>state4 <= s6; when s6 =>state4 <= s7; when s7 =>state4 <= s8; when s8 =>state4 <= s9; when s9 =>state4 <= s10; when s10 =>state4 <= s11; when s11 =>state4 <= s12; when s12 =>state4 <= s13; when s13 =>state4 <= s14; when s14 =>state4 <= s15; when s15 =>state4 <= s16; when s16 =>state4 <= s17; when s17 =>state4 <= s0; when others => state2 <=s0; end case ; end if;
--模式4 的状态机设置 --初始化状态 end if;
end process; process(clr,mode) begin
if(clr='0')then
led<=\"000000000000000000\"; --当CLR为低电平时,LED灯为全灭状态 a1<=\"1111\"; --当CLR为低电平时,把数码驱动信号全置为高电平,相当于把数显管的显示全置为1,即全灭状态 a2<=\"1111\"; a3<=\"1111\"; a4<=\"1111\"; a5<=\"1111\"; a6<=\"1111\"; a7<=\"1111\"; a8<=\"1111\";
else --当CLR为高电平时,开始实现流水灯方式 if mode=\"00\"then --模式1
a1<=\"0001\";a2<=\"0001\";a3<=\"0001\";a4<=\"0001\";a5<=\"0001\";a6<=\"0001\";a7<=\"0001\";a8<=\"0001\"; -- 数码管驱动为0001,数码管显示1 case state1 is
when s0 =>led<=\"000001000001000001\"; when s1 =>led<=\"000010000010000010\"; when s2 =>led<=\"000100000100000100\"; when s3 =>led<=\"001000001000001000\"; when s4 =>led<=\"010000010000010000\"; when s5 =>led<=\"100000100000100000\"; when others=>led <=\"000000000000000000\"; end case;
elsif mode=\"01\"then --模式2
a1<=\"0010\";a2<=\"0010\";a3<=\"0010\";a4<=\"0010\";a5<=\"0010\";a6<=\"0010\"; a7<=\"0010\";a8<=\"0010\"; -- 数码管驱动为0010,数码管显示2 case state2 is
when s0 =>led<=\"000001000001000001\"; when s1 =>led<=\"000011000011000011\"; when s2 =>led<=\"000111000111000111\"; when s3 =>led<=\"001111001111001111\"; when s4 =>led<=\"011111011111011111\"; when s5 =>led<=\"111111111111111111\"; when others=>led <=\"000000000000000000\"; end case;
elsif mode=\"10\"then --模式3
a1<=\"0011\";a2<=\"0011\";a3<=\"0011\";a4<=\"0011\";a5<=\"0011\";a6<=\"0011\";
a7<=\"0011\";a8<=\"0011\"; --数码管驱动为0011,数码管显示3 case state3 is
when s0 =>led<=\"000000000000000001\"; when s1 =>led<=\"000000000000000011\"; when s2 =>led<=\"000000000000000111\"; when s3 =>led<=\"000000000000001111\"; when s4 =>led<=\"000000000000011111\"; when s5 =>led<=\"000000000000111111\"; when s6 =>led<=\"000000000001111111\"; when s7 =>led<=\"000000000011111111\"; when s8 =>led<=\"000000000111111111\"; when s9 =>led<=\"000000001111111111\"; when s10=>led<=\"000000011111111111\"; when s11=>led<=\"000000111111111111\"; when s12=>led<=\"000001111111111111\"; when s13=>led<=\"000011111111111111\"; when s14=>led<=\"000111111111111111\"; when s15=>led<=\"001111111111111111\"; when s16=>led<=\"011111111111111111\"; when s17=>led<=\"111111111111111111\"; when others=>led<=\"000000000000000000\"; end case;
elsif mode=\"11\"then --模式4
a1<=\"0100\";a2<=\"0100\";a3<=\"0100\";a4<=\"0100\";a5<=\"0100\";a6<=\"0100\";a7<=\"0100\";a8<=\"0100\"; -- 数码管驱动为0100,数码管显示4 case state4 is
when s0 =>led<=\"000000001100000000\"; when s1 =>led<=\"000000011110000000\"; when s2 =>led<=\"000000111111000000\"; when s3 =>led<=\"000001111111100000\"; when s4 =>led<=\"000011111111110000\"; when s5 =>led<=\"000111111111111000\"; when s6 =>led<=\"001111111111111100\"; when s7 =>led<=\"011111111111111110\"; when s8 =>led<=\"111111111111111111\"; when s9 =>led<=\"011111111111111110\"; when s10=>led<=\"001111111111111100\"; when s11=>led<=\"000111111111111000\"; when s12=>led<=\"000011111111110000\"; when s13=>led<=\"000001111111100000\"; when s14=>led<=\"000000111111000000\"; when s15=>led<=\"000000011110000000\"; when s16=>led<=\"000000001100000000\";
when s17=>led<=\"000000000000000000\"; when others=>led<=\"000000000000000000\"; end case; end if; end if;
end process; end a;
5、数码管的驱动
方案:将输入用4位二进制数表示的BCD码转换成相应的数字输出。数码管的闪烁信号是从前面2hz信号输入的,可以设置闪烁信号为使能信号,当闪烁信号为低电平时,控制数显管的灭状态,当闪烁信号为高电平时,数码管开始工作,即开始显示不同的输出。 数码管的驱动的程序: library ieee;
use ieee.std_logic_1164.all; use ieee.std_Logic_unsigned.all; entity led7s is
port(a:in std_logic_vector(3 downto 0); -- 数显管的驱动信号 flash :in std_logic; --数显管的闪烁信号 y:out std_Logic_vector(6 downto 0)); --数显管的输出 end;
architecture h of led7s is begin
process(a,flash) begin
if flash ='0'then
y<=\"1111111\"; else
case a is
when \"0000\"=>y<=\"1000000\"; when \"0001\"=>y<=\"1111001\"; when \"0010\"=>y<=\"0100100\"; when \"0011\"=>y<=\"0110000\"; when \"0100\"=>y<=\"0011001\"; when \"0101\"=>y<=\"0010010\"; when \"0110\"=>y<=\"0000010\"; when \"0111\"=>y<=\"1111000\"; when \"1000\"=>y<=\"0000000\"; when \"1001\"=>y<=\"0010000\";
when \"1111\"=>y<=\"1111111\"; when others =>y<=\"1111111\"; end case;
end if;
end process; end h;
5、用quartus进行仿真
6、用modelsim进行仿真
7、用signaltap进行仿真
8、用DE2板进行程序的下载
9、RTL图
10、状态转换图
11、结束语:
对我们电子的同学来说,EDA是一门很有用的课程,FPGA是一项很有前途的技术,虽然EDA只是一门专业选修课,但其实他值得大家去付出努力去学好它,去掌握它,在短短的半个学期里面,大家通过EDA的学习也基本掌握了quartus、modelsim等软件的使用,也激起大家学习EDA的热情,希望以后大家以后可以不断超越自我,勇往直前。
在设计的过程中,在一个小组里面,有时候分歧还是很多的,因为其实每个的VHDL的写法,思路都有些不一样,但是在这个过程之中,也让大家学会如何处理这种团队的问题,怎样去把一个团队给捏合起来,所以总的来说,我觉得这是一次非常好的学习过程。
因篇幅问题不能全部显示,请点此查看更多更全内容