2021-06-04 09:06:35 +08:00
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Copyright ( c ) 2020 - 2021 Institute of Computing Technology , Chinese Academy of Sciences
2021-07-24 23:26:38 +08:00
* Copyright ( c ) 2020 - 2021 Peng Cheng Laboratory
2021-06-04 09:06:35 +08:00
*
* XiangShan is licensed under Mulan PSL v2 .
* You can use this software according to the terms and conditions of the Mulan PSL v2 .
* You may obtain a copy of Mulan PSL v2 at :
* http : //license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS , WITHOUT WARRANTIES OF ANY KIND ,
* EITHER EXPRESS OR IMPLIED , INCLUDING BUT NOT LIMITED TO NON - INFRINGEMENT ,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE .
*
* See the Mulan PSL v2 for more details .
***************************************************************************************/
2020-08-06 16:58:13 +08:00
package xiangshan.mem
2021-04-19 21:19:20 +08:00
import chipsalliance.rocketchip.config.Parameters
2020-08-06 16:58:13 +08:00
import chisel3._
import chisel3.util._
import utils._
2021-12-09 20:15:29 +08:00
import xiangshan.ExceptionNO._
2020-08-06 16:58:13 +08:00
import xiangshan._
2021-10-11 21:56:10 +08:00
import xiangshan.backend.fu.PMPRespBundle
2020-10-25 13:24:10 +08:00
import xiangshan.cache._
2021-12-09 20:15:29 +08:00
import xiangshan.cache.mmu. { TlbCmd , TlbReq , TlbRequestIO , TlbResp }
2020-08-06 16:58:13 +08:00
2021-04-19 21:19:20 +08:00
class LoadToLsqIO ( implicit p : Parameters ) extends XSBundle {
2020-08-06 16:58:13 +08:00
val loadIn = ValidIO ( new LsPipelineBundle )
val ldout = Flipped ( DecoupledIO ( new ExuOutput ) )
2021-01-25 19:46:19 +08:00
val loadDataForwarded = Output ( Bool ( ) )
2021-02-05 23:10:00 +08:00
val needReplayFromRS = Output ( Bool ( ) )
2021-04-30 10:40:51 +08:00
val forward = new PipeLoadForwardQueryIO
2021-10-22 15:29:07 +08:00
val loadViolationQuery = new LoadViolationQueryIO
2020-08-06 16:58:13 +08:00
}
2021-08-20 22:39:07 +08:00
class LoadToLoadIO ( implicit p : Parameters ) extends XSBundle {
2021-09-28 09:23:31 +08:00
// load to load fast path is limited to ld (64 bit) used as vaddr src1 only
2021-08-20 22:39:07 +08:00
val data = UInt ( XLEN . W )
val valid = Bool ( )
}
2020-10-17 21:05:46 +08:00
// Load Pipeline Stage 0
// Generate addr, use addr to query DCache and DTLB
2021-10-10 11:51:53 +08:00
class LoadUnit_S0 ( implicit p : Parameters ) extends XSModule with HasDCacheParameters {
2020-08-06 16:58:13 +08:00
val io = IO ( new Bundle ( ) {
2020-10-17 21:05:46 +08:00
val in = Flipped ( Decoupled ( new ExuInput ) )
val out = Decoupled ( new LsPipelineBundle )
2021-08-20 22:39:07 +08:00
val fastpath = Input ( Vec ( LoadPipelineWidth , new LoadToLoadIO ) )
2020-11-07 17:40:20 +08:00
val dtlbReq = DecoupledIO ( new TlbReq )
2021-01-08 17:17:13 +08:00
val dcacheReq = DecoupledIO ( new DCacheWordReq )
2021-01-30 17:31:42 +08:00
val rsIdx = Input ( UInt ( log2Up ( IssQueSize ) . W ) )
2021-03-13 08:49:36 +08:00
val isFirstIssue = Input ( Bool ( ) )
2021-09-02 09:18:01 +08:00
val loadFastMatch = Input ( UInt ( exuParameters . LduCnt . W ) )
2020-08-06 16:58:13 +08:00
} )
2021-09-02 09:18:01 +08:00
require ( LoadPipelineWidth == exuParameters . LduCnt )
2020-08-06 16:58:13 +08:00
2020-10-17 21:05:46 +08:00
val s0_uop = io . in . bits . uop
2021-08-20 22:39:07 +08:00
val imm12 = WireInit ( s0_uop . ctrl . imm ( 11 , 0 ) )
2021-11-30 20:27:16 +08:00
val s0_vaddr = WireInit ( io . in . bits . src ( 0 ) + SignExt ( s0_uop . ctrl . imm ( 11 , 0 ) , VAddrBits ) )
val s0_mask = WireInit ( genWmask ( s0_vaddr , s0_uop . ctrl . fuOpType ( 1 , 0 ) ) )
2021-08-20 22:39:07 +08:00
2021-11-30 20:27:16 +08:00
if ( EnableLoadToLoadForward ) {
// slow vaddr from non-load insts
val slowpath_vaddr = io . in . bits . src ( 0 ) + SignExt ( s0_uop . ctrl . imm ( 11 , 0 ) , VAddrBits )
val slowpath_mask = genWmask ( slowpath_vaddr , s0_uop . ctrl . fuOpType ( 1 , 0 ) )
2021-08-20 22:39:07 +08:00
2021-11-30 20:27:16 +08:00
// fast vaddr from load insts
val fastpath_vaddrs = WireInit ( VecInit ( List . tabulate ( LoadPipelineWidth ) ( i => {
io . fastpath ( i ) . data + SignExt ( s0_uop . ctrl . imm ( 11 , 0 ) , VAddrBits )
} ) ) )
val fastpath_masks = WireInit ( VecInit ( List . tabulate ( LoadPipelineWidth ) ( i => {
genWmask ( fastpath_vaddrs ( i ) , s0_uop . ctrl . fuOpType ( 1 , 0 ) )
} ) ) )
val fastpath_vaddr = Mux1H ( io . loadFastMatch , fastpath_vaddrs )
val fastpath_mask = Mux1H ( io . loadFastMatch , fastpath_masks )
// select vaddr from 2 alus
s0_vaddr : = Mux ( io . loadFastMatch . orR , fastpath_vaddr , slowpath_vaddr )
s0_mask : = Mux ( io . loadFastMatch . orR , fastpath_mask , slowpath_mask )
XSPerfAccumulate ( "load_to_load_forward" , io . loadFastMatch . orR && io . in . fire ( ) )
}
2020-10-17 21:05:46 +08:00
2021-10-27 14:45:39 +08:00
val isSoftPrefetch = LSUOpType . isPrefetch ( s0_uop . ctrl . fuOpType )
val isSoftPrefetchRead = s0_uop . ctrl . fuOpType === LSUOpType . prefetch_r
val isSoftPrefetchWrite = s0_uop . ctrl . fuOpType === LSUOpType . prefetch_w
2021-10-10 11:51:53 +08:00
2020-10-17 21:05:46 +08:00
// query DTLB
2020-12-11 19:59:25 +08:00
io . dtlbReq . valid : = io . in . valid
2020-10-25 13:24:10 +08:00
io . dtlbReq . bits . vaddr : = s0_vaddr
io . dtlbReq . bits . cmd : = TlbCmd . read
2021-10-11 21:56:10 +08:00
io . dtlbReq . bits . size : = LSUOpType . size ( io . in . bits . uop . ctrl . fuOpType )
2021-09-28 09:23:31 +08:00
io . dtlbReq . bits . robIdx : = s0_uop . robIdx
2020-10-25 13:24:10 +08:00
io . dtlbReq . bits . debug . pc : = s0_uop . cf . pc
2021-03-13 08:49:36 +08:00
io . dtlbReq . bits . debug . isFirstIssue : = io . isFirstIssue
2020-10-17 21:05:46 +08:00
// query DCache
2020-12-11 19:59:25 +08:00
io . dcacheReq . valid : = io . in . valid
2021-10-10 11:51:53 +08:00
when ( isSoftPrefetchRead ) {
io . dcacheReq . bits . cmd : = MemoryOpConstants . M_PFR
} . elsewhen ( isSoftPrefetchWrite ) {
io . dcacheReq . bits . cmd : = MemoryOpConstants . M_PFW
} . otherwise {
pma: add pmp-like pma, software can read and write (#1169)
remove the old hard-wired pma and turn to pmp-like csr registers. the pma config is writen in pma register.
1. pma are m-priv csr, so only m-mode csrrw can change pma
2. even in m-mode, pma should be always checked, no matter lock or not
3. so carefully write pma, make sure not to "suicide"
* pma: add pmp-like pma, just module/bundle added, not to circuit
use reserved 2 bits as atomic and cached
* pma: add pmp-like pma into pmp module
pma have two more attribute than pmp
1. atmoic;
2. c/cache, if false, go to mmio.
pma uses 16+4 machine-level custom ready write csr.
pma will always be checked even in m-mode.
* pma: remove the old MemMap in tlb, mmio arrives next cycle
* pma: ptw raise af when mmio
* pma: fix bug of match's zip with last entry
* pma: fix bug of pass reset signal through method's parameter
strange bug, want to reset, pass reset signal to a method, does not
work.
import chisel3.Module.reset, the method can access reset it's self.
* pma: move some method to trait and fix bug of pma_init value
* pma: fix bug of pma init value assign way
* tlb: fix stupid bug that pf.ld not & fault_valid
* loadunit: fix bug that uop is flushed, pmp's dcache kill failed also
* ifu: mmio access needs f2_valid now
* loadunit: if mmio and have sent fastUop, flush pipe when commit
* storeunit: stu->lsq at stage1 and re-in lsq at stage2 to update mmio
2021-10-25 20:16:15 +08:00
io . dcacheReq . bits . cmd : = MemoryOpConstants . M_XRD
2021-10-10 11:51:53 +08:00
}
2020-10-25 13:24:10 +08:00
io . dcacheReq . bits . addr : = s0_vaddr
io . dcacheReq . bits . mask : = s0_mask
2020-10-26 12:11:38 +08:00
io . dcacheReq . bits . data : = DontCare
2021-10-10 11:51:53 +08:00
when ( isSoftPrefetch ) {
io . dcacheReq . bits . instrtype : = SOFT_PREFETCH . U
} . otherwise {
io . dcacheReq . bits . instrtype : = LOAD_SOURCE . U
}
2020-10-26 12:11:38 +08:00
// TODO: update cache meta
2021-01-24 10:18:49 +08:00
io . dcacheReq . bits . id : = DontCare
2020-10-17 21:05:46 +08:00
val addrAligned = LookupTree ( s0_uop . ctrl . fuOpType ( 1 , 0 ) , List (
"b00" . U -> true . B , //b
"b01" . U -> ( s0_vaddr ( 0 ) === 0. U ) , //h
"b10" . U -> ( s0_vaddr ( 1 , 0 ) === 0. U ) , //w
"b11" . U -> ( s0_vaddr ( 2 , 0 ) === 0. U ) //d
2020-09-03 23:49:29 +08:00
) )
2020-10-17 21:05:46 +08:00
2020-12-14 11:59:11 +08:00
io . out . valid : = io . in . valid && io . dcacheReq . ready
2020-12-11 19:59:25 +08:00
2020-10-17 21:05:46 +08:00
io . out . bits : = DontCare
io . out . bits . vaddr : = s0_vaddr
io . out . bits . mask : = s0_mask
io . out . bits . uop : = s0_uop
io . out . bits . uop . cf . exceptionVec ( loadAddrMisaligned ) : = ! addrAligned
2021-01-30 17:31:42 +08:00
io . out . bits . rsIdx : = io . rsIdx
2021-09-22 15:48:08 +08:00
io . out . bits . isFirstIssue : = io . isFirstIssue
pma: add pmp-like pma, software can read and write (#1169)
remove the old hard-wired pma and turn to pmp-like csr registers. the pma config is writen in pma register.
1. pma are m-priv csr, so only m-mode csrrw can change pma
2. even in m-mode, pma should be always checked, no matter lock or not
3. so carefully write pma, make sure not to "suicide"
* pma: add pmp-like pma, just module/bundle added, not to circuit
use reserved 2 bits as atomic and cached
* pma: add pmp-like pma into pmp module
pma have two more attribute than pmp
1. atmoic;
2. c/cache, if false, go to mmio.
pma uses 16+4 machine-level custom ready write csr.
pma will always be checked even in m-mode.
* pma: remove the old MemMap in tlb, mmio arrives next cycle
* pma: ptw raise af when mmio
* pma: fix bug of match's zip with last entry
* pma: fix bug of pass reset signal through method's parameter
strange bug, want to reset, pass reset signal to a method, does not
work.
import chisel3.Module.reset, the method can access reset it's self.
* pma: move some method to trait and fix bug of pma_init value
* pma: fix bug of pma init value assign way
* tlb: fix stupid bug that pf.ld not & fault_valid
* loadunit: fix bug that uop is flushed, pmp's dcache kill failed also
* ifu: mmio access needs f2_valid now
* loadunit: if mmio and have sent fastUop, flush pipe when commit
* storeunit: stu->lsq at stage1 and re-in lsq at stage2 to update mmio
2021-10-25 20:16:15 +08:00
io . out . bits . isSoftPrefetch : = isSoftPrefetch
2020-10-17 21:05:46 +08:00
2020-12-11 19:59:25 +08:00
io . in . ready : = ! io . in . valid || ( io . out . ready && io . dcacheReq . ready )
2020-10-27 18:11:11 +08:00
2020-12-11 19:59:25 +08:00
XSDebug ( io . dcacheReq . fire ( ) ,
2020-12-13 21:31:00 +08:00
p "[DCACHE LOAD REQ] pc ${Hexadecimal(s0_uop.cf.pc)}, vaddr ${Hexadecimal(s0_vaddr)}\n"
2020-10-27 18:11:11 +08:00
)
2021-09-22 15:48:08 +08:00
XSPerfAccumulate ( "in_valid" , io . in . valid )
XSPerfAccumulate ( "in_fire" , io . in . fire )
XSPerfAccumulate ( "in_fire_first_issue" , io . in . valid && io . isFirstIssue )
2021-03-25 21:08:52 +08:00
XSPerfAccumulate ( "stall_out" , io . out . valid && ! io . out . ready && io . dcacheReq . ready )
XSPerfAccumulate ( "stall_dcache" , io . out . valid && io . out . ready && ! io . dcacheReq . ready )
2021-05-09 09:05:53 +08:00
XSPerfAccumulate ( "addr_spec_success" , io . out . fire ( ) && s0_vaddr ( VAddrBits - 1 , 12 ) === io . in . bits . src ( 0 ) ( VAddrBits - 1 , 12 ) )
XSPerfAccumulate ( "addr_spec_failed" , io . out . fire ( ) && s0_vaddr ( VAddrBits - 1 , 12 ) =/= io . in . bits . src ( 0 ) ( VAddrBits - 1 , 12 ) )
XSPerfAccumulate ( "addr_spec_success_once" , io . out . fire ( ) && s0_vaddr ( VAddrBits - 1 , 12 ) === io . in . bits . src ( 0 ) ( VAddrBits - 1 , 12 ) && io . isFirstIssue )
XSPerfAccumulate ( "addr_spec_failed_once" , io . out . fire ( ) && s0_vaddr ( VAddrBits - 1 , 12 ) =/= io . in . bits . src ( 0 ) ( VAddrBits - 1 , 12 ) && io . isFirstIssue )
2020-10-17 21:05:46 +08:00
}
// Load Pipeline Stage 1
// TLB resp (send paddr to dcache)
2021-04-19 21:19:20 +08:00
class LoadUnit_S1 ( implicit p : Parameters ) extends XSModule {
2020-10-17 21:05:46 +08:00
val io = IO ( new Bundle ( ) {
val in = Flipped ( Decoupled ( new LsPipelineBundle ) )
val out = Decoupled ( new LsPipelineBundle )
2020-12-13 21:31:00 +08:00
val dtlbResp = Flipped ( DecoupledIO ( new TlbResp ) )
val dcachePAddr = Output ( UInt ( PAddrBits . W ) )
2021-01-08 20:49:30 +08:00
val dcacheKill = Output ( Bool ( ) )
2021-12-01 12:52:37 +08:00
val fastUopKill = Output ( Bool ( ) )
2021-10-11 16:01:26 +08:00
val dcacheBankConflict = Input ( Bool ( ) )
2021-08-20 01:27:12 +08:00
val fullForwardFast = Output ( Bool ( ) )
2020-11-02 19:23:04 +08:00
val sbuffer = new LoadForwardQueryIO
2021-04-30 10:40:51 +08:00
val lsq = new PipeLoadForwardQueryIO
2021-10-22 15:29:07 +08:00
val loadViolationQueryReq = Decoupled ( new LoadViolationQueryReq )
2021-10-11 16:01:26 +08:00
val rsFeedback = ValidIO ( new RSFeedback )
2021-10-22 15:29:07 +08:00
val csrCtrl = Flipped ( new CustomCSRCtrlIO )
val needLdVioCheckRedo = Output ( Bool ( ) )
2020-08-06 16:58:13 +08:00
} )
2020-08-16 15:59:15 +08:00
2020-10-17 21:05:46 +08:00
val s1_uop = io . in . bits . uop
2020-12-13 21:31:00 +08:00
val s1_paddr = io . dtlbResp . bits . paddr
2021-12-09 20:15:29 +08:00
// af & pf exception were modified below.
val s1_exception = ExceptionNO . selectByFu ( io . out . bits . uop . cf . exceptionVec , lduCfg ) . asUInt . orR
2020-12-13 21:31:00 +08:00
val s1_tlb_miss = io . dtlbResp . bits . miss
2020-11-02 19:23:04 +08:00
val s1_mask = io . in . bits . mask
2021-10-11 16:01:26 +08:00
val s1_bank_conflict = io . dcacheBankConflict
2020-11-18 20:47:14 +08:00
2020-11-02 19:23:04 +08:00
io . out . bits : = io . in . bits // forwardXX field will be updated in s1
2020-12-13 21:31:00 +08:00
io . dtlbResp . ready : = true . B
2021-01-10 12:20:47 +08:00
// TOOD: PMA check
2020-12-13 21:31:00 +08:00
io . dcachePAddr : = s1_paddr
2021-10-10 11:51:53 +08:00
//io.dcacheKill := s1_tlb_miss || s1_exception || s1_mmio
pma: add pmp-like pma, software can read and write (#1169)
remove the old hard-wired pma and turn to pmp-like csr registers. the pma config is writen in pma register.
1. pma are m-priv csr, so only m-mode csrrw can change pma
2. even in m-mode, pma should be always checked, no matter lock or not
3. so carefully write pma, make sure not to "suicide"
* pma: add pmp-like pma, just module/bundle added, not to circuit
use reserved 2 bits as atomic and cached
* pma: add pmp-like pma into pmp module
pma have two more attribute than pmp
1. atmoic;
2. c/cache, if false, go to mmio.
pma uses 16+4 machine-level custom ready write csr.
pma will always be checked even in m-mode.
* pma: remove the old MemMap in tlb, mmio arrives next cycle
* pma: ptw raise af when mmio
* pma: fix bug of match's zip with last entry
* pma: fix bug of pass reset signal through method's parameter
strange bug, want to reset, pass reset signal to a method, does not
work.
import chisel3.Module.reset, the method can access reset it's self.
* pma: move some method to trait and fix bug of pma_init value
* pma: fix bug of pma init value assign way
* tlb: fix stupid bug that pf.ld not & fault_valid
* loadunit: fix bug that uop is flushed, pmp's dcache kill failed also
* ifu: mmio access needs f2_valid now
* loadunit: if mmio and have sent fastUop, flush pipe when commit
* storeunit: stu->lsq at stage1 and re-in lsq at stage2 to update mmio
2021-10-25 20:16:15 +08:00
io . dcacheKill : = s1_tlb_miss || s1_exception
2021-12-01 12:52:37 +08:00
io . fastUopKill : = io . dtlbResp . bits . fast_miss || s1_exception
2020-10-21 10:40:51 +08:00
2020-11-02 19:23:04 +08:00
// load forward query datapath
2021-08-03 22:14:51 +08:00
io . sbuffer . valid : = io . in . valid && ! ( s1_exception || s1_tlb_miss )
2021-07-29 16:18:24 +08:00
io . sbuffer . vaddr : = io . in . bits . vaddr
2020-11-02 19:23:04 +08:00
io . sbuffer . paddr : = s1_paddr
io . sbuffer . uop : = s1_uop
io . sbuffer . sqIdx : = s1_uop . sqIdx
io . sbuffer . mask : = s1_mask
io . sbuffer . pc : = s1_uop . cf . pc // FIXME: remove it
2020-11-18 20:47:14 +08:00
2021-08-03 22:14:51 +08:00
io . lsq . valid : = io . in . valid && ! ( s1_exception || s1_tlb_miss )
2021-07-29 16:18:24 +08:00
io . lsq . vaddr : = io . in . bits . vaddr
2020-11-18 20:47:14 +08:00
io . lsq . paddr : = s1_paddr
io . lsq . uop : = s1_uop
io . lsq . sqIdx : = s1_uop . sqIdx
2021-02-02 00:17:52 +08:00
io . lsq . sqIdxMask : = DontCare // will be overwritten by sqIdxMask pre-generated in s0
2020-11-18 20:47:14 +08:00
io . lsq . mask : = s1_mask
io . lsq . pc : = s1_uop . cf . pc // FIXME: remove it
2020-11-02 19:23:04 +08:00
2021-10-22 15:29:07 +08:00
// ld-ld violation query
io . loadViolationQueryReq . valid : = io . in . valid && ! ( s1_exception || s1_tlb_miss )
io . loadViolationQueryReq . bits . paddr : = s1_paddr
io . loadViolationQueryReq . bits . uop : = s1_uop
2021-08-20 01:27:12 +08:00
// Generate forwardMaskFast to wake up insts earlier
val forwardMaskFast = io . lsq . forwardMaskFast . asUInt | io . sbuffer . forwardMaskFast . asUInt
io . fullForwardFast : = ( ~ forwardMaskFast & s1_mask ) === 0. U
2021-10-22 15:29:07 +08:00
// Generate feedback signal caused by:
// * dcache bank conflict
// * need redo ld-ld violation check
val needLdVioCheckRedo = io . loadViolationQueryReq . valid &&
! io . loadViolationQueryReq . ready &&
RegNext ( io . csrCtrl . ldld_vio_check )
io . needLdVioCheckRedo : = needLdVioCheckRedo
io . rsFeedback . valid : = io . in . valid && ( s1_bank_conflict || needLdVioCheckRedo )
io . rsFeedback . bits . hit : = false . B // we have found s1_bank_conflict / re do ld-ld violation check
2021-10-11 16:01:26 +08:00
io . rsFeedback . bits . rsIdx : = io . in . bits . rsIdx
io . rsFeedback . bits . flushState : = io . in . bits . ptwBack
2021-10-22 15:29:07 +08:00
io . rsFeedback . bits . sourceType : = Mux ( s1_bank_conflict , RSFeedbackType . bankConflict , RSFeedbackType . ldVioCheckRedo )
2021-10-12 19:51:51 +08:00
io . rsFeedback . bits . dataInvalidSqIdx : = DontCare
2021-10-11 16:01:26 +08:00
pma: add pmp-like pma, software can read and write (#1169)
remove the old hard-wired pma and turn to pmp-like csr registers. the pma config is writen in pma register.
1. pma are m-priv csr, so only m-mode csrrw can change pma
2. even in m-mode, pma should be always checked, no matter lock or not
3. so carefully write pma, make sure not to "suicide"
* pma: add pmp-like pma, just module/bundle added, not to circuit
use reserved 2 bits as atomic and cached
* pma: add pmp-like pma into pmp module
pma have two more attribute than pmp
1. atmoic;
2. c/cache, if false, go to mmio.
pma uses 16+4 machine-level custom ready write csr.
pma will always be checked even in m-mode.
* pma: remove the old MemMap in tlb, mmio arrives next cycle
* pma: ptw raise af when mmio
* pma: fix bug of match's zip with last entry
* pma: fix bug of pass reset signal through method's parameter
strange bug, want to reset, pass reset signal to a method, does not
work.
import chisel3.Module.reset, the method can access reset it's self.
* pma: move some method to trait and fix bug of pma_init value
* pma: fix bug of pma init value assign way
* tlb: fix stupid bug that pf.ld not & fault_valid
* loadunit: fix bug that uop is flushed, pmp's dcache kill failed also
* ifu: mmio access needs f2_valid now
* loadunit: if mmio and have sent fastUop, flush pipe when commit
* storeunit: stu->lsq at stage1 and re-in lsq at stage2 to update mmio
2021-10-25 20:16:15 +08:00
// if replay is detected in load_s1,
// load inst will be canceled immediately
io . out . valid : = io . in . valid && ! io . rsFeedback . valid
2020-10-17 21:05:46 +08:00
io . out . bits . paddr : = s1_paddr
2020-10-26 12:11:38 +08:00
io . out . bits . tlbMiss : = s1_tlb_miss
2021-10-10 11:51:53 +08:00
pma: add pmp-like pma, software can read and write (#1169)
remove the old hard-wired pma and turn to pmp-like csr registers. the pma config is writen in pma register.
1. pma are m-priv csr, so only m-mode csrrw can change pma
2. even in m-mode, pma should be always checked, no matter lock or not
3. so carefully write pma, make sure not to "suicide"
* pma: add pmp-like pma, just module/bundle added, not to circuit
use reserved 2 bits as atomic and cached
* pma: add pmp-like pma into pmp module
pma have two more attribute than pmp
1. atmoic;
2. c/cache, if false, go to mmio.
pma uses 16+4 machine-level custom ready write csr.
pma will always be checked even in m-mode.
* pma: remove the old MemMap in tlb, mmio arrives next cycle
* pma: ptw raise af when mmio
* pma: fix bug of match's zip with last entry
* pma: fix bug of pass reset signal through method's parameter
strange bug, want to reset, pass reset signal to a method, does not
work.
import chisel3.Module.reset, the method can access reset it's self.
* pma: move some method to trait and fix bug of pma_init value
* pma: fix bug of pma init value assign way
* tlb: fix stupid bug that pf.ld not & fault_valid
* loadunit: fix bug that uop is flushed, pmp's dcache kill failed also
* ifu: mmio access needs f2_valid now
* loadunit: if mmio and have sent fastUop, flush pipe when commit
* storeunit: stu->lsq at stage1 and re-in lsq at stage2 to update mmio
2021-10-25 20:16:15 +08:00
// current ori test will cause the case of ldest == 0, below will be modifeid in the future.
2021-10-10 11:51:53 +08:00
// af & pf exception were modified
pma: add pmp-like pma, software can read and write (#1169)
remove the old hard-wired pma and turn to pmp-like csr registers. the pma config is writen in pma register.
1. pma are m-priv csr, so only m-mode csrrw can change pma
2. even in m-mode, pma should be always checked, no matter lock or not
3. so carefully write pma, make sure not to "suicide"
* pma: add pmp-like pma, just module/bundle added, not to circuit
use reserved 2 bits as atomic and cached
* pma: add pmp-like pma into pmp module
pma have two more attribute than pmp
1. atmoic;
2. c/cache, if false, go to mmio.
pma uses 16+4 machine-level custom ready write csr.
pma will always be checked even in m-mode.
* pma: remove the old MemMap in tlb, mmio arrives next cycle
* pma: ptw raise af when mmio
* pma: fix bug of match's zip with last entry
* pma: fix bug of pass reset signal through method's parameter
strange bug, want to reset, pass reset signal to a method, does not
work.
import chisel3.Module.reset, the method can access reset it's self.
* pma: move some method to trait and fix bug of pma_init value
* pma: fix bug of pma init value assign way
* tlb: fix stupid bug that pf.ld not & fault_valid
* loadunit: fix bug that uop is flushed, pmp's dcache kill failed also
* ifu: mmio access needs f2_valid now
* loadunit: if mmio and have sent fastUop, flush pipe when commit
* storeunit: stu->lsq at stage1 and re-in lsq at stage2 to update mmio
2021-10-25 20:16:15 +08:00
io . out . bits . uop . cf . exceptionVec ( loadPageFault ) : = io . dtlbResp . bits . excp . pf . ld
io . out . bits . uop . cf . exceptionVec ( loadAccessFault ) : = io . dtlbResp . bits . excp . af . ld
2021-10-10 11:51:53 +08:00
2021-03-05 20:23:11 +08:00
io . out . bits . ptwBack : = io . dtlbResp . bits . ptwBack
2021-01-30 17:31:42 +08:00
io . out . bits . rsIdx : = io . in . bits . rsIdx
2020-08-06 16:58:13 +08:00
pma: add pmp-like pma, software can read and write (#1169)
remove the old hard-wired pma and turn to pmp-like csr registers. the pma config is writen in pma register.
1. pma are m-priv csr, so only m-mode csrrw can change pma
2. even in m-mode, pma should be always checked, no matter lock or not
3. so carefully write pma, make sure not to "suicide"
* pma: add pmp-like pma, just module/bundle added, not to circuit
use reserved 2 bits as atomic and cached
* pma: add pmp-like pma into pmp module
pma have two more attribute than pmp
1. atmoic;
2. c/cache, if false, go to mmio.
pma uses 16+4 machine-level custom ready write csr.
pma will always be checked even in m-mode.
* pma: remove the old MemMap in tlb, mmio arrives next cycle
* pma: ptw raise af when mmio
* pma: fix bug of match's zip with last entry
* pma: fix bug of pass reset signal through method's parameter
strange bug, want to reset, pass reset signal to a method, does not
work.
import chisel3.Module.reset, the method can access reset it's self.
* pma: move some method to trait and fix bug of pma_init value
* pma: fix bug of pma init value assign way
* tlb: fix stupid bug that pf.ld not & fault_valid
* loadunit: fix bug that uop is flushed, pmp's dcache kill failed also
* ifu: mmio access needs f2_valid now
* loadunit: if mmio and have sent fastUop, flush pipe when commit
* storeunit: stu->lsq at stage1 and re-in lsq at stage2 to update mmio
2021-10-25 20:16:15 +08:00
io . out . bits . isSoftPrefetch : = io . in . bits . isSoftPrefetch
2021-10-10 11:51:53 +08:00
2020-12-11 19:59:25 +08:00
io . in . ready : = ! io . in . valid || io . out . ready
2020-08-19 15:28:58 +08:00
2021-09-22 15:48:08 +08:00
XSPerfAccumulate ( "in_valid" , io . in . valid )
XSPerfAccumulate ( "in_fire" , io . in . fire )
XSPerfAccumulate ( "in_fire_first_issue" , io . in . fire && io . in . bits . isFirstIssue )
XSPerfAccumulate ( "tlb_miss" , io . in . fire && s1_tlb_miss )
XSPerfAccumulate ( "tlb_miss_first_issue" , io . in . fire && s1_tlb_miss && io . in . bits . isFirstIssue )
2021-03-25 21:08:52 +08:00
XSPerfAccumulate ( "stall_out" , io . out . valid && ! io . out . ready )
2020-10-17 21:05:46 +08:00
}
2020-08-19 15:28:58 +08:00
2020-10-17 21:05:46 +08:00
// Load Pipeline Stage 2
// DCache resp
2021-04-19 21:19:20 +08:00
class LoadUnit_S2 ( implicit p : Parameters ) extends XSModule with HasLoadHelper {
2020-10-17 21:05:46 +08:00
val io = IO ( new Bundle ( ) {
val in = Flipped ( Decoupled ( new LsPipelineBundle ) )
val out = Decoupled ( new LsPipelineBundle )
2021-04-30 10:40:51 +08:00
val rsFeedback = ValidIO ( new RSFeedback )
2020-10-25 13:24:10 +08:00
val dcacheResp = Flipped ( DecoupledIO ( new DCacheWordResp ) )
pma: add pmp-like pma, software can read and write (#1169)
remove the old hard-wired pma and turn to pmp-like csr registers. the pma config is writen in pma register.
1. pma are m-priv csr, so only m-mode csrrw can change pma
2. even in m-mode, pma should be always checked, no matter lock or not
3. so carefully write pma, make sure not to "suicide"
* pma: add pmp-like pma, just module/bundle added, not to circuit
use reserved 2 bits as atomic and cached
* pma: add pmp-like pma into pmp module
pma have two more attribute than pmp
1. atmoic;
2. c/cache, if false, go to mmio.
pma uses 16+4 machine-level custom ready write csr.
pma will always be checked even in m-mode.
* pma: remove the old MemMap in tlb, mmio arrives next cycle
* pma: ptw raise af when mmio
* pma: fix bug of match's zip with last entry
* pma: fix bug of pass reset signal through method's parameter
strange bug, want to reset, pass reset signal to a method, does not
work.
import chisel3.Module.reset, the method can access reset it's self.
* pma: move some method to trait and fix bug of pma_init value
* pma: fix bug of pma init value assign way
* tlb: fix stupid bug that pf.ld not & fault_valid
* loadunit: fix bug that uop is flushed, pmp's dcache kill failed also
* ifu: mmio access needs f2_valid now
* loadunit: if mmio and have sent fastUop, flush pipe when commit
* storeunit: stu->lsq at stage1 and re-in lsq at stage2 to update mmio
2021-10-25 20:16:15 +08:00
val pmpResp = Flipped ( new PMPRespBundle ( ) )
2020-12-02 18:16:42 +08:00
val lsq = new LoadForwardQueryIO
2021-10-12 19:51:51 +08:00
val dataInvalidSqIdx = Input ( UInt ( ) )
2020-12-16 14:44:10 +08:00
val sbuffer = new LoadForwardQueryIO
2021-01-25 19:46:19 +08:00
val dataForwarded = Output ( Bool ( ) )
2021-02-05 23:10:00 +08:00
val needReplayFromRS = Output ( Bool ( ) )
2021-10-23 13:38:45 +08:00
val fullForward = Output ( Bool ( ) )
2021-08-20 22:39:07 +08:00
val fastpath = Output ( new LoadToLoadIO )
2021-10-11 21:56:10 +08:00
val dcache_kill = Output ( Bool ( ) )
2021-10-22 15:29:07 +08:00
val loadViolationQueryResp = Flipped ( Valid ( new LoadViolationQueryResp ) )
val csrCtrl = Flipped ( new CustomCSRCtrlIO )
pma: add pmp-like pma, software can read and write (#1169)
remove the old hard-wired pma and turn to pmp-like csr registers. the pma config is writen in pma register.
1. pma are m-priv csr, so only m-mode csrrw can change pma
2. even in m-mode, pma should be always checked, no matter lock or not
3. so carefully write pma, make sure not to "suicide"
* pma: add pmp-like pma, just module/bundle added, not to circuit
use reserved 2 bits as atomic and cached
* pma: add pmp-like pma into pmp module
pma have two more attribute than pmp
1. atmoic;
2. c/cache, if false, go to mmio.
pma uses 16+4 machine-level custom ready write csr.
pma will always be checked even in m-mode.
* pma: remove the old MemMap in tlb, mmio arrives next cycle
* pma: ptw raise af when mmio
* pma: fix bug of match's zip with last entry
* pma: fix bug of pass reset signal through method's parameter
strange bug, want to reset, pass reset signal to a method, does not
work.
import chisel3.Module.reset, the method can access reset it's self.
* pma: move some method to trait and fix bug of pma_init value
* pma: fix bug of pma init value assign way
* tlb: fix stupid bug that pf.ld not & fault_valid
* loadunit: fix bug that uop is flushed, pmp's dcache kill failed also
* ifu: mmio access needs f2_valid now
* loadunit: if mmio and have sent fastUop, flush pipe when commit
* storeunit: stu->lsq at stage1 and re-in lsq at stage2 to update mmio
2021-10-25 20:16:15 +08:00
val sentFastUop = Input ( Bool ( ) )
2020-10-17 21:05:46 +08:00
} )
pma: add pmp-like pma, software can read and write (#1169)
remove the old hard-wired pma and turn to pmp-like csr registers. the pma config is writen in pma register.
1. pma are m-priv csr, so only m-mode csrrw can change pma
2. even in m-mode, pma should be always checked, no matter lock or not
3. so carefully write pma, make sure not to "suicide"
* pma: add pmp-like pma, just module/bundle added, not to circuit
use reserved 2 bits as atomic and cached
* pma: add pmp-like pma into pmp module
pma have two more attribute than pmp
1. atmoic;
2. c/cache, if false, go to mmio.
pma uses 16+4 machine-level custom ready write csr.
pma will always be checked even in m-mode.
* pma: remove the old MemMap in tlb, mmio arrives next cycle
* pma: ptw raise af when mmio
* pma: fix bug of match's zip with last entry
* pma: fix bug of pass reset signal through method's parameter
strange bug, want to reset, pass reset signal to a method, does not
work.
import chisel3.Module.reset, the method can access reset it's self.
* pma: move some method to trait and fix bug of pma_init value
* pma: fix bug of pma init value assign way
* tlb: fix stupid bug that pf.ld not & fault_valid
* loadunit: fix bug that uop is flushed, pmp's dcache kill failed also
* ifu: mmio access needs f2_valid now
* loadunit: if mmio and have sent fastUop, flush pipe when commit
* storeunit: stu->lsq at stage1 and re-in lsq at stage2 to update mmio
2021-10-25 20:16:15 +08:00
val isSoftPrefetch = io . in . bits . isSoftPrefetch
2021-10-11 21:56:10 +08:00
val excep = WireInit ( io . in . bits . uop . cf . exceptionVec )
excep ( loadAccessFault ) : = io . in . bits . uop . cf . exceptionVec ( loadAccessFault ) || io . pmpResp . ld
pma: add pmp-like pma, software can read and write (#1169)
remove the old hard-wired pma and turn to pmp-like csr registers. the pma config is writen in pma register.
1. pma are m-priv csr, so only m-mode csrrw can change pma
2. even in m-mode, pma should be always checked, no matter lock or not
3. so carefully write pma, make sure not to "suicide"
* pma: add pmp-like pma, just module/bundle added, not to circuit
use reserved 2 bits as atomic and cached
* pma: add pmp-like pma into pmp module
pma have two more attribute than pmp
1. atmoic;
2. c/cache, if false, go to mmio.
pma uses 16+4 machine-level custom ready write csr.
pma will always be checked even in m-mode.
* pma: remove the old MemMap in tlb, mmio arrives next cycle
* pma: ptw raise af when mmio
* pma: fix bug of match's zip with last entry
* pma: fix bug of pass reset signal through method's parameter
strange bug, want to reset, pass reset signal to a method, does not
work.
import chisel3.Module.reset, the method can access reset it's self.
* pma: move some method to trait and fix bug of pma_init value
* pma: fix bug of pma init value assign way
* tlb: fix stupid bug that pf.ld not & fault_valid
* loadunit: fix bug that uop is flushed, pmp's dcache kill failed also
* ifu: mmio access needs f2_valid now
* loadunit: if mmio and have sent fastUop, flush pipe when commit
* storeunit: stu->lsq at stage1 and re-in lsq at stage2 to update mmio
2021-10-25 20:16:15 +08:00
when ( isSoftPrefetch ) {
excep : = 0. U . asTypeOf ( excep . cloneType )
}
2021-12-09 20:15:29 +08:00
val s2_exception = ExceptionNO . selectByFu ( io . out . bits . uop . cf . exceptionVec , lduCfg ) . asUInt . orR
2021-10-11 21:56:10 +08:00
pma: add pmp-like pma, software can read and write (#1169)
remove the old hard-wired pma and turn to pmp-like csr registers. the pma config is writen in pma register.
1. pma are m-priv csr, so only m-mode csrrw can change pma
2. even in m-mode, pma should be always checked, no matter lock or not
3. so carefully write pma, make sure not to "suicide"
* pma: add pmp-like pma, just module/bundle added, not to circuit
use reserved 2 bits as atomic and cached
* pma: add pmp-like pma into pmp module
pma have two more attribute than pmp
1. atmoic;
2. c/cache, if false, go to mmio.
pma uses 16+4 machine-level custom ready write csr.
pma will always be checked even in m-mode.
* pma: remove the old MemMap in tlb, mmio arrives next cycle
* pma: ptw raise af when mmio
* pma: fix bug of match's zip with last entry
* pma: fix bug of pass reset signal through method's parameter
strange bug, want to reset, pass reset signal to a method, does not
work.
import chisel3.Module.reset, the method can access reset it's self.
* pma: move some method to trait and fix bug of pma_init value
* pma: fix bug of pma init value assign way
* tlb: fix stupid bug that pf.ld not & fault_valid
* loadunit: fix bug that uop is flushed, pmp's dcache kill failed also
* ifu: mmio access needs f2_valid now
* loadunit: if mmio and have sent fastUop, flush pipe when commit
* storeunit: stu->lsq at stage1 and re-in lsq at stage2 to update mmio
2021-10-25 20:16:15 +08:00
val actually_mmio = io . pmpResp . mmio
2020-10-17 21:05:46 +08:00
val s2_uop = io . in . bits . uop
val s2_mask = io . in . bits . mask
val s2_paddr = io . in . bits . paddr
2021-01-08 20:49:30 +08:00
val s2_tlb_miss = io . in . bits . tlbMiss
2021-04-30 10:40:51 +08:00
val s2_data_invalid = io . lsq . dataInvalid
pma: add pmp-like pma, software can read and write (#1169)
remove the old hard-wired pma and turn to pmp-like csr registers. the pma config is writen in pma register.
1. pma are m-priv csr, so only m-mode csrrw can change pma
2. even in m-mode, pma should be always checked, no matter lock or not
3. so carefully write pma, make sure not to "suicide"
* pma: add pmp-like pma, just module/bundle added, not to circuit
use reserved 2 bits as atomic and cached
* pma: add pmp-like pma into pmp module
pma have two more attribute than pmp
1. atmoic;
2. c/cache, if false, go to mmio.
pma uses 16+4 machine-level custom ready write csr.
pma will always be checked even in m-mode.
* pma: remove the old MemMap in tlb, mmio arrives next cycle
* pma: ptw raise af when mmio
* pma: fix bug of match's zip with last entry
* pma: fix bug of pass reset signal through method's parameter
strange bug, want to reset, pass reset signal to a method, does not
work.
import chisel3.Module.reset, the method can access reset it's self.
* pma: move some method to trait and fix bug of pma_init value
* pma: fix bug of pma init value assign way
* tlb: fix stupid bug that pf.ld not & fault_valid
* loadunit: fix bug that uop is flushed, pmp's dcache kill failed also
* ifu: mmio access needs f2_valid now
* loadunit: if mmio and have sent fastUop, flush pipe when commit
* storeunit: stu->lsq at stage1 and re-in lsq at stage2 to update mmio
2021-10-25 20:16:15 +08:00
val s2_mmio = ! isSoftPrefetch && actually_mmio && ! s2_exception
2020-10-25 13:24:10 +08:00
val s2_cache_miss = io . dcacheResp . bits . miss
2021-01-08 17:17:13 +08:00
val s2_cache_replay = io . dcacheResp . bits . replay
2021-10-27 14:45:39 +08:00
val s2_is_prefetch = io . in . bits . isSoftPrefetch
2021-08-20 01:27:12 +08:00
// val cnt = RegInit(127.U)
// cnt := cnt + io.in.valid.asUInt
// val s2_forward_fail = io.lsq.matchInvalid || io.sbuffer.matchInvalid || cnt === 0.U
2021-08-03 14:28:43 +08:00
val s2_forward_fail = io . lsq . matchInvalid || io . sbuffer . matchInvalid
2021-08-16 15:23:32 +08:00
// assert(!s2_forward_fail)
pma: add pmp-like pma, software can read and write (#1169)
remove the old hard-wired pma and turn to pmp-like csr registers. the pma config is writen in pma register.
1. pma are m-priv csr, so only m-mode csrrw can change pma
2. even in m-mode, pma should be always checked, no matter lock or not
3. so carefully write pma, make sure not to "suicide"
* pma: add pmp-like pma, just module/bundle added, not to circuit
use reserved 2 bits as atomic and cached
* pma: add pmp-like pma into pmp module
pma have two more attribute than pmp
1. atmoic;
2. c/cache, if false, go to mmio.
pma uses 16+4 machine-level custom ready write csr.
pma will always be checked even in m-mode.
* pma: remove the old MemMap in tlb, mmio arrives next cycle
* pma: ptw raise af when mmio
* pma: fix bug of match's zip with last entry
* pma: fix bug of pass reset signal through method's parameter
strange bug, want to reset, pass reset signal to a method, does not
work.
import chisel3.Module.reset, the method can access reset it's self.
* pma: move some method to trait and fix bug of pma_init value
* pma: fix bug of pma init value assign way
* tlb: fix stupid bug that pf.ld not & fault_valid
* loadunit: fix bug that uop is flushed, pmp's dcache kill failed also
* ifu: mmio access needs f2_valid now
* loadunit: if mmio and have sent fastUop, flush pipe when commit
* storeunit: stu->lsq at stage1 and re-in lsq at stage2 to update mmio
2021-10-25 20:16:15 +08:00
io . dcache_kill : = false . B // move pmp resp kill to outside
2020-10-25 13:24:10 +08:00
io . dcacheResp . ready : = true . B
2021-10-27 14:45:39 +08:00
val dcacheShouldResp = ! ( s2_tlb_miss || s2_exception || s2_mmio || s2_is_prefetch )
assert ( ! ( io . in . valid && ( dcacheShouldResp && ! io . dcacheResp . valid ) ) , "DCache response got lost" )
2020-08-06 16:58:13 +08:00
2021-02-01 23:59:58 +08:00
// merge forward result
// lsq has higher priority than sbuffer
val forwardMask = Wire ( Vec ( 8 , Bool ( ) ) )
val forwardData = Wire ( Vec ( 8 , UInt ( 8. W ) ) )
2021-01-08 20:49:30 +08:00
2021-04-30 10:40:51 +08:00
val fullForward = ( ~ forwardMask . asUInt & s2_mask ) === 0. U && ! io . lsq . dataInvalid
2021-02-01 23:59:58 +08:00
io . lsq : = DontCare
io . sbuffer : = DontCare
2021-10-23 13:38:45 +08:00
io . fullForward : = fullForward
2021-02-01 23:59:58 +08:00
// generate XLEN/8 Muxs
for ( i <- 0 until XLEN / 8 ) {
forwardMask ( i ) : = io . lsq . forwardMask ( i ) || io . sbuffer . forwardMask ( i )
forwardData ( i ) : = Mux ( io . lsq . forwardMask ( i ) , io . lsq . forwardData ( i ) , io . sbuffer . forwardData ( i ) )
}
2020-08-06 16:58:13 +08:00
2020-12-02 18:16:42 +08:00
XSDebug ( io . out . fire ( ) , "[FWD LOAD RESP] pc %x fwd %x(%b) + %x(%b)\n" ,
s2_uop . cf . pc ,
io . lsq . forwardData . asUInt , io . lsq . forwardMask . asUInt ,
io . in . bits . forwardData . asUInt , io . in . bits . forwardMask . asUInt
)
2020-08-06 16:58:13 +08:00
// data merge
2021-02-01 23:59:58 +08:00
val rdataVec = VecInit ( ( 0 until XLEN / 8 ) . map ( j =>
Mux ( forwardMask ( j ) , forwardData ( j ) , io . dcacheResp . bits . data ( 8 * ( j + 1 ) - 1 , 8 * j ) ) ) )
val rdata = rdataVec . asUInt
2020-10-17 21:05:46 +08:00
val rdataSel = LookupTree ( s2_paddr ( 2 , 0 ) , List (
2020-08-06 16:58:13 +08:00
"b000" . U -> rdata ( 63 , 0 ) ,
"b001" . U -> rdata ( 63 , 8 ) ,
"b010" . U -> rdata ( 63 , 16 ) ,
"b011" . U -> rdata ( 63 , 24 ) ,
"b100" . U -> rdata ( 63 , 32 ) ,
"b101" . U -> rdata ( 63 , 40 ) ,
"b110" . U -> rdata ( 63 , 48 ) ,
"b111" . U -> rdata ( 63 , 56 )
) )
2020-12-12 23:48:12 +08:00
val rdataPartialLoad = rdataHelper ( s2_uop , rdataSel )
2020-08-06 16:58:13 +08:00
2021-08-17 20:59:08 +08:00
io . out . valid : = io . in . valid && ! s2_tlb_miss && ! s2_data_invalid
2020-11-18 20:47:14 +08:00
// Inst will be canceled in store queue / lsq,
2020-10-26 14:36:09 +08:00
// so we do not need to care about flush in load / store unit's out.valid
2020-10-17 21:05:46 +08:00
io . out . bits : = io . in . bits
io . out . bits . data : = rdataPartialLoad
2021-09-28 09:23:31 +08:00
// when exception occurs, set it to not miss and let it write back to rob (via int port)
2021-08-20 01:27:12 +08:00
if ( EnableFastForward ) {
2021-10-27 14:45:39 +08:00
io . out . bits . miss : = s2_cache_miss &&
! s2_exception &&
! s2_forward_fail &&
! fullForward &&
! s2_is_prefetch
2021-08-20 01:27:12 +08:00
} else {
2021-10-27 14:45:39 +08:00
io . out . bits . miss : = s2_cache_miss &&
! s2_exception &&
! s2_forward_fail &&
! s2_is_prefetch
2021-08-20 01:27:12 +08:00
}
2021-01-15 22:24:39 +08:00
io . out . bits . uop . ctrl . fpWen : = io . in . bits . uop . ctrl . fpWen && ! s2_exception
2021-10-22 15:29:07 +08:00
// if forward fail, replay this inst from fetch
val forwardFailReplay = s2_forward_fail && ! s2_mmio
// if ld-ld violation is detected, replay from this inst from fetch
val ldldVioReplay = io . loadViolationQueryResp . valid &&
io . loadViolationQueryResp . bits . have_violation &&
RegNext ( io . csrCtrl . ldld_vio_check )
io . out . bits . uop . ctrl . replayInst : = forwardFailReplay || ldldVioReplay
2021-01-11 22:00:04 +08:00
io . out . bits . mmio : = s2_mmio
2021-12-09 20:15:29 +08:00
io . out . bits . uop . ctrl . flushPipe : = s2_mmio && io . sentFastUop
2021-10-11 21:56:10 +08:00
io . out . bits . uop . cf . exceptionVec : = excep
2021-09-28 09:23:31 +08:00
2021-08-20 01:27:12 +08:00
// For timing reasons, sometimes we can not let
2021-01-25 19:46:19 +08:00
// io.out.bits.miss := s2_cache_miss && !s2_exception && !fullForward
// We use io.dataForwarded instead. It means forward logic have prepared all data needed,
// and dcache query is no longer needed.
// Such inst will be writebacked from load queue.
2021-08-02 19:42:28 +08:00
io . dataForwarded : = s2_cache_miss && fullForward && ! s2_exception && ! s2_forward_fail
2021-02-01 23:59:58 +08:00
// io.out.bits.forwardX will be send to lq
2021-03-05 20:23:11 +08:00
io . out . bits . forwardMask : = forwardMask
2021-02-01 23:59:58 +08:00
// data retbrived from dcache is also included in io.out.bits.forwardData
io . out . bits . forwardData : = rdataVec
2021-01-25 19:46:19 +08:00
2020-10-17 21:05:46 +08:00
io . in . ready : = io . out . ready || ! io . in . valid
2021-08-20 18:17:28 +08:00
// feedback tlb result to RS
io . rsFeedback . valid : = io . in . valid
2021-10-10 11:51:53 +08:00
when ( io . in . bits . isSoftPrefetch ) {
2021-10-27 14:45:39 +08:00
io . rsFeedback . bits . hit : = ( ! s2_tlb_miss && ( ! s2_cache_replay || s2_mmio || s2_exception ) )
2021-10-10 11:51:53 +08:00
} . otherwise {
2021-11-29 11:34:37 +08:00
if ( EnableFastForward ) {
io . rsFeedback . bits . hit : = ! s2_tlb_miss && ( ! s2_cache_replay || s2_mmio || s2_exception || fullForward ) && ! s2_data_invalid
} else {
io . rsFeedback . bits . hit : = ! s2_tlb_miss && ( ! s2_cache_replay || s2_mmio || s2_exception ) && ! s2_data_invalid
}
2021-10-10 11:51:53 +08:00
}
2021-08-20 18:17:28 +08:00
io . rsFeedback . bits . rsIdx : = io . in . bits . rsIdx
io . rsFeedback . bits . flushState : = io . in . bits . ptwBack
io . rsFeedback . bits . sourceType : = Mux ( s2_tlb_miss , RSFeedbackType . tlbMiss ,
2021-10-27 14:45:39 +08:00
Mux ( s2_cache_replay ,
RSFeedbackType . mshrFull ,
RSFeedbackType . dataInvalid
2021-08-20 18:17:28 +08:00
)
)
2021-10-12 19:51:51 +08:00
io . rsFeedback . bits . dataInvalidSqIdx . value : = io . dataInvalidSqIdx
io . rsFeedback . bits . dataInvalidSqIdx . flag : = DontCare
2021-08-20 18:17:28 +08:00
// s2_cache_replay is quite slow to generate, send it separately to LQ
2021-11-29 11:34:37 +08:00
if ( EnableFastForward ) {
io . needReplayFromRS : = s2_cache_replay && ! fullForward
} else {
io . needReplayFromRS : = s2_cache_replay
}
2021-08-20 18:17:28 +08:00
2021-09-02 09:18:01 +08:00
// fast load to load forward
io . fastpath . valid : = io . in . valid // for debug only
io . fastpath . data : = rdata // raw data
2021-09-02 13:54:49 +08:00
2020-11-18 20:47:14 +08:00
XSDebug ( io . out . fire ( ) , "[DCACHE LOAD RESP] pc %x rdata %x <- D$ %x + fwd %x(%b)\n" ,
2020-10-26 19:48:20 +08:00
s2_uop . cf . pc , rdataPartialLoad , io . dcacheResp . bits . data ,
2021-02-01 23:59:58 +08:00
forwardData . asUInt , forwardMask . asUInt
2020-08-06 16:58:13 +08:00
)
2021-03-08 22:31:59 +08:00
2021-09-22 15:48:08 +08:00
XSPerfAccumulate ( "in_valid" , io . in . valid )
XSPerfAccumulate ( "in_fire" , io . in . fire )
XSPerfAccumulate ( "in_fire_first_issue" , io . in . fire && io . in . bits . isFirstIssue )
XSPerfAccumulate ( "dcache_miss" , io . in . fire && s2_cache_miss )
XSPerfAccumulate ( "dcache_miss_first_issue" , io . in . fire && s2_cache_miss && io . in . bits . isFirstIssue )
2021-03-25 21:08:52 +08:00
XSPerfAccumulate ( "full_forward" , io . in . valid && fullForward )
XSPerfAccumulate ( "dcache_miss_full_forward" , io . in . valid && s2_cache_miss && fullForward )
2021-04-30 10:40:51 +08:00
XSPerfAccumulate ( "replay" , io . rsFeedback . valid && ! io . rsFeedback . bits . hit )
XSPerfAccumulate ( "replay_tlb_miss" , io . rsFeedback . valid && ! io . rsFeedback . bits . hit && s2_tlb_miss )
XSPerfAccumulate ( "replay_cache" , io . rsFeedback . valid && ! io . rsFeedback . bits . hit && ! s2_tlb_miss && s2_cache_replay )
2021-03-25 21:08:52 +08:00
XSPerfAccumulate ( "stall_out" , io . out . valid && ! io . out . ready )
2021-10-22 15:29:07 +08:00
XSPerfAccumulate ( "replay_from_fetch_forward" , io . out . valid && forwardFailReplay )
XSPerfAccumulate ( "replay_from_fetch_load_vio" , io . out . valid && ldldVioReplay )
2020-10-17 21:05:46 +08:00
}
2020-08-06 16:58:13 +08:00
2021-04-19 21:19:20 +08:00
class LoadUnit ( implicit p : Parameters ) extends XSModule with HasLoadHelper {
2020-10-17 21:05:46 +08:00
val io = IO ( new Bundle ( ) {
val ldin = Flipped ( Decoupled ( new ExuInput ) )
val ldout = Decoupled ( new ExuOutput )
val redirect = Flipped ( ValidIO ( new Redirect ) )
2021-10-11 16:01:26 +08:00
val feedbackSlow = ValidIO ( new RSFeedback )
val feedbackFast = ValidIO ( new RSFeedback )
2021-01-30 17:31:42 +08:00
val rsIdx = Input ( UInt ( log2Up ( IssQueSize ) . W ) )
2021-03-13 08:49:36 +08:00
val isFirstIssue = Input ( Bool ( ) )
2020-10-25 13:24:10 +08:00
val dcache = new DCacheLoadIO
2020-10-17 21:05:46 +08:00
val sbuffer = new LoadForwardQueryIO
2020-11-18 20:47:14 +08:00
val lsq = new LoadToLsqIO
2021-08-04 09:07:05 +08:00
val fastUop = ValidIO ( new MicroOp ) // early wakeup signal generated in load_s1
l0tlb: add a new level tlb, a load tlb and a store tlb (#961)
* Revert "Revert "l0tlb: add a new level tlb to each mem pipeline (#936)" (#945)"
This reverts commit b052b97230d6fdeedaf4e4905092adef6e768b4f.
* fu: remove unused import
* mmu.tlb: 2 load/store pipeline has 1 dtlb
* mmu: remove btlb, the l1-tlb
* mmu: set split-tlb to 32 to check perf effect
* mmu: wrap tlb's param with TLBParameters
* mmu: add params 'useBTlb'
dtlb size is small: normal 8, super 2
* mmu.tlb: add Bundle TlbEntry, simplify tlb hit logic(coding)
* mmu.tlb: seperate tlb's storage, relative hit/sfence logic
tlb now supports full-associate, set-associate, directive-associate.
more: change tlb's parameter usage, change util.Random to support
case that mod is 1.
* mmu.tlb: support normalAsVictim, super(fa) -> normal(sa/da)
be carefull to use tlb's parameter, only a part of param combination
is supported
* mmu.tlb: fix bug of hit method and victim write
* mmu.tlb: add tlb storage's perf counter
* mmu.tlb: rewrite replace part, support set or non-set
* mmu.tlb: add param outReplace to receive out replace index
* mmu.tlb: change param superSize to superNWays
add param superNSets, which should always be 1
* mmu.tlb: change some perf counter's name and change some params
* mmu.tlb: fix bug of replace io bundle
* mmu.tlb: remove unused signal wayIdx in tlbstorageio
* mmu.tlb: separate tlb_ld/st into two 'same' tlb
* mmu.tlb: when nWays is 1, replace returns 0.U
before, replace will return 1.U, no influence for refill but bad
for perf counter
* mmu.tlb: give tlb_ld and tlb_st a name (in waveform)
2021-09-02 22:53:18 +08:00
val tlb = new TlbRequestIO
pma: add pmp-like pma, software can read and write (#1169)
remove the old hard-wired pma and turn to pmp-like csr registers. the pma config is writen in pma register.
1. pma are m-priv csr, so only m-mode csrrw can change pma
2. even in m-mode, pma should be always checked, no matter lock or not
3. so carefully write pma, make sure not to "suicide"
* pma: add pmp-like pma, just module/bundle added, not to circuit
use reserved 2 bits as atomic and cached
* pma: add pmp-like pma into pmp module
pma have two more attribute than pmp
1. atmoic;
2. c/cache, if false, go to mmio.
pma uses 16+4 machine-level custom ready write csr.
pma will always be checked even in m-mode.
* pma: remove the old MemMap in tlb, mmio arrives next cycle
* pma: ptw raise af when mmio
* pma: fix bug of match's zip with last entry
* pma: fix bug of pass reset signal through method's parameter
strange bug, want to reset, pass reset signal to a method, does not
work.
import chisel3.Module.reset, the method can access reset it's self.
* pma: move some method to trait and fix bug of pma_init value
* pma: fix bug of pma init value assign way
* tlb: fix stupid bug that pf.ld not & fault_valid
* loadunit: fix bug that uop is flushed, pmp's dcache kill failed also
* ifu: mmio access needs f2_valid now
* loadunit: if mmio and have sent fastUop, flush pipe when commit
* storeunit: stu->lsq at stage1 and re-in lsq at stage2 to update mmio
2021-10-25 20:16:15 +08:00
val pmp = Flipped ( new PMPRespBundle ( ) ) // arrive same to tlb now
2021-10-11 21:56:10 +08:00
2021-08-20 22:39:07 +08:00
val fastpathOut = Output ( new LoadToLoadIO )
val fastpathIn = Input ( Vec ( LoadPipelineWidth , new LoadToLoadIO ) )
2021-09-02 09:18:01 +08:00
val loadFastMatch = Input ( UInt ( exuParameters . LduCnt . W ) )
2021-10-22 15:29:07 +08:00
val csrCtrl = Flipped ( new CustomCSRCtrlIO )
2020-10-17 21:05:46 +08:00
} )
val load_s0 = Module ( new LoadUnit_S0 )
val load_s1 = Module ( new LoadUnit_S1 )
val load_s2 = Module ( new LoadUnit_S2 )
load_s0 . io . in <> io . ldin
l0tlb: add a new level tlb, a load tlb and a store tlb (#961)
* Revert "Revert "l0tlb: add a new level tlb to each mem pipeline (#936)" (#945)"
This reverts commit b052b97230d6fdeedaf4e4905092adef6e768b4f.
* fu: remove unused import
* mmu.tlb: 2 load/store pipeline has 1 dtlb
* mmu: remove btlb, the l1-tlb
* mmu: set split-tlb to 32 to check perf effect
* mmu: wrap tlb's param with TLBParameters
* mmu: add params 'useBTlb'
dtlb size is small: normal 8, super 2
* mmu.tlb: add Bundle TlbEntry, simplify tlb hit logic(coding)
* mmu.tlb: seperate tlb's storage, relative hit/sfence logic
tlb now supports full-associate, set-associate, directive-associate.
more: change tlb's parameter usage, change util.Random to support
case that mod is 1.
* mmu.tlb: support normalAsVictim, super(fa) -> normal(sa/da)
be carefull to use tlb's parameter, only a part of param combination
is supported
* mmu.tlb: fix bug of hit method and victim write
* mmu.tlb: add tlb storage's perf counter
* mmu.tlb: rewrite replace part, support set or non-set
* mmu.tlb: add param outReplace to receive out replace index
* mmu.tlb: change param superSize to superNWays
add param superNSets, which should always be 1
* mmu.tlb: change some perf counter's name and change some params
* mmu.tlb: fix bug of replace io bundle
* mmu.tlb: remove unused signal wayIdx in tlbstorageio
* mmu.tlb: separate tlb_ld/st into two 'same' tlb
* mmu.tlb: when nWays is 1, replace returns 0.U
before, replace will return 1.U, no influence for refill but bad
for perf counter
* mmu.tlb: give tlb_ld and tlb_st a name (in waveform)
2021-09-02 22:53:18 +08:00
load_s0 . io . dtlbReq <> io . tlb . req
2020-10-25 13:24:10 +08:00
load_s0 . io . dcacheReq <> io . dcache . req
2021-01-30 17:31:42 +08:00
load_s0 . io . rsIdx : = io . rsIdx
2021-03-13 08:49:36 +08:00
load_s0 . io . isFirstIssue : = io . isFirstIssue
2021-08-20 22:39:07 +08:00
load_s0 . io . fastpath : = io . fastpathIn
2021-09-02 09:18:01 +08:00
load_s0 . io . loadFastMatch : = io . loadFastMatch
2020-10-17 21:05:46 +08:00
2021-10-16 15:03:19 +08:00
PipelineConnect ( load_s0 . io . out , load_s1 . io . in , true . B , load_s0 . io . out . bits . uop . robIdx . needFlush ( io . redirect ) )
2020-10-17 21:05:46 +08:00
l0tlb: add a new level tlb, a load tlb and a store tlb (#961)
* Revert "Revert "l0tlb: add a new level tlb to each mem pipeline (#936)" (#945)"
This reverts commit b052b97230d6fdeedaf4e4905092adef6e768b4f.
* fu: remove unused import
* mmu.tlb: 2 load/store pipeline has 1 dtlb
* mmu: remove btlb, the l1-tlb
* mmu: set split-tlb to 32 to check perf effect
* mmu: wrap tlb's param with TLBParameters
* mmu: add params 'useBTlb'
dtlb size is small: normal 8, super 2
* mmu.tlb: add Bundle TlbEntry, simplify tlb hit logic(coding)
* mmu.tlb: seperate tlb's storage, relative hit/sfence logic
tlb now supports full-associate, set-associate, directive-associate.
more: change tlb's parameter usage, change util.Random to support
case that mod is 1.
* mmu.tlb: support normalAsVictim, super(fa) -> normal(sa/da)
be carefull to use tlb's parameter, only a part of param combination
is supported
* mmu.tlb: fix bug of hit method and victim write
* mmu.tlb: add tlb storage's perf counter
* mmu.tlb: rewrite replace part, support set or non-set
* mmu.tlb: add param outReplace to receive out replace index
* mmu.tlb: change param superSize to superNWays
add param superNSets, which should always be 1
* mmu.tlb: change some perf counter's name and change some params
* mmu.tlb: fix bug of replace io bundle
* mmu.tlb: remove unused signal wayIdx in tlbstorageio
* mmu.tlb: separate tlb_ld/st into two 'same' tlb
* mmu.tlb: when nWays is 1, replace returns 0.U
before, replace will return 1.U, no influence for refill but bad
for perf counter
* mmu.tlb: give tlb_ld and tlb_st a name (in waveform)
2021-09-02 22:53:18 +08:00
load_s1 . io . dtlbResp <> io . tlb . resp
2020-12-13 21:31:00 +08:00
io . dcache . s1_paddr <> load_s1 . io . dcachePAddr
2021-01-08 20:49:30 +08:00
io . dcache . s1_kill <> load_s1 . io . dcacheKill
2020-12-11 19:59:25 +08:00
load_s1 . io . sbuffer <> io . sbuffer
load_s1 . io . lsq <> io . lsq . forward
2021-10-22 15:29:07 +08:00
load_s1 . io . loadViolationQueryReq <> io . lsq . loadViolationQuery . req
2021-10-11 16:01:26 +08:00
load_s1 . io . dcacheBankConflict <> io . dcache . s1_bank_conflict
2021-10-22 15:29:07 +08:00
load_s1 . io . csrCtrl <> io . csrCtrl
2020-10-17 21:05:46 +08:00
2021-10-16 15:03:19 +08:00
PipelineConnect ( load_s1 . io . out , load_s2 . io . in , true . B , load_s1 . io . out . bits . uop . robIdx . needFlush ( io . redirect ) )
2020-10-17 21:05:46 +08:00
pma: add pmp-like pma, software can read and write (#1169)
remove the old hard-wired pma and turn to pmp-like csr registers. the pma config is writen in pma register.
1. pma are m-priv csr, so only m-mode csrrw can change pma
2. even in m-mode, pma should be always checked, no matter lock or not
3. so carefully write pma, make sure not to "suicide"
* pma: add pmp-like pma, just module/bundle added, not to circuit
use reserved 2 bits as atomic and cached
* pma: add pmp-like pma into pmp module
pma have two more attribute than pmp
1. atmoic;
2. c/cache, if false, go to mmio.
pma uses 16+4 machine-level custom ready write csr.
pma will always be checked even in m-mode.
* pma: remove the old MemMap in tlb, mmio arrives next cycle
* pma: ptw raise af when mmio
* pma: fix bug of match's zip with last entry
* pma: fix bug of pass reset signal through method's parameter
strange bug, want to reset, pass reset signal to a method, does not
work.
import chisel3.Module.reset, the method can access reset it's self.
* pma: move some method to trait and fix bug of pma_init value
* pma: fix bug of pma init value assign way
* tlb: fix stupid bug that pf.ld not & fault_valid
* loadunit: fix bug that uop is flushed, pmp's dcache kill failed also
* ifu: mmio access needs f2_valid now
* loadunit: if mmio and have sent fastUop, flush pipe when commit
* storeunit: stu->lsq at stage1 and re-in lsq at stage2 to update mmio
2021-10-25 20:16:15 +08:00
io . dcache . s2_kill : = load_s2 . io . dcache_kill || ( io . pmp . ld || io . pmp . mmio ) // to kill mmio resp which are redirected
2020-10-25 13:24:10 +08:00
load_s2 . io . dcacheResp <> io . dcache . resp
2021-10-11 21:56:10 +08:00
load_s2 . io . pmpResp <> io . pmp
2020-12-13 21:31:00 +08:00
load_s2 . io . lsq . forwardData <> io . lsq . forward . forwardData
load_s2 . io . lsq . forwardMask <> io . lsq . forward . forwardMask
2021-08-20 01:27:12 +08:00
load_s2 . io . lsq . forwardMaskFast <> io . lsq . forward . forwardMaskFast // should not be used in load_s2
2021-04-30 10:40:51 +08:00
load_s2 . io . lsq . dataInvalid <> io . lsq . forward . dataInvalid
2021-08-02 19:42:28 +08:00
load_s2 . io . lsq . matchInvalid <> io . lsq . forward . matchInvalid
2020-12-16 14:44:10 +08:00
load_s2 . io . sbuffer . forwardData <> io . sbuffer . forwardData
load_s2 . io . sbuffer . forwardMask <> io . sbuffer . forwardMask
2021-08-20 01:27:12 +08:00
load_s2 . io . sbuffer . forwardMaskFast <> io . sbuffer . forwardMaskFast // should not be used in load_s2
2021-04-30 10:40:51 +08:00
load_s2 . io . sbuffer . dataInvalid <> io . sbuffer . dataInvalid // always false
2021-08-02 19:42:28 +08:00
load_s2 . io . sbuffer . matchInvalid <> io . sbuffer . matchInvalid
2021-01-25 19:46:19 +08:00
load_s2 . io . dataForwarded <> io . lsq . loadDataForwarded
2021-08-20 22:39:07 +08:00
load_s2 . io . fastpath <> io . fastpathOut
2021-10-12 19:51:51 +08:00
load_s2 . io . dataInvalidSqIdx : = io . lsq . forward . dataInvalidSqIdx // provide dataInvalidSqIdx to make wakeup faster
2021-10-22 15:29:07 +08:00
load_s2 . io . loadViolationQueryResp <> io . lsq . loadViolationQuery . resp
load_s2 . io . csrCtrl <> io . csrCtrl
pma: add pmp-like pma, software can read and write (#1169)
remove the old hard-wired pma and turn to pmp-like csr registers. the pma config is writen in pma register.
1. pma are m-priv csr, so only m-mode csrrw can change pma
2. even in m-mode, pma should be always checked, no matter lock or not
3. so carefully write pma, make sure not to "suicide"
* pma: add pmp-like pma, just module/bundle added, not to circuit
use reserved 2 bits as atomic and cached
* pma: add pmp-like pma into pmp module
pma have two more attribute than pmp
1. atmoic;
2. c/cache, if false, go to mmio.
pma uses 16+4 machine-level custom ready write csr.
pma will always be checked even in m-mode.
* pma: remove the old MemMap in tlb, mmio arrives next cycle
* pma: ptw raise af when mmio
* pma: fix bug of match's zip with last entry
* pma: fix bug of pass reset signal through method's parameter
strange bug, want to reset, pass reset signal to a method, does not
work.
import chisel3.Module.reset, the method can access reset it's self.
* pma: move some method to trait and fix bug of pma_init value
* pma: fix bug of pma init value assign way
* tlb: fix stupid bug that pf.ld not & fault_valid
* loadunit: fix bug that uop is flushed, pmp's dcache kill failed also
* ifu: mmio access needs f2_valid now
* loadunit: if mmio and have sent fastUop, flush pipe when commit
* storeunit: stu->lsq at stage1 and re-in lsq at stage2 to update mmio
2021-10-25 20:16:15 +08:00
load_s2 . io . sentFastUop : = RegEnable ( io . fastUop . valid , load_s1 . io . out . fire ( ) ) // RegNext is also ok
2021-02-08 20:48:27 +08:00
io . lsq . needReplayFromRS : = load_s2 . io . needReplayFromRS
2020-10-17 21:05:46 +08:00
2021-10-11 16:01:26 +08:00
// feedback tlb miss / dcache miss queue full
io . feedbackSlow . bits : = RegNext ( load_s2 . io . rsFeedback . bits )
2021-10-16 15:03:19 +08:00
io . feedbackSlow . valid : = RegNext ( load_s2 . io . rsFeedback . valid && ! load_s2 . io . out . bits . uop . robIdx . needFlush ( io . redirect ) )
2021-10-11 16:01:26 +08:00
// feedback bank conflict to rs
io . feedbackFast . bits : = load_s1 . io . rsFeedback . bits
io . feedbackFast . valid : = load_s1 . io . rsFeedback . valid
2021-10-22 15:29:07 +08:00
// If replay is reported at load_s1, inst will be canceled (will not enter load_s2),
pma: add pmp-like pma, software can read and write (#1169)
remove the old hard-wired pma and turn to pmp-like csr registers. the pma config is writen in pma register.
1. pma are m-priv csr, so only m-mode csrrw can change pma
2. even in m-mode, pma should be always checked, no matter lock or not
3. so carefully write pma, make sure not to "suicide"
* pma: add pmp-like pma, just module/bundle added, not to circuit
use reserved 2 bits as atomic and cached
* pma: add pmp-like pma into pmp module
pma have two more attribute than pmp
1. atmoic;
2. c/cache, if false, go to mmio.
pma uses 16+4 machine-level custom ready write csr.
pma will always be checked even in m-mode.
* pma: remove the old MemMap in tlb, mmio arrives next cycle
* pma: ptw raise af when mmio
* pma: fix bug of match's zip with last entry
* pma: fix bug of pass reset signal through method's parameter
strange bug, want to reset, pass reset signal to a method, does not
work.
import chisel3.Module.reset, the method can access reset it's self.
* pma: move some method to trait and fix bug of pma_init value
* pma: fix bug of pma init value assign way
* tlb: fix stupid bug that pf.ld not & fault_valid
* loadunit: fix bug that uop is flushed, pmp's dcache kill failed also
* ifu: mmio access needs f2_valid now
* loadunit: if mmio and have sent fastUop, flush pipe when commit
* storeunit: stu->lsq at stage1 and re-in lsq at stage2 to update mmio
2021-10-25 20:16:15 +08:00
// in that case:
2021-10-22 15:29:07 +08:00
// * replay should not be reported twice
2021-10-11 16:01:26 +08:00
assert ( ! ( RegNext ( RegNext ( io . feedbackFast . valid ) ) && io . feedbackSlow . valid ) )
2021-10-22 15:29:07 +08:00
// * io.fastUop.valid should not be reported
assert ( ! RegNext ( io . feedbackFast . valid && io . fastUop . valid ) )
2021-10-11 16:01:26 +08:00
2021-02-02 00:17:52 +08:00
// pre-calcuate sqIdx mask in s0, then send it to lsq in s1 for forwarding
val sqIdxMaskReg = RegNext ( UIntToMask ( load_s0 . io . in . bits . uop . sqIdx . value , StoreQueueSize ) )
io . lsq . forward . sqIdxMask : = sqIdxMaskReg
2020-10-17 21:05:46 +08:00
2021-03-10 08:26:40 +08:00
// // use s2_hit_way to select data received in s1
// load_s2.io.dcacheResp.bits.data := Mux1H(RegNext(io.dcache.s1_hit_way), RegNext(io.dcache.s1_data))
// assert(load_s2.io.dcacheResp.bits.data === io.dcache.resp.bits.data)
2021-08-20 18:17:28 +08:00
io . fastUop . valid : = io . dcache . s1_hit_way . orR && // dcache hit
! io . dcache . s1_disable_fast_wakeup && // load fast wakeup should be disabled when dcache data read is not ready
load_s1 . io . in . valid && // valid laod request
2021-12-01 12:52:37 +08:00
! load_s1 . io . fastUopKill && // not mmio or tlb miss
2021-10-22 15:29:07 +08:00
! io . lsq . forward . dataInvalidFast && // forward failed
! load_s1 . io . needLdVioCheckRedo // load-load violation check: load paddr cam struct hazard
2021-03-10 08:26:40 +08:00
io . fastUop . bits : = load_s1 . io . out . bits . uop
2020-10-17 21:05:46 +08:00
XSDebug ( load_s0 . io . out . valid ,
2020-10-31 23:12:13 +08:00
p "S0: pc ${Hexadecimal(load_s0.io.out.bits.uop.cf.pc)}, lId ${Hexadecimal(load_s0.io.out.bits.uop.lqIdx.asUInt)}, " +
2020-10-17 21:05:46 +08:00
p "vaddr ${Hexadecimal(load_s0.io.out.bits.vaddr)}, mask ${Hexadecimal(load_s0.io.out.bits.mask)}\n" )
2020-11-18 20:47:14 +08:00
XSDebug ( load_s1 . io . out . valid ,
l0tlb: add a new level tlb, a load tlb and a store tlb (#961)
* Revert "Revert "l0tlb: add a new level tlb to each mem pipeline (#936)" (#945)"
This reverts commit b052b97230d6fdeedaf4e4905092adef6e768b4f.
* fu: remove unused import
* mmu.tlb: 2 load/store pipeline has 1 dtlb
* mmu: remove btlb, the l1-tlb
* mmu: set split-tlb to 32 to check perf effect
* mmu: wrap tlb's param with TLBParameters
* mmu: add params 'useBTlb'
dtlb size is small: normal 8, super 2
* mmu.tlb: add Bundle TlbEntry, simplify tlb hit logic(coding)
* mmu.tlb: seperate tlb's storage, relative hit/sfence logic
tlb now supports full-associate, set-associate, directive-associate.
more: change tlb's parameter usage, change util.Random to support
case that mod is 1.
* mmu.tlb: support normalAsVictim, super(fa) -> normal(sa/da)
be carefull to use tlb's parameter, only a part of param combination
is supported
* mmu.tlb: fix bug of hit method and victim write
* mmu.tlb: add tlb storage's perf counter
* mmu.tlb: rewrite replace part, support set or non-set
* mmu.tlb: add param outReplace to receive out replace index
* mmu.tlb: change param superSize to superNWays
add param superNSets, which should always be 1
* mmu.tlb: change some perf counter's name and change some params
* mmu.tlb: fix bug of replace io bundle
* mmu.tlb: remove unused signal wayIdx in tlbstorageio
* mmu.tlb: separate tlb_ld/st into two 'same' tlb
* mmu.tlb: when nWays is 1, replace returns 0.U
before, replace will return 1.U, no influence for refill but bad
for perf counter
* mmu.tlb: give tlb_ld and tlb_st a name (in waveform)
2021-09-02 22:53:18 +08:00
p "S1: pc ${Hexadecimal(load_s1.io.out.bits.uop.cf.pc)}, lId ${Hexadecimal(load_s1.io.out.bits.uop.lqIdx.asUInt)}, tlb_miss ${io.tlb.resp.bits.miss}, " +
2020-10-26 17:31:38 +08:00
p "paddr ${Hexadecimal(load_s1.io.out.bits.paddr)}, mmio ${load_s1.io.out.bits.mmio}\n" )
2020-08-06 16:58:13 +08:00
2020-11-18 20:47:14 +08:00
// writeback to LSQ
2020-08-06 16:58:13 +08:00
// Current dcache use MSHR
2021-01-06 01:09:22 +08:00
// Load queue will be updated at s2 for both hit/miss int/fp load
2020-11-18 20:47:14 +08:00
io . lsq . loadIn . valid : = load_s2 . io . out . valid
io . lsq . loadIn . bits : = load_s2 . io . out . bits
2021-01-15 22:24:39 +08:00
// write to rob and writeback bus
2021-04-24 09:22:59 +08:00
val s2_wb_valid = load_s2 . io . out . valid && ! load_s2 . io . out . bits . miss && ! load_s2 . io . out . bits . mmio
2020-08-06 16:58:13 +08:00
2021-01-06 01:09:22 +08:00
// Int load, if hit, will be writebacked at s2
2021-02-19 22:41:55 +08:00
val hitLoadOut = Wire ( Valid ( new ExuOutput ) )
hitLoadOut . valid : = s2_wb_valid
hitLoadOut . bits . uop : = load_s2 . io . out . bits . uop
hitLoadOut . bits . data : = load_s2 . io . out . bits . data
hitLoadOut . bits . redirectValid : = false . B
hitLoadOut . bits . redirect : = DontCare
hitLoadOut . bits . debug . isMMIO : = load_s2 . io . out . bits . mmio
hitLoadOut . bits . debug . isPerfCnt : = false . B
hitLoadOut . bits . debug . paddr : = load_s2 . io . out . bits . paddr
2021-11-15 11:32:40 +08:00
hitLoadOut . bits . debug . vaddr : = load_s2 . io . out . bits . vaddr
2021-02-19 22:41:55 +08:00
hitLoadOut . bits . fflags : = DontCare
2020-08-06 16:58:13 +08:00
2020-10-17 21:05:46 +08:00
load_s2 . io . out . ready : = true . B
2021-01-06 01:09:22 +08:00
2021-02-19 22:41:55 +08:00
io . ldout . bits : = Mux ( hitLoadOut . valid , hitLoadOut . bits , io . lsq . ldout . bits )
io . ldout . valid : = hitLoadOut . valid || io . lsq . ldout . valid
2021-01-14 16:18:29 +08:00
2021-02-19 22:41:55 +08:00
io . lsq . ldout . ready : = ! hitLoadOut . valid
2020-08-16 15:59:15 +08:00
2021-10-23 13:38:45 +08:00
val perfinfo = IO ( new Bundle ( ) {
val perfEvents = Output ( new PerfEventsBundle ( 12 ) )
} )
val perfEvents = Seq (
( "load_s0_in_fire " , load_s0 . io . in . fire ( ) ) ,
( "load_to_load_forward " , load_s0 . io . loadFastMatch . orR && load_s0 . io . in . fire ( ) ) ,
( "stall_dcache " , load_s0 . io . out . valid && load_s0 . io . out . ready && ! load_s0 . io . dcacheReq . ready ) ,
( "addr_spec_success " , load_s0 . io . out . fire ( ) && load_s0 . io . dtlbReq . bits . vaddr ( VAddrBits - 1 , 12 ) === load_s0 . io . in . bits . src ( 0 ) ( VAddrBits - 1 , 12 ) ) ,
( "addr_spec_failed " , load_s0 . io . out . fire ( ) && load_s0 . io . dtlbReq . bits . vaddr ( VAddrBits - 1 , 12 ) =/= load_s0 . io . in . bits . src ( 0 ) ( VAddrBits - 1 , 12 ) ) ,
( "load_s1_in_fire " , load_s1 . io . in . fire ) ,
( "load_s1_tlb_miss " , load_s1 . io . in . fire && load_s1 . io . dtlbResp . bits . miss ) ,
( "load_s2_in_fire " , load_s2 . io . in . fire ) ,
( "load_s2_dcache_miss " , load_s2 . io . in . fire && load_s2 . io . dcacheResp . bits . miss ) ,
( "load_s2_replay " , load_s2 . io . rsFeedback . valid && ! load_s2 . io . rsFeedback . bits . hit ) ,
( "load_s2_replay_tlb_miss " , load_s2 . io . rsFeedback . valid && ! load_s2 . io . rsFeedback . bits . hit && load_s2 . io . in . bits . tlbMiss ) ,
( "load_s2_replay_cache " , load_s2 . io . rsFeedback . valid && ! load_s2 . io . rsFeedback . bits . hit && ! load_s2 . io . in . bits . tlbMiss && load_s2 . io . dcacheResp . bits . miss ) ,
)
for ( ( ( perf_out , ( perf_name , perf ) ) , i ) <- perfinfo . perfEvents . perf_events . zip ( perfEvents ) . zipWithIndex ) {
perf_out . incr_step : = RegNext ( perf )
}
2020-08-20 22:46:53 +08:00
when ( io . ldout . fire ( ) ) {
2021-01-06 01:09:22 +08:00
XSDebug ( "ldout %x\n" , io . ldout . bits . uop . cf . pc )
}
2021-01-08 17:17:13 +08:00
}