loadstore1: Eliminate two_dwords variable

The computation of two_dwords from r.second_bytes has shown up as
part of a critical path at times.  Instead we add a 'last_dword'
flag to the reg_stage_t record which tells us more directly
whether a valid flag coming in from dcache means that the
instruction is done, thereby shortening the path to the busy output
back to execute1.

This also simplifies some of the trim_ctl logic.  The two_dwords = 0
case could never have use_second(i) = 1 for any of the bytes being
transferred, so "not use_second(i)" is always 1.

Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
pull/233/head
Paul Mackerras 5 years ago
parent 9160e29c56
commit b2ba024a48

@ -69,6 +69,7 @@ architecture behave of loadstore1 is
priv_mode : std_ulogic;
state : state_t;
dwords_done : std_ulogic;
last_dword : std_ulogic;
first_bytes : std_ulogic_vector(7 downto 0);
second_bytes : std_ulogic_vector(7 downto 0);
dar : std_ulogic_vector(63 downto 0);
@ -146,7 +147,6 @@ begin
variable wdata : std_ulogic_vector(63 downto 0);
variable write_enable : std_ulogic;
variable do_update : std_ulogic;
variable two_dwords : std_ulogic;
variable done : std_ulogic;
variable data_permuted : std_ulogic_vector(63 downto 0);
variable data_trimmed : std_ulogic_vector(63 downto 0);
@ -174,7 +174,6 @@ begin

write_enable := '0';
do_update := '0';
two_dwords := or (r.second_bytes);

-- load data formatting
byte_offset := unsigned(r.addr(2 downto 0));
@ -204,10 +203,10 @@ begin
-- trim and sign-extend
for i in 0 to 7 loop
if i < to_integer(unsigned(r.length)) then
if two_dwords = '1' then
if r.dwords_done = '1' then
trim_ctl(i) := '1' & not use_second(i);
else
trim_ctl(i) := not use_second(i) & '0';
trim_ctl(i) := "10";
end if;
else
trim_ctl(i) := '0' & (negative and r.sign_extend);
@ -237,6 +236,7 @@ begin
byte_sel := r.second_bytes;
req := '1';
v.state := ACK_WAIT;
v.last_dword := '0';

when ACK_WAIT =>
if d_in.valid = '1' then
@ -263,8 +263,9 @@ begin
v.state := MMU_LOOKUP;
end if;
else
if two_dwords = '1' and r.dwords_done = '0' then
if r.last_dword = '0' then
v.dwords_done := '1';
v.last_dword := '1';
if r.load = '1' then
v.load_data := data_permuted;
end if;
@ -297,7 +298,7 @@ begin
if r.instr_fault = '0' then
-- retry the request now that the MMU has installed a TLB entry
req := '1';
if two_dwords = '1' and r.dwords_done = '0' then
if r.last_dword = '0' then
v.state := SECOND_REQ;
else
v.state := ACK_WAIT;
@ -349,6 +350,7 @@ begin
v.tlbie := '0';
v.instr_fault := '0';
v.dwords_done := '0';
v.last_dword := '1';
v.write_reg := l_in.write_reg;
v.length := l_in.length;
v.byte_reverse := l_in.byte_reverse;

Loading…
Cancel
Save