----------------------------------------------------------
-- timer interrupt
-- xiaoyang@2011.4.18
----------------------------------------------------------
-- 7段显示码模块(共阴)
-- 最大公约数硬件
----------------------------------------------------------
-- 输入:clk,xin,yin;准备信号rdy;
-- 输出:digitron1七段显示码输出;state_out计算状态
----------------------------------------------------------
-- enable=0,ready=0载入数据
-- enable=1
-- ready=0,计算,正忙
-- ready=1,计算完毕,显示
-- state_out将显示ready的状态
----------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity gcd is
port(
clk: in std_logic;
xin: in std_logic_vector(5 downto 0);
yin: in std_logic_vector(5 downto 0);
enable: in std_logic;
digitron1 :out std_logic_vector(8 downto 0); --7 segment display
state_out :out boolean
);
end gcd;
architecture rt1 of gcd is
--for xin,yin
signal xx,yy : std_logic_vector(5 downto 0);
signal ready:boolean := true;--用来对loop计算最小公约数,计算完毕后设置over为true
constant num0 : std_logic_vector(5 downto 0) := "000000";
constant num1 : std_logic_vector(5 downto 0) := "000001";
constant num2 : std_logic_vector(5 downto 0) := "000010";
constant num3 : std_logic_vector(5 downto 0) := "000011";
constant num4 : std_logic_vector(5 downto 0) := "000100";
constant num5 : std_logic_vector(5 downto 0) := "000101";
constant num6 : std_logic_vector(5 downto 0) := "000110";
constant num7 : std_logic_vector(5 downto 0) := "000111";
constant num8 : std_logic_vector(5 downto 0) := "001000";
constant num9 : std_logic_vector(5 downto 0) := "001001";
begin
--p1 process for gcd calculate--
p1:process(clk)
variable tmpxx,tmpyy: std_logic_vector(5 downto 0);
begin
if(clk' event and clk='1')then
--在enable为高时计算数据或者显示结果
if(enable='1')then
--ready为true表示计算完成,显示结果
if(ready=true) then
case xx is
when num0 => digitron1<="000000000";--"111111000";--show:'0',code:[a-g-dp-com]=111111000
when num1 => digitron1<="000000001";--"000011000";--show:'1'
when num2 => digitron1<="000000010";--"110110100";--show:'2'
when num3 => digitron1<="000000011";--"111100100";--show:'3'
when num4 => digitron1<="000000100";--"011001100";--show:'4'
when num5 => digitron1<="000000101";--"101101100";--show:'5'
when num6 => digitron1<="000000110";--"101111100";--show:'6'
when num7 => digitron1<="000000111";--"111000000";--show:'7'
when num8 => digitron1<="000001001";--"111111100";--show:'8'
when num9 => digitron1<="000001010";--"111101100";--show:'9'
when others => digitron1<="111111111";--"000000100";--show:'-'
end case;
--ready为flase表示正在计算
else
--calculate
if(yy = num0)then--cal complete
ready <= true;
else
if(xx < yy)then
tmpxx := xx;
tmpyy := yy;
xx <= tmpyy;
yy <= tmpxx;
else
xx <= (xx-yy);
end if;
end if;
end if;
else
--在enable为低时载入数据xin,yin
xx <= xin;
yy <= num6;
--tmpxx <= num0;
if(xx < yy)then
tmpxx := xx;
xx <= yy;
yy <= tmpxx;
end if;
ready <= false;
end if;
--show stat
state_out <= ready;
end if;
end process p1;
end rt1;
题目是设计最大公约数硬件实现
求两个自然数最大公约数的专用处理器。计算完成后用七段译码器将结果显示出来。需要考虑如何输入这两个自然数,如有必要,可以预置一个自然数,另一个靠外部输入。
考虑到开发板的资源限制,设计中输出仅为一个七段显示码。即只能计算出最大公约数只有1位的一对数的。
由于VHDL的loop语句仅仅在仿真时有用,并不能综合,而初学者又容易进入软件设计中的“循环”的概念中,极容易犯错。VHDL是硬件描述语言,并没有循环的概念,主要描述是什么样的组合逻辑部分(运算),有什么样的存储单元(变量),以及怎么样的状态转换(State Machine)。一般来说,对于类似循环的计算逻辑,可以用start/enable之类的信号来控制你的逻辑部分(set),然后运算结束之后设定标志位(done/finish/ready)。
对于本实验来说也可以用状态机实现。逻辑会相对清晰。
模拟波形分析(1):0x04和0x06最大公约数
模拟波形分析(2):0x01和0x06最大公约数