Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
OpenXiangShan
XiangShan
提交
0c96dad7
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 搜索 >>
提交
0c96dad7
编写于
2月 02, 2021
作者:
Y
Yinan Xu
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
roq: optimize exceptionVec and flushPipe usage
上级
eab03f65
变更
1
隐藏空白更改
内联
并排
Showing
1 changed file
with
141 addition
and
77 deletion
+141
-77
src/main/scala/xiangshan/backend/roq/Roq.scala
src/main/scala/xiangshan/backend/roq/Roq.scala
+141
-77
未找到文件。
src/main/scala/xiangshan/backend/roq/Roq.scala
浏览文件 @
0c96dad7
...
...
@@ -66,9 +66,9 @@ class RoqDispatchData extends RoqCommitInfo {
val
crossPageIPFFix
=
Bool
()
}
class
RoqWbData
extends
XSBundle
{
val
flushPipe
=
Bool
()
}
//
class RoqWbData extends XSBundle {
// //
val flushPipe = Bool()
//
}
class
RoqDeqPtrWrapper
extends
XSModule
with
HasCircularQueuePtrHelper
{
val
io
=
IO
(
new
Bundle
{
...
...
@@ -76,8 +76,7 @@ class RoqDeqPtrWrapper extends XSModule with HasCircularQueuePtrHelper {
val
state
=
Input
(
UInt
(
2.
W
))
val
deq_v
=
Vec
(
CommitWidth
,
Input
(
Bool
()))
val
deq_w
=
Vec
(
CommitWidth
,
Input
(
Bool
()))
val
deq_exceptionVec
=
Vec
(
CommitWidth
,
Input
(
ExceptionVec
()))
val
deq_flushPipe
=
Vec
(
CommitWidth
,
Input
(
Bool
()))
val
exception_state
=
Flipped
(
ValidIO
(
new
RoqExceptionInfo
))
// for flush: when exception occurs, reset deqPtrs to range(0, CommitWidth)
val
intrBitSetReg
=
Input
(
Bool
())
val
hasNoSpecExec
=
Input
(
Bool
())
...
...
@@ -91,20 +90,19 @@ class RoqDeqPtrWrapper extends XSModule with HasCircularQueuePtrHelper {
val
deqPtrVec
=
RegInit
(
VecInit
((
0
until
CommitWidth
).
map
(
_
.
U
.
asTypeOf
(
new
RoqPtr
))))
val
possibleException
=
VecInit
(
io
.
deq_exceptionVec
.
map
(
selectAll
(
_
,
false
)))
// for exceptions (flushPipe included) and interrupts:
// only consider the first instruction
val
intrEnable
=
io
.
intrBitSetReg
&&
!
io
.
hasNoSpecExec
&&
!
CommitType
.
isLoadStore
(
io
.
commitType
)
val
exceptionEnable
=
io
.
deq_w
(
0
)
&&
(
possibleException
(
0
).
asUInt
.
orR
||
io
.
deq_flushPipe
(
0
)
)
val
exceptionEnable
=
io
.
deq_w
(
0
)
&&
io
.
exception_state
.
valid
&&
io
.
exception_state
.
bits
.
roqIdx
===
deqPtrVec
(
0
)
val
redirectOutValid
=
io
.
state
===
0.
U
&&
io
.
deq_v
(
0
)
&&
(
intrEnable
||
exceptionEnable
)
// for normal commits: only to consider when there're no exceptions
// we don't need to consider whether the first instruction has exceptions since it wil trigger exceptions.
val
commit
Blocked
=
VecInit
((
0
until
CommitWidth
).
map
(
i
=>
if
(
i
==
0
)
false
.
B
else
possibleException
(
i
).
asUInt
.
orR
||
io
.
deq_flushPipe
(
i
))
)
val
commit
_exception
=
io
.
exception_state
.
valid
&&
isAfter
(
deqPtrVec
.
last
,
io
.
exception_state
.
bits
.
roqIdx
)
val
canCommit
=
VecInit
((
0
until
CommitWidth
).
map
(
i
=>
io
.
deq_v
(
i
)
&&
io
.
deq_w
(
i
)
&&
!
io
.
misPredBlock
&&
!
io
.
isReplaying
))
val
normalCommitCnt
=
PriorityEncoder
(
canCommit
.
map
(
c
=>
!
c
)
:+
true
.
B
)
// when io.intrBitSetReg or there're possible exceptions in these instructions, only one instruction is allowed to commit
val
allowOnlyOne
=
VecInit
(
commitBlocked
.
drop
(
1
)).
asUInt
.
orR
||
io
.
intrBitSetReg
val
allowOnlyOne
=
commit_exception
||
io
.
intrBitSetReg
val
commitCnt
=
Mux
(
allowOnlyOne
,
canCommit
(
0
),
normalCommitCnt
)
val
resetDeqPtrVec
=
VecInit
((
0
until
CommitWidth
).
map
(
_
.
U
.
asTypeOf
(
new
RoqPtr
)))
...
...
@@ -128,8 +126,8 @@ class RoqEnqPtrWrapper extends XSModule with HasCircularQueuePtrHelper {
val
state
=
Input
(
UInt
(
2.
W
))
val
deq_v
=
Input
(
Bool
())
val
deq_w
=
Input
(
Bool
())
val
deq
_exceptionVec
=
Input
(
ExceptionVec
()
)
val
deq_flushPipe
=
Input
(
Bool
(
))
val
deq
Ptr
=
Input
(
new
RoqPtr
)
val
exception_state
=
Flipped
(
ValidIO
(
new
RoqExceptionInfo
))
val
intrBitSetReg
=
Input
(
Bool
())
val
hasNoSpecExec
=
Input
(
Bool
())
val
commitType
=
Input
(
CommitType
())
...
...
@@ -147,7 +145,7 @@ class RoqEnqPtrWrapper extends XSModule with HasCircularQueuePtrHelper {
// for exceptions (flushPipe included) and interrupts:
// only consider the first instruction
val
intrEnable
=
io
.
intrBitSetReg
&&
!
io
.
hasNoSpecExec
&&
!
CommitType
.
isLoadStore
(
io
.
commitType
)
val
exceptionEnable
=
io
.
deq_w
&&
(
selectAll
(
io
.
deq_exceptionVec
,
false
).
asUInt
.
orR
||
io
.
deq_flushPipe
)
val
exceptionEnable
=
io
.
deq_w
(
0
)
&&
io
.
exception_state
.
valid
&&
io
.
exception_state
.
bits
.
roqIdx
===
io
.
deqPtr
val
redirectOutValid
=
io
.
state
===
0.
U
&&
io
.
deq_v
&&
(
intrEnable
||
exceptionEnable
)
// enqueue
...
...
@@ -166,6 +164,87 @@ class RoqEnqPtrWrapper extends XSModule with HasCircularQueuePtrHelper {
}
class
RoqExceptionInfo
extends
XSBundle
{
// val valid = Bool()
val
roqIdx
=
new
RoqPtr
val
exceptionVec
=
ExceptionVec
()
val
flushPipe
=
Bool
()
def
has_exception
=
exceptionVec
.
asUInt
.
orR
||
flushPipe
// only exceptions are allowed to writeback when enqueue
def
can_writeback
=
exceptionVec
.
asUInt
.
orR
}
class
ExceptionGen
extends
XSModule
with
HasCircularQueuePtrHelper
{
val
io
=
IO
(
new
Bundle
{
val
redirect
=
Input
(
Valid
(
new
Redirect
))
val
flush
=
Input
(
Bool
())
val
enq
=
Vec
(
RenameWidth
,
Flipped
(
ValidIO
(
new
RoqExceptionInfo
)))
val
wb
=
Vec
(
5
,
Flipped
(
ValidIO
(
new
RoqExceptionInfo
)))
val
out
=
ValidIO
(
new
RoqExceptionInfo
)
val
state
=
ValidIO
(
new
RoqExceptionInfo
)
})
val
current
=
Reg
(
Valid
(
new
RoqExceptionInfo
))
// orR the exceptionVec
val
in_enq_valid
=
VecInit
(
io
.
enq
.
map
(
e
=>
e
.
valid
&&
e
.
bits
.
has_exception
))
val
in_wb_valid
=
io
.
wb
.
map
(
w
=>
w
.
valid
&&
w
.
bits
.
has_exception
)
// s0: compare wb(1),wb(2) and wb(3),wb(4)
val
wb_valid
=
in_wb_valid
.
zip
(
io
.
wb
.
map
(
_
.
bits
)).
map
{
case
(
v
,
bits
)
=>
v
&&
!
bits
.
roqIdx
.
needFlush
(
io
.
redirect
,
io
.
flush
)
}
val
csr_wb_bits
=
io
.
wb
(
0
).
bits
val
load_wb_bits
=
Mux
(!
in_wb_valid
(
2
)
||
in_wb_valid
(
1
)
&&
isAfter
(
io
.
wb
(
2
).
bits
.
roqIdx
,
io
.
wb
(
1
).
bits
.
roqIdx
),
io
.
wb
(
1
).
bits
,
io
.
wb
(
2
).
bits
)
val
store_wb_bits
=
Mux
(!
in_wb_valid
(
4
)
||
in_wb_valid
(
3
)
&&
isAfter
(
io
.
wb
(
4
).
bits
.
roqIdx
,
io
.
wb
(
3
).
bits
.
roqIdx
),
io
.
wb
(
3
).
bits
,
io
.
wb
(
4
).
bits
)
val
s0_out_valid
=
RegNext
(
VecInit
(
Seq
(
wb_valid
(
0
),
wb_valid
(
1
)
||
wb_valid
(
2
),
wb_valid
(
3
)
||
wb_valid
(
4
))))
val
s0_out_bits
=
RegNext
(
VecInit
(
Seq
(
csr_wb_bits
,
load_wb_bits
,
store_wb_bits
)))
// s1: compare last four and current flush
val
s1_valid
=
VecInit
(
s0_out_valid
.
zip
(
s0_out_bits
).
map
{
case
(
v
,
b
)
=>
v
&&
!
b
.
roqIdx
.
needFlush
(
io
.
redirect
,
io
.
flush
)
})
val
compare_01_valid
=
s0_out_valid
(
0
)
||
s0_out_valid
(
1
)
val
compare_01_bits
=
Mux
(!
s0_out_valid
(
0
)
||
s0_out_valid
(
1
)
&&
isAfter
(
s0_out_bits
(
0
).
roqIdx
,
s0_out_bits
(
1
).
roqIdx
),
s0_out_bits
(
1
),
s0_out_bits
(
0
))
val
compare_bits
=
Mux
(!
s0_out_valid
(
2
)
||
compare_01_valid
&&
isAfter
(
s0_out_bits
(
2
).
roqIdx
,
compare_01_bits
.
roqIdx
),
compare_01_bits
,
s0_out_bits
(
2
))
val
s1_out_bits
=
RegNext
(
compare_bits
)
val
s1_out_valid
=
RegNext
(
s1_valid
.
asUInt
.
orR
)
val
enq_valid
=
RegNext
(
in_enq_valid
.
asUInt
.
orR
)
val
enq_bits
=
RegNext
(
ParallelPriorityMux
(
in_enq_valid
,
io
.
enq
.
map
(
_
.
bits
)))
// s2: compare the input exception with the current one
// priorities:
// (1) system reset
// (2) current is valid: flush, remain, merge, update
// (3) current is not valid: s1 or enq
val
current_flush
=
current
.
bits
.
roqIdx
.
needFlush
(
io
.
redirect
,
io
.
flush
)
val
s1_flush
=
s1_out_bits
.
roqIdx
.
needFlush
(
io
.
redirect
,
io
.
flush
)
when
(
reset
.
asBool
)
{
current
.
valid
:=
false
.
B
}.
elsewhen
(
current
.
valid
)
{
when
(
current_flush
)
{
current
.
valid
:=
Mux
(
s1_flush
,
false
.
B
,
s1_out_valid
)
}
when
(
s1_out_valid
&&
!
s1_flush
)
{
when
(
isAfter
(
current
.
bits
.
roqIdx
,
s1_out_bits
.
roqIdx
))
{
current
.
bits
:=
s1_out_bits
}.
elsewhen
(
current
.
bits
.
roqIdx
===
s1_out_bits
.
roqIdx
)
{
current
.
bits
.
exceptionVec
:=
(
s1_out_bits
.
exceptionVec
.
asUInt
|
current
.
bits
.
exceptionVec
.
asUInt
).
asTypeOf
(
ExceptionVec
())
current
.
bits
.
flushPipe
:=
s1_out_bits
.
flushPipe
||
current
.
bits
.
flushPipe
}
}
}.
elsewhen
(
s1_out_valid
&&
!
s1_flush
)
{
current
.
valid
:=
true
.
B
current
.
bits
:=
s1_out_bits
}.
elsewhen
(
enq_valid
&&
!(
io
.
redirect
.
valid
||
io
.
flush
))
{
current
.
valid
:=
true
.
B
current
.
bits
:=
enq_bits
}
io
.
out
.
valid
:=
s1_out_valid
||
enq_valid
&&
enq_bits
.
can_writeback
io
.
out
.
bits
:=
Mux
(
s1_out_valid
,
s1_out_bits
,
enq_bits
)
io
.
state
:=
current
}
class
RoqFlushInfo
extends
XSBundle
{
val
ftqIdx
=
new
FtqPtr
val
ftqOffset
=
UInt
(
log2Up
(
PredictWidth
).
W
)
...
...
@@ -255,10 +334,11 @@ class Roq(numWbPorts: Int) extends XSModule with HasCircularQueuePtrHelper {
val
dispatchData
=
Module
(
new
SyncDataModuleTemplate
(
new
RoqDispatchData
,
RoqSize
,
CommitWidth
,
RenameWidth
))
val
dispatchDataRead
=
dispatchData
.
io
.
rdata
val
writebackData
=
Module
(
new
SyncDataModuleTemplate
(
new
RoqWbData
,
RoqSize
,
CommitWidth
,
numWbPorts
))
val
writebackDataRead
=
writebackData
.
io
.
rdata
//
val writebackData = Module(new SyncDataModuleTemplate(new RoqWbData, RoqSize, CommitWidth, numWbPorts))
//
val writebackDataRead = writebackData.io.rdata
val
exceptionDataRead
=
Wire
(
Vec
(
CommitWidth
,
ExceptionVec
()))
val
exceptionGen
=
Module
(
new
ExceptionGen
)
val
exceptionDataRead
=
exceptionGen
.
io
.
state
val
fflagsDataRead
=
Wire
(
Vec
(
CommitWidth
,
UInt
(
5.
W
)))
io
.
roqDeqPtr
:=
deqPtr
...
...
@@ -330,17 +410,19 @@ class Roq(numWbPorts: Int) extends XSModule with HasCircularQueuePtrHelper {
* RedirectOut: Interrupt and Exceptions
*/
val
deqDispatchData
=
dispatchDataRead
(
0
)
val
deqWritebackData
=
writebackDataRead
(
0
)
//
val deqWritebackData = writebackDataRead(0)
val
debug_deqUop
=
debug_microOp
(
deqPtr
.
value
)
val
deqExceptionVec
=
exceptionDataRead
(
0
)
// For MMIO instructions, they should not trigger interrupts since they may be sent to lower level before it writes back.
// However, we cannot determine whether a load/store instruction is MMIO.
// Thus, we don't allow load/store instructions to trigger an interrupt.
val
intrBitSetReg
=
RegNext
(
io
.
csr
.
intrBitSet
)
val
intrEnable
=
intrBitSetReg
&&
!
hasNoSpecExec
&&
!
CommitType
.
isLoadStore
(
deqDispatchData
.
commitType
)
val
exceptionEnable
=
writebacked
(
deqPtr
.
value
)
&&
deqExceptionVec
.
asUInt
.
orR
()
val
isFlushPipe
=
writebacked
(
deqPtr
.
value
)
&&
deqWritebackData
.
flushPipe
val
deqHasExceptionOrFlush
=
exceptionDataRead
.
valid
&&
exceptionDataRead
.
bits
.
roqIdx
===
deqPtr
val
deqHasException
=
deqHasExceptionOrFlush
&&
!
exceptionDataRead
.
bits
.
flushPipe
val
deqHasFlushPipe
=
deqHasExceptionOrFlush
&&
exceptionDataRead
.
bits
.
flushPipe
val
exceptionEnable
=
writebacked
(
deqPtr
.
value
)
&&
deqHasException
val
isFlushPipe
=
writebacked
(
deqPtr
.
value
)
&&
deqHasFlushPipe
io
.
flushOut
.
valid
:=
(
state
===
s_idle
)
&&
valid
(
deqPtr
.
value
)
&&
(
intrEnable
||
exceptionEnable
||
isFlushPipe
)
io
.
flushOut
.
bits
.
ftqIdx
:=
deqDispatchData
.
ftqIdx
...
...
@@ -350,14 +432,14 @@ class Roq(numWbPorts: Int) extends XSModule with HasCircularQueuePtrHelper {
io
.
exception
.
valid
:=
RegNext
(
exceptionHappen
)
io
.
exception
.
bits
.
uop
:=
RegEnable
(
debug_deqUop
,
exceptionHappen
)
io
.
exception
.
bits
.
uop
.
ctrl
.
commitType
:=
RegEnable
(
deqDispatchData
.
commitType
,
exceptionHappen
)
io
.
exception
.
bits
.
uop
.
cf
.
exceptionVec
:=
RegEnable
(
deqE
xceptionVec
,
exceptionHappen
)
io
.
exception
.
bits
.
uop
.
cf
.
exceptionVec
:=
RegEnable
(
exceptionDataRead
.
bits
.
e
xceptionVec
,
exceptionHappen
)
io
.
exception
.
bits
.
uop
.
cf
.
crossPageIPFFix
:=
RegEnable
(
deqDispatchData
.
crossPageIPFFix
,
exceptionHappen
)
io
.
exception
.
bits
.
isInterrupt
:=
RegEnable
(
intrEnable
,
exceptionHappen
)
XSDebug
(
io
.
flushOut
.
valid
,
p
"generate redirect: pc 0x${Hexadecimal(io.exception.bits.uop.cf.pc)} intr $intrEnable "
+
p
"excp $exceptionEnable flushPipe $isFlushPipe "
+
p
"Trap_target 0x${Hexadecimal(io.csr.trapTarget)} exceptionVec ${Binary(
deqE
xceptionVec.asUInt)}\n"
)
p
"Trap_target 0x${Hexadecimal(io.csr.trapTarget)} exceptionVec ${Binary(
exceptionDataRead.bits.e
xceptionVec.asUInt)}\n"
)
/**
...
...
@@ -406,14 +488,14 @@ class Roq(numWbPorts: Int) extends XSModule with HasCircularQueuePtrHelper {
io
.
commits
.
isWalk
:=
state
=/=
s_idle
val
commit_v
=
Mux
(
state
===
s_idle
,
VecInit
(
deqPtrVec
.
map
(
ptr
=>
valid
(
ptr
.
value
))),
VecInit
(
walkPtrVec
.
map
(
ptr
=>
valid
(
ptr
.
value
))))
val
commit_w
=
VecInit
(
deqPtrVec
.
map
(
ptr
=>
writebacked
(
ptr
.
value
)))
val
commit_exception
=
exceptionDataRead
.
zip
(
writebackDataRead
.
map
(
_
.
flushPipe
)).
map
{
case
(
e
,
f
)
=>
e
.
asUInt
.
orR
||
f
}
val
commit_exception
=
exceptionDataRead
.
valid
&&
isAfter
(
deqPtrVec
.
last
,
exceptionDataRead
.
bits
.
roqIdx
)
val
commit_block
=
VecInit
((
0
until
CommitWidth
).
map
(
i
=>
!
commit_w
(
i
)))
val
allowOnlyOneCommit
=
VecInit
(
commit_exception
).
asUInt
.
orR
||
intrBitSetReg
val
allowOnlyOneCommit
=
commit_exception
||
intrBitSetReg
// for instructions that may block others, we don't allow them to commit
for
(
i
<-
0
until
CommitWidth
)
{
// defaults: state === s_idle and instructions commit
// when intrBitSetReg, allow only one instruction to commit at each clock cycle
val
isBlocked
=
if
(
i
!=
0
)
Cat
(
commit_block
.
take
(
i
)).
orR
||
allowOnlyOneCommit
else
intrEnable
||
deq
ExceptionVec
.
asUInt
.
orR
val
isBlocked
=
if
(
i
!=
0
)
Cat
(
commit_block
.
take
(
i
)).
orR
||
allowOnlyOneCommit
else
intrEnable
||
deq
HasException
io
.
commits
.
valid
(
i
)
:=
commit_v
(
i
)
&&
commit_w
(
i
)
&&
!
isBlocked
&&
!
misPredBlock
&&
!
isReplaying
io
.
commits
.
info
(
i
)
:=
dispatchDataRead
(
i
)
...
...
@@ -492,8 +574,7 @@ class Roq(numWbPorts: Int) extends XSModule with HasCircularQueuePtrHelper {
deqPtrGenModule
.
io
.
state
:=
state
deqPtrGenModule
.
io
.
deq_v
:=
commit_v
deqPtrGenModule
.
io
.
deq_w
:=
commit_w
deqPtrGenModule
.
io
.
deq_exceptionVec
:=
exceptionDataRead
deqPtrGenModule
.
io
.
deq_flushPipe
:=
writebackDataRead
.
map
(
_
.
flushPipe
)
deqPtrGenModule
.
io
.
exception_state
:=
exceptionDataRead
deqPtrGenModule
.
io
.
intrBitSetReg
:=
intrBitSetReg
deqPtrGenModule
.
io
.
hasNoSpecExec
:=
hasNoSpecExec
deqPtrGenModule
.
io
.
commitType
:=
deqDispatchData
.
commitType
...
...
@@ -507,8 +588,8 @@ class Roq(numWbPorts: Int) extends XSModule with HasCircularQueuePtrHelper {
enqPtrGenModule
.
io
.
state
:=
state
enqPtrGenModule
.
io
.
deq_v
:=
commit_v
(
0
)
enqPtrGenModule
.
io
.
deq_w
:=
commit_w
(
0
)
enqPtrGenModule
.
io
.
deq
_exceptionVec
:=
deqExceptionVec
enqPtrGenModule
.
io
.
deq_flushPipe
:=
writebackDataRead
(
0
).
flushPipe
enqPtrGenModule
.
io
.
deq
Ptr
:=
deqPtr
enqPtrGenModule
.
io
.
exception_state
:=
exceptionDataRead
enqPtrGenModule
.
io
.
intrBitSetReg
:=
intrBitSetReg
enqPtrGenModule
.
io
.
hasNoSpecExec
:=
hasNoSpecExec
enqPtrGenModule
.
io
.
commitType
:=
deqDispatchData
.
commitType
...
...
@@ -600,14 +681,19 @@ class Roq(numWbPorts: Int) extends XSModule with HasCircularQueuePtrHelper {
// enqueue logic set 6 writebacked to false
for
(
i
<-
0
until
RenameWidth
)
{
when
(
canEnqueue
(
i
))
{
writebacked
(
enqPtrVec
(
i
).
value
)
:=
selectFrontend
(
io
.
enq
.
req
(
i
).
bits
.
cf
.
exceptionVec
,
false
).
asUInt
.
orR
writebacked
(
enqPtrVec
(
i
).
value
)
:=
false
.
B
}
}
when
(
exceptionGen
.
io
.
out
.
valid
)
{
val
wbIdx
=
exceptionGen
.
io
.
out
.
bits
.
roqIdx
.
value
writebacked
(
wbIdx
)
:=
true
.
B
}
// writeback logic set numWbPorts writebacked to true
for
(
i
<-
0
until
numWbPorts
)
{
when
(
io
.
exeWbResults
(
i
).
valid
)
{
val
wbIdx
=
io
.
exeWbResults
(
i
).
bits
.
uop
.
roqIdx
.
value
writebacked
(
wbIdx
)
:=
true
.
B
val
block_wb
=
selectAll
(
io
.
exeWbResults
(
i
).
bits
.
uop
.
cf
.
exceptionVec
,
false
,
true
).
asUInt
.
orR
||
io
.
exeWbResults
(
i
).
bits
.
uop
.
ctrl
.
flushPipe
writebacked
(
wbIdx
)
:=
!
block_wb
}
}
...
...
@@ -645,55 +731,33 @@ class Roq(numWbPorts: Int) extends XSModule with HasCircularQueuePtrHelper {
}
dispatchData
.
io
.
raddr
:=
commitReadAddr_next
writebackData
.
io
.
wen
:=
io
.
exeWbResults
.
map
(
_
.
valid
)
writebackData
.
io
.
waddr
:=
io
.
exeWbResults
.
map
(
_
.
bits
.
uop
.
roqIdx
.
value
)
writebackData
.
io
.
wdata
.
zip
(
io
.
exeWbResults
.
map
(
_
.
bits
)).
map
{
case
(
wdata
,
wb
)
=>
wdata
.
flushPipe
:=
wb
.
uop
.
ctrl
.
flushPipe
}
writebackData
.
io
.
raddr
:=
commitReadAddr_next
for
(
i
<-
0
until
16
)
{
val
exceptionData
=
Module
(
new
SyncDataModuleTemplate
(
Bool
(),
RoqSize
,
CommitWidth
,
RenameWidth
+
writebackCount
(
i
)))
exceptionData
.
suggestName
(
"exceptionData"
)
var
wPortIdx
=
0
for
(
j
<-
0
until
RenameWidth
)
{
exceptionData
.
io
.
wen
(
wPortIdx
)
:=
canEnqueue
(
j
)
exceptionData
.
io
.
waddr
(
wPortIdx
)
:=
enqPtrVec
(
j
).
value
exceptionData
.
io
.
wdata
(
wPortIdx
)
:=
(
if
(
allPossibleSet
.
contains
(
i
))
io
.
enq
.
req
(
j
).
bits
.
cf
.
exceptionVec
(
i
)
else
false
.
B
)
wPortIdx
=
wPortIdx
+
1
}
if
(
csrWbCount
(
i
)
>
0
)
{
exceptionData
.
io
.
wen
(
wPortIdx
)
:=
io
.
exeWbResults
(
6
).
valid
exceptionData
.
io
.
waddr
(
wPortIdx
)
:=
io
.
exeWbResults
(
6
).
bits
.
uop
.
roqIdx
.
value
exceptionData
.
io
.
wdata
(
wPortIdx
)
:=
io
.
exeWbResults
(
6
).
bits
.
uop
.
cf
.
exceptionVec
(
i
)
wPortIdx
=
wPortIdx
+
1
}
if
(
atomicsWbCount
(
i
)
>
0
)
{
exceptionData
.
io
.
wen
(
wPortIdx
)
:=
io
.
exeWbResults
(
4
).
valid
exceptionData
.
io
.
waddr
(
wPortIdx
)
:=
io
.
exeWbResults
(
4
).
bits
.
uop
.
roqIdx
.
value
exceptionData
.
io
.
wdata
(
wPortIdx
)
:=
io
.
exeWbResults
(
4
).
bits
.
uop
.
cf
.
exceptionVec
(
i
)
wPortIdx
=
wPortIdx
+
1
}
if
(
loadWbCount
(
i
)
>
0
)
{
exceptionData
.
io
.
wen
(
wPortIdx
)
:=
io
.
exeWbResults
(
5
).
valid
exceptionData
.
io
.
waddr
(
wPortIdx
)
:=
io
.
exeWbResults
(
5
).
bits
.
uop
.
roqIdx
.
value
exceptionData
.
io
.
wdata
(
wPortIdx
)
:=
io
.
exeWbResults
(
5
).
bits
.
uop
.
cf
.
exceptionVec
(
i
)
wPortIdx
=
wPortIdx
+
1
}
if
(
storeWbCount
(
i
)
>
0
)
{
exceptionData
.
io
.
wen
(
wPortIdx
)
:=
io
.
exeWbResults
(
16
).
valid
exceptionData
.
io
.
waddr
(
wPortIdx
)
:=
io
.
exeWbResults
(
16
).
bits
.
uop
.
roqIdx
.
value
exceptionData
.
io
.
wdata
(
wPortIdx
)
:=
io
.
exeWbResults
(
16
).
bits
.
uop
.
cf
.
exceptionVec
(
i
)
wPortIdx
=
wPortIdx
+
1
exceptionData
.
io
.
wen
(
wPortIdx
)
:=
io
.
exeWbResults
(
17
).
valid
exceptionData
.
io
.
waddr
(
wPortIdx
)
:=
io
.
exeWbResults
(
17
).
bits
.
uop
.
roqIdx
.
value
exceptionData
.
io
.
wdata
(
wPortIdx
)
:=
io
.
exeWbResults
(
17
).
bits
.
uop
.
cf
.
exceptionVec
(
i
)
wPortIdx
=
wPortIdx
+
1
}
// writebackData.io.wen := io.exeWbResults.map(_.valid)
// writebackData.io.waddr := io.exeWbResults.map(_.bits.uop.roqIdx.value)
// writebackData.io.wdata.zip(io.exeWbResults.map(_.bits)).map{ case (wdata, wb) =>
// wdata.flushPipe := wb.uop.ctrl.flushPipe
// }
// writebackData.io.raddr := commitReadAddr_next
exceptionData
.
io
.
raddr
:=
VecInit
(
deqPtrVec_next
.
map
(
_
.
value
))
exceptionDataRead
.
zip
(
exceptionData
.
io
.
rdata
).
map
{
case
(
d
,
r
)
=>
d
(
i
)
:=
r
}
exceptionGen
.
io
.
redirect
<>
io
.
redirect
exceptionGen
.
io
.
flush
:=
io
.
flushOut
.
valid
for
(
i
<-
0
until
RenameWidth
)
{
exceptionGen
.
io
.
enq
(
i
).
valid
:=
canEnqueue
(
i
)
exceptionGen
.
io
.
enq
(
i
).
bits
.
roqIdx
:=
io
.
enq
.
req
(
i
).
bits
.
roqIdx
exceptionGen
.
io
.
enq
(
i
).
bits
.
exceptionVec
:=
selectFrontend
(
io
.
enq
.
req
(
i
).
bits
.
cf
.
exceptionVec
,
false
,
true
)
exceptionGen
.
io
.
enq
(
i
).
bits
.
flushPipe
:=
io
.
enq
.
req
(
i
).
bits
.
ctrl
.
flushPipe
}
def
connect_exception
(
index
:
Int
,
wb_index
:
Int
)
=
{
exceptionGen
.
io
.
wb
(
index
).
valid
:=
io
.
exeWbResults
(
wb_index
).
valid
exceptionGen
.
io
.
wb
(
index
).
bits
.
roqIdx
:=
io
.
exeWbResults
(
wb_index
).
bits
.
uop
.
roqIdx
val
selectFunc
=
(
if
(
wb_index
==
6
)
selectCSR
(
_
,
_
,
_
)
else
if
(
wb_index
==
4
)
selectAtomics
(
_
,
_
,
_
)
else
if
(
wb_index
==
5
)
selectLoad
(
_
,
_
,
_
)
else
selectStore
(
_
,
_
,
_
))
exceptionGen
.
io
.
wb
(
index
).
bits
.
exceptionVec
:=
selectFunc
(
io
.
exeWbResults
(
wb_index
).
bits
.
uop
.
cf
.
exceptionVec
,
false
,
true
)
exceptionGen
.
io
.
wb
(
index
).
bits
.
flushPipe
:=
io
.
exeWbResults
(
wb_index
).
bits
.
uop
.
ctrl
.
flushPipe
}
val
all_exception_possibilities
=
Seq
(
6
,
4
,
5
,
16
,
17
)
all_exception_possibilities
.
zipWithIndex
.
map
{
case
(
p
,
i
)
=>
connect_exception
(
i
,
p
)
}
val
fflagsDataModule
=
Module
(
new
SyncDataModuleTemplate
(
UInt
(
5.
W
),
RoqSize
,
CommitWidth
,
7
))
var
wPortIdx
=
0
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录