题目要求:
(1)设计10以内的加减法计算器。
(2)1个按键用于指定加法或减法,一个用于指定加数或被加数,还有两个分别控制加数或被加数的增加或减少。
(3)设置的结果和计算的结果用数码管显示。
本实验我还是将其视作Mealy型向量机,具体的见我之前关于秒表的内容:VHDL实验:基于有限状态机实现秒表
按照题目意思,有4个键是必不可少的,但我还是决定增加两个推键,本实验状态图如下:
S0:初态模式,所有数码管置零
S1:计算模式,等待用户设置并计算
这两者之间的转换我用开发板上的推键来完成。
另一个推键指示是进行整数运算还是一位小数。
我的代码:(抱歉注释是全英文的)
library ieee ;
use ieee.std_logic_1164.all ;
use ieee.std_logic_unsigned.all ;
use ieee.std_logic_arith.all ;entity Computer isport (key3 : in std_logic ; -- is addition or subtraction?key2 : in std_logic ; -- who is augend or minuend?key1 : in std_logic ; -- change the value of augend or minuendkey0 : in std_logic ; -- change the value of addend or subtrahendsw0 : in std_logic ; -- change the state of circuitsw1 : in std_logic ;first1 : out std_logic_vector(0 to 6) ;first2 : out std_logic_vector(0 to 6) ;second1 : out std_logic_vector(0 to 6) ;second2 : out std_logic_vector(0 to 6) ;negative : out std_logic_vector(0 to 6) ; -- Is the result a negative number?empty : out std_logic_vector(0 to 6) ;result1 : out std_logic_vector(0 to 6) ; -- the result of computingresult2 : out std_logic_vector(0 to 6) ; -- the result of computingPoint : out std_logic_vector(7 downto 0) ; -- Radix pointledg8 : out std_logic ; -- if substractionledr16 : out std_logic ; -- it is augend or minuendledr13 : out std_logic -- it is augend or minuend) ;
end Computer ;architecture mathematic of Computer isconstant matrix_num : integer := 9 ;TYPE Number is array (0 to matrix_num) of std_logic_vector(0 to 6);signal Display : Number := (('0', '0', '0', '0', '0', '0', '1'), -- 0('1', '0', '0', '1', '1', '1', '1'), -- 1('0', '0', '1', '0', '0', '1', '0'), -- 2('0', '0', '0', '0', '1', '1', '0'), -- 3('1', '0', '0', '1', '1', '0', '0'), -- 4('0', '1', '0', '0', '1', '0', '0'), -- 5('0', '1', '0', '0', '0', '0', '0'), -- 6('0', '0', '0', '1', '1', '1', '1'), -- 7('0', '0', '0', '0', '0', '0', '0'), -- 8('0', '0', '0', '0', '1', '0', '0') -- 9) ;TYPE state_type is (s0, s1) ; -- how many states does the circuit have?signal current_state : state_type ;-- all of them below are middle datasignal neg : std_logic_vector(0 to 6) := ('1', '1', '1', '1', '1', '1', '1') ;signal led8 : std_logic ; signal led16 : std_logic ; signal led13 : std_logic ;signal p : std_logic_vector(7 downto 0) ;
beginprocess(sw0) -- to change the state of circuitbeginif (sw0 = '0') thencurrent_state <= s0 ;elsecurrent_state <= s1 ;end if ;end process ;process(current_state, key3, key2, key1, key0, sw1) -- take action according to statevariable First : integer := 0 ;variable Second : integer := 0 ;variable Result : integer := 0 ;variable num3 : integer := 0 ;variable num2 : integer := 0 ;beginif (current_state = s0) thenFirst := 0 ;Second:= 0 ;Result:= 0 ;num3 := 0 ;num2 := 0 ;neg <= ('1', '1', '1', '1', '1', '1', '1') ; p <= ('1', '1', '1', '1', '1', '1', '1', '1') ;led8 <= '0' ;led16 <= '0' ; led13 <= '0' ;elsif (current_state = s1) thenif (sw1 = '1') then -- make sure integer or floatp <= ('0', '1', '0', '1', '1', '1', '0', '1') ;else p <= ('1', '1', '1', '1', '1', '1', '1', '1') ;end if ;if falling_edge(key2) then -- make sure who is augend or minuend?num2 := num2 + 1 ;end if ;if ((num2 > 0) and(num2 MOD 2 = 0)) thenled16 <= '0' ;led13 <= '1' ;elsif (num2 MOD 2 = 1) thenled16 <= '1' ;led13 <= '0' ;end if ;if falling_edge(key1) then -- decide the value of first numberFirst := First + 1 ;if (First > 10) thenFirst := 0 ;end if ;end if ;if falling_edge(key0) then -- decide the value of second numberSecond := Second + 1 ;if (Second > 10) thenSecond := 0 ;end if ;end if ;if falling_edge(key3) thennum3 := num3 + 1 ;end if ;if (num3 MOD 2 = 1) thenled8 <= '0' ;neg(6) <= '1' ;Result := First + Second ;elsif ((num3>0) and (num3 MOD 2 = 0)) thenled8 <= '1' ;if (led13 = '1') thenif (Second < first) thenneg(6) <= '0' ;Result := First - Second ;elseneg(6) <= '1' ;Result := Second - First ;end if ;elsif (led16 = '1') thenif (first < Second) thenneg(6) <= '0' ;Result := Second - First ;elseneg(6) <= '1' ;Result := First - Second ;end if ;end if ;end if ;end if ;empty <= ('1', '1', '1', '1', '1', '1', '1') ;first1 <= Display(First/10) ;first2 <= Display(First MOD 10) ;second1 <= Display(Second/10) ;second2 <= Display(Second MOD 10) ;negative <= neg ;result1 <= Display(Result/10) ;result2 <= Display(Result MOD 10);Point <= p ;ledg8 <= led8 ;ledr16 <= led16 ;ledr13 <= led13 ;end process ;
end mathematic ;