- UID
- 83441
- 性别
- 男
|
根据要求, 秒表的设计要有三个输入端:runstop,rst和clk.
runstop是开关, 按一下开始计时, 再按一下停止计时, 显示时间. 可以使用一个T触发器来实现. 当我们把T触发器的T端接高电平时, 它将实现翻转功能. 然后用输入端口runstop 来控制, 当runstop 被按一下, 一个时钟到来, T触发器就进行一次翻转. 我们也可以用D触发器来代替T触发器, 需要用一个反馈信号, 将输出的信号反馈到D端口.
Rst 是复位, 当按下rst 时, 秒表的显示变为0.
Clk是时钟, 实验中的时钟信号是250KHZ,为了实现秒表的正确计时功能, 需要进行2500分频. 所以clk首先就应该接到一个分频器, 然后再为其他模块提供时钟.
接着我们把秒表划分为以下几个模块:分频器, 计数器, T触发器, 扫描器, 八选一选择器, 七段译码器, 另外还有一个模块要在分, 秒和毫秒之间做一个划分(BAR).
计数器的功能是要实现毫秒,秒,分的计数,比较麻烦.我们再将它分成几个模块, 可以是六进制的计数器和十进制的计数器进行级联来实现.也可以是用100进制的计数器和60进制的计数器进行级联. 我两种方法都尝试了一下.发现后一种方法编程要复杂的多, 级联的时候可以稍微简单一些.
因为D触发器,八选一选择器是程序包里有的,所以可以不编.
把这些模块都编好了以后要做的就是把他们连在一起. 有两种方法. 一是用画图的方法, 二是用编程的方法, 用port map语句. 同样, 这两种方法我也都尝试了. 我觉得用画图的方法要简单一些.
1程序如下:
分频器:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity df is
port(clkin:in std_logic;
doutut std_logic);
end;
architecture behavioral of df is
begin
process(clkin)
variable df: std_logic_vector(7 downto 0):="00000000";
begin
if (clkin'event and clkin='1')then
if df/="11111010"
then df:=df+1;
else df:="00000001";
end if;
end if;
dout<=df(7);
end process;
end behavioral;
扫描器:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity scan is
port(clk:in std_logic;
sut std_logic_vector(2 downto 0));
end scan;
architecture behavioral of scan is
variable scan:std_logic_vector(2 downto 0);
begin
process(clk)
begin
if(clk'event and clk='1')then
scan:=scan+1;
end if;
s<=scan;
end process;
end behavioral;
七段译码器:
library ieee;
use ieee.std_logic_1164.all;
entity bcd is
port(o:in std_logic_vector(3 downto 0);
qut std_logic_vector(6 downto 0));
end bcd ;
architecture behavioral of bcd is
begin
process(o)
begin
case o is
when"0000"=>q<="0111111";
when"0001"=>q<="0000110";
when"0010"=>q<="1011011";
when"0011"=>q<="1001111";
when"0100"=>q<="1100110";
when"0101"=>q<="1101101";
when"0110"=>q<="1111101";
when"0111"=>q<="0100111";
when"1000"=>q<="1111111";
when"1001"=>q<="1101111";
when others=>q<="0000000";
end case;
end process;
end behavioral;
当然,以上的100进制和60进制计数器的设计过于复杂,可以由六进制和十进制的计数器级联代替,程序如下:
六进制:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity c6 is
port(countut std_logic_vector(3 downto 0);
coutut std_logic;
cin,rst,clk:in std_logic);
end c6;
architecture behavioral of c6 is
signal counter:std_logic_vector(2 downto 0);
begin
process(clk,rst)
begin
if rst='1'then
counter<="000";cout<='0';
elsif clk'event and clk='1' then
if cin='1' then
if counter="101"then
counter<="000";cout<='1';
else
counter<=counter+"001";
cout<='0';
end if;
end if;
end if;
end process;
count(2 downto 0)<=counter;
count(3)<='0';
end behavioral;
十进制:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity c10 is
port(countut std_logic_vector(3 downto 0);
coutut std_logic;
cin,rst,clk:in std_logic);
end c10;
architecture behavioral of c10 is
signal counter:std_logic_vector(3 downto 0);
begin
process(clk,rst)
begin
if rst='1'then
counter<="0000";cout<='0';
elsif clk'event and clk='1' then
if cin='1' then
if counter="1001"then
counter<="0000";cout<='1';
else
counter<=counter+"0001";
cout<='0';
end if;
end if;
end if;
end process;
count<=counter;
end behavioral;
最后用画图讲这些模块连接起来. |
|