library ieee;
use ieee.std_logic_1164.all;
+library work;
+use work.common.all;
+
entity control is
generic (
PIPELINE_DEPTH : natural := 2
complete_in : in std_ulogic;
valid_in : in std_ulogic;
flush_in : in std_ulogic;
+ busy_in : in std_ulogic;
+ deferred : in std_ulogic;
sgl_pipe_in : in std_ulogic;
stop_mark_in : in std_ulogic;
gpr_write_valid_in : in std_ulogic;
- gpr_write_in : in std_ulogic_vector(4 downto 0);
+ gpr_write_in : in gspr_index_t;
+ gpr_bypassable : in std_ulogic;
+
+ update_gpr_write_valid : in std_ulogic;
+ update_gpr_write_reg : in gspr_index_t;
gpr_a_read_valid_in : in std_ulogic;
- gpr_a_read_in : in std_ulogic_vector(4 downto 0);
+ gpr_a_read_in : in gspr_index_t;
gpr_b_read_valid_in : in std_ulogic;
- gpr_b_read_in : in std_ulogic_vector(4 downto 0);
+ gpr_b_read_in : in gspr_index_t;
gpr_c_read_valid_in : in std_ulogic;
- gpr_c_read_in : in std_ulogic_vector(4 downto 0);
+ gpr_c_read_in : in gspr_index_t;
cr_read_in : in std_ulogic;
cr_write_in : in std_ulogic;
+ cr_bypassable : in std_ulogic;
valid_out : out std_ulogic;
stall_out : out std_ulogic;
- stopped_out : out std_ulogic
+ stopped_out : out std_ulogic;
+
+ gpr_bypass_a : out std_ulogic;
+ gpr_bypass_b : out std_ulogic;
+ gpr_bypass_c : out std_ulogic;
+ cr_bypass : out std_ulogic
);
end entity control;
signal gpr_write_valid : std_ulogic := '0';
signal cr_write_valid : std_ulogic := '0';
+
begin
gpr_hazard0: entity work.gpr_hazard
generic map (
- PIPELINE_DEPTH => 2
+ PIPELINE_DEPTH => PIPELINE_DEPTH
)
port map (
clk => clk,
+ busy_in => busy_in,
+ deferred => deferred,
+ complete_in => complete_in,
+ flush_in => flush_in,
+ issuing => valid_out,
gpr_write_valid_in => gpr_write_valid,
gpr_write_in => gpr_write_in,
+ bypass_avail => gpr_bypassable,
gpr_read_valid_in => gpr_a_read_valid_in,
gpr_read_in => gpr_a_read_in,
- stall_out => stall_a_out
+ ugpr_write_valid => update_gpr_write_valid,
+ ugpr_write_reg => update_gpr_write_reg,
+
+ stall_out => stall_a_out,
+ use_bypass => gpr_bypass_a
);
gpr_hazard1: entity work.gpr_hazard
generic map (
- PIPELINE_DEPTH => 2
+ PIPELINE_DEPTH => PIPELINE_DEPTH
)
port map (
clk => clk,
+ busy_in => busy_in,
+ deferred => deferred,
+ complete_in => complete_in,
+ flush_in => flush_in,
+ issuing => valid_out,
gpr_write_valid_in => gpr_write_valid,
gpr_write_in => gpr_write_in,
+ bypass_avail => gpr_bypassable,
gpr_read_valid_in => gpr_b_read_valid_in,
gpr_read_in => gpr_b_read_in,
- stall_out => stall_b_out
+ ugpr_write_valid => update_gpr_write_valid,
+ ugpr_write_reg => update_gpr_write_reg,
+
+ stall_out => stall_b_out,
+ use_bypass => gpr_bypass_b
);
gpr_hazard2: entity work.gpr_hazard
generic map (
- PIPELINE_DEPTH => 2
+ PIPELINE_DEPTH => PIPELINE_DEPTH
)
port map (
clk => clk,
+ busy_in => busy_in,
+ deferred => deferred,
+ complete_in => complete_in,
+ flush_in => flush_in,
+ issuing => valid_out,
gpr_write_valid_in => gpr_write_valid,
gpr_write_in => gpr_write_in,
+ bypass_avail => gpr_bypassable,
gpr_read_valid_in => gpr_c_read_valid_in,
gpr_read_in => gpr_c_read_in,
- stall_out => stall_c_out
+ ugpr_write_valid => update_gpr_write_valid,
+ ugpr_write_reg => update_gpr_write_reg,
+
+ stall_out => stall_c_out,
+ use_bypass => gpr_bypass_c
);
cr_hazard0: entity work.cr_hazard
generic map (
- PIPELINE_DEPTH => 2
+ PIPELINE_DEPTH => PIPELINE_DEPTH
)
port map (
clk => clk,
+ busy_in => busy_in,
+ deferred => deferred,
+ complete_in => complete_in,
+ flush_in => flush_in,
+ issuing => valid_out,
cr_read_in => cr_read_in,
cr_write_in => cr_write_valid,
+ bypassable => cr_bypassable,
- stall_out => cr_stall_out
+ stall_out => cr_stall_out,
+ use_bypass => cr_bypass
);
control0: process(clk)
begin
if rising_edge(clk) then
- assert r_int.outstanding >= 0 and r_int.outstanding <= (PIPELINE_DEPTH+1) report "Outstanding bad " & integer'image(r_int.outstanding) severity failure;
+ assert rin_int.outstanding >= 0 and rin_int.outstanding <= (PIPELINE_DEPTH+1)
+ report "Outstanding bad " & integer'image(rin_int.outstanding) severity failure;
r_int <= rin_int;
end if;
end process;
valid_tmp := valid_in and not flush_in;
stall_tmp := '0';
- if complete_in = '1' then
+ if flush_in = '1' then
+ -- expect to see complete_in next cycle
+ v_int.outstanding := 1;
+ elsif complete_in = '1' then
v_int.outstanding := r_int.outstanding - 1;
end if;
+ if rst = '1' then
+ v_int := reg_internal_init;
+ valid_tmp := '0';
+ end if;
+
-- Handle debugger stop
stopped_out <= '0';
if stop_mark_in = '1' and v_int.outstanding = 0 then
end if;
if valid_tmp = '1' then
- v_int.outstanding := v_int.outstanding + 1;
+ if deferred = '0' then
+ v_int.outstanding := v_int.outstanding + 1;
+ end if;
gpr_write_valid <= gpr_write_valid_in;
cr_write_valid <= cr_write_in;
else
cr_write_valid <= '0';
end if;
- if rst = '1' then
- v_int.state := IDLE;
- v_int.outstanding := 0;
- stall_tmp := '0';
- end if;
-
-- update outputs
valid_out <= valid_tmp;
- stall_out <= stall_tmp;
+ stall_out <= stall_tmp or deferred;
-- update registers
rin_int <= v_int;