cal.vhd

来自「用VHDL语言实现通用计算器设计」· VHDL 代码 · 共 347 行

VHD
347
字号
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;

entity cal is
	port(
    --inclk
	clk: in std_logic;
	num:   in std_logic_vector(9 downto 0);
	plus:  in std_logic;
	subt:  in std_logic;
    mult:  in std_logic;
    mdiv:  in std_logic;
    equal: in std_logic;
    c:     in std_logic;
    onum1,onum2,onum3: out std_logic_vector( 0 to 6)
    ---
     --clk:  inout std_logic

	);
end cal;

architecture c of cal is
--194
type state is (takenum,hundred,ten,one);

signal viewstep:state;
signal ktemp:std_logic_vector(7 downto 0);
signal flag: std_logic;
signal f1:   std_logic;
signal acc:  std_logic_vector(7 downto 0);
signal reg:  std_logic_vector(7 downto 0);
signal keep: std_logic_vector(7 downto 0);
signal ans:  std_logic_vector(7 downto 0);
signal dans: std_logic_vector(3 downto 0);
signal numbuff :std_logic_vector(3 downto 0);
signal vf:   std_logic;
signal strdiv: std_logic;
signal numclk: std_logic;
signal clear:  std_logic;
--195
signal inplus: std_logic;
signal insubt: std_logic;
signal inmult: std_logic;
signal inmdiv: std_logic;
signal inequal: std_logic;
signal view1,view2,view3 : std_logic_vector( 3 downto 0);
signal cou : std_logic_vector(1 downto 0);
signal clk_gg: std_logic_vector(11 downto 0);
--signal clk:   std_logic;

component numdecoder is
 port(
      reset: in std_logic;
      inclk: in std_logic;
      innum: in std_logic_vector(9 downto 0);
      outnum: buffer std_logic_vector(3 downto 0);
      outflag : out std_logic
);
end component;

component vdecode is
port(
indata: in std_logic_vector (3 downto 0);
outdata:out std_logic_vector(0 to 6)

);
end component;

component div is
port(
a: in std_logic_vector(7 downto 0);
b: in std_logic_vector(3 downto 0);
clk: in std_logic;
str: in std_logic;
s : out std_logic_vector(3 downto 0);
y : out std_logic_vector(3 downto 0)
);
end component;

--196
begin

inum1:numdecoder port map(c,clk,num,numbuff,numclk);

--clock:process(inclk,c)
--begin
--if c='1' then
 --clk_gg(11 downto 0)<="0";
--elsif inclk'event and inclk='1' then
-- clk_gg(11 downto 0)<=clk_gg(11 downto 0)+1;
--end if;
--end process clock;

--clk<=clk_gg(11);

pacecal:process(c,clk)
begin
if c='1' then
inplus<='0';
insubt<='0';
inmult<='0';
inmdiv<='0';
elsif clk'event and clk='1' then
	if plus='1' then
--197
inplus<='1';
insubt<='0';
inmult<='0';
inmdiv<='0';
   	elsif subt='1' then
   	inplus<='0';
	insubt<='1';
	inmult<='0';
	inmdiv<='0';
	elsif mult='1' then
	inplus<='0';
	insubt<='0';
	inmult<='1';
	inmdiv<='0';
	elsif mdiv='1' then
	inplus<='0';
	insubt<='0';
	inmult<='0';
	inmdiv<='1';
	end if;
    end if;
end process pacecal;

ctrflag: process(c,clk)

begin
if c='1' then
flag<='0';
elsif clk'event and clk='1' then
	if inplus ='1' or insubt='1' or inmult='1' or inmdiv ='1' then
	flag<='1';
	else flag<='0';
	end if;

end if;
end process ctrflag;

ctrfirstnum:process(c,numclk)
begin
if c='1' then
acc<="00000000";
--198
elsif numclk'event and numclk='0' then
	if flag='0' then
    acc<=acc*"1010"+numbuff;
     end if;
end if;
end process ctrfirstnum;

ctrsecondnum :process(c,numclk)
begin
if c='1' or clear='1' then
reg<="00000000";
f1<='0';
elsif numclk'event and numclk='0' then
	if flag='1' then
	f1<='1';
	reg<=reg*"1010"+numbuff;
	end if;
