From e49192cb5bbaf259aa66268a46fb1c6da9a54b59 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Tue, 24 Nov 2020 11:53:17 +1100 Subject: [PATCH] execute1: Fix forwarding of result when doing delayed LR update Random execution testcases showed that a bdnzl which doesn't branch, followed immediately by a bdnz, uses the wrong value for CTR for the bdnz. Decode2 detects the read-after-write hazard on CTR and tells execute1 to use the bypass path. However, the bdnzl takes two cycles because it has to write back both CTR and LR, meaning that by the time the bdnz starts to execute, r.e.write_data no longer contains the CTR value, but instead contains zero. To fix this, we make execute1 maintain the written-back value of CTR in r.e.write_data across the cycle where LR is written back (this is possible because the LR writeback uses the exc_write_data path). Signed-off-by: Paul Mackerras --- execute1.vhdl | 3 +++ 1 file changed, 3 insertions(+) diff --git a/execute1.vhdl b/execute1.vhdl index 61df974..4f85f3d 100644 --- a/execute1.vhdl +++ b/execute1.vhdl @@ -1145,6 +1145,9 @@ begin v.e.exc_write_data := r.next_lr; v.e.exc_write_reg := fast_spr_num(SPR_LR); v.e.valid := '1'; + -- Keep r.e.write_data unchanged next cycle in case it is needed + -- for a forwarded result (e.g. for CTR). + result := r.e.write_data; elsif r.cntz_in_progress = '1' then -- cnt[lt]z always takes two cycles result := countzero_result;