1
0
mirror of https://github.com/antonblanchard/microwatt.git synced 2026-05-04 15:26:12 +00:00

Start removing SPRs from register file

This starts the process of removing SPRs from the register file by
moving SRR0/1, SPRG0-3, HSRR0/1 and HSPRG0/1 out of the register file
and putting them into execute1.  They are stored in a pair of small
RAM arrays, referred to as "even" and "odd".  The reason for having
two arrays is so that two values can be read and written in each
cycle.  For example, SRR0 and SRR1 can be written in parallel by an
interrupt and read in parallel by the rfid instruction.

The addresses in the RAM which will be accessed are determined in the
decode2 stage.  We have one write address for both sides, but two read
addresses, since in future we will want to be able to read CTR at the
same time as either LR or TAR.

We now have a connection from writeback to execute1 which carries the
partial SRR1 value for an interrupt.  SRR0 comes from the execute
pipeline; we no longer need to carry instruction addresses along the
LSU and FPU pipelines.  Since SRR0 and SRR1 can be written in the same
cycle now, we don't need the little state machine in writeback any
more.

Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
This commit is contained in:
Paul Mackerras
2022-07-12 08:52:05 +10:00
parent 73cc5167ec
commit bc4d02cb0d
8 changed files with 242 additions and 108 deletions

View File

@@ -25,20 +25,12 @@ entity writeback is
events : out WritebackEventType;
flush_out : out std_ulogic;
interrupt_out: out std_ulogic;
interrupt_out: out WritebackToExecute1Type;
complete_out : out instr_tag_t
);
end entity writeback;
architecture behaviour of writeback is
type irq_state_t is (WRITE_SRR0, WRITE_SRR1);
type reg_type is record
state : irq_state_t;
srr1 : std_ulogic_vector(63 downto 0);
end record;
signal r, rin : reg_type;
begin
writeback_0: process(clk)
@@ -47,13 +39,6 @@ begin
variable w : std_ulogic_vector(0 downto 0);
begin
if rising_edge(clk) then
if rst = '1' then
r.state <= WRITE_SRR0;
r.srr1 <= (others => '0');
else
r <= rin;
end if;
-- Do consistency checks only on the clock edge
x(0) := e_in.valid;
y(0) := l_in.valid;
@@ -82,7 +67,6 @@ begin
end process;
writeback_1: process(all)
variable v : reg_type;
variable f : WritebackToFetch1Type;
variable scf : std_ulogic_vector(3 downto 0);
variable vec : integer range 0 to 16#fff#;
@@ -92,9 +76,7 @@ begin
w_out <= WritebackToRegisterFileInit;
c_out <= WritebackToCrFileInit;
f := WritebackToFetch1Init;
interrupt_out <= '0';
vec := 0;
v := r;
complete_out <= instr_tag_init;
if e_in.valid = '1' then
@@ -108,37 +90,21 @@ begin
events.fp_complete <= fp_in.valid;
intr := e_in.interrupt or l_in.interrupt or fp_in.interrupt;
interrupt_out.intr <= intr;
if r.state = WRITE_SRR1 then
w_out.write_reg <= fast_spr_num(SPR_SRR1);
w_out.write_data <= r.srr1;
w_out.write_enable <= '1';
interrupt_out <= '1';
v.state := WRITE_SRR0;
elsif intr = '1' then
w_out.write_reg <= fast_spr_num(SPR_SRR0);
w_out.write_enable <= '1';
v.state := WRITE_SRR1;
if intr = '1' then
srr1 := (others => '0');
if e_in.interrupt = '1' then
vec := e_in.intr_vec;
w_out.write_data <= e_in.last_nia;
srr1 := e_in.srr1;
elsif l_in.interrupt = '1' then
vec := l_in.intr_vec;
w_out.write_data <= l_in.srr0;
srr1 := l_in.srr1;
elsif fp_in.interrupt = '1' then
vec := fp_in.intr_vec;
w_out.write_data <= fp_in.srr0;
srr1 := fp_in.srr1;
end if;
v.srr1(63 downto 31) := e_in.msr(63 downto 31);
v.srr1(30 downto 27) := srr1(14 downto 11);
v.srr1(26 downto 22) := e_in.msr(26 downto 22);
v.srr1(21 downto 16) := srr1(5 downto 0);
v.srr1(15 downto 0) := e_in.msr(15 downto 0);
interrupt_out.srr1 <= srr1;
else
if e_in.write_enable = '1' then
@@ -229,6 +195,5 @@ begin
wb_bypass.tag.valid <= complete_out.valid and w_out.write_enable;
wb_bypass.data <= w_out.write_data;
rin <= v;
end process;
end;