一、实验题目:
功能实现:
1、具备3各车站的选择
2、可接受5元,1元的输入
3、可按照1元的输出找零
设计框图:
图1.1整体设计框图
设计要求:
1、 输入均以低电平有效,对于投币口,在一个时钟的上升沿扫描到一次低电平,表示投币一次,
2、 三个车站:2元 5元 7元
3、 找钱口输出一个脉冲代表找回1元
4、 系统在使用时应先按下所选车站后,在投币,其中系统自动判断投入钱的是否足够
二、实验过程:
为了简化实验,本实验采用了模块化设计。模块化的好处有:有利于设计的简便性,在设计过程中由于采用模块化,将每个模块相互独立开来,让设计思路更加明确。同时每一个模块都能独立测试,为仿真检错带来了方便。
在本次设计方案中,采用了三个子模块,分别是按键模块,车站模块,找零并行转串行输出模块。下面是每一个模块的设计方框图:
按键模块:
图2.1按键模块设计框图
车站模块:
图2.2车站模块设计框图
图2.3找零模块设计框图
1、 算法流程与程序设计:
按键模块设计:
程序设计:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
entity key is
port(clk:in std_logic;
rst:in std_logic;
key:in std_logic_vector(2 downto 0);
s0:out std_logic;
s1:out std_logic;
s2:out std_logic);
end entity;
architecture behav of key is
begin
process(clk,rst)
begin
if(rst='0') then
s0<='1';
s1<='1';
s2<='1';
else
case key is
when "011"=>
s0<='0';
s1<='1';
s2<='1';
when "101"=>
s0<='1';
s1<='0';
s2<='1';
when "110"=>
s0<='1';
s1<='1';
s2<='0';
when others=>
s0<='1';
s1<='1';
s2<='1';
end case;
end if;
end process;
end behav;
仿真波形:
仿真波形分析:
clk信号为时钟信号,产生时钟脉冲。rst为系统复位信号。低电平复位。fan信号用车站进程结束反馈信号。key分别为三个输入按键。s0,s1,s3分别选通车站的片选信号。
车站模块设计:每个车站的设计思想都是一样的。只是设计的状态机不一样。
车站一:收费2元;输入可能是两个1元,一个1元一个5元,一个5元:三种可能。
状态机设计流图:
程序设计如下:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
entity tran1 is
port(clk:in std_logic;
s:in std_logic;
x:in std_logic;
y:in std_logic;
chu1:out std_logic;
z1:out std_logic_vector(2 downto 0));
end entity;
architecture behav of tran1 is
type state is(s0,s1,s2);
signal present_state:state:=s0;
begin
process(clk,x,y,s)
begin
if clk'event and clk='1' then
case present_state is
when s0=>
if(s='0') then
chu1<='0';z1<="000";
present_state<=s1;
else
chu1<='0'; z1<="000"; present_state<=s0;
end if;
when s1=>
if(x='1') then
if(y='0') then
chu1<='1';
z1<="011"; ----找回3块钱
present_state<=s0;
else chu1<='0'; present_state<=s1;
end if;
else
chu1<='0'; present_state<=s2;
end if;
when s2=>
if(x='1') then
if(y='1') then
chu1<='0'; present_state<=s2;
else
chu1<='1';
z1<="100"; ----找回4块钱
present_state<=s0;
end if;
else chu1<='1';
z1<="000";
present_state<=s0;
end if;
end case;
end if;
end process;
end behav;仿真波形如下:
车站二:收费5元;输入可能是5个1元,or先输入n(0<=n<5)个1元和一个5元:6种可能。
状态机设计流程图如下:
程序设计如下:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
entity tran2 is
port(clk:in std_logic;
s:in std_logic;
x:in std_logic;
y:in std_logic;
chu2:out std_logic;
z2:out std_logic_vector(2 downto 0));
end entity;
architecture behav of tran2 is
type state is(s0,s1,s2,s3,s4,s5);
signal present_state:state:=s0;
begin
process(clk,x,y,s)
begin
if clk'event and clk='1' then
case present_state is
when s0=>
if(s='0') then
chu2<='0';z2<="000";
present_state<=s1;
else
chu2<='0'; z2<="000"; present_state<=s0;
end if;
when s1=>
if(x='1') then
if(y='1') then
chu2<='0';
z2<="000";
present_state<=s1;
else
chu2<='1';
z2<="000";
present_state<=s0;
end if;
else
chu2<='0'; z2<="000"; present_state<=s2;
end if;
when s2=>
if(x='1') then
if(y='1') then
chu2<='0';
z2<="000";
present_state<=s2;
else
chu2<='1';
z2<="001";
present_state<=s0;
end if;
else
chu2<='0';z2<="000"; present_state<=s3;
end if;
when s3=>
if(x='1') then
if(y='1') then
chu2<='0';
z2<="000";
present_state<=s3;
else
chu2<='1';
z2<="010";
present_state<=s0;
end if;
else
chu2<='0';z2<="000"; present_state<=s4;
end if;
when s4=>
if(x='1') then
if(y='1') then
chu2<='0';
z2<="000";
present_state<=s4;
else
chu2<='1';
z2<="011";
present_state<=s0;
end if;
else
chu2<='0';z2<="000"; present_state<=s5;
end if;
when s5=>
if(x='1') then
if(y='1') then
chu2<='0';
z2<="000";
present_state<=s5;
else
chu2<='1';
z2<="100";
present_state<=s0;
end if;
else
chu2<='1';z2<="000"; present_state<=s0;
end if;
end case;
end if;
end process;
end behav;
仿真波形如下:
车站三:收费7元:
程序设计如下:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
entity tran3 is
port(clk:in std_logic;
s:in std_logic;
x:in std_logic;
y:in std_logic;
chu3:out std_logic;
z3:out std_logic_vector(2 downto 0));
end entity;
architecture behav of tran3 is
type state is(s0,s1,s2,s3,s4,s5,s6,s7,m0);
signal present_state:state:=s0;
begin
qian: process(clk,x,y,s)
begin
if clk'event and clk='1' then
case present_state is
when s0=>
if(s='0') then
chu3<='0';z3<="000";
present_state<=s1;
else
chu3<='0'; z3<="000"; present_state<=s0;
end if;
when s1=>
if(x='1') then
if(y='1') then
chu3<='0'; z3<="000";
present_state<=s1;
else chu3<='0'; z3<="000"; present_state<=m0;
end if;
else
chu3<='0'; z3<="000"; present_state<=s2;
end if;
when s2=>
if(x='1') then
if(y='1') then
chu3<='0'; z3<="000"; present_state<=s2;
else
chu3<='0'; z3<="000"; present_state<=s7;
end if;
else
chu3<='0'; z3<="000"; present_state<=s3;
end if;
when s3=>
if(x='1') then
if(y='1') then
chu3<='0'; z3<="000"; present_state<=s3;
else
chu3<='1';
z3<="000";
present_state<=s0;
end if;
else
chu3<='0'; z3<="000"; present_state<=s4;
end if;
when s4=>
if(x='1') then
if(y='1') then
chu3<='0'; z3<="000"; present_state<=s4;
else
chu3<='1';
z3<="001";
present_state<=s0;
end if;
else
chu3<='0'; z3<="000"; present_state<=s5;
end if;
when s5=>
if(x='1') then
if(y='1') then
chu3<='0'; z3<="000"; present_state<=s5;
else
chu3<='1';
z3<="010";
present_state<=s0;
end if;
else
chu3<='0'; z3<="000"; present_state<=s6;
end if;
when s6=>
if(x='1') then
if(y='1') then
chu3<='0'; z3<="000"; present_state<=s6;
else
chu3<='1';
z3<="011";
present_state<=s0;
end if;
else
chu3<='0'; z3<="000"; present_state<=s7;
end if;
when s7=>
if(x='1') then
if(y='1') then
chu3<='0'; z3<="000"; present_state<=s7;
else
chu3<='1';
z3<="100";
present_state<=s0;
end if;
else
chu3<='1';
z3<="000";
present_state<=s0;
end if;
when m0=>
if(x='1') then
if(y='1') then
chu3<='0'; z3<="000"; present_state<=m0;
else
chu3<='1';
z3<="011";
present_state<=s0;
end if;
else
chu3<='0'; z3<="000"; present_state<=s7;
end if;
when others=>
chu3<='0';
z3<="000";
end case;
end if;
end process;
end behav;
找零并行转串行脉冲输出模块:输入信号为3位并行信号,输出为串行脉冲信号。
状态机设计:
程序设计:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
entity change is
port(clk,send:in std_logic;
d_in:in std_logic_vector(2 downto 0);
y:out std_logic:='0');
end entity;
architecture behav of change is
type state is(s0,s1);
signal reg:std_logic_vector(0 to 7);
begin
process(clk,send,d_in)
variable present_state:state;
variable cnt:integer range 0 to 8:=0;
variable count:integer range 0 to 5:=0;
variable sign:integer range 0 to 1:=0;
begin
if(clk'event and clk='1') then
case present_state is
when s0=>
cnt:=0;
sign:=0;
y<='0';
reg<=(others=>'0');
if(send='1') then
if(d_in="100") then
reg<="10101010";
elsif(d_in="011") then
reg<="10101000";
elsif(d_in="010") then
reg<="10100000";
elsif(d_in="001") then
reg<="10000000";
end if;
present_state:=s1;
else
present_state:=s0;
end if;
when s1=>
if(sign=0) then
y<='0';
sign:=1;
present_state:=s1;
else
if(cnt<8) then
if(reg(cnt)='0') then
y<='0';
cnt:=cnt+1;
present_state:=s1;
elsif(reg(cnt)='1') then
y<='1';
cnt:=cnt+1;
present_state:=s1;
end if;
else
present_state:=s0;
end if;
end if;
end case;
end if;
end process;
end behav;
仿真运行结果:
综合设计
图形化设计:
仿真波形图:
仿真分析:key0选通车站3,y投入两个5元,change3找回零钱3元,out3出票一张。key1选通车站2,x投入1元,y投入5元,change2找回零钱1元,out2出票一张。Key2选通车站1,y投入5元,change1找回零钱3元,out1出票一张。
实验总结:啊。又完成了一次对自己的超越。好开心。一直以来自己的编程能力都是一般般,但是这次的程序基本上都是自己设计完成的。发现状态机真的是化腐朽为神奇,特别是在设计找零钱这一个模块上。开始接触VHDL的时候,听说他是并行的,速度快,挺不错。但是现在编程才发现,并行的同时也意味着程序的无序性。这是个相当纠结的问题。好在还有状态机,将原来并行的无序性治的服服帖帖。感觉两次作业都是一次对自己的飞跃性的超越,第一次作业是一次对自己从不懂到懂的一个过程的超越。而第二次作业时一次对自己从局部到整体的一个过程的超越。在这次作业中,自己不但能够独立的设计程序的同时,更加深的一层的熟悉了软件的开发环境,学会了利用图形化设计的工具,学会了模块化设计,掌握了一个工程如何构架,如何分工,如何实现的开发过程,特别是在模块化设计的同时,深深体会到一个工程可以分割成多个子模块进行同步设计,这样的话一个团队工作可以共同进行,同时也加快了工程的设计进度,同时也减轻了程序的繁杂,化繁为简,有利于工程的顺利进行,体现了团队合作的精神。感觉这也是每一个工程师的必走之路。希望以后再接再厉,不断超越自我。
主要遇到的问题:
问题1:并行程序的并行性和无序性。在设计程序的时候这个问题是相当郁闷,后来利用状态机搞掂了这个问题。
问题2:error(10028):can't resolve multiple constant drivers for net
在可逆计数器的设计中的错误,两个进程里都有同一个条件判断的话,会产生并行信号冲突的问题。 同一个信号不允许在多个进程中赋值,否则则为多驱动。 进程的并行性决定了多进程不同能对同一个对象进行赋值。
原本以为可以将每一个找零钱的端口都连接在一起。但是却发现怎么也行不通,当初在这个地方纠结了好一阵。后来就直接放弃了。将每一个找零的口都分别接出来。再后来利用波形仿真的时候才发现,这是根本行不通的。如下图: change3和change2冲突了。 问题3:系统的bug,原本设计的时候在系统框图上设计了一个反馈信号,用于等完成一次才能选择下一个车站。但是后来感觉不用反馈信号也能完成功能。所以程序设计的时候没有加上去。现在想想这里应该是系统的一个bug,应用到实际中,不加反馈信号好像是会有一些意想不到的问题出现 |
文章评论(0条评论)
登录后参与讨论