Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
OpenXiangShan
XiangShan
提交
4fe32a16
X
XiangShan
项目概览
OpenXiangShan
/
XiangShan
10 个月 前同步成功
通知
1183
Star
3914
Fork
526
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
X
XiangShan
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
未验证
提交
4fe32a16
编写于
11月 13, 2021
作者:
Y
Yinan Xu
提交者:
GitHub
11月 13, 2021
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #1202 from OpenXiangShan/dtlb-pipe
core: add one more cycles between dtlb and ptw
上级
066ac8a4
5c14ffc2
变更
7
隐藏空白更改
内联
并排
Showing
7 changed file
with
170 addition
and
56 deletion
+170
-56
src/main/scala/utils/PipelineConnect.scala
src/main/scala/utils/PipelineConnect.scala
+1
-1
src/main/scala/utils/ResetGen.scala
src/main/scala/utils/ResetGen.scala
+1
-1
src/main/scala/xiangshan/XSCore.scala
src/main/scala/xiangshan/XSCore.scala
+3
-2
src/main/scala/xiangshan/cache/mmu/PTW.scala
src/main/scala/xiangshan/cache/mmu/PTW.scala
+15
-9
src/main/scala/xiangshan/cache/mmu/PageTableCache.scala
src/main/scala/xiangshan/cache/mmu/PageTableCache.scala
+31
-20
src/main/scala/xiangshan/cache/mmu/PageTableWalker.scala
src/main/scala/xiangshan/cache/mmu/PageTableWalker.scala
+11
-11
src/main/scala/xiangshan/cache/mmu/Repeater.scala
src/main/scala/xiangshan/cache/mmu/Repeater.scala
+108
-12
未找到文件。
src/main/scala/utils/PipelineConnect.scala
浏览文件 @
4fe32a16
...
...
@@ -54,4 +54,4 @@ object PipelineConnect {
pipelineConnect
.
io
.
isFlush
:=
isFlush
right
<>
pipelineConnect
.
io
.
out
}
}
}
\ No newline at end of file
src/main/scala/utils/ResetGen.scala
浏览文件 @
4fe32a16
...
...
@@ -28,7 +28,7 @@ class ResetGen extends Module {
}
object
ResetGen
{
def
apply
(
resetChain
:
Seq
[
Seq
[
Module
]],
reset
:
Bool
,
sim
:
Boolean
)
:
Seq
[
Bool
]
=
{
def
apply
(
resetChain
:
Seq
[
Seq
[
M
ultiIOM
odule
]],
reset
:
Bool
,
sim
:
Boolean
)
:
Seq
[
Bool
]
=
{
val
resetReg
=
Wire
(
Vec
(
resetChain
.
length
+
1
,
Bool
()))
resetReg
.
foreach
(
_
:=
reset
)
for
((
resetLevel
,
i
)
<-
resetChain
.
zipWithIndex
)
{
...
...
src/main/scala/xiangshan/XSCore.scala
浏览文件 @
4fe32a16
...
...
@@ -297,7 +297,8 @@ class XSCoreImp(outer: XSCoreBase) extends LazyModuleImp(outer)
val
itlbRepeater1
=
PTWRepeater
(
frontend
.
io
.
ptw
,
fenceio
.
sfence
,
csrioIn
.
tlb
)
val
itlbRepeater2
=
PTWRepeater
(
itlbRepeater1
.
io
.
ptw
,
ptw
.
io
.
tlb
(
0
),
fenceio
.
sfence
,
csrioIn
.
tlb
)
val
dtlbRepeater
=
PTWFilter
(
memBlock
.
io
.
ptw
,
ptw
.
io
.
tlb
(
1
),
fenceio
.
sfence
,
csrioIn
.
tlb
,
l2tlbParams
.
filterSize
)
val
dtlbRepeater1
=
PTWFilter
(
memBlock
.
io
.
ptw
,
fenceio
.
sfence
,
csrioIn
.
tlb
,
l2tlbParams
.
filterSize
)
val
dtlbRepeater2
=
PTWRepeaterNB
(
passReady
=
false
,
dtlbRepeater1
.
io
.
ptw
,
ptw
.
io
.
tlb
(
1
),
fenceio
.
sfence
,
csrioIn
.
tlb
)
ptw
.
io
.
sfence
<>
fenceio
.
sfence
ptw
.
io
.
csr
.
tlb
<>
csrioIn
.
tlb
ptw
.
io
.
csr
.
distribute_csr
<>
csrioIn
.
customCtrl
.
distribute_csr
...
...
@@ -311,7 +312,7 @@ class XSCoreImp(outer: XSCoreBase) extends LazyModuleImp(outer)
// v v v v v
// PTW {MemBlock, dtlb} ExuBlocks CtrlBlock {Frontend, itlb}
val
resetChain
=
Seq
(
Seq
(
memBlock
,
dtlbRepeater
),
Seq
(
memBlock
,
dtlbRepeater
1
,
dtlbRepeater2
),
Seq
(
exuBlocks
.
head
),
// Note: arbiters don't actually have reset ports
exuBlocks
.
tail
++
Seq
(
outer
.
wbArbiter
.
module
),
...
...
src/main/scala/xiangshan/cache/mmu/PTW.scala
浏览文件 @
4fe32a16
...
...
@@ -98,6 +98,7 @@ class PTWImp(outer: PTW)(implicit p: Parameters) extends PtwModule(outer) with H
val
source
=
UInt
(
bSourceWidth
.
W
)
},
if
(
l2tlbParams
.
enablePrefetch
)
3
else
2
))
val
outArb
=
(
0
until
PtwWidth
).
map
(
i
=>
Module
(
new
Arbiter
(
new
PtwResp
,
3
)).
io
)
val
outArbCachePort
=
0
val
outArbFsmPort
=
1
val
outArbMqPort
=
2
...
...
@@ -130,7 +131,9 @@ class PTWImp(outer: PTW)(implicit p: Parameters) extends PtwModule(outer) with H
cache
.
io
.
req
.
bits
.
isFirst
:=
arb2
.
io
.
chosen
=/=
InArbMissQueuePort
.
U
cache
.
io
.
sfence
:=
sfence
cache
.
io
.
csr
:=
csr
cache
.
io
.
resp
.
ready
:=
Mux
(
cache
.
io
.
resp
.
bits
.
hit
,
true
.
B
,
missQueue
.
io
.
in
.
ready
||
(!
cache
.
io
.
resp
.
bits
.
toFsm
.
l2Hit
&&
fsm
.
io
.
req
.
ready
))
cache
.
io
.
resp
.
ready
:=
Mux
(
cache
.
io
.
resp
.
bits
.
hit
,
outReady
(
cache
.
io
.
resp
.
bits
.
req_info
.
source
,
outArbCachePort
),
missQueue
.
io
.
in
.
ready
||
(!
cache
.
io
.
resp
.
bits
.
toFsm
.
l2Hit
&&
fsm
.
io
.
req
.
ready
))
val
mq_in_arb
=
Module
(
new
Arbiter
(
new
L2TlbMQInBundle
,
2
))
mq_in_arb
.
io
.
in
(
0
).
valid
:=
cache
.
io
.
resp
.
valid
&&
!
cache
.
io
.
resp
.
bits
.
hit
&&
(
cache
.
io
.
resp
.
bits
.
toFsm
.
l2Hit
||
!
fsm
.
io
.
req
.
ready
)
...
...
@@ -150,8 +153,7 @@ class PTWImp(outer: PTW)(implicit p: Parameters) extends PtwModule(outer) with H
fsm
.
io
.
req
.
bits
.
ppn
:=
cache
.
io
.
resp
.
bits
.
toFsm
.
ppn
fsm
.
io
.
csr
:=
csr
fsm
.
io
.
sfence
:=
sfence
fsm
.
io
.
resp
.
ready
:=
MuxLookup
(
fsm
.
io
.
resp
.
bits
.
source
,
true
.
B
,
(
0
until
PtwWidth
).
map
(
i
=>
i
.
U
->
outArb
(
i
).
in
(
outArbFsmPort
).
ready
))
fsm
.
io
.
resp
.
ready
:=
outReady
(
fsm
.
io
.
resp
.
bits
.
source
,
outArbFsmPort
)
// mem req
def
blockBytes_align
(
addr
:
UInt
)
=
{
...
...
@@ -239,13 +241,12 @@ class PTWImp(outer: PTW)(implicit p: Parameters) extends PtwModule(outer) with H
pmp_check
(
1
).
req
<>
missQueue
.
io
.
pmp
.
req
missQueue
.
io
.
pmp
.
resp
<>
pmp_check
(
1
).
resp
mq_out
.
ready
:=
MuxLookup
(
missQueue
.
io
.
out
.
bits
.
req_info
.
source
,
true
.
B
,
(
0
until
PtwWidth
).
map
(
i
=>
i
.
U
->
outArb
(
i
).
in
(
outArbMqPort
).
ready
))
mq_out
.
ready
:=
outReady
(
mq_out
.
bits
.
req_info
.
source
,
outArbMqPort
)
for
(
i
<-
0
until
PtwWidth
)
{
outArb
(
i
).
in
(
0
).
valid
:=
cache
.
io
.
resp
.
valid
&&
cache
.
io
.
resp
.
bits
.
hit
&&
cache
.
io
.
resp
.
bits
.
req_info
.
source
===
i
.
U
outArb
(
i
).
in
(
0
).
bits
.
entry
:=
cache
.
io
.
resp
.
bits
.
toTlb
outArb
(
i
).
in
(
0
).
bits
.
pf
:=
false
.
B
outArb
(
i
).
in
(
0
).
bits
.
af
:=
false
.
B
outArb
(
i
).
in
(
outArbCachePort
).
valid
:=
cache
.
io
.
resp
.
valid
&&
cache
.
io
.
resp
.
bits
.
hit
&&
cache
.
io
.
resp
.
bits
.
req_info
.
source
===
i
.
U
outArb
(
i
).
in
(
outArbCachePort
).
bits
.
entry
:=
cache
.
io
.
resp
.
bits
.
toTlb
outArb
(
i
).
in
(
outArbCachePort
).
bits
.
pf
:=
false
.
B
outArb
(
i
).
in
(
outArbCachePort
).
bits
.
af
:=
false
.
B
outArb
(
i
).
in
(
outArbFsmPort
).
valid
:=
fsm
.
io
.
resp
.
valid
&&
fsm
.
io
.
resp
.
bits
.
source
===
i
.
U
outArb
(
i
).
in
(
outArbFsmPort
).
bits
:=
fsm
.
io
.
resp
.
bits
.
resp
outArb
(
i
).
in
(
outArbMqPort
).
valid
:=
mq_out
.
valid
&&
mq_out
.
bits
.
req_info
.
source
===
i
.
U
...
...
@@ -297,6 +298,11 @@ class PTWImp(outer: PTW)(implicit p: Parameters) extends PtwModule(outer) with H
ptw_resp
}
def
outReady
(
source
:
UInt
,
port
:
Int
)
:
Bool
=
{
MuxLookup
(
source
,
true
.
B
,
(
0
until
PtwWidth
).
map
(
i
=>
i
.
U
->
outArb
(
i
).
in
(
port
).
ready
))
}
// debug info
for
(
i
<-
0
until
PtwWidth
)
{
XSDebug
(
p
"[io.tlb(${i.U})] ${io.tlb(i)}\n"
)
...
...
src/main/scala/xiangshan/cache/mmu/PageTableCache.scala
浏览文件 @
4fe32a16
...
...
@@ -103,13 +103,18 @@ class PtwCache()(implicit p: Parameters) extends XSModule with HasPtwConst {
val
rwHarzad
=
if
(
sramSinglePort
)
io
.
refill
.
valid
else
false
.
B
// handle hand signal and req_info
val
stage1
=
Wire
(
Decoupled
(
new
PtwCacheReq
()))
val
stage2
=
Wire
(
Decoupled
(
new
PtwCacheReq
()))
val
stage3
=
Wire
(
Decoupled
(
new
PtwCacheReq
()))
val
stage1
=
Wire
(
Decoupled
(
new
PtwCacheReq
()))
// enq stage & read page cache valid
val
stage2
=
Wire
(
Vec
(
2
,
Decoupled
(
new
PtwCacheReq
())))
// page cache resp & check hit & check ecc
val
stage3
=
Wire
(
Decoupled
(
new
PtwCacheReq
()))
// deq stage
/* stage1.valid && stage2(0).ready : stage1 (in) -> stage2
* stage2(1).valid && stage3.ready : stage2 -> stage3
* stage3.valid && io.resp.ready : stage3 (out) -> outside
*/
stage1
<>
io
.
req
PipelineConnect
(
stage1
,
stage2
,
stage3
.
ready
,
flush
,
rwHarzad
)
PipelineConnect
(
stage2
,
stage3
,
io
.
resp
.
ready
,
flush
)
stage3
.
ready
:=
io
.
resp
.
ready
PipelineConnect
(
stage1
,
stage2
(
0
),
stage2
(
1
).
ready
,
flush
,
rwHarzad
)
InsideStageConnect
(
stage2
(
0
),
stage2
(
1
))
PipelineConnect
(
stage2
(
1
),
stage3
,
io
.
resp
.
ready
,
flush
)
stage3
.
ready
:=
!
stage3
.
valid
||
io
.
resp
.
ready
// l1: level 0 non-leaf pte
val
l1
=
Reg
(
Vec
(
l2tlbParams
.
l1Size
,
new
PtwEntry
(
tagLen
=
PtwL1TagLen
)))
...
...
@@ -200,7 +205,7 @@ class PtwCache()(implicit p: Parameters) extends XSModule with HasPtwConst {
XSDebug
(
stage1
.
fire
,
p
"[l1] l1(${i.U}) ${l1(i)} hit:${l1(i).hit(stage1.bits.req_info.vpn, io.csr.satp.asid)}\n"
)
}
XSDebug
(
stage1
.
fire
,
p
"[l1] l1v:${Binary(l1v)} hitVecT:${Binary(VecInit(hitVecT).asUInt)}\n"
)
XSDebug
(
stage2
.
valid
,
p
"[l1] l1Hit:${hit} l1HitPPN:0x${Hexadecimal(hitPPN)} hitVec:${VecInit(hitVec).asUInt}\n"
)
XSDebug
(
stage2
(
0
)
.
valid
,
p
"[l1] l1Hit:${hit} l1HitPPN:0x${Hexadecimal(hitPPN)} hitVec:${VecInit(hitVec).asUInt}\n"
)
VecInit
(
hitVecT
).
suggestName
(
s
"l1_hitVecT"
)
VecInit
(
hitVec
).
suggestName
(
s
"l1_hitVec"
)
...
...
@@ -217,7 +222,7 @@ class PtwCache()(implicit p: Parameters) extends XSModule with HasPtwConst {
l2
.
io
.
r
.
req
.
valid
:=
stage1
.
fire
l2
.
io
.
r
.
req
.
bits
.
apply
(
setIdx
=
ridx
)
val
ramDatas
=
l2
.
io
.
r
.
resp
.
data
val
hitVec
=
VecInit
(
ramDatas
.
zip
(
vidx
).
map
{
case
(
wayData
,
v
)
=>
wayData
.
entries
.
hit
(
stage2
.
bits
.
req_info
.
vpn
,
io
.
csr
.
satp
.
asid
)
&&
v
})
val
hitVec
=
VecInit
(
ramDatas
.
zip
(
vidx
).
map
{
case
(
wayData
,
v
)
=>
wayData
.
entries
.
hit
(
stage2
(
0
)
.
bits
.
req_info
.
vpn
,
io
.
csr
.
satp
.
asid
)
&&
v
})
val
hitWayEntry
=
ParallelPriorityMux
(
hitVec
zip
ramDatas
)
val
hitWayData
=
hitWayEntry
.
entries
val
hit
=
ParallelOR
(
hitVec
)
&&
cache_read_valid
&&
RegNext
(
l2
.
io
.
r
.
req
.
ready
,
init
=
false
.
B
)
...
...
@@ -231,16 +236,16 @@ class PtwCache()(implicit p: Parameters) extends XSModule with HasPtwConst {
hitWayData
.
suggestName
(
s
"l2_hitWayData"
)
hitWay
.
suggestName
(
s
"l2_hitWay"
)
when
(
hit
)
{
ptwl2replace
.
access
(
genPtwL2SetIdx
(
stage2
.
bits
.
req_info
.
vpn
),
hitWay
)
}
when
(
hit
)
{
ptwl2replace
.
access
(
genPtwL2SetIdx
(
stage2
(
0
)
.
bits
.
req_info
.
vpn
),
hitWay
)
}
l2AccessPerf
.
zip
(
hitVec
).
map
{
case
(
l
,
h
)
=>
l
:=
h
&&
RegNext
(
stage1
.
fire
)
}
XSDebug
(
stage1
.
fire
,
p
"[l2] ridx:0x${Hexadecimal(ridx)}\n"
)
for
(
i
<-
0
until
l2tlbParams
.
l2nWays
)
{
XSDebug
(
RegNext
(
stage1
.
fire
),
p
"[l2] ramDatas(${i.U}) ${ramDatas(i)} l2v:${vidx(i)} hit:${ramDatas(i).entries.hit(stage2.bits.req_info.vpn, io.csr.satp.asid)}\n"
)
XSDebug
(
RegNext
(
stage1
.
fire
),
p
"[l2] ramDatas(${i.U}) ${ramDatas(i)} l2v:${vidx(i)} hit:${ramDatas(i).entries.hit(stage2
(0)
.bits.req_info.vpn, io.csr.satp.asid)}\n"
)
}
XSDebug
(
stage2
.
valid
,
p
"[l2] l2Hit:${hit} l2HitPPN:0x${Hexadecimal(hitWayData.ppns(genPtwL2SectorIdx(stage2
.bits.req_info.vpn)))} hitVec:${Binary(hitVec.asUInt)} hitWay:${hitWay} vidx:${Binary(vidx.asUInt)}\n"
)
XSDebug
(
stage2
(
0
).
valid
,
p
"[l2] l2Hit:${hit} l2HitPPN:0x${Hexadecimal(hitWayData.ppns(genPtwL2SectorIdx(stage2(0)
.bits.req_info.vpn)))} hitVec:${Binary(hitVec.asUInt)} hitWay:${hitWay} vidx:${Binary(vidx.asUInt)}\n"
)
(
hit
,
hitWayData
.
ppns
(
genPtwL2SectorIdx
(
stage2
.
bits
.
req_info
.
vpn
)),
hitWayData
.
prefetch
,
eccError
)
(
hit
,
hitWayData
.
ppns
(
genPtwL2SectorIdx
(
stage2
(
0
)
.
bits
.
req_info
.
vpn
)),
hitWayData
.
prefetch
,
eccError
)
}
// l3
...
...
@@ -252,7 +257,7 @@ class PtwCache()(implicit p: Parameters) extends XSModule with HasPtwConst {
l3
.
io
.
r
.
req
.
valid
:=
stage1
.
fire
l3
.
io
.
r
.
req
.
bits
.
apply
(
setIdx
=
ridx
)
val
ramDatas
=
l3
.
io
.
r
.
resp
.
data
val
hitVec
=
VecInit
(
ramDatas
.
zip
(
vidx
).
map
{
case
(
wayData
,
v
)
=>
wayData
.
entries
.
hit
(
stage2
.
bits
.
req_info
.
vpn
,
io
.
csr
.
satp
.
asid
)
&&
v
})
val
hitVec
=
VecInit
(
ramDatas
.
zip
(
vidx
).
map
{
case
(
wayData
,
v
)
=>
wayData
.
entries
.
hit
(
stage2
(
0
)
.
bits
.
req_info
.
vpn
,
io
.
csr
.
satp
.
asid
)
&&
v
})
val
hitWayEntry
=
ParallelPriorityMux
(
hitVec
zip
ramDatas
)
val
hitWayData
=
hitWayEntry
.
entries
val
hitWayEcc
=
hitWayEntry
.
ecc
...
...
@@ -260,14 +265,14 @@ class PtwCache()(implicit p: Parameters) extends XSModule with HasPtwConst {
val
hitWay
=
ParallelPriorityMux
(
hitVec
zip
(
0
until
l2tlbParams
.
l3nWays
).
map
(
_
.
U
))
val
eccError
=
hitWayEntry
.
decode
()
when
(
hit
)
{
ptwl3replace
.
access
(
genPtwL3SetIdx
(
stage2
.
bits
.
req_info
.
vpn
),
hitWay
)
}
when
(
hit
)
{
ptwl3replace
.
access
(
genPtwL3SetIdx
(
stage2
(
0
)
.
bits
.
req_info
.
vpn
),
hitWay
)
}
l3AccessPerf
.
zip
(
hitVec
).
map
{
case
(
l
,
h
)
=>
l
:=
h
&&
RegNext
(
stage1
.
fire
)
}
XSDebug
(
stage1
.
fire
,
p
"[l3] ridx:0x${Hexadecimal(ridx)}\n"
)
for
(
i
<-
0
until
l2tlbParams
.
l3nWays
)
{
XSDebug
(
RegNext
(
stage1
.
fire
),
p
"[l3] ramDatas(${i.U}) ${ramDatas(i)} l3v:${vidx(i)} hit:${ramDatas(i).entries.hit(stage2.bits.req_info.vpn, io.csr.satp.asid)}\n"
)
XSDebug
(
RegNext
(
stage1
.
fire
),
p
"[l3] ramDatas(${i.U}) ${ramDatas(i)} l3v:${vidx(i)} hit:${ramDatas(i).entries.hit(stage2
(0)
.bits.req_info.vpn, io.csr.satp.asid)}\n"
)
}
XSDebug
(
stage2
.
valid
,
p
"[l3] l3Hit:${hit} l3HitData:${hitWayData} hitVec:${Binary(hitVec.asUInt)} hitWay:${hitWay} vidx:${Binary(vidx.asUInt)}\n"
)
XSDebug
(
stage2
(
0
)
.
valid
,
p
"[l3] l3Hit:${hit} l3HitData:${hitWayData} hitVec:${Binary(hitVec.asUInt)} hitWay:${hitWay} vidx:${Binary(vidx.asUInt)}\n"
)
ridx
.
suggestName
(
s
"l3_ridx"
)
vidx
.
suggestName
(
s
"l3_vidx"
)
...
...
@@ -277,8 +282,8 @@ class PtwCache()(implicit p: Parameters) extends XSModule with HasPtwConst {
(
hit
,
hitWayData
,
hitWayData
.
prefetch
,
eccError
)
}
val
l3HitPPN
=
l3HitData
.
ppns
(
genPtwL3SectorIdx
(
stage2
.
bits
.
req_info
.
vpn
))
val
l3HitPerm
=
l3HitData
.
perms
.
getOrElse
(
0.
U
.
asTypeOf
(
Vec
(
PtwL3SectorSize
,
new
PtePermBundle
)))(
genPtwL3SectorIdx
(
stage2
.
bits
.
req_info
.
vpn
))
val
l3HitPPN
=
l3HitData
.
ppns
(
genPtwL3SectorIdx
(
stage2
(
0
)
.
bits
.
req_info
.
vpn
))
val
l3HitPerm
=
l3HitData
.
perms
.
getOrElse
(
0.
U
.
asTypeOf
(
Vec
(
PtwL3SectorSize
,
new
PtePermBundle
)))(
genPtwL3SectorIdx
(
stage2
(
0
)
.
bits
.
req_info
.
vpn
))
// super page
val
spreplace
=
ReplacementPolicy
.
fromString
(
l2tlbParams
.
spReplacer
,
l2tlbParams
.
spSize
)
...
...
@@ -294,7 +299,7 @@ class PtwCache()(implicit p: Parameters) extends XSModule with HasPtwConst {
for
(
i
<-
0
until
l2tlbParams
.
spSize
)
{
XSDebug
(
stage1
.
fire
,
p
"[sp] sp(${i.U}) ${sp(i)} hit:${sp(i).hit(stage1.bits.req_info.vpn, io.csr.satp.asid)} spv:${spv(i)}\n"
)
}
XSDebug
(
stage2
.
valid
,
p
"[sp] spHit:${hit} spHitData:${hitData} hitVec:${Binary(VecInit(hitVec).asUInt)}\n"
)
XSDebug
(
stage2
(
0
)
.
valid
,
p
"[sp] spHit:${hit} spHitData:${hitData} hitVec:${Binary(VecInit(hitVec).asUInt)}\n"
)
VecInit
(
hitVecT
).
suggestName
(
s
"sp_hitVecT"
)
VecInit
(
hitVec
).
suggestName
(
s
"sp_hitVec"
)
...
...
@@ -313,7 +318,7 @@ class PtwCache()(implicit p: Parameters) extends XSModule with HasPtwConst {
// stage3, add stage 3 for ecc check...
val
s3_res
=
Reg
(
new
PageCacheRespBundle
)
when
(
stage2
.
fire
())
{
when
(
stage2
(
1
)
.
fire
())
{
s3_res
:=
s2_res_reg
}
...
...
@@ -551,6 +556,12 @@ class PtwCache()(implicit p: Parameters) extends XSModule with HasPtwConst {
}
}
def
InsideStageConnect
[
T
<:
Data
](
in
:
DecoupledIO
[
T
],
out
:
DecoupledIO
[
T
],
block
:
Bool
=
false
.
B
)
:
Unit
=
{
in
.
ready
:=
!
in
.
valid
||
out
.
ready
out
.
valid
:=
in
.
valid
out
.
bits
:=
in
.
bits
}
// Perf Count
val
resp_l3
=
s3_res
.
l3
.
hit
val
resp_sp
=
s3_res
.
sp
.
hit
...
...
src/main/scala/xiangshan/cache/mmu/PageTableWalker.scala
浏览文件 @
4fe32a16
...
...
@@ -117,21 +117,21 @@ class PtwFsm()(implicit p: Parameters) extends XSModule with HasPtwConst {
}
is
(
s_check_pte
)
{
when
(
io
.
resp
.
valid
)
{
when
(
io
.
resp
.
valid
)
{
// find pte already or accessFault (mentioned below)
when
(
io
.
resp
.
fire
())
{
state
:=
s_idle
}
finish
:=
true
.
B
}.
otherwise
{
when
(
io
.
pmp
.
resp
.
ld
)
{
// do nothing
}
.
elsewhen
(
io
.
mq
.
valid
)
{
when
(
io
.
mq
.
fire
())
{
state
:=
s_idle
}
finish
:=
true
.
B
}.
otherwise
{
//
when level is 1.U, finish
assert
(
level
=
/=
2
.
U
)
}.
elsewhen
(
io
.
mq
.
valid
)
{
// the next level is pte, go to miss queue
when
(
io
.
mq
.
fire
()
)
{
state
:=
s_idle
}
finish
:=
true
.
B
}
otherwise
{
// go to next level, access the memory, need pmp check first
when
(
io
.
pmp
.
resp
.
ld
)
{
// pmp check failed, raise access-fault
// do nothing, RegNext the pmp check result and do it later (mentioned above)
}.
otherwise
{
//
go to next level.
assert
(
level
=
==
0
.
U
)
level
:=
levelNext
state
:=
s_mem_req
}
...
...
src/main/scala/xiangshan/cache/mmu/Repeater.scala
浏览文件 @
4fe32a16
...
...
@@ -29,6 +29,19 @@ class PTWReapterIO(Width: Int)(implicit p: Parameters) extends MMUIOBaseBundle {
val
tlb
=
Flipped
(
new
TlbPtwIO
(
Width
))
val
ptw
=
new
TlbPtwIO
def
apply
(
tlb
:
TlbPtwIO
,
ptw
:
TlbPtwIO
,
sfence
:
SfenceBundle
,
csr
:
TlbCsrBundle
)
:
Unit
=
{
this
.
tlb
<>
tlb
this
.
ptw
<>
ptw
this
.
sfence
<>
sfence
this
.
csr
<>
csr
}
def
apply
(
tlb
:
TlbPtwIO
,
sfence
:
SfenceBundle
,
csr
:
TlbCsrBundle
)
:
Unit
=
{
this
.
tlb
<>
tlb
this
.
sfence
<>
sfence
this
.
csr
<>
csr
}
override
def
cloneType
:
this.
type
=
(
new
PTWReapterIO
(
Width
)).
asInstanceOf
[
this.
type
]
}
...
...
@@ -71,10 +84,66 @@ class PTWRepeater(Width: Int = 1)(implicit p: Parameters) extends XSModule with
/* dtlb
*
*/
class
PTWRepeaterNB
(
Width
:
Int
=
1
,
passReady
:
Boolean
=
false
)(
implicit
p
:
Parameters
)
extends
XSModule
with
HasPtwConst
{
val
io
=
IO
(
new
PTWReapterIO
(
Width
))
val
req_in
=
if
(
Width
==
1
)
{
io
.
tlb
.
req
(
0
)
}
else
{
val
arb
=
Module
(
new
RRArbiter
(
io
.
tlb
.
req
(
0
).
bits
.
cloneType
,
Width
))
arb
.
io
.
in
<>
io
.
tlb
.
req
arb
.
io
.
out
}
val
(
tlb
,
ptw
,
flush
)
=
(
io
.
tlb
,
io
.
ptw
,
RegNext
(
io
.
sfence
.
valid
||
io
.
csr
.
satp
.
changed
))
/* sent: tlb -> repeater -> ptw
* recv: ptw -> repeater -> tlb
* different from PTWRepeater
*/
// tlb -> repeater -> ptw
val
req
=
RegEnable
(
req_in
.
bits
,
req_in
.
fire
())
val
sent
=
BoolStopWatch
(
req_in
.
fire
(),
ptw
.
req
(
0
).
fire
()
||
flush
)
req_in
.
ready
:=
!
sent
||
{
if
(
passReady
)
ptw
.
req
(
0
).
ready
else
false
.
B
}
ptw
.
req
(
0
).
valid
:=
sent
ptw
.
req
(
0
).
bits
:=
req
// ptw -> repeater -> tlb
val
resp
=
RegEnable
(
ptw
.
resp
.
bits
,
ptw
.
resp
.
fire
())
val
recv
=
BoolStopWatch
(
ptw
.
resp
.
fire
(),
tlb
.
resp
.
fire
()
||
flush
)
ptw
.
resp
.
ready
:=
!
recv
||
{
if
(
passReady
)
tlb
.
resp
.
ready
else
false
.
B
}
tlb
.
resp
.
valid
:=
recv
tlb
.
resp
.
bits
:=
resp
XSPerfAccumulate
(
"req"
,
req_in
.
fire
())
XSPerfAccumulate
(
"resp"
,
tlb
.
resp
.
fire
())
if
(!
passReady
)
{
XSPerfAccumulate
(
"req_blank"
,
req_in
.
valid
&&
sent
&&
ptw
.
req
(
0
).
ready
)
XSPerfAccumulate
(
"resp_blank"
,
ptw
.
resp
.
valid
&&
recv
&&
tlb
.
resp
.
ready
)
XSPerfAccumulate
(
"req_blank_ignore_ready"
,
req_in
.
valid
&&
sent
)
XSPerfAccumulate
(
"resp_blank_ignore_ready"
,
ptw
.
resp
.
valid
&&
recv
)
}
XSDebug
(
req_in
.
valid
||
io
.
tlb
.
resp
.
valid
,
p
"tlb: ${tlb}\n"
)
XSDebug
(
io
.
ptw
.
req
(
0
).
valid
||
io
.
ptw
.
resp
.
valid
,
p
"ptw: ${ptw}\n"
)
}
class
PTWFilterIO
(
Width
:
Int
)(
implicit
p
:
Parameters
)
extends
MMUIOBaseBundle
{
val
tlb
=
Flipped
(
new
BTlbPtwIO
(
Width
))
val
ptw
=
new
TlbPtwIO
()
def
apply
(
tlb
:
BTlbPtwIO
,
ptw
:
TlbPtwIO
,
sfence
:
SfenceBundle
,
csr
:
TlbCsrBundle
)
:
Unit
=
{
this
.
tlb
<>
tlb
this
.
ptw
<>
ptw
this
.
sfence
<>
sfence
this
.
csr
<>
csr
}
def
apply
(
tlb
:
BTlbPtwIO
,
sfence
:
SfenceBundle
,
csr
:
TlbCsrBundle
)
:
Unit
=
{
this
.
tlb
<>
tlb
this
.
sfence
<>
sfence
this
.
csr
<>
csr
}
override
def
cloneType
:
this.
type
=
(
new
PTWFilterIO
(
Width
)).
asInstanceOf
[
this.
type
]
}
...
...
@@ -233,10 +302,7 @@ object PTWRepeater {
)(
implicit
p
:
Parameters
)
=
{
val
width
=
tlb
.
req
.
size
val
repeater
=
Module
(
new
PTWRepeater
(
width
))
repeater
.
io
.
tlb
<>
tlb
repeater
.
io
.
sfence
<>
sfence
repeater
.
io
.
csr
<>
csr
repeater
.
io
.
apply
(
tlb
,
sfence
,
csr
)
repeater
}
...
...
@@ -248,11 +314,32 @@ object PTWRepeater {
)(
implicit
p
:
Parameters
)
=
{
val
width
=
tlb
.
req
.
size
val
repeater
=
Module
(
new
PTWRepeater
(
width
))
repeater
.
io
.
tlb
<>
tlb
repeater
.
io
.
ptw
<>
ptw
repeater
.
io
.
sfence
<>
sfence
repeater
.
io
.
csr
<>
csr
repeater
.
io
.
apply
(
tlb
,
ptw
,
sfence
,
csr
)
repeater
}
}
object
PTWRepeaterNB
{
def
apply
(
passReady
:
Boolean
,
tlb
:
TlbPtwIO
,
sfence
:
SfenceBundle
,
csr
:
TlbCsrBundle
)(
implicit
p
:
Parameters
)
=
{
val
width
=
tlb
.
req
.
size
val
repeater
=
Module
(
new
PTWRepeaterNB
(
width
,
passReady
))
repeater
.
io
.
apply
(
tlb
,
sfence
,
csr
)
repeater
}
def
apply
(
passReady
:
Boolean
,
tlb
:
TlbPtwIO
,
ptw
:
TlbPtwIO
,
sfence
:
SfenceBundle
,
csr
:
TlbCsrBundle
)(
implicit
p
:
Parameters
)
=
{
val
width
=
tlb
.
req
.
size
val
repeater
=
Module
(
new
PTWRepeaterNB
(
width
,
passReady
))
repeater
.
io
.
apply
(
tlb
,
ptw
,
sfence
,
csr
)
repeater
}
}
...
...
@@ -267,11 +354,20 @@ object PTWFilter {
)(
implicit
p
:
Parameters
)
=
{
val
width
=
tlb
.
req
.
size
val
filter
=
Module
(
new
PTWFilter
(
width
,
size
))
filter
.
io
.
tlb
<>
tlb
filter
.
io
.
ptw
<>
ptw
filter
.
io
.
sfence
<>
sfence
filter
.
io
.
csr
<>
csr
filter
.
io
.
apply
(
tlb
,
ptw
,
sfence
,
csr
)
filter
}
def
apply
(
tlb
:
BTlbPtwIO
,
sfence
:
SfenceBundle
,
csr
:
TlbCsrBundle
,
size
:
Int
)(
implicit
p
:
Parameters
)
=
{
val
width
=
tlb
.
req
.
size
val
filter
=
Module
(
new
PTWFilter
(
width
,
size
))
filter
.
io
.
apply
(
tlb
,
sfence
,
csr
)
filter
}
}
\ No newline at end of file
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录