VHDL设计——10位计算器

设计一个10位计算器(+,-,*,/),要有BCD码转换,共阴极LED笔画显示部分实现。
输入:A,B:XXXXXXXXXX(10位二进制数),CH:XX(+-*/状态控制信号)
输出:共阴极LED七段显示码C0~C6(由低位至高位)
在这里插入图片描述
Design Block:

LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
USE IEEE.STD_LOGIC_ARITH.ALL;
ENTITY CACULATE IS
	PORT(A,B:IN STD_LOGIC_VECTOR(9 DOWNTO 0);
		CLK:IN STD_LOGIC;
		CH:IN STD_LOGIC_VECTOR(1 DOWNTO 0);
		C0,C1,C2,C3,C4,C5,C6:OUT STD_LOGIC_VECTOR(0 TO 6));
END ENTITY;
ARCHITECTURE BEHAV OF CACULATE IS
TYPE STATES IS (S0,S1,S2,S3);
	ATTRIBUTE ENUM_ENCODING:STRING;
	ATTRIBUTE ENUM_ENCODING OF STATES:TYPE IS "one-hot/gray";
	SIGNAL C_ST,N_ST:STATES:=S0;
	SIGNAL D:STD_LOGIC_VECTOR(19 DOWNTO 0);
	SIGNAL BCD:STD_LOGIC_VECTOR(27 DOWNTO 0);
	BEGIN
	COM:PROCESS(A,B,CH,C_ST)
	VARIABLE DATA:STD_LOGIC_VECTOR(19 DOWNTO 0);
		BEGIN
		DATA:="00000000000000000000";
		CASE C_ST IS
		WHEN S0 => DATA(10 DOWNTO 0):=('0'&A)+('0'&B);D<=DATA;
			IF CH="00" THEN N_ST<=S0;
			ELSIF CH="01" THEN N_ST<=S1;
			ELSIF CH="10" THEN N_ST<=S2;
			ELSIF CH="11" THEN N_ST<=S3;
			END IF;
		WHEN S1 => DATA(9 DOWNTO 0):=A-B;D<=DATA;
			IF CH="00" THEN N_ST<=S0;
			ELSIF CH="01" THEN N_ST<=S1;
			ELSIF CH="10" THEN N_ST<=S2;
			ELSIF CH="11" THEN N_ST<=S3;
			END IF;
		WHEN S2 => DATA:=A*B;D<=DATA;
			IF CH="00" THEN N_ST<=S0;
			ELSIF CH="01" THEN N_ST<=S1;
			ELSIF CH="10" THEN N_ST<=S2;
			ELSIF CH="11" THEN N_ST<=S3;
			END IF;
		WHEN S3 => DATA(4 DOWNTO 0):=CONV_STD_LOGIC_VECTOR(CONV_INTEGER(A)/CONV_INTEGER(B),5);D<=DATA;
			IF CH="00" THEN N_ST<=S0;
			ELSIF CH="01" THEN N_ST<=S1;
			ELSIF CH="10" THEN N_ST<=S2;
			ELSIF CH="11" THEN N_ST<=S3;
			END IF;
		END CASE;		
	END PROCESS COM;
	REG:PROCESS(CLK)
		BEGIN
		IF CLK'EVENT AND CLK='1' THEN C_ST<=N_ST;
		END IF;
	END PROCESS REG;
	BCDC:PROCESS(D)
	VARIABLE TEMP:INTEGER;
	VARIABLE DATA_TEMP:INTEGER;
	VARIABLE BCD_TEMP:STD_LOGIC_VECTOR(27 DOWNTO 0);
		BEGIN
		BCD_TEMP:=(OTHERS=>'0');
		DATA_TEMP:=CONV_INTEGER(D);
		FOR K IN 0 TO 6 LOOP
			TEMP:=DATA_TEMP REM 10;
			BCD_TEMP(3+4*K DOWNTO 4*K):=CONV_STD_LOGIC_VECTOR(TEMP,4);
			DATA_TEMP:=(DATA_TEMP-TEMP)/10;
			IF DATA_TEMP=0 THEN EXIT;
			END IF;
		END LOOP;
		BCD<=BCD_TEMP;
	END PROCESS BCDC;
	WITH BCD(3 DOWNTO 0) SELECT
		C0<="1111110" WHEN "0000","0110000" WHEN "0001",
				"1101101" WHEN "0010","1111001" WHEN "0011",
				"0110011" WHEN "0100","1011011" WHEN "0101",
				"1011111" WHEN "0110","1110000" WHEN "0111",
				"1111111" WHEN "1000","1111011" WHEN "1001",
				"0000000" WHEN OTHERS;
		WITH BCD(7 DOWNTO 4) SELECT
		C1<="1111110" WHEN "0000","0110000" WHEN "0001",
				"1101101" WHEN "0010","1111001" WHEN "0011",
				"0110011" WHEN "0100","1011011" WHEN "0101",
				"1011111" WHEN "0110","1110000" WHEN "0111",
				"1111111" WHEN "1000","1111011" WHEN "1001",
				"0000000" WHEN OTHERS;
		WITH BCD(11 DOWNTO 8) SELECT
		C2<="1111110" WHEN "0000","0110000" WHEN "0001",
				"1101101" WHEN "0010","1111001" WHEN "0011",
				"0110011" WHEN "0100","1011011" WHEN "0101",
				"1011111" WHEN "0110","1110000" WHEN "0111",
				"1111111" WHEN "1000","1111011" WHEN "1001",
				"0000000" WHEN OTHERS;
		WITH BCD(15 DOWNTO 12) SELECT
		C3<="1111110" WHEN "0000","0110000" WHEN "0001",
				"1101101" WHEN "0010","1111001" WHEN "0011",
				"0110011" WHEN "0100","1011011" WHEN "0101",
				"1011111" WHEN "0110","1110000" WHEN "0111",
				"1111111" WHEN "1000","1111011" WHEN "1001",
				"0000000" WHEN OTHERS;
		WITH BCD(19 DOWNTO 16) SELECT
		C4<="1111110" WHEN "0000","0110000" WHEN "0001",
				"1101101" WHEN "0010","1111001" WHEN "0011",
				"0110011" WHEN "0100","1011011" WHEN "0101",
				"1011111" WHEN "0110","1110000" WHEN "0111",
				"1111111" WHEN "1000","1111011" WHEN "1001",
				"0000000" WHEN OTHERS;
		WITH BCD(23 DOWNTO 20) SELECT
		C5<="1111110" WHEN "0000","0110000" WHEN "0001",
				"1101101" WHEN "0010","1111001" WHEN "0011",
				"0110011" WHEN "0100","1011011" WHEN "0101",
				"1011111" WHEN "0110","1110000" WHEN "0111",
				"1111111" WHEN "1000","1111011" WHEN "1001",
				"0000000" WHEN OTHERS;
		WITH BCD(27 DOWNTO 24) SELECT
		C6<="1111110" WHEN "0000","0110000" WHEN "0001",
				"1101101" WHEN "0010","1111001" WHEN "0011",
				"0110011" WHEN "0100","1011011" WHEN "0101",
				"1011111" WHEN "0110","1110000" WHEN "0111",
				"1111111" WHEN "1000","1111011" WHEN "1001",
				"0000000" WHEN OTHERS;
