------------------------------------------------------------
-- 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;