Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
OpenXiangShan
XiangShan
提交
fd7be884
X
XiangShan
项目概览
OpenXiangShan
/
XiangShan
大约 1 年 前同步成功
通知
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,发现更多精彩内容 >>
未验证
提交
fd7be884
编写于
12月 20, 2020
作者:
S
Steve Gou
提交者:
GitHub
12月 20, 2020
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #334 from RISCVERS/replay-br-update
recover speculatively updated stuff at replay redirect
上级
71990dd3
c1c3a116
变更
15
隐藏空白更改
内联
并排
Showing
15 changed file
with
432 addition
and
426 deletion
+432
-426
src/main/scala/xiangshan/Bundle.scala
src/main/scala/xiangshan/Bundle.scala
+14
-12
src/main/scala/xiangshan/backend/CtrlBlock.scala
src/main/scala/xiangshan/backend/CtrlBlock.scala
+6
-5
src/main/scala/xiangshan/backend/brq/Brq.scala
src/main/scala/xiangshan/backend/brq/Brq.scala
+34
-27
src/main/scala/xiangshan/backend/fu/Jump.scala
src/main/scala/xiangshan/backend/fu/Jump.scala
+2
-2
src/main/scala/xiangshan/frontend/BPU.scala
src/main/scala/xiangshan/frontend/BPU.scala
+36
-36
src/main/scala/xiangshan/frontend/Bim.scala
src/main/scala/xiangshan/frontend/Bim.scala
+5
-5
src/main/scala/xiangshan/frontend/Btb.scala
src/main/scala/xiangshan/frontend/Btb.scala
+282
-282
src/main/scala/xiangshan/frontend/Frontend.scala
src/main/scala/xiangshan/frontend/Frontend.scala
+2
-2
src/main/scala/xiangshan/frontend/IFU.scala
src/main/scala/xiangshan/frontend/IFU.scala
+11
-15
src/main/scala/xiangshan/frontend/Ibuffer.scala
src/main/scala/xiangshan/frontend/Ibuffer.scala
+3
-3
src/main/scala/xiangshan/frontend/LoopPredictor.scala
src/main/scala/xiangshan/frontend/LoopPredictor.scala
+7
-7
src/main/scala/xiangshan/frontend/RAS.scala
src/main/scala/xiangshan/frontend/RAS.scala
+6
-6
src/main/scala/xiangshan/frontend/Tage.scala
src/main/scala/xiangshan/frontend/Tage.scala
+8
-8
src/main/scala/xiangshan/frontend/uBTB.scala
src/main/scala/xiangshan/frontend/uBTB.scala
+8
-8
src/test/scala/xiangshan/frontend/uBTBTest.scala
src/test/scala/xiangshan/frontend/uBTBTest.scala
+8
-8
未找到文件。
src/main/scala/xiangshan/Bundle.scala
浏览文件 @
fd7be884
...
@@ -24,7 +24,7 @@ class FetchPacket extends XSBundle {
...
@@ -24,7 +24,7 @@ class FetchPacket extends XSBundle {
// val pc = UInt(VAddrBits.W)
// val pc = UInt(VAddrBits.W)
val
pc
=
Vec
(
PredictWidth
,
UInt
(
VAddrBits
.
W
))
val
pc
=
Vec
(
PredictWidth
,
UInt
(
VAddrBits
.
W
))
val
pnpc
=
Vec
(
PredictWidth
,
UInt
(
VAddrBits
.
W
))
val
pnpc
=
Vec
(
PredictWidth
,
UInt
(
VAddrBits
.
W
))
val
b
rInfo
=
Vec
(
PredictWidth
,
new
BranchInfo
)
val
b
puMeta
=
Vec
(
PredictWidth
,
new
BpuMeta
)
val
pd
=
Vec
(
PredictWidth
,
new
PreDecodeInfo
)
val
pd
=
Vec
(
PredictWidth
,
new
PreDecodeInfo
)
val
ipf
=
Bool
()
val
ipf
=
Bool
()
val
acf
=
Bool
()
val
acf
=
Bool
()
...
@@ -116,7 +116,7 @@ class BranchPrediction extends XSBundle with HasIFUConst {
...
@@ -116,7 +116,7 @@ class BranchPrediction extends XSBundle with HasIFUConst {
def
hasNotTakenBrs
=
Mux
(
taken
,
ParallelPriorityMux
(
realTakens
,
sawNotTakenBr
),
ParallelORR
(
brNotTakens
))
def
hasNotTakenBrs
=
Mux
(
taken
,
ParallelPriorityMux
(
realTakens
,
sawNotTakenBr
),
ParallelORR
(
brNotTakens
))
}
}
class
B
ranchInfo
extends
XSBundle
with
HasBPUParameter
{
class
B
puMeta
extends
XSBundle
with
HasBPUParameter
{
val
ubtbWriteWay
=
UInt
(
log2Up
(
UBtbWays
).
W
)
val
ubtbWriteWay
=
UInt
(
log2Up
(
UBtbWays
).
W
)
val
ubtbHits
=
Bool
()
val
ubtbHits
=
Bool
()
val
btbWriteWay
=
UInt
(
log2Up
(
BtbWays
).
W
)
val
btbWriteWay
=
UInt
(
log2Up
(
BtbWays
).
W
)
...
@@ -155,20 +155,22 @@ class Predecode extends XSBundle with HasIFUConst {
...
@@ -155,20 +155,22 @@ class Predecode extends XSBundle with HasIFUConst {
val
pd
=
Vec
(
FetchWidth
*
2
,
(
new
PreDecodeInfo
))
val
pd
=
Vec
(
FetchWidth
*
2
,
(
new
PreDecodeInfo
))
}
}
class
Branch
UpdateInfo
extends
XSBundle
{
class
Cfi
UpdateInfo
extends
XSBundle
{
// from backend
// from backend
val
pc
=
UInt
(
VAddrBits
.
W
)
val
pc
=
UInt
(
VAddrBits
.
W
)
val
pnpc
=
UInt
(
VAddrBits
.
W
)
val
pnpc
=
UInt
(
VAddrBits
.
W
)
val
fetchIdx
=
UInt
(
log2Up
(
FetchWidth
*
2
).
W
)
// frontend -> backend -> frontend
val
pd
=
new
PreDecodeInfo
val
bpuMeta
=
new
BpuMeta
// need pipeline update
val
target
=
UInt
(
VAddrBits
.
W
)
val
target
=
UInt
(
VAddrBits
.
W
)
val
brTarget
=
UInt
(
VAddrBits
.
W
)
val
brTarget
=
UInt
(
VAddrBits
.
W
)
val
taken
=
Bool
()
val
taken
=
Bool
()
val
fetchIdx
=
UInt
(
log2Up
(
FetchWidth
*
2
).
W
)
val
isMisPred
=
Bool
()
val
isMisPred
=
Bool
()
val
brTag
=
new
BrqPtr
val
brTag
=
new
BrqPtr
val
isReplay
=
Bool
()
// frontend -> backend -> frontend
val
pd
=
new
PreDecodeInfo
val
brInfo
=
new
BranchInfo
}
}
// Dequeue DecodeWidth insts from Ibuffer
// Dequeue DecodeWidth insts from Ibuffer
...
@@ -177,7 +179,7 @@ class CtrlFlow extends XSBundle {
...
@@ -177,7 +179,7 @@ class CtrlFlow extends XSBundle {
val
pc
=
UInt
(
VAddrBits
.
W
)
val
pc
=
UInt
(
VAddrBits
.
W
)
val
exceptionVec
=
Vec
(
16
,
Bool
())
val
exceptionVec
=
Vec
(
16
,
Bool
())
val
intrVec
=
Vec
(
12
,
Bool
())
val
intrVec
=
Vec
(
12
,
Bool
())
val
brUpdate
=
new
Branch
UpdateInfo
val
brUpdate
=
new
Cfi
UpdateInfo
val
crossPageIPFFix
=
Bool
()
val
crossPageIPFFix
=
Bool
()
}
}
...
@@ -274,7 +276,7 @@ class ExuOutput extends XSBundle {
...
@@ -274,7 +276,7 @@ class ExuOutput extends XSBundle {
val
fflags
=
new
Fflags
val
fflags
=
new
Fflags
val
redirectValid
=
Bool
()
val
redirectValid
=
Bool
()
val
redirect
=
new
Redirect
val
redirect
=
new
Redirect
val
brUpdate
=
new
Branch
UpdateInfo
val
brUpdate
=
new
Cfi
UpdateInfo
val
debug
=
new
DebugBundle
val
debug
=
new
DebugBundle
}
}
...
@@ -321,8 +323,8 @@ class FrontendToBackendIO extends XSBundle {
...
@@ -321,8 +323,8 @@ class FrontendToBackendIO extends XSBundle {
val
cfVec
=
Vec
(
DecodeWidth
,
DecoupledIO
(
new
CtrlFlow
))
val
cfVec
=
Vec
(
DecodeWidth
,
DecoupledIO
(
new
CtrlFlow
))
// from backend
// from backend
val
redirect
=
Flipped
(
ValidIO
(
UInt
(
VAddrBits
.
W
)))
val
redirect
=
Flipped
(
ValidIO
(
UInt
(
VAddrBits
.
W
)))
val
outOfOrderBrInfo
=
Flipped
(
ValidIO
(
new
Branch
UpdateInfo
))
// val cfiUpdateInfo = Flipped(ValidIO(new Cfi
UpdateInfo))
val
inOrderBrInfo
=
Flipped
(
ValidIO
(
new
Branch
UpdateInfo
))
val
cfiUpdateInfo
=
Flipped
(
ValidIO
(
new
Cfi
UpdateInfo
))
}
}
class
TlbCsrBundle
extends
XSBundle
{
class
TlbCsrBundle
extends
XSBundle
{
...
...
src/main/scala/xiangshan/backend/CtrlBlock.scala
浏览文件 @
fd7be884
...
@@ -78,10 +78,10 @@ class CtrlBlock extends XSModule with HasCircularQueuePtrHelper {
...
@@ -78,10 +78,10 @@ class CtrlBlock extends XSModule with HasCircularQueuePtrHelper {
val
redirectValid
=
roq
.
io
.
redirect
.
valid
||
brq
.
io
.
redirect
.
valid
||
io
.
fromLsBlock
.
replay
.
valid
val
redirectValid
=
roq
.
io
.
redirect
.
valid
||
brq
.
io
.
redirect
.
valid
||
io
.
fromLsBlock
.
replay
.
valid
val
redirect
=
Mux
(
roq
.
io
.
redirect
.
valid
,
roq
.
io
.
redirect
.
bits
,
redirectArb
)
val
redirect
=
Mux
(
roq
.
io
.
redirect
.
valid
,
roq
.
io
.
redirect
.
bits
,
redirectArb
)
io
.
frontend
.
redirect
.
valid
:=
redirectValid
io
.
frontend
.
redirect
.
valid
:=
RegNext
(
redirectValid
)
io
.
frontend
.
redirect
.
bits
:=
Mux
(
roq
.
io
.
redirect
.
valid
,
roq
.
io
.
redirect
.
bits
.
target
,
redirectArb
.
target
)
io
.
frontend
.
redirect
.
bits
:=
RegNext
(
Mux
(
roq
.
io
.
redirect
.
valid
,
roq
.
io
.
redirect
.
bits
.
target
,
redirectArb
.
target
)
)
io
.
frontend
.
outOfOrderBrInfo
<>
brq
.
io
.
outOfOrderBr
Info
// io.frontend.cfiUpdateInfo <> brq.io.cfi
Info
io
.
frontend
.
inOrderBrInfo
<>
brq
.
io
.
inOrderBr
Info
io
.
frontend
.
cfiUpdateInfo
<>
brq
.
io
.
cfi
Info
decode
.
io
.
in
<>
io
.
frontend
.
cfVec
decode
.
io
.
in
<>
io
.
frontend
.
cfVec
decode
.
io
.
toBrq
<>
brq
.
io
.
enqReqs
decode
.
io
.
toBrq
<>
brq
.
io
.
enqReqs
...
@@ -95,8 +95,9 @@ class CtrlBlock extends XSModule with HasCircularQueuePtrHelper {
...
@@ -95,8 +95,9 @@ class CtrlBlock extends XSModule with HasCircularQueuePtrHelper {
brq
.
io
.
exuRedirect
<>
io
.
fromIntBlock
.
exuRedirect
brq
.
io
.
exuRedirect
<>
io
.
fromIntBlock
.
exuRedirect
// pipeline between decode and dispatch
// pipeline between decode and dispatch
val
lastCycleRedirect
=
RegNext
(
redirectValid
)
for
(
i
<-
0
until
RenameWidth
)
{
for
(
i
<-
0
until
RenameWidth
)
{
PipelineConnect
(
decode
.
io
.
out
(
i
),
rename
.
io
.
in
(
i
),
rename
.
io
.
in
(
i
).
ready
,
redirectValid
)
PipelineConnect
(
decode
.
io
.
out
(
i
),
rename
.
io
.
in
(
i
),
rename
.
io
.
in
(
i
).
ready
,
redirectValid
||
lastCycleRedirect
)
}
}
rename
.
io
.
redirect
.
valid
<>
redirectValid
rename
.
io
.
redirect
.
valid
<>
redirectValid
...
...
src/main/scala/xiangshan/backend/brq/Brq.scala
浏览文件 @
fd7be884
...
@@ -51,11 +51,9 @@ class BrqIO extends XSBundle{
...
@@ -51,11 +51,9 @@ class BrqIO extends XSBundle{
val
out
=
ValidIO
(
new
ExuOutput
)
val
out
=
ValidIO
(
new
ExuOutput
)
// misprediction, flush pipeline
// misprediction, flush pipeline
val
redirect
=
Output
(
Valid
(
new
Redirect
))
val
redirect
=
Output
(
Valid
(
new
Redirect
))
val
outOfOrderBrInfo
=
ValidIO
(
new
Branch
UpdateInfo
)
val
cfiInfo
=
ValidIO
(
new
Cfi
UpdateInfo
)
// commit cnt of branch instr
// commit cnt of branch instr
val
bcommit
=
Input
(
UInt
(
BrTagWidth
.
W
))
val
bcommit
=
Input
(
UInt
(
BrTagWidth
.
W
))
// in order dequeue to train bpd
val
inOrderBrInfo
=
ValidIO
(
new
BranchUpdateInfo
)
}
}
class
Brq
extends
XSModule
with
HasCircularQueuePtrHelper
{
class
Brq
extends
XSModule
with
HasCircularQueuePtrHelper
{
...
@@ -63,7 +61,6 @@ class Brq extends XSModule with HasCircularQueuePtrHelper {
...
@@ -63,7 +61,6 @@ class Brq extends XSModule with HasCircularQueuePtrHelper {
class
BrqEntry
extends
Bundle
{
class
BrqEntry
extends
Bundle
{
val
ptrFlag
=
Bool
()
val
ptrFlag
=
Bool
()
val
npc
=
UInt
(
VAddrBits
.
W
)
val
exuOut
=
new
ExuOutput
val
exuOut
=
new
ExuOutput
}
}
...
@@ -117,15 +114,13 @@ class Brq extends XSModule with HasCircularQueuePtrHelper {
...
@@ -117,15 +114,13 @@ class Brq extends XSModule with HasCircularQueuePtrHelper {
val
deqValid
=
stateQueue
(
headIdx
).
isCommit
&&
brCommitCnt
=/=
0.
U
val
deqValid
=
stateQueue
(
headIdx
).
isCommit
&&
brCommitCnt
=/=
0.
U
val
commitValid
=
stateQueue
(
commitIdx
).
isWb
val
commitValid
=
stateQueue
(
commitIdx
).
isWb
val
commitEntry
=
brQueue
(
commitIdx
)
val
commitEntry
=
brQueue
(
commitIdx
)
val
commitIsMisPred
=
commitEntry
.
exuOut
.
redirect
.
isMisPred
val
commitIsMisPred
=
commitEntry
.
exuOut
.
brUpdate
.
isMisPred
brCommitCnt
:=
brCommitCnt
+
io
.
bcommit
-
deqValid
brCommitCnt
:=
brCommitCnt
+
io
.
bcommit
-
deqValid
XSDebug
(
p
"brCommitCnt:$brCommitCnt\n"
)
XSDebug
(
p
"brCommitCnt:$brCommitCnt\n"
)
assert
(
brCommitCnt
+
io
.
bcommit
>=
deqValid
)
assert
(
brCommitCnt
+
io
.
bcommit
>=
deqValid
)
io
.
inOrderBrInfo
.
valid
:=
commitValid
XSDebug
(
io
.
cfiInfo
.
valid
,
"inOrderValid: pc=%x\n"
,
io
.
cfiInfo
.
bits
.
pc
)
io
.
inOrderBrInfo
.
bits
:=
commitEntry
.
exuOut
.
brUpdate
XSDebug
(
io
.
inOrderBrInfo
.
valid
,
"inOrderValid: pc=%x\n"
,
io
.
inOrderBrInfo
.
bits
.
pc
)
XSDebug
(
p
"headIdx:$headIdx commitIdx:$commitIdx\n"
)
XSDebug
(
p
"headIdx:$headIdx commitIdx:$commitIdx\n"
)
XSDebug
(
p
"headPtr:$headPtr tailPtr:$tailPtr\n"
)
XSDebug
(
p
"headPtr:$headPtr tailPtr:$tailPtr\n"
)
...
@@ -149,20 +144,19 @@ class Brq extends XSModule with HasCircularQueuePtrHelper {
...
@@ -149,20 +144,19 @@ class Brq extends XSModule with HasCircularQueuePtrHelper {
assert
(!(
commitIdx
===
headIdx
&&
commitValid
&&
deqValid
),
"Error: deq and commit a same entry!"
)
assert
(!(
commitIdx
===
headIdx
&&
commitValid
&&
deqValid
),
"Error: deq and commit a same entry!"
)
headPtr
:=
headPtrNext
headPtr
:=
headPtrNext
io
.
redirect
.
valid
:=
commitValid
&&
commitIsMisPred
//&&
// !io.roqRedirect.valid &&
// !io.redirect.bits.roqIdx.needFlush(io.memRedirect)
io
.
redirect
.
valid
:=
commitValid
&&
commitIsMisPred
io
.
redirect
.
bits
:=
commitEntry
.
exuOut
.
redirect
io
.
redirect
.
bits
:=
commitEntry
.
exuOut
.
redirect
io
.
redirect
.
bits
.
brTag
:=
BrqPtr
(
commitEntry
.
ptrFlag
,
commitIdx
)
io
.
out
.
valid
:=
commitValid
io
.
out
.
valid
:=
commitValid
io
.
out
.
bits
:=
commitEntry
.
exuOut
io
.
out
.
bits
:=
commitEntry
.
exuOut
io
.
outOfOrderBrInfo
.
valid
:=
commitValid
io
.
outOfOrderBrInfo
.
bits
:=
commitEntry
.
exuOut
.
brUpdate
when
(
io
.
redirect
.
valid
)
{
val
brTagRead
=
RegNext
(
Mux
(
io
.
memRedirect
.
bits
.
isReplay
,
io
.
memRedirect
.
bits
.
brTag
-
1.
U
,
io
.
memRedirect
.
bits
.
brTag
))
commitEntry
.
npc
:=
io
.
redirect
.
bits
.
target
io
.
cfiInfo
.
valid
:=
RegNext
(
io
.
memRedirect
.
valid
||
commitValid
)
}
io
.
cfiInfo
.
bits
:=
brQueue
(
brTagRead
.
value
).
exuOut
.
brUpdate
io
.
cfiInfo
.
bits
.
brTag
:=
brTagRead
io
.
cfiInfo
.
bits
.
isReplay
:=
RegNext
(
io
.
memRedirect
.
bits
.
isReplay
)
XSInfo
(
io
.
out
.
valid
,
XSInfo
(
io
.
out
.
valid
,
p
"commit branch to roq, mispred:${io.redirect.valid} pc=${Hexadecimal(io.out.bits.uop.cf.pc)}\n"
p
"commit branch to roq, mispred:${io.redirect.valid} pc=${Hexadecimal(io.out.bits.uop.cf.pc)}\n"
...
@@ -176,9 +170,13 @@ class Brq extends XSModule with HasCircularQueuePtrHelper {
...
@@ -176,9 +170,13 @@ class Brq extends XSModule with HasCircularQueuePtrHelper {
val
idx
=
brTag
.
value
val
idx
=
brTag
.
value
io
.
enqReqs
(
i
).
ready
:=
validEntries
<=
(
BrqSize
-
(
i
+
1
)).
U
io
.
enqReqs
(
i
).
ready
:=
validEntries
<=
(
BrqSize
-
(
i
+
1
)).
U
io
.
brTags
(
i
)
:=
brTag
io
.
brTags
(
i
)
:=
brTag
when
(
io
.
enqReqs
(
i
).
fire
()){
when
(
io
.
enqReqs
(
i
).
fire
())
{
brQueue
(
idx
).
npc
:=
io
.
enqReqs
(
i
).
bits
.
cf
.
brUpdate
.
pnpc
brQueue
(
idx
).
ptrFlag
:=
brTag
.
flag
brQueue
(
idx
).
ptrFlag
:=
brTag
.
flag
brQueue
(
idx
).
exuOut
.
brUpdate
.
pc
:=
io
.
enqReqs
(
i
).
bits
.
cf
.
brUpdate
.
pc
brQueue
(
idx
).
exuOut
.
brUpdate
.
pnpc
:=
io
.
enqReqs
(
i
).
bits
.
cf
.
brUpdate
.
pnpc
brQueue
(
idx
).
exuOut
.
brUpdate
.
fetchIdx
:=
io
.
enqReqs
(
i
).
bits
.
cf
.
brUpdate
.
fetchIdx
brQueue
(
idx
).
exuOut
.
brUpdate
.
pd
:=
io
.
enqReqs
(
i
).
bits
.
cf
.
brUpdate
.
pd
brQueue
(
idx
).
exuOut
.
brUpdate
.
bpuMeta
:=
io
.
enqReqs
(
i
).
bits
.
cf
.
brUpdate
.
bpuMeta
stateQueue
(
idx
)
:=
s_idle
stateQueue
(
idx
)
:=
s_idle
}
}
}
}
...
@@ -187,20 +185,29 @@ class Brq extends XSModule with HasCircularQueuePtrHelper {
...
@@ -187,20 +185,29 @@ class Brq extends XSModule with HasCircularQueuePtrHelper {
// exu write back
// exu write back
for
(
exuWb
<-
io
.
exuRedirect
){
for
(
exuWb
<-
io
.
exuRedirect
){
when
(
exuWb
.
valid
)
{
when
(
exuWb
.
valid
)
{
val
wbIdx
=
exuWb
.
bits
.
redirect
.
brTag
.
value
val
wbIdx
=
exuWb
.
bits
.
redirect
.
brTag
.
value
XSInfo
(
XSInfo
(
p
"exu write back: brTag:${exuWb.bits.redirect.brTag}"
+
p
"exu write back: brTag:${exuWb.bits.redirect.brTag}"
+
p
" pc=${Hexadecimal(exuWb.bits.uop.cf.pc)} pnpc=${Hexadecimal(brQueue(wbIdx).npc)} target=${Hexadecimal(exuWb.bits.redirect.target)}\n"
p
" pc=${Hexadecimal(exuWb.bits.uop.cf.pc)} "
+
p
"pnpc=${Hexadecimal(brQueue(wbIdx).exuOut.brUpdate.pnpc)} "
+
p
"target=${Hexadecimal(exuWb.bits.redirect.target)}\n"
)
)
when
(
stateQueue
(
wbIdx
).
isIdle
)
{
when
(
stateQueue
(
wbIdx
).
isIdle
)
{
stateQueue
(
wbIdx
)
:=
s_wb
stateQueue
(
wbIdx
)
:=
s_wb
}
}
val
exuOut
=
WireInit
(
exuWb
.
bits
)
val
isMisPred
=
brQueue
(
wbIdx
).
exuOut
.
brUpdate
.
pnpc
=/=
exuWb
.
bits
.
redirect
.
target
val
isMisPred
=
brQueue
(
wbIdx
).
npc
=/=
exuWb
.
bits
.
redirect
.
target
// only writeback necessary information
exuOut
.
redirect
.
isMisPred
:=
isMisPred
brQueue
(
wbIdx
).
exuOut
.
uop
:=
exuWb
.
bits
.
uop
exuOut
.
brUpdate
.
isMisPred
:=
isMisPred
brQueue
(
wbIdx
).
exuOut
.
data
:=
exuWb
.
bits
.
data
brQueue
(
wbIdx
).
exuOut
:=
exuOut
brQueue
(
wbIdx
).
exuOut
.
fflags
:=
exuWb
.
bits
.
fflags
brQueue
(
wbIdx
).
exuOut
.
redirectValid
:=
exuWb
.
bits
.
redirectValid
brQueue
(
wbIdx
).
exuOut
.
redirect
:=
exuWb
.
bits
.
redirect
brQueue
(
wbIdx
).
exuOut
.
debug
:=
exuWb
.
bits
.
debug
brQueue
(
wbIdx
).
exuOut
.
brUpdate
.
target
:=
exuWb
.
bits
.
brUpdate
.
target
brQueue
(
wbIdx
).
exuOut
.
brUpdate
.
brTarget
:=
exuWb
.
bits
.
brUpdate
.
brTarget
brQueue
(
wbIdx
).
exuOut
.
brUpdate
.
taken
:=
exuWb
.
bits
.
brUpdate
.
taken
brQueue
(
wbIdx
).
exuOut
.
brUpdate
.
isMisPred
:=
isMisPred
}
}
}
}
...
...
src/main/scala/xiangshan/backend/fu/Jump.scala
浏览文件 @
fd7be884
...
@@ -11,7 +11,7 @@ import xiangshan.backend.decode.isa._
...
@@ -11,7 +11,7 @@ import xiangshan.backend.decode.isa._
trait
HasRedirectOut
{
this:
RawModule
=>
trait
HasRedirectOut
{
this:
RawModule
=>
val
redirectOutValid
=
IO
(
Output
(
Bool
()))
val
redirectOutValid
=
IO
(
Output
(
Bool
()))
val
redirectOut
=
IO
(
Output
(
new
Redirect
))
val
redirectOut
=
IO
(
Output
(
new
Redirect
))
val
brUpdate
=
IO
(
Output
(
new
Branch
UpdateInfo
))
val
brUpdate
=
IO
(
Output
(
new
Cfi
UpdateInfo
))
}
}
class
Jump
extends
FunctionUnit
with
HasRedirectOut
{
class
Jump
extends
FunctionUnit
with
HasRedirectOut
{
...
@@ -44,7 +44,7 @@ class Jump extends FunctionUnit with HasRedirectOut {
...
@@ -44,7 +44,7 @@ class Jump extends FunctionUnit with HasRedirectOut {
brUpdate
:=
uop
.
cf
.
brUpdate
brUpdate
:=
uop
.
cf
.
brUpdate
brUpdate
.
pc
:=
uop
.
cf
.
pc
brUpdate
.
pc
:=
uop
.
cf
.
pc
brUpdate
.
target
:=
target
brUpdate
.
target
:=
target
brUpdate
.
brTarget
:=
target
// DontCare
brUpdate
.
brTarget
:=
target
brUpdate
.
taken
:=
true
.
B
brUpdate
.
taken
:=
true
.
B
// Output
// Output
...
...
src/main/scala/xiangshan/frontend/BPU.scala
浏览文件 @
fd7be884
...
@@ -115,7 +115,7 @@ abstract class BasePredictor extends XSModule
...
@@ -115,7 +115,7 @@ abstract class BasePredictor extends XSModule
val
pc
=
Flipped
(
ValidIO
(
UInt
(
VAddrBits
.
W
)))
val
pc
=
Flipped
(
ValidIO
(
UInt
(
VAddrBits
.
W
)))
val
hist
=
Input
(
UInt
(
HistoryLength
.
W
))
val
hist
=
Input
(
UInt
(
HistoryLength
.
W
))
val
inMask
=
Input
(
UInt
(
PredictWidth
.
W
))
val
inMask
=
Input
(
UInt
(
PredictWidth
.
W
))
val
update
=
Flipped
(
ValidIO
(
new
BranchUpdateInfoWithHist
))
val
update
=
Flipped
(
ValidIO
(
new
CfiUpdateInfo
))
val
outFire
=
Input
(
Bool
())
val
outFire
=
Input
(
Bool
())
}
}
...
@@ -129,7 +129,7 @@ class BPUStageIO extends XSBundle {
...
@@ -129,7 +129,7 @@ class BPUStageIO extends XSBundle {
val
mask
=
UInt
(
PredictWidth
.
W
)
val
mask
=
UInt
(
PredictWidth
.
W
)
val
resp
=
new
PredictorResponse
val
resp
=
new
PredictorResponse
// val target = UInt(VAddrBits.W)
// val target = UInt(VAddrBits.W)
val
brInfo
=
Vec
(
PredictWidth
,
new
B
ranchInfo
)
val
brInfo
=
Vec
(
PredictWidth
,
new
B
puMeta
)
// val saveHalfRVI = Bool()
// val saveHalfRVI = Bool()
}
}
...
@@ -251,7 +251,7 @@ class BPUStage3 extends BPUStage {
...
@@ -251,7 +251,7 @@ class BPUStage3 extends BPUStage {
val
predecode
=
Input
(
new
Predecode
)
val
predecode
=
Input
(
new
Predecode
)
val
realMask
=
Input
(
UInt
(
PredictWidth
.
W
))
val
realMask
=
Input
(
UInt
(
PredictWidth
.
W
))
val
prevHalf
=
Input
(
new
PrevHalfInstr
)
val
prevHalf
=
Input
(
new
PrevHalfInstr
)
val
recover
=
Flipped
(
ValidIO
(
new
Branch
UpdateInfo
))
val
recover
=
Flipped
(
ValidIO
(
new
Cfi
UpdateInfo
))
}
}
val
s3IO
=
IO
(
new
S3IO
)
val
s3IO
=
IO
(
new
S3IO
)
// TAGE has its own pipelines and the
// TAGE has its own pipelines and the
...
@@ -315,9 +315,9 @@ class BPUStage3 extends BPUStage {
...
@@ -315,9 +315,9 @@ class BPUStage3 extends BPUStage {
ras
.
io
.
recover
:=
s3IO
.
recover
ras
.
io
.
recover
:=
s3IO
.
recover
for
(
i
<-
0
until
PredictWidth
){
for
(
i
<-
0
until
PredictWidth
){
io
.
out
.
brInfo
(
i
).
rasSp
:=
ras
.
io
.
branchInfo
.
rasSp
io
.
out
.
brInfo
(
i
).
rasSp
:=
ras
.
io
.
meta
.
rasSp
io
.
out
.
brInfo
(
i
).
rasTopCtr
:=
ras
.
io
.
branchInfo
.
rasTopCtr
io
.
out
.
brInfo
(
i
).
rasTopCtr
:=
ras
.
io
.
meta
.
rasTopCtr
io
.
out
.
brInfo
(
i
).
rasToqAddr
:=
ras
.
io
.
branchInfo
.
rasToqAddr
io
.
out
.
brInfo
(
i
).
rasToqAddr
:=
ras
.
io
.
meta
.
rasToqAddr
}
}
takens
:=
VecInit
((
0
until
PredictWidth
).
map
(
i
=>
{
takens
:=
VecInit
((
0
until
PredictWidth
).
map
(
i
=>
{
((
brTakens
(
i
)
||
jalrs
(
i
))
&&
btbHits
(
i
))
||
((
brTakens
(
i
)
||
jalrs
(
i
))
&&
btbHits
(
i
))
||
...
@@ -401,25 +401,25 @@ class BPUReq extends XSBundle {
...
@@ -401,25 +401,25 @@ class BPUReq extends XSBundle {
// val histPtr = UInt(log2Up(ExtHistoryLength).W) // only for debug
// val histPtr = UInt(log2Up(ExtHistoryLength).W) // only for debug
}
}
class
Branch
UpdateInfoWithHist
extends
XSBundle
{
// class Cfi
UpdateInfoWithHist extends XSBundle {
val
ui
=
new
Branch
UpdateInfo
// val ui = new Cfi
UpdateInfo
val
hist
=
UInt
(
HistoryLength
.
W
)
//
val hist = UInt(HistoryLength.W)
}
//
}
object
Branch
UpdateInfoWithHist
{
// object Cfi
UpdateInfoWithHist {
def
apply
(
brInfo
:
Branch
UpdateInfo
,
hist
:
UInt
)
=
{
// def apply (brInfo: Cfi
UpdateInfo, hist: UInt) = {
val
b
=
Wire
(
new
Branch
UpdateInfoWithHist
)
// val b = Wire(new Cfi
UpdateInfoWithHist)
b
.
ui
<>
brInfo
//
b.ui <> brInfo
b
.
hist
:=
hist
//
b.hist := hist
b
//
b
}
//
}
}
//
}
abstract
class
BaseBPU
extends
XSModule
with
BranchPredictorComponents
with
HasBPUParameter
{
abstract
class
BaseBPU
extends
XSModule
with
BranchPredictorComponents
with
HasBPUParameter
{
val
io
=
IO
(
new
Bundle
()
{
val
io
=
IO
(
new
Bundle
()
{
// from backend
// from backend
val
inOrderBrInfo
=
Flipped
(
ValidIO
(
new
BranchUpdateInfoWithHist
))
val
cfiUpdateInfo
=
Flipped
(
ValidIO
(
new
CfiUpdateInfo
))
val
outOfOrderBrInfo
=
Flipped
(
ValidIO
(
new
Branch
UpdateInfoWithHist
))
// val cfiUpdateInfo = Flipped(ValidIO(new Cfi
UpdateInfoWithHist))
// from ifu, frontend redirect
// from ifu, frontend redirect
val
flush
=
Input
(
Vec
(
3
,
Bool
()))
val
flush
=
Input
(
Vec
(
3
,
Bool
()))
// from if1
// from if1
...
@@ -432,13 +432,13 @@ abstract class BaseBPU extends XSModule with BranchPredictorComponents with HasB
...
@@ -432,13 +432,13 @@ abstract class BaseBPU extends XSModule with BranchPredictorComponents with HasB
val
realMask
=
Input
(
UInt
(
PredictWidth
.
W
))
val
realMask
=
Input
(
UInt
(
PredictWidth
.
W
))
val
prevHalf
=
Input
(
new
PrevHalfInstr
)
val
prevHalf
=
Input
(
new
PrevHalfInstr
)
// to if4, some bpu info used for updating
// to if4, some bpu info used for updating
val
b
ranchInfo
=
Output
(
Vec
(
PredictWidth
,
new
BranchInfo
))
val
b
puMeta
=
Output
(
Vec
(
PredictWidth
,
new
BpuMeta
))
})
})
def
npc
(
pc
:
UInt
,
instCount
:
UInt
)
=
pc
+
(
instCount
<<
1.
U
)
def
npc
(
pc
:
UInt
,
instCount
:
UInt
)
=
pc
+
(
instCount
<<
1.
U
)
preds
.
map
(
_
.
io
.
update
<>
io
.
outOfOrderBr
Info
)
preds
.
map
(
_
.
io
.
update
<>
io
.
cfiUpdate
Info
)
tage
.
io
.
update
<>
io
.
inOrderBr
Info
// tage.io.update <> io.cfiUpdate
Info
val
s1
=
Module
(
new
BPUStage1
)
val
s1
=
Module
(
new
BPUStage1
)
val
s2
=
Module
(
new
BPUStage2
)
val
s2
=
Module
(
new
BPUStage2
)
...
@@ -469,12 +469,12 @@ abstract class BaseBPU extends XSModule with BranchPredictorComponents with HasB
...
@@ -469,12 +469,12 @@ abstract class BaseBPU extends XSModule with BranchPredictorComponents with HasB
io
.
out
(
1
)
<>
s2
.
io
.
pred
io
.
out
(
1
)
<>
s2
.
io
.
pred
io
.
out
(
2
)
<>
s3
.
io
.
pred
io
.
out
(
2
)
<>
s3
.
io
.
pred
io
.
b
ranchInfo
:=
s3
.
io
.
out
.
brInfo
io
.
b
puMeta
:=
s3
.
io
.
out
.
brInfo
if
(
BPUDebug
)
{
if
(
BPUDebug
)
{
XSDebug
(
io
.
inFire
(
3
),
"b
ranchInfo
sent!\n"
)
XSDebug
(
io
.
inFire
(
3
),
"b
puMeta
sent!\n"
)
for
(
i
<-
0
until
PredictWidth
)
{
for
(
i
<-
0
until
PredictWidth
)
{
val
b
=
io
.
b
ranchInfo
(
i
)
val
b
=
io
.
b
puMeta
(
i
)
XSDebug
(
io
.
inFire
(
3
),
"brInfo(%d): ubtbWrWay:%d, ubtbHit:%d, btbWrWay:%d, btbHitJal:%d, bimCtr:%d, fetchIdx:%d\n"
,
XSDebug
(
io
.
inFire
(
3
),
"brInfo(%d): ubtbWrWay:%d, ubtbHit:%d, btbWrWay:%d, btbHitJal:%d, bimCtr:%d, fetchIdx:%d\n"
,
i
.
U
,
b
.
ubtbWriteWay
,
b
.
ubtbHits
,
b
.
btbWriteWay
,
b
.
btbHitJal
,
b
.
bimCtr
,
b
.
fetchIdx
)
i
.
U
,
b
.
ubtbWriteWay
,
b
.
ubtbHits
,
b
.
btbWriteWay
,
b
.
btbHitJal
,
b
.
bimCtr
,
b
.
fetchIdx
)
val
t
=
b
.
tageMeta
val
t
=
b
.
tageMeta
...
@@ -492,7 +492,7 @@ class FakeBPU extends BaseBPU {
...
@@ -492,7 +492,7 @@ class FakeBPU extends BaseBPU {
i
<>
DontCare
i
<>
DontCare
i
.
takens
:=
0.
U
i
.
takens
:=
0.
U
})
})
io
.
b
ranchInfo
<>
DontCare
io
.
b
puMeta
<>
DontCare
}
}
@chiselName
@chiselName
class
BPU
extends
BaseBPU
{
class
BPU
extends
BaseBPU
{
...
@@ -500,7 +500,7 @@ class BPU extends BaseBPU {
...
@@ -500,7 +500,7 @@ class BPU extends BaseBPU {
//**********************Stage 1****************************//
//**********************Stage 1****************************//
val
s1_resp_in
=
Wire
(
new
PredictorResponse
)
val
s1_resp_in
=
Wire
(
new
PredictorResponse
)
val
s1_brInfo_in
=
Wire
(
Vec
(
PredictWidth
,
new
B
ranchInfo
))
val
s1_brInfo_in
=
Wire
(
Vec
(
PredictWidth
,
new
B
puMeta
))
s1_resp_in
.
tage
:=
DontCare
s1_resp_in
.
tage
:=
DontCare
s1_resp_in
.
loop
:=
DontCare
s1_resp_in
.
loop
:=
DontCare
...
@@ -518,8 +518,8 @@ class BPU extends BaseBPU {
...
@@ -518,8 +518,8 @@ class BPU extends BaseBPU {
// Wrap ubtb response into resp_in and brInfo_in
// Wrap ubtb response into resp_in and brInfo_in
s1_resp_in
.
ubtb
<>
ubtb
.
io
.
out
s1_resp_in
.
ubtb
<>
ubtb
.
io
.
out
for
(
i
<-
0
until
PredictWidth
)
{
for
(
i
<-
0
until
PredictWidth
)
{
s1_brInfo_in
(
i
).
ubtbWriteWay
:=
ubtb
.
io
.
uBTB
BranchInfo
.
writeWay
(
i
)
s1_brInfo_in
(
i
).
ubtbWriteWay
:=
ubtb
.
io
.
uBTB
Meta
.
writeWay
(
i
)
s1_brInfo_in
(
i
).
ubtbHits
:=
ubtb
.
io
.
uBTB
BranchInfo
.
hits
(
i
)
s1_brInfo_in
(
i
).
ubtbHits
:=
ubtb
.
io
.
uBTB
Meta
.
hits
(
i
)
}
}
btb
.
io
.
flush
:=
io
.
flush
(
0
)
// TODO: fix this
btb
.
io
.
flush
:=
io
.
flush
(
0
)
// TODO: fix this
...
@@ -598,8 +598,8 @@ class BPU extends BaseBPU {
...
@@ -598,8 +598,8 @@ class BPU extends BaseBPU {
s3
.
s3IO
.
prevHalf
:=
io
.
prevHalf
s3
.
s3IO
.
prevHalf
:=
io
.
prevHalf
s3
.
s3IO
.
recover
.
valid
<>
io
.
inOrderBr
Info
.
valid
s3
.
s3IO
.
recover
.
valid
<>
io
.
cfiUpdate
Info
.
valid
s3
.
s3IO
.
recover
.
bits
<>
io
.
inOrderBrInfo
.
bits
.
ui
s3
.
s3IO
.
recover
.
bits
<>
io
.
cfiUpdateInfo
.
bits
if
(
BPUDebug
)
{
if
(
BPUDebug
)
{
if
(
debug_verbose
)
{
if
(
debug_verbose
)
{
...
@@ -615,11 +615,11 @@ class BPU extends BaseBPU {
...
@@ -615,11 +615,11 @@ class BPU extends BaseBPU {
if
(
EnableCFICommitLog
)
{
if
(
EnableCFICommitLog
)
{
val
buValid
=
io
.
inOrderBr
Info
.
valid
val
buValid
=
io
.
cfiUpdate
Info
.
valid
val
buinfo
=
io
.
inOrderBrInfo
.
bits
.
ui
val
buinfo
=
io
.
cfiUpdateInfo
.
bits
val
pd
=
buinfo
.
pd
val
pd
=
buinfo
.
pd
val
tage_cycle
=
buinfo
.
b
rInfo
.
debug_tage_cycle
val
tage_cycle
=
buinfo
.
b
puMeta
.
debug_tage_cycle
XSDebug
(
buValid
,
p
"cfi_update: isBr(${pd.isBr}) pc(${Hexadecimal(buinfo.pc)}) taken(${buinfo.taken}) mispred(${buinfo.isMisPred}) cycle($tage_cycle) hist(${Hexadecimal(
io.inOrderBrInfo.bits.his
t)})\n"
)
XSDebug
(
buValid
,
p
"cfi_update: isBr(${pd.isBr}) pc(${Hexadecimal(buinfo.pc)}) taken(${buinfo.taken}) mispred(${buinfo.isMisPred}) cycle($tage_cycle) hist(${Hexadecimal(
buinfo.bpuMeta.predHist.asUIn
t)})\n"
)
}
}
}
}
...
...
src/main/scala/xiangshan/frontend/Bim.scala
浏览文件 @
fd7be884
...
@@ -80,7 +80,7 @@ class BIM extends BasePredictor with BimParams {
...
@@ -80,7 +80,7 @@ class BIM extends BasePredictor with BimParams {
io
.
meta
.
ctrs
(
b
)
:=
ctr
io
.
meta
.
ctrs
(
b
)
:=
ctr
}
}
val
u
=
io
.
update
.
bits
.
ui
val
u
=
io
.
update
.
bits
val
updateBank
=
bimAddr
.
getBank
(
u
.
pc
)
val
updateBank
=
bimAddr
.
getBank
(
u
.
pc
)
val
updateRow
=
bimAddr
.
getBankIdx
(
u
.
pc
)
val
updateRow
=
bimAddr
.
getBankIdx
(
u
.
pc
)
...
@@ -96,12 +96,12 @@ class BIM extends BasePredictor with BimParams {
...
@@ -96,12 +96,12 @@ class BIM extends BasePredictor with BimParams {
val
wrbypass_hit
=
wrbypass_hits
.
reduce
(
_
||
_
)
val
wrbypass_hit
=
wrbypass_hits
.
reduce
(
_
||
_
)
val
wrbypass_hit_idx
=
PriorityEncoder
(
wrbypass_hits
)
val
wrbypass_hit_idx
=
PriorityEncoder
(
wrbypass_hits
)
val
oldCtr
=
Mux
(
wrbypass_hit
&&
wrbypass_ctr_valids
(
wrbypass_hit_idx
)(
updateBank
),
wrbypass_ctrs
(
wrbypass_hit_idx
)(
updateBank
),
u
.
b
rInfo
.
bimCtr
)
val
oldCtr
=
Mux
(
wrbypass_hit
&&
wrbypass_ctr_valids
(
wrbypass_hit_idx
)(
updateBank
),
wrbypass_ctrs
(
wrbypass_hit_idx
)(
updateBank
),
u
.
b
puMeta
.
bimCtr
)
val
newTaken
=
u
.
taken
val
newTaken
=
u
.
taken
val
newCtr
=
satUpdate
(
oldCtr
,
2
,
newTaken
)
val
newCtr
=
satUpdate
(
oldCtr
,
2
,
newTaken
)
// val oldSaturated = newCtr === oldCtr
// val oldSaturated = newCtr === oldCtr
val
needToUpdate
=
io
.
update
.
valid
&&
u
.
pd
.
isBr
val
needToUpdate
=
io
.
update
.
valid
&&
u
.
pd
.
isBr
&&
!
u
.
isReplay
when
(
reset
.
asBool
)
{
wrbypass_ctr_valids
.
foreach
(
_
.
foreach
(
_
:=
false
.
B
))}
when
(
reset
.
asBool
)
{
wrbypass_ctr_valids
.
foreach
(
_
.
foreach
(
_
:=
false
.
B
))}
...
@@ -126,9 +126,9 @@ class BIM extends BasePredictor with BimParams {
...
@@ -126,9 +126,9 @@ class BIM extends BasePredictor with BimParams {
if
(
BPUDebug
&&
debug
)
{
if
(
BPUDebug
&&
debug
)
{
XSDebug
(
doing_reset
,
"Reseting...\n"
)
XSDebug
(
doing_reset
,
"Reseting...\n"
)
XSDebug
(
"[update] v=%d pc=%x pnpc=%x tgt=%x
brTgt=%x\n"
,
io
.
update
.
valid
,
u
.
pc
,
u
.
pnpc
,
u
.
target
,
u
.
brT
arget
)
XSDebug
(
"[update] v=%d pc=%x pnpc=%x tgt=%x
"
,
io
.
update
.
valid
,
u
.
pc
,
u
.
pnpc
,
u
.
t
arget
)
XSDebug
(
"[update] taken=%d isMisPred=%d"
,
u
.
taken
,
u
.
isMisPred
)
XSDebug
(
"[update] taken=%d isMisPred=%d"
,
u
.
taken
,
u
.
isMisPred
)
XSDebug
(
false
,
true
.
B
,
p
"brTag=${u.brTag} pd.isBr=${u.pd.isBr} brInfo.bimCtr=${Binary(u.b
rInfo
.bimCtr)}\n"
)
XSDebug
(
false
,
true
.
B
,
p
"brTag=${u.brTag} pd.isBr=${u.pd.isBr} brInfo.bimCtr=${Binary(u.b
puMeta
.bimCtr)}\n"
)
XSDebug
(
"needToUpdate=%d updateBank=%x updateRow=%x newCtr=%b oldCtr=%b\n"
,
needToUpdate
,
updateBank
,
updateRow
,
newCtr
,
oldCtr
)
XSDebug
(
"needToUpdate=%d updateBank=%x updateRow=%x newCtr=%b oldCtr=%b\n"
,
needToUpdate
,
updateBank
,
updateRow
,
newCtr
,
oldCtr
)
XSDebug
(
"[wrbypass] hit=%d hits=%b\n"
,
wrbypass_hit
,
wrbypass_hits
.
asUInt
)
XSDebug
(
"[wrbypass] hit=%d hits=%b\n"
,
wrbypass_hit
,
wrbypass_hits
.
asUInt
)
}
}
...
...
src/main/scala/xiangshan/frontend/Btb.scala
浏览文件 @
fd7be884
package
xiangshan.frontend
package
xiangshan.frontend
import
chisel3._
import
chisel3._
import
chisel3.stage.
{
ChiselGeneratorAnnotation
,
ChiselStage
}
import
chisel3.stage.
{
ChiselGeneratorAnnotation
,
ChiselStage
}
import
chisel3.util._
import
chisel3.util._
import
xiangshan._
import
xiangshan._
import
xiangshan.backend.ALUOpType
import
xiangshan.backend.ALUOpType
import
utils._
import
utils._
import
xiangshan.backend.decode.XSTrap
import
xiangshan.backend.decode.XSTrap
import
chisel3.experimental.chiselName
import
chisel3.experimental.chiselName
import
scala.math.min
import
scala.math.min
trait
BTBParams
extends
HasXSParameter
{
trait
BTBParams
extends
HasXSParameter
{
val
nRows
=
BtbSize
/
(
PredictWidth
*
BtbWays
)
val
nRows
=
BtbSize
/
(
PredictWidth
*
BtbWays
)
val
offsetLen
=
13
val
offsetLen
=
13
val
extendedNRows
=
nRows
val
extendedNRows
=
nRows
}
}
class
BtbDataEntry
extends
XSBundle
with
BTBParams
{
class
BtbDataEntry
extends
XSBundle
with
BTBParams
{
val
offset
=
SInt
(
offsetLen
.
W
)
val
offset
=
SInt
(
offsetLen
.
W
)
val
extended
=
Bool
()
val
extended
=
Bool
()
}
}
object
BtbDataEntry
{
object
BtbDataEntry
{
def
apply
(
offset
:
SInt
,
extended
:
Bool
)
=
{
def
apply
(
offset
:
SInt
,
extended
:
Bool
)
=
{
val
e
=
Wire
(
new
BtbDataEntry
)
val
e
=
Wire
(
new
BtbDataEntry
)
e
.
offset
:=
offset
e
.
offset
:=
offset
e
.
extended
:=
extended
e
.
extended
:=
extended
e
e
}
}
}
}
class
BtbMetaEntry
()
extends
XSBundle
with
BTBParams
{
class
BtbMetaEntry
()
extends
XSBundle
with
BTBParams
{
val
valid
=
Bool
()
val
valid
=
Bool
()
// TODO: don't need full length of tag
// TODO: don't need full length of tag
val
tag
=
UInt
((
VAddrBits
-
log2Up
(
BtbSize
)
-
1
).
W
)
val
tag
=
UInt
((
VAddrBits
-
log2Up
(
BtbSize
)
-
1
).
W
)
val
btbType
=
UInt
(
2.
W
)
val
btbType
=
UInt
(
2.
W
)
val
isRVC
=
Bool
()
val
isRVC
=
Bool
()
}
}
object
BtbMetaEntry
{
object
BtbMetaEntry
{
def
apply
(
tag
:
UInt
,
btbType
:
UInt
,
isRVC
:
Bool
)
=
{
def
apply
(
tag
:
UInt
,
btbType
:
UInt
,
isRVC
:
Bool
)
=
{
val
e
=
Wire
(
new
BtbMetaEntry
)
val
e
=
Wire
(
new
BtbMetaEntry
)
e
.
valid
:=
true
.
B
e
.
valid
:=
true
.
B
e
.
tag
:=
tag
e
.
tag
:=
tag
e
.
btbType
:=
btbType
e
.
btbType
:=
btbType
e
.
isRVC
:=
isRVC
e
.
isRVC
:=
isRVC
e
e
}
}
}
}
class
BTB
extends
BasePredictor
with
BTBParams
{
class
BTB
extends
BasePredictor
with
BTBParams
{
class
BTBResp
extends
Resp
{
class
BTBResp
extends
Resp
{
val
targets
=
Vec
(
PredictWidth
,
UInt
(
VAddrBits
.
W
))
val
targets
=
Vec
(
PredictWidth
,
UInt
(
VAddrBits
.
W
))
val
hits
=
Vec
(
PredictWidth
,
Bool
())
val
hits
=
Vec
(
PredictWidth
,
Bool
())
val
types
=
Vec
(
PredictWidth
,
UInt
(
2.
W
))
val
types
=
Vec
(
PredictWidth
,
UInt
(
2.
W
))
val
isRVC
=
Vec
(
PredictWidth
,
Bool
())
val
isRVC
=
Vec
(
PredictWidth
,
Bool
())
}
}
class
BTBMeta
extends
Meta
{
class
BTBMeta
extends
Meta
{
val
writeWay
=
Vec
(
PredictWidth
,
UInt
(
log2Up
(
BtbWays
).
W
))
val
writeWay
=
Vec
(
PredictWidth
,
UInt
(
log2Up
(
BtbWays
).
W
))
val
hitJal
=
Vec
(
PredictWidth
,
Bool
())
val
hitJal
=
Vec
(
PredictWidth
,
Bool
())
}
}
class
BTBFromOthers
extends
FromOthers
{}
class
BTBFromOthers
extends
FromOthers
{}
class
BTBIO
extends
DefaultBasePredictorIO
{
class
BTBIO
extends
DefaultBasePredictorIO
{
val
resp
=
Output
(
new
BTBResp
)
val
resp
=
Output
(
new
BTBResp
)
val
meta
=
Output
(
new
BTBMeta
)
val
meta
=
Output
(
new
BTBMeta
)
}
}
override
val
debug
=
true
override
val
debug
=
true
override
val
io
=
IO
(
new
BTBIO
)
override
val
io
=
IO
(
new
BTBIO
)
val
btbAddr
=
new
TableAddr
(
log2Up
(
BtbSize
/
BtbWays
),
BtbBanks
)
val
btbAddr
=
new
TableAddr
(
log2Up
(
BtbSize
/
BtbWays
),
BtbBanks
)
val
if1_bankAlignedPC
=
bankAligned
(
io
.
pc
.
bits
)
val
if1_bankAlignedPC
=
bankAligned
(
io
.
pc
.
bits
)
val
if2_pc
=
RegEnable
(
if1_bankAlignedPC
,
io
.
pc
.
valid
)
val
if2_pc
=
RegEnable
(
if1_bankAlignedPC
,
io
.
pc
.
valid
)
val
data
=
List
.
fill
(
BtbWays
)
{
val
data
=
List
.
fill
(
BtbWays
)
{
List
.
fill
(
BtbBanks
)
{
List
.
fill
(
BtbBanks
)
{
Module
(
new
SRAMTemplate
(
new
BtbDataEntry
,
set
=
nRows
,
shouldReset
=
true
,
holdRead
=
true
))
Module
(
new
SRAMTemplate
(
new
BtbDataEntry
,
set
=
nRows
,
shouldReset
=
true
,
holdRead
=
true
))
}
}
}
}
val
meta
=
List
.
fill
(
BtbWays
)
{
val
meta
=
List
.
fill
(
BtbWays
)
{
List
.
fill
(
BtbBanks
)
{
List
.
fill
(
BtbBanks
)
{
Module
(
new
SRAMTemplate
(
new
BtbMetaEntry
,
set
=
nRows
,
shouldReset
=
true
,
holdRead
=
true
))
Module
(
new
SRAMTemplate
(
new
BtbMetaEntry
,
set
=
nRows
,
shouldReset
=
true
,
holdRead
=
true
))
}
}
}
}
val
edata
=
List
.
fill
(
2
)(
Module
(
new
SRAMTemplate
(
UInt
(
VAddrBits
.
W
),
set
=
extendedNRows
/
2
,
shouldReset
=
true
,
holdRead
=
true
)))
val
edata
=
List
.
fill
(
2
)(
Module
(
new
SRAMTemplate
(
UInt
(
VAddrBits
.
W
),
set
=
extendedNRows
/
2
,
shouldReset
=
true
,
holdRead
=
true
)))
// BTB read requests
// BTB read requests
// this bank means cache bank
// this bank means cache bank
val
if1_startsAtOddBank
=
bankInGroup
(
if1_bankAlignedPC
)(
0
)
val
if1_startsAtOddBank
=
bankInGroup
(
if1_bankAlignedPC
)(
0
)
val
if1_baseBank
=
btbAddr
.
getBank
(
if1_bankAlignedPC
)
val
if1_baseBank
=
btbAddr
.
getBank
(
if1_bankAlignedPC
)
val
if1_realMask
=
Mux
(
if1_startsAtOddBank
,
val
if1_realMask
=
Mux
(
if1_startsAtOddBank
,
Cat
(
io
.
inMask
(
bankWidth
-
1
,
0
),
io
.
inMask
(
PredictWidth
-
1
,
bankWidth
)),
Cat
(
io
.
inMask
(
bankWidth
-
1
,
0
),
io
.
inMask
(
PredictWidth
-
1
,
bankWidth
)),
io
.
inMask
)
io
.
inMask
)
val
if2_realMask
=
RegEnable
(
if1_realMask
,
io
.
pc
.
valid
)
val
if2_realMask
=
RegEnable
(
if1_realMask
,
io
.
pc
.
valid
)
val
if1_isInNextRow
=
VecInit
((
0
until
BtbBanks
).
map
(
i
=>
Mux
(
if1_startsAtOddBank
,
(
i
<
bankWidth
).
B
,
false
.
B
)))
val
if1_isInNextRow
=
VecInit
((
0
until
BtbBanks
).
map
(
i
=>
Mux
(
if1_startsAtOddBank
,
(
i
<
bankWidth
).
B
,
false
.
B
)))
val
if1_baseRow
=
btbAddr
.
getBankIdx
(
if1_bankAlignedPC
)
val
if1_baseRow
=
btbAddr
.
getBankIdx
(
if1_bankAlignedPC
)
val
if1_nextRowStartsUp
=
if1_baseRow
.
andR
val
if1_nextRowStartsUp
=
if1_baseRow
.
andR
val
if1_realRow
=
VecInit
((
0
until
BtbBanks
).
map
(
b
=>
Mux
(
if1_isInNextRow
(
b
),
(
if1_baseRow
+
1.
U
)(
log2Up
(
nRows
)-
1
,
0
),
if1_baseRow
)))
val
if1_realRow
=
VecInit
((
0
until
BtbBanks
).
map
(
b
=>
Mux
(
if1_isInNextRow
(
b
),
(
if1_baseRow
+
1.
U
)(
log2Up
(
nRows
)-
1
,
0
),
if1_baseRow
)))
val
if2_realRow
=
VecInit
(
if1_realRow
.
map
(
RegEnable
(
_
,
enable
=
io
.
pc
.
valid
)))
val
if2_realRow
=
VecInit
(
if1_realRow
.
map
(
RegEnable
(
_
,
enable
=
io
.
pc
.
valid
)))
for
(
w
<-
0
until
BtbWays
)
{
for
(
w
<-
0
until
BtbWays
)
{
for
(
b
<-
0
until
BtbBanks
)
{
for
(
b
<-
0
until
BtbBanks
)
{
meta
(
w
)(
b
).
io
.
r
.
req
.
valid
:=
if1_realMask
(
b
)
&&
io
.
pc
.
valid
meta
(
w
)(
b
).
io
.
r
.
req
.
valid
:=
if1_realMask
(
b
)
&&
io
.
pc
.
valid
meta
(
w
)(
b
).
io
.
r
.
req
.
bits
.
setIdx
:=
if1_realRow
(
b
)
meta
(
w
)(
b
).
io
.
r
.
req
.
bits
.
setIdx
:=
if1_realRow
(
b
)
data
(
w
)(
b
).
io
.
r
.
req
.
valid
:=
if1_realMask
(
b
)
&&
io
.
pc
.
valid
data
(
w
)(
b
).
io
.
r
.
req
.
valid
:=
if1_realMask
(
b
)
&&
io
.
pc
.
valid
data
(
w
)(
b
).
io
.
r
.
req
.
bits
.
setIdx
:=
if1_realRow
(
b
)
data
(
w
)(
b
).
io
.
r
.
req
.
bits
.
setIdx
:=
if1_realRow
(
b
)
}
}
}
}
for
(
b
<-
0
to
1
)
{
for
(
b
<-
0
to
1
)
{
edata
(
b
).
io
.
r
.
req
.
valid
:=
io
.
pc
.
valid
edata
(
b
).
io
.
r
.
req
.
valid
:=
io
.
pc
.
valid
val
row
=
if
(
b
==
0
)
{
Mux
(
if1_startsAtOddBank
,
if1_realRow
(
bankWidth
),
if1_realRow
(
0
))
}
val
row
=
if
(
b
==
0
)
{
Mux
(
if1_startsAtOddBank
,
if1_realRow
(
bankWidth
),
if1_realRow
(
0
))
}
else
{
Mux
(
if1_startsAtOddBank
,
if1_realRow
(
0
),
if1_realRow
(
bankWidth
))}
else
{
Mux
(
if1_startsAtOddBank
,
if1_realRow
(
0
),
if1_realRow
(
bankWidth
))}
edata
(
b
).
io
.
r
.
req
.
bits
.
setIdx
:=
row
edata
(
b
).
io
.
r
.
req
.
bits
.
setIdx
:=
row
}
}
// Entries read from SRAM
// Entries read from SRAM
val
if2_metaRead
=
VecInit
((
0
until
BtbWays
).
map
(
w
=>
VecInit
((
0
until
BtbBanks
).
map
(
b
=>
meta
(
w
)(
b
).
io
.
r
.
resp
.
data
(
0
)))))
val
if2_metaRead
=
VecInit
((
0
until
BtbWays
).
map
(
w
=>
VecInit
((
0
until
BtbBanks
).
map
(
b
=>
meta
(
w
)(
b
).
io
.
r
.
resp
.
data
(
0
)))))
val
if2_dataRead
=
VecInit
((
0
until
BtbWays
).
map
(
w
=>
VecInit
((
0
until
BtbBanks
).
map
(
b
=>
data
(
w
)(
b
).
io
.
r
.
resp
.
data
(
0
)))))
val
if2_dataRead
=
VecInit
((
0
until
BtbWays
).
map
(
w
=>
VecInit
((
0
until
BtbBanks
).
map
(
b
=>
data
(
w
)(
b
).
io
.
r
.
resp
.
data
(
0
)))))
val
if2_edataRead
=
VecInit
((
0
to
1
).
map
(
i
=>
edata
(
i
).
io
.
r
.
resp
.
data
(
0
)))
val
if2_edataRead
=
VecInit
((
0
to
1
).
map
(
i
=>
edata
(
i
).
io
.
r
.
resp
.
data
(
0
)))
val
if2_baseBank
=
btbAddr
.
getBank
(
if2_pc
)
val
if2_baseBank
=
btbAddr
.
getBank
(
if2_pc
)
val
if2_startsAtOddBank
=
bankInGroup
(
if2_pc
)(
0
)
val
if2_startsAtOddBank
=
bankInGroup
(
if2_pc
)(
0
)
val
if2_baseTag
=
btbAddr
.
getTag
(
if2_pc
)
val
if2_baseTag
=
btbAddr
.
getTag
(
if2_pc
)
val
if2_tagIncremented
=
VecInit
((
0
until
BtbBanks
).
map
(
b
=>
RegEnable
(
if1_isInNextRow
(
b
.
U
)
&&
if1_nextRowStartsUp
,
io
.
pc
.
valid
)))
val
if2_tagIncremented
=
VecInit
((
0
until
BtbBanks
).
map
(
b
=>
RegEnable
(
if1_isInNextRow
(
b
.
U
)
&&
if1_nextRowStartsUp
,
io
.
pc
.
valid
)))
val
if2_realTags
=
VecInit
((
0
until
BtbBanks
).
map
(
b
=>
Mux
(
if2_tagIncremented
(
b
),
if2_baseTag
+
1.
U
,
if2_baseTag
)))
val
if2_realTags
=
VecInit
((
0
until
BtbBanks
).
map
(
b
=>
Mux
(
if2_tagIncremented
(
b
),
if2_baseTag
+
1.
U
,
if2_baseTag
)))
val
if2_totalHits
=
VecInit
((
0
until
BtbBanks
).
map
(
b
=>
val
if2_totalHits
=
VecInit
((
0
until
BtbBanks
).
map
(
b
=>
VecInit
((
0
until
BtbWays
).
map
(
w
=>
VecInit
((
0
until
BtbWays
).
map
(
w
=>
// This should correspond to the real mask from last valid cycle!
// This should correspond to the real mask from last valid cycle!
if2_metaRead
(
w
)(
b
).
tag
===
if2_realTags
(
b
)
&&
if2_metaRead
(
w
)(
b
).
valid
&&
if2_realMask
(
b
)
if2_metaRead
(
w
)(
b
).
tag
===
if2_realTags
(
b
)
&&
if2_metaRead
(
w
)(
b
).
valid
&&
if2_realMask
(
b
)
))
))
))
))
val
if2_bankHits
=
VecInit
(
if2_totalHits
.
map
(
_
.
reduce
(
_
||
_
)))
val
if2_bankHits
=
VecInit
(
if2_totalHits
.
map
(
_
.
reduce
(
_
||
_
)))
val
if2_bankHitWays
=
VecInit
(
if2_totalHits
.
map
(
PriorityEncoder
(
_
)))
val
if2_bankHitWays
=
VecInit
(
if2_totalHits
.
map
(
PriorityEncoder
(
_
)))
def
allocWay
(
valids
:
UInt
,
meta_tags
:
UInt
,
req_tag
:
UInt
)
=
{
def
allocWay
(
valids
:
UInt
,
meta_tags
:
UInt
,
req_tag
:
UInt
)
=
{
val
randomAlloc
=
true
val
randomAlloc
=
true
if
(
BtbWays
>
1
)
{
if
(
BtbWays
>
1
)
{
val
w
=
Wire
(
UInt
(
log2Up
(
BtbWays
).
W
))
val
w
=
Wire
(
UInt
(
log2Up
(
BtbWays
).
W
))
val
valid
=
WireInit
(
valids
.
andR
)
val
valid
=
WireInit
(
valids
.
andR
)
val
tags
=
Cat
(
meta_tags
,
req_tag
)
val
tags
=
Cat
(
meta_tags
,
req_tag
)
val
l
=
log2Up
(
BtbWays
)
val
l
=
log2Up
(
BtbWays
)
val
nChunks
=
(
tags
.
getWidth
+
l
-
1
)
/
l
val
nChunks
=
(
tags
.
getWidth
+
l
-
1
)
/
l
val
chunks
=
(
0
until
nChunks
).
map
(
i
=>
val
chunks
=
(
0
until
nChunks
).
map
(
i
=>
tags
(
min
((
i
+
1
)*
l
,
tags
.
getWidth
)-
1
,
i
*
l
)
tags
(
min
((
i
+
1
)*
l
,
tags
.
getWidth
)-
1
,
i
*
l
)
)
)
w
:=
Mux
(
valid
,
if
(
randomAlloc
)
{
LFSR64
()(
log2Up
(
BtbWays
)-
1
,
0
)}
else
{
chunks
.
reduce
(
_
^
_
)},
PriorityEncoder
(~
valids
))
w
:=
Mux
(
valid
,
if
(
randomAlloc
)
{
LFSR64
()(
log2Up
(
BtbWays
)-
1
,
0
)}
else
{
chunks
.
reduce
(
_
^
_
)},
PriorityEncoder
(~
valids
))
w
w
}
else
{
}
else
{
val
w
=
WireInit
(
0.
U
)
val
w
=
WireInit
(
0.
U
)
w
w
}
}
}
}
val
allocWays
=
VecInit
((
0
until
BtbBanks
).
map
(
b
=>
val
allocWays
=
VecInit
((
0
until
BtbBanks
).
map
(
b
=>
allocWay
(
VecInit
(
if2_metaRead
.
map
(
w
=>
w
(
b
).
valid
)).
asUInt
,
allocWay
(
VecInit
(
if2_metaRead
.
map
(
w
=>
w
(
b
).
valid
)).
asUInt
,
VecInit
(
if2_metaRead
.
map
(
w
=>
w
(
b
).
tag
)).
asUInt
,
VecInit
(
if2_metaRead
.
map
(
w
=>
w
(
b
).
tag
)).
asUInt
,
if2_realTags
(
b
))))
if2_realTags
(
b
))))
val
writeWay
=
VecInit
((
0
until
BtbBanks
).
map
(
val
writeWay
=
VecInit
((
0
until
BtbBanks
).
map
(
b
=>
Mux
(
if2_bankHits
(
b
),
if2_bankHitWays
(
b
),
allocWays
(
b
))
b
=>
Mux
(
if2_bankHits
(
b
),
if2_bankHitWays
(
b
),
allocWays
(
b
))
))
))
for
(
b
<-
0
until
BtbBanks
)
{
for
(
b
<-
0
until
BtbBanks
)
{
val
realBank
=
(
if
(
b
<
bankWidth
)
Mux
(
if2_startsAtOddBank
,
(
b
+
bankWidth
).
U
,
b
.
U
)
val
realBank
=
(
if
(
b
<
bankWidth
)
Mux
(
if2_startsAtOddBank
,
(
b
+
bankWidth
).
U
,
b
.
U
)
else
Mux
(
if2_startsAtOddBank
,
(
b
-
bankWidth
).
U
,
b
.
U
))
else
Mux
(
if2_startsAtOddBank
,
(
b
-
bankWidth
).
U
,
b
.
U
))
val
meta_entry
=
if2_metaRead
(
if2_bankHitWays
(
realBank
))(
realBank
)
val
meta_entry
=
if2_metaRead
(
if2_bankHitWays
(
realBank
))(
realBank
)
val
data_entry
=
if2_dataRead
(
if2_bankHitWays
(
realBank
))(
realBank
)
val
data_entry
=
if2_dataRead
(
if2_bankHitWays
(
realBank
))(
realBank
)
val
edataBank
=
(
if
(
b
<
bankWidth
)
Mux
(
if2_startsAtOddBank
,
1.
U
,
0.
U
)
val
edataBank
=
(
if
(
b
<
bankWidth
)
Mux
(
if2_startsAtOddBank
,
1.
U
,
0.
U
)
else
Mux
(
if2_startsAtOddBank
,
0.
U
,
1.
U
))
else
Mux
(
if2_startsAtOddBank
,
0.
U
,
1.
U
))
// Use real pc to calculate the target
// Use real pc to calculate the target
io
.
resp
.
targets
(
b
)
:=
Mux
(
data_entry
.
extended
,
if2_edataRead
(
edataBank
),
(
if2_pc
.
asSInt
+
(
b
<<
1
).
S
+
data_entry
.
offset
).
asUInt
)
io
.
resp
.
targets
(
b
)
:=
Mux
(
data_entry
.
extended
,
if2_edataRead
(
edataBank
),
(
if2_pc
.
asSInt
+
(
b
<<
1
).
S
+
data_entry
.
offset
).
asUInt
)
io
.
resp
.
hits
(
b
)
:=
if2_bankHits
(
realBank
)
io
.
resp
.
hits
(
b
)
:=
if2_bankHits
(
realBank
)
io
.
resp
.
types
(
b
)
:=
meta_entry
.
btbType
io
.
resp
.
types
(
b
)
:=
meta_entry
.
btbType
io
.
resp
.
isRVC
(
b
)
:=
meta_entry
.
isRVC
io
.
resp
.
isRVC
(
b
)
:=
meta_entry
.
isRVC
io
.
meta
.
writeWay
(
b
)
:=
writeWay
(
realBank
)
io
.
meta
.
writeWay
(
b
)
:=
writeWay
(
realBank
)
io
.
meta
.
hitJal
(
b
)
:=
if2_bankHits
(
realBank
)
&&
meta_entry
.
btbType
===
BTBtype
.
J
io
.
meta
.
hitJal
(
b
)
:=
if2_bankHits
(
realBank
)
&&
meta_entry
.
btbType
===
BTBtype
.
J
}
}
def
pdInfoToBTBtype
(
pd
:
PreDecodeInfo
)
=
{
def
pdInfoToBTBtype
(
pd
:
PreDecodeInfo
)
=
{
val
t
=
WireInit
(
0.
U
(
2.
W
))
val
t
=
WireInit
(
0.
U
(
2.
W
))
when
(
pd
.
isJalr
)
{
t
:=
BTBtype
.
I
}
when
(
pd
.
isJalr
)
{
t
:=
BTBtype
.
I
}
when
(
pd
.
isRet
)
{
t
:=
BTBtype
.
R
}
when
(
pd
.
isRet
)
{
t
:=
BTBtype
.
R
}
when
(
pd
.
isJal
)
{
t
:=
BTBtype
.
J
}
when
(
pd
.
isJal
)
{
t
:=
BTBtype
.
J
}
when
(
pd
.
isBr
)
{
t
:=
BTBtype
.
B
}
when
(
pd
.
isBr
)
{
t
:=
BTBtype
.
B
}
t
t
}
}
val
u
=
io
.
update
.
bits
.
ui
val
u
=
io
.
update
.
bits
val
max_offset
=
Cat
(
0.
B
,
~(
0.
U
((
offsetLen
-
1
).
W
))).
asSInt
val
max_offset
=
Cat
(
0.
B
,
~(
0.
U
((
offsetLen
-
1
).
W
))).
asSInt
val
min_offset
=
Cat
(
1.
B
,
(
0.
U
((
offsetLen
-
1
).
W
))).
asSInt
val
min_offset
=
Cat
(
1.
B
,
(
0.
U
((
offsetLen
-
1
).
W
))).
asSInt
val
new_target
=
Mux
(
u
.
pd
.
isBr
,
u
.
brTarget
,
u
.
target
)
val
new_target
=
Mux
(
u
.
pd
.
isBr
,
u
.
brTarget
,
u
.
target
)
val
new_offset
=
(
new_target
.
asSInt
-
u
.
pc
.
asSInt
)
val
new_offset
=
(
new_target
.
asSInt
-
u
.
pc
.
asSInt
)
val
new_extended
=
(
new_offset
>
max_offset
||
new_offset
<
min_offset
)
val
new_extended
=
(
new_offset
>
max_offset
||
new_offset
<
min_offset
)
val
updateWay
=
u
.
b
rInfo
.
btbWriteWay
val
updateWay
=
u
.
b
puMeta
.
btbWriteWay
val
updateBankIdx
=
btbAddr
.
getBank
(
u
.
pc
)
val
updateBankIdx
=
btbAddr
.
getBank
(
u
.
pc
)
val
updateEBank
=
updateBankIdx
(
log2Ceil
(
BtbBanks
)-
1
)
// highest bit of bank idx
val
updateEBank
=
updateBankIdx
(
log2Ceil
(
BtbBanks
)-
1
)
// highest bit of bank idx
val
updateRow
=
btbAddr
.
getBankIdx
(
u
.
pc
)
val
updateRow
=
btbAddr
.
getBankIdx
(
u
.
pc
)
val
updateType
=
pdInfoToBTBtype
(
u
.
pd
)
val
updateType
=
pdInfoToBTBtype
(
u
.
pd
)
val
metaWrite
=
BtbMetaEntry
(
btbAddr
.
getTag
(
u
.
pc
),
updateType
,
u
.
pd
.
isRVC
)
val
metaWrite
=
BtbMetaEntry
(
btbAddr
.
getTag
(
u
.
pc
),
updateType
,
u
.
pd
.
isRVC
)
val
dataWrite
=
BtbDataEntry
(
new_offset
,
new_extended
)
val
dataWrite
=
BtbDataEntry
(
new_offset
,
new_extended
)
val
jalFirstEncountered
=
!
u
.
isMisPred
&&
!
u
.
b
rInfo
.
btbHitJal
&&
updateType
===
BTBtype
.
J
val
jalFirstEncountered
=
!
u
.
isMisPred
&&
!
u
.
b
puMeta
.
btbHitJal
&&
updateType
===
BTBtype
.
J
val
updateValid
=
io
.
update
.
valid
&&
(
u
.
isMisPred
||
jalFirstEncountered
)
val
updateValid
=
io
.
update
.
valid
&&
(
u
.
isMisPred
||
jalFirstEncountered
)
&&
!
u
.
isReplay
// Update btb
// Update btb
for
(
w
<-
0
until
BtbWays
)
{
for
(
w
<-
0
until
BtbWays
)
{
for
(
b
<-
0
until
BtbBanks
)
{
for
(
b
<-
0
until
BtbBanks
)
{
meta
(
w
)(
b
).
io
.
w
.
req
.
valid
:=
updateValid
&&
b
.
U
===
updateBankIdx
&&
w
.
U
===
updateWay
meta
(
w
)(
b
).
io
.
w
.
req
.
valid
:=
updateValid
&&
b
.
U
===
updateBankIdx
&&
w
.
U
===
updateWay
meta
(
w
)(
b
).
io
.
w
.
req
.
bits
.
setIdx
:=
updateRow
meta
(
w
)(
b
).
io
.
w
.
req
.
bits
.
setIdx
:=
updateRow
meta
(
w
)(
b
).
io
.
w
.
req
.
bits
.
data
:=
metaWrite
meta
(
w
)(
b
).
io
.
w
.
req
.
bits
.
data
:=
metaWrite
data
(
w
)(
b
).
io
.
w
.
req
.
valid
:=
updateValid
&&
b
.
U
===
updateBankIdx
&&
w
.
U
===
updateWay
data
(
w
)(
b
).
io
.
w
.
req
.
valid
:=
updateValid
&&
b
.
U
===
updateBankIdx
&&
w
.
U
===
updateWay
data
(
w
)(
b
).
io
.
w
.
req
.
bits
.
setIdx
:=
updateRow
data
(
w
)(
b
).
io
.
w
.
req
.
bits
.
setIdx
:=
updateRow
data
(
w
)(
b
).
io
.
w
.
req
.
bits
.
data
:=
dataWrite
data
(
w
)(
b
).
io
.
w
.
req
.
bits
.
data
:=
dataWrite
}
}
}
}
for
(
b
<-
0
to
1
)
{
for
(
b
<-
0
to
1
)
{
edata
(
b
).
io
.
w
.
req
.
valid
:=
updateValid
&&
new_extended
&&
b
.
U
===
updateEBank
edata
(
b
).
io
.
w
.
req
.
valid
:=
updateValid
&&
new_extended
&&
b
.
U
===
updateEBank
edata
(
b
).
io
.
w
.
req
.
bits
.
setIdx
:=
updateRow
edata
(
b
).
io
.
w
.
req
.
bits
.
setIdx
:=
updateRow
edata
(
b
).
io
.
w
.
req
.
bits
.
data
:=
u
.
target
edata
(
b
).
io
.
w
.
req
.
bits
.
data
:=
u
.
target
}
}
if
(
BPUDebug
&&
debug
)
{
if
(
BPUDebug
&&
debug
)
{
val
debug_verbose
=
true
val
debug_verbose
=
true
XSDebug
(
"isInNextRow: "
)
XSDebug
(
"isInNextRow: "
)
(
0
until
BtbBanks
).
foreach
(
i
=>
{
(
0
until
BtbBanks
).
foreach
(
i
=>
{
XSDebug
(
false
,
true
.
B
,
"%d "
,
if1_isInNextRow
(
i
))
XSDebug
(
false
,
true
.
B
,
"%d "
,
if1_isInNextRow
(
i
))
if
(
i
==
BtbBanks
-
1
)
{
XSDebug
(
false
,
true
.
B
,
"\n"
)
}
if
(
i
==
BtbBanks
-
1
)
{
XSDebug
(
false
,
true
.
B
,
"\n"
)
}
})
})
val
validLatch
=
RegNext
(
io
.
pc
.
valid
)
val
validLatch
=
RegNext
(
io
.
pc
.
valid
)
XSDebug
(
io
.
pc
.
valid
,
"read: pc=0x%x, baseBank=%d, realMask=%b\n"
,
if1_bankAlignedPC
,
if1_baseBank
,
if1_realMask
)
XSDebug
(
io
.
pc
.
valid
,
"read: pc=0x%x, baseBank=%d, realMask=%b\n"
,
if1_bankAlignedPC
,
if1_baseBank
,
if1_realMask
)
XSDebug
(
validLatch
,
"read_resp: pc=0x%x, readIdx=%d-------------------------------\n"
,
XSDebug
(
validLatch
,
"read_resp: pc=0x%x, readIdx=%d-------------------------------\n"
,
if2_pc
,
btbAddr
.
getIdx
(
if2_pc
))
if2_pc
,
btbAddr
.
getIdx
(
if2_pc
))
if
(
debug_verbose
)
{
if
(
debug_verbose
)
{
for
(
i
<-
0
until
BtbBanks
){
for
(
i
<-
0
until
BtbBanks
){
for
(
j
<-
0
until
BtbWays
)
{
for
(
j
<-
0
until
BtbWays
)
{
XSDebug
(
validLatch
,
"read_resp[w=%d][b=%d][r=%d] is valid(%d) mask(%d), tag=0x%x, offset=0x%x, type=%d, isExtend=%d, isRVC=%d\n"
,
XSDebug
(
validLatch
,
"read_resp[w=%d][b=%d][r=%d] is valid(%d) mask(%d), tag=0x%x, offset=0x%x, type=%d, isExtend=%d, isRVC=%d\n"
,
j
.
U
,
i
.
U
,
if2_realRow
(
i
),
if2_metaRead
(
j
)(
i
).
valid
,
if2_realMask
(
i
),
if2_metaRead
(
j
)(
i
).
tag
,
if2_dataRead
(
j
)(
i
).
offset
,
if2_metaRead
(
j
)(
i
).
btbType
,
if2_dataRead
(
j
)(
i
).
extended
,
if2_metaRead
(
j
)(
i
).
isRVC
)
j
.
U
,
i
.
U
,
if2_realRow
(
i
),
if2_metaRead
(
j
)(
i
).
valid
,
if2_realMask
(
i
),
if2_metaRead
(
j
)(
i
).
tag
,
if2_dataRead
(
j
)(
i
).
offset
,
if2_metaRead
(
j
)(
i
).
btbType
,
if2_dataRead
(
j
)(
i
).
extended
,
if2_metaRead
(
j
)(
i
).
isRVC
)
}
}
}
}
}
}
// e.g: baseBank == 5 => (5, 6,..., 15, 0, 1, 2, 3, 4)
// e.g: baseBank == 5 => (5, 6,..., 15, 0, 1, 2, 3, 4)
val
bankIdxInOrder
=
VecInit
((
0
until
BtbBanks
).
map
(
b
=>
(
if2_baseBank
+&
b
.
U
)(
log2Up
(
BtbBanks
)-
1
,
0
)))
val
bankIdxInOrder
=
VecInit
((
0
until
BtbBanks
).
map
(
b
=>
(
if2_baseBank
+&
b
.
U
)(
log2Up
(
BtbBanks
)-
1
,
0
)))
for
(
i
<-
0
until
BtbBanks
)
{
for
(
i
<-
0
until
BtbBanks
)
{
val
idx
=
bankIdxInOrder
(
i
)
val
idx
=
bankIdxInOrder
(
i
)
XSDebug
(
validLatch
&&
if2_bankHits
(
bankIdxInOrder
(
i
)),
"resp(%d): bank(%d) hits, tgt=%x, isRVC=%d, type=%d\n"
,
XSDebug
(
validLatch
&&
if2_bankHits
(
bankIdxInOrder
(
i
)),
"resp(%d): bank(%d) hits, tgt=%x, isRVC=%d, type=%d\n"
,
i
.
U
,
idx
,
io
.
resp
.
targets
(
i
),
io
.
resp
.
isRVC
(
i
),
io
.
resp
.
types
(
i
))
i
.
U
,
idx
,
io
.
resp
.
targets
(
i
),
io
.
resp
.
isRVC
(
i
),
io
.
resp
.
types
(
i
))
}
}
XSDebug
(
updateValid
,
"update_req: cycle=%d, pc=0x%x, target=0x%x, misPred=%d, offset=%x, extended=%d, way=%d, bank=%d, row=0x%x\n"
,
XSDebug
(
updateValid
,
"update_req: cycle=%d, pc=0x%x, target=0x%x, misPred=%d, offset=%x, extended=%d, way=%d, bank=%d, row=0x%x\n"
,
u
.
b
rInfo
.
debug_btb_cycle
,
u
.
pc
,
new_target
,
u
.
isMisPred
,
new_offset
,
new_extended
,
updateWay
,
updateBankIdx
,
updateRow
)
u
.
b
puMeta
.
debug_btb_cycle
,
u
.
pc
,
new_target
,
u
.
isMisPred
,
new_offset
,
new_extended
,
updateWay
,
updateBankIdx
,
updateRow
)
for
(
i
<-
0
until
BtbBanks
)
{
for
(
i
<-
0
until
BtbBanks
)
{
// Conflict when not hit and allocating a valid entry
// Conflict when not hit and allocating a valid entry
val
conflict
=
if2_metaRead
(
allocWays
(
i
))(
i
).
valid
&&
!
if2_bankHits
(
i
)
val
conflict
=
if2_metaRead
(
allocWays
(
i
))(
i
).
valid
&&
!
if2_bankHits
(
i
)
XSDebug
(
conflict
,
"bank(%d) is trying to allocate a valid way(%d)\n"
,
i
.
U
,
allocWays
(
i
))
XSDebug
(
conflict
,
"bank(%d) is trying to allocate a valid way(%d)\n"
,
i
.
U
,
allocWays
(
i
))
// There is another circumstance when a branch is on its way to update while another
// There is another circumstance when a branch is on its way to update while another
// branch chose the same way to udpate, then after the first branch is wrote in,
// branch chose the same way to udpate, then after the first branch is wrote in,
// the second branch will overwrite the first branch
// the second branch will overwrite the first branch
}
}
}
}
}
}
\ No newline at end of file
src/main/scala/xiangshan/frontend/Frontend.scala
浏览文件 @
fd7be884
...
@@ -27,8 +27,8 @@ class Frontend extends XSModule {
...
@@ -27,8 +27,8 @@ class Frontend extends XSModule {
//backend
//backend
ifu
.
io
.
redirect
<>
io
.
backend
.
redirect
ifu
.
io
.
redirect
<>
io
.
backend
.
redirect
ifu
.
io
.
inOrderBrInfo
<>
io
.
backend
.
inOrderBr
Info
ifu
.
io
.
cfiUpdateInfo
<>
io
.
backend
.
cfiUpdate
Info
ifu
.
io
.
outOfOrderBrInfo
<>
io
.
backend
.
outOfOrderBr
Info
// ifu.io.cfiUpdateInfo <> io.backend.cfiUpdate
Info
//icache
//icache
ifu
.
io
.
icacheResp
<>
icache
.
io
.
resp
ifu
.
io
.
icacheResp
<>
icache
.
io
.
resp
icache
.
io
.
req
<>
ifu
.
io
.
icacheReq
icache
.
io
.
req
<>
ifu
.
io
.
icacheReq
...
...
src/main/scala/xiangshan/frontend/IFU.scala
浏览文件 @
fd7be884
...
@@ -70,8 +70,8 @@ class IFUIO extends XSBundle
...
@@ -70,8 +70,8 @@ class IFUIO extends XSBundle
{
{
val
fetchPacket
=
DecoupledIO
(
new
FetchPacket
)
val
fetchPacket
=
DecoupledIO
(
new
FetchPacket
)
val
redirect
=
Flipped
(
ValidIO
(
UInt
(
VAddrBits
.
W
)))
val
redirect
=
Flipped
(
ValidIO
(
UInt
(
VAddrBits
.
W
)))
val
outOfOrderBrInfo
=
Flipped
(
ValidIO
(
new
Branch
UpdateInfo
))
// val cfiUpdateInfo = Flipped(ValidIO(new Cfi
UpdateInfo))
val
inOrderBrInfo
=
Flipped
(
ValidIO
(
new
Branch
UpdateInfo
))
val
cfiUpdateInfo
=
Flipped
(
ValidIO
(
new
Cfi
UpdateInfo
))
val
icacheReq
=
DecoupledIO
(
new
ICacheReq
)
val
icacheReq
=
DecoupledIO
(
new
ICacheReq
)
val
icacheResp
=
Flipped
(
DecoupledIO
(
new
ICacheResp
))
val
icacheResp
=
Flipped
(
DecoupledIO
(
new
ICacheResp
))
val
icacheFlush
=
Output
(
UInt
(
2.
W
))
val
icacheFlush
=
Output
(
UInt
(
2.
W
))
...
@@ -355,11 +355,11 @@ class IFU extends XSModule with HasIFUConst
...
@@ -355,11 +355,11 @@ class IFU extends XSModule with HasIFUConst
val
cfiUpdate
=
io
.
cfiUpdateInfo
when
(
io
.
outOfOrderBrInfo
.
valid
&&
io
.
outOfOrderBrInfo
.
bits
.
isMisPred
)
{
when
(
cfiUpdate
.
valid
&&
(
cfiUpdate
.
bits
.
isMisPred
||
cfiUpdate
.
bits
.
isReplay
)
)
{
val
b
=
io
.
outOfOrderBrInfo
.
bits
val
b
=
cfiUpdate
.
bits
val
oldGh
=
b
.
b
rInfo
.
hist
val
oldGh
=
b
.
b
puMeta
.
hist
val
sawNTBr
=
b
.
b
rInfo
.
sawNotTakenBranch
val
sawNTBr
=
b
.
b
puMeta
.
sawNotTakenBranch
val
isBr
=
b
.
pd
.
isBr
val
isBr
=
b
.
pd
.
isBr
val
taken
=
b
.
taken
val
taken
=
b
.
taken
val
updatedGh
=
oldGh
.
update
(
sawNTBr
,
isBr
&&
taken
)
val
updatedGh
=
oldGh
.
update
(
sawNTBr
,
isBr
&&
taken
)
...
@@ -398,11 +398,7 @@ class IFU extends XSModule with HasIFUConst
...
@@ -398,11 +398,7 @@ class IFU extends XSModule with HasIFUConst
io
.
icacheFlush
:=
Cat
(
if3_flush
,
if2_flush
)
io
.
icacheFlush
:=
Cat
(
if3_flush
,
if2_flush
)
val
inOrderBrHist
=
io
.
inOrderBrInfo
.
bits
.
brInfo
.
predHist
bpu
.
io
.
cfiUpdateInfo
<>
io
.
cfiUpdateInfo
bpu
.
io
.
inOrderBrInfo
.
valid
:=
io
.
inOrderBrInfo
.
valid
bpu
.
io
.
inOrderBrInfo
.
bits
:=
BranchUpdateInfoWithHist
(
io
.
inOrderBrInfo
.
bits
,
inOrderBrHist
.
asUInt
)
bpu
.
io
.
outOfOrderBrInfo
.
valid
:=
io
.
outOfOrderBrInfo
.
valid
bpu
.
io
.
outOfOrderBrInfo
.
bits
:=
BranchUpdateInfoWithHist
(
io
.
outOfOrderBrInfo
.
bits
,
inOrderBrHist
.
asUInt
)
// Dont care about hist
// bpu.io.flush := Cat(if4_flush, if3_flush, if2_flush)
// bpu.io.flush := Cat(if4_flush, if3_flush, if2_flush)
bpu
.
io
.
flush
:=
VecInit
(
if2_flush
,
if3_flush
,
if4_flush
)
bpu
.
io
.
flush
:=
VecInit
(
if2_flush
,
if3_flush
,
if4_flush
)
...
@@ -465,9 +461,9 @@ class IFU extends XSModule with HasIFUConst
...
@@ -465,9 +461,9 @@ class IFU extends XSModule with HasIFUConst
when
(
if4_bp
.
taken
)
{
when
(
if4_bp
.
taken
)
{
fetchPacketWire
.
pnpc
(
if4_bp
.
jmpIdx
)
:=
if4_bp
.
target
fetchPacketWire
.
pnpc
(
if4_bp
.
jmpIdx
)
:=
if4_bp
.
target
}
}
fetchPacketWire
.
b
rInfo
:=
bpu
.
io
.
branchInfo
fetchPacketWire
.
b
puMeta
:=
bpu
.
io
.
bpuMeta
(
0
until
PredictWidth
).
foreach
(
i
=>
fetchPacketWire
.
b
rInfo
(
i
).
hist
:=
final_gh
)
(
0
until
PredictWidth
).
foreach
(
i
=>
fetchPacketWire
.
b
puMeta
(
i
).
hist
:=
final_gh
)
(
0
until
PredictWidth
).
foreach
(
i
=>
fetchPacketWire
.
b
rInfo
(
i
).
predHist
:=
if4_predHist
.
asTypeOf
(
new
GlobalHistory
))
(
0
until
PredictWidth
).
foreach
(
i
=>
fetchPacketWire
.
b
puMeta
(
i
).
predHist
:=
if4_predHist
.
asTypeOf
(
new
GlobalHistory
))
fetchPacketWire
.
pd
:=
if4_pd
.
pd
fetchPacketWire
.
pd
:=
if4_pd
.
pd
fetchPacketWire
.
ipf
:=
if4_ipf
fetchPacketWire
.
ipf
:=
if4_ipf
fetchPacketWire
.
acf
:=
if4_acf
fetchPacketWire
.
acf
:=
if4_acf
...
...
src/main/scala/xiangshan/frontend/Ibuffer.scala
浏览文件 @
fd7be884
...
@@ -20,7 +20,7 @@ class Ibuffer extends XSModule {
...
@@ -20,7 +20,7 @@ class Ibuffer extends XSModule {
val
inst
=
UInt
(
32.
W
)
val
inst
=
UInt
(
32.
W
)
val
pc
=
UInt
(
VAddrBits
.
W
)
val
pc
=
UInt
(
VAddrBits
.
W
)
val
pnpc
=
UInt
(
VAddrBits
.
W
)
val
pnpc
=
UInt
(
VAddrBits
.
W
)
val
brInfo
=
new
B
ranchInfo
val
brInfo
=
new
B
puMeta
val
pd
=
new
PreDecodeInfo
val
pd
=
new
PreDecodeInfo
val
ipf
=
Bool
()
val
ipf
=
Bool
()
val
acf
=
Bool
()
val
acf
=
Bool
()
...
@@ -63,7 +63,7 @@ class Ibuffer extends XSModule {
...
@@ -63,7 +63,7 @@ class Ibuffer extends XSModule {
inWire
.
inst
:=
io
.
in
.
bits
.
instrs
(
i
)
inWire
.
inst
:=
io
.
in
.
bits
.
instrs
(
i
)
inWire
.
pc
:=
io
.
in
.
bits
.
pc
(
i
)
inWire
.
pc
:=
io
.
in
.
bits
.
pc
(
i
)
inWire
.
pnpc
:=
io
.
in
.
bits
.
pnpc
(
i
)
inWire
.
pnpc
:=
io
.
in
.
bits
.
pnpc
(
i
)
inWire
.
brInfo
:=
io
.
in
.
bits
.
b
rInfo
(
i
)
inWire
.
brInfo
:=
io
.
in
.
bits
.
b
puMeta
(
i
)
inWire
.
pd
:=
io
.
in
.
bits
.
pd
(
i
)
inWire
.
pd
:=
io
.
in
.
bits
.
pd
(
i
)
inWire
.
ipf
:=
io
.
in
.
bits
.
ipf
inWire
.
ipf
:=
io
.
in
.
bits
.
ipf
inWire
.
acf
:=
io
.
in
.
bits
.
acf
inWire
.
acf
:=
io
.
in
.
bits
.
acf
...
@@ -98,7 +98,7 @@ class Ibuffer extends XSModule {
...
@@ -98,7 +98,7 @@ class Ibuffer extends XSModule {
io
.
out
(
i
).
bits
.
brUpdate
.
pc
:=
outWire
.
pc
io
.
out
(
i
).
bits
.
brUpdate
.
pc
:=
outWire
.
pc
io
.
out
(
i
).
bits
.
brUpdate
.
pnpc
:=
outWire
.
pnpc
io
.
out
(
i
).
bits
.
brUpdate
.
pnpc
:=
outWire
.
pnpc
io
.
out
(
i
).
bits
.
brUpdate
.
pd
:=
outWire
.
pd
io
.
out
(
i
).
bits
.
brUpdate
.
pd
:=
outWire
.
pd
io
.
out
(
i
).
bits
.
brUpdate
.
b
rInfo
:=
outWire
.
brInfo
io
.
out
(
i
).
bits
.
brUpdate
.
b
puMeta
:=
outWire
.
brInfo
io
.
out
(
i
).
bits
.
crossPageIPFFix
:=
outWire
.
crossPageIPFFix
io
.
out
(
i
).
bits
.
crossPageIPFFix
:=
outWire
.
crossPageIPFFix
}
}
head_ptr
:=
head_ptr
+
io
.
out
.
map
(
_
.
fire
).
fold
(
0.
U
(
log2Up
(
DecodeWidth
).
W
))(
_
+
_
)
head_ptr
:=
head_ptr
+
io
.
out
.
map
(
_
.
fire
).
fold
(
0.
U
(
log2Up
(
DecodeWidth
).
W
))(
_
+
_
)
...
...
src/main/scala/xiangshan/frontend/LoopPredictor.scala
浏览文件 @
fd7be884
...
@@ -309,13 +309,13 @@ class LoopPredictor extends BasePredictor with LTBParams {
...
@@ -309,13 +309,13 @@ class LoopPredictor extends BasePredictor with LTBParams {
ltbs
(
i
).
io
.
req
.
idx
:=
Mux
(
isInNextRow
(
i
),
baseRow
+
1.
U
,
baseRow
)
ltbs
(
i
).
io
.
req
.
idx
:=
Mux
(
isInNextRow
(
i
),
baseRow
+
1.
U
,
baseRow
)
ltbs
(
i
).
io
.
req
.
tag
:=
realTags
(
i
)
ltbs
(
i
).
io
.
req
.
tag
:=
realTags
(
i
)
// ltbs(i).io.outMask := outMask(i)
// ltbs(i).io.outMask := outMask(i)
ltbs
(
i
).
io
.
update
.
valid
:=
i
.
U
===
ltbAddr
.
getBank
(
io
.
update
.
bits
.
ui
.
pc
)
&&
io
.
update
.
valid
&&
io
.
update
.
bits
.
ui
.
pd
.
isBr
ltbs
(
i
).
io
.
update
.
valid
:=
i
.
U
===
ltbAddr
.
getBank
(
io
.
update
.
bits
.
pc
)
&&
io
.
update
.
valid
&&
io
.
update
.
bits
.
pd
.
isBr
ltbs
(
i
).
io
.
update
.
bits
.
misPred
:=
io
.
update
.
bits
.
ui
.
isMisPred
ltbs
(
i
).
io
.
update
.
bits
.
misPred
:=
io
.
update
.
bits
.
isMisPred
ltbs
(
i
).
io
.
update
.
bits
.
pc
:=
io
.
update
.
bits
.
ui
.
pc
ltbs
(
i
).
io
.
update
.
bits
.
pc
:=
io
.
update
.
bits
.
pc
ltbs
(
i
).
io
.
update
.
bits
.
meta
:=
io
.
update
.
bits
.
ui
.
brInfo
.
specCnt
ltbs
(
i
).
io
.
update
.
bits
.
meta
:=
io
.
update
.
bits
.
bpuMeta
.
specCnt
ltbs
(
i
).
io
.
update
.
bits
.
taken
:=
io
.
update
.
bits
.
ui
.
taken
ltbs
(
i
).
io
.
update
.
bits
.
taken
:=
io
.
update
.
bits
.
taken
ltbs
(
i
).
io
.
update
.
bits
.
brTag
:=
io
.
update
.
bits
.
ui
.
brTag
ltbs
(
i
).
io
.
update
.
bits
.
brTag
:=
io
.
update
.
bits
.
brTag
ltbs
(
i
).
io
.
repair
:=
i
.
U
=/=
ltbAddr
.
getBank
(
io
.
update
.
bits
.
ui
.
pc
)
&&
io
.
update
.
valid
&&
io
.
update
.
bits
.
ui
.
isMisPred
ltbs
(
i
).
io
.
repair
:=
i
.
U
=/=
ltbAddr
.
getBank
(
io
.
update
.
bits
.
pc
)
&&
io
.
update
.
valid
&&
io
.
update
.
bits
.
isMisPred
}
}
val
ltbResps
=
VecInit
((
0
until
PredictWidth
).
map
(
i
=>
ltbs
(
i
).
io
.
resp
))
val
ltbResps
=
VecInit
((
0
until
PredictWidth
).
map
(
i
=>
ltbs
(
i
).
io
.
resp
))
...
...
src/main/scala/xiangshan/frontend/RAS.scala
浏览文件 @
fd7be884
...
@@ -28,9 +28,9 @@ class RAS extends BasePredictor
...
@@ -28,9 +28,9 @@ class RAS extends BasePredictor
val
callIdx
=
Flipped
(
ValidIO
(
UInt
(
log2Ceil
(
PredictWidth
).
W
)))
val
callIdx
=
Flipped
(
ValidIO
(
UInt
(
log2Ceil
(
PredictWidth
).
W
)))
val
isRVC
=
Input
(
Bool
())
val
isRVC
=
Input
(
Bool
())
val
isLastHalfRVI
=
Input
(
Bool
())
val
isLastHalfRVI
=
Input
(
Bool
())
val
recover
=
Flipped
(
ValidIO
(
new
Branch
UpdateInfo
))
val
recover
=
Flipped
(
ValidIO
(
new
Cfi
UpdateInfo
))
val
out
=
ValidIO
(
new
RASResp
)
val
out
=
ValidIO
(
new
RASResp
)
val
branchInfo
=
Output
(
new
RASBranchInfo
)
val
meta
=
Output
(
new
RASBranchInfo
)
}
}
class
RASEntry
()
extends
XSBundle
{
class
RASEntry
()
extends
XSBundle
{
...
@@ -187,7 +187,7 @@ class RAS extends BasePredictor
...
@@ -187,7 +187,7 @@ class RAS extends BasePredictor
// TODO: back-up stack for ras
// TODO: back-up stack for ras
// use checkpoint to recover RAS
// use checkpoint to recover RAS
val
copy_valid
=
io
.
recover
.
valid
&&
io
.
recover
.
bits
.
isMisPred
val
copy_valid
=
io
.
recover
.
valid
&&
(
io
.
recover
.
bits
.
isMisPred
||
io
.
recover
.
bits
.
isReplay
)
val
copy_next
=
RegNext
(
copy_valid
)
val
copy_next
=
RegNext
(
copy_valid
)
spec_ras
.
copy_valid
:=
copy_next
spec_ras
.
copy_valid
:=
copy_next
spec_ras
.
copy_in_mem
:=
commit_ras
.
copy_out_mem
spec_ras
.
copy_in_mem
:=
commit_ras
.
copy_out_mem
...
@@ -197,9 +197,9 @@ class RAS extends BasePredictor
...
@@ -197,9 +197,9 @@ class RAS extends BasePredictor
commit_ras
.
copy_in_sp
:=
DontCare
commit_ras
.
copy_in_sp
:=
DontCare
//no need to pass the ras branchInfo
//no need to pass the ras branchInfo
io
.
branchInfo
.
rasSp
:=
DontCare
io
.
meta
.
rasSp
:=
DontCare
io
.
branchInfo
.
rasTopCtr
:=
DontCare
io
.
meta
.
rasTopCtr
:=
DontCare
io
.
branchInfo
.
rasToqAddr
:=
DontCare
io
.
meta
.
rasToqAddr
:=
DontCare
if
(
BPUDebug
&&
debug
)
{
if
(
BPUDebug
&&
debug
)
{
val
spec_debug
=
spec
.
debugIO
val
spec_debug
=
spec
.
debugIO
...
...
src/main/scala/xiangshan/frontend/Tage.scala
浏览文件 @
fd7be884
...
@@ -448,12 +448,12 @@ class Tage extends BaseTage {
...
@@ -448,12 +448,12 @@ class Tage extends BaseTage {
val
debug_hist_s2
=
RegEnable
(
io
.
hist
,
enable
=
io
.
pc
.
valid
)
val
debug_hist_s2
=
RegEnable
(
io
.
hist
,
enable
=
io
.
pc
.
valid
)
val
debug_hist_s3
=
RegEnable
(
debug_hist_s2
,
enable
=
io
.
s3Fire
)
val
debug_hist_s3
=
RegEnable
(
debug_hist_s2
,
enable
=
io
.
s3Fire
)
val
u
=
io
.
update
.
bits
.
ui
val
u
=
io
.
update
.
bits
val
updateValid
=
io
.
update
.
valid
val
updateValid
=
io
.
update
.
valid
&&
!
io
.
update
.
bits
.
isReplay
val
updateHist
=
io
.
update
.
bits
.
his
t
val
updateHist
=
u
.
bpuMeta
.
predHist
.
asUIn
t
val
updateIsBr
=
u
.
pd
.
isBr
val
updateIsBr
=
u
.
pd
.
isBr
val
updateMeta
=
u
.
b
rInfo
.
tageMeta
val
updateMeta
=
u
.
b
puMeta
.
tageMeta
val
updateMisPred
=
u
.
isMisPred
&&
updateIsBr
val
updateMisPred
=
u
.
isMisPred
&&
updateIsBr
val
updateMask
=
WireInit
(
0.
U
.
asTypeOf
(
Vec
(
TageNTables
,
Vec
(
TageBanks
,
Bool
()))))
val
updateMask
=
WireInit
(
0.
U
.
asTypeOf
(
Vec
(
TageNTables
,
Vec
(
TageBanks
,
Bool
()))))
...
@@ -475,7 +475,7 @@ class Tage extends BaseTage {
...
@@ -475,7 +475,7 @@ class Tage extends BaseTage {
scUpdateTaken
:=
DontCare
scUpdateTaken
:=
DontCare
scUpdateOldCtrs
:=
DontCare
scUpdateOldCtrs
:=
DontCare
val
updateSCMeta
=
u
.
b
rInfo
.
tageMeta
.
scMeta
val
updateSCMeta
=
u
.
b
puMeta
.
tageMeta
.
scMeta
val
updateTageMisPred
=
updateMeta
.
taken
=/=
u
.
taken
&&
updateIsBr
val
updateTageMisPred
=
updateMeta
.
taken
=/=
u
.
taken
&&
updateIsBr
val
updateBank
=
u
.
pc
(
log2Ceil
(
TageBanks
),
1
)
val
updateBank
=
u
.
pc
(
log2Ceil
(
TageBanks
),
1
)
...
@@ -641,7 +641,7 @@ class Tage extends BaseTage {
...
@@ -641,7 +641,7 @@ class Tage extends BaseTage {
// use fetch pc instead of instruction pc
// use fetch pc instead of instruction pc
tables
(
i
).
io
.
update
.
pc
:=
u
.
pc
tables
(
i
).
io
.
update
.
pc
:=
u
.
pc
tables
(
i
).
io
.
update
.
hist
:=
updateHist
tables
(
i
).
io
.
update
.
hist
:=
updateHist
tables
(
i
).
io
.
update
.
fetchIdx
:=
u
.
b
rInfo
.
fetchIdx
tables
(
i
).
io
.
update
.
fetchIdx
:=
u
.
b
puMeta
.
fetchIdx
}
}
for
(
i
<-
0
until
SCNTables
)
{
for
(
i
<-
0
until
SCNTables
)
{
...
@@ -651,14 +651,14 @@ class Tage extends BaseTage {
...
@@ -651,14 +651,14 @@ class Tage extends BaseTage {
scTables
(
i
).
io
.
update
.
oldCtr
:=
scUpdateOldCtrs
(
i
)
scTables
(
i
).
io
.
update
.
oldCtr
:=
scUpdateOldCtrs
(
i
)
scTables
(
i
).
io
.
update
.
pc
:=
u
.
pc
scTables
(
i
).
io
.
update
.
pc
:=
u
.
pc
scTables
(
i
).
io
.
update
.
hist
:=
updateHist
scTables
(
i
).
io
.
update
.
hist
:=
updateHist
scTables
(
i
).
io
.
update
.
fetchIdx
:=
u
.
b
rInfo
.
fetchIdx
scTables
(
i
).
io
.
update
.
fetchIdx
:=
u
.
b
puMeta
.
fetchIdx
}
}
if
(
BPUDebug
&&
debug
)
{
if
(
BPUDebug
&&
debug
)
{
val
m
=
updateMeta
val
m
=
updateMeta
val
bri
=
u
.
b
rInfo
val
bri
=
u
.
b
puMeta
XSDebug
(
io
.
pc
.
valid
,
"req: pc=0x%x, hist=%x\n"
,
io
.
pc
.
bits
,
io
.
hist
)
XSDebug
(
io
.
pc
.
valid
,
"req: pc=0x%x, hist=%x\n"
,
io
.
pc
.
bits
,
io
.
hist
)
XSDebug
(
io
.
s3Fire
,
"s3Fire:%d, resp: pc=%x, hist=%x\n"
,
io
.
s3Fire
,
debug_pc_s2
,
debug_hist_s2
)
XSDebug
(
io
.
s3Fire
,
"s3Fire:%d, resp: pc=%x, hist=%x\n"
,
io
.
s3Fire
,
debug_pc_s2
,
debug_hist_s2
)
XSDebug
(
RegNext
(
io
.
s3Fire
),
"s3FireOnLastCycle: resp: pc=%x, hist=%x, hits=%b, takens=%b\n"
,
XSDebug
(
RegNext
(
io
.
s3Fire
),
"s3FireOnLastCycle: resp: pc=%x, hist=%x, hits=%b, takens=%b\n"
,
...
...
src/main/scala/xiangshan/frontend/uBTB.scala
浏览文件 @
fd7be884
...
@@ -43,12 +43,12 @@ class MicroBTB extends BasePredictor
...
@@ -43,12 +43,12 @@ class MicroBTB extends BasePredictor
class
MicroBTBIO
extends
DefaultBasePredictorIO
class
MicroBTBIO
extends
DefaultBasePredictorIO
{
{
val
out
=
Output
(
new
MicroBTBResp
)
//
val
out
=
Output
(
new
MicroBTBResp
)
//
val
uBTB
BranchInfo
=
Output
(
new
MicroBTBBranchInfo
)
val
uBTB
Meta
=
Output
(
new
MicroBTBBranchInfo
)
}
}
override
val
debug
=
true
override
val
debug
=
true
override
val
io
=
IO
(
new
MicroBTBIO
)
override
val
io
=
IO
(
new
MicroBTBIO
)
io
.
uBTB
BranchInfo
<>
out_ubtb_br_info
io
.
uBTB
Meta
<>
out_ubtb_br_info
def
getTag
(
pc
:
UInt
)
=
(
pc
>>
untaggedBits
)(
tagSize
-
1
,
0
)
def
getTag
(
pc
:
UInt
)
=
(
pc
>>
untaggedBits
)(
tagSize
-
1
,
0
)
def
getBank
(
pc
:
UInt
)
=
pc
(
log2Ceil
(
PredictWidth
)
,
1
)
def
getBank
(
pc
:
UInt
)
=
pc
(
log2Ceil
(
PredictWidth
)
,
1
)
...
@@ -251,13 +251,13 @@ class MicroBTB extends BasePredictor
...
@@ -251,13 +251,13 @@ class MicroBTB extends BasePredictor
//uBTB update
//uBTB update
//backend should send fetch pc to update
//backend should send fetch pc to update
val
u
=
io
.
update
.
bits
.
ui
val
u
=
io
.
update
.
bits
val
update_br_pc
=
u
.
pc
val
update_br_pc
=
u
.
pc
val
update_br_idx
=
u
.
fetchIdx
val
update_br_idx
=
u
.
fetchIdx
val
update_br_offset
=
(
update_br_idx
<<
1
).
asUInt
()
val
update_br_offset
=
(
update_br_idx
<<
1
).
asUInt
()
val
update_fetch_pc
=
update_br_pc
-
update_br_offset
val
update_fetch_pc
=
update_br_pc
-
update_br_offset
val
update_write_way
=
u
.
b
rInfo
.
ubtbWriteWay
val
update_write_way
=
u
.
b
puMeta
.
ubtbWriteWay
val
update_hits
=
u
.
b
rInfo
.
ubtbHits
val
update_hits
=
u
.
b
puMeta
.
ubtbHits
val
update_taken
=
u
.
taken
val
update_taken
=
u
.
taken
val
update_bank
=
getBank
(
update_br_pc
)
val
update_bank
=
getBank
(
update_br_pc
)
...
@@ -268,9 +268,9 @@ class MicroBTB extends BasePredictor
...
@@ -268,9 +268,9 @@ class MicroBTB extends BasePredictor
val
update_is_BR_or_JAL
=
(
u
.
pd
.
brType
===
BrType
.
branch
)
||
(
u
.
pd
.
brType
===
BrType
.
jal
)
val
update_is_BR_or_JAL
=
(
u
.
pd
.
brType
===
BrType
.
branch
)
||
(
u
.
pd
.
brType
===
BrType
.
jal
)
val
jalFirstEncountered
=
!
u
.
isMisPred
&&
!
u
.
b
rInfo
.
btbHitJal
&&
(
u
.
pd
.
brType
===
BrType
.
jal
)
val
jalFirstEncountered
=
!
u
.
isMisPred
&&
!
u
.
b
puMeta
.
btbHitJal
&&
(
u
.
pd
.
brType
===
BrType
.
jal
)
val
entry_write_valid
=
io
.
update
.
valid
&&
(
u
.
isMisPred
||
jalFirstEncountered
)
//io.update.valid //&& update_is_BR_or_JAL
val
entry_write_valid
=
io
.
update
.
valid
&&
(
u
.
isMisPred
||
jalFirstEncountered
)
&&
!
u
.
isReplay
//io.update.valid //&& update_is_BR_or_JAL
val
meta_write_valid
=
io
.
update
.
valid
&&
(
u
.
isMisPred
||
jalFirstEncountered
)
//io.update.valid //&& update_is_BR_or_JAL
val
meta_write_valid
=
io
.
update
.
valid
&&
(
u
.
isMisPred
||
jalFirstEncountered
)
&&
!
u
.
isReplay
//io.update.valid //&& update_is_BR_or_JAL
//write btb target when miss prediction
//write btb target when miss prediction
// when(entry_write_valid)
// when(entry_write_valid)
// {
// {
...
...
src/test/scala/xiangshan/frontend/uBTBTest.scala
浏览文件 @
fd7be884
...
@@ -17,14 +17,14 @@ with HasPartialDecoupledDriver {
...
@@ -17,14 +17,14 @@ with HasPartialDecoupledDriver {
test
(
new
MicroBTB
)
{
c
=>
test
(
new
MicroBTB
)
{
c
=>
def
genUpdateReq
(
pc
:
Long
,
target
:
Long
,
taken
:
Boolean
,
fetchIdx
:
Int
,
isMiss
:
Boolean
,
write_way
:
Int
,
hit
:
Boolean
)
=
{
def
genUpdateReq
(
pc
:
Long
,
target
:
Long
,
taken
:
Boolean
,
fetchIdx
:
Int
,
isMiss
:
Boolean
,
write_way
:
Int
,
hit
:
Boolean
)
=
{
c
.
io
.
update
.
valid
.
poke
(
true
.
B
)
c
.
io
.
update
.
valid
.
poke
(
true
.
B
)
c
.
io
.
update
.
bits
.
ui
.
pc
.
poke
(
pc
.
U
)
c
.
io
.
update
.
bits
.
pc
.
poke
(
pc
.
U
)
c
.
io
.
update
.
bits
.
ui
.
target
.
poke
(
target
.
U
)
c
.
io
.
update
.
bits
.
target
.
poke
(
target
.
U
)
c
.
io
.
update
.
bits
.
ui
.
taken
.
poke
(
taken
.
B
)
c
.
io
.
update
.
bits
.
taken
.
poke
(
taken
.
B
)
c
.
io
.
update
.
bits
.
ui
.
fetchIdx
.
poke
(
fetchIdx
.
U
)
c
.
io
.
update
.
bits
.
fetchIdx
.
poke
(
fetchIdx
.
U
)
c
.
io
.
update
.
bits
.
ui
.
isMisPred
.
poke
(
isMiss
.
B
)
c
.
io
.
update
.
bits
.
isMisPred
.
poke
(
isMiss
.
B
)
c
.
io
.
update
.
bits
.
ui
.
brInfo
.
ubtbWriteWay
.
poke
(
write_way
.
U
)
c
.
io
.
update
.
bits
.
bpuMeta
.
ubtbWriteWay
.
poke
(
write_way
.
U
)
c
.
io
.
update
.
bits
.
ui
.
brInfo
.
ubtbHits
.
poke
(
hit
.
B
)
c
.
io
.
update
.
bits
.
bpuMeta
.
ubtbHits
.
poke
(
hit
.
B
)
c
.
io
.
update
.
bits
.
ui
.
pd
.
brType
.
poke
(
BrType
.
branch
)
c
.
io
.
update
.
bits
.
pd
.
brType
.
poke
(
BrType
.
branch
)
}
}
def
genReadReq
(
fetchpc
:
Long
){
def
genReadReq
(
fetchpc
:
Long
){
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录