Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
OpenXiangShan
XiangShan
提交
2be37cbb
X
XiangShan
项目概览
OpenXiangShan
/
XiangShan
8 个月 前同步成功
通知
1183
Star
3914
Fork
526
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
X
XiangShan
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
未验证
提交
2be37cbb
编写于
1月 08, 2021
作者:
L
ljw
提交者:
GitHub
1月 08, 2021
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #381 from RISCVERS/opt-brq
brq: add needAlloc to optimize timing
上级
c90fa626
2ef221a9
变更
4
隐藏空白更改
内联
并排
Showing
4 changed file
with
42 addition
and
170 deletion
+42
-170
src/main/scala/xiangshan/backend/CtrlBlock.scala
src/main/scala/xiangshan/backend/CtrlBlock.scala
+1
-3
src/main/scala/xiangshan/backend/brq/Brq.scala
src/main/scala/xiangshan/backend/brq/Brq.scala
+19
-15
src/main/scala/xiangshan/backend/decode/DecodeStage.scala
src/main/scala/xiangshan/backend/decode/DecodeStage.scala
+22
-23
src/test/scala/xiangshan/backend/brq/BrqTest.scala
src/test/scala/xiangshan/backend/brq/BrqTest.scala
+0
-129
未找到文件。
src/main/scala/xiangshan/backend/CtrlBlock.scala
浏览文件 @
2be37cbb
...
...
@@ -80,13 +80,11 @@ class CtrlBlock extends XSModule with HasCircularQueuePtrHelper {
io
.
frontend
.
cfiUpdateInfo
<>
brq
.
io
.
cfiInfo
decode
.
io
.
in
<>
io
.
frontend
.
cfVec
decode
.
io
.
toBrq
<>
brq
.
io
.
enqReqs
decode
.
io
.
brTags
<>
brq
.
io
.
brTags
decode
.
io
.
enqBrq
<>
brq
.
io
.
enq
brq
.
io
.
redirect
.
valid
<>
redirectValid
brq
.
io
.
redirect
.
bits
<>
redirect
brq
.
io
.
bcommit
<>
roq
.
io
.
bcommit
brq
.
io
.
enqReqs
<>
decode
.
io
.
toBrq
brq
.
io
.
exuRedirectWb
<>
io
.
fromIntBlock
.
exuRedirect
// pipeline between decode and dispatch
...
...
src/main/scala/xiangshan/backend/brq/Brq.scala
浏览文件 @
2be37cbb
...
...
@@ -38,14 +38,18 @@ object BrqPtr extends HasXSParameter {
}
}
class
BrqEnqIO
extends
XSBundle
{
val
needAlloc
=
Vec
(
RenameWidth
,
Input
(
Bool
()))
val
req
=
Vec
(
RenameWidth
,
Flipped
(
DecoupledIO
(
new
CtrlFlow
)))
val
resp
=
Vec
(
RenameWidth
,
Output
(
new
BrqPtr
))
}
class
BrqIO
extends
XSBundle
{
val
redirect
=
Input
(
ValidIO
(
new
Redirect
))
// receive branch/jump calculated target
val
exuRedirectWb
=
Vec
(
exuParameters
.
AluCnt
+
exuParameters
.
JmpCnt
,
Flipped
(
ValidIO
(
new
ExuOutput
)))
// from decode, branch insts enq
val
enqReqs
=
Vec
(
DecodeWidth
,
Flipped
(
DecoupledIO
(
new
CfCtrl
)))
// to decode
val
brTags
=
Output
(
Vec
(
DecodeWidth
,
new
BrqPtr
))
val
enq
=
new
BrqEnqIO
// to roq
val
out
=
ValidIO
(
new
ExuOutput
)
// misprediction, flush pipeline
...
...
@@ -118,22 +122,22 @@ class Brq extends XSModule with HasCircularQueuePtrHelper {
val
lastCycleRedirect
=
RegNext
(
io
.
redirect
.
valid
)
val
validEntries
=
distanceBetween
(
tailPtr
,
headPtr
)
for
(
i
<-
0
until
DecodeWidth
){
val
offset
=
if
(
i
==
0
)
0.
U
else
PopCount
(
io
.
enqReqs
.
take
(
i
).
map
(
_
.
valid
))
val
offset
=
if
(
i
==
0
)
0.
U
else
PopCount
(
io
.
enq
.
needAlloc
.
take
(
i
))
val
brTag
=
tailPtr
+
offset
val
idx
=
brTag
.
value
io
.
enq
Reqs
(
i
).
ready
:=
validEntries
<=
(
BrqSize
-
(
i
+
1
)).
U
&&
!
lastCycleRedirect
io
.
brTags
(
i
)
:=
brTag
when
(
io
.
enq
Reqs
(
i
).
fire
())
{
io
.
enq
.
req
(
i
).
ready
:=
validEntries
<=
(
BrqSize
-
(
i
+
1
)).
U
&&
!
lastCycleRedirect
io
.
enq
.
resp
(
i
)
:=
brTag
when
(
io
.
enq
.
req
(
i
).
fire
())
{
brQueue
(
idx
).
ptrFlag
:=
brTag
.
flag
brQueue
(
idx
).
exuOut
.
brUpdate
.
pc
:=
io
.
enq
Reqs
(
i
).
bits
.
cf
.
pc
brQueue
(
idx
).
exuOut
.
brUpdate
.
pnpc
:=
io
.
enq
Reqs
(
i
).
bits
.
cf
.
brUpdate
.
pnpc
brQueue
(
idx
).
exuOut
.
brUpdate
.
fetchIdx
:=
io
.
enq
Reqs
(
i
).
bits
.
cf
.
brUpdate
.
fetchIdx
brQueue
(
idx
).
exuOut
.
brUpdate
.
pd
:=
io
.
enq
Reqs
(
i
).
bits
.
cf
.
brUpdate
.
pd
brQueue
(
idx
).
exuOut
.
brUpdate
.
bpuMeta
:=
io
.
enq
Reqs
(
i
).
bits
.
cf
.
brUpdate
.
bpuMeta
brQueue
(
idx
).
exuOut
.
brUpdate
.
pc
:=
io
.
enq
.
req
(
i
).
bits
.
pc
brQueue
(
idx
).
exuOut
.
brUpdate
.
pnpc
:=
io
.
enq
.
req
(
i
).
bits
.
brUpdate
.
pnpc
brQueue
(
idx
).
exuOut
.
brUpdate
.
fetchIdx
:=
io
.
enq
.
req
(
i
).
bits
.
brUpdate
.
fetchIdx
brQueue
(
idx
).
exuOut
.
brUpdate
.
pd
:=
io
.
enq
.
req
(
i
).
bits
.
brUpdate
.
pd
brQueue
(
idx
).
exuOut
.
brUpdate
.
bpuMeta
:=
io
.
enq
.
req
(
i
).
bits
.
brUpdate
.
bpuMeta
stateQueue
(
idx
)
:=
s_idle
}
}
val
enqCnt
=
PopCount
(
io
.
enq
Reqs
.
map
(
_
.
fire
()))
val
enqCnt
=
PopCount
(
io
.
enq
.
req
.
map
(
_
.
fire
()))
tailPtr
:=
tailPtr
+
enqCnt
/**
...
...
@@ -194,8 +198,8 @@ class Brq extends XSModule with HasCircularQueuePtrHelper {
for
(
i
<-
0
until
DecodeWidth
){
XSDebug
(
debug_normal_mode
,
p
"enq v:${io.enq
Reqs(i).valid} rdy:${io.enqReqs(i).ready} pc:${Hexadecimal(io.enqReqs(i).bits.cf
.pc)}"
+
p
" brTag:${io.
brTags
(i)}\n"
p
"enq v:${io.enq
.req(i).valid} rdy:${io.enq.req(i).ready} pc:${Hexadecimal(io.enq.req(i).bits
.pc)}"
+
p
" brTag:${io.
enq.resp
(i)}\n"
)
}
...
...
src/main/scala/xiangshan/backend/decode/DecodeStage.scala
浏览文件 @
2be37cbb
...
...
@@ -3,15 +3,13 @@ package xiangshan.backend.decode
import
chisel3._
import
chisel3.util._
import
xiangshan._
import
xiangshan.backend.brq.Brq
Ptr
import
xiangshan.backend.brq.Brq
EnqIO
import
utils._
class
DecodeStage
extends
XSModule
{
val
io
=
IO
(
new
Bundle
()
{
// enq Brq
val
toBrq
=
Vec
(
DecodeWidth
,
DecoupledIO
(
new
CfCtrl
))
// get brMask/brTag
val
brTags
=
Input
(
Vec
(
DecodeWidth
,
new
BrqPtr
))
val
enqBrq
=
Flipped
(
new
BrqEnqIO
)
// from Ibuffer
val
in
=
Vec
(
DecodeWidth
,
Flipped
(
DecoupledIO
(
new
CtrlFlow
)))
...
...
@@ -19,9 +17,8 @@ class DecodeStage extends XSModule {
// to DecBuffer
val
out
=
Vec
(
DecodeWidth
,
DecoupledIO
(
new
CfCtrl
))
})
val
decoders
=
Seq
.
fill
(
DecodeWidth
)(
Module
(
new
DecodeUnit
))
val
decoderToBrq
=
Wire
(
Vec
(
DecodeWidth
,
new
CfCtrl
))
// without brTag and brMask
val
decoderToDecBuffer
=
Wire
(
Vec
(
DecodeWidth
,
new
CfCtrl
))
// with brTag and brMask
// Handshake ---------------------
// 1. if current instruction is valid, then:
...
...
@@ -33,21 +30,23 @@ class DecodeStage extends XSModule {
for
(
i
<-
0
until
DecodeWidth
)
{
decoders
(
i
).
io
.
enq
.
ctrl_flow
<>
io
.
in
(
i
).
bits
decoderToBrq
(
i
)
:=
decoders
(
i
).
io
.
deq
.
cf_ctrl
// CfCtrl without bfTag and brMask
decoderToBrq
(
i
).
brTag
:=
DontCare
io
.
toBrq
(
i
).
bits
:=
decoderToBrq
(
i
)
decoderToDecBuffer
(
i
)
:=
decoders
(
i
).
io
.
deq
.
cf_ctrl
decoderToDecBuffer
(
i
).
brTag
:=
io
.
brTags
(
i
)
io
.
out
(
i
).
bits
:=
decoderToDecBuffer
(
i
)
val
isMret
=
decoders
(
i
).
io
.
deq
.
cf_ctrl
.
cf
.
instr
===
BitPat
(
"b001100000010_00000_000_00000_1110011"
)
val
isSret
=
decoders
(
i
).
io
.
deq
.
cf_ctrl
.
cf
.
instr
===
BitPat
(
"b000100000010_00000_000_00000_1110011"
)
val
thisBrqValid
=
!
decoders
(
i
).
io
.
deq
.
cf_ctrl
.
cf
.
brUpdate
.
pd
.
notCFI
||
isMret
||
isSret
io
.
in
(
i
).
ready
:=
io
.
out
(
i
).
ready
&&
io
.
toBrq
(
i
).
ready
io
.
out
(
i
).
valid
:=
io
.
in
(
i
).
valid
&&
io
.
toBrq
(
i
).
ready
io
.
toBrq
(
i
).
valid
:=
io
.
in
(
i
).
valid
&&
thisBrqValid
&&
io
.
out
(
i
).
ready
XSDebug
(
io
.
in
(
i
).
valid
||
io
.
out
(
i
).
valid
||
io
.
toBrq
(
i
).
valid
,
"i:%d In(%d %d) Out(%d %d) ToBrq(%d %d) pc:%x instr:%x\n"
,
i
.
U
,
io
.
in
(
i
).
valid
,
io
.
in
(
i
).
ready
,
io
.
out
(
i
).
valid
,
io
.
out
(
i
).
ready
,
io
.
toBrq
(
i
).
valid
,
io
.
toBrq
(
i
).
ready
,
io
.
in
(
i
).
bits
.
pc
,
io
.
in
(
i
).
bits
.
instr
)
val
isMret
=
io
.
in
(
i
).
bits
.
instr
===
BitPat
(
"b001100000010_00000_000_00000_1110011"
)
val
isSret
=
io
.
in
(
i
).
bits
.
instr
===
BitPat
(
"b000100000010_00000_000_00000_1110011"
)
val
thisBrqValid
=
!
io
.
in
(
i
).
bits
.
brUpdate
.
pd
.
notCFI
||
isMret
||
isSret
io
.
enqBrq
.
needAlloc
(
i
)
:=
thisBrqValid
io
.
enqBrq
.
req
(
i
).
valid
:=
io
.
in
(
i
).
valid
&&
thisBrqValid
&&
io
.
out
(
i
).
ready
io
.
enqBrq
.
req
(
i
).
bits
:=
io
.
in
(
i
).
bits
io
.
out
(
i
).
valid
:=
io
.
in
(
i
).
valid
&&
io
.
enqBrq
.
req
(
i
).
ready
io
.
out
(
i
).
bits
:=
decoders
(
i
).
io
.
deq
.
cf_ctrl
io
.
out
(
i
).
bits
.
brTag
:=
io
.
enqBrq
.
resp
(
i
)
io
.
in
(
i
).
ready
:=
io
.
out
(
i
).
ready
&&
io
.
enqBrq
.
req
(
i
).
ready
XSDebug
(
io
.
in
(
i
).
valid
||
io
.
out
(
i
).
valid
||
io
.
enqBrq
.
req
(
i
).
valid
,
"i:%d In(%d %d) Out(%d %d) ToBrq(%d %d) pc:%x instr:%x\n"
,
i
.
U
,
io
.
in
(
i
).
valid
,
io
.
in
(
i
).
ready
,
io
.
out
(
i
).
valid
,
io
.
out
(
i
).
ready
,
io
.
enqBrq
.
req
(
i
).
valid
,
io
.
enqBrq
.
req
(
i
).
ready
,
io
.
in
(
i
).
bits
.
pc
,
io
.
in
(
i
).
bits
.
instr
)
}
}
\ No newline at end of file
}
src/test/scala/xiangshan/backend/brq/BrqTest.scala
已删除
100644 → 0
浏览文件 @
c90fa626
package
xiangshan.backend.brq
import
org.scalatest._
import
chiseltest._
import
chisel3._
import
chisel3.experimental.BundleLiterals._
import
chisel3.util._
import
chiseltest.experimental.TestOptionBuilder._
import
chiseltest.internal.VerilatorBackendAnnotation
import
org.scalatest.flatspec.AnyFlatSpec
import
org.scalatest.matchers.must.Matchers
import
top.Parameters
import
utils.XSLog
import
xiangshan._
import
xiangshan.testutils._
import
xiangshan.testutils.TestCaseGenerator._
import
scala.util.Random
class
BrqTest
extends
AnyFlatSpec
with
ChiselScalatestTester
with
Matchers
with
ParallelTestExecution
with
HasPartialDecoupledDriver
{
it
should
"redirect out-of-order, dequeue in-order"
in
{
Parameters
.
set
(
Parameters
.
debugParameters
)
test
(
new
Brq
{
AddSinks
()
}).
withAnnotations
(
Seq
())
{
c
=>
def
genEnqReq
(
x
:
=>
DecoupledIO
[
CfCtrl
],
pc
:
Long
)
=
{
chiselTypeOf
(
x
.
bits
).
Lit
(
_
.
cf
.
pc
->
pc
.
U
,
_
.
cf
.
brUpdate
.
pnpc
->
(
pc
+
4
).
U
)
}
def
genExuWb
(
exuRedirect
:
=>
Valid
[
ExuOutput
],
tagIdx
:
Int
,
tagFlag
:
Boolean
,
target
:
Long
)
=
{
chiselTypeOf
(
exuRedirect
.
bits
).
Lit
(
_
.
redirect
.
brTag
.
value
->
tagIdx
.
U
,
_
.
redirect
.
brTag
.
flag
->
tagFlag
.
B
,
_
.
redirect
.
target
->
target
.
U
)
}
c
.
io
.
enqReqs
.
head
.
initSource
().
setSourceClock
(
c
.
clock
)
var
brqPtrSeq
=
Seq
[(
BigInt
,
Boolean
)]()
for
(
i
<-
0
until
10
)
{
val
enqPort
=
c
.
io
.
enqReqs
.
head
enqPort
.
enqueuePartial
(
genEnqReq
(
enqPort
,
i
*
0x1000
))
}
var
enqTags
=
List
.
tabulate
(
10
)(
i
=>
i
)
val
misPred
=
6
println
(
s
"enqTags:$enqTags misPredTag:$misPred"
)
enqTags
=
enqTags
.
take
(
misPred
+
1
)
var
commitTags
,
deqTags
=
List
[
Int
]()
def
checkCommit
=
{
if
(
c
.
io
.
out
.
valid
.
peek
().
litToBoolean
)
{
commitTags
=
commitTags
:+
c
.
io
.
redirect
.
bits
.
brTag
.
value
.
peek
().
litValue
().
toInt
println
(
s
"====commited tags:$commitTags===="
)
}
}
def
checkDeq
=
{
if
(
c
.
io
.
out
.
valid
.
peek
().
litToBoolean
){
deqTags
=
deqTags
:+
c
.
io
.
out
.
bits
.
uop
.
brTag
.
value
.
peek
().
litValue
().
toInt
println
(
s
"====deq tags:$deqTags===="
)
}
}
println
(
"====Start random write back===="
)
val
wbPort
=
c
.
io
.
exuRedirectWb
.
head
//-----------------write back-----------------//
while
(
enqTags
.
nonEmpty
)
{
val
idx
=
Random
.
nextInt
(
enqTags
.
size
)
val
tag
=
enqTags
(
idx
)
println
(
s
"====write tag:$tag back to Brq===="
)
enqTags
=
enqTags
.
filter
(
x
=>
x
!=
tag
)
wbPort
.
valid
.
poke
(
true
.
B
)
wbPort
.
bits
.
pokePartial
(
genExuWb
(
wbPort
,
tag
,
tagFlag
=
false
,
if
(
tag
==
misPred
)
0xffff
else
tag
*
0x1000
+
4
)
)
checkCommit
c
.
clock
.
step
(
1
)
wbPort
.
valid
.
poke
(
false
.
B
)
for
(
i
<-
0
until
Random
.
nextInt
(
3
))
{
checkCommit
c
.
clock
.
step
(
1
)
}
}
c
.
io
.
bcommit
.
poke
((
misPred
+
1
).
U
)
c
.
clock
.
step
(
1
)
c
.
io
.
bcommit
.
poke
(
0.
U
)
while
(
deqTags
.
size
!=
misPred
+
1
)
{
checkCommit
checkDeq
c
.
clock
.
step
(
1
)
}
c
.
clock
.
step
(
10
)
val
left
=
commitTags
.
takeWhile
(
x
=>
x
!=
misPred
)
val
right
=
commitTags
.
dropWhile
(
x
=>
x
!=
misPred
).
drop
(
1
)
println
(
s
"commited before mispred: $left"
)
println
(
s
"commited after mispred: $right"
)
def
isValidCommitSeq
(
in
:
Seq
[
Int
])
:
Boolean
=
{
for
(
i
<-
1
until
in
.
size
){
if
(
in
(
i
)
==
in
(
i
-
1
))
return
false
}
true
}
assert
(
isValidCommitSeq
(
left
)
&&
isValidCommitSeq
(
right
))
println
(
s
"deq tags: $deqTags"
)
def
isValidDeqSeq
(
in
:
Seq
[
Int
])
:
Boolean
=
{
in
.
zipWithIndex
.
map
(
x
=>
x
.
_1
==
x
.
_2
).
reduce
(
_
&&
_
)
}
assert
(
isValidDeqSeq
(
deqTags
))
}
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录