已经设计好risc的指令集,时序也已经写好,不太会用vhdl语言编写硬布线控制的控制器,不过已经大致写了一下,但是仿真结果不太对,请各位大佬帮忙看看!!
!
指令集如下:
图片说明
代码如下:
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY CONTROL IS
PORT(IR:IN STD_LOGIC_VECTOR(7 DOWNTO 0);
T1:IN STD_LOGIC;
T2:IN STD_LOGIC;
T3:IN STD_LOGIC;
T4:IN STD_LOGIC;
S:OUT STD_LOGIC_VECTOR(2 DOWNTO 0);
SEL1:OUT STD_LOGIC_VECTOR(1 DOWNTO 0);
SEL2:OUT STD_LOGIC_VECTOR(1 DOWNTO 0);
LA,LB,ALU_EN,LD1,LD0,RS_EN,RD_EN,LD4R,LOAD,LDPC,PC_EN,RST,LDAR,WR_EN,MEM_EN,LDIR,SW_B,LED_B,LDBUS,LDREG:OUT STD_LOGIC);
END CONTROL;
ARCHITECTURE behave OF CONTROL IS
SIGNAL STATE: STD_LOGIC_VECTOR(3 DOWNTO 0):="0000";
BEGIN
PROCESS(IR,T1,T2,T3,T4,STATE)
BEGIN
CASE STATE IS
WHEN "0000"=> --取地址
S<="000";
SEL1<="00";
SEL2<="00";
SW_B<='0';LED_B<='0';LD4R<='0';LD1<='0';LD0<='0';RS_EN<='0';RD_EN<='0';
LA<='0';LB<='0';ALU_EN<='0';LOAD<='0';LDPC<='0';RST<='0';PC_EN<='0';LDAR<='0';WR_EN<='0';MEM_EN<='0';LDIR<='0';
STATE<="0001";
IF(T1='1') THEN
PC_EN<='1';
LDAR<='1';
END IF;
IF(T2='1') THEN
LDPC<='1';
END IF;
WHEN "0001"=> --取指令
IF(IR(7 DOWNTO 4)="0000") THEN --IN
STATE<="0010";
ELSIF(IR(7 DOWNTO 4)="0001") THEN --OUT
STATE<="0011";
ELSIF(IR(7 DOWNTO 4)="0010") THEN --ADD
STATE<="0100";
ELSIF(IR(7 DOWNTO 4)="0011") THEN --SUB
STATE<="0101";
ELSIF(IR(7 DOWNTO 4)="0100") THEN --MOV
STATE<="0110";
ELSIF(IR(7 DOWNTO 4)="0101") THEN --INC
STATE<="0111";
ELSIF(IR(7 DOWNTO 4)="0110") THEN --DEC
STATE<="1000";
ELSIF(IR(7 DOWNTO 4)="0111") THEN --NEG
STATE<="1001";
ELSIF(IR(7 DOWNTO 4)="1000") THEN --JMP
STATE<="1010";
ELSIF(IR(7 DOWNTO 4)="1001") THEN --AND
STATE<="1011";
ELSIF(IR(7 DOWNTO 4)="1010") THEN --OR
STATE<="1100";
ELSIF(IR(7 DOWNTO 4)="1011") THEN --STA
STATE<="1101";
END IF;
IF(T1='1') THEN
MEM_EN<='1';
END IF;
IF(T2='1') THEN
LDIR<='1';
END IF;
WHEN "0010"=> --IN
STATE<="0000";
IF(T1='1') THEN
SW_B<='1';
END IF;
IF(T2='1') THEN
LD4R<='1';
LD1<=IR(1);
LD0<=IR(0);
END IF;
WHEN "0011"=> --OUT
STATE<="0000";
IF(T1='1') THEN
RS_EN<='1';
SEL1(1)<=IR(3);
SEL1(0)<=IR(2);
END IF;
IF(T2='1') THEN
LED_B<='1';
END IF;
WHEN "0100"=> --ADD
STATE<="0000";
IF(T1='1') THEN
LA<='1';
LB<='1';
SEL1(1)<=IR(3);
SEL1(0)<=IR(2);
SEL2(1)<=IR(1);
SEL2(0)<=IR(0);
LDBUS<='0';
LDREG<='1';
END IF;
IF(T2='1') THEN
ALU_EN<='1';
S(2 DOWNTO 0)<="000";
END IF;
IF(T3='1') THEN
LD1<=IR(1);
LD0<=IR(0);
LD4R<='1';
END IF;
WHEN "0101"=> --SUB
STATE<="0000";
IF(T1='1') THEN
LA<='1';
LB<='1';
SEL1(1)<=IR(3);
SEL1(0)<=IR(2);
SEL2(1)<=IR(1);
SEL2(0)<=IR(0);
LDBUS<='0';
LDREG<='1';
END IF;
IF(T2='1') THEN
ALU_EN<='1';
S(2 DOWNTO 0)<="001";
END IF;
IF(T3='1') THEN
LD1<=IR(1);
LD0<=IR(0);
LD4R<='1';
END IF;
WHEN "0110"=> --MOV
STATE<="0000";
IF(T1='1') THEN
SEL1(1)<=IR(3);
SEL1(0)<=IR(2);
END IF;
IF(T2='1') THEN
LD1<=IR(1);
LD0<=IR(0);
LD4R<='1';
END IF;
WHEN "0111"=> --INC
STATE<="0000";
IF(T1='1') THEN
LA<='1';
SEL1(1)<=IR(3);
SEL1(0)<=IR(2);
LDBUS<='0';
LDREG<='1';
END IF;
IF(T2='1') THEN
ALU_EN<='1';
S(2 DOWNTO 0)<="100";
END IF;
IF(T3='1') THEN
LD1<=IR(1);
LD0<=IR(0);
LD4R<='1';
END IF;
WHEN "1000"=> --DEC
STATE<="0000";
IF(T1='1') THEN
LA<='1';
SEL1(1)<=IR(3);
SEL1(0)<=IR(2);
LDBUS<='0';
LDREG<='1';
END IF;
IF(T2='1') THEN
ALU_EN<='1';
S(2 DOWNTO 0)<="101";
END IF;
IF(T3='1') THEN
LD1<=IR(1);
LD0<=IR(0);
LD4R<='1';
END IF;
WHEN "1001"=> --NEG
STATE<="0000";
IF(T1='1') THEN
LA<='1';
SEL1(1)<=IR(3);
SEL1(0)<=IR(2);
LDBUS<='0';
LDREG<='1';
END IF;
IF(T2='1') THEN
ALU_EN<='1';
S(2 DOWNTO 0)<="110";
END IF;
IF(T3='1') THEN
LD1<=IR(1);
LD0<=IR(0);
LD4R<='1';
END IF;
WHEN "1010"=> --JMP
STATE<="0000";
IF(T1='1') THEN
SEL1(1)<=IR(3);
SEL1(0)<=IR(2);
END IF;
IF(T2='1') THEN
LD1<=IR(1);
LD0<=IR(0);
LOAD<='1';
LDPC<='1';
END IF;
WHEN "1011"=> --AND
STATE<="0000";
IF(T1='1') THEN
LA<='1';
LB<='1';
SEL1(1)<=IR(3);
SEL1(0)<=IR(2);
SEL2(1)<=IR(1);
SEL2(0)<=IR(0);
LDBUS<='0';
LDREG<='1';
END IF;
IF(T2='1') THEN
ALU_EN<='1';
S(2 DOWNTO 0)<="010";
END IF;
IF(T3='1') THEN
LD1<=IR(1);
LD0<=IR(0);
LD4R<='1';
END IF;
WHEN "1100"=> --OR
STATE<="0000";
IF(T1='1') THEN
LA<='1';
LB<='1';
SEL1(1)<=IR(3);
SEL1(0)<=IR(2);
SEL2(1)<=IR(1);
SEL2(0)<=IR(0);
LDBUS<='0';
LDREG<='1';
END IF;
IF(T2='1') THEN
ALU_EN<='1';
S(2 DOWNTO 0)<="011";
END IF;
IF(T3='1') THEN
LD1<=IR(1);
LD0<=IR(0);
LD4R<='1';
END IF;
WHEN "1101"=> --STA CLK1
STATE<="1111";
IF(T1='1') THEN
SEL2(1)<=IR(1);
SEL2(0)<=IR(0);
RD_EN<='1';
END IF;
IF(T2='1') THEN
LDAR<='1';
END IF;
WHEN "1111"=> --STA CLK2
STATE<="0000";
IF(T1='1') THEN
SEL1(1)<=IR(3);
SEL1(0)<=IR(2);
RS_EN<='1';
END IF;
IF(T2='1') THEN
WR_EN<='1';
END IF;
WHEN OTHERS=> NULL;
END CASE;
END PROCESS;
END behave;