------------------------------------------------------------ -- Copyright Mentor Graphic Corporation 1991. -- All rights reserved. ------------------------------------------------------------ -- -- Model Title: control unit -- Date Created: 95/10/29 (SUN) -- Author: T. Ohstuka ( tootsuka@ss.titech.ac.jp ) -- ------------------------------------------------------------ -- Model Description: -- ----------------------------------------------------------- -- LIBRARY IEEE,ARITHMETIC ; USE IEEE.STD_LOGIC_1164.ALL ; USE ARITHMETIC.STD_LOGIC_ARITH.ALL ; LIBRARY work ; ENTITY cu_syn IS PORT ( sp_load : OUT STD_LOGIC ; -- load signal for SP acc_load : OUT STD_LOGIC ; -- load signal for ACC rotate_right : OUT STD_LOGIC ; -- rotate right signal of ACC rotate_left : OUT STD_LOGIC ; -- rotate left signal of ACC shift_right : OUT STD_LOGIC ; -- shift right signal of ACC shift_left : OUT STD_LOGIC ; -- shift left signal of ACC zfc_acc_on : OUT STD_LOGIC ; -- zero flag condition which ACC is zero or not zfc_alu_on : OUT STD_LOGIC ; -- zero flag condition which ALU result is zero mar_load : OUT STD_LOGIC ; -- load signal for MAR add_with_carry : OUT STD_LOGIC ; -- add with carry signal sub_with_borrow : OUT STD_LOGIC ; -- substract with borrow signal pc_out : OUT STD_LOGIC ; -- output signal for PC sp_out : OUT STD_LOGIC ; -- output signal for SP acc_out : OUT STD_LOGIC ; -- output signal for ACC if_carry : OUT STD_LOGIC ; -- carry jump condition if_zero : OUT STD_LOGIC ; -- zero jump condition pc_load : OUT STD_LOGIC ; -- load signal for PC clk1 : IN STD_LOGIC ; -- phase 1 clock clk2 : IN STD_LOGIC ; -- phase 2 clock io_write : OUT STD_LOGIC ; -- I/O write signal init : IN STD_LOGIC ; -- initialize signal carry : IN STD_LOGIC ; -- carry flag zero : IN STD_LOGIC ; -- zero flag active : OUT STD_LOGIC ; -- active signal ( RUN signal ) mrd : OUT STD_LOGIC ; -- memory read signal mwr : OUT STD_LOGIC ; -- memory write signal ir : IN STD_LOGIC_VECTOR(7 DOWNTO 0) ; -- instruction resistor alu_f_ctl : OUT STD_LOGIC_VECTOR(4 DOWNTO 0) ; -- ALU function control (M,S3,S2,S1,S0) c_ctl : OUT STD_LOGIC_VECTOR(2 DOWNTO 0) ; -- ALU carry control (A,B,C) stop0 : OUT STD_LOGIC ; -- stop signal last_cycle0 : OUT STD_LOGIC ; -- last cycle of the instruction ( ir_clear ) rff0 : IN STD_LOGIC -- output of run FF ) ; END cu_syn ; -- --------------------------------------------------------- --Copyright Mentor Graphic Corporation 1991. --All rights reserved. ----------------------------------------------------------- --Arch. Body for entity declared in ------------------------------------------------------------ LIBRARY IEEE,ARITHMETIC ; LIBRARY work ; USE IEEE.STD_LOGIC_1164.ALL ; USE ARITHMETIC.STD_LOGIC_ARITH.ALL ; ARCHITECTURE behav1 OF cu_syn IS SIGNAL unused0,unused1,unused2,unused3,unused4,unused5,unused6 : STD_LOGIC ; SIGNAL ir_clear, ir_load, ir_enable : STD_LOGIC ; -- internal use for sequencing SIGNAL stop, last_cycle : STD_LOGIC ; -- internal use for stepwise execution SIGNAL if_c, if_z : STD_LOGIC ; -- for conditional jump operation control SIGNAL f_ctl : STD_LOGIC_VECTOR(4 DOWNTO 0) ; -- internal use for alu_f_ctl CONSTANT cssize : POSITIVE := 4096 ; -- SIZE OF CONTROL STRAGE CONSTANT cswidth : POSITIVE := 40 ; -- size of control word SIGNAL csar : STD_LOGIC_VECTOR(11 DOWNTO 0) ; -- control strage address register SIGNAL mir : STD_LOGIC_VECTOR(cswidth-1 DOWNTO 0) ; -- micro instruction register SIGNAL rff : STD_LOGIC ; -- RUN flip flop SIGNAL decode_alu_mode : STD_LOGIC_VECTOR(3 DOWNTO 0) ; -- decode the alu mode BEGIN rff <= rff0 ; csar_process : PROCESS(clk1) -- process for the control strage(memory) address register BEGIN IF ((clk1='1') AND (clk1'LAST_VALUE='0') AND (clk1'EVENT) ) THEN IF ( init = '1' OR ir_clear = '1' ) THEN -- clear the control strage register csar <= "000000000000" ; ELSIF ( ir_load = '1' ) THEN -- load the instruction code from RAM into control storage address register csar <= ir & "0000" ; ELSIF ( ir_enable = '1' ) THEN -- increment the control strage address register csar <= csar + "000000000001" ; END IF; END IF ; END PROCESS csar_process ; mir_process : PROCESS(clk2) -- procress for micro instruction register BEGIN IF ((clk2='1') AND (clk2'LAST_VALUE='0') AND (clk2'EVENT) ) THEN IF ( rff = '1' ) THEN CASE csar IS -- Add Instructions yourself !! -- -- instruction fetch cycle --+-- CSAR ----+ +--------- micro instruction code ------+ ----------------+---------+---------+---------+--------- ----------------9876543210987654321098765432109876543210 -- fetch cycle WHEN "000000000000" => mir <="0000000000000000000010010000000000000011";--000. MAR <-PC WHEN "000000000001" => mir <="0000000000000000010010000011000000000011";--001. PC <-INC(PC) WHEN "000000000010" => mir <="0000000000000000000000001000000000000101";--002. IR <-MS(MAR) --(IR,0000) --> CSAR ; -- clrc : clear carry flag ----------------+---------+---------+---------+--------- ----------------9876543210987654321098765432109876543210 WHEN "000000010000" => mir <="0000000000000000000000000000011000001001";--010. CARRY <- 0 --(0) --> CSAR ; -- setc : set carry flag ----------------+---------+---------+---------+--------- ----------------9876543210987654321098765432109876543210 WHEN "000000100000" => mir <="0000000000000000000000000000100000001001";--020. CARRY <- 1 --(0) --> CSAR ; -- dec : decrement acc ----------------+---------+---------+---------+--------- ----------------9876543210987654321098765432109876543210 WHEN "000100000000" => mir <="0000010000010000000000100011001111111001";--100. ACC <- DEC(ACC) --(0) --> CSAR ; -- inc : increment acc ----------------+---------+---------+---------+--------- ----------------9876543210987654321098765432109876543210 WHEN "000100010000" => mir <="0000010000010000000000100011001000001001";--110. ACC <- INC(ACC) --(0) --> CSAR ; -- shl : shift acc to left ----------------+---------+---------+---------+--------- ----------------9876543210987654321098765432109876543210 WHEN "001000000000" => mir <="0000000000100010000000100000110000001001";--200. ACC <- shl(ACC) --(0) --> CSAR ; -- shr : shift acc to right ----------------+---------+---------+---------+--------- ----------------9876543210987654321098765432109876543210 WHEN "001000010000" => mir <="0000000000100001000000100000101000001001";--210. ACC <- shr(ACC) --(0) --> CSAR ; -- rotl : rotate acc to left ----------------+---------+---------+---------+--------- ----------------9876543210987654321098765432109876543210 WHEN "001000100000" => mir <="0000000000101000000000100000110000001001";--210. ACC <- rotl(ACC) --(0) --> CSAR ; -- rotr : rotate acc to right ----------------+---------+---------+---------+--------- ----------------9876543210987654321098765432109876543210 WHEN "001000110000" => mir <="0000000000100100000000100000101000001001";--210. ACC <- rotl(ACC) --(0) --> CSAR ; -- jp : jump directly ----------------+---------+---------+---------+--------- ----------------9876543210987654321098765432109876543210 WHEN "001100000000" => mir <="0000000000000000000010010000000000000011";--300. MAR <- PC WHEN "001100000001" => mir <="0000000000000000010000001000000110101001";--301. PC <- MS(MAR) --(0) --> CSAR ; -- jc : jump if carry is high ----------------+---------+---------+---------+--------- ----------------9876543210987654321098765432109876543210 WHEN "001100010000" => mir <="0000000000000000000010010000000000000011";--310. MAR <- PC WHEN "001100010001" => mir <="0000000000000000001000001000000110101001";--311. PC <- MS(MAR)if carry --(0) --> CSAR ; -- jz : jump if zero is high ----------------+---------+---------+---------+--------- ----------------9876543210987654321098765432109876543210 WHEN "001100100000" => mir <="0000000000000000000010010000000000000011";--320. MAR <- PC WHEN "001100100001" => mir <="0000000000000000000100001000000110101001";--321. PC <- MS(MAR)if zero --(0) --> CSAR ; -- add : add memory data to ACC without carry ----------------+---------+---------+---------+--------- ----------------9876543210987654321098765432109876543210 WHEN "110000000000" => mir <="0000000000000000000010010000000000000011";--c00. MAR <- PC WHEN "110000000001" => mir <="0000000000000000010010000011000000000011";--c01. PC <- INC(PC) WHEN "110000000010" => mir <="0000000000000000000000011000000110100011";--c02. MAR <- MS(MAR) WHEN "110000000011" => mir <="0000010000010000000000101000001010011001";--c03. ACC <- ACC + MS(MAR) --(0) --> CSAR ; -- addi : add immediately to ACC without carry ----------------+---------+---------+---------+--------- ----------------9876543210987654321098765432109876543210 WHEN "110000010000" => mir <="0000000000000000000010010000000000000011";--c10. MAR <- PC WHEN "110000010001" => mir <="0000000000000000010010000011000000000011";--c11. PC <- INC(PC) WHEN "110000010010" => mir <="0000010000000000000000101000001010011001";--c12. ACC <- ACC + #OPR --(0) --> CSAR ; -- load : load acc memory data to ACC ----------------+---------+---------+---------+--------- ----------------9876543210987654321098765432109876543210 WHEN "110110000000" => mir <="0000000000000000000010010000000000000011";--d80. MAR <- PC WHEN "110110000001" => mir <="0000000000000000010010000011000000000011";--d81 PC <- INC(PC) WHEN "110110000010" => mir <="0000000000000000000000011000000110100011";--d82. MAR <- MS(MAR) WHEN "110110000011" => mir <="0000010000100000000000001000000110101001";--d83. ACC <- MS(MAR) --(0) --> CSAR ; -- load : load acc immediately ----------------+---------+---------+---------+--------- ----------------9876543210987654321098765432109876543210 WHEN "110110010000" => mir <="0000000000000000000010010000000000000011";--d90. MAR <- PC WHEN "110110010001" => mir <="0000000000000000010010000011000000000011";--d91 PC <- INC(PC) WHEN "110110010010" => mir <="0000010000100000000000001000000110101001";--d92. ACC <- MS(MAR) --(0) --> CSAR ; ----------------+---------+---------+---------+--------- ----------------9876543210987654321098765432109876543210 WHEN OTHERS => mir <="0000000000000000000000000000000000000000"; END CASE ; ELSE mir <= "0000000000000000000000000000000000000000" ; END IF ; END IF ; END PROCESS mir_process ; -- decode the ALU function mode decode_alu_mode <= carry & if_c & zero & if_z ; WITH decode_alu_mode SELECT alu_f_ctl <= "11010" WHEN "1100", "11010" WHEN "0011", "11010" WHEN "1111", f_ctl WHEN OTHERS ; -- interconnection last_cycle <= ir_clear ; if_carry <= if_c ; if_zero <= if_z ; -- mir bit assignment unused5 <= mir(39) ; unused4 <= mir(38) ; unused3 <= mir(37) ; unused2 <= mir(36) ; sp_load <= mir(35) ; acc_load <= mir(34) ; io_write <= mir(33) ; unused1 <= mir(32) ; unused0 <= mir(31) ; unused6 <= mir(30) ; zfc_acc_on <= mir(29) ; zfc_alu_on <= mir(28) ; rotate_left <= mir(27) ; rotate_right <= mir(26) ; shift_left <= mir(25) ; shift_right <= mir(24) ; stop <= mir(23) ; pc_load <= mir(22) ; if_c <= mir(21) ; if_z <= mir(20) ; pc_out <= mir(19) ; sp_out <= mir(18) ; acc_out <= mir(17) ; mar_load <= mir(16) ; mrd <= mir(15) ; mwr <= mir(14) ; add_with_carry <= mir(13) ; sub_with_borrow <= mir(12) ; c_ctl(2) <= mir(11) ; c_ctl(1) <= mir(10) ; c_ctl(0) <= mir(9) ; f_ctl(4) <= mir(8) ; f_ctl(3) <= mir(7) ; f_ctl(2) <= mir(6) ; f_ctl(1) <= mir(5) ; f_ctl(0) <= mir(4) ; ir_clear <= mir(3) ; ir_load <= mir(2) ; ir_enable <= mir(1) ; active <= mir(0) ; -- I/O interface stop0 <= stop ; last_cycle0 <= last_cycle ; END behav1;