Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
OpenXiangShan
XiangShan
提交
9b538998
X
XiangShan
项目概览
OpenXiangShan
/
XiangShan
大约 1 年 前同步成功
通知
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,发现更多精彩内容 >>
提交
9b538998
编写于
10月 23, 2020
作者:
Z
ZhangZifei
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
[WIP] add bpass & wakeup part
上级
f02ea73a
变更
1
隐藏空白更改
内联
并排
Showing
1 changed file
with
93 addition
and
30 deletion
+93
-30
src/main/scala/xiangshan/backend/issue/ReservationStationNew.scala
...scala/xiangshan/backend/issue/ReservationStationNew.scala
+93
-30
未找到文件。
src/main/scala/xiangshan/backend/issue/ReservationStationNew.scala
浏览文件 @
9b538998
...
...
@@ -4,7 +4,20 @@ import chisel3._
import
chisel3.util._
import
xiangshan._
import
xiangshan.backend.exu.
{
Exu
,
ExuConfig
}
import
java.rmi.registry.Registry
import
java.
{
util
=>
ju
}
class
SrcBundle
extends
XSBundle
{
val
src
=
UInt
(
PhyRegIdxWidth
.
W
)
val
state
=
SrcState
()
val
srctype
=
SrcType
()
def
hit
(
uop
:
MicorOp
)
:
Bool
=
{
(
src
===
uop
.
pdest
)
&&
(
state
===
SrcState
.
busy
)
&&
((
srctype
===
SrcType
.
reg
&&
uop
.
ctrl
.
rfWen
)
||
(
srctype
===
SrcType
.
fp
&&
uop
.
ctrl
.
fpWen
))
}
}
class
ReservationStationNew
(
...
...
@@ -52,64 +65,114 @@ class ReservationStationNew
io
<>
DontCare
// TODO: wanna put state machine into ReservationEntry, but difficult to use if we do that, how?
val
entries
=
(
0
until
iqSize
).
map
{
val
entry
=
Module
(
new
ReservationEntry
);
entry
.
io
}
val
tailPtr
=
RegInit
(
0.
U
((
iqIdxWidth
+
1
).
W
))
val
idxQueue
=
RegInit
(
VecInit
((
0
until
qsize
).
map
(
_
.
U
(
idxWidth
.
W
))))
val
emptyQueueTmp
=
VecInit
(
entries
.
map
(
_
.
state
.
empty
))
val
emptyQueue
=
(
0
until
iqSize
).
map
(
emptyQueueTmp
(
idxQueue
(
i
)))
// TODO: may have long latency
// GOAL:
// 1. divide control part and data part
// 2. store control signal in sending RS and send out when after paticular cycles
// 3. one RS only have one paticular delay
// 4. remove the issue stage
// 5. support replay will cause one or two more latency for state machine change
// so would not support replay in current edition.
// here is three logial part:
// control part: psrc(5.W)*3 srcState(1.W)*3 fuOpType/Latency(3.W) roqIdx
// data part: data(64.W)*3
// other part: lsroqIdx and many other signal in uop. may set them to control part(close to dispatch)
// control part:
val
validQueue
=
RegInit
(
VecInit
(
Seq
.
fill
(
false
.
B
)))
val
srcQueue
=
RegInit
(
Vec
(
iqSize
,
Seq
.
fill
(
srcNum
)(
new
SrcBundle
)))
// data part:
val
data
=
Reg
(
Vec
(
iqSize
,
Seq
.
fill
(
3
/*srcNum*/
)(
UInt
(
XLEN
.
W
))))
// other part:
val
uop
=
Reg
(
Vec
(
iqSize
,
new
MicroOp
))
// rs queue part:
val
tailPtr
=
RegInit
(
0.
U
(
idxWidth
+
1
).
W
)
val
idxQueue
=
RegInit
(
VecInit
((
0
until
iqSize
).
map
(
_
.
U
(
idxWidth
.
W
))))
val
readyQueue
=
srcState
.
map
(
_
.
andR
).
zip
(
validQueue
).
map
(
_
&
_
)
// real deq
// TODO: can we apply multi-in multi-out style?
val
(
first
Bubble
,
findBubble
)
=
PriorityEncoderWithFlag
(
empty
Queue
)
val
realDeqIdx
=
firstBubble
val
realDeqValid
=
(
firstBubble
<
tailPtr
)
&&
findBubble
// TODO:
val
(
firstBubble
,
findBubble
)
=
PriorityEncoderWithFlag
(
validQueue
.
map
(!
_
))
val
(
first
Ready
,
findReady
)
=
PriorityEncoderWithFlag
(
valid
Queue
)
val
deqIdx
=
Mux
(
findBubble
,
firstBubble
,
findReady
)
val
deqValid
=
((
firstBubble
<
tailPtr
)
&&
findBubble
)
||
((
firstReady
<
tailPtr
)
&&
findReady
)
val
moveMask
=
{
(
Fill
(
qsize
,
1.
U
(
1.
W
))
<<
realD
eqIdx
)(
qsize
-
1
,
0
)
}
&
Fill
(
qsize
,
realD
eqValid
)
(
Fill
(
iqSize
,
1.
U
(
1.
W
))
<<
d
eqIdx
)(
qsize
-
1
,
0
)
}
&
Fill
(
iqSize
,
d
eqValid
)
for
(
i
<-
0
until
qsize
-
1
){
when
(
moveMask
(
i
)){
idxQueue
(
i
)
:=
idxQueue
(
i
+
1
)
idxQueue
(
i
)
:=
idxQueue
(
i
+
1
)
srcQueue
(
i
)
:=
srcQueue
(
i
+
1
)
validQueue
(
i
)
:=
validQueue
(
i
+
1
)
}
}
when
(
realDeqValid
){
idxQueue
.
last
:=
idxQueue
(
realDeqIdx
)
validQueue
.
last
:=
false
.
B
}
// wakeup and bypass and flush
// data update and control update
// bypass update and wakeup update -> wakeup method and bypass method may not be ok
// for ld/st, still need send to control part, long latency
def
wakeup
(
src
:
SrcState
)
:
(
Bool
,
UInt
)
=
{
val
hitVec
=
extraListenPorts
.
map
(
port
=>
src
.
hit
(
port
.
bits
.
uop
)
&&
port
.
valid
)
assert
(
PopCount
(
hitVec
)===
0.
U
||
PopCount
(
hitVec
)===
1.
U
)
val
hit
=
hitVec
.
orR
(
Mux
(
hit
,
ParallelMux
(
hitVec
zip
extraListenPorts
.
map
(
_
.
data
)))
}
def
bypass
(
src
:
SrcState
)
:
(
Bool
,
Bool
,
UInt
)
=
{
val
hitVec
=
broadcastedUops
.
map
(
port
=>
src
.
hit
(
port
.
bits
)
&&
port
.
valid
)
assert
(
PopCount
(
hitVec
)===
0.
U
||
PopCount
(
hitVec
)===
1.
U
)
val
hit
=
hitVec
.
orR
(
Mux
(
hit
,
RegNext
(
hit
),
ParallelMux
(
RegNext
(
hitVec
)
zip
writeBackedData
))
}
for
(
i
<-
0
until
iqSize
)
{
entries
(
i
).
bypassUops
:=
io
.
boradcastedUops
entries
(
i
).
bypassData
:=
io
.
writeBackedData
entries
(
i
).
wakeup
:=
io
.
extraListenPorts
entries
(
i
).
redirect
:=
io
.
redirect
for
(
j
<-
0
until
srcNum
)
{
val
(
wuHit
,
wuData
)
=
wakeup
(
srcQueue
(
i
)(
j
))
val
(
bpHit
,
bpHitReg
,
bpData
)
=
bypass
(
srcQueue
(
i
)(
j
))
assert
(!(
bpHit
&&
wuHit
))
assert
(!(
bpHitReg
&&
wuHit
))
when
(
wuHit
||
bpHit
)
{
srcQueue
(
i
)(
j
).
srcState
:=
SrcState
.
rdy
}
when
(
wuHit
)
{
data
(
idxQueue
(
i
))(
j
)
:=
wuData
}
when
(
bpHitReg
)
{
data
(
RegNext
(
idxQueue
(
i
)))(
j
)
:=
bpData
}
// NOTE: can not use Mem/Sram to store data, for multi-read/multi-write
}
}
// select
val
rdyQueue
=
entries
.
map
(
_
.
state
.
ready
)
val
selectedIdxRegOH
=
Wire
(
UInt
(
qsize
.
W
))
val
selectMask
=
WireInit
(
VecInit
(
(
0
until
qsize
).
map
(
i
=>
rdyQueue
(
i
)
&&
!(
selectedIdxRegOH
(
i
)
&&
io
.
deq
.
fire
())
// TODO: read it
r
ea
dyQueue
(
i
)
&&
!(
selectedIdxRegOH
(
i
)
&&
io
.
deq
.
fire
())
// TODO: read it
)
))
val
(
selectedIdxWire
,
sel
)
=
PriorityEncoderWithFlag
(
selectMask
)
val
selReg
=
RegNext
(
sel
)
val
(
selectedIdxWire
,
sel
ected
)
=
PriorityEncoderWithFlag
(
selectMask
)
val
selReg
=
RegNext
(
sel
ected
)
val
selectedIdxReg
=
RegNext
(
selectedIdxWire
-
moveMask
(
selectedIdxWire
))
selectedIdxRegOH
:=
UIntToOH
(
selectedIdxReg
)
// fake deq
// TODO: add fake deq later
// TODO: add deq: may have one more latency, but for replay later.
// TODO: may change to another way to deq and select, for there is no Vec, but Seq, change to multi-in multi-out
io
.
deq
.
valid
:=
rdyQueue
(
selectedIdxReg
)
&&
selReg
// TODO: read it and add assert for rdyQueue
io
.
deq
.
bits
.
uop
:=
entries
(
0
).
io
.
out
.
uop
for
(
i
<-
0
until
iqSize
)
{
when
(
idxQueue
(
selectedIdxReg
)===
i
.
U
)
{
io
.
deq
.
bits
.
uop
:=
entries
(
i
).
out
.
uop
}
}
io
.
deq
.
valid
:=
readyQueue
(
selectedIdxReg
)
&&
selReg
// TODO: read it and add assert for rdyQueue
io
.
deq
.
bits
.
uop
:=
uop
(
idxQueue
(
selectedIdxReg
))
io
.
deq
.
bits
.
uop
.
src1
:=
data
(
selectedIdxReg
)(
0
)
if
(
srcNum
>
1
)
{
io
.
deq
.
bits
.
uop
.
src2
:=
data
(
selectedIdxReg
)(
1
)
}
if
(
srcNum
>
2
)
{
io
.
deq
.
bits
.
uop
.
src3
:=
data
(
selectedIdxReg
)(
2
)
}
// TODO: beautify it
io
.
deq
.
bits
.
uop
.
src1State
:=
srcQueue
(
selectedIdxReg
)(
0
).
state
if
(
srcNum
>
1
)
{
io
.
deq
.
bits
.
uop
.
src2State
:=
srcQueue
(
selectedIdxReg
)(
1
).
state
}
if
(
srcNum
>
2
)
{
io
.
deq
.
bits
.
uop
.
src3State
:=
srcQueue
(
selectedIdxReg
)(
2
).
state
}
// enq
val
tailAfterRealDeq
=
tailPtr
-
moveMask
(
tailPtr
.
tail
(
1
))
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录