这两天一直在做VHDL大作业,先是写了大作业的基础部分-时钟,这部分还是比较简单的,主要是写两个事情,一个是数码管的驱动,一个是时钟高雅的二十四进制和六十进制。
先说数码管的驱动,分为两部分,一部分是译码,另一部分是扫描。译码部分是把数字译码成七段数码管的七位寄存器。由于是低电平有效,根据数码管的排列,很容易得出0000=>1000000,0001=>1110011…扫描部分稍微复杂,原理是将一个数码管的七段输入对应一个译码部分的输出,共6个。然后每个时钟周期选中1个数码管,将其置低电平使其被点亮,循环往复,只要循环的足够快,人眼看起来就是六位数码管都显示其数值。
二十四进制与六十进制比较简单,都是用两个十进制计数器组成。以二十四进制计数器为例,第一个十进制计数器内部有两个计时信号,第一个计时信号是逢十返零进一,第二个计时信号是逢二十四返零,同时将计时信号一置零并进一。计时器一的进位信号作为第二个十进制计数器的时钟信号,第二个十进制计数器改成逢三返零进一。最后将秒计数器的进位输出作为分计数器时钟,将分计数器的进位输出作为秒计数器时钟,将时分秒的输出作为六个译码器输入,将六个译码器输出接扫描部分输入即可。
比较神奇的是,在写分频器的时候,计数器忘了写返回0的的语句,但仍能分频,占空比为25/64,照理这样的错误应该是无法实现分频的,为什么会出现这样的情况不得而知。错误的代码如下:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity clk_1hz is
port( clk:in std_logic;
clk_out:out std_logic);
end clk_1hz;
architecture behav of clk_1hz is
begin
process(clk)
variable temp:integer range 0 to 50000000;
begin
if clk'event and clk='1' then
temp:=temp + 1;
if temp>=25000000 then
clk_out<='0';
else clk_out<='1';
end if;
end if;
end process;
end behav;
总体唯一的问题是数码管的小数点部分没有点亮,后面还要完成许多功能,所以在往后的代码中再加入。