Plumb loadstore1 input from execute1 not decode2

This allows us to use the bypass at the input of execute1 for the
address and data operands for loadstore1.

Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
pull/134/head
Paul Mackerras 4 years ago
parent b14d982011
commit 5422007f83

@ -127,12 +127,16 @@ package common is
is_signed: std_ulogic; is_signed: std_ulogic;
insn: std_ulogic_vector(31 downto 0); insn: std_ulogic_vector(31 downto 0);
data_len: std_ulogic_vector(3 downto 0); data_len: std_ulogic_vector(3 downto 0);
byte_reverse : std_ulogic;
sign_extend : std_ulogic; -- do we need to sign extend?
update : std_ulogic; -- is this an update instruction?
end record; end record;
constant Decode2ToExecute1Init : Decode2ToExecute1Type := constant Decode2ToExecute1Init : Decode2ToExecute1Type :=
(valid => '0', insn_type => OP_ILLEGAL, bypass_data1 => '0', bypass_data2 => '0', bypass_data3 => '0', (valid => '0', insn_type => OP_ILLEGAL, bypass_data1 => '0', bypass_data2 => '0', bypass_data3 => '0',
lr => '0', rc => '0', oe => '0', invert_a => '0', lr => '0', rc => '0', oe => '0', invert_a => '0',
invert_out => '0', input_carry => ZERO, output_carry => '0', input_cr => '0', output_cr => '0', invert_out => '0', input_carry => ZERO, output_carry => '0', input_cr => '0', output_cr => '0',
is_32bit => '0', is_signed => '0', xerc => xerc_init, others => (others => '0')); is_32bit => '0', is_signed => '0', xerc => xerc_init,
byte_reverse => '0', sign_extend => '0', update => '0', others => (others => '0'));


type Execute1ToMultiplyType is record type Execute1ToMultiplyType is record
valid: std_ulogic; valid: std_ulogic;
@ -189,7 +193,7 @@ package common is
end record; end record;
constant Execute1ToFetch1TypeInit : Execute1ToFetch1Type := (redirect => '0', others => (others => '0')); constant Execute1ToFetch1TypeInit : Execute1ToFetch1Type := (redirect => '0', others => (others => '0'));


type Decode2ToLoadstore1Type is record type Execute1ToLoadstore1Type is record
valid : std_ulogic; valid : std_ulogic;
load : std_ulogic; -- is this a load or store load : std_ulogic; -- is this a load or store
addr1 : std_ulogic_vector(63 downto 0); addr1 : std_ulogic_vector(63 downto 0);
@ -203,9 +207,9 @@ package common is
update_reg : gpr_index_t; -- if so, the register to update update_reg : gpr_index_t; -- if so, the register to update
xerc : xer_common_t; xerc : xer_common_t;
end record; end record;
constant Decode2ToLoadstore1Init : Decode2ToLoadstore1Type := (valid => '0', load => '0', byte_reverse => '0', constant Execute1ToLoadstore1Init : Execute1ToLoadstore1Type := (valid => '0', load => '0', byte_reverse => '0',
sign_extend => '0', update => '0', xerc => xerc_init, sign_extend => '0', update => '0', xerc => xerc_init,
others => (others => '0')); others => (others => '0'));


type Loadstore1ToDcacheType is record type Loadstore1ToDcacheType is record
valid : std_ulogic; valid : std_ulogic;

@ -60,7 +60,7 @@ architecture behave of core is
signal execute1_to_fetch1: Execute1ToFetch1Type; signal execute1_to_fetch1: Execute1ToFetch1Type;


-- load store signals -- load store signals
signal decode2_to_loadstore1: Decode2ToLoadstore1Type; signal execute1_to_loadstore1: Execute1ToLoadstore1Type;
signal loadstore1_to_dcache: Loadstore1ToDcacheType; signal loadstore1_to_dcache: Loadstore1ToDcacheType;
signal dcache_to_writeback: DcacheToWritebackType; signal dcache_to_writeback: DcacheToWritebackType;


