fetch1: Change the way predictions from the BTC are sent downstream

Instead of sending down the predicted taken/not-taken bits with the
target of the branch, we now send them down with the branch itself.
Previously icache adjusted for this by sending the prediction bits to
decode1 without a 1-clock delay while everything else had a 1-clock
delay.  Now icache keeps the prediction bits with the rest of the
attributes for the request.

Also fix a buglet in fetch1 where the first address sent out after
reset didn't have .req set.  Currently this doesn't cause a problem
because icache doesn't really look at .req.

Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
pull/419/head
Paul Mackerras 2 years ago
parent 83dcfeabf8
commit 4416ebe92e

@ -41,7 +41,6 @@ architecture behaviour of fetch1 is
mode_32bit: std_ulogic; mode_32bit: std_ulogic;
rd_is_niap4: std_ulogic; rd_is_niap4: std_ulogic;
predicted_taken: std_ulogic; predicted_taken: std_ulogic;
pred_not_taken: std_ulogic;
predicted_nia: std_ulogic_vector(63 downto 0); predicted_nia: std_ulogic_vector(63 downto 0);
end record; end record;
signal r, r_next : Fetch1ToIcacheType; signal r, r_next : Fetch1ToIcacheType;
@ -87,7 +86,6 @@ begin
r.pred_ntaken <= r_next.pred_ntaken; r.pred_ntaken <= r_next.pred_ntaken;
r.nia <= r_next.nia; r.nia <= r_next.nia;
r_int.predicted_taken <= r_next_int.predicted_taken; r_int.predicted_taken <= r_next_int.predicted_taken;
r_int.pred_not_taken <= r_next_int.pred_not_taken;
r_int.predicted_nia <= r_next_int.predicted_nia; r_int.predicted_nia <= r_next_int.predicted_nia;
r_int.rd_is_niap4 <= r_next_int.rd_is_niap4; r_int.rd_is_niap4 <= r_next_int.rd_is_niap4;
end if; end if;
@ -155,7 +153,6 @@ begin
v.predicted := '0'; v.predicted := '0';
v.pred_ntaken := '0'; v.pred_ntaken := '0';
v_int.predicted_taken := '0'; v_int.predicted_taken := '0';
v_int.pred_not_taken := '0';
v_int.rd_is_niap4 := '0'; v_int.rd_is_niap4 := '0';


if rst = '1' then if rst = '1' then
@ -185,10 +182,8 @@ begin
end if; end if;
elsif r_int.predicted_taken = '1' then elsif r_int.predicted_taken = '1' then
v.nia := r_int.predicted_nia; v.nia := r_int.predicted_nia;
v.predicted := '1'; elsif r.req = '1' then
else
v_int.rd_is_niap4 := '1'; v_int.rd_is_niap4 := '1';
v.pred_ntaken := r_int.pred_not_taken;
v.nia := std_ulogic_vector(unsigned(r.nia) + 4); v.nia := std_ulogic_vector(unsigned(r.nia) + 4);
if r_int.mode_32bit = '1' then if r_int.mode_32bit = '1' then
v.nia(63 downto 32) := x"00000000"; v.nia(63 downto 32) := x"00000000";
@ -198,7 +193,8 @@ begin
btc_rd_data(BTC_WIDTH - 3 downto BTC_TARGET_BITS) btc_rd_data(BTC_WIDTH - 3 downto BTC_TARGET_BITS)
= v.nia(BTC_TAG_BITS + BTC_ADDR_BITS + 1 downto BTC_ADDR_BITS + 2) then = v.nia(BTC_TAG_BITS + BTC_ADDR_BITS + 1 downto BTC_ADDR_BITS + 2) then
v_int.predicted_taken := btc_rd_data(BTC_WIDTH - 1); v_int.predicted_taken := btc_rd_data(BTC_WIDTH - 1);
v_int.pred_not_taken := not btc_rd_data(BTC_WIDTH - 1); v.predicted := btc_rd_data(BTC_WIDTH - 1);
v.pred_ntaken := not btc_rd_data(BTC_WIDTH - 1);
end if; end if;
end if; end if;
v_int.predicted_nia := btc_rd_data(BTC_TARGET_BITS - 1 downto 0) & "00"; v_int.predicted_nia := btc_rd_data(BTC_TARGET_BITS - 1 downto 0) & "00";

@ -192,6 +192,8 @@ architecture rtl of icache is
hit_smark : std_ulogic; hit_smark : std_ulogic;
hit_valid : std_ulogic; hit_valid : std_ulogic;
big_endian: std_ulogic; big_endian: std_ulogic;
predicted : std_ulogic;
pred_ntaken: std_ulogic;


-- Cache miss state (reload state machine) -- Cache miss state (reload state machine)
state : state_t; state : state_t;
@ -629,8 +631,8 @@ begin
i_out.stop_mark <= r.hit_smark; i_out.stop_mark <= r.hit_smark;
i_out.fetch_failed <= r.fetch_failed; i_out.fetch_failed <= r.fetch_failed;
i_out.big_endian <= r.big_endian; i_out.big_endian <= r.big_endian;
i_out.next_predicted <= i_in.predicted; i_out.next_predicted <= r.predicted;
i_out.next_pred_ntaken <= i_in.pred_ntaken; i_out.next_pred_ntaken <= r.pred_ntaken;


-- Stall fetch1 if we have a miss on cache or TLB or a protection fault -- Stall fetch1 if we have a miss on cache or TLB or a protection fault
stall_out <= not (is_hit and access_ok); stall_out <= not (is_hit and access_ok);
@ -673,6 +675,8 @@ begin
r.hit_smark <= i_in.stop_mark; r.hit_smark <= i_in.stop_mark;
r.hit_nia <= i_in.nia; r.hit_nia <= i_in.nia;
r.big_endian <= i_in.big_endian; r.big_endian <= i_in.big_endian;
r.predicted <= i_in.predicted;
r.pred_ntaken <= i_in.pred_ntaken;
end if; end if;
if i_out.valid = '1' then if i_out.valid = '1' then
assert not is_X(i_out.insn) severity failure; assert not is_X(i_out.insn) severity failure;

Loading…
Cancel
Save