Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
OpenXiangShan
XiangShan
提交
78105e83
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,发现更多精彩内容 >>
提交
78105e83
编写于
11月 04, 2020
作者:
Z
zoujr
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
LoopBuffer: Separate the LoopBuffer and the IBuffer
上级
da17840b
变更
7
展开全部
隐藏空白更改
内联
并排
Showing
7 changed file
with
711 addition
and
409 deletion
+711
-409
src/main/scala/xiangshan/backend/fu/CSR.scala
src/main/scala/xiangshan/backend/fu/CSR.scala
+4
-1
src/main/scala/xiangshan/frontend/Frontend.scala
src/main/scala/xiangshan/frontend/Frontend.scala
+2
-10
src/main/scala/xiangshan/frontend/IFU.scala
src/main/scala/xiangshan/frontend/IFU.scala
+46
-35
src/main/scala/xiangshan/frontend/Ibuffer.scala
src/main/scala/xiangshan/frontend/Ibuffer.scala
+10
-4
src/main/scala/xiangshan/frontend/LoopBuffer.scala
src/main/scala/xiangshan/frontend/LoopBuffer.scala
+393
-358
src/main/scala/xiangshan/frontend/NewLoopBuffer.scala
src/main/scala/xiangshan/frontend/NewLoopBuffer.scala
+252
-0
src/test/scala/xiangshan/testutils/AddSinks.scala
src/test/scala/xiangshan/testutils/AddSinks.scala
+4
-1
未找到文件。
src/main/scala/xiangshan/backend/fu/CSR.scala
浏览文件 @
78105e83
...
...
@@ -830,7 +830,10 @@ class CSR extends FunctionUnit(csrCfg) with HasCSRConst{
"ICacheReq"
->
(
0xb28
,
"perfCntIcacheReqCnt"
),
"ICacheMiss"
->
(
0xb29
,
"perfCntIcacheMissCnt"
),
"FetchFromICache"
->
(
0xb2a
,
"CntFetchFromICache"
),
"FetchFromLoopBuffer"
->
(
0xb2b
,
"CntFetchFromLoopBuffer"
)
"FetchFromLoopBuffer"
->
(
0xb2b
,
"CntFetchFromLoopBuffer"
),
"ExitLoop1"
->
(
0xb2c
,
"CntExitLoop1"
),
"ExitLoop2"
->
(
0xb2d
,
"CntExitLoop2"
),
"ExitLoop3"
->
(
0xb2e
,
"CntExitLoop3"
)
// "Custom1" -> (0xb1b, "Custom1" ),
// "Custom2" -> (0xb1c, "Custom2" ),
// "Custom3" -> (0xb1d, "Custom3" ),
...
...
src/main/scala/xiangshan/frontend/Frontend.scala
浏览文件 @
78105e83
...
...
@@ -18,8 +18,7 @@ class Frontend extends XSModule {
})
val
ifu
=
Module
(
new
IFU
)
val
ibuffer
=
if
(
EnableLB
)
Module
(
new
LoopBuffer
)
else
Module
(
new
Ibuffer
)
// val ibuffer = Module(new LoopBuffer)
val
ibuffer
=
Module
(
new
Ibuffer
)
val
needFlush
=
io
.
backend
.
redirect
.
valid
...
...
@@ -41,16 +40,9 @@ class Frontend extends XSModule {
//ibuffer
ibuffer
.
io
.
in
<>
ifu
.
io
.
fetchPacket
ibuffer
.
io
.
flush
:=
needFlush
ifu
.
io
.
loopBufPar
<>
ibuffer
.
io
.
loopBufPar
io
.
backend
.
cfVec
<>
ibuffer
.
io
.
out
for
(
out
<-
ibuffer
.
io
.
out
){
XSInfo
(
out
.
fire
(),
p
"inst:${Hexadecimal(out.bits.instr)} pc:${Hexadecimal(out.bits.pc)}\n"
)
}
// for(out <- ibuffer.io.out){
// XSInfo(out.fire(),
// p"inst:${Hexadecimal(out.bits.instr)} pc:${Hexadecimal(out.bits.pc)}\n"
...
...
@@ -58,4 +50,4 @@ class Frontend extends XSModule {
// }
}
}
\ No newline at end of file
src/main/scala/xiangshan/frontend/IFU.scala
浏览文件 @
78105e83
...
...
@@ -40,7 +40,7 @@ class IFUIO extends XSBundle
val
icacheReq
=
DecoupledIO
(
new
ICacheReq
)
val
icacheResp
=
Flipped
(
DecoupledIO
(
new
ICacheResp
))
val
icacheFlush
=
Output
(
UInt
(
2.
W
))
val
loopBufPar
=
Flipped
(
new
LoopBufferParameters
)
//
val loopBufPar = Flipped(new LoopBufferParameters)
}
class
IFU
extends
XSModule
with
HasIFUConst
...
...
@@ -48,22 +48,27 @@ class IFU extends XSModule with HasIFUConst
val
io
=
IO
(
new
IFUIO
)
val
bpu
=
BPU
(
EnableBPU
)
val
pd
=
Module
(
new
PreDecode
)
val
loopBuffer
=
Module
(
new
NewLoopBuffer
)
val
if2_redirect
,
if3_redirect
,
if4_redirect
=
WireInit
(
false
.
B
)
val
if1_flush
,
if2_flush
,
if3_flush
,
if4_flush
=
WireInit
(
false
.
B
)
val
icacheResp
=
WireInit
(
Mux
(
io
.
loopBufPar
.
inLoop
,
io
.
loopBufPar
.
LBResp
,
io
.
icacheResp
.
bits
))
val
loopBufPar
=
loopBuffer
.
io
.
loopBufPar
val
inLoop
=
WireInit
(
loopBuffer
.
io
.
out
.
valid
)
val
icacheResp
=
WireInit
(
Mux
(
inLoop
,
loopBuffer
.
io
.
out
.
bits
,
io
.
icacheResp
.
bits
))
if4_flush
:=
io
.
redirect
.
valid
||
io
.
loopBufPar
.
LBredirect
.
valid
if4_flush
:=
io
.
redirect
.
valid
||
loopBufPar
.
LBredirect
.
valid
if3_flush
:=
if4_flush
||
if4_redirect
if2_flush
:=
if3_flush
||
if3_redirect
if1_flush
:=
if2_flush
||
if2_redirect
loopBuffer
.
io
.
flush
:=
io
.
redirect
.
valid
//********************** IF1 ****************************//
val
if1_valid
=
!
reset
.
asBool
&&
GTimer
()
>
500.
U
val
if1_npc
=
WireInit
(
0.
U
(
VAddrBits
.
W
))
val
if2_ready
=
WireInit
(
false
.
B
)
val
if1_fire
=
if1_valid
&&
(
if2_ready
||
if1_flush
)
&&
(
i
o
.
loopBufPar
.
i
nLoop
||
io
.
icacheReq
.
ready
)
val
if1_fire
=
if1_valid
&&
(
if2_ready
||
if1_flush
)
&&
(
inLoop
||
io
.
icacheReq
.
ready
)
val
if1_histPtr
,
if2_histPtr
,
if3_histPtr
,
if4_histPtr
=
Wire
(
UInt
(
log2Up
(
ExtHistoryLength
).
W
))
...
...
@@ -133,7 +138,7 @@ class IFU extends XSModule with HasIFUConst
//********************** IF3 ****************************//
val
if3_valid
=
RegEnable
(
next
=
if2_valid
,
init
=
false
.
B
,
enable
=
if2_fire
)
val
if4_ready
=
WireInit
(
false
.
B
)
val
if3_fire
=
if3_valid
&&
if4_ready
&&
(
i
o
.
loopBufPar
.
i
nLoop
||
io
.
icacheResp
.
valid
)
&&
!
if3_flush
val
if3_fire
=
if3_valid
&&
if4_ready
&&
(
inLoop
||
io
.
icacheResp
.
valid
)
&&
!
if3_flush
val
if3_pc
=
RegEnable
(
if2_pc
,
if2_fire
)
val
if3_GHInfo
=
RegEnable
(
if2_realGHInfo
,
if2_fire
)
val
if3_predHistPtr
=
RegEnable
(
if2_predHistPtr
,
enable
=
if2_fire
)
...
...
@@ -345,15 +350,15 @@ class IFU extends XSModule with HasIFUConst
}
}
when
(
io
.
loopBufPar
.
LBredirect
.
valid
)
{
if1_npc
:=
io
.
loopBufPar
.
LBredirect
.
bits
when
(
loopBufPar
.
LBredirect
.
valid
)
{
if1_npc
:=
loopBufPar
.
LBredirect
.
bits
}
when
(
io
.
redirect
.
valid
)
{
if1_npc
:=
io
.
redirect
.
bits
.
target
}
when
(
i
o
.
loopBufPar
.
i
nLoop
)
{
when
(
inLoop
)
{
io
.
icacheReq
.
valid
:=
if2_flush
}.
otherwise
{
io
.
icacheReq
.
valid
:=
if1_valid
&&
if2_ready
...
...
@@ -373,8 +378,7 @@ class IFU extends XSModule with HasIFUConst
// io.loopBufPar.LBReq := snpc(if4_pc)
// XSDebug(p"snpc(if4_pc)=${Hexadecimal(snpc(if4_pc))}\n")
// }
io
.
loopBufPar
.
LBReq
:=
if3_pc
io
.
loopBufPar
.
tgtpc
:=
if4_bp
.
target
loopBufPar
.
fetchReq
:=
if3_pc
io
.
icacheReq
.
bits
.
mask
:=
mask
(
if1_npc
)
...
...
@@ -389,7 +393,7 @@ class IFU extends XSModule with HasIFUConst
// bpu.io.flush := Cat(if4_flush, if3_flush, if2_flush)
bpu
.
io
.
flush
:=
VecInit
(
if2_flush
,
if3_flush
,
if4_flush
)
bpu
.
io
.
cacheValid
:=
(
i
o
.
loopBufPar
.
i
nLoop
||
io
.
icacheResp
.
valid
)
bpu
.
io
.
cacheValid
:=
(
inLoop
||
io
.
icacheResp
.
valid
)
bpu
.
io
.
in
.
valid
:=
if1_fire
bpu
.
io
.
in
.
bits
.
pc
:=
if1_npc
bpu
.
io
.
in
.
bits
.
hist
:=
hist
.
asUInt
...
...
@@ -404,16 +408,15 @@ class IFU extends XSModule with HasIFUConst
bpu
.
io
.
predecode
.
bits
.
isFetchpcEqualFirstpc
:=
if4_pc
===
if4_pd
.
pc
(
0
)
bpu
.
io
.
branchInfo
.
ready
:=
if4_fire
when
(
io
.
loopBufPar
.
inLoop
)
{
pd
.
io
.
in
:=
io
.
loopBufPar
.
LBResp
pd
.
io
.
in
.
mask
:=
io
.
loopBufPar
.
LBResp
.
mask
&
mask
(
io
.
loopBufPar
.
LBResp
.
pc
)
XSDebug
(
"Fetch from LB\n"
)
XSDebug
(
p
"pc=${Hexadecimal(io.loopBufPar.LBResp.pc)}\n"
)
XSDebug
(
p
"data=${Hexadecimal(io.loopBufPar.LBResp.data)}\n"
)
XSDebug
(
p
"mask=${Hexadecimal(io.loopBufPar.LBResp.mask)}\n"
)
}.
otherwise
{
pd
.
io
.
in
:=
icacheResp
pd
.
io
.
in
:=
icacheResp
when
(
inLoop
)
{
pd
.
io
.
in
.
mask
:=
loopBuffer
.
io
.
out
.
bits
.
mask
&
mask
(
loopBuffer
.
io
.
out
.
bits
.
pc
)
// XSDebug("Fetch from LB\n")
// XSDebug(p"pc=${Hexadecimal(io.loopBufPar.LBResp.pc)}\n")
// XSDebug(p"data=${Hexadecimal(io.loopBufPar.LBResp.data)}\n")
// XSDebug(p"mask=${Hexadecimal(io.loopBufPar.LBResp.mask)}\n")
}
pd
.
io
.
prev
.
valid
:=
if3_hasPrevHalfInstr
pd
.
io
.
prev
.
bits
:=
prevHalfInstr
.
instr
// if a fetch packet triggers page fault, set the pf instruction to nop
...
...
@@ -432,27 +435,35 @@ class IFU extends XSModule with HasIFUConst
//Performance Counter
if
(!
env
.
FPGAPlatform
)
{
ExcitingUtils
.
addSource
(
io
.
fetchPacket
.
fire
&&
!
i
o
.
loopBufPar
.
i
nLoop
,
"CntFetchFromICache"
,
Perf
)
ExcitingUtils
.
addSource
(
io
.
fetchPacket
.
fire
&&
i
o
.
loopBufPar
.
i
nLoop
,
"CntFetchFromLoopBuffer"
,
Perf
)
ExcitingUtils
.
addSource
(
io
.
fetchPacket
.
fire
&&
!
inLoop
,
"CntFetchFromICache"
,
Perf
)
ExcitingUtils
.
addSource
(
io
.
fetchPacket
.
fire
&&
inLoop
,
"CntFetchFromLoopBuffer"
,
Perf
)
}
io
.
fetchPacket
.
valid
:=
if4_valid
&&
!
io
.
redirect
.
valid
io
.
fetchPacket
.
bits
.
instrs
:=
if4_pd
.
instrs
io
.
fetchPacket
.
bits
.
mask
:=
if4_pd
.
mask
&
(
Fill
(
PredictWidth
,
!
if4_bp
.
taken
)
|
(
Fill
(
PredictWidth
,
1.
U
(
1.
W
))
>>
(~
if4_bp
.
jmpIdx
)))
io
.
fetchPacket
.
bits
.
pc
:=
if4_pd
.
pc
(
0
until
PredictWidth
).
foreach
(
i
=>
io
.
fetchPacket
.
bits
.
pnpc
(
i
)
:=
if4_pd
.
pc
(
i
)
+
Mux
(
if4_pd
.
pd
(
i
).
isRVC
,
2.
U
,
4.
U
))
val
fetchPacketValid
=
if4_valid
&&
!
io
.
redirect
.
valid
val
fetchPacketWire
=
Wire
(
new
FetchPacket
)
// io.fetchPacket.valid := if4_valid && !io.redirect.valid
fetchPacketWire
.
instrs
:=
if4_pd
.
instrs
fetchPacketWire
.
mask
:=
if4_pd
.
mask
&
(
Fill
(
PredictWidth
,
!
if4_bp
.
taken
)
|
(
Fill
(
PredictWidth
,
1.
U
(
1.
W
))
>>
(~
if4_bp
.
jmpIdx
)))
fetchPacketWire
.
pc
:=
if4_pd
.
pc
(
0
until
PredictWidth
).
foreach
(
i
=>
fetchPacketWire
.
pnpc
(
i
)
:=
if4_pd
.
pc
(
i
)
+
Mux
(
if4_pd
.
pd
(
i
).
isRVC
,
2.
U
,
4.
U
))
when
(
if4_bp
.
taken
)
{
io
.
fetchPacket
.
bits
.
pnpc
(
if4_bp
.
jmpIdx
)
:=
if4_bp
.
target
fetchPacketWire
.
pnpc
(
if4_bp
.
jmpIdx
)
:=
if4_bp
.
target
}
io
.
fetchPacket
.
bits
.
brInfo
:=
bpu
.
io
.
branchInfo
.
bits
(
0
until
PredictWidth
).
foreach
(
i
=>
io
.
fetchPacket
.
bits
.
brInfo
(
i
).
histPtr
:=
finalPredHistPtr
)
(
0
until
PredictWidth
).
foreach
(
i
=>
io
.
fetchPacket
.
bits
.
brInfo
(
i
).
predHistPtr
:=
if4_predHistPtr
)
io
.
fetchPacket
.
bits
.
pd
:=
if4_pd
.
pd
io
.
fetchPacket
.
bits
.
ipf
:=
if4_ipf
io
.
fetchPacket
.
bits
.
crossPageIPFFix
:=
if4_crossPageIPF
fetchPacketWire
.
brInfo
:=
bpu
.
io
.
branchInfo
.
bits
(
0
until
PredictWidth
).
foreach
(
i
=>
fetchPacketWire
.
brInfo
(
i
).
histPtr
:=
finalPredHistPtr
)
(
0
until
PredictWidth
).
foreach
(
i
=>
fetchPacketWire
.
brInfo
(
i
).
predHistPtr
:=
if4_predHistPtr
)
fetchPacketWire
.
pd
:=
if4_pd
.
pd
fetchPacketWire
.
ipf
:=
if4_ipf
fetchPacketWire
.
crossPageIPFFix
:=
if4_crossPageIPF
// predTaken Vec
io
.
fetchPacket
.
bits
.
predTaken
:=
if4_bp
.
taken
fetchPacketWire
.
predTaken
:=
if4_bp
.
taken
loopBuffer
.
io
.
in
.
bits
:=
fetchPacketWire
io
.
fetchPacket
.
bits
:=
fetchPacketWire
io
.
fetchPacket
.
valid
:=
fetchPacketValid
loopBuffer
.
io
.
in
.
valid
:=
io
.
fetchPacket
.
fire
// debug info
if
(
IFUDebug
)
{
...
...
src/main/scala/xiangshan/frontend/Ibuffer.scala
浏览文件 @
78105e83
...
...
@@ -7,8 +7,14 @@ import xiangshan._
import
utils._
import
xiangshan.backend.fu.HasExceptionNO
class
IBufferIO
extends
XSBundle
{
val
flush
=
Input
(
Bool
())
val
in
=
Flipped
(
DecoupledIO
(
new
FetchPacket
))
val
out
=
Vec
(
DecodeWidth
,
DecoupledIO
(
new
CtrlFlow
))
}
class
Ibuffer
extends
XSModule
{
val
io
=
IO
(
new
Loop
BufferIO
)
val
io
=
IO
(
new
I
BufferIO
)
class
IBufEntry
extends
XSBundle
{
val
inst
=
UInt
(
32.
W
)
...
...
@@ -21,9 +27,9 @@ class Ibuffer extends XSModule {
}
// Ignore
io
.
loopBufPar
<>
DontCare
io
.
loopBufPar
.
LBredirect
.
valid
:=
false
.
B
io
.
loopBufPar
.
inLoop
:=
false
.
B
//
io.loopBufPar <> DontCare
//
io.loopBufPar.LBredirect.valid := false.B
//
io.loopBufPar.inLoop := false.B
for
(
out
<-
io
.
out
)
{
...
...
src/main/scala/xiangshan/frontend/LoopBuffer.scala
浏览文件 @
78105e83
此差异已折叠。
点击以展开。
src/main/scala/xiangshan/frontend/NewLoopBuffer.scala
0 → 100644
浏览文件 @
78105e83
package
xiangshan.frontend
import
chisel3._
import
chisel3.util._
import
chisel3.util.experimental.BoringUtils
import
chisel3.ExcitingUtils._
import
utils._
import
xiangshan._
import
xiangshan.cache._
trait
HasLoopBufferCst
extends
HasXSParameter
{
val
preFetchBufferSize
=
2
}
class
LoopBufferParameters
extends
XSBundle
{
val
LBredirect
=
ValidIO
(
UInt
(
VAddrBits
.
W
))
val
fetchReq
=
Input
(
UInt
(
VAddrBits
.
W
))
// val preFetchPC = DecoupledIO(UInt(VAddrBits.W))
// val preFetchResp = Flipped(DecoupledIO(new ICacheResp))
// val preFetchSend = DecoupledIO(new ICacheResp)
}
class
LoopBufferIO
extends
XSBundle
{
val
flush
=
Input
(
Bool
())
val
in
=
Flipped
(
DecoupledIO
(
new
FetchPacket
))
val
out
=
ValidIO
(
new
ICacheResp
)
val
loopBufPar
=
new
LoopBufferParameters
}
class
NewLoopBuffer
extends
XSModule
with
HasLoopBufferCst
{
val
io
=
IO
(
new
LoopBufferIO
)
// FSM state define
val
s_idle
::
s_fill
::
s_active
::
Nil
=
Enum
(
3
)
val
LBstate
=
RegInit
(
s_idle
)
io
.
out
<>
DontCare
io
.
out
.
valid
:=
LBstate
===
s_active
io
.
in
.
ready
:=
true
.
B
io
.
loopBufPar
.
fetchReq
:=
DontCare
class
LBufEntry
extends
XSBundle
{
val
inst
=
UInt
(
16.
W
)
// val tag = UInt(tagBits.W)
}
def
sbboffset
(
inst
:
UInt
)
=
{
val
isJal
=
inst
===
BitPat
(
"b1111_???????_111111111_?????_1101111"
)
val
isCon
=
inst
===
BitPat
(
"b1111???_?????_?????_???_????1_1100011"
)
val
isRVCJal
=
inst
===
BitPat
(
"b????????????????_001_1?111??????_01"
)
val
isRVCCon
=
inst
===
BitPat
(
"b????????????????_11?_1??_???_?????_01"
)
val
rst
=
PriorityMux
(
Seq
(
isJal
->
inst
(
27
,
21
),
isCon
->
Cat
(
inst
(
27
,
25
),
inst
(
11
,
8
)),
isRVCJal
->
Cat
(
inst
(
6
),
inst
(
7
),
inst
(
2
),
inst
(
11
),
inst
(
5
,
3
)),
isRVCCon
->
Cat
(
inst
(
6
),
inst
(
5
),
inst
(
2
),
inst
(
11
,
10
),
inst
(
4
,
3
)),
true
.
B
->
0.
U
(
7.
W
)
))
((~
rst
).
asUInt
+
1.
U
,
rst
)
}
def
isSBB
(
inst
:
UInt
)
:
Bool
=
{
val
sbboffsetWire
=
WireInit
(
sbboffset
(
inst
).
_1
)
sbboffsetWire
>
0.
U
&&
sbboffsetWire
<=
112.
U
// TODO < 56.U
}
// predTaken to OH
val
predTakenVec
=
Mux
(
io
.
in
.
bits
.
predTaken
,
Reverse
(
PriorityEncoderOH
(
Reverse
(
io
.
in
.
bits
.
mask
))),
0.
U
(
PredictWidth
.
W
))
// Loop detect register
val
offsetCounter
=
Reg
(
UInt
((
log2Up
(
IBufSize
)+
2
).
W
))
val
tsbbPC
=
RegInit
(
0.
U
(
VAddrBits
.
W
))
val
brTaken
=
Cat
((
0
until
PredictWidth
).
map
(
i
=>
io
.
in
.
fire
&&
io
.
in
.
bits
.
mask
(
i
)
&&
predTakenVec
(
i
))).
orR
()
val
brIdx
=
OHToUInt
(
predTakenVec
.
asUInt
)
val
sbbTaken
=
brTaken
&&
isSBB
(
io
.
in
.
bits
.
instrs
(
brIdx
))
val
tsbbVec
=
Cat
((
0
until
PredictWidth
).
map
(
i
=>
io
.
in
.
fire
&&
io
.
in
.
bits
.
mask
(
i
)
&&
io
.
in
.
bits
.
pc
(
i
)
===
tsbbPC
))
val
hasTsbb
=
tsbbVec
.
orR
()
val
tsbbIdx
=
OHToUInt
(
Reverse
(
tsbbVec
))
val
tsbbTaken
=
brTaken
&&
io
.
in
.
bits
.
pc
(
brIdx
)
===
tsbbPC
val
buffer
=
Mem
(
IBufSize
*
2
,
new
LBufEntry
)
val
bufferValid
=
RegInit
(
VecInit
(
Seq
.
fill
(
IBufSize
*
2
)(
false
.
B
)))
val
redirect_pc
=
io
.
in
.
bits
.
pnpc
(
PredictWidth
.
U
-
PriorityEncoder
(
Reverse
(
io
.
in
.
bits
.
mask
))
-
1.
U
)
def
flush
()
=
{
XSDebug
(
"Loop Buffer Flushed.\n"
)
LBstate
:=
s_idle
for
(
i
<-
0
until
IBufSize
*
2
)
{
buffer
(
i
).
inst
:=
0.
U
// TODO: This is to make the debugging information clearer, this can be deleted
bufferValid
(
i
)
:=
false
.
B
}
}
when
(
io
.
in
.
fire
&&
LBstate
===
s_fill
)
{
io
.
in
.
bits
.
mask
.
asBools
().
zipWithIndex
.
map
{
case
(
m
,
i
)
=>
when
(
m
)
{
buffer
(
io
.
in
.
bits
.
pc
(
i
)(
7
,
1
)).
inst
:=
io
.
in
.
bits
.
instrs
(
i
)(
15
,
0
)
bufferValid
(
io
.
in
.
bits
.
pc
(
i
)(
7
,
1
))
:=
true
.
B
when
(!
io
.
in
.
bits
.
pd
(
i
).
isRVC
)
{
buffer
(
io
.
in
.
bits
.
pc
(
i
)(
7
,
1
)
+
1.
U
).
inst
:=
io
.
in
.
bits
.
instrs
(
i
)(
31
,
16
)
bufferValid
(
io
.
in
.
bits
.
pc
(
i
)(
7
,
1
)
+
1.
U
)
:=
true
.
B
// May need to be considered already valid
}
}
}
}
// This is ugly
val
pcStep
=
(
0
until
PredictWidth
).
map
(
i
=>
Mux
(!
io
.
in
.
fire
||
!
io
.
in
.
bits
.
mask
(
i
),
0.
U
,
Mux
(
io
.
in
.
bits
.
pd
(
i
).
isRVC
,
1.
U
,
2.
U
))).
fold
(
0.
U
(
log2Up
(
16
+
1
).
W
))(
_
+
_
)
val
offsetCounterWire
=
WireInit
(
offsetCounter
+
pcStep
)
offsetCounter
:=
offsetCounterWire
when
(
LBstate
===
s_active
)
{
io
.
out
.
bits
.
pc
:=
io
.
loopBufPar
.
fetchReq
io
.
out
.
bits
.
data
:=
Cat
((
31
to
0
by
-
1
).
map
(
i
=>
buffer
(
io
.
loopBufPar
.
fetchReq
(
7
,
1
)
+
i
.
U
).
inst
))
io
.
out
.
bits
.
mask
:=
Cat
((
31
to
0
by
-
1
).
map
(
i
=>
bufferValid
(
io
.
loopBufPar
.
fetchReq
(
7
,
1
)
+
i
.
U
)))
io
.
out
.
bits
.
ipf
:=
false
.
B
}
io
.
loopBufPar
.
LBredirect
.
valid
:=
false
.
B
io
.
loopBufPar
.
LBredirect
.
bits
:=
DontCare
/*-----------------------*/
/* Loop Buffer FSM */
/*-----------------------*/
when
(
io
.
in
.
fire
)
{
switch
(
LBstate
)
{
is
(
s_idle
)
{
// To FILL
// 检测到sbb且跳转,sbb成为triggering sbb
when
(
sbbTaken
)
{
LBstate
:=
s_fill
XSDebug
(
"State change: FILL\n"
)
// This is ugly
// offsetCounter := Cat("b1".U, sbboffset(io.in.bits.instrs(brIdx))) +
// (0 until PredictWidth).map(i => Mux(!io.in.bits.mask(i) || i.U < brIdx, 0.U, Mux(io.in.bits.pd(i).isRVC, 1.U, 2.U))).fold(0.U(log2Up(16+1).W))(_+_)
offsetCounter
:=
Cat
(
"b1"
.
U
,
sbboffset
(
io
.
in
.
bits
.
instrs
(
brIdx
)).
_2
)
tsbbPC
:=
io
.
in
.
bits
.
pc
(
brIdx
)
}
}
is
(
s_fill
)
{
// To AVTIVE
// triggering sbb 造成cof
when
(
offsetCounterWire
((
log2Up
(
IBufSize
)+
2
)-
1
)
===
0.
U
){
when
(
hasTsbb
&&
tsbbTaken
)
{
LBstate
:=
s_active
XSDebug
(
"State change: ACTIVE\n"
)
}.
otherwise
{
LBstate
:=
s_idle
XSDebug
(
"State change: IDLE\n"
)
flush
()
}
}
when
(
brTaken
&&
!
tsbbTaken
)
{
// To IDLE
LBstate
:=
s_idle
XSDebug
(
"State change: IDLE\n"
)
flush
()
}
}
is
(
s_active
)
{
// To IDLE
// triggering sbb不跳转 退出循环
when
(
hasTsbb
&&
!
tsbbTaken
)
{
XSDebug
(
"tsbb not taken, State change: IDLE\n"
)
LBstate
:=
s_idle
io
.
loopBufPar
.
LBredirect
.
valid
:=
true
.
B
// io.loopBufPar.LBredirect.bits := tsbbPC + Mux(io.in.bits.pd(tsbbIdx).isRVC, 2.U, 4.U)
io
.
loopBufPar
.
LBredirect
.
bits
:=
redirect_pc
// ExcitingUtils.addSource(true.B, "CntLBRedirect1", Perf)
XSDebug
(
p
"redirect pc=${Hexadecimal(redirect_pc)}\n"
)
flush
()
}
when
(
brTaken
&&
!
tsbbTaken
)
{
XSDebug
(
"cof by other inst, State change: IDLE\n"
)
LBstate
:=
s_idle
io
.
loopBufPar
.
LBredirect
.
valid
:=
true
.
B
io
.
loopBufPar
.
LBredirect
.
bits
:=
redirect_pc
// io.loopBufPar.LBredirect.bits := Mux(brIdx > tsbbIdx, tsbbPC + 4.U, io.loopBufPar.LBReq)
// ExcitingUtils.addSource(true.B, "CntLBRedirect2", Perf)
XSDebug
(
p
"redirect pc=${Hexadecimal(redirect_pc)}\n"
)
flush
()
}
when
(
hasTsbb
&&
brTaken
&&
!
tsbbTaken
)
{
XSDebug
(
"tsbb and cof, State change: IDLE\n"
)
LBstate
:=
s_idle
io
.
loopBufPar
.
LBredirect
.
valid
:=
true
.
B
io
.
loopBufPar
.
LBredirect
.
bits
:=
redirect_pc
// io.loopBufPar.LBredirect.bits := Mux(brIdx > tsbbIdx, tsbbPC + 4.U, io.loopBufPar.LBReq)
// ExcitingUtils.addSource(true.B, "CntLBRedirect3", Perf)
XSDebug
(
p
"redirect pc=${Hexadecimal(redirect_pc)}\n"
)
flush
()
}
}
}
}
when
(
io
.
flush
){
flush
()
}
// XSDebug(io.flush, "LoopBuffer Flushed\n")
if
(!
env
.
FPGAPlatform
)
{
ExcitingUtils
.
addSource
(
LBstate
===
s_active
&&
hasTsbb
&&
!
tsbbTaken
,
"CntExitLoop1"
,
Perf
)
ExcitingUtils
.
addSource
(
LBstate
===
s_active
&&
brTaken
&&
!
tsbbTaken
,
"CntExitLoop2"
,
Perf
)
ExcitingUtils
.
addSource
(
LBstate
===
s_active
&&
hasTsbb
&&
brTaken
&&
!
tsbbTaken
,
"CntExitLoop3"
,
Perf
)
}
XSDebug
(
LBstate
===
s_idle
,
"Current state: IDLE\n"
)
XSDebug
(
LBstate
===
s_fill
,
"Current state: FILL\n"
)
XSDebug
(
LBstate
===
s_active
,
"Current state: ACTIVE\n"
)
XSDebug
(
p
"offsetCounter = ${Binary(offsetCounterWire)}\n"
)
XSDebug
(
p
"tsbbIdx = ${tsbbIdx}\n"
)
when
(
io
.
in
.
fire
)
{
XSDebug
(
"Enque:\n"
)
XSDebug
(
brTaken
,
p
"Detected jump, idx=${brIdx}\n"
)
XSDebug
(
p
"predTaken=${io.in.bits.predTaken}, predTakenVec=${Binary(predTakenVec)}\n"
)
XSDebug
(
p
"MASK=${Binary(io.in.bits.mask)}\n"
)
for
(
i
<-
0
until
PredictWidth
){
XSDebug
(
p
"PC=${Hexadecimal(io.in.bits.pc(i))} ${Hexadecimal(io.in.bits.instrs(i))}\n"
)
}
}
XSDebug
(
"LoopBuffer:\n"
)
for
(
i
<-
0
until
IBufSize
*
2
/
8
)
{
XSDebug
(
"%x v:%b | %x v:%b | %x v:%b | %x v:%b | %x v:%b | %x v:%b | %x v:%b | %x v:%b\n"
,
buffer
(
i
*
8
+
0
).
inst
,
bufferValid
(
i
*
8
+
0
),
buffer
(
i
*
8
+
1
).
inst
,
bufferValid
(
i
*
8
+
1
),
buffer
(
i
*
8
+
2
).
inst
,
bufferValid
(
i
*
8
+
2
),
buffer
(
i
*
8
+
3
).
inst
,
bufferValid
(
i
*
8
+
3
),
buffer
(
i
*
8
+
4
).
inst
,
bufferValid
(
i
*
8
+
4
),
buffer
(
i
*
8
+
5
).
inst
,
bufferValid
(
i
*
8
+
5
),
buffer
(
i
*
8
+
6
).
inst
,
bufferValid
(
i
*
8
+
6
),
buffer
(
i
*
8
+
7
).
inst
,
bufferValid
(
i
*
8
+
7
)
)
}
XSDebug
(
io
.
out
.
valid
,
p
"fetch pc: ${Hexadecimal(io.loopBufPar.fetchReq)}\n"
)
XSDebug
(
io
.
out
.
valid
,
p
"fetchIdx: ${io.loopBufPar.fetchReq(7,1)}\n"
)
XSDebug
(
io
.
out
.
valid
,
p
"out data: ${Hexadecimal(io.out.bits.data)}\n"
)
XSDebug
(
io
.
out
.
valid
,
p
"out mask: ${Binary(io.out.bits.mask)}\n"
)
XSDebug
(
io
.
out
.
valid
,
p
"out pc : ${Hexadecimal(io.out.bits.pc)}\n"
)
}
\ No newline at end of file
src/test/scala/xiangshan/testutils/AddSinks.scala
浏览文件 @
78105e83
...
...
@@ -32,7 +32,10 @@ object AddSinks {
"perfCntCondMbpRRight"
,
"perfCntCondMbpRWrong"
,
"CntFetchFromICache"
,
"CntFetchFromLoopBuffer"
"CntFetchFromLoopBuffer"
,
"CntExitLoop1"
,
"CntExitLoop2"
,
"CntExitLoop3"
)
for
(
s
<-
sinks
){
BoringUtils
.
addSink
(
tmp
,
s
)
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录