Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
OpenXiangShan
XiangShan
提交
8ba1aec3
X
XiangShan
项目概览
OpenXiangShan
/
XiangShan
9 个月 前同步成功
通知
1183
Star
3914
Fork
526
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
X
XiangShan
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
提交
8ba1aec3
编写于
12月 19, 2020
作者:
Y
Yinan Xu
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
roq: optimize enq timing
上级
c348ab30
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
50 addition
and
84 deletion
+50
-84
src/main/scala/xiangshan/backend/dispatch/Dispatch.scala
src/main/scala/xiangshan/backend/dispatch/Dispatch.scala
+2
-8
src/main/scala/xiangshan/backend/dispatch/Dispatch1.scala
src/main/scala/xiangshan/backend/dispatch/Dispatch1.scala
+19
-37
src/main/scala/xiangshan/backend/roq/Roq.scala
src/main/scala/xiangshan/backend/roq/Roq.scala
+29
-39
未找到文件。
src/main/scala/xiangshan/backend/dispatch/Dispatch.scala
浏览文件 @
8ba1aec3
...
...
@@ -6,7 +6,7 @@ import xiangshan._
import
utils._
import
xiangshan.backend.regfile.RfReadPort
import
chisel3.ExcitingUtils._
import
xiangshan.backend.roq.
RoqPtr
import
xiangshan.backend.roq.
{
RoqPtr
,
RoqEnqIO
}
import
xiangshan.backend.rename.RenameBypassInfo
case
class
DispatchParameters
...
...
@@ -29,13 +29,7 @@ class Dispatch extends XSModule {
// to busytable: set pdest to busy (not ready) when they are dispatched
val
allocPregs
=
Vec
(
RenameWidth
,
Output
(
new
ReplayPregReq
))
// enq Roq
val
enqRoq
=
new
Bundle
{
val
canAccept
=
Input
(
Bool
())
val
isEmpty
=
Input
(
Bool
())
val
extraWalk
=
Vec
(
RenameWidth
,
Output
(
Bool
()))
val
req
=
Vec
(
RenameWidth
,
ValidIO
(
new
MicroOp
))
val
resp
=
Vec
(
RenameWidth
,
Input
(
new
RoqPtr
))
}
val
enqRoq
=
Flipped
(
new
RoqEnqIO
)
// enq Lsq
val
enqLsq
=
new
Bundle
()
{
val
canAccept
=
Input
(
Bool
())
...
...
src/main/scala/xiangshan/backend/dispatch/Dispatch1.scala
浏览文件 @
8ba1aec3
...
...
@@ -5,7 +5,7 @@ import chisel3.util._
import
chisel3.ExcitingUtils._
import
xiangshan._
import
utils.
{
XSDebug
,
XSError
,
XSInfo
}
import
xiangshan.backend.roq.
RoqPtr
import
xiangshan.backend.roq.
{
RoqPtr
,
RoqEnqIO
}
import
xiangshan.backend.rename.RenameBypassInfo
// read rob and enqueue
...
...
@@ -16,14 +16,7 @@ class Dispatch1 extends XSModule {
val
renameBypass
=
Input
(
new
RenameBypassInfo
)
val
recv
=
Output
(
Vec
(
RenameWidth
,
Bool
()))
// enq Roq
val
enqRoq
=
new
Bundle
{
val
canAccept
=
Input
(
Bool
())
val
isEmpty
=
Input
(
Bool
())
// if set, Roq needs extra walk
val
extraWalk
=
Vec
(
RenameWidth
,
Output
(
Bool
()))
val
req
=
Vec
(
RenameWidth
,
ValidIO
(
new
MicroOp
))
val
resp
=
Vec
(
RenameWidth
,
Input
(
new
RoqPtr
))
}
val
enqRoq
=
Flipped
(
new
RoqEnqIO
)
// enq Lsq
val
enqLsq
=
new
Bundle
()
{
val
canAccept
=
Input
(
Bool
())
...
...
@@ -132,33 +125,24 @@ class Dispatch1 extends XSModule {
// this instruction can actually dequeue: 3 conditions
// (1) resources are ready
// (2) previous instructions are ready
val
thisCanActualOut
=
(
0
until
RenameWidth
).
map
(
i
=>
allResourceReady
&&
!
thisIsBlocked
(
i
)
&&
notBlockedByPrevious
(
i
))
val
thisCanActualOut
=
(
0
until
RenameWidth
).
map
(
i
=>
!
thisIsBlocked
(
i
)
&&
notBlockedByPrevious
(
i
))
// input for ROQ and LSQ
// note that LSQ needs roqIdx
// (1) LSQ needs roqIdx; (2) DPQ needs roqIdx and lsIdx
val
updateUopWithIndex
=
Wire
(
Vec
(
RenameWidth
,
new
MicroOp
))
for
(
i
<-
0
until
RenameWidth
)
{
io
.
enqRoq
.
extraWalk
(
i
)
:=
io
.
fromRename
(
i
).
valid
&&
!
thisCanActualOut
(
i
)
io
.
enqRoq
.
req
(
i
).
valid
:=
io
.
fromRename
(
i
).
valid
&&
thisCanActualOut
(
i
)
io
.
enqRoq
.
needAlloc
(
i
)
:=
io
.
fromRename
(
i
).
valid
io
.
enqRoq
.
req
(
i
).
valid
:=
io
.
fromRename
(
i
).
valid
&&
thisCanActualOut
(
i
)
&&
io
.
enqLsq
.
canAccept
&&
io
.
toIntDq
.
canAccept
&&
io
.
toFpDq
.
canAccept
&&
io
.
toLsDq
.
canAccept
io
.
enqRoq
.
req
(
i
).
bits
:=
updatedUop
(
i
)
XSDebug
(
io
.
enqRoq
.
req
(
i
).
valid
,
p
"pc 0x${Hexadecimal(io.fromRename(i).bits.cf.pc)} receives nroq ${io.enqRoq.resp(i)}\n"
)
val
shouldEnqLsq
=
isLs
(
i
)
&&
io
.
fromRename
(
i
).
bits
.
ctrl
.
fuType
=/=
FuType
.
mou
io
.
enqLsq
.
req
(
i
).
valid
:=
io
.
fromRename
(
i
).
valid
&&
shouldEnqLsq
&&
thisCanActualOut
(
i
)
io
.
enqLsq
.
req
(
i
).
valid
:=
io
.
fromRename
(
i
).
valid
&&
shouldEnqLsq
&&
thisCanActualOut
(
i
)
&&
io
.
enqRoq
.
canAccept
&&
io
.
toIntDq
.
canAccept
&&
io
.
toFpDq
.
canAccept
&&
io
.
toLsDq
.
canAccept
io
.
enqLsq
.
req
(
i
).
bits
:=
updatedUop
(
i
)
io
.
enqLsq
.
req
(
i
).
bits
.
roqIdx
:=
io
.
enqRoq
.
resp
(
i
)
XSDebug
(
io
.
enqLsq
.
req
(
i
).
valid
,
p
"pc 0x${Hexadecimal(io.fromRename(i).bits.cf.pc)} receives lq ${io.enqLsq.resp(i).lqIdx} sq ${io.enqLsq.resp(i).sqIdx}\n"
)
XSDebug
(
io
.
enqRoq
.
req
(
i
).
valid
,
p
"pc 0x${Hexadecimal(io.fromRename(i).bits.cf.pc)} receives nroq ${io.enqRoq.resp(i)}\n"
)
}
/**
* Part 4:
* append ROQ and LSQ indexed to uop, and send them to dispatch queue
*/
val
updateUopWithIndex
=
Wire
(
Vec
(
RenameWidth
,
new
MicroOp
))
for
(
i
<-
0
until
RenameWidth
)
{
updateUopWithIndex
(
i
)
:=
updatedUop
(
i
)
updateUopWithIndex
(
i
).
roqIdx
:=
io
.
enqRoq
.
resp
(
i
)
updateUopWithIndex
(
i
).
lqIdx
:=
io
.
enqLsq
.
resp
(
i
).
lqIdx
...
...
@@ -168,18 +152,16 @@ class Dispatch1 extends XSModule {
// Note that if one of their previous instructions cannot enqueue, they should not enter dispatch queue.
// We use notBlockedByPrevious here.
io
.
toIntDq
.
req
(
i
).
bits
:=
updateUopWithIndex
(
i
)
io
.
toIntDq
.
req
(
i
).
valid
:=
io
.
fromRename
(
i
).
valid
&&
isInt
(
i
)
&&
allResourceReady
&&
!
thisIsBlocked
(
i
)
&&
notBlockedByPrevious
(
i
)
io
.
toIntDq
.
req
(
i
).
valid
:=
io
.
fromRename
(
i
).
valid
&&
isInt
(
i
)
&&
thisCanActualOut
(
i
)
&&
io
.
enqLsq
.
canAccept
&&
io
.
enqRoq
.
canAccept
&&
io
.
toFpDq
.
canAccept
&&
io
.
toLsDq
.
canAccept
// NOTE: floating point instructions are not noSpecExec currently
// remove commit /**/ when fp instructions are possible to be noSpecExec
io
.
toFpDq
.
req
(
i
).
bits
:=
updateUopWithIndex
(
i
)
io
.
toFpDq
.
req
(
i
).
valid
:=
io
.
fromRename
(
i
).
valid
&&
isFp
(
i
)
&&
allResourceReady
&&
/*!thisIsBlocked(i) && */
notBlockedByPrevious
(
i
)
io
.
toFpDq
.
req
(
i
).
valid
:=
io
.
fromRename
(
i
).
valid
&&
isFp
(
i
)
&&
thisCanActualOut
(
i
)
&&
io
.
enqLsq
.
canAccept
&&
io
.
enqRoq
.
canAccept
&&
io
.
toIntDq
.
canAccept
&&
io
.
toLsDq
.
canAccept
io
.
toLsDq
.
req
(
i
).
bits
:=
updateUopWithIndex
(
i
)
io
.
toLsDq
.
req
(
i
).
valid
:=
io
.
fromRename
(
i
).
valid
&&
isLs
(
i
)
&&
allResourceReady
&&
!
thisIsBlocked
(
i
)
&&
notBlockedByPrevious
(
i
)
io
.
toLsDq
.
req
(
i
).
valid
:=
io
.
fromRename
(
i
).
valid
&&
isLs
(
i
)
&&
thisCanActualOut
(
i
)
&&
io
.
enqLsq
.
canAccept
&&
io
.
enqRoq
.
canAccept
&&
io
.
toIntDq
.
canAccept
&&
io
.
toFpDq
.
canAccept
XSDebug
(
io
.
toIntDq
.
req
(
i
).
valid
,
p
"pc 0x${Hexadecimal(io.toIntDq.req(i).bits.cf.pc)} int index $i\n"
)
XSDebug
(
io
.
toFpDq
.
req
(
i
).
valid
,
p
"pc 0x${Hexadecimal(io.toFpDq.req(i).bits.cf.pc )} fp index $i\n"
)
...
...
@@ -187,12 +169,12 @@ class Dispatch1 extends XSModule {
}
/**
* Part
3
: send response to rename when dispatch queue accepts the uop
* Part
4
: send response to rename when dispatch queue accepts the uop
*/
val
readyVector
=
(
0
until
RenameWidth
).
map
(
i
=>
!
io
.
fromRename
(
i
).
valid
||
io
.
recv
(
i
))
val
hasSpecialInstr
=
Cat
((
0
until
RenameWidth
).
map
(
i
=>
io
.
fromRename
(
i
).
valid
&&
(
isBlockBackward
(
i
)
||
isNoSpecExec
(
i
)))).
orR
for
(
i
<-
0
until
RenameWidth
)
{
io
.
recv
(
i
)
:=
thisCanActualOut
(
i
)
io
.
fromRename
(
i
).
ready
:=
Cat
(
readyVector
).
andR
()
io
.
recv
(
i
)
:=
thisCanActualOut
(
i
)
&&
io
.
enqLsq
.
canAccept
&&
io
.
enqRoq
.
canAccept
&&
io
.
toIntDq
.
canAccept
&&
io
.
toFpDq
.
canAccept
&&
io
.
toLsDq
.
canAccept
io
.
fromRename
(
i
).
ready
:=
!
hasSpecialInstr
&&
io
.
enqLsq
.
canAccept
&&
io
.
enqRoq
.
canAccept
&&
io
.
toIntDq
.
canAccept
&&
io
.
toFpDq
.
canAccept
&&
io
.
toLsDq
.
canAccept
XSInfo
(
io
.
recv
(
i
)
&&
io
.
fromRename
(
i
).
valid
,
p
"pc 0x${Hexadecimal(io.fromRename(i).bits.cf.pc)}, type(${isInt(i)}, ${isFp(i)}, ${isLs(i)}), "
+
...
...
src/main/scala/xiangshan/backend/roq/Roq.scala
浏览文件 @
8ba1aec3
...
...
@@ -38,17 +38,20 @@ class RoqCSRIO extends XSBundle {
val
dirty_fs
=
Output
(
Bool
())
}
class
RoqEnqIO
extends
XSBundle
{
val
canAccept
=
Output
(
Bool
())
val
isEmpty
=
Output
(
Bool
())
// valid vector, for roqIdx gen and walk
val
needAlloc
=
Vec
(
RenameWidth
,
Input
(
Bool
()))
val
req
=
Vec
(
RenameWidth
,
Flipped
(
ValidIO
(
new
MicroOp
)))
val
resp
=
Vec
(
RenameWidth
,
Output
(
new
RoqPtr
))
}
class
Roq
(
numWbPorts
:
Int
)
extends
XSModule
with
HasCircularQueuePtrHelper
{
val
io
=
IO
(
new
Bundle
()
{
val
brqRedirect
=
Input
(
Valid
(
new
Redirect
))
val
memRedirect
=
Input
(
Valid
(
new
Redirect
))
val
enq
=
new
Bundle
{
val
canAccept
=
Output
(
Bool
())
val
isEmpty
=
Output
(
Bool
())
val
extraWalk
=
Vec
(
RenameWidth
,
Input
(
Bool
()))
val
req
=
Vec
(
RenameWidth
,
Flipped
(
ValidIO
(
new
MicroOp
)))
val
resp
=
Vec
(
RenameWidth
,
Output
(
new
RoqPtr
))
}
val
enq
=
new
RoqEnqIO
val
redirect
=
Output
(
Valid
(
new
Redirect
))
val
exception
=
Output
(
new
MicroOp
)
// exu + brq
...
...
@@ -108,14 +111,7 @@ class Roq(numWbPorts: Int) extends XSModule with HasCircularQueuePtrHelper {
io
.
roqDeqPtr
:=
deqPtrExt
// common signal
val
enqPtrValPlus
=
Wire
(
Vec
(
RenameWidth
,
UInt
(
log2Up
(
RoqSize
).
W
)))
val
enqPtrFlagPlus
=
Wire
(
Vec
(
RenameWidth
,
Bool
()))
for
(
i
<-
0
until
RenameWidth
)
{
val
offset
=
PopCount
(
io
.
enq
.
req
.
map
(
_
.
valid
).
take
(
i
))
val
roqIdxExt
=
enqPtrExt
+
offset
enqPtrValPlus
(
i
)
:=
roqIdxExt
.
value
enqPtrFlagPlus
(
i
)
:=
roqIdxExt
.
flag
}
val
enqPtrVec
=
WireInit
(
VecInit
((
0
until
RenameWidth
).
map
(
i
=>
enqPtrExt
+
PopCount
(
io
.
enq
.
needAlloc
.
take
(
i
)))))
val
deqPtrExtPlus
=
Wire
(
Vec
(
RenameWidth
,
UInt
(
log2Up
(
RoqSize
).
W
)))
for
(
i
<-
0
until
CommitWidth
){
...
...
@@ -138,14 +134,9 @@ class Roq(numWbPorts: Int) extends XSModule with HasCircularQueuePtrHelper {
val
walkNoSpecExec
=
io
.
commits
.
isWalk
&&
Cat
((
0
until
CommitWidth
).
map
(
i
=>
io
.
commits
.
valid
(
i
)
&&
io
.
commits
.
uop
(
i
).
ctrl
.
noSpecExec
)).
orR
XSError
(
state
=/=
s_extrawalk
&&
walkNoSpecExec
,
"noSpecExec should not walk\n"
)
val
validDispatch
=
io
.
enq
.
req
.
map
(
_
.
valid
)
for
(
i
<-
0
until
RenameWidth
)
{
val
offset
=
PopCount
(
validDispatch
.
take
(
i
))
val
roqIdxExt
=
enqPtrExt
+
offset
val
roqIdx
=
roqIdxExt
.
value
when
(
io
.
enq
.
req
(
i
).
valid
)
{
microOp
(
roqIdx
)
:=
io
.
enq
.
req
(
i
).
bits
when
(
io
.
enq
.
req
(
i
).
valid
&&
io
.
enq
.
canAccept
)
{
microOp
(
enqPtrVec
(
i
).
value
)
:=
io
.
enq
.
req
(
i
).
bits
when
(
io
.
enq
.
req
(
i
).
bits
.
ctrl
.
blockBackward
)
{
hasBlockBackward
:=
true
.
B
}
...
...
@@ -153,19 +144,18 @@ class Roq(numWbPorts: Int) extends XSModule with HasCircularQueuePtrHelper {
hasNoSpecExec
:=
true
.
B
}
}
io
.
enq
.
resp
(
i
)
:=
roqIdxExt
io
.
enq
.
resp
(
i
)
:=
enqPtrVec
(
i
)
}
val
validEntries
=
distanceBetween
(
enqPtrExt
,
deqPtrExt
)
val
firedDispatch
=
Cat
(
io
.
enq
.
req
.
map
(
_
.
valid
)
)
val
firedDispatch
=
Mux
(
io
.
enq
.
canAccept
,
PopCount
(
Cat
(
io
.
enq
.
req
.
map
(
_
.
valid
))),
0.
U
)
io
.
enq
.
canAccept
:=
(
validEntries
<=
(
RoqSize
-
RenameWidth
).
U
)
&&
!
hasBlockBackward
io
.
enq
.
isEmpty
:=
isEmpty
XSDebug
(
p
"(ready, valid): ${io.enq.canAccept}, ${Binary(
firedDispatch
)}\n"
)
XSDebug
(
p
"(ready, valid): ${io.enq.canAccept}, ${Binary(
Cat(io.enq.req.map(_.valid))
)}\n"
)
val
dispatchCnt
=
PopCount
(
firedDispatch
)
enqPtrExt
:=
enqPtrExt
+
dispatchCnt
when
(
firedDispatch
.
orR
)
{
XSInfo
(
"dispatched %d insts\n"
,
dispatchCnt
)
enqPtrExt
:=
enqPtrExt
+
firedDispatch
when
(
firedDispatch
=/=
0.
U
)
{
XSInfo
(
"dispatched %d insts\n"
,
firedDispatch
)
}
// Writeback
...
...
@@ -224,7 +214,7 @@ class Roq(numWbPorts: Int) extends XSModule with HasCircularQueuePtrHelper {
// extra space is used weh roq has no enough space, but mispredict recovery needs such info to walk regmap
val
needExtraSpaceForMPR
=
WireInit
(
VecInit
(
List
.
tabulate
(
RenameWidth
)(
i
=>
io
.
brqRedirect
.
valid
&&
io
.
enq
.
extraWalk
(
i
))
List
.
tabulate
(
RenameWidth
)(
i
=>
io
.
brqRedirect
.
valid
&&
io
.
enq
.
needAlloc
(
i
))
))
val
extraSpaceForMPR
=
Reg
(
Vec
(
RenameWidth
,
new
MicroOp
))
val
usedSpaceForMPR
=
Reg
(
Vec
(
RenameWidth
,
Bool
()))
...
...
@@ -345,12 +335,12 @@ class Roq(numWbPorts: Int) extends XSModule with HasCircularQueuePtrHelper {
// when redirect, walk back roq entries
when
(
io
.
brqRedirect
.
valid
){
// TODO: need check if consider exception redirect?
state
:=
s_walk
val
nextEnqPtr
=
(
enqPtrExt
-
1.
U
)
+
dispatchCnt
val
walkPtrStart
=
enqPtrExt
-
1.
U
walkPtrExt
:=
Mux
(
state
===
s_walk
,
walkPtrExt
-
Mux
(
walkFinished
,
walkCounter
,
CommitWidth
.
U
),
Mux
(
state
===
s_extrawalk
,
walkPtrExt
,
nextEnqPtr
))
Mux
(
state
===
s_extrawalk
,
walkPtrExt
,
walkPtrStart
))
// walkTgtExt := io.brqRedirect.bits.roqIdx
val
currentWalkPtr
=
Mux
(
state
===
s_walk
||
state
===
s_extrawalk
,
walkPtrExt
,
nextEnqPtr
)
val
currentWalkPtr
=
Mux
(
state
===
s_walk
||
state
===
s_extrawalk
,
walkPtrExt
,
walkPtrStart
)
walkCounter
:=
distanceBetween
(
currentWalkPtr
,
io
.
brqRedirect
.
bits
.
roqIdx
)
-
Mux
(
state
===
s_walk
,
commitCnt
,
0.
U
)
enqPtrExt
:=
io
.
brqRedirect
.
bits
.
roqIdx
+
1.
U
}
...
...
@@ -375,8 +365,8 @@ class Roq(numWbPorts: Int) extends XSModule with HasCircularQueuePtrHelper {
// write
// enqueue logic writes 6 valid
for
(
i
<-
0
until
RenameWidth
)
{
when
(
io
.
enq
.
req
(
i
).
fire
()
){
valid
(
enqPtrV
alPlus
(
i
)
)
:=
true
.
B
when
(
io
.
enq
.
req
(
i
).
valid
&&
io
.
enq
.
canAccept
&&
!
io
.
brqRedirect
.
valid
){
valid
(
enqPtrV
ec
(
i
).
value
)
:=
true
.
B
}
}
// dequeue/walk logic writes 6 valid, dequeue and walk will not happen at the same time
...
...
@@ -412,8 +402,8 @@ class Roq(numWbPorts: Int) extends XSModule with HasCircularQueuePtrHelper {
// write
// enqueue logic set 6 writebacked to false
for
(
i
<-
0
until
RenameWidth
)
{
when
(
io
.
enq
.
req
(
i
).
fire
()
){
writebacked
(
enqPtrV
alPlus
(
i
)
)
:=
false
.
B
when
(
io
.
enq
.
req
(
i
).
valid
&&
io
.
enq
.
canAccept
&&
!
io
.
brqRedirect
.
valid
){
writebacked
(
enqPtrV
ec
(
i
).
value
)
:=
false
.
B
}
}
// writeback logic set numWbPorts writebacked to true
...
...
@@ -443,8 +433,8 @@ class Roq(numWbPorts: Int) extends XSModule with HasCircularQueuePtrHelper {
// write: update when enqueue
// enqueue logic set 6 flagBkup at most
for
(
i
<-
0
until
RenameWidth
)
{
when
(
io
.
enq
.
req
(
i
).
fire
()
){
flagBkup
(
enqPtrV
alPlus
(
i
))
:=
enqPtrFlagPlus
(
i
)
when
(
io
.
enq
.
req
(
i
).
valid
&&
io
.
enq
.
canAccept
&&
!
io
.
brqRedirect
.
valid
){
flagBkup
(
enqPtrV
ec
(
i
).
value
)
:=
enqPtrVec
(
i
).
flag
}
}
// read: used in rollback logic
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录