From d05b661c96d466e872e881ca34f3afa6b42b569c Mon Sep 17 00:00:00 2001 From: Minseong Jang Date: Wed, 4 Sep 2024 12:39:29 +0900 Subject: [PATCH] Update branch predictor skeleton code --- .../src/cpu/branch_predictor/bht.rs | 4 ++-- .../src/cpu/branch_predictor/mod.rs | 9 +++++++-- hazardflow-designs/src/cpu/decode.rs | 20 +++++++++++++------ hazardflow-designs/src/cpu/fetch.rs | 8 ++++---- scripts/cpu/constants.py | 18 ++++++++--------- 5 files changed, 36 insertions(+), 23 deletions(-) diff --git a/hazardflow-designs/src/cpu/branch_predictor/bht.rs b/hazardflow-designs/src/cpu/branch_predictor/bht.rs index 52920bb..c18793a 100644 --- a/hazardflow-designs/src/cpu/branch_predictor/bht.rs +++ b/hazardflow-designs/src/cpu/branch_predictor/bht.rs @@ -66,10 +66,10 @@ impl Bht { todo!("assignment 2") } - /// Returns the updated BHT when a branch misprediction occurs at the given PC. + /// Returns the updated BHT when a branch instruction resolves at the execute stage with the given PC. /// /// It updates the entry corresponding to the given PC. - pub fn update(self, _pc: u32) -> Self { + pub fn update(self, _pc: u32, _taken: bool) -> Self { todo!("assignment 2") } } diff --git a/hazardflow-designs/src/cpu/branch_predictor/mod.rs b/hazardflow-designs/src/cpu/branch_predictor/mod.rs index 9213455..19d1796 100644 --- a/hazardflow-designs/src/cpu/branch_predictor/mod.rs +++ b/hazardflow-designs/src/cpu/branch_predictor/mod.rs @@ -31,8 +31,13 @@ pub struct BpResult { pub enum BpUpdate { /// Updates BHT. /// - /// It contains the mispredicted PC. - Bht(u32), + /// It contains the branch instruction PC and the direction. + Bht { + /// Branch instruction PC. + pc: u32, + /// Taken or not taken. + taken: bool, + }, /// Updates BTB. /// diff --git a/hazardflow-designs/src/cpu/decode.rs b/hazardflow-designs/src/cpu/decode.rs index 2e38eac..9b6e030 100644 --- a/hazardflow-designs/src/cpu/decode.rs +++ b/hazardflow-designs/src/cpu/decode.rs @@ -45,6 +45,16 @@ pub struct DecEP { pub debug_inst: u32, } +/// Hazard from decode stage to fetch stage. +#[derive(Debug, Clone, Copy)] +pub struct DecR { + /// Indicates that the fetch stage is killed or not. + pub kill: bool, + + /// Next PC selector. + pub pc_sel: PcSel, +} + /// Decode stage ingress interface hazard. #[derive(Debug, Clone, Copy)] pub struct DecH; @@ -69,12 +79,12 @@ impl Hazard for DecH { } /// Generates resolver from decode stage to fetch stage. -fn gen_resolver(er: (HOption<(FetEP, Instruction)>, ExeR, MemR, WbR)) -> (bool, PcSel) { +fn gen_resolver(er: (HOption<(FetEP, Instruction)>, ExeR, MemR, WbR)) -> DecR { let (p, exer, memr, _) = er; let inst = p.map(|(_, inst)| inst); let is_fencei = inst.is_some_and(|inst| inst.is_fencei); - let if_kill = exer.if_kill || is_fencei || memr.pipeline_kill; + let kill = exer.if_kill || is_fencei || memr.pipeline_kill; let pc_sel = if matches!(exer.pc_sel, PcSel::Jmp { .. } | PcSel::Exception(_)) { exer.pc_sel @@ -84,7 +94,7 @@ fn gen_resolver(er: (HOption<(FetEP, Instruction)>, ExeR, MemR, WbR)) -> (bool, exer.pc_sel }; - (if_kill, pc_sel) + DecR { kill, pc_sel } } /// Generates payload from decode stage to execute stage. @@ -151,9 +161,7 @@ fn gen_payload(ip: FetEP, inst: Instruction, er: (ExeR, MemR, WbR)) -> HOption, { Dep::Demanding }>, -) -> I, { Dep::Demanding }> { +pub fn decode(i: I, { Dep::Demanding }>) -> I, { Dep::Demanding }> { i.map_resolver_inner::<(HOption<(FetEP, Instruction)>, ExeR, MemR, WbR)>(gen_resolver) .reg_fwd(true) .map(|p| (p, Instruction::from(p.imem_resp.data))) diff --git a/hazardflow-designs/src/cpu/fetch.rs b/hazardflow-designs/src/cpu/fetch.rs index 980b2d9..9f82435 100644 --- a/hazardflow-designs/src/cpu/fetch.rs +++ b/hazardflow-designs/src/cpu/fetch.rs @@ -39,7 +39,7 @@ pub struct FetEP { /// Fetch stage. pub fn fetch( imem: impl FnOnce(Vr) -> Vr, -) -> I, { Dep::Demanding }> { +) -> I, { Dep::Demanding }> { let next_pc = , PcSel), _>, { Dep::Demanding }>>::source_drop() .filter_map(|(p, pc_sel)| match pc_sel { PcSel::Jmp(target) | PcSel::Exception(target) => Some(target), @@ -52,9 +52,9 @@ pub fn fetch( .map(|pc| MemReq::load(pc, MemOpTyp::WU)) .comb::, { Dep::Helpful }>>(attach_resolver(imem)) .map(|imem_resp| FetEP { imem_resp }) - .map_resolver_drop_with_p::>(|ip, er| { - let (kill, pc_sel) = er.inner; + .map_resolver_drop_with_p::>(|ip, er| { + let DecR { kill, pc_sel } = er.inner; Ready::new(er.ready || kill, (ip, pc_sel)) // We need `kill` here to extract the mispredicted PC from register, and then filter out them. }) - .filter_map_drop_with_r_inner(|resp, (killed, _)| if !killed { Some(resp) } else { None }) + .filter_map_drop_with_r_inner(|resp, er| if !er.kill { Some(resp) } else { None }) } diff --git a/scripts/cpu/constants.py b/scripts/cpu/constants.py index 000dd1b..afa5131 100644 --- a/scripts/cpu/constants.py +++ b/scripts/cpu/constants.py @@ -32,15 +32,15 @@ } # Cached CPI values for branch prediction BRANCH_PREDICTION_CPI = { - "aes": 1.0886296740433883, - "coremark": 1.2187339929366727, - "ellpack": 1.0596931299025947, - "gemm-block": 1.1967700018563208, - "gemm": 1.1938486919632336, - "kmp": 1.0171380924892566, - "nw": 1.0771787743261212, - "queue": 1.1282135101688187, - "radix": 1.1176876179416462, + "aes": 1.073133514986376, + "coremark": 1.1979357129607546, + "ellpack": 1.057687344059193, + "gemm-block": 1.1849320790656486, + "gemm": 1.181595521343597, + "kmp": 1.0109134952508447, + "nw": 1.073114438245093, + "queue": 1.1186424853535, + "radix": 1.0883295248415745, } FORMAT = "%(message)s" # Logger format