Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
OpenXiangShan
XiangShan
提交
6a9a0533
X
XiangShan
项目概览
OpenXiangShan
/
XiangShan
10 个月 前同步成功
通知
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 搜索 >>
提交
6a9a0533
编写于
11月 29, 2020
作者:
Y
Yinan Xu
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
dispatch1: block valid when blockBackward or noSpecExec
上级
5e33e227
变更
4
隐藏空白更改
内联
并排
Showing
4 changed file
with
66 addition
and
39 deletion
+66
-39
src/main/scala/xiangshan/backend/decode/DecodeBuffer.scala
src/main/scala/xiangshan/backend/decode/DecodeBuffer.scala
+5
-4
src/main/scala/xiangshan/backend/dispatch/Dispatch.scala
src/main/scala/xiangshan/backend/dispatch/Dispatch.scala
+1
-0
src/main/scala/xiangshan/backend/dispatch/Dispatch1.scala
src/main/scala/xiangshan/backend/dispatch/Dispatch1.scala
+38
-24
src/main/scala/xiangshan/backend/roq/Roq.scala
src/main/scala/xiangshan/backend/roq/Roq.scala
+22
-11
未找到文件。
src/main/scala/xiangshan/backend/decode/DecodeBuffer.scala
浏览文件 @
6a9a0533
...
...
@@ -43,10 +43,11 @@ class DecodeBuffer extends XSModule {
if
(
i
>
0
){
io
.
out
(
i
).
valid
:=
validVec
(
i
)
&&
!
flush
&&
Mux
(
r
.
ctrl
.
noSpecExec
,
!
ParallelOR
(
validVec
.
take
(
i
)),
!
ParallelOR
(
io
.
out
.
zip
(
validVec
).
take
(
i
).
map
(
x
=>
x
.
_2
&&
x
.
_1
.
bits
.
ctrl
.
noSpecExec
))
)
&&
!
io
.
isWalking
// Mux(r.ctrl.noSpecExec,
!
ParallelOR
(
validVec
.
take
(
i
))
//,
// !ParallelOR(io.out.zip(validVec).take(i).map(x => x._2 && x._1.bits.ctrl.noSpecExec))
//) &&
!
io
.
isWalking
}
else
{
require
(
i
==
0
)
io
.
out
(
i
).
valid
:=
validVec
(
i
)
&&
!
flush
&&
!
io
.
isWalking
...
...
src/main/scala/xiangshan/backend/dispatch/Dispatch.scala
浏览文件 @
6a9a0533
...
...
@@ -31,6 +31,7 @@ class Dispatch extends XSModule {
// 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
))
...
...
src/main/scala/xiangshan/backend/dispatch/Dispatch1.scala
浏览文件 @
6a9a0533
...
...
@@ -17,6 +17,7 @@ class Dispatch1 extends XSModule {
// 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
))
...
...
@@ -41,10 +42,12 @@ class Dispatch1 extends XSModule {
* Part 1: choose the target dispatch queue and the corresponding write ports
*/
// valid bits for different dispatch queues
val
isInt
=
WireInit
(
VecInit
(
io
.
fromRename
.
map
(
uop
=>
FuType
.
isIntExu
(
uop
.
bits
.
ctrl
.
fuType
))))
val
isFp
=
WireInit
(
VecInit
(
io
.
fromRename
.
map
(
uop
=>
FuType
.
isFpExu
(
uop
.
bits
.
ctrl
.
fuType
))))
val
isLs
=
WireInit
(
VecInit
(
io
.
fromRename
.
map
(
uop
=>
FuType
.
isMemExu
(
uop
.
bits
.
ctrl
.
fuType
))))
val
isStore
=
WireInit
(
VecInit
(
io
.
fromRename
.
map
(
uop
=>
FuType
.
isStoreExu
(
uop
.
bits
.
ctrl
.
fuType
))))
val
isInt
=
VecInit
(
io
.
fromRename
.
map
(
req
=>
FuType
.
isIntExu
(
req
.
bits
.
ctrl
.
fuType
)))
val
isFp
=
VecInit
(
io
.
fromRename
.
map
(
req
=>
FuType
.
isFpExu
(
req
.
bits
.
ctrl
.
fuType
)))
val
isLs
=
VecInit
(
io
.
fromRename
.
map
(
req
=>
FuType
.
isMemExu
(
req
.
bits
.
ctrl
.
fuType
)))
val
isStore
=
VecInit
(
io
.
fromRename
.
map
(
req
=>
FuType
.
isStoreExu
(
req
.
bits
.
ctrl
.
fuType
)))
val
isBlockBackward
=
VecInit
(
io
.
fromRename
.
map
(
_
.
bits
.
ctrl
.
blockBackward
))
val
isNoSpecExec
=
VecInit
(
io
.
fromRename
.
map
(
_
.
bits
.
ctrl
.
noSpecExec
))
// generate index mapping
val
intIndex
=
Module
(
new
IndexMapping
(
RenameWidth
,
dpParams
.
DqEnqWidth
,
false
))
...
...
@@ -79,24 +82,30 @@ class Dispatch1 extends XSModule {
// Thus, for i >= dpParams.DqEnqWidth, we have to check whether it's previous instructions (and the instruction itself) can enqueue.
// However, since, for instructions with indices less than dpParams.DqEnqWidth,
// they can always enter dispatch queue when ROB and LSQ are ready, we don't need to check whether they can enqueue.
//
prevCanOut: previous instructions can enqueue
//
thisIsBlocked: this instruction is blocked by itself
// thisCanOut: this instruction can enqueue
val
thisCanOut
=
(
0
until
RenameWidth
).
map
(
i
=>
// nextCanOut: next instructions can out
// notBlockedByPrevious: previous instructions can enqueue
val
thisIsBlocked
=
VecInit
((
0
until
RenameWidth
).
map
(
i
=>
isNoSpecExec
(
i
)
&&
!
io
.
enqRoq
.
isEmpty
))
val
thisCanOut
=
VecInit
((
0
until
RenameWidth
).
map
(
i
=>
{
// For i in [0, DqEnqWidth), they can always enqueue when ROB and LSQ are ready
if
(
i
<
dpParams
.
DqEnqWidth
)
true
.
B
else
Cat
(
Seq
(
intIndex
,
fpIndex
,
lsIndex
).
map
(
_
.
io
.
reverseMapping
(
i
).
valid
)).
orR
)
val
prevCanOut
=
VecInit
((
0
until
RenameWidth
).
map
(
i
=>
// For i in [0, DqEnqWidth], previous instructions can always enqueue when ROB and LSQ are ready
if
(
i
<=
dpParams
.
DqEnqWidth
)
true
.
B
// They need to check their previous ones
else
Cat
((
dpParams
.
DqEnqWidth
until
i
).
map
(
j
=>
thisCanOut
(
j
)
||
!
io
.
fromRename
(
j
).
valid
)).
andR
if
(
i
<
dpParams
.
DqEnqWidth
)
!
thisIsBlocked
(
i
)
else
Cat
(
Seq
(
intIndex
,
fpIndex
,
lsIndex
).
map
(
_
.
io
.
reverseMapping
(
i
).
valid
)).
orR
&&
!
thisIsBlocked
(
i
)
}))
val
nextCanOut
=
VecInit
((
0
until
RenameWidth
).
map
(
i
=>
(
thisCanOut
(
i
)
&&
!
isBlockBackward
(
i
))
||
!
io
.
fromRename
(
i
).
valid
))
val
notBlockedByPrevious
=
VecInit
((
0
until
RenameWidth
).
map
(
i
=>
if
(
i
==
0
)
true
.
B
else
Cat
((
0
until
i
).
map
(
j
=>
nextCanOut
(
j
))).
andR
))
// this instruction can actually dequeue: 3 conditions
// (1) resources are ready
// (2) previous instructions are ready
val
thisCanActualOut
=
(
0
until
RenameWidth
).
map
(
i
=>
allResourceReady
&&
thisCanOut
(
i
)
&&
prevCanOut
(
i
))
val
thisCanActualOut
=
(
0
until
RenameWidth
).
map
(
i
=>
allResourceReady
&&
thisCanOut
(
i
)
&&
notBlockedByPrevious
(
i
))
val
uopWithIndex
=
Wire
(
Vec
(
RenameWidth
,
new
MicroOp
))
...
...
@@ -129,17 +138,22 @@ class Dispatch1 extends XSModule {
// send uops with correct indexes to dispatch queues
// Note that if one of their previous instructions cannot enqueue, they should not enter dispatch queue.
// We use
prevCanOut
here since mapping(i).valid implies there's a valid instruction that can enqueue,
// We use
notBlockedByPrevious
here since mapping(i).valid implies there's a valid instruction that can enqueue,
// thus we don't need to check thisCanOut.
for
(
i
<-
0
until
dpParams
.
DqEnqWidth
)
{
io
.
toIntDq
(
i
).
bits
:=
uopWithIndex
(
intIndex
.
io
.
mapping
(
i
).
bits
)
io
.
toIntDq
(
i
).
valid
:=
intIndex
.
io
.
mapping
(
i
).
valid
&&
allResourceReady
&&
prevCanOut
(
intIndex
.
io
.
mapping
(
i
).
bits
)
io
.
toFpDq
(
i
).
bits
:=
uopWithIndex
(
fpIndex
.
io
.
mapping
(
i
).
bits
)
io
.
toFpDq
(
i
).
valid
:=
fpIndex
.
io
.
mapping
(
i
).
valid
&&
allResourceReady
&&
prevCanOut
(
fpIndex
.
io
.
mapping
(
i
).
bits
)
io
.
toLsDq
(
i
).
bits
:=
uopWithIndex
(
lsIndex
.
io
.
mapping
(
i
).
bits
)
io
.
toLsDq
(
i
).
valid
:=
lsIndex
.
io
.
mapping
(
i
).
valid
&&
allResourceReady
&&
prevCanOut
(
lsIndex
.
io
.
mapping
(
i
).
bits
)
io
.
toIntDq
(
i
).
bits
:=
uopWithIndex
(
intIndex
.
io
.
mapping
(
i
).
bits
)
io
.
toIntDq
(
i
).
valid
:=
intIndex
.
io
.
mapping
(
i
).
valid
&&
allResourceReady
&&
!
thisIsBlocked
(
intIndex
.
io
.
mapping
(
i
).
bits
)
&&
notBlockedByPrevious
(
intIndex
.
io
.
mapping
(
i
).
bits
)
// NOTE: floating point instructions are not noSpecExec currently
// remove commit /**/ when fp instructions are possible to be noSpecExec
io
.
toFpDq
(
i
).
bits
:=
uopWithIndex
(
fpIndex
.
io
.
mapping
(
i
).
bits
)
io
.
toFpDq
(
i
).
valid
:=
fpIndex
.
io
.
mapping
(
i
).
valid
&&
allResourceReady
&&
/*!thisIsBlocked(fpIndex.io.mapping(i).bits) && */
notBlockedByPrevious
(
fpIndex
.
io
.
mapping
(
i
).
bits
)
io
.
toLsDq
(
i
).
bits
:=
uopWithIndex
(
lsIndex
.
io
.
mapping
(
i
).
bits
)
io
.
toLsDq
(
i
).
valid
:=
lsIndex
.
io
.
mapping
(
i
).
valid
&&
allResourceReady
&&
!
thisIsBlocked
(
lsIndex
.
io
.
mapping
(
i
).
bits
)
&&
notBlockedByPrevious
(
lsIndex
.
io
.
mapping
(
i
).
bits
)
XSDebug
(
io
.
toIntDq
(
i
).
valid
,
p
"pc 0x${Hexadecimal(io.toIntDq(i).bits.cf.pc)} int index $i\n"
)
XSDebug
(
io
.
toFpDq
(
i
).
valid
,
p
"pc 0x${Hexadecimal(io.toFpDq(i).bits.cf.pc )} fp index $i\n"
)
...
...
src/main/scala/xiangshan/backend/roq/Roq.scala
浏览文件 @
6a9a0533
...
...
@@ -44,6 +44,7 @@ class Roq(numWbPorts: Int) extends XSModule with HasCircularQueuePtrHelper {
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
))
...
...
@@ -85,14 +86,13 @@ class Roq(numWbPorts: Int) extends XSModule with HasCircularQueuePtrHelper {
io
.
roqDeqPtr
:=
deqPtrExt
// Dispatch
val
validEntries
=
distanceBetween
(
enqPtrExt
,
deqPtrExt
)
val
firedDispatch
=
Cat
(
io
.
enq
.
req
.
map
(
_
.
valid
))
io
.
enq
.
canAccept
:=
validEntries
<=
(
RoqSize
-
RenameWidth
).
U
XSDebug
(
p
"(ready, valid): ${io.enq.canAccept}, ${Binary(firedDispatch)}\n"
)
val
hasBlockBackward
=
RegInit
(
false
.
B
)
val
hasNoSpecExec
=
RegInit
(
false
.
B
)
val
blockBackwardCommit
=
Cat
(
io
.
commits
.
map
(
c
=>
c
.
valid
&&
!
c
.
bits
.
isWalk
&&
c
.
bits
.
uop
.
ctrl
.
blockBackward
)).
orR
val
noSpecExecCommit
=
Cat
(
io
.
commits
.
map
(
c
=>
c
.
valid
&&
!
c
.
bits
.
isWalk
&&
c
.
bits
.
uop
.
ctrl
.
noSpecExec
)).
orR
when
(
blockBackwardCommit
){
hasBlockBackward
:=
false
.
B
}
when
(
noSpecExecCommit
){
hasNoSpecExec
:=
false
.
B
}
val
noSpecEnq
=
io
.
enq
.
req
.
map
(
i
=>
i
.
bits
.
ctrl
.
blockBackward
)
val
hasNoSpec
=
RegInit
(
false
.
B
)
when
(
isEmpty
){
hasNoSpec
:=
false
.
B
}
val
validDispatch
=
io
.
enq
.
req
.
map
(
_
.
valid
)
XSDebug
(
"(ready, valid): "
)
for
(
i
<-
0
until
RenameWidth
)
{
...
...
@@ -100,19 +100,30 @@ class Roq(numWbPorts: Int) extends XSModule with HasCircularQueuePtrHelper {
val
roqIdxExt
=
enqPtrExt
+
offset
val
roqIdx
=
roqIdxExt
.
value
when
(
io
.
enq
.
req
(
i
).
valid
){
when
(
io
.
enq
.
req
(
i
).
valid
)
{
microOp
(
roqIdx
)
:=
io
.
enq
.
req
(
i
).
bits
valid
(
roqIdx
)
:=
true
.
B
flag
(
roqIdx
)
:=
roqIdxExt
.
flag
writebacked
(
roqIdx
)
:=
false
.
B
when
(
noSpecEnq
(
i
)){
hasNoSpec
:=
true
.
B
}
when
(
io
.
enq
.
req
(
i
).
bits
.
ctrl
.
blockBackward
)
{
hasBlockBackward
:=
true
.
B
}
when
(
io
.
enq
.
req
(
i
).
bits
.
ctrl
.
noSpecExec
)
{
hasNoSpecExec
:=
true
.
B
}
}
io
.
enq
.
resp
(
i
)
:=
roqIdxExt
}
val
validEntries
=
distanceBetween
(
enqPtrExt
,
deqPtrExt
)
val
firedDispatch
=
Cat
(
io
.
enq
.
req
.
map
(
_
.
valid
))
io
.
enq
.
canAccept
:=
(
validEntries
<=
(
RoqSize
-
RenameWidth
).
U
)
&&
!
hasBlockBackward
io
.
enq
.
isEmpty
:=
isEmpty
XSDebug
(
p
"(ready, valid): ${io.enq.canAccept}, ${Binary(firedDispatch)}\n"
)
val
dispatchCnt
=
PopCount
(
firedDispatch
)
enqPtrExt
:=
enqPtrExt
+
PopCount
(
firedDispatch
)
when
(
firedDispatch
.
orR
)
{
enqPtrExt
:=
enqPtrExt
+
dispatchCnt
XSInfo
(
"dispatched %d insts\n"
,
dispatchCnt
)
}
...
...
@@ -144,7 +155,7 @@ class Roq(numWbPorts: Int) extends XSModule with HasCircularQueuePtrHelper {
val
deqUop
=
microOp
(
deqPtr
)
val
deqPtrWritebacked
=
writebacked
(
deqPtr
)
&&
valid
(
deqPtr
)
val
intrEnable
=
io
.
csr
.
intrBitSet
&&
!
isEmpty
&&
!
hasNoSpec
&&
val
intrEnable
=
io
.
csr
.
intrBitSet
&&
!
isEmpty
&&
!
hasNoSpec
Exec
&&
deqUop
.
ctrl
.
commitType
=/=
CommitType
.
STORE
&&
deqUop
.
ctrl
.
commitType
=/=
CommitType
.
LOAD
// TODO: wanna check why has hasCsr(hasNoSpec)
val
exceptionEnable
=
deqPtrWritebacked
&&
Cat
(
deqUop
.
cf
.
exceptionVec
).
orR
()
val
isFlushPipe
=
deqPtrWritebacked
&&
deqUop
.
ctrl
.
flushPipe
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录