Files
lt16lab/soc/core/controlpath.vhd
Thomas Fehmel 657a54ba18 Initial Commit
2016-10-18 14:21:45 +02:00

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;