设计一个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;
仿真波形图: