1
0
mirror of https://github.com/antonblanchard/microwatt.git synced 2026-01-11 23:43:15 +00:00
antonblanchard.microwatt/cr_hazard.vhdl
Benjamin Herrenschmidt e4f475e17f sprs: Store common SPRs in register file
This stores the most common SPRs in the register file.

This includes CTR and LR and a not yet final list of others.

The register file is set to 64 entries for now. Specific types
are defined that can represent a GPR index (gpr_index_t) or
a GPR/SPR index (gspr_index_t) along with conversion functions
between the two.

On order to deal with some forms of branch updating both LR and
CTR, we introduced a delayed update of LR after a branch link.

Note: We currently stall the pipeline on such a delayed branch,
but we could avoid stalling fetch in that specific case as we
know we have a branch delay. We could also limit that to the
specific case where we need to update both CTR and LR.

This allows us to make bcreg, mtspr and mfspr pipelined. decode1
will automatically force the single issue flag on mfspr/mtspr to
a "slow" SPR.

[paulus@ozlabs.org - fix direction of decode2.stall_in]

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
2019-12-07 15:30:40 +11:00

67 lines
1.5 KiB
VHDL

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity cr_hazard is
generic (
PIPELINE_DEPTH : natural := 2
);
port(
clk : in std_ulogic;
stall_in : in std_ulogic;
cr_read_in : in std_ulogic;
cr_write_in : in std_ulogic;
stall_out : out std_ulogic
);
end entity cr_hazard;
architecture behaviour of cr_hazard is
type pipeline_entry_type is record
valid : std_ulogic;
end record;
constant pipeline_entry_init : pipeline_entry_type := (valid => '0');
type pipeline_t is array(0 to PIPELINE_DEPTH-1) of pipeline_entry_type;
constant pipeline_t_init : pipeline_t := (others => pipeline_entry_init);
signal r, rin : pipeline_t := pipeline_t_init;
begin
cr_hazard0: process(clk)
begin
if rising_edge(clk) then
if stall_in = '0' then
r <= rin;
end if;
end if;
end process;
cr_hazard1: process(all)
variable v : pipeline_t;
begin
v := r;
stall_out <= '0';
loop_0: for i in 0 to PIPELINE_DEPTH-1 loop
if (r(i).valid = cr_read_in) then
stall_out <= '1';
end if;
end loop;
v(0).valid := cr_write_in;
loop_1: for i in 0 to PIPELINE_DEPTH-2 loop
-- propagate to next slot
v(i+1) := r(i);
end loop;
-- asynchronous output
if cr_read_in = '0' then
stall_out <= '0';
end if;
-- update registers
rin <= v;
end process;
end;