end if;
end process ctrsecondnum;

ctrclear:process(c,clk)
begin
if c='1' then
clear<='0';
elsif clk'event and clk='1' then
	if plus='1' or subt='1' then
	clear<='1';
	else clear<='0';
	end if;
end if;
end process ctrclear;
--199
ctrinequal:process(c,clk)
begin
if c='1' then
inequal<='0';
elsif clk'event and clk='1' then
	if plus ='1' or subt='1' or mult='1' or equal='1' then
    inequal<='1';
	else inequal<='0';

    end if;
end if;

end process ctrinequal;

ctrcou:process(c,inequal)
begin
if c='1' then
cou<="00";
elsif inequal'event and inequal='1' then
	if cou="10" then
	cou<=cou;
	else cou<=cou+1;
	end if;
end if;
end process ctrcou;

--200
ctrcal:process(c,inequal)
begin
if c='1' then
ans<="00000000";
strdiv<='0';
elsif inequal'event and inequal='1' then
	if flag='1' then
    	if inplus='1' then
		if cou="10" then
		ans<=ans+reg;
		else ans<=acc+reg;
		end if;
		elsif insubt='1' then
		if cou="10" then
        ans<=ans-reg;
        else ans<=acc-reg;
		end if;
        elsif inmult='1' then
        if acc<="00001111" and reg<="00001111" then
 		ans<=acc(3 downto 0)*reg(3 downto 0);
		else ans<="00000000";
        end if;
        elsif inmdiv='1' then
 		strdiv<='1';
		end if;
		else strdiv<='0';
		end if;
    end if;
end process ctrcal;

--201
d1:div port map(acc,reg(3 downto 0),clk,strdiv,dans);
ctrvf:process(c,equal)
begin
if c='1' then
vf<='0';
--elsif equal'event and equal='1' then
--vf<='0';
elsif equal'event and equal='1' then
vf<='1';
end if;
end process ctrvf;

ctrkeep:process(c,clk)
begin
if c='1' then
keep<="00000000";
elsif clk'event and clk='0' then
	if flag='0' then
	keep<=acc;
-----?????
	elsif flag='1' and f1='1' and vf='0' then
	keep<=reg;
	elsif flag='1' and f1='0' and vf='0' and cou="10" then
	keep<=ans;
	elsif flag='1' and vf='1' then
    if inmdiv='0' then
    keep<=ans;
	else
	keep(3 downto 0)<=dans;
	end if;
    end if;
end if;
end process ctrkeep;

--202
ctrview: process(c,clk)
begin
if c='1' then
view1<="0000";
view2<="0000";
view3<="0000";
---何处改变viewstep
viewstep<=takenum;
--viewstep<=ten;
elsif clk'event and clk='1' then

case viewstep is
when takenum=>
	ktemp<=keep;
	viewstep<=hundred;
when hundred=>
	if ktemp>="11001000" then
	view1<="0010";
	ktemp<=ktemp-"11001000";
	elsif ktemp>="01100100" then
	view1<="0001";
	ktemp<=ktemp-"01100100";
	else view1<="0000";
	end if;
viewstep<=ten;
--203
when ten=>
if ktemp>="01011010" then
view2<="1001";
ktemp<=ktemp-"01011010";
elsif ktemp>="01010000" then 
view2<="1000";
ktemp<=ktemp-"01010000";
elsif ktemp>="01000110" then
view2<="0111";
ktemp<=ktemp-"01000110";
elsif ktemp>="00110010" then
view2<="0101";
ktemp<=ktemp-"00110010";

elsif ktemp>="00101000" then
view2<="0100";
ktemp<=ktemp-"00101000";

elsif ktemp>="00011110" then
view2<="0011";
ktemp<=ktemp-"00011110";

elsif ktemp>="00010100" then
view2<="0010";
ktemp<=ktemp-"00010100";

elsif ktemp>="00001010" then
view2<="0001";
ktemp<=ktemp-"00001010";
else view2<="0000";
end if;
viewstep<=one;

when one =>
view3<=ktemp(3 downto 0);
viewstep<=takenum;
when others => null;
end case ;
end if;

end process ctrview;
v1:vdecode port map(view1,onum1);
v2:vdecode port map(view2,onum2);
v3:vdecode port map(view3,onum3);
end c;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?