131 lines
4.2 KiB
VHDL
131 lines
4.2 KiB
VHDL
-- See the file "LICENSE" for the full license governing this code. --
|
|
|
|
library ieee;
|
|
use ieee.std_logic_1164.all;
|
|
use ieee.numeric_std.all;
|
|
use work.lt16x32_internal.all;
|
|
|
|
-- the controlpath mostly covers the pipelining of control signals, but also includes some "glue"-logic
|
|
entity controlpath is
|
|
port(
|
|
-- clock signal
|
|
clk : in std_logic;
|
|
-- reset signal, active high, synchronous
|
|
rst : in std_logic;
|
|
-- stall signal, active high
|
|
stall : in std_logic;
|
|
|
|
-- signals from decoder
|
|
in_dec : in dec_cp;
|
|
-- signals to decoder
|
|
out_dec : out cp_dec;
|
|
|
|
-- signals to datapath
|
|
out_dp : out cp_dp;
|
|
|
|
-- signals to PC counter
|
|
out_pc : out cp_pc;
|
|
|
|
-- signals to data memory
|
|
out_dmem : out cp_dmem;
|
|
|
|
-- signals from datapath
|
|
in_dp : in dp_cp;
|
|
|
|
-- hardfault, active high
|
|
hardfault : out std_logic
|
|
);
|
|
end entity controlpath;
|
|
|
|
architecture RTL of controlpath is
|
|
|
|
-- pipelined signals
|
|
-- decoder information for dp-stage 2 in stage 2
|
|
signal in_dec_2_s2 : dec_cp_s2;
|
|
-- decoder information for dp-stage 3 in stage 2
|
|
signal in_dec_3_s2 : dec_cp_s3;
|
|
-- decoder information for dp-stage 3 in stage 3
|
|
signal in_dec_3_s3 : dec_cp_s3;
|
|
|
|
begin
|
|
-- forward internal signals to ports
|
|
hardfault <= in_dec.hardfault;
|
|
|
|
out_pc.instruction_width <= in_dec.s1.instruction_width;
|
|
|
|
out_dp.s1.register_read_number_a <= in_dec.s1.register_read_number_a;
|
|
out_dp.s1.register_read_number_b <= in_dec.s1.register_read_number_b;
|
|
|
|
out_dp.s2.alu_input_data_select <= in_dec_2_s2.alu_input_data_select;
|
|
out_dp.s2.alu_mode <= in_dec_2_s2.alu_mode;
|
|
out_dp.s2.immediate <= in_dec_2_s2.immediate;
|
|
out_dp.s2.memory_read_addr_select <= in_dec_2_s2.dmem_read_addr_select;
|
|
|
|
out_dmem.read_en <= in_dec_2_s2.dmem_read_en;
|
|
out_dmem.read_size <= in_dec_2_s2.dmem_read_size;
|
|
|
|
out_dmem.write_en <= in_dec_3_s3.dmem_write_en;
|
|
out_dmem.write_size <= in_dec_3_s3.dmem_write_size;
|
|
|
|
out_dp.s3.ovfflag_write_enable <= in_dec_3_s3.ovfflag_write_enable;
|
|
out_dp.s3.memory_write_data_select <= in_dec_3_s3.dmem_write_data_select;
|
|
out_dp.s3.register_write_data_select <= in_dec_3_s3.register_write_data_select;
|
|
out_dp.s3.register_write_enable <= in_dec_3_s3.register_write_enable;
|
|
out_dp.s3.register_write_number <= in_dec_3_s3.register_write_number;
|
|
out_dp.s3.register_write_size <= in_dec_3_s3.register_write_size;
|
|
out_dp.s3.tflag_write_data_select <= in_dec_3_s3.tflag_write_data_select;
|
|
out_dp.s3.tflag_write_enable <= in_dec_3_s3.tflag_write_enable;
|
|
|
|
-- pipeline register stage 1 -> 2
|
|
pipeline_s1_s2 : process(clk) is
|
|
begin
|
|
if (rising_edge(clk)) then
|
|
if (rst = '1') then
|
|
in_dec_2_s2 <= get_default_dec_cp_s2;
|
|
in_dec_3_s2 <= get_default_dec_cp_s3;
|
|
elsif (stall = '0') then
|
|
in_dec_2_s2 <= in_dec.s2;
|
|
in_dec_3_s2 <= in_dec.s3;
|
|
end if;
|
|
end if;
|
|
end process pipeline_s1_s2;
|
|
|
|
-- pipeline register stage 2 -> 3
|
|
pipeline_s2_s3 : process(clk) is
|
|
begin
|
|
if (rising_edge(clk)) then
|
|
if (rst = '1') then
|
|
in_dec_3_s3 <= get_default_dec_cp_s3;
|
|
elsif (stall = '0') then
|
|
in_dec_3_s3 <= in_dec_3_s2;
|
|
end if;
|
|
end if;
|
|
end process pipeline_s2_s3;
|
|
|
|
-- PC signal combinatorics and condition holds flag for decoder
|
|
pc_comb : process(in_dec_2_s2.pc_summand_select, in_dec_2_s2.pc_mode_select, in_dec_2_s2.pc_condition, in_dp.s2.tflag) is
|
|
begin
|
|
case in_dec_2_s2.pc_condition is
|
|
when sel_unconditional =>
|
|
-- without condition, always use proposed pc options
|
|
out_pc.summand_select <= in_dec_2_s2.pc_summand_select;
|
|
out_pc.mode_select <= in_dec_2_s2.pc_mode_select;
|
|
out_dec.condition_holds <= '1';
|
|
when sel_true =>
|
|
-- with condition = true
|
|
if (in_dp.s2.tflag = '1') then
|
|
-- if condition is true (as needed), use proposed pc options
|
|
out_pc.summand_select <= in_dec_2_s2.pc_summand_select;
|
|
out_pc.mode_select <= in_dec_2_s2.pc_mode_select;
|
|
out_dec.condition_holds <= '1';
|
|
else
|
|
-- if condition is false (opposed to what is needed) resume normal pc operation
|
|
out_pc.summand_select <= sel_run;
|
|
out_pc.mode_select <= sel_relative;
|
|
out_dec.condition_holds <= '0';
|
|
end if;
|
|
end case;
|
|
end process pc_comb;
|
|
|
|
end architecture RTL;
|