-- Copyright © 1993 by McGraw-Hill, Inc. and Zainalabedin Navabi
-- FIGURE 9.52
-- ENTITY DECLARATION OF PARWAN CONTROL SECTION :
LIBRARY cmos;
USE cmos.basic_utilities.ALL;
LIBRARY par_library;
USE par_library.par_utilities.ALL;
USE WORK.alu_operations.ALL;
--
ENTITY par_control_unit IS
GENERIC (read_delay, write_delay : TIME := 3 NS);
PORT (clk : IN qit;
-- register control signals:
load_ac, zero_ac,
load_ir,
increment_pc, load_page_pc, load_offset_pc, reset_pc,
load_page_mar, load_offset_mar,
load_sr, cm_carry_sr,
-- bus connection control signals:
pc_on_mar_page_bus, ir_on_mar_page_bus,
pc_on_mar_offset_bus, dbus_on_mar_offset_bus,
pc_offset_on_dbus, obus_on_dbus, databus_on_dbus,
mar_on_adbus,
dbus_on_databus,
-- logic unit function control outputs:
arith_shift_left, arith_shift_right : OUT qit;
alu_code : OUT qit_vector (2 DOWNTO 0);
-- inputs from the data section:
ir_lines : IN byte; status : IN nibble;
-- memory control and other external signals:
read_mem, write_mem : OUT qit; interrupt : IN qit
);
END par_control_unit;
--
-- FIGURE 9.53
-- DECLARATIVE PART OF PARWAN CONTROL UNIT ARCHITECTURE:
ARCHITECTURE dataflow OF par_control_unit IS
-- oring is implied in the following signals (oi)
SIGNAL load_ac_oi, zero_ac_oi,
load_ir_oi,
increment_pc_oi, load_page_pc_oi, load_offset_pc_oi, reset_pc_oi,
load_page_mar_oi, load_offset_mar_oi,
load_sr_oi, cm_carry_sr_oi,
pc_on_mar_page_bus_oi, ir_on_mar_page_bus_oi,
pc_on_mar_offset_bus_oi, dbus_on_mar_offset_bus_oi,
pc_offset_on_dbus_oi, obus_on_dbus_oi, databus_on_dbus_oi,
mar_on_adbus_oi,
dbus_on_databus_oi,
arith_shift_left_oi, arith_shift_right_oi,
read_mem_oi, write_mem_oi : ored_qit BUS;
SIGNAL alu_code_oi : ored_qit_vector (2 DOWNTO 0) BUS;
SIGNAL s : ored_qit_vector (9 DOWNTO 1) REGISTER := "000000001";
-- FIGURE 9.54
-- ASSIGNING SIGNALS WITH IMPLIED ORIGIN TO THE
-- PARWAN CONTROL UNIT OUTPUTS:
BEGIN
-- implied or assignments to output signals
load_ac <= load_ac_oi;
zero_ac <= zero_ac_oi;
load_ir <= load_ir_oi;
increment_pc <= increment_pc_oi;
load_page_pc <= load_page_pc_oi;
load_offset_pc <= load_offset_pc_oi;
reset_pc <= reset_pc_oi;
load_page_mar <= load_page_mar_oi;
load_offset_mar <= load_offset_mar_oi;
load_sr <= load_sr_oi;
cm_carry_sr <= cm_carry_sr_oi;
pc_on_mar_page_bus <= pc_on_mar_page_bus_oi;
ir_on_mar_page_bus <= ir_on_mar_page_bus_oi;
pc_on_mar_offset_bus <= pc_on_mar_offset_bus_oi;
dbus_on_mar_offset_bus <= dbus_on_mar_offset_bus_oi;
pc_offset_on_dbus <= pc_offset_on_dbus_oi;
obus_on_dbus <= obus_on_dbus_oi;
databus_on_dbus <= databus_on_dbus_oi;
mar_on_adbus <= mar_on_adbus_oi;
dbus_on_databus <= dbus_on_databus_oi;
arith_shift_left <= arith_shift_left_oi;
arith_shift_right <= arith_shift_right_oi;
read_mem <= read_mem_oi;
write_mem <= write_mem_oi;
alu_code <= qit_vector (alu_code_oi);
------------
-- FIGURE 9.55
-- STATE 1 : STARTING A FETCH:
s1: BLOCK (s(1) = '1')
BEGIN -- start of fetch
-- pc to mar
pc_on_mar_page_bus_oi <= GUARDED '1';
pc_on_mar_offset_bus_oi <= GUARDED '1';
load_page_mar_oi <= GUARDED '1';
load_offset_mar_oi <= GUARDED '1';
-- reset pc if interrupt
reset_pc_oi <= GUARDED '1' WHEN interrupt = '1' ELSE '0';
-- goto 2 if interrupt is off
ck: BLOCK ( (clk = '0' AND NOT clk'STABLE) AND GUARD )
BEGIN
s(1) <= GUARDED '1' WHEN interrupt = '1' ELSE '0';
s(2) <= GUARDED '1' WHEN interrupt /= '1' ELSE '0';
END BLOCK ck;
END BLOCK s1;
-------------
-- FIGURE 9.56
-- STATE 2 : COMPLETING A FETCH:
s2: BLOCK (s(2) = '1')
BEGIN -- fetching continues
-- read memory into ir
mar_on_adbus_oi <= GUARDED '1';
read_mem_oi <= GUARDED '1' AFTER read_delay;
databus_on_dbus_oi <= GUARDED '1';
alu_code_oi <= GUARDED ored_qit_vector (a_input);
load_ir_oi <= GUARDED '1';
-- increment pc
increment_pc_oi <= GUARDED '1';
-- goto 3
ck: BLOCK ( (clk = '0' AND NOT clk'STABLE) AND GUARD )
BEGIN
s(3) <= GUARDED '1';
END BLOCK ck;
END BLOCK s2;
-------------
-- FIGURE 9.57
-- STATE 3 : PREPARING FOR ADDRESS FETCH, EXECUTION OF
-- SINGLE BYTE INSTRUCTIONS :
s3: BLOCK (s(3) = '1')
BEGIN
-- pc to mar, for next read
pc_on_mar_page_bus_oi <= GUARDED '1';
pc_on_mar_offset_bus_oi <= GUARDED '1';
load_page_mar_oi <= GUARDED '1';
load_offset_mar_oi <= GUARDED '1';
-- goto 4 if not single byte instruction
ck: BLOCK ( (clk = '0' AND NOT clk'STABLE) AND GUARD )
BEGIN
s(4) <= GUARDED '1' WHEN ir_lines (7 DOWNTO 4) /= "1110" ELSE '0';
END BLOCK ck;
-- perform single byte instructions
sb: BLOCK ( (ir_lines (7 DOWNTO 4) = "1110") AND GUARD)
BEGIN
alu_code_oi <= GUARDED
ored_qit_vector (b_compl) WHEN ir_lines (1) = '1' ELSE
ored_qit_vector (b_input);
arith_shift_left_oi <= GUARDED '1' WHEN ir_lines (3 DOWNTO 0) = "1000" ELSE '0';
arith_shift_right_oi <= GUARDED '1' WHEN ir_lines (3 DOWNTO 0) = "1001" ELSE '0';
load_sr_oi <= GUARDED
'1' WHEN ( ir_lines (3) = '1' OR ir_lines (1) = '1' ) ELSE '0';
cm_carry_sr_oi <= GUARDED '1' WHEN ir_lines (2) = '1' ELSE '0';
load_ac_oi <= GUARDED
'1' WHEN ( ir_lines (3) = '1' OR ir_lines (1) = '1' ) ELSE '0';
zero_ac_oi <= GUARDED
'1' WHEN ( ir_lines (3) = '0' AND ir_lines (0) = '1' ) ELSE '0';
ck: BLOCK ( (clk = '0' AND NOT clk'STABLE) AND GUARD )
BEGIN
s(2) <= GUARDED '1';
END BLOCK ck;
END BLOCK sb;
END BLOCK s3;
-------------
-- FIGURE 9.58
-- STATE 4 : COMPLETING ADDRESS OF FULL ADDRESS INSTRUCTIONS;
-- BRANCHING FOR INDIRECT, DIRECT, JSR AND BRANCH :
s4: BLOCK (s(4) = '1')
BEGIN -- page from ir, and offset from next memory makeup 12-bit address
-- read memory into mar offset
mar_on_adbus_oi <= GUARDED '1';
read_mem_oi <= GUARDED '1' AFTER read_delay;
databus_on_dbus_oi <= GUARDED '1';
dbus_on_mar_offset_bus_oi <= GUARDED '1';
load_offset_mar_oi <= GUARDED '1'; -- completed operand (dir/indir) address
-- page from ir if not branch or jsr
pg: BLOCK ( (ir_lines (7 DOWNTO 6) /= "11") AND GUARD)
BEGIN
ir_on_mar_page_bus_oi <= GUARDED '1';
load_page_mar_oi <= GUARDED '1';
-- goto 5 for indirect, 6 for direct
ck: BLOCK ( (clk = '0' AND NOT clk'STABLE) AND GUARD )
BEGIN
s(5) <= GUARDED '1' WHEN ir_lines (4) = '1' ELSE '0'; -- indir
s(6) <= GUARDED '1' WHEN ir_lines (4) = '0' ELSE '0'; -- direct
END BLOCK ck;
END BLOCK pg;
-- keep page in mar_page if jms or bra (same-page instructions)
sp: BLOCK ( (ir_lines (7 DOWNTO 6) = "11") AND GUARD)
BEGIN
-- fot 7 for jsr, 9 for bra
ck: BLOCK ( (clk = '0' AND NOT clk'STABLE) AND GUARD )
BEGIN
s(7) <= GUARDED '1' WHEN ir_lines (5) = '0' ELSE '0'; -- jsr
s(9) <= GUARDED '1' WHEN ir_lines (5) = '1' ELSE '0'; -- bra
END BLOCK ck;
END BLOCK sp;
-- increment pc
increment_pc_oi <= GUARDED '1';
END BLOCK s4;
-------------
-- FIGURE 9.59
-- STATE 5 : TAKING CARE OF INDIRECT ADDRESSING :
s5: BLOCK (s(5) = '1')
BEGIN -- indirect addressing
-- read actual operand from memory into mar offset
mar_on_adbus_oi <= GUARDED '1';
read_mem_oi <= GUARDED '1' AFTER read_delay;
databus_on_dbus_oi <= GUARDED '1';
dbus_on_mar_offset_bus_oi <= GUARDED '1';
load_offset_mar_oi <= GUARDED '1';
-- goto 6
ck: BLOCK ( (clk = '0' AND NOT clk'STABLE) AND GUARD )
BEGIN
s(6) <= GUARDED '1';
END BLOCK ck;
END BLOCK s5;
-------------
-- FIGURE 9.60
-- STATE 6 : READING THE ACTUAL OPERAND, AND EXECUTING
-- JMP, STA, LDA, AND ADD, AND SUB INSTRUCTIONS:
s6: BLOCK (s(6) = '1')
BEGIN
jm: BLOCK ( (ir_lines (7 DOWNTO 5) = "100") AND GUARD)
BEGIN
load_page_pc_oi <= GUARDED '1';
load_offset_pc_oi <= GUARDED '1';
-- goto 2
ck: BLOCK ( (clk = '0' AND NOT clk'STABLE) AND GUARD )
BEGIN
s(2) <= GUARDED '1';
END BLOCK ck;
END BLOCK jm;
--
st: BLOCK ( (ir_lines (7 DOWNTO 5) = "101") AND GUARD)
BEGIN
-- mar on adbus, ac on databus, write to memory
mar_on_adbus_oi <= GUARDED '1';
alu_code_oi <= GUARDED ored_qit_vector (b_input);
obus_on_dbus_oi <= GUARDED '1';
dbus_on_databus_oi <= GUARDED '1';
write_mem_oi <= GUARDED '1' AFTER write_delay;
-- goto 1
ck: BLOCK ( (clk = '0' AND NOT clk'STABLE) AND GUARD )
BEGIN
s(1) <= GUARDED '1';
END BLOCK ck;
END BLOCK st;
--
rd: BLOCK ( (ir_lines (7) = '0') AND GUARD)
BEGIN
-- mar on adbus, read memory for operand, perform operation
mar_on_adbus_oi <= GUARDED '1';
read_mem_oi <= GUARDED '1' AFTER read_delay;
databus_on_dbus_oi <= GUARDED '1';
WITH ir_lines (6 DOWNTO 5) SELECT
alu_code_oi <= GUARDED
ored_qit_vector (a_input) WHEN "00",
ored_qit_vector (a_and_b) WHEN "01",
ored_qit_vector (a_add_b) WHEN "10",
ored_qit_vector (a_sub_b) WHEN "11",
ored_qit_vector (b_input) WHEN OTHERS;
load_sr_oi <= GUARDED '1';
load_ac_oi <= GUARDED '1';
-- goto 1
ck: BLOCK ( (clk = '0' AND NOT clk'STABLE) AND GUARD )
BEGIN
s(1) <= GUARDED '1';
END BLOCK ck;
END BLOCK rd;
END BLOCK s6;
---------------
-- FIGURE 9.61
-- STATE 7 : WRITING RETURN ADDRESS OF SUBROUTINE;
-- MAKING PC POINT TO TOP OF SUBROUTINE :
s7: BLOCK (s(7) = '1')
BEGIN -- jsr
-- write pc offset to top of subroutine
mar_on_adbus_oi <= GUARDED '1';
pc_offset_on_dbus_oi <= GUARDED '1';
dbus_on_databus_oi <= GUARDED '1';
write_mem_oi <= GUARDED '1' AFTER write_delay;
-- address of subroutine to pc
load_offset_pc_oi <= GUARDED '1';
-- goto 8
ck: BLOCK ( (clk = '0' AND NOT clk'STABLE) AND GUARD )
BEGIN
s(8) <= GUARDED '1';
END BLOCK ck;
END BLOCK s7;
-------------
-- FIGURE 9.62
-- STATE 8 :INCREMENTING PC POINT TO SKIP THE LOCATION
-- RESERVED FOR THE RETURN ADDRESS :
s8: BLOCK (s(8) = '1')
BEGIN
-- increment pc
increment_pc_oi <= GUARDED '1';
-- goto 1
ck: BLOCK ( (clk = '0' AND NOT clk'STABLE) AND GUARD )
BEGIN
s(1) <= GUARDED '1';
END BLOCK ck;
END BLOCK s8;
-------------
-- FIGURE 9.63
-- STATE 9 : CONDITIONAL LOAADING OF PCFOR THE BRANCH INSTRUCTIONS :
s9: BLOCK (s(9) = '1')
BEGIN
load_offset_pc_oi <= GUARDED
'1' WHEN (status AND ir_lines (3 DOWNTO 0)) /= "0000" ELSE '0';
-- goto 1
ck: BLOCK ( (clk = '0' AND NOT clk'STABLE) AND GUARD )
BEGIN
s(1) <= GUARDED '1';
END BLOCK ck;
END BLOCK s9;
---------------
-- FIGURE 9.64
-- A ZERO DRIVERS IS PLACED ON ALL STATES, ENDING THE
-- DATAFLOW DESCRIPTION OF THE PARWAN CONTROL UNIT:
ck: BLOCK ( clk = '0' AND NOT clk'STABLE )
BEGIN
s (9 DOWNTO 1) <= GUARDED "000000000";
END BLOCK ck;
---------------
END dataflow;
--