@ -190,7 +190,6 @@ begin
stopped_out => dbg_core_is_stopped, stopped_out => dbg_core_is_stopped,
d_in => decode1_to_decode2, d_in => decode1_to_decode2,
e_out => decode2_to_execute1, e_out => decode2_to_execute1,
l_out => decode2_to_loadstore1,
r_in => register_file_to_decode2, r_in => register_file_to_decode2,
r_out => decode2_to_register_file, r_out => decode2_to_register_file,
c_in => cr_file_to_decode2, c_in => cr_file_to_decode2,
@ -233,6 +232,7 @@ begin
flush_out => flush, flush_out => flush,
stall_out => ex1_stall_out, stall_out => ex1_stall_out,
e_in => decode2_to_execute1, e_in => decode2_to_execute1,
l_out => execute1_to_loadstore1,
f_out => execute1_to_fetch1, f_out => execute1_to_fetch1,
e_out => execute1_to_writeback, e_out => execute1_to_writeback,
icache_inval => ex1_icache_inval, icache_inval => ex1_icache_inval,
@ -242,7 +242,7 @@ begin
loadstore1_0: entity work.loadstore1 loadstore1_0: entity work.loadstore1
port map ( port map (
clk => clk, clk => clk,
l_in => decode2_to_loadstore1, l_in => execute1_to_loadstore1,
l_out => loadstore1_to_dcache l_out => loadstore1_to_dcache
); );



@ -27,7 +27,6 @@ entity decode2 is
d_in : in Decode1ToDecode2Type; d_in : in Decode1ToDecode2Type;


e_out : out Decode2ToExecute1Type; e_out : out Decode2ToExecute1Type;
l_out : out Decode2ToLoadstore1Type;


r_in : in RegisterFileToDecode2Type; r_in : in RegisterFileToDecode2Type;
r_out : out Decode2ToRegisterFileType; r_out : out Decode2ToRegisterFileType;
@ -40,7 +39,6 @@ end entity decode2;
architecture behaviour of decode2 is architecture behaviour of decode2 is
type reg_type is record type reg_type is record
e : Decode2ToExecute1Type; e : Decode2ToExecute1Type;
l : Decode2ToLoadstore1Type;
end record; end record;


signal r, rin : reg_type; signal r, rin : reg_type;
@ -246,7 +244,7 @@ begin
decode2_0: process(clk) decode2_0: process(clk)
begin begin
if rising_edge(clk) then if rising_edge(clk) then
if rin.e.valid = '1' or rin.l.valid = '1' then if rin.e.valid = '1' then
report "execute " & to_hstring(rin.e.nia); report "execute " & to_hstring(rin.e.nia);
end if; end if;
r <= rin; r <= rin;
@ -272,7 +270,6 @@ begin
v := r; v := r;


v.e := Decode2ToExecute1Init; v.e := Decode2ToExecute1Init;
v.l := Decode2ToLoadStore1Init;


mul_a := (others => '0'); mul_a := (others => '0');
mul_b := (others => '0'); mul_b := (others => '0');
@ -331,25 +328,9 @@ begin
end if; end if;
v.e.insn := d_in.insn; v.e.insn := d_in.insn;
v.e.data_len := length; v.e.data_len := length;

v.e.byte_reverse := d_in.decode.byte_reverse;
-- load/store unit v.e.sign_extend := d_in.decode.sign_extend;
v.l.update_reg := gspr_to_gpr(decoded_reg_a.reg); v.e.update := d_in.decode.update;
v.l.addr1 := decoded_reg_a.data;
v.l.addr2 := decoded_reg_b.data;
v.l.data := decoded_reg_c.data;
v.l.write_reg := gspr_to_gpr(decoded_reg_o.reg);

if d_in.decode.insn_type = OP_LOAD then
v.l.load := '1';
else
v.l.load := '0';
end if;

v.l.length := length;
v.l.byte_reverse := d_in.decode.byte_reverse;
v.l.sign_extend := d_in.decode.sign_extend;
v.l.update := d_in.decode.update;
v.l.xerc := c_in.read_xerc_data;


-- issue control -- issue control
control_valid_in <= d_in.valid; control_valid_in <= d_in.valid;
@ -373,21 +354,13 @@ begin


