mirror of
https://github.com/antonblanchard/microwatt.git
synced 2026-01-31 05:42:15 +00:00
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>
This commit is contained in:
14
common.vhdl
14
common.vhdl
@@ -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
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
42
decode2.vhdl
42
decode2.vhdl
@@ -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
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user