exjobb-public/src/controller/control_unit.vhd

87 lines
2.6 KiB
VHDL

library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.MATH_REAL.all;
library gan_ganimede;
use gan_ganimede.io_types.all;
entity control_unit is
port (
clk, rst : in std_logic;
manager_to_controller : in manager_to_controller_t;
controller_to_manager : out controller_to_manager_t;
drivers_to_controller : in drivers_to_controller_t;
controller_to_drivers : out controller_to_drivers_t
);
end entity control_unit;
architecture behave of control_unit is
type state_t is record
address: std_logic_vector(address_width - 1 downto 0);
seq_mem_access_count: integer;
curr_driver: std_logic;
ready: std_logic;
instruction: instruction_command_t;
end record state_t;
signal state: state_t;
shared variable ored: std_logic;
begin
comb_proc: process(manager_to_controller, drivers_to_controller, state)
begin
ored := '0';
ready_reduction: for i in 0 to number_of_drivers - 1 loop
ored := ored or drivers_to_controller.socbridge.is_active;
end loop ready_reduction;
controller_to_drivers.socbridge.request <= state.curr_driver;
controller_to_drivers.socbridge.address <= state.address;
controller_to_drivers.socbridge.seq_mem_access_count <= state.seq_mem_access_count;
controller_to_manager.ready <= state.ready;
controller_to_drivers.socbridge.instruction <= state.instruction;
end process comb_proc;
sync_proc: process(clk, state)
begin
if rising_edge(clk) then
if rst = '1' then
state <= ((others => '0'),
0,
'0',
'1',
NO_OP);
else
-- Make sure to tell the management unit instruction is done
if ored = '0' and state.ready = '0' then
controller_to_manager.done <= '1';
state.ready <= '1';
else
controller_to_manager.done <= '0';
end if;
if ored = '0' then
state.address <= manager_to_controller.address;
state.seq_mem_access_count <= manager_to_controller.seq_mem_access_count;
state.curr_driver <= manager_to_controller.driver_id(0);
if manager_to_controller.cmd = "01" then
state.instruction <= WRITE;
elsif manager_to_controller.cmd = "10" then
state.instruction <= READ;
else
state.instruction <= NO_OP;
end if;
else
state <= ((others => '0'),
0,
'0',
'1',
NO_OP);
end if;
end if;
end if;
end process sync_proc;
end architecture behave;