END BEHAV;

Test Bench:

LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
USE IEEE.STD_LOGIC_ARITH.ALL;
ENTITY CACULATE_vhd_tst IS
END CACULATE_vhd_tst;
ARCHITECTURE CACULATE_arch OF CACULATE_vhd_tst IS                                                  
SIGNAL CLK1 : STD_LOGIC;
SIGNAL A1 : STD_LOGIC_VECTOR(9 DOWNTO 0);
SIGNAL B1 : STD_LOGIC_VECTOR(9 DOWNTO 0);
SIGNAL CH1 : STD_LOGIC_VECTOR(1 DOWNTO 0);
SIGNAL CT0,CT1,CT2,CT3,CT4,CT5,CT6 : STD_LOGIC_VECTOR(0 TO 6);
CONSTANT CLK_P:TIME:=100 us;
COMPONENT CACULATE
	PORT(A,B:IN STD_LOGIC_VECTOR(9 DOWNTO 0);
		CLK:IN STD_LOGIC;
		CH:IN STD_LOGIC_VECTOR(1 DOWNTO 0);
		C0,C1,C2,C3,C4,C5,C6:OUT STD_LOGIC_VECTOR(0 TO 6));
END COMPONENT;
BEGIN
	i1 : CACULATE PORT MAP(CLK => CLK1, A => A1, B => B1, CH => CH1,
		C0 => CT0, C1 => CT1, C2 => CT2, C3 => CT3, C4 => CT4, C5 => CT5, C6 => CT6);
	PROCESS
		BEGIN
		CLK1<='0'; WAIT FOR CLK_P;
		CLK1<='1'; WAIT FOR CLK_P;
	END PROCESS;
	A1<="1111111111","1111101000" AFTER 20 ms;
	B1<="1111111110","0000110010" AFTER 20 ms;
	CH1<="00","01" AFTER 10 ms,"10" AFTER 20 ms,"11" AFTER 30 ms;
END CACULATE_arch;

仿真波形图:
在这里插入图片描述

  • 2
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值