Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
OpenXiangShan
XiangShan
提交
38a7fe59
X
XiangShan
项目概览
OpenXiangShan
/
XiangShan
9 个月 前同步成功
通知
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 搜索 >>
提交
38a7fe59
编写于
8月 06, 2021
作者:
L
Lingrui98
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
frontend: send load replay redirect to bpu
上级
351914a5
变更
4
隐藏空白更改
内联
并排
Showing
4 changed file
with
15 addition
and
75 deletion
+15
-75
src/main/scala/xiangshan/decoupled-frontend/FrontendBundle.scala
...n/scala/xiangshan/decoupled-frontend/FrontendBundle.scala
+0
-1
src/main/scala/xiangshan/decoupled-frontend/IFU.scala
src/main/scala/xiangshan/decoupled-frontend/IFU.scala
+0
-5
src/main/scala/xiangshan/decoupled-frontend/NewFtq.scala
src/main/scala/xiangshan/decoupled-frontend/NewFtq.scala
+13
-66
src/main/scala/xiangshan/decoupled-frontend/PreDecode.scala
src/main/scala/xiangshan/decoupled-frontend/PreDecode.scala
+2
-3
未找到文件。
src/main/scala/xiangshan/decoupled-frontend/FrontendBundle.scala
浏览文件 @
38a7fe59
...
...
@@ -10,7 +10,6 @@ class FetchRequestBundle(implicit p: Parameters) extends XSBundle {
val
startAddr
=
UInt
(
VAddrBits
.
W
)
val
fallThruAddr
=
UInt
(
VAddrBits
.
W
)
val
ftqIdx
=
new
FtqPtr
val
ldReplayOffset
=
ValidUndirectioned
(
UInt
(
log2Ceil
(
PredictWidth
).
W
))
val
ftqOffset
=
ValidUndirectioned
(
UInt
(
log2Ceil
(
PredictWidth
).
W
))
val
target
=
UInt
(
VAddrBits
.
W
)
val
oversize
=
Bool
()
...
...
src/main/scala/xiangshan/decoupled-frontend/IFU.scala
浏览文件 @
38a7fe59
...
...
@@ -64,7 +64,6 @@ class IfuToPreDecode(implicit p: Parameters) extends XSBundle {
val
instValid
=
Bool
()
val
lastHalfMatch
=
Bool
()
val
oversize
=
Bool
()
val
startRange
=
Vec
(
PredictWidth
,
Bool
())
}
class
NewIFU
(
implicit
p
:
Parameters
)
extends
XSModule
with
HasICacheParameters
...
...
@@ -184,8 +183,6 @@ class NewIFU(implicit p: Parameters) extends XSModule with HasICacheParameters
val
f2_ftq_req
=
RegEnable
(
next
=
f1_ftq_req
,
enable
=
f1_fire
)
val
f2_situation
=
RegEnable
(
next
=
f1_situation
,
enable
=
f1_fire
)
val
f2_doubleLine
=
RegEnable
(
next
=
f1_doubleLine
,
enable
=
f1_fire
)
val
f2_isLoadReplay
=
f2_ftq_req
.
ldReplayOffset
.
valid
val
f2_ldReplayIdx
=
f2_ftq_req
.
ldReplayOffset
.
bits
val
f2_fire
=
io
.
toIbuffer
.
fire
()
f1_ready
:=
f2_ready
||
!
f1_valid
...
...
@@ -316,7 +313,6 @@ class NewIFU(implicit p: Parameters) extends XSModule with HasICacheParameters
else
bank
:=
Mux
(
f2_bank_hit
(
i
),
f2_hit_datas
(
i
),
Mux
(
sec_miss_reg
(
3
),
reservedRefillData
(
1
),
Mux
(
sec_miss_reg
(
1
),
reservedRefillData
(
0
),
f2_mq_datas
(
i
))))
}
val
f2_ldreplay_valids
=
Fill
(
PredictWidth
,
!
f2_ftq_req
.
ldReplayOffset
.
valid
)
|
Fill
(
PredictWidth
,
1.
U
(
1.
W
))
<<
(
f2_ftq_req
.
ldReplayOffset
.
bits
)
val
f2_jump_valids
=
Fill
(
PredictWidth
,
!
preDecoderOut
.
cfiOffset
.
valid
)
|
Fill
(
PredictWidth
,
1.
U
(
1.
W
))
>>
(~
preDecoderOut
.
cfiOffset
.
bits
)
val
f2_predecode_valids
=
VecInit
(
preDecoderOut
.
pd
.
map
(
instr
=>
instr
.
valid
)).
asUInt
&
f2_jump_valids
...
...
@@ -352,7 +348,6 @@ class NewIFU(implicit p: Parameters) extends XSModule with HasICacheParameters
preDecoderIn
.
target
:=
f2_ftq_req
.
target
preDecoderIn
.
oversize
:=
f2_ftq_req
.
oversize
preDecoderIn
.
lastHalfMatch
:=
f2_lastHalfMatch
preDecoderIn
.
startRange
:=
f2_ldreplay_valids
.
asTypeOf
(
Vec
(
PredictWidth
,
Bool
()))
predecodeOutValid
:=
(
f2_valid
&&
f2_hit
)
||
miss_all_fix
...
...
src/main/scala/xiangshan/decoupled-frontend/NewFtq.scala
浏览文件 @
38a7fe59
...
...
@@ -354,11 +354,7 @@ class Ftq(implicit p: Parameters) extends XSModule with HasCircularQueuePtrHelpe
val
allowBpuIn
,
allowToIfu
=
WireInit
(
false
.
B
)
val
flushToIfu
=
!
allowToIfu
// all redirect except load replay
allowBpuIn
:=
!
ifuFlush
&&
!
roqFlush
.
valid
&&
!(
stage2Redirect
.
valid
&&
!
isLoadReplay
(
stage2Redirect
))
&&
!(
stage3Redirect
.
valid
&&
!
isLoadReplay
(
stage3Redirect
))
allowBpuIn
:=
!
ifuFlush
&&
!
roqFlush
.
valid
&&
!
stage2Redirect
.
valid
&&
!
stage3Redirect
.
valid
allowToIfu
:=
!
ifuFlush
&&
!
roqFlush
.
valid
&&
!
stage2Redirect
.
valid
&&
!
stage3Redirect
.
valid
val
bpuPtr
,
ifuPtr
,
ifuWbPtr
,
commPtr
=
RegInit
(
FtqPtr
(
false
.
B
,
0.
U
))
...
...
@@ -420,9 +416,6 @@ class Ftq(implicit p: Parameters) extends XSModule with HasCircularQueuePtrHelpe
val
f_to_send
::
f_sent
::
Nil
=
Enum
(
2
)
val
entry_fetch_status
=
RegInit
(
VecInit
(
Seq
.
fill
(
FtqSize
)(
f_sent
)))
val
l_invalid
::
l_replaying
::
Nil
=
Enum
(
2
)
val
entry_replay_status
=
RegInit
(
VecInit
(
Seq
.
fill
(
FtqSize
)(
l_invalid
)))
val
h_not_hit
::
h_false_hit
::
h_hit
::
Nil
=
Enum
(
3
)
val
entry_hit_status
=
RegInit
(
VecInit
(
Seq
.
fill
(
FtqSize
)(
h_not_hit
)))
...
...
@@ -441,7 +434,6 @@ class Ftq(implicit p: Parameters) extends XSModule with HasCircularQueuePtrHelpe
}
val
set_fetch_status_between
=
set_status_between
(
entry_fetch_status
)(
_
,
_
,
_
)
val
set_commit_status_between
=
set_status_between
(
commitStateQueue
)(
_
,
_
,
_
)
val
set_replay_status_between
=
set_status_between
(
entry_replay_status
)(
_
,
_
,
_
)
when
(
enq_fire
)
{
val
enqIdx
=
bpuPtr
.
value
...
...
@@ -450,7 +442,6 @@ class Ftq(implicit p: Parameters) extends XSModule with HasCircularQueuePtrHelpe
val
enq_cfiIndex
=
WireInit
(
0.
U
.
asTypeOf
(
new
ValidUndirectioned
(
UInt
(
log2Ceil
(
PredictWidth
).
W
))))
entry_fetch_status
(
enqIdx
)
:=
f_to_send
commitStateQueue
(
enqIdx
)
:=
VecInit
(
Seq
.
fill
(
PredictWidth
)(
c_invalid
))
entry_replay_status
(
enqIdx
)
:=
l_invalid
// may be useless
entry_hit_status
(
enqIdx
)
:=
Mux
(
io
.
fromBpu
.
resp
.
bits
.
hit
,
h_hit
,
h_not_hit
)
// pd may change it to h_false_hit
enq_cfiIndex
.
valid
:=
preds
.
real_taken_mask
.
asUInt
.
orR
// when no takens, set cfiIndex to PredictWidth-1
...
...
@@ -472,12 +463,11 @@ class Ftq(implicit p: Parameters) extends XSModule with HasCircularQueuePtrHelpe
val
ifu_wb_idx
=
pdWb
.
bits
.
ftqIdx
.
value
// read ports: commit update
val
ftq_pd_mem
=
Module
(
new
SyncDataModuleTemplate
(
new
Ftq_pd_Entry
,
FtqSize
,
1
,
1
))
ftq_pd_mem
.
io
.
wen
(
0
)
:=
ifu_wb_valid
&&
entry_replay_status
(
ifu_wb_idx
)
=/=
l_replaying
ftq_pd_mem
.
io
.
wen
(
0
)
:=
ifu_wb_valid
ftq_pd_mem
.
io
.
waddr
(
0
)
:=
pdWb
.
bits
.
ftqIdx
.
value
ftq_pd_mem
.
io
.
wdata
(
0
).
fromPdWb
(
pdWb
.
bits
)
val
hit_pd_valid
=
entry_hit_status
(
ifu_wb_idx
)
===
h_hit
&&
entry_replay_status
(
ifu_wb_idx
)
=/=
l_replaying
&&
ifu_wb_valid
val
hit_pd_mispred
=
hit_pd_valid
&&
pdWb
.
bits
.
misOffset
.
valid
val
hit_pd_mispred_reg
=
RegNext
(
hit_pd_mispred
,
init
=
false
.
B
)
...
...
@@ -492,7 +482,6 @@ class Ftq(implicit p: Parameters) extends XSModule with HasCircularQueuePtrHelpe
(
commitStateQueue
(
ifu_wb_idx
)
zip
comm_stq_wen
).
map
{
case
(
qe
,
v
)
=>
when
(
v
)
{
qe
:=
c_valid
}
}
entry_replay_status
(
ifu_wb_idx
)
:=
l_invalid
}
ifuWbPtr
:=
ifuWbPtr
+
ifu_wb_valid
...
...
@@ -523,10 +512,6 @@ class Ftq(implicit p: Parameters) extends XSModule with HasCircularQueuePtrHelpe
entry_hit_status
(
wb_idx_reg
)
:=
h_false_hit
}
XSError
(
ifu_wb_valid
&&
pdWb
.
bits
.
misOffset
.
valid
&&
entry_replay_status
(
ifu_wb_idx
)
===
l_replaying
,
p
"unexpected predecode mispredict detected at idx: ${ifu_wb_idx} startAddr: ${Hexadecimal(pdWb.bits.pc(0))} "
+
p
"misOffset: ${pdWb.bits.misOffset.bits}\n"
)
// ****************************************************************
// **************************** to ifu ****************************
...
...
@@ -551,15 +536,10 @@ class Ftq(implicit p: Parameters) extends XSModule with HasCircularQueuePtrHelpe
// read pc and target
ftq_pc_mem
.
io
.
raddr
.
init
.
last
:=
ifuPtr
.
value
val
loadReplayOffset
=
RegInit
(
0.
U
.
asTypeOf
(
Valid
(
UInt
(
log2Ceil
(
PredictWidth
).
W
))))
when
(
to_buf_fire
)
{
ifu_req_buf
.
bits
.
ftqIdx
:=
ifuPtr
ifu_req_buf
.
bits
.
ldReplayOffset
:=
loadReplayOffset
ifu_req_buf
.
bits
.
target
:=
update_target
(
ifuPtr
.
value
)
ifu_req_buf
.
bits
.
ftqOffset
:=
cfiIndex_vec
(
ifuPtr
.
value
)
when
(
loadReplayOffset
.
valid
)
{
loadReplayOffset
.
valid
:=
false
.
B
}
}
when
(
RegNext
(
to_buf_fire
))
{
...
...
@@ -722,52 +702,23 @@ class Ftq(implicit p: Parameters) extends XSModule with HasCircularQueuePtrHelpe
)
// when redirect, we should reset ptrs and status queues
// For normal redirects, the inst casusing redirect itself
// should not be flushed (called flushAfter), we should reset
// both bpuPtr and ifuPtr, and send redirect request to both module.
// However, for load replays, the load instruction itself should be
// re-fetched and re-executed. In this case we only send another
// fetch request to ifu, fetching instructions starting from this load,
// resetting ifuPtr. We do not trigger a redirect for bpu, and we reuse
// previously predicted results to provide the following fetch stream
when
(
redirectVec
.
map
(
r
=>
r
.
valid
).
reduce
(
_
||
_
)){
val
r
=
PriorityMux
(
redirectVec
.
map
(
r
=>
(
r
.
valid
->
r
)))
val
notIfu
=
redirectVec
.
dropRight
(
1
).
map
(
r
=>
r
.
valid
).
reduce
(
_
||
_
)
val
(
idx
,
offset
,
flushItSelf
)
=
(
r
.
ftqIdx
,
r
.
ftqOffset
,
r
.
flushItSelf
)
val
next
=
idx
+
1.
U
when
(!
flushItSelf
)
{
bpuPtr
:=
next
ifuPtr
:=
next
ifuWbPtr
:=
next
when
(
notIfu
)
{
commitStateQueue
(
idx
.
value
).
zipWithIndex
.
foreach
({
case
(
s
,
i
)
=>
when
(
i
.
U
>
offset
){
s
:=
c_invalid
}
})
when
(
next
.
value
=/=
commPtr
.
value
){
// if next.value === commPtr.value, ftq is full
commitStateQueue
(
next
.
value
).
foreach
(
_
:=
c_invalid
)
bpuPtr
:=
next
ifuPtr
:=
next
ifuWbPtr
:=
next
when
(
notIfu
)
{
commitStateQueue
(
idx
.
value
).
zipWithIndex
.
foreach
({
case
(
s
,
i
)
=>
when
(
i
.
U
>
offset
||
i
.
U
===
offset
&&
flushItSelf
){
s
:=
c_invalid
}
})
when
(
next
.
value
=/=
commPtr
.
value
){
// if next.value === commPtr.value, ftq is full
commitStateQueue
(
next
.
value
).
foreach
(
_
:=
c_invalid
)
}
set_replay_status_between
(
ifuPtr
,
FtqPtr
.
inverse
(
ifuPtr
),
l_invalid
)
// set all to invalid
loadReplayOffset
.
valid
:=
false
.
B
// load replay
}.
otherwise
{
ifuPtr
:=
idx
ifuWbPtr
:=
idx
// set fetch status of entries between ifuPtr and bpuPtr to f_to_send
set_fetch_status_between
(
idx
,
ifuPtr
,
f_to_send
)
// set commit state of entries between ifuWbPtr and bpuPtr to c_invalid
set_commit_status_between
(
idx
+
1.
U
,
ifuWbPtr
,
VecInit
(
Seq
.
fill
(
PredictWidth
)(
c_invalid
)))
// set replay status
set_replay_status_between
(
idx
,
ifuWbPtr
,
l_replaying
)
// set load replay offset
loadReplayOffset
.
valid
:=
true
.
B
loadReplayOffset
.
bits
:=
offset
}
}
...
...
@@ -786,11 +737,7 @@ class Ftq(implicit p: Parameters) extends XSModule with HasCircularQueuePtrHelpe
// **************************** to bpu ****************************
// ****************************************************************
// do not send redirect to bpu when load replay
io
.
toBpu
.
redirect
<>
Mux
(
fromBackendRedirect
.
valid
&&
!
fromBackendRedirect
.
bits
.
flushItself
,
fromBackendRedirect
,
ifuRedirectToBpu
)
io
.
toBpu
.
redirect
<>
Mux
(
fromBackendRedirect
.
valid
,
fromBackendRedirect
,
ifuRedirectToBpu
)
val
do_commit
=
Wire
(
Bool
())
val
canCommit
=
commPtr
=/=
ifuWbPtr
&&
!
do_commit
&&
...
...
src/main/scala/xiangshan/decoupled-frontend/PreDecode.scala
浏览文件 @
38a7fe59
...
...
@@ -85,7 +85,6 @@ class PreDecode(implicit p: Parameters) extends XSModule with HasPdConst{
})
val
instValid
=
io
.
in
.
instValid
val
startRange
=
io
.
in
.
startRange
val
data
=
io
.
in
.
data
val
pcStart
=
io
.
in
.
startAddr
val
pcEnd
=
io
.
in
.
fallThruAddr
...
...
@@ -122,7 +121,7 @@ class PreDecode(implicit p: Parameters) extends XSModule with HasPdConst{
val
lastIsValidEnd
=
if
(
i
==
0
)
{
!
io
.
in
.
lastHalfMatch
}
else
{
validEnd
(
i
-
1
)
||
isFirstInBlock
||
!
HasCExtension
.
B
}
validStart
(
i
)
:=
(
lastIsValidEnd
||
!
HasCExtension
.
B
)
&&
startRange
(
i
)
validStart
(
i
)
:=
(
lastIsValidEnd
||
!
HasCExtension
.
B
)
validEnd
(
i
)
:=
validStart
(
i
)
&&
currentIsRVC
||
!
validStart
(
i
)
||
!
HasCExtension
.
B
val
brType
::
isCall
::
isRet
::
Nil
=
brInfo
(
inst
)
...
...
@@ -176,7 +175,7 @@ class PreDecode(implicit p: Parameters) extends XSModule with HasPdConst{
val
endRange
=
((
Fill
(
PredictWidth
,
1.
U
(
1.
W
))
>>
(~
getBasicBlockIdx
(
realEndPC
,
pcStart
)))
|
(
Fill
(
PredictWidth
,
oversize
)))
val
takeRange
=
Fill
(
PredictWidth
,
!
ParallelOR
(
takens
))
|
Fill
(
PredictWidth
,
1.
U
(
1.
W
))
>>
(~
PriorityEncoder
(
takens
))
instRange
:=
VecInit
((
0
until
PredictWidth
).
map
(
i
=>
endRange
(
i
)
&
startRange
(
i
)
&
&
takeRange
(
i
)))
instRange
:=
VecInit
((
0
until
PredictWidth
).
map
(
i
=>
endRange
(
i
)
&&
takeRange
(
i
)))
realEndPC
:=
Mux
(
hasFalseHit
,
Mux
(
hasJump
,
jumpNextPC
,
pcStart
+
(
PredictWidth
*
2
).
U
),
pcEnd
)
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录