Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
OpenXiangShan
XiangShan
提交
e4e77596
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 搜索 >>
提交
e4e77596
编写于
8月 18, 2020
作者:
Y
Yinan Xu
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'dev-soc' of github.com:RISCVERS/XiangShan into dev-soc
上级
cc78b5b0
ed7e94a8
变更
6
隐藏空白更改
内联
并排
Showing
6 changed file
with
438 addition
and
24 deletion
+438
-24
src/main/scala/xiangshan/cache/dcache.scala
src/main/scala/xiangshan/cache/dcache.scala
+8
-2
src/main/scala/xiangshan/cache/dcacheWrapper.scala
src/main/scala/xiangshan/cache/dcacheWrapper.scala
+134
-20
src/main/scala/xiangshan/cache/misc.scala
src/main/scala/xiangshan/cache/misc.scala
+165
-0
src/main/scala/xiangshan/cache/miscMissQueue.scala
src/main/scala/xiangshan/cache/miscMissQueue.scala
+127
-0
src/main/scala/xiangshan/cache/stu.scala
src/main/scala/xiangshan/cache/stu.scala
+2
-2
src/main/scala/xiangshan/mem/Memend.scala
src/main/scala/xiangshan/mem/Memend.scala
+2
-0
未找到文件。
src/main/scala/xiangshan/cache/dcache.scala
浏览文件 @
e4e77596
...
...
@@ -23,6 +23,7 @@ case class DCacheParameters(
nMissEntries
:
Int
=
1
,
nLoadMissEntries
:
Int
=
1
,
nStoreMissEntries
:
Int
=
1
,
nMiscMissEntries
:
Int
=
1
,
nMMIOEntries
:
Int
=
1
,
nSDQ
:
Int
=
17
,
nRPQ
:
Int
=
16
,
...
...
@@ -75,8 +76,13 @@ trait HasDCacheParameters extends HasL1CacheParameters {
def
missQueueEntryIdWidth
=
log2Up
(
cfg
.
nMissEntries
)
def
loadMissQueueEntryIdWidth
=
log2Up
(
cfg
.
nLoadMissEntries
)
def
storeMissQueueEntryIdWidth
=
log2Up
(
cfg
.
nStoreMissEntries
)
def
clientMissQueueEntryIdWidth
=
max
(
loadMissQueueEntryIdWidth
,
storeMissQueueEntryIdWidth
)
def
nClientMissQueues
=
2
def
miscMissQueueEntryIdWidth
=
log2Up
(
cfg
.
nMiscMissEntries
)
def
clientMissQueueEntryIdWidth
=
max
(
max
(
loadMissQueueEntryIdWidth
,
storeMissQueueEntryIdWidth
),
miscMissQueueEntryIdWidth
)
def
nClientMissQueues
=
3
def
clientIdWidth
=
log2Up
(
nClientMissQueues
)
def
missQueueClientIdWidth
=
clientIdWidth
+
clientMissQueueEntryIdWidth
def
clientIdMSB
=
missQueueClientIdWidth
-
1
...
...
src/main/scala/xiangshan/cache/dcacheWrapper.scala
浏览文件 @
e4e77596
...
...
@@ -69,13 +69,15 @@ class DCacheStoreIO extends DCacheBundle
}
class
DCacheToLsuIO
extends
DCacheBundle
{
val
load
=
Vec
(
LoadPipelineWidth
,
Flipped
(
new
DCacheLoadIO
))
// for speculative load
val
lsroq
=
Flipped
(
new
DCacheLoadIO
)
// lsroq load/store
val
store
=
Flipped
(
new
DCacheStoreIO
)
// for sbuffer
val
load
=
Vec
(
LoadPipelineWidth
,
Flipped
(
new
DCacheLoadIO
))
// for speculative load
val
lsroq
=
Flipped
(
new
DCacheLoadIO
)
// lsroq load/store
val
store
=
Flipped
(
new
DCacheStoreIO
)
// for sbuffer
val
misc
=
Flipped
(
new
DCacheLoadIO
)
// misc reqs
}
class
DCacheIO
extends
DCacheBundle
{
val
lsu
=
new
DCacheToLsuIO
val
ptw
=
Flipped
(
new
DCacheLoadIO
)
val
bus
=
new
TLCached
(
cfg
.
busParams
)
}
...
...
@@ -92,8 +94,10 @@ class DCache extends DCacheModule {
// core modules
val
ldu
=
Seq
.
fill
(
LoadPipelineWidth
)
{
Module
(
new
LoadPipe
)
}
val
stu
=
Module
(
new
StorePipe
)
val
misc
=
Module
(
new
MiscPipe
)
val
loadMissQueue
=
Module
(
new
LoadMissQueue
)
val
storeMissQueue
=
Module
(
new
StoreMissQueue
)
val
miscMissQueue
=
Module
(
new
MiscMissQueue
)
val
missQueue
=
Module
(
new
MissQueue
)
val
wb
=
Module
(
new
WritebackUnit
)
...
...
@@ -113,11 +117,13 @@ class DCache extends DCacheModule {
// To simplify port arbitration
// MissQueue, Prober and StorePipe all use port 0
val
MetaReadPortCount
=
4
// if contention got severe, considering load balancing on two ports?
val
MetaReadPortCount
=
5
val
MissQueueMetaReadPort
=
0
val
ProberMetaReadPort
=
1
val
StorePipeMetaReadPort
=
2
val
LoadPipeMetaReadPort
=
3
val
MiscPipeMetaReadPort
=
4
val
metaReadArb
=
Module
(
new
Arbiter
(
new
L1MetaReadReq
,
MetaReadPortCount
))
...
...
@@ -126,6 +132,7 @@ class DCache extends DCacheModule {
metaReadArb
.
io
.
in
(
ProberMetaReadPort
).
bits
:=
DontCare
metaReadArb
.
io
.
in
(
StorePipeMetaReadPort
)
<>
stu
.
io
.
meta_read
metaReadArb
.
io
.
in
(
LoadPipeMetaReadPort
)
<>
ldu
(
0
).
io
.
meta_read
metaReadArb
.
io
.
in
(
MiscPipeMetaReadPort
)
<>
misc
.
io
.
meta_read
metaArray
.
io
.
read
(
0
)
<>
metaReadArb
.
io
.
out
...
...
@@ -133,6 +140,7 @@ class DCache extends DCacheModule {
// metaArray.io.resp(0) <> prober.io.meta_resp
metaArray
.
io
.
resp
(
0
)
<>
stu
.
io
.
meta_resp
metaArray
.
io
.
resp
(
0
)
<>
ldu
(
0
).
io
.
meta_resp
metaArray
.
io
.
resp
(
0
)
<>
misc
.
io
.
meta_resp
for
(
w
<-
1
until
LoadPipelineWidth
)
{
metaArray
.
io
.
read
(
w
)
<>
ldu
(
w
).
io
.
meta_read
...
...
@@ -140,34 +148,39 @@ class DCache extends DCacheModule {
}
//----------------------------------------
// meta array
val
DataWritePortCount
=
2
val
MissQueueDataWritePort
=
0
val
StorePipeDataWritePort
=
1
// data array
val
DataWritePortCount
=
3
val
StorePipeDataWritePort
=
0
val
MissQueueDataWritePort
=
1
val
MiscPipeDataWritePort
=
2
val
dataWriteArb
=
Module
(
new
Arbiter
(
new
L1DataWriteReq
,
DataWritePortCount
))
dataWriteArb
.
io
.
in
(
MissQueueDataWritePort
)
<>
missQueue
.
io
.
refill
dataWriteArb
.
io
.
in
(
StorePipeDataWritePort
)
<>
stu
.
io
.
data_write
dataWriteArb
.
io
.
in
(
MissQueueDataWritePort
)
<>
missQueue
.
io
.
refill
dataWriteArb
.
io
.
in
(
MiscPipeDataWritePort
)
<>
misc
.
io
.
data_write
dataArray
.
io
.
write
<>
dataWriteArb
.
io
.
out
// To simplify port arbitration
// WritebackUnit and StorePipe use port 0
val
DataReadPortCount
=
3
val
DataReadPortCount
=
4
val
WritebackDataReadPort
=
0
val
StorePipeDataReadPort
=
1
val
LoadPipeDataReadPort
=
2
val
MiscPipeDataReadPort
=
3
val
dataReadArb
=
Module
(
new
Arbiter
(
new
L1DataReadReq
,
DataReadPortCount
))
dataReadArb
.
io
.
in
(
WritebackDataReadPort
)
<>
wb
.
io
.
data_req
dataReadArb
.
io
.
in
(
StorePipeDataReadPort
)
<>
stu
.
io
.
data_read
dataReadArb
.
io
.
in
(
MiscPipeDataReadPort
)
<>
misc
.
io
.
data_read
dataReadArb
.
io
.
in
(
LoadPipeDataReadPort
)
<>
ldu
(
0
).
io
.
data_read
dataArray
.
io
.
read
(
0
)
<>
dataReadArb
.
io
.
out
dataArray
.
io
.
resp
(
0
)
<>
wb
.
io
.
data_resp
dataArray
.
io
.
resp
(
0
)
<>
stu
.
io
.
data_resp
dataArray
.
io
.
resp
(
0
)
<>
misc
.
io
.
data_resp
dataArray
.
io
.
resp
(
0
)
<>
ldu
(
0
).
io
.
data_resp
for
(
w
<-
1
until
LoadPipelineWidth
)
{
...
...
@@ -230,32 +243,102 @@ class DCache extends DCacheModule {
block_decoupled
(
storeMissQueue
.
io
.
replay
.
req
,
stu
.
io
.
lsu
.
req
,
store_block
&&
!
storeMissQueue
.
io
.
replay
.
req
.
bits
.
meta
.
replay
)
storeMissQueue
.
io
.
replay
.
resp
<>
stu
.
io
.
lsu
.
resp
//----------------------------------------
// misc pipe
miscMissQueue
.
io
.
replay
<>
misc
.
io
.
lsu
val
miscClientIdWidth
=
1
val
lsuMiscClientId
=
0.
U
(
miscClientIdWidth
.
W
)
val
ptwMiscClientId
=
1.
U
(
miscClientIdWidth
.
W
)
val
miscClientIdMSB
=
reqIdWidth
-
1
val
miscClientIdLSB
=
reqIdWidth
-
miscClientIdWidth
// Request
val
miscReqArb
=
Module
(
new
Arbiter
(
new
DCacheWordReq
,
2
))
val
miscReq
=
miscMissQueue
.
io
.
lsu
.
req
val
lsuMiscReq
=
io
.
lsu
.
misc
.
req
val
ptwMiscReq
=
io
.
ptw
.
req
miscReqArb
.
io
.
in
(
0
).
valid
:=
lsuMiscReq
.
valid
lsuMiscReq
.
ready
:=
miscReqArb
.
io
.
in
(
0
).
ready
miscReqArb
.
io
.
in
(
0
).
bits
:=
lsuMiscReq
.
bits
miscReqArb
.
io
.
in
(
0
).
bits
.
meta
.
id
:=
Cat
(
lsuMiscClientId
,
lsuMiscReq
.
bits
.
meta
.
id
(
miscClientIdLSB
-
1
,
0
))
miscReqArb
.
io
.
in
(
1
).
valid
:=
ptwMiscReq
.
valid
ptwMiscReq
.
ready
:=
miscReqArb
.
io
.
in
(
1
).
ready
miscReqArb
.
io
.
in
(
1
).
bits
:=
ptwMiscReq
.
bits
miscReqArb
.
io
.
in
(
1
).
bits
.
meta
.
id
:=
Cat
(
ptwMiscClientId
,
ptwMiscReq
.
bits
.
meta
.
id
(
miscClientIdLSB
-
1
,
0
))
val
misc_block
=
block_misc
(
miscReqArb
.
io
.
out
.
bits
.
addr
)
block_decoupled
(
miscReqArb
.
io
.
out
,
miscReq
,
misc_block
)
// Response
val
miscResp
=
miscMissQueue
.
io
.
lsu
.
resp
val
lsuMiscResp
=
io
.
lsu
.
misc
.
resp
val
ptwMiscResp
=
io
.
ptw
.
resp
miscResp
.
ready
:=
false
.
B
val
miscClientId
=
miscResp
.
bits
.
meta
.
id
(
miscClientIdMSB
,
miscClientIdLSB
)
val
isLsuMiscResp
=
miscClientId
===
lsuMiscClientId
lsuMiscResp
.
valid
:=
miscResp
.
valid
&&
isLsuMiscResp
lsuMiscResp
.
bits
:=
miscResp
.
bits
lsuMiscResp
.
bits
.
meta
.
id
:=
miscResp
.
bits
.
meta
.
id
(
miscClientIdLSB
-
1
,
0
)
when
(
lsuMiscResp
.
valid
)
{
miscResp
.
ready
:=
lsuMiscResp
.
ready
}
val
isPTWMiscResp
=
miscClientId
===
ptwMiscClientId
ptwMiscResp
.
valid
:=
miscResp
.
valid
&&
isPTWMiscResp
ptwMiscResp
.
bits
:=
miscResp
.
bits
ptwMiscResp
.
bits
.
meta
.
id
:=
miscResp
.
bits
.
meta
.
id
(
miscClientIdLSB
-
1
,
0
)
when
(
ptwMiscResp
.
valid
)
{
miscResp
.
ready
:=
ptwMiscResp
.
ready
}
// some other stuff
miscMissQueue
.
io
.
lsu
.
s1_kill
:=
false
.
B
assert
(!(
miscReq
.
fire
()
&&
miscReq
.
bits
.
meta
.
replay
),
"Misc should not replay requests"
)
assert
(!
io
.
lsu
.
misc
.
s1_kill
,
"Lsroq should never use s1 kill on misc"
)
assert
(!
io
.
ptw
.
s1_kill
,
"Lsroq should never use s1 kill on misc"
)
//----------------------------------------
// miss queue
val
loadMissQueueClientId
=
0.
U
(
clientIdWidth
.
W
)
val
loadMissQueueClientId
=
0.
U
(
clientIdWidth
.
W
)
val
storeMissQueueClientId
=
1.
U
(
clientIdWidth
.
W
)
val
miscMissQueueClientId
=
2.
U
(
clientIdWidth
.
W
)
// Request
val
missReqArb
=
Module
(
new
Arbiter
(
new
MissReq
,
2
))
val
missReqArb
=
Module
(
new
Arbiter
(
new
MissReq
,
3
))
val
missReq
=
missQueue
.
io
.
req
val
loadMissReq
=
loadMissQueue
.
io
.
miss_req
val
storeMissReq
=
storeMissQueue
.
io
.
miss_req
val
miscMissReq
=
miscMissQueue
.
io
.
miss_req
missReqArb
.
io
.
in
(
0
).
valid
:=
loadMissReq
.
valid
loadMissReq
.
ready
:=
missReqArb
.
io
.
in
(
0
).
ready
missReqArb
.
io
.
in
(
0
).
bits
.
cmd
:=
loadMissReq
.
bits
.
cmd
missReqArb
.
io
.
in
(
0
).
bits
.
addr
:=
loadMissReq
.
bits
.
addr
missReqArb
.
io
.
in
(
0
).
bits
:=
loadMissReq
.
bits
missReqArb
.
io
.
in
(
0
).
bits
.
client_id
:=
Cat
(
loadMissQueueClientId
,
loadMissReq
.
bits
.
client_id
(
entryIdMSB
,
entryIdLSB
))
missReqArb
.
io
.
in
(
1
).
valid
:=
storeMissReq
.
valid
storeMissReq
.
ready
:=
missReqArb
.
io
.
in
(
1
).
ready
missReqArb
.
io
.
in
(
1
).
bits
.
cmd
:=
storeMissReq
.
bits
.
cmd
missReqArb
.
io
.
in
(
1
).
bits
.
addr
:=
storeMissReq
.
bits
.
addr
missReqArb
.
io
.
in
(
1
).
bits
:=
storeMissReq
.
bits
missReqArb
.
io
.
in
(
1
).
bits
.
client_id
:=
Cat
(
storeMissQueueClientId
,
storeMissReq
.
bits
.
client_id
(
entryIdMSB
,
entryIdLSB
))
missReqArb
.
io
.
in
(
2
).
valid
:=
miscMissReq
.
valid
miscMissReq
.
ready
:=
missReqArb
.
io
.
in
(
2
).
ready
missReqArb
.
io
.
in
(
2
).
bits
:=
miscMissReq
.
bits
missReqArb
.
io
.
in
(
2
).
bits
.
client_id
:=
Cat
(
miscMissQueueClientId
,
miscMissReq
.
bits
.
client_id
(
entryIdMSB
,
entryIdLSB
))
val
miss_block
=
block_miss
(
missReqArb
.
io
.
out
.
bits
.
addr
)
block_decoupled
(
missReqArb
.
io
.
out
,
missReq
,
miss_block
)
...
...
@@ -263,6 +346,7 @@ class DCache extends DCacheModule {
val
missResp
=
missQueue
.
io
.
resp
val
loadMissResp
=
loadMissQueue
.
io
.
miss_resp
val
storeMissResp
=
storeMissQueue
.
io
.
miss_resp
val
miscMissResp
=
miscMissQueue
.
io
.
miss_resp
val
clientId
=
missResp
.
bits
.
client_id
(
clientIdMSB
,
clientIdLSB
)
...
...
@@ -276,12 +360,18 @@ class DCache extends DCacheModule {
storeMissResp
.
bits
.
entry_id
:=
missResp
.
bits
.
entry_id
storeMissResp
.
bits
.
client_id
:=
missResp
.
bits
.
client_id
(
entryIdMSB
,
entryIdLSB
)
val
isMiscMissResp
=
clientId
===
miscMissQueueClientId
miscMissResp
.
valid
:=
missResp
.
valid
&&
isMiscMissResp
miscMissResp
.
bits
.
entry_id
:=
missResp
.
bits
.
entry_id
miscMissResp
.
bits
.
client_id
:=
missResp
.
bits
.
client_id
(
entryIdMSB
,
entryIdLSB
)
// Finish
val
missFinish
=
missQueue
.
io
.
finish
val
loadMissFinish
=
loadMissQueue
.
io
.
miss_finish
val
storeMissFinish
=
storeMissQueue
.
io
.
miss_finish
val
miscMissFinish
=
miscMissQueue
.
io
.
miss_finish
val
missFinishArb
=
Module
(
new
Arbiter
(
new
MissFinish
,
2
))
val
missFinishArb
=
Module
(
new
Arbiter
(
new
MissFinish
,
3
))
missFinishArb
.
io
.
in
(
0
).
valid
:=
loadMissFinish
.
valid
loadMissFinish
.
ready
:=
missFinishArb
.
io
.
in
(
0
).
ready
missFinishArb
.
io
.
in
(
0
).
bits
.
entry_id
:=
loadMissFinish
.
bits
.
entry_id
...
...
@@ -294,6 +384,12 @@ class DCache extends DCacheModule {
missFinishArb
.
io
.
in
(
1
).
bits
.
client_id
:=
Cat
(
storeMissQueueClientId
,
storeMissFinish
.
bits
.
client_id
(
entryIdMSB
,
entryIdLSB
))
missFinishArb
.
io
.
in
(
2
).
valid
:=
miscMissFinish
.
valid
miscMissFinish
.
ready
:=
missFinishArb
.
io
.
in
(
2
).
ready
missFinishArb
.
io
.
in
(
2
).
bits
.
entry_id
:=
miscMissFinish
.
bits
.
entry_id
missFinishArb
.
io
.
in
(
2
).
bits
.
client_id
:=
Cat
(
miscMissQueueClientId
,
miscMissFinish
.
bits
.
client_id
(
entryIdMSB
,
entryIdLSB
))
missFinish
<>
missFinishArb
.
io
.
out
// tilelink stuff
...
...
@@ -332,26 +428,44 @@ class DCache extends DCacheModule {
val
store_addr_matches
=
VecInit
(
stu
.
io
.
inflight_req_block_addrs
map
(
entry
=>
entry
.
valid
&&
entry
.
bits
===
get_block_addr
(
addr
)))
val
store_addr_match
=
store_addr_matches
.
reduce
(
_
||
_
)
val
misc_addr_matches
=
VecInit
(
misc
.
io
.
inflight_req_block_addrs
map
(
entry
=>
entry
.
valid
&&
entry
.
bits
===
get_block_addr
(
addr
)))
val
misc_addr_match
=
misc_addr_matches
.
reduce
(
_
||
_
)
val
miss_idx_matches
=
VecInit
(
missQueue
.
io
.
inflight_req_idxes
map
(
entry
=>
entry
.
valid
&&
entry
.
bits
===
get_idx
(
addr
)))
val
miss_idx_match
=
miss_idx_matches
.
reduce
(
_
||
_
)
store_addr_match
||
miss_idx_match
store_addr_match
||
mis
c_addr_match
||
mis
s_idx_match
}
def
block_store
(
addr
:
UInt
)
=
{
val
misc_addr_matches
=
VecInit
(
misc
.
io
.
inflight_req_block_addrs
map
(
entry
=>
entry
.
valid
&&
entry
.
bits
===
get_block_addr
(
addr
)))
val
misc_addr_match
=
misc_addr_matches
.
reduce
(
_
||
_
)
val
miss_idx_matches
=
VecInit
(
missQueue
.
io
.
inflight_req_idxes
map
(
entry
=>
entry
.
valid
&&
entry
.
bits
===
get_idx
(
addr
)))
val
miss_idx_match
=
miss_idx_matches
.
reduce
(
_
||
_
)
miss_idx_match
misc_addr_match
||
miss_idx_match
}
def
block_misc
(
addr
:
UInt
)
=
{
val
store_addr_matches
=
VecInit
(
stu
.
io
.
inflight_req_block_addrs
map
(
entry
=>
entry
.
valid
&&
entry
.
bits
===
get_block_addr
(
addr
)))
val
store_addr_match
=
store_addr_matches
.
reduce
(
_
||
_
)
val
miss_idx_matches
=
VecInit
(
missQueue
.
io
.
inflight_req_idxes
map
(
entry
=>
entry
.
valid
&&
entry
.
bits
===
get_idx
(
addr
)))
val
miss_idx_match
=
miss_idx_matches
.
reduce
(
_
||
_
)
store_addr_match
||
miss_idx_match
}
def
block_miss
(
addr
:
UInt
)
=
{
val
store_idx_matches
=
VecInit
(
stu
.
io
.
inflight_req_idxes
map
(
entry
=>
entry
.
valid
&&
entry
.
bits
===
get_idx
(
addr
)))
val
store_idx_match
=
store_idx_matches
.
reduce
(
_
||
_
)
val
misc_idx_matches
=
VecInit
(
misc
.
io
.
inflight_req_idxes
map
(
entry
=>
entry
.
valid
&&
entry
.
bits
===
get_idx
(
addr
)))
val
misc_idx_match
=
misc_idx_matches
.
reduce
(
_
||
_
)
val
miss_idx_matches
=
VecInit
(
missQueue
.
io
.
inflight_req_idxes
map
(
entry
=>
entry
.
valid
&&
entry
.
bits
===
get_idx
(
addr
)))
val
miss_idx_match
=
miss_idx_matches
.
reduce
(
_
||
_
)
store_idx_match
||
miss_idx_match
store_idx_match
||
mis
c_idx_match
||
mis
s_idx_match
}
def
block_decoupled
[
T
<:
Data
](
source
:
DecoupledIO
[
T
],
sink
:
DecoupledIO
[
T
],
block_signal
:
Bool
)
=
{
...
...
src/main/scala/xiangshan/cache/misc.scala
0 → 100644
浏览文件 @
e4e77596
package
xiangshan.cache
import
chisel3._
import
chisel3.util._
import
utils.XSDebug
// this is a traditional cache pipeline:
// it handles load/store/amo/lr,sc
class
MiscPipe
extends
DCacheModule
{
val
io
=
IO
(
new
DCacheBundle
{
val
lsu
=
Flipped
(
new
DCacheLoadIO
)
val
data_read
=
DecoupledIO
(
new
L1DataReadReq
)
val
data_resp
=
Input
(
Vec
(
nWays
,
Vec
(
refillCycles
,
Bits
(
encRowBits
.
W
))))
val
data_write
=
DecoupledIO
(
new
L1DataWriteReq
)
val
meta_read
=
DecoupledIO
(
new
L1MetaReadReq
)
val
meta_resp
=
Input
(
Vec
(
nWays
,
new
L1Metadata
))
val
inflight_req_idxes
=
Output
(
Vec
(
3
,
Valid
(
UInt
())))
val
inflight_req_block_addrs
=
Output
(
Vec
(
3
,
Valid
(
UInt
())))
})
// LSU requests
io
.
lsu
.
req
.
ready
:=
io
.
meta_read
.
ready
&&
io
.
data_read
.
ready
io
.
meta_read
.
valid
:=
io
.
lsu
.
req
.
valid
io
.
data_read
.
valid
:=
io
.
lsu
.
req
.
valid
val
meta_read
=
io
.
meta_read
.
bits
val
data_read
=
io
.
data_read
.
bits
// Tag read for new requests
meta_read
.
idx
:=
get_idx
(
io
.
lsu
.
req
.
bits
.
addr
)
meta_read
.
way_en
:=
~
0.
U
(
nWays
.
W
)
meta_read
.
tag
:=
DontCare
// Data read for new requests
data_read
.
addr
:=
io
.
lsu
.
req
.
bits
.
addr
data_read
.
way_en
:=
~
0.
U
(
nWays
.
W
)
// only needs to read the specific beat
data_read
.
rmask
:=
UIntToOH
(
get_beat
(
io
.
lsu
.
req
.
bits
.
addr
))
// Pipeline
// stage 0
val
s0_valid
=
io
.
lsu
.
req
.
fire
()
val
s0_req
=
io
.
lsu
.
req
.
bits
dump_pipeline_reqs
(
"MiscPipe s0"
,
s0_valid
,
s0_req
)
// stage 1
val
s1_req
=
RegNext
(
s0_req
)
val
s1_valid
=
RegNext
(
s0_valid
,
init
=
false
.
B
)
val
s1_addr
=
s1_req
.
addr
val
s1_nack
=
false
.
B
dump_pipeline_reqs
(
"MiscPipe s1"
,
s1_valid
,
s1_req
)
// tag check
val
meta_resp
=
io
.
meta_resp
def
wayMap
[
T
<:
Data
](
f
:
Int
=>
T
)
=
VecInit
((
0
until
nWays
).
map
(
f
))
val
s1_tag_eq_way
=
wayMap
((
w
:
Int
)
=>
meta_resp
(
w
).
tag
===
(
get_tag
(
s1_addr
))).
asUInt
val
s1_tag_match_way
=
wayMap
((
w
:
Int
)
=>
s1_tag_eq_way
(
w
)
&&
meta_resp
(
w
).
coh
.
isValid
()).
asUInt
// stage 2
val
s2_req
=
RegNext
(
s1_req
)
val
s2_valid
=
RegNext
(
s1_valid
&&
!
io
.
lsu
.
s1_kill
,
init
=
false
.
B
)
dump_pipeline_reqs
(
"MiscPipe s2"
,
s2_valid
,
s2_req
)
val
s2_tag_match_way
=
RegNext
(
s1_tag_match_way
)
val
s2_tag_match
=
s2_tag_match_way
.
orR
val
s2_hit_state
=
Mux1H
(
s2_tag_match_way
,
wayMap
((
w
:
Int
)
=>
RegNext
(
meta_resp
(
w
).
coh
)))
val
s2_has_permission
=
s2_hit_state
.
onAccess
(
s2_req
.
cmd
).
_1
val
s2_new_hit_state
=
s2_hit_state
.
onAccess
(
s2_req
.
cmd
).
_3
// we not only need permissions
// we also require that state does not change on hit
// thus we require new_hit_state === old_hit_state
//
// If state changes on hit,
// we should treat it as not hit, and let mshr deal with it,
// since we can not write meta data on the main pipeline.
// It's possible that we had permission but state changes on hit:
// eg: write to exclusive but clean block
val
s2_hit
=
s2_tag_match
&&
s2_has_permission
&&
s2_hit_state
===
s2_new_hit_state
val
s2_nack
=
Wire
(
Bool
())
val
s2_data
=
Wire
(
Vec
(
nWays
,
UInt
(
encRowBits
.
W
)))
val
data_resp
=
io
.
data_resp
for
(
w
<-
0
until
nWays
)
{
s2_data
(
w
)
:=
data_resp
(
w
)(
get_beat
(
s2_req
.
addr
))
}
val
s2_data_muxed
=
Mux1H
(
s2_tag_match_way
,
s2_data
)
// the index of word in a row, in case rowBits != wordBits
val
s2_word_idx
=
if
(
rowWords
==
1
)
0.
U
else
s2_req
.
addr
(
log2Up
(
rowWords
*
wordBytes
)-
1
,
log2Up
(
wordBytes
))
val
s2_nack_hit
=
RegNext
(
s1_nack
)
// Can't allocate MSHR for same set currently being written back
// the same set is busy
val
s2_nack_set_busy
=
s2_valid
&&
false
.
B
// Bank conflict on data arrays
val
s2_nack_data
=
false
.
B
s2_nack
:=
s2_nack_hit
||
s2_nack_set_busy
||
s2_nack_data
// only dump these signals when they are actually valid
dump_pipeline_valids
(
"MiscPipe s2"
,
"s2_hit"
,
s2_valid
&&
s2_hit
)
dump_pipeline_valids
(
"MiscPipe s2"
,
"s2_nack"
,
s2_valid
&&
s2_nack
)
dump_pipeline_valids
(
"MiscPipe s2"
,
"s2_nack_hit"
,
s2_valid
&&
s2_nack_hit
)
dump_pipeline_valids
(
"MiscPipe s2"
,
"s2_nack_set_busy"
,
s2_valid
&&
s2_nack_set_busy
)
// load data gen
val
s2_data_word
=
s2_data_muxed
>>
Cat
(
s2_word_idx
,
0.
U
(
log2Ceil
(
wordBits
).
W
))
val
resp
=
Wire
(
ValidIO
(
new
DCacheResp
))
resp
.
valid
:=
s2_valid
resp
.
bits
.
data
:=
s2_data_word
resp
.
bits
.
meta
:=
s2_req
.
meta
resp
.
bits
.
miss
:=
!
s2_hit
resp
.
bits
.
nack
:=
s2_nack
io
.
lsu
.
resp
.
valid
:=
resp
.
valid
io
.
lsu
.
resp
.
bits
:=
resp
.
bits
assert
(!(
resp
.
valid
&&
!
io
.
lsu
.
resp
.
ready
))
when
(
resp
.
valid
)
{
XSDebug
(
s
"MiscPipe resp: data: %x id: %d replay: %b miss: %b nack: %b\n"
,
resp
.
bits
.
data
,
resp
.
bits
.
meta
.
id
,
resp
.
bits
.
meta
.
replay
,
resp
.
bits
.
miss
,
resp
.
bits
.
nack
)
}
// assign default value to output signals
io
.
data_write
.
valid
:=
false
.
B
io
.
data_write
.
bits
:=
DontCare
io
.
inflight_req_idxes
(
0
).
valid
:=
io
.
lsu
.
req
.
valid
io
.
inflight_req_idxes
(
1
).
valid
:=
s1_valid
io
.
inflight_req_idxes
(
2
).
valid
:=
s2_valid
io
.
inflight_req_idxes
(
0
).
bits
:=
get_idx
(
s0_req
.
addr
)
io
.
inflight_req_idxes
(
1
).
bits
:=
get_idx
(
s1_req
.
addr
)
io
.
inflight_req_idxes
(
2
).
bits
:=
get_idx
(
s2_req
.
addr
)
io
.
inflight_req_block_addrs
(
0
).
valid
:=
io
.
lsu
.
req
.
valid
io
.
inflight_req_block_addrs
(
1
).
valid
:=
s1_valid
io
.
inflight_req_block_addrs
(
2
).
valid
:=
s2_valid
io
.
inflight_req_block_addrs
(
0
).
bits
:=
get_block_addr
(
s0_req
.
addr
)
io
.
inflight_req_block_addrs
(
1
).
bits
:=
get_block_addr
(
s1_req
.
addr
)
io
.
inflight_req_block_addrs
(
2
).
bits
:=
get_block_addr
(
s2_req
.
addr
)
// -------
// Debug logging functions
def
dump_pipeline_reqs
(
pipeline_stage_name
:
String
,
valid
:
Bool
,
req
:
DCacheWordReq
)
=
{
when
(
valid
)
{
XSDebug
(
s
"$pipeline_stage_name cmd: %x addr: %x data: %x mask: %x id: %d replay: %b\n"
,
req
.
cmd
,
req
.
addr
,
req
.
data
,
req
.
mask
,
req
.
meta
.
id
,
req
.
meta
.
replay
)
}
}
def
dump_pipeline_valids
(
pipeline_stage_name
:
String
,
signal_name
:
String
,
valid
:
Bool
)
=
{
when
(
valid
)
{
XSDebug
(
s
"$pipeline_stage_name $signal_name\n"
)
}
}
}
src/main/scala/xiangshan/cache/miscMissQueue.scala
0 → 100644
浏览文件 @
e4e77596
package
xiangshan.cache
import
chisel3._
import
chisel3.util._
import
utils.XSDebug
// wraps around MiscPipe
// when requests misse, send miss req to missQueue and replays reqs
class
MiscMissQueue
extends
DCacheModule
{
val
io
=
IO
(
new
DCacheBundle
{
val
lsu
=
Flipped
(
new
DCacheLoadIO
)
val
replay
=
new
DCacheLoadIO
val
miss_req
=
DecoupledIO
(
new
MissReq
)
val
miss_resp
=
Flipped
(
ValidIO
(
new
MissResp
))
val
miss_finish
=
DecoupledIO
(
new
MissFinish
)
})
val
s_invalid
::
s_replay_req
::
s_replay_resp
::
s_resp
::
s_miss_req
::
s_miss_resp
::
s_miss_finish
::
Nil
=
Enum
(
7
)
val
state
=
RegInit
(
s_invalid
)
val
id
=
0.
U
val
req
=
Reg
(
new
DCacheWordReq
)
val
resp
=
Reg
(
new
DCacheResp
)
val
req_block_addr
=
get_block_addr
(
req
.
addr
)
val
reg_miss_resp
=
Reg
(
new
MissResp
)
// assign default values to output signals
io
.
lsu
.
req
.
ready
:=
state
===
s_invalid
io
.
lsu
.
resp
.
valid
:=
false
.
B
io
.
lsu
.
resp
.
bits
:=
DontCare
io
.
replay
.
req
.
valid
:=
false
.
B
io
.
replay
.
req
.
bits
:=
DontCare
io
.
replay
.
resp
.
ready
:=
false
.
B
io
.
replay
.
s1_kill
:=
false
.
B
io
.
miss_req
.
valid
:=
false
.
B
io
.
miss_req
.
bits
:=
DontCare
io
.
miss_finish
.
valid
:=
false
.
B
io
.
miss_finish
.
bits
:=
DontCare
XSDebug
(
"state: %d\n"
,
state
)
// --------------------------------------------
// s_invalid: receive requests
when
(
state
===
s_invalid
)
{
when
(
io
.
lsu
.
req
.
fire
())
{
assert
(!
io
.
lsu
.
req
.
bits
.
meta
.
replay
)
req
:=
io
.
lsu
.
req
.
bits
state
:=
s_replay_req
}
}
// --------------------------------------------
// replay
when
(
state
===
s_replay_req
)
{
io
.
replay
.
req
.
valid
:=
true
.
B
io
.
replay
.
req
.
bits
:=
req
when
(
io
.
replay
.
req
.
fire
())
{
state
:=
s_replay_resp
}
}
when
(
state
===
s_replay_resp
)
{
io
.
replay
.
resp
.
ready
:=
true
.
B
when
(
io
.
replay
.
resp
.
fire
())
{
when
(
io
.
replay
.
resp
.
bits
.
miss
)
{
// replayed reqs should not miss
assert
(!
req
.
meta
.
replay
)
when
(!
req
.
meta
.
replay
)
{
state
:=
s_miss_req
}
}
.
otherwise
{
resp
:=
io
.
replay
.
resp
.
bits
when
(!
req
.
meta
.
replay
)
{
state
:=
s_resp
}
.
otherwise
{
state
:=
s_miss_finish
}
}
assert
(!
io
.
replay
.
resp
.
bits
.
nack
)
}
}
// --------------------------------------------
when
(
state
===
s_miss_req
)
{
io
.
miss_req
.
valid
:=
true
.
B
io
.
miss_req
.
bits
.
cmd
:=
req
.
cmd
io
.
miss_req
.
bits
.
addr
:=
req_block_addr
io
.
miss_req
.
bits
.
client_id
:=
id
when
(
io
.
miss_req
.
fire
())
{
state
:=
s_miss_resp
}
}
when
(
state
===
s_miss_resp
)
{
when
(
io
.
miss_resp
.
fire
())
{
reg_miss_resp
:=
io
.
miss_resp
.
bits
// mark req as replayed req
req
.
meta
.
replay
:=
true
.
B
state
:=
s_replay_req
}
}
when
(
state
===
s_miss_finish
)
{
io
.
miss_finish
.
valid
:=
true
.
B
io
.
miss_finish
.
bits
.
client_id
:=
id
io
.
miss_finish
.
bits
.
entry_id
:=
reg_miss_resp
.
entry_id
when
(
io
.
miss_finish
.
fire
())
{
state
:=
s_resp
}
}
// --------------------------------------------
when
(
state
===
s_resp
)
{
io
.
lsu
.
resp
.
valid
:=
true
.
B
io
.
lsu
.
resp
.
bits
:=
resp
when
(
io
.
lsu
.
resp
.
fire
())
{
state
:=
s_invalid
}
}
}
src/main/scala/xiangshan/cache/stu.scala
浏览文件 @
e4e77596
...
...
@@ -142,7 +142,7 @@ class StorePipe extends DCacheModule
resp
.
bits
.
data
,
resp
.
bits
.
meta
.
id
,
resp
.
bits
.
meta
.
replay
,
resp
.
bits
.
miss
,
resp
.
bits
.
nack
)
}
io
.
inflight_req_idxes
(
0
).
valid
:=
s0_
valid
io
.
inflight_req_idxes
(
0
).
valid
:=
io
.
lsu
.
req
.
valid
io
.
inflight_req_idxes
(
1
).
valid
:=
s1_valid
io
.
inflight_req_idxes
(
2
).
valid
:=
s2_valid
...
...
@@ -150,7 +150,7 @@ class StorePipe extends DCacheModule
io
.
inflight_req_idxes
(
1
).
bits
:=
get_idx
(
s1_req
.
addr
)
io
.
inflight_req_idxes
(
2
).
bits
:=
get_idx
(
s2_req
.
addr
)
io
.
inflight_req_block_addrs
(
0
).
valid
:=
s0_
valid
io
.
inflight_req_block_addrs
(
0
).
valid
:=
io
.
lsu
.
req
.
valid
io
.
inflight_req_block_addrs
(
1
).
valid
:=
s1_valid
io
.
inflight_req_block_addrs
(
2
).
valid
:=
s2_valid
...
...
src/main/scala/xiangshan/mem/Memend.scala
浏览文件 @
e4e77596
...
...
@@ -132,6 +132,8 @@ class Memend extends XSModule {
dcache
.
io
.
bus
<>
io
.
mem
uncache
.
io
.
bus
<>
io
.
mmio
dcache
.
io
.
lsu
.
misc
<>
DontCare
dcache
.
io
.
ptw
<>
DontCare
// LoadUnit
for
(
i
<-
0
until
exuParameters
.
LduCnt
)
{
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录