Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
OpenXiangShan
XiangShan
提交
6f2bcb99
X
XiangShan
项目概览
OpenXiangShan
/
XiangShan
11 个月 前同步成功
通知
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,发现更多精彩内容 >>
提交
6f2bcb99
编写于
10月 21, 2020
作者:
Y
Yinan Xu
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
dispatch queue: support !isPower2(size)
上级
968988f0
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
34 addition
and
58 deletion
+34
-58
src/main/scala/xiangshan/XSCore.scala
src/main/scala/xiangshan/XSCore.scala
+3
-3
src/main/scala/xiangshan/backend/dispatch/DispatchQueue.scala
...main/scala/xiangshan/backend/dispatch/DispatchQueue.scala
+31
-55
未找到文件。
src/main/scala/xiangshan/XSCore.scala
浏览文件 @
6f2bcb99
...
...
@@ -58,9 +58,9 @@ case class XSCoreParameters
RoqSize
:
Int
=
32
,
dpParams
:
DispatchParameters
=
DispatchParameters
(
DqEnqWidth
=
4
,
IntDqSize
=
64
,
FpDqSize
=
64
,
LsDqSize
=
64
,
IntDqSize
=
12
,
FpDqSize
=
12
,
LsDqSize
=
12
,
IntDqDeqWidth
=
4
,
FpDqDeqWidth
=
4
,
LsDqDeqWidth
=
4
,
...
...
src/main/scala/xiangshan/backend/dispatch/DispatchQueue.scala
浏览文件 @
6f2bcb99
...
...
@@ -2,7 +2,7 @@ package xiangshan.backend.dispatch
import
chisel3._
import
chisel3.util._
import
utils.
{
XSDebug
,
XSError
,
XSInfo
}
import
utils.
_
import
xiangshan.backend.decode.SrcType
import
xiangshan.
{
MicroOp
,
Redirect
,
ReplayPregReq
,
RoqCommit
,
XSBundle
,
XSModule
}
...
...
@@ -21,57 +21,41 @@ class DispatchQueueIO(enqnum: Int, deqnum: Int, replayWidth: Int) extends XSBund
}
// dispatch queue: accepts at most enqnum uops from dispatch1 and dispatches deqnum uops at every clock cycle
class
DispatchQueue
(
size
:
Int
,
enqnum
:
Int
,
deqnum
:
Int
,
replayWidth
:
Int
)
extends
XSModule
{
class
DispatchQueue
(
size
:
Int
,
enqnum
:
Int
,
deqnum
:
Int
,
replayWidth
:
Int
)
extends
XSModule
with
HasCircularQueuePtrHelper
{
val
io
=
IO
(
new
DispatchQueueIO
(
enqnum
,
deqnum
,
replayWidth
))
val
indexWidth
=
log2Ceil
(
size
)
val
s_invalid
::
s_valid
::
s_dispatched
::
Nil
=
Enum
(
3
)
// queue data array
val
uopEntries
=
Mem
(
size
,
new
MicroOp
)
//Reg(Vec(size, new MicroOp))
val
uopEntries
=
Mem
(
size
,
new
MicroOp
)
val
stateEntries
=
RegInit
(
VecInit
(
Seq
.
fill
(
size
)(
s_invalid
)))
// head: first valid entry (dispatched entry)
val
headPtr
=
RegInit
(
0.
U
((
indexWidth
+
1
).
W
))
val
headIndex
=
headPtr
(
indexWidth
-
1
,
0
)
val
headDirection
=
headPtr
(
indexWidth
)
val
headPtr
=
RegInit
(
0.
U
.
asTypeOf
(
new
CircularQueuePtr
(
size
)))
// dispatch: first entry that has not been dispatched
val
dispatchPtr
=
RegInit
(
0.
U
((
indexWidth
+
1
).
W
))
val
dispatchIndex
=
dispatchPtr
(
indexWidth
-
1
,
0
)
val
dispatchDirection
=
dispatchPtr
(
indexWidth
)
val
dispatchPtr
=
RegInit
(
0.
U
.
asTypeOf
(
new
CircularQueuePtr
(
size
)))
// tail: first invalid entry (free entry)
val
tailPtr
=
RegInit
(
0.
U
((
indexWidth
+
1
).
W
))
val
tailIndex
=
tailPtr
(
indexWidth
-
1
,
0
)
val
tailDirection
=
tailPtr
(
indexWidth
)
val
tailPtr
=
RegInit
(
0.
U
.
asTypeOf
(
new
CircularQueuePtr
(
size
)))
// TODO: make ptr a vector to reduce latency?
// commit: starting from head ptr
val
commitPtr
=
(
0
until
CommitWidth
).
map
(
i
=>
headPtr
+
i
.
U
)
val
commitIndex
=
commitPtr
.
map
(
ptr
=>
ptr
(
indexWidth
-
1
,
0
))
val
commitIndex
=
(
0
until
CommitWidth
).
map
(
i
=>
headPtr
+
i
.
U
).
map
(
_
.
value
)
// deq: starting from dispatch ptr
val
deqPtr
=
(
0
until
enqnum
).
map
(
i
=>
dispatchPtr
+
i
.
U
)
val
deqIndex
=
deqPtr
.
map
(
ptr
=>
ptr
(
indexWidth
-
1
,
0
))
val
deqIndex
=
(
0
until
deqnum
).
map
(
i
=>
dispatchPtr
+
i
.
U
).
map
(
_
.
value
)
// enq: starting from tail ptr
val
enqPtr
=
(
0
until
enqnum
).
map
(
i
=>
tailPtr
+
i
.
U
)
val
enqIndex
=
enqPtr
.
map
(
ptr
=>
ptr
(
indexWidth
-
1
,
0
))
val
enqIndex
=
(
0
until
enqnum
).
map
(
i
=>
tailPtr
+
i
.
U
).
map
(
_
.
value
)
def
distanceBetween
(
left
:
UInt
,
right
:
UInt
)
=
{
Mux
(
left
(
indexWidth
)
===
right
(
indexWidth
),
left
(
indexWidth
-
1
,
0
)
-
right
(
indexWidth
-
1
,
0
),
size
.
U
+
left
(
indexWidth
-
1
,
0
)
-
right
(
indexWidth
-
1
,
0
))
}
val
validEntries
=
distanceBetween
(
tailPtr
,
headPtr
)
val
dispatchEntries
=
distanceBetween
(
tailPtr
,
dispatchPtr
)
val
commitEntries
=
validEntries
-
dispatchEntries
val
emptyEntries
=
size
.
U
-
validEntries
val
isFull
=
tailDirection
=/=
headDirection
&&
tailIndex
===
headIndex
val
isFullDispatch
=
dispatchDirection
=/=
headDirection
&&
dispatchIndex
===
headIndex
def
rangeMask
(
start
:
UInt
,
end
:
UInt
)
:
UInt
=
{
val
startMask
=
(
1.
U
((
size
+
1
).
W
)
<<
start
(
indexWidth
-
1
,
0
)
).
asUInt
-
1.
U
val
endMask
=
(
1.
U
((
size
+
1
).
W
)
<<
end
(
indexWidth
-
1
,
0
)
).
asUInt
-
1.
U
def
rangeMask
(
start
:
CircularQueuePtr
,
end
:
CircularQueuePtr
)
:
UInt
=
{
val
startMask
=
(
1.
U
((
size
+
1
).
W
)
<<
start
.
value
).
asUInt
-
1.
U
val
endMask
=
(
1.
U
((
size
+
1
).
W
)
<<
end
.
value
).
asUInt
-
1.
U
val
xorMask
=
startMask
(
size
-
1
,
0
)
^
endMask
(
size
-
1
,
0
)
Mux
(
start
(
indexWidth
)
===
end
(
indexWidth
)
,
xorMask
,
~
xorMask
)
Mux
(
start
.
flag
===
end
.
flag
,
xorMask
,
~
xorMask
)
}
val
dispatchedMask
=
rangeMask
(
headPtr
,
dispatchPtr
)
...
...
@@ -185,25 +169,25 @@ class DispatchQueue(size: Int, enqnum: Int, deqnum: Int, replayWidth: Int) exten
// if all bits are one, we need to keep the index unchanged
// 00000000, 11111111: unchanged
// otherwise: firstMaskPosition
val
cancelPosition
=
Mux
(!
Cat
(
needCancel
).
orR
||
allCancel
,
tail
Index
,
getFirstMaskPosition
(
needCancel
))
val
replayPosition
=
Mux
(!
someReplay
||
allReplay
,
dispatch
Index
,
getFirstMaskPosition
(
maskedNeedReplay
.
asBools
))
val
cancelPosition
=
Mux
(!
Cat
(
needCancel
).
orR
||
allCancel
,
tail
Ptr
.
value
,
getFirstMaskPosition
(
needCancel
))
val
replayPosition
=
Mux
(!
someReplay
||
allReplay
,
dispatch
Ptr
.
value
,
getFirstMaskPosition
(
maskedNeedReplay
.
asBools
))
XSDebug
(
replayValid
,
p
"getFirstMaskPosition: ${getFirstMaskPosition(maskedNeedReplay.asBools)}\n"
)
assert
(
cancelPosition
.
getWidth
==
indexWidth
)
assert
(
replayPosition
.
getWidth
==
indexWidth
)
// If the highest bit is one, the direction flips.
// Otherwise, the direction keeps the same.
val
tailCancelPtr
Direction
=
Mux
(
needCancel
(
size
-
1
),
~
tailDirection
,
tailDirection
)
val
tailCancelPtrIndex
=
Mux
(
needCancel
(
size
-
1
)
&&
!
allCancel
,
~
cancelPosition
+
1.
U
,
cancelPosition
)
val
tailCancelPtr
=
Cat
(
tailCancelPtrDirection
,
tailCancelPtrIndex
)
val
tailCancelPtr
=
Wire
(
new
CircularQueuePtr
(
size
)
)
tailCancelPtr
.
flag
:=
Mux
(
needCancel
(
size
-
1
),
~
tailPtr
.
flag
,
tailPtr
.
flag
)
tailCancelPtr
.
value
:=
Mux
(
needCancel
(
size
-
1
)
&&
!
allCancel
,
size
.
U
-
cancelPosition
,
cancelPosition
)
// In case of branch mis-prediction:
// If mis-prediction happens after dispatchPtr, the pointer keeps the same as before.
// If dispatchPtr needs to be cancelled, reset dispatchPtr to tailPtr.
val
dispatchCancelPtr
=
Mux
(
needCancel
(
dispatch
Index
)
||
dispatchEntries
===
0.
U
,
tailCancelPtr
,
dispatchPtr
)
val
dispatchCancelPtr
=
Mux
(
needCancel
(
dispatch
Ptr
.
value
)
||
dispatchEntries
===
0.
U
,
tailCancelPtr
,
dispatchPtr
)
// In case of replay, we need to walk back and recover preg states in the busy table.
// We keep track of the number of entries needed to be walked instead of target position to reduce overhead
// for 11111111, replayPosition is unuseful. We naively set Cnt to size.U
val
dispatchReplayCnt
=
Mux
(
allReplay
,
size
.
U
,
Mux
(
maskedNeedReplay
(
size
-
1
),
dispatch
Index
+
replayPosition
,
dispatchIndex
-
replayPosition
))
val
dispatchReplayCntReg
=
RegInit
(
0.
U
((
indexWidth
+
1
).
W
)
)
val
dispatchReplayCnt
=
Mux
(
allReplay
,
size
.
U
,
Mux
(
maskedNeedReplay
(
size
-
1
),
dispatch
Ptr
.
value
+
replayPosition
,
dispatchPtr
.
value
-
replayPosition
))
val
dispatchReplayCntReg
=
RegInit
(
0.
U
)
// actually, if deqIndex points to head uops and they are replayed, there's no need for extraWalk
// however, to simplify logic, we simply let it do extra walk now
val
needExtraReplayWalk
=
Cat
((
0
until
deqnum
).
map
(
i
=>
needReplay
(
deqIndex
(
i
)))).
orR
...
...
@@ -212,7 +196,7 @@ class DispatchQueue(size: Int, enqnum: Int, deqnum: Int, replayWidth: Int) exten
val
dispatchReplayStep
=
Mux
(
needExtraReplayWalkReg
,
0.
U
,
Mux
(
dispatchReplayCntReg
>
replayWidth
.
U
,
replayWidth
.
U
,
dispatchReplayCntReg
))
when
(
exceptionValid
)
{
dispatchReplayCntReg
:=
0.
U
}.
elsewhen
(
inReplayWalk
&&
mispredictionValid
&&
needCancel
(
dispatch
Index
-
1.
U
))
{
}.
elsewhen
(
inReplayWalk
&&
mispredictionValid
&&
needCancel
(
dispatch
Ptr
.
value
-
1.
U
))
{
val
distance
=
distanceBetween
(
dispatchPtr
,
tailCancelPtr
)
dispatchReplayCntReg
:=
Mux
(
dispatchReplayCntReg
>
distance
,
dispatchReplayCntReg
-
distance
,
0.
U
)
}.
elsewhen
(
replayValid
&&
someReplay
)
{
...
...
@@ -222,7 +206,7 @@ class DispatchQueue(size: Int, enqnum: Int, deqnum: Int, replayWidth: Int) exten
}
io
.
inReplayWalk
:=
inReplayWalk
val
replayIndex
=
(
0
until
replayWidth
).
map
(
i
=>
(
dispatchPtr
-
(
i
+
1
).
U
)
(
indexWidth
-
1
,
0
)
)
val
replayIndex
=
(
0
until
replayWidth
).
map
(
i
=>
(
dispatchPtr
-
(
i
+
1
).
U
)
.
value
)
for
(
i
<-
0
until
replayWidth
)
{
val
index
=
Mux
(
needExtraReplayWalkReg
,
(
if
(
i
<
deqnum
)
deqIndex
(
i
)
else
0.
U
),
replayIndex
(
i
))
val
shouldResetDest
=
inReplayWalk
&&
stateEntries
(
index
)
===
s_valid
...
...
@@ -247,7 +231,7 @@ class DispatchQueue(size: Int, enqnum: Int, deqnum: Int, replayWidth: Int) exten
val
numEnq
=
PriorityEncoder
(
io
.
enq
.
map
(!
_
.
fire
())
:+
true
.
B
)
XSError
(
numEnq
=/=
0.
U
&&
(
mispredictionValid
||
exceptionValid
),
"should not enqueue when redirect\n"
)
tailPtr
:=
Mux
(
exceptionValid
,
0.
U
,
0.
U
.
asTypeOf
(
new
CircularQueuePtr
(
size
))
,
Mux
(
mispredictionValid
,
tailCancelPtr
,
tailPtr
+
numEnq
)
...
...
@@ -263,13 +247,13 @@ class DispatchQueue(size: Int, enqnum: Int, deqnum: Int, replayWidth: Int) exten
}
:+
true
.
B
)
val
numDeq
=
Mux
(
numDeqTry
>
numDeqFire
,
numDeqFire
,
numDeqTry
)
dispatchPtr
:=
Mux
(
exceptionValid
,
0.
U
,
Mux
(
mispredictionValid
&&
(!
inReplayWalk
||
needCancel
(
dispatch
Index
-
1.
U
)),
0.
U
.
asTypeOf
(
new
CircularQueuePtr
(
size
))
,
Mux
(
mispredictionValid
&&
(!
inReplayWalk
||
needCancel
(
dispatch
Ptr
.
value
-
1.
U
)),
dispatchCancelPtr
,
Mux
(
inReplayWalk
,
dispatchPtr
-
dispatchReplayStep
,
dispatchPtr
+
numDeq
))
)
headPtr
:=
Mux
(
exceptionValid
,
0.
U
,
headPtr
+
numCommit
)
headPtr
:=
Mux
(
exceptionValid
,
0.
U
.
asTypeOf
(
new
CircularQueuePtr
(
size
))
,
headPtr
+
numCommit
)
/**
* Part 4: set output and input
...
...
@@ -287,14 +271,6 @@ class DispatchQueue(size: Int, enqnum: Int, deqnum: Int, replayWidth: Int) exten
}
// debug: dump dispatch queue states
def
greaterOrEqualThan
(
left
:
UInt
,
right
:
UInt
)
=
{
Mux
(
left
(
indexWidth
)
===
right
(
indexWidth
),
left
(
indexWidth
-
1
,
0
)
>=
right
(
indexWidth
-
1
,
0
),
left
(
indexWidth
-
1
,
0
)
<=
right
(
indexWidth
-
1
,
0
)
)
}
XSDebug
(
p
"head: $headPtr, tail: $tailPtr, dispatch: $dispatchPtr, "
+
p
"replayCnt: $dispatchReplayCntReg, needExtraReplayWalkReg: $needExtraReplayWalkReg\n"
)
XSDebug
(
p
"state: "
)
...
...
@@ -306,14 +282,14 @@ class DispatchQueue(size: Int, enqnum: Int, deqnum: Int, replayWidth: Int) exten
XSDebug
(
false
,
true
.
B
,
"\n"
)
XSDebug
(
p
"ptr: "
)
(
0
until
size
).
reverse
.
foreach
{
i
=>
val
isPtr
=
i
.
U
===
head
Index
||
i
.
U
===
tailIndex
||
i
.
U
===
dispatchIndex
val
isPtr
=
i
.
U
===
head
Ptr
.
value
||
i
.
U
===
tailPtr
.
value
||
i
.
U
===
dispatchPtr
.
value
XSDebug
(
false
,
isPtr
,
"^"
)
XSDebug
(
false
,
!
isPtr
,
" "
)
}
XSDebug
(
false
,
true
.
B
,
"\n"
)
XSError
(
!
greaterOrEqualThan
(
tailPtr
,
head
Ptr
),
p
"assert greaterOrEqualThan(tailPtr: $tailPtr, headPtr: $headPtr) failed\n"
)
XSError
(
!
greaterOrEqualThan
(
tailPtr
,
dispatch
Ptr
)
&&
!
inReplayWalk
,
p
"assert greaterOrEqualThan(tailPtr: $tailPtr, dispatchPtr: $dispatchPtr) failed\n"
)
XSError
(
!
greaterOrEqualThan
(
dispatchPtr
,
head
Ptr
),
p
"assert greaterOrEqualThan(dispatchPtr: $dispatchPtr, headPtr: $headPtr) failed\n"
)
XSError
(
isAfter
(
headPtr
,
tail
Ptr
),
p
"assert greaterOrEqualThan(tailPtr: $tailPtr, headPtr: $headPtr) failed\n"
)
XSError
(
isAfter
(
dispatchPtr
,
tail
Ptr
)
&&
!
inReplayWalk
,
p
"assert greaterOrEqualThan(tailPtr: $tailPtr, dispatchPtr: $dispatchPtr) failed\n"
)
XSError
(
isAfter
(
headPtr
,
dispatch
Ptr
),
p
"assert greaterOrEqualThan(dispatchPtr: $dispatchPtr, headPtr: $headPtr) failed\n"
)
XSError
(
validEntries
<
dispatchEntries
&&
!
inReplayWalk
,
"validEntries should be less than dispatchEntries\n"
)
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录