引言:设计图像部分同学们重新画一下,要求横平竖直不要出现曲线,导线链接方向尽量变一下,不要提我的名 就说在网上看的
代码可以直接复制到运行环境里,作报告的时候记得删除注释!!!
①数字时钟
通过三组二位运算器(由两个一位数组成)模拟时钟运行模式
我们通过代码就可以很简单地理解这个程序 ↓↓↓↓↓↓↓↓
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity abc is
port (clk :in bit;
sgewei :out std_logic_vector(3 downto 0); --定义6个输出实体和时钟脉冲
sshiwei :out std_logic_vector(2 downto 0); --只有输出实体才能对外输出,输出实体不能被直接赋值
mgewei :out std_logic_vector(3 downto 0); --下面会定义成员变量来对输出实体赋值
mshiwei :out std_logic_vector(2 downto 0);
hgewei :out std_logic_vector(3 downto 0);
hshiwei :out std_logic_vector(1 downto 0));
end;
architecture abcd of abc is --定义6个成员变量对实体赋值
signal sge :std_logic_vector(3 downto 0); --秒钟个位计数器
signal sshi :std_logic_vector(2 downto 0); --秒钟十位计数器
signal mge :std_logic_vector(3 downto 0); --分钟个位计数器
signal mshi :std_logic_vector(2 downto 0); --分钟十位计数器
signal hge :std_logic_vector(3 downto 0); --小时个位计数器
signal hshi :std_logic_vector(1 downto 0); --小时十位计数器
begin
process(clk)
begin
if(clk' event and clk='1')then --时钟脉冲为上升沿并且为高电平时触发以下所有if
if sge (3 downto 0)=9 then --当秒钟个位为9时秒钟十位+1,秒钟个位归零
sge (3 downto 0)<="0000"; --也就是00:00:09 跳成 00:00:10
sshi (2 downto 0)<=sshi (2 downto 0)+1;
elsif (sshi = 6)then --当秒钟十位为6时秒钟个位十位全部归零
sge (3 downto 0)<="0000"; --且分钟秒为+1 //其实这里应该判断个位9十位
sshi (2 downto 0)<="000"; //但是vhdl语言语法不太熟练这么写报错
mge (3 downto 0)<=mge (3 downto 0)+1; --等同于00:00:59 跳到 00:01:00
else
sge (3 downto 0)<=sge (3 downto 0)+1; --当以上条件均不符合则秒钟个位+1
if mge (3 downto 0)=9 then --分钟部分
mge (3 downto 0)<="0000";
mshi (2 downto 0)<=mshi (2 downto 0)+1;
elsif (mge = 9 and mshi =5)then --分钟这里和秒钟逻辑一样,这里不过多赘述
mge (3 downto 0)<="0000"; --唯一区别就是没有秒钟+1这一步
mshi (2 downto 0)<="000";
sge (3 downto 0)<=sge (3 downto 0)+1;
if hge (3 downto 0)=9 then
hge (3 downto 0)<="0000";
hshi (1 downto 0)<=hshi (1 downto 0)+1;
elsif (hge = 4 and hshi =2)then --当小时个位等于4,分位等于2则所有变量全部归零
hge (3 downto 0)<="0000"; --模拟24过去了
hshi (1 downto 0)<="00"; --//其实这里也应该判断 23:59:59
sge(3 downto 0)<="0000"; --23:59:59 跳到 00:00:00
sshi (2 downto 0)<="000";
mge (3 downto 0)<="0000";
mshi (2 downto 0)<="000";
end if;
end if;
end if;
end if;
end process;
sgewei (3 downto 0)<=sge(3 downto 0); --这里就是成员变量赋值给输出实体
sshiwei(2 downto 0)<=sshi (2 downto 0); --以便输出给EDA试验箱
mgewei(3 downto 0)<=mge(3 downto 0);
mshiwei(2 downto 0)<=mshi(2 downto 0);
hgewei(3 downto 0)<=hge(3 downto 0);
hshiwei(1 downto 0)<=hshi(1 downto 0);
end;
这个程序非常简单,把时钟00:00:00 这六个数字三个为一组,每组都为两个独立的个位运算器组成 同学们在下面波形图也可以清晰地理解程序运行方式
00:00:59 → 00:01:00 00:59:59 → 01:00:00 23:59:59 → 00:00:00
数字钟设计总体框图如下
引脚图如下
实验效果截图
编译成功截图
②电梯控制系统
这个系统比起时钟来说稍微复杂一点,if判断稍微有一点点多,同学们尽量理解下这里面的if逻辑 联系波形图一起看这个程序就会非常简单了
整个电梯系统大体规则如下:
输入只有呼叫电梯上升和呼叫电梯下降 (可以看成外面呼叫电梯的两个按钮)
输出只有开门状态,关门状态,上升状态,下降状态
当呼叫电梯上升为高电平 1 时,先开门等待下一次脉冲在关门(模拟行人上电梯)当门关闭也就是关门状态为0 低电平时 电梯上升状态为高电平 1 当电梯到达时(呼叫电梯信号为低电平)重复开门关门操作。
呼叫电梯下降同上
当呼叫电梯上升和呼叫电梯下降同为低电平0时则清除所有输出信号
以下为代码部分
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity dianti is
port(clk :in bit; --定义时钟脉冲
shangsheng: in std_logic; --上升输入逻辑信号,可以理解为电梯上行按钮
xiajiang: in std_logic; --下降输入逻辑信号,可以理解为电梯下行按钮
dopen: out std_logic; --开门状态输出指示逻辑信号 以下四个输出信号需要逻辑变量赋值
dclose: out std_logic; --关门状态输出指示逻辑信号
dshangsheng: out std_logic; --上升状态输出指示逻辑信号
dxiajiang: out std_logic); --下降状态输出指示逻辑信号
--请同学们记住这几个实体,下面我将不再详细描述,以免你们弄混
end entity dianti ;
architecture haveatry of dianti is
signal a1,b1:std_logic; --a1 开门状态输出指示信号 b1 上升状态输出指示信号
signal a2,b2,flag: std_logic; --a2 关门状态输出指示信号 b2 下降状态输出指示信号
begin
process(clk,shangsheng,xiajiang) --这里是调用实体以便下面if块使用
begin
if(clk' event and clk='1')then
if(shangsheng = '0' and xiajiang = '0')then--当电梯没有上升或下降输入信号所有指示信号为地电平
a1<='0'; --模拟没人叫电梯所有指示灯归零
a2<='0';
b1<='0';
b2<='0';
end if; --以下部分1均为高电平,0为低电平
if (shangsheng = '1' and xiajiang = '0' and a2='0' and b1 = '0') then
a1<='1'; --当上升=1 下降=0 门关闭状态 不处于下降状态 则开门
end if;
if (shangsheng = '1' and xiajiang = '0') then --当上升=1 下降=0时则运行下一个if
if (a1='1' and a2='0' ) then --当门开启时 经过一个时钟脉冲后关门
a1<='0';
a2<='1';
end if;
end if;
if (a2='1' and a1='0' and shangsheng = '1') then --当门处于关闭状态 门没开启 有上升信号时
a2<='0';
b1<='1'; --电梯上升
end if;
---------------------------------------------------------
if (xiajiang = '1' and shangsheng = '0' and a2='0' and b2 = '0') then
a1<='1'; --下降也与上升同理这里不过多赘述
end if;
if (xiajiang = '1' and shangsheng = '0' ) then
if(a1='1' and a2='0') then
a1<='0';
a2<='1';
end if;
end if;
if (a2='1' and a1='0' and xiajiang = '1') then
a2<='0';
b2<='1';
end if;
end if;
end process; --成员变量赋值
dopen<=a1;
dclose<=a2; --a1 开门 b1 上升
dshangsheng<=b1; --a2 关门 b2 下降
dxiajiang<=b2;
end;
总体框图如下(网上找的电梯中控图,老师说尽量复杂点最后可以和程序不一样 //别问,问就是一开始就想这么做结果没做出来)
引脚图如下
波形图如下,我会在波形图里解释系统运行逻辑
编译结果如下
③数字波形产生器
这个我没有太理解,上面那俩都是自己做的所以能解释出来这个跟着书上做的,只做了一个方波产生器 就知道方波是如何产生的,这里就不详细介绍
大概思路就是一个八位运算器初始值是00000000然后有一个输出q模拟波形
每一次时钟脉冲八位运算器就会+1 使00000000 趋向于 111111111然后归零
当00000000时a为低电平波形为____________
当00000000变成11111111时a输出高电平———————— 八位寄存器归零 00000000
当00000000再次变成11111111时a输出低电平 这样我们就能得到一个方波 我来用波形图帮助同学们理解以下这个过程
代码如下
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity square is
port(clk,clr:in std_logic;
q:out std_logic_vector(7 downto 0));
end square;
architecture art of square is
signal a:std_logic;
begin
process(clk,clr)
variable tmp:std_logic_vector(7 downto 0);
begin
if clr='0' then
a<='0';
elsif rising_edge(clk) then
if tmp="11111111" then tmp:="00000000";
els
tmp:=tmp+1;
end if;
if tmp<"10000000" then
a<='1';
else
a<='0';
end if;
end if;
end process;
process(clk,a)
begin
if rising_edge(clk) then
if a='1' then
q<="11111111";
else
q<="00000000";
end if;
end if;
end process;
end art;
波形图如下
编译成功如下
总框图如下
引脚截图如下