cr_write_valid <= d_in.decode.output_cr or decode_rc(d_in.decode.rc, d_in.insn); cr_write_valid <= d_in.decode.output_cr or decode_rc(d_in.decode.rc, d_in.insn);


v.e.valid := '0'; v.e.valid := control_valid_out;
v.l.valid := '0'; if d_in.decode.unit = NONE then
case d_in.decode.unit is
when ALU =>
v.e.valid := control_valid_out;
when LDST =>
v.l.valid := control_valid_out;
when NONE =>
v.e.valid := control_valid_out;
v.e.insn_type := OP_ILLEGAL; v.e.insn_type := OP_ILLEGAL;
end case; end if;


if rst = '1' then if rst = '1' then
v.e := Decode2ToExecute1Init; v.e := Decode2ToExecute1Init;
v.l := Decode2ToLoadStore1Init;
end if; end if;


-- Update registers -- Update registers
@ -395,6 +368,5 @@ begin


-- Update outputs -- Update outputs
e_out <= r.e; e_out <= r.e;
l_out <= r.l;
end process; end process;
end architecture behaviour; end architecture behaviour;

@ -25,6 +25,7 @@ entity execute1 is
e_in : in Decode2ToExecute1Type; e_in : in Decode2ToExecute1Type;


-- asynchronous -- asynchronous
l_out : out Execute1ToLoadstore1Type;
f_out : out Execute1ToFetch1Type; f_out : out Execute1ToFetch1Type;


e_out : out Execute1ToWritebackType; e_out : out Execute1ToWritebackType;
@ -210,6 +211,7 @@ begin
variable zerohi, zerolo : std_ulogic; variable zerohi, zerolo : std_ulogic;
variable msb_a, msb_b : std_ulogic; variable msb_a, msb_b : std_ulogic;
variable a_lt : std_ulogic; variable a_lt : std_ulogic;
variable lv : Execute1ToLoadstore1Type;
begin begin
result := (others => '0'); result := (others => '0');
result_with_carry := (others => '0'); result_with_carry := (others => '0');
@ -667,6 +669,10 @@ begin
stall_out <= '1'; stall_out <= '1';
x_to_divider.valid <= '1'; x_to_divider.valid <= '1';


when OP_LOAD | OP_STORE =>
-- loadstore/dcache has its own port to writeback
v.e.valid := '0';

when others => when others =>
terminate_out <= '1'; terminate_out <= '1';
report "illegal"; report "illegal";
@ -731,11 +737,31 @@ begin
v.e.write_data := result; v.e.write_data := result;
v.e.write_enable := result_en; v.e.write_enable := result_en;


-- Outputs to loadstore1 (async)
lv := Execute1ToLoadstore1Init;
if e_in.valid = '1' and (e_in.insn_type = OP_LOAD or e_in.insn_type = OP_STORE) then
lv.valid := '1';
end if;
if e_in.insn_type = OP_LOAD then
lv.load := '1';
end if;
lv.addr1 := a_in;
lv.addr2 := b_in;
lv.data := c_in;
lv.write_reg := gspr_to_gpr(e_in.write_reg);
lv.length := e_in.data_len;
lv.byte_reverse := e_in.byte_reverse;
lv.sign_extend := e_in.sign_extend;
lv.update := e_in.update;
lv.update_reg := gspr_to_gpr(e_in.read_reg1);
lv.xerc := v.e.xerc;

-- Update registers -- Update registers
rin <= v; rin <= v;


-- update outputs -- update outputs
--f_out <= r.f; --f_out <= r.f;
l_out <= lv;
e_out <= r.e; e_out <= r.e;
flush_out <= f_out.redirect; flush_out <= f_out.redirect;
end process; end process;

@ -13,7 +13,7 @@ entity loadstore1 is
port ( port (
clk : in std_ulogic; clk : in std_ulogic;


l_in : in Decode2ToLoadstore1Type; l_in : in Execute1ToLoadstore1Type;


l_out : out Loadstore1ToDcacheType l_out : out Loadstore1ToDcacheType
); );

Loading…
Cancel
Save