CONSTANT prog : mem_array:=(
0=>op2slv(sta) & STD_LOGIC_VECTOR(TO_UNSIGNED(9,word_w-op_w-1)) & '0', 1=> op2slv(sta) & STD_LOGIC_VECTOR(TO_UNSIGNED(10,word_w-op_w-1)) & '1', 2=> op2slv(add) & STD_LOGIC_VECTOR(TO_UNSIGNED(9,word_w-op_w-1)) & '1', 3=> op2slv(sub) & STD_LOGIC_VECTOR(TO_UNSIGNED(10,word_w-op_w-1)) & '0', 4=> op2slv(and1) & STD_LOGIC_VECTOR(TO_UNSIGNED(10,word_w-op_w-1)) & '0', 5=> op2slv(shl) & STD_LOGIC_VECTOR(TO_UNSIGNED(10,word_w-op_w-1)) & '0', 6=> op2slv(nop) & STD_LOGIC_VECTOR(TO_UNSIGNED(9,word_w-op_w-1)) & '0',
7=> op2slv(sta) & STD_LOGIC_VECTOR(TO_UNSIGNED(11,word_w-op_w-1)) & '0', 8=> op2slv(jmp) & STD_LOGIC_VECTOR(TO_UNSIGNED(12,word_w-op_w-1)) & '0', 9=> STD_LOGIC_VECTOR(TO_UNSIGNED(2,word_w)), 10=> STD_LOGIC_VECTOR(TO_UNSIGNED(3,word_w)), OTHERS => (OTHERS =>'0'));
TYPE microcode_array IS ARRAY (0 TO 25) OF STD_LOGIC_VECTOR(21 DOWNTO 0); CONSTANT code : microcode_array:=( 0=> \
1=> \ 2=> \ 3=> \ 4=> \ 5=> \ 6=> \ 7=> \
8=> \ 9=> \ 10=> \ 11=> \ 12=> \ 13=> \ 14=> \ 15=> \ 16=> \ 17=> \
18=> \ 19=> \
20=> \ 21=> \
22=> \ 23=> \
24=> \ 25=> \
SIGNAL count : UNSIGNED(word_w-op_w-1 DOWNTO 0);
SIGNAL op : STD_LOGIC_VECTOR(op_w-1 DOWNTO 0); SIGNAL z_flag : STD_LOGIC; SIGNAL mdr_out : STD_LOGIC_VECTOR(word_w-1 DOWNTO 0); SIGNAL mar_out : UNSIGNED(word_w-op_w-1 DOWNTO 0); SIGNAL IR_out : STD_LOGIC_VECTOR(word_w-1 DOWNTO 0); SIGNAL acc_out : UNSIGNED(word_w-1 DOWNTO 0); SIGNAL sysbus_out : STD_LOGIC_VECTOR(word_w-1 DOWNTO 0); BEGIN
PROCESS(reset,clock)
VARIABLE instr_reg : STD_LOGIC_VECTOR(word_w-1 DOWNTO 0); VARIABLE acc : UNSIGNED(word_w-1 DOWNTO 0);
CONSTANT zero : UNSIGNED(word_w-1 DOWNTO 0):=(OTHERS =>'0'); VARIABLE mdr : STD_LOGIC_VECTOR(word_w-1 DOWNTO 0); VARIABLE reg : STD_LOGIC_VECTOR(word_w-1 DOWNTO 0); VARIABLE mar : UNSIGNED(word_w-op_w-1 DOWNTO 0);
VARIABLE sysbus : STD_LOGIC_VECTOR(word_w-1 DOWNTO 0); VARIABLE microcode : microcode_array;
VARIABLE add_r : UNSIGNED(4 DOWNTO 0);
VARIABLE data_r : STD_LOGIC_VECTOR(21 DOWNTO 0); VARIABLE temp : STD_LOGIC_VECTOR(4 DOWNTO 0); BEGIN
IF reset='0' THEN
add_r :=(OTHERS =>'0'); count <= (OTHERS =>'0'); instr_reg := (OTHERS =>'0'); acc := (OTHERS =>'0'); mdr := (OTHERS =>'0'); reg := (OTHERS =>'0'); mar := (OTHERS =>'0'); z_flag <='0'; mem <= prog;
sysbus :=(OTHERS =>'0');
ELSIF RISING_EDGE(clock) THEN --microprogram controller
data_r := code(TO_INTEGER(add_r)); IF data_r(4 DOWNTO 0)=\--判断下地址 temp:=\ add_r := UNSIGNED(temp);
ELSIF data_r(4 DOWNTO 0)=\ IF IR_out(0)='1' THEN
add_r :=\ ELSE
add_r :=\ END IF;
ELSIF data_r(4 DOWNTO 0)=\ IF IR_out(0)='1' THEN add_r :=\ ELSE
add_r :=\ END IF;
ELSIF data_r(4 DOWNTO 0)=\ IF z_flag='1' THEN add_r:=\ ELSE
add_r :=\ END IF; ELSE
add_r := UNSIGNED(data_r(4 DOWNTO 0)); END IF; data_r_out <=data_r; add_r_out <= add_r; --PC
IF data_r(16)='1' THEN --PC_bus='1'
sysbus := rfill & STD_LOGIC_VECTOR(count); END IF;
IF data_r(19)='1' THEN --load_PC='1'
count <= UNSIGNED(mdr(word_w-op_w-1 DOWNTO 0)); ELSIF data_r(10)='1' THEN --INC_PC='1' count <= count+1; ELSE
count <= count; END IF; --IR
IF data_r(15)='1' THEN --load_IR instr_reg := mdr; END IF;
IF data_r(9)='1' THEN --Addr_bus='1'
sysbus :='0' & rfill & instr_reg(word_w-op_w-1 DOWNTO 1); END IF;
op <= instr_reg(word_w-1 DOWNTO word_w-op_w); IR_out <= instr_reg; op_out <=op;
--ALU
IF data_r(18)='1' THEN --ACC_bus='1' sysbus := STD_LOGIC_VECTOR(acc); END IF;
IF data_r(20)='1' THEN --REG_bus='1' sysbus := STD_LOGIC_VECTOR(reg); END IF;
IF data_r(17)='1' THEN --load_ACC='1' acc:=UNSIGNED(mdr); END IF;
IF data_r(13)='1' THEN --MDR_bus='1' sysbus:=mdr; END IF;
IF IR_out(0)='0' THEN
IF data_r(11)='1' THEN --ALU_ACC='1' IF data_r(6)='1' THEN --ALU_add='1' acc := acc + UNSIGNED(mdr);
ELSIF data_r(5)='1' THEN --ALU_sub='1' acc := acc - UNSIGNED(mdr);
ELSIF data_r(12)='1' THEN --ALU_and='1' acc := acc and UNSIGNED(mdr);
ELSIF data_r(21)='1' THEN --ALU_srl='1' acc :=acc(word_w-1-1 DOWNTO 0) & '0'; END IF; END IF; ELSE
IF data_r(11)='1' THEN --ALU_ACC='1' IF data_r(6)='1' THEN --ALU_add='1' acc := acc + UNSIGNED(reg);
ELSIF data_r(12)='1' THEN --ALU_and='1' acc := acc and UNSIGNED(reg);
ELSIF data_r(21)='1' THEN --ALU_srl='1' acc :=acc(word_w-1-1 DOWNTO 0) & '0'; END IF; END IF; END IF;
IF acc=zero THEN z_flag <='1'; ELSE
z_flag <='0'; END IF;
acc_out<=acc;
--RAM
IF data_r(14)='1' THEN --load_MAR='1'
mar := UNSIGNED(sysbus(word_w-op_w-1 DOWNTO 0)); ELSIF data_r(12)='1' THEN --load_MDR='1' mdr := sysbus;
ELSIF data_r(18)='1' THEN --load_REG='1' reg := sysbus;
ELSIF data_r(8)='1' THEN --CS='1'
IF data_r(7)='1' THEN --R_NW='1'
mdr := mem(TO_INTEGER(mar)); ELSE
mem(TO_INTEGER(mar))<=mdr; END IF;
END IF;
mdr_out <= mdr; mar_out <= mar; END IF;
sysbus_out <=sysbus;
END PROCESS;
PROCESS(mode,mem_addr) BEGIN
--mode=0 -> sysbus --mode=1 -> PC
--mode=2 -> result of ALU --mode=3 -> IR --mode=4 -> MAR --mode=5 -> MDR
--mode=6 -> mem output <= (OTHERS =>'0'); CASE mode is WHEN \
output<=sysbus_out;
WHEN \
output(word_w-op_w-1 DOWNTO 0)<= STD_LOGIC_VECTOR(count); WHEN \
output <= STD_LOGIC_VECTOR(acc_out); WHEN \
output <= IR_out;