Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
OpenXiangShan
XiangShan
提交
db7f55d9
X
XiangShan
项目概览
OpenXiangShan
/
XiangShan
12 个月 前同步成功
通知
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,发现更多精彩内容 >>
提交
db7f55d9
编写于
11月 18, 2022
作者:
W
William Wang
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
sbuffer: set EnsbufferWidth upper bound to 2
上级
3d3419b9
变更
1
隐藏空白更改
内联
并排
Showing
1 changed file
with
41 addition
and
34 deletion
+41
-34
src/main/scala/xiangshan/mem/sbuffer/Sbuffer.scala
src/main/scala/xiangshan/mem/sbuffer/Sbuffer.scala
+41
-34
未找到文件。
src/main/scala/xiangshan/mem/sbuffer/Sbuffer.scala
浏览文件 @
db7f55d9
...
...
@@ -147,7 +147,7 @@ class SbufferData(implicit p: Parameters) extends XSModule with HasSbufferConst
class
Sbuffer
(
implicit
p
:
Parameters
)
extends
DCacheModule
with
HasSbufferConst
with
HasPerfEvents
{
val
io
=
IO
(
new
Bundle
()
{
val
hartId
=
Input
(
UInt
(
8.
W
))
val
in
=
Vec
(
EnsbufferWidth
,
Flipped
(
Decoupled
(
new
DCacheWordReqWithVaddr
)))
val
in
=
Vec
(
EnsbufferWidth
,
Flipped
(
Decoupled
(
new
DCacheWordReqWithVaddr
)))
//Todo: store logic only support Width == 2 now
val
dcache
=
Flipped
(
new
DCacheToSbufferIO
)
val
forward
=
Vec
(
LoadPipelineWidth
,
Flipped
(
new
LoadForwardQueryIO
))
val
sqempty
=
Input
(
Bool
())
...
...
@@ -251,9 +251,10 @@ class Sbuffer(implicit p: Parameters) extends DCacheModule with HasSbufferConst
val
inptags
=
io
.
in
.
map
(
in
=>
getPTag
(
in
.
bits
.
addr
))
val
invtags
=
io
.
in
.
map
(
in
=>
getVTag
(
in
.
bits
.
vaddr
))
val
sameTag
=
Seq
.
tabulate
(
io
.
in
.
length
)(
x
=>
Seq
.
tabulate
(
io
.
in
.
length
)(
y
=>
inptags
(
x
)
===
inptags
(
y
)))
val
words
=
(
0
until
EnsbufferWidth
).
map
(
i
=>
getWord
(
io
.
in
(
i
).
bits
.
addr
))
val
sameWord
=
Seq
.
tabulate
(
EnsbufferWidth
)(
x
=>
Seq
.
tabulate
(
EnsbufferWidth
)(
y
=>
words
(
x
)
===
words
(
y
)))
val
sameTag
=
inptags
(
0
)
===
inptags
(
1
)
val
firstWord
=
getWord
(
io
.
in
(
0
).
bits
.
addr
)
val
secondWord
=
getWord
(
io
.
in
(
1
).
bits
.
addr
)
val
sameWord
=
firstWord
===
secondWord
// merge condition
val
mergeMask
=
Wire
(
Vec
(
EnsbufferWidth
,
Vec
(
StoreBufferSize
,
Bool
())))
...
...
@@ -273,7 +274,8 @@ class Sbuffer(implicit p: Parameters) extends DCacheModule with HasSbufferConst
// if first entry canMerge or second entry has the same ptag with the first entry,
// secondInsert equal the first invalid entry, otherwise, the second invalid entry
val
invalidMask
=
VecInit
(
stateVec
.
map
(
s
=>
s
.
isInvalid
()))
val
remInvalidMask
=
GetRemBits
(
EnsbufferWidth
)(
invalidMask
.
asUInt
)
val
evenInvalidMask
=
GetEvenBits
(
invalidMask
.
asUInt
)
val
oddInvalidMask
=
GetOddBits
(
invalidMask
.
asUInt
)
def
getFirstOneOH
(
input
:
UInt
)
:
UInt
=
{
assert
(
input
.
getWidth
>
1
)
...
...
@@ -284,37 +286,42 @@ class Sbuffer(implicit p: Parameters) extends DCacheModule with HasSbufferConst
output
.
asUInt
}
val
remRawInsertVec
=
remInvalidMask
.
map
(
getFirstOneOH
(
_
)
)
val
remRawInsert
=
remInvalidMask
.
map
(
PriorityEncoderWithFlag
(
_
)).
unzip
val
(
remRawInsertIdx
,
remCanInsert
)
=
(
remRawInsert
.
_1
,
VecInit
(
remRawInsert
.
_2
)
)
val
remInsertIdx
=
VecInit
(
remRawInsertIdx
.
zipWithIndex
.
map
{
case
(
raw
,
idx
)
=>
if
(
EnsbufferWidth
>
1
)
Cat
(
raw
,
idx
.
U
(
log2Ceil
(
EnsbufferWidth
).
W
))
else
raw
})
// slow to generate, for debug only
val
remInsertVec
=
VecInit
(
GetRemBits
.
reverse
(
EnsbufferWidth
)(
remRawInsertVec
)
)
val
enbufferSelReg
=
RegInit
(
0.
U
(
log2Up
(
EnsbufferWidth
).
W
)
)
if
(
EnsbufferWidth
>
1
)
when
(
io
.
in
(
0
).
valid
)
{
enbufferSelReg
:=
enbufferSelReg
+
1.
U
val
evenRawInsertVec
=
getFirstOneOH
(
evenInvalidMask
)
val
oddRawInsertVec
=
getFirstOneOH
(
oddInvalidMask
)
val
(
evenRawInsertIdx
,
evenCanInsert
)
=
PriorityEncoderWithFlag
(
evenInvalidMask
)
val
(
oddRawInsertIdx
,
oddCanInsert
)
=
PriorityEncoderWithFlag
(
oddInvalidMask
)
val
evenInsertIdx
=
Cat
(
evenRawInsertIdx
,
0.
U
(
1.
W
))
// slow to generate, for debug only
val
oddInsertIdx
=
Cat
(
oddRawInsertIdx
,
1.
U
(
1.
W
))
// slow to generate, for debug only
val
evenInsertVec
=
GetEvenBits
.
reverse
(
evenRawInsertVec
)
val
oddInsertVec
=
GetOddBits
.
reverse
(
oddRawInsertVec
)
val
enbufferSelReg
=
RegInit
(
false
.
B
)
when
(
io
.
in
(
0
).
valid
)
{
enbufferSelReg
:=
~
enbufferSelReg
}
val
insertIdxs
=
(
0
until
EnsbufferWidth
).
map
(
i
=>
PriorityMuxDefault
(
if
(
i
==
0
)
Seq
(
0.
B
->
0.
U
)
else
(
0
until
i
).
map
(
j
=>
sameTag
(
i
)(
j
)
->
remInsertIdx
(
enbufferSelReg
+
j
.
U
)),
remInsertIdx
(
enbufferSelReg
+
i
.
U
))
val
firstInsertIdx
=
Mux
(
enbufferSelReg
,
evenInsertIdx
,
oddInsertIdx
)
// slow to generate, for debug only
val
secondInsertIdx
=
Mux
(
sameTag
,
firstInsertIdx
,
Mux
(~
enbufferSelReg
,
evenInsertIdx
,
oddInsertIdx
)
)
// slow to generate, for debug only
val
insertVecs
=
(
0
until
EnsbufferWidth
).
map
(
i
=>
PriorityMuxDefault
(
if
(
i
==
0
)
Seq
(
0.
B
->
0.
U
)
else
(
0
until
i
).
map
(
j
=>
sameTag
(
i
)(
j
)
->
remInsertVec
(
enbufferSelReg
+
j
.
U
)),
remInsertVec
(
enbufferSelReg
+
i
.
U
))
val
firstInsertVec
=
Mux
(
enbufferSelReg
,
evenInsertVec
,
oddInsertVec
)
val
secondInsertVec
=
Mux
(
sameTag
,
firstInsertVec
,
Mux
(~
enbufferSelReg
,
evenInsertVec
,
oddInsertVec
)
)
// slow to generate, for debug only
val
canInserts
=
(
0
until
EnsbufferWidth
).
map
(
i
=>
PriorityMuxDefault
(
if
(
i
==
0
)
Seq
(
0.
B
->
0.
B
)
else
(
0
until
i
).
map
(
j
=>
sameTag
(
i
)(
j
)
->
remCanInsert
(
enbufferSelReg
+
j
.
U
)),
remCanInsert
(
enbufferSelReg
+
i
.
U
))
).
map
(
_
&&
sbuffer_state
=/=
x_drain_sbuffer
)
val
firstCanInsert
=
sbuffer_state
=/=
x_drain_sbuffer
&&
Mux
(
enbufferSelReg
,
evenCanInsert
,
oddCanInsert
)
val
secondCanInsert
=
sbuffer_state
=/=
x_drain_sbuffer
&&
Mux
(
sameTag
,
firstCanInsert
,
Mux
(~
enbufferSelReg
,
evenCanInsert
,
oddCanInsert
)
)
&&
(
EnsbufferWidth
>=
1
).
B
val
forward_need_uarch_drain
=
WireInit
(
false
.
B
)
val
merge_need_uarch_drain
=
WireInit
(
false
.
B
)
val
do_uarch_drain
=
RegNext
(
forward_need_uarch_drain
)
||
RegNext
(
RegNext
(
merge_need_uarch_drain
))
XSPerfAccumulate
(
"do_uarch_drain"
,
do_uarch_drain
)
(
0
until
EnsbufferWidth
).
foreach
(
i
=>
io
.
in
(
i
).
ready
:=
canInserts
(
i
)
&&
(
if
(
i
==
0
)
1.
B
else
!
sameWord
(
0
)(
i
)
&&
io
.
in
(
i
-
1
).
ready
)
)
io
.
in
(
0
).
ready
:=
firstCanInsert
io
.
in
(
1
).
ready
:=
secondCanInsert
&&
!
sameWord
&&
io
.
in
(
0
).
ready
def
wordReqToBufLine
(
// allocate a new line in sbuffer
req
:
DCacheWordReq
,
...
...
@@ -369,7 +376,7 @@ class Sbuffer(implicit p: Parameters) extends DCacheModule with HasSbufferConst
})
}
for
(((
in
,
wordOffset
),
i
)
<-
io
.
in
.
zip
(
words
).
zipWithIndex
){
for
(((
in
,
wordOffset
),
i
)
<-
io
.
in
.
zip
(
Seq
(
firstWord
,
secondWord
)
).
zipWithIndex
){
writeReq
(
i
).
valid
:=
in
.
fire
()
writeReq
(
i
).
bits
.
wordOffset
:=
wordOffset
writeReq
(
i
).
bits
.
mask
:=
in
.
bits
.
mask
...
...
@@ -380,8 +387,7 @@ class Sbuffer(implicit p: Parameters) extends DCacheModule with HasSbufferConst
val
insertVec
=
if
(
i
==
0
)
firstInsertVec
else
secondInsertVec
assert
(!((
PopCount
(
insertVec
)
>
1.
U
)
&&
in
.
fire
()))
val
insertIdx
=
OHToUInt
(
insertVec
)
val
flushMask
=
if
(
i
==
0
)
true
.
B
else
(
0
until
i
).
map
(
j
=>
!
sameTag
(
i
)(
j
)).
reduce
(
_
&&
_
)
flushMask
.
suggestName
(
s
"flushMask_${i}"
)
val
flushMask
=
if
(
i
==
0
)
true
.
B
else
!
sameTag
accessIdx
(
i
).
valid
:=
RegNext
(
in
.
fire
())
accessIdx
(
i
).
bits
:=
RegNext
(
Mux
(
canMerge
(
i
),
mergeIdx
(
i
),
insertIdx
))
when
(
in
.
fire
()){
...
...
@@ -532,7 +538,7 @@ class Sbuffer(implicit p: Parameters) extends DCacheModule with HasSbufferConst
// ---------------------------------------------------------------------------
// TODO: use EnsbufferWidth
val
shouldWaitWriteFinish
=
VecInit
((
0
until
StorePipeline
Width
).
map
{
i
=>
val
shouldWaitWriteFinish
=
VecInit
((
0
until
Ensbuffer
Width
).
map
{
i
=>
(
RegNext
(
writeReq
(
i
).
bits
.
wvec
).
asUInt
&
UIntToOH
(
RegNext
(
sbuffer_out_s0_evictionIdx
))).
asUInt
.
orR
&&
RegNext
(
writeReq
(
i
).
valid
)
}).
asUInt
.
orR
...
...
@@ -662,7 +668,7 @@ class Sbuffer(implicit p: Parameters) extends DCacheModule with HasSbufferConst
// ---------------------- Load Data Forward ---------------------
val
mismatch
=
Wire
(
Vec
(
LoadPipelineWidth
,
Bool
()))
XSPerfAccumulate
(
"vaddr_match_failed"
,
mismatch
.
reduce
(
_
||
_
))
XSPerfAccumulate
(
"vaddr_match_failed"
,
mismatch
(
0
)
||
mismatch
(
1
))
for
((
forward
,
i
)
<-
io
.
forward
.
zipWithIndex
)
{
val
vtag_matches
=
VecInit
(
widthMap
(
w
=>
vtag
(
w
)
===
getVTag
(
forward
.
vaddr
)))
val
ptag_matches
=
VecInit
(
widthMap
(
w
=>
ptag
(
w
)
===
getPTag
(
forward
.
paddr
)))
...
...
@@ -752,7 +758,8 @@ class Sbuffer(implicit p: Parameters) extends DCacheModule with HasSbufferConst
XSPerfAccumulate
(
"sbuffer_idle"
,
sbuffer_state
===
x_idle
)
XSPerfAccumulate
(
"sbuffer_flush"
,
sbuffer_state
===
x_drain_sbuffer
)
XSPerfAccumulate
(
"sbuffer_replace"
,
sbuffer_state
===
x_replace
)
(
0
until
EnsbufferWidth
).
foreach
(
i
=>
XSPerfAccumulate
(
s
"canInserts_${i}"
,
canInserts
(
i
)))
XSPerfAccumulate
(
"evenCanInsert"
,
evenCanInsert
)
XSPerfAccumulate
(
"oddCanInsert"
,
oddCanInsert
)
XSPerfAccumulate
(
"mainpipe_resp_valid"
,
io
.
dcache
.
main_pipe_hit_resp
.
fire
())
XSPerfAccumulate
(
"refill_resp_valid"
,
io
.
dcache
.
refill_hit_resp
.
fire
())
XSPerfAccumulate
(
"replay_resp_valid"
,
io
.
dcache
.
replay_resp
.
fire
())
...
...
@@ -783,4 +790,4 @@ class Sbuffer(implicit p: Parameters) extends DCacheModule with HasSbufferConst
)
generatePerfEvent
()
}
}
\ No newline at end of file
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录