-- Model Name : Synthesizable Dataflow - Parwan Data Path -- Author : Zainalabedin Navabi -- Last Updated : 09 / 15 / 1996 -- This document is © copyrighted by the Author.

LIBRARY IEEE;
USE IEEE.std_logic_1164.ALL;
--
LIBRARY EXEMPLAR;
USE EXEMPLAR.exemplar_1164.ALL;
--
LIBRARY parwan_s;
USE parwan_s.synthesis_parameters.ALL;
USE parwan_s.synthesis_utilities.ALL;
--
ENTITY par_data_path IS
    PORT (databus : INOUT byte := "ZZZZZZZZ"; adbus : OUT twelve;
      clk : IN std_logic;
      -- register controls:
      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 connections:
      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 inputs:
      arith_shift_left, arith_shift_right : IN std_logic;
      alu_code : IN std_logic_vector (2 DOWNTO 0);
      -- outputs to the controller:
      ir_lines : OUT byte; status : OUT nibble
      );
END par_data_path;
--
ARCHITECTURE structural_synthesizable OF par_data_path IS
    --
    COMPONENT accumulator_unit
      PORT (i8: IN byte; o8: OUT byte; load, zero, ck: IN std_logic);
    END COMPONENT;
    --
    COMPONENT instruction_register_unit
      PORT (i8: IN byte; o8: OUT byte; load, ck: IN std_logic);
    END COMPONENT;
    --
    COMPONENT program_counter_unit
      PORT (i12 : IN twelve; o12 : OUT twelve;
        increment, load_page, load_offset, reset, ck : IN std_logic);
    END COMPONENT;
    --
    COMPONENT memory_address_register_unit
      PORT (i12 : IN twelve; o12 : OUT twelve;
        load_page, load_offset, ck : IN std_logic);
    END COMPONENT;
    --
    COMPONENT status_register_unit
      PORT (in_flags : IN nibble; out_status : OUT nibble;
        load, cm_carry, ck : IN std_logic );
    END COMPONENT;
    --
    COMPONENT arithmetic_logic_unit
      PORT (a_side, b_side : IN byte; code : IN std_logic_vector; in_flags : IN nibble;
        z_out : OUT byte; out_flags : OUT nibble);
    END COMPONENT;
    --
    COMPONENT shifter_unit
      PORT (alu_side : IN byte; arith_shift_left, arith_shift_right : IN std_logic;
        in_flags : IN nibble; obus_side : OUT byte; out_flags : OUT nibble);
    END COMPONENT;
    --
    SIGNAL ac_out, ir_out, alu_out, obus : byte;
    SIGNAL pc_out, mar_out : twelve;
    SIGNAL dbus : byte;
    SIGNAL alu_flags, shu_flags, sr_out : nibble;
    SIGNAL mar_bus : twelve;
BEGIN
    -- bus connections --
    --
    mar_bus (7 DOWNTO 0) <= dbus WHEN dbus_on_mar_offset_bus = '1' ELSE "ZZZZZZZZ";
    databus <= dbus WHEN dbus_on_databus = '1' ELSE "ZZZZZZZZ";
    --
    dbus <= obus WHEN obus_on_dbus = '1' ELSE "ZZZZZZZZ";
    --
    dbus <= databus WHEN databus_on_dbus = '1' ELSE "ZZZZZZZZ";
    --
    -- register connections --
    --
    r1: accumulator_unit PORT MAP (obus, ac_out, load_ac, zero_ac, clk);
    --
    r2: instruction_register_unit PORT MAP (obus, ir_out, load_ir, clk);
    ir_lines <= ir_out;
    mar_bus (11 DOWNTO 8) <= ir_out (3 DOWNTO 0) WHEN ir_on_mar_page_bus = '1' ELSE "ZZZZ";
    --
    r3: program_counter_unit PORT MAP (mar_out, pc_out, increment_pc, load_page_pc, load_offset_pc, reset_pc, clk);
    mar_bus (11 DOWNTO 8) <= pc_out (11 DOWNTO 8) WHEN pc_on_mar_page_bus = '1' ELSE "ZZZZ";
    mar_bus (7 DOWNTO 0) <= pc_out (7 DOWNTO 0) WHEN pc_on_mar_offset_bus = '1' ELSE "ZZZZZZZZ";
    dbus <= pc_out (7 DOWNTO 0) WHEN pc_offset_on_dbus = '1' ELSE "ZZZZZZZZ";
    --
    r4: memory_address_register_unit PORT MAP (mar_bus, mar_out, load_page_mar, load_offset_mar, clk);
    adbus <= mar_out WHEN mar_on_adbus = '1' ELSE "ZZZZZZZZZZZZ";
    --
    r5: status_register_unit PORT MAP (shu_flags, sr_out, load_sr, cm_carry_sr, clk);
    status <= sr_out;
    --
    -- connection of logical and register structures --
    --
    l1: arithmetic_logic_unit PORT MAP (dbus, ac_out, alu_code, sr_out, alu_out, alu_flags);
    l2: shifter_unit PORT MAP (alu_out, arith_shift_left, arith_shift_right, alu_flags, obus, shu_flags);
END structural_synthesizable;