From b2ba024a4885f026200bdfb6ef804ed0f9dd72ca Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Fri, 10 Jul 2020 20:11:15 +1000 Subject: [PATCH] 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 --- loadstore1.vhdl | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/loadstore1.vhdl b/loadstore1.vhdl index cf00987..dd11221 100644 --- a/loadstore1.vhdl +++ b/loadstore1.vhdl @@ -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;