Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
OpenXiangShan
XiangShan
提交
a44ab5cd
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 搜索 >>
提交
a44ab5cd
编写于
7月 28, 2020
作者:
Y
Yinan Xu
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
dispatchqueue: add commit/replay interface
上级
c4459445
变更
1
隐藏空白更改
内联
并排
Showing
1 changed file
with
66 addition
and
40 deletion
+66
-40
src/main/scala/xiangshan/backend/dispatch/DispatchQueue.scala
...main/scala/xiangshan/backend/dispatch/DispatchQueue.scala
+66
-40
未找到文件。
src/main/scala/xiangshan/backend/dispatch/DispatchQueue.scala
浏览文件 @
a44ab5cd
...
...
@@ -15,76 +15,102 @@ class DispatchQueueIO(enqnum: Int, deqnum: Int) extends XSBundle {
new
DispatchQueueIO
(
enqnum
,
deqnum
).
asInstanceOf
[
this.
type
]
}
class
DispatchQEntry
extends
XSBundle
{
val
uop
=
new
MicroOp
val
state
=
UInt
(
2.
W
)
}
// 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
,
name
:
String
)
extends
XSModule
{
val
io
=
IO
(
new
DispatchQueueIO
(
enqnum
,
deqnum
))
val
index_width
=
log2Ceil
(
size
)
val
indexWidth
=
log2Ceil
(
size
)
val
s_valid
::
s_dispatched
::
s_invalid
::
Nil
=
Enum
(
3
)
// queue data array
val
entries
=
Reg
(
Vec
(
size
,
new
MicroOp
))
val
entriesValid
=
Reg
(
Vec
(
size
,
Bool
()))
val
head
=
RegInit
(
0.
U
(
index_width
.
W
))
val
tail
=
RegInit
(
0.
U
(
index_width
.
W
))
val
enq_index
=
Wire
(
Vec
(
enqnum
,
UInt
(
index_width
.
W
)))
val
enq_count
=
Wire
(
Vec
(
enqnum
,
UInt
((
index_width
+
1
).
W
)))
val
deq_index
=
Wire
(
Vec
(
deqnum
,
UInt
(
index_width
.
W
)))
val
head_direction
=
RegInit
(
0.
U
(
1.
W
))
val
tail_direction
=
RegInit
(
0.
U
(
1.
W
))
val
valid_entries
=
Mux
(
head_direction
===
tail_direction
,
tail
-
head
,
size
.
U
+
tail
-
head
)
val
empty_entries
=
size
.
U
-
valid_entries
val
entries
=
Reg
(
Vec
(
size
,
new
DispatchQEntry
))
val
headPtr
=
RegInit
(
0.
U
((
indexWidth
+
1
).
W
))
val
dispatchPtr
=
RegInit
(
0.
U
((
indexWidth
+
1
).
W
))
val
tailPtr
=
RegInit
(
0.
U
((
indexWidth
+
1
).
W
))
val
headIndex
=
headPtr
(
indexWidth
-
1
,
0
)
val
dispatchIndex
=
dispatchPtr
(
indexWidth
-
1
,
0
)
val
tailIndex
=
tailPtr
(
indexWidth
-
1
,
0
)
val
headDirection
=
headPtr
(
indexWidth
)
val
dispatchDirection
=
dispatchPtr
(
indexWidth
)
val
tailDirection
=
tailPtr
(
indexWidth
)
val
commitPtr
=
(
0
until
CommitWidth
).
map
(
i
=>
headPtr
+
i
.
U
)
val
enqPtr
=
(
0
until
enqnum
).
map
(
i
=>
tailPtr
+
i
.
U
)
val
deqPtr
=
(
0
until
enqnum
).
map
(
i
=>
dispatchDirection
+
i
.
U
)
val
commitIndex
=
commitPtr
.
map
(
ptr
=>
ptr
(
indexWidth
-
1
,
0
))
val
enqIndex
=
enqPtr
.
map
(
ptr
=>
ptr
(
indexWidth
-
1
,
0
))
val
deqIndex
=
deqPtr
.
map
(
ptr
=>
ptr
(
indexWidth
-
1
,
0
))
val
validEntries
=
Mux
(
headDirection
===
tailDirection
,
tailIndex
-
headIndex
,
size
.
U
+
tailIndex
-
headIndex
)
val
dispatchEntries
=
Mux
(
dispatchDirection
===
tailDirection
,
tailIndex
-
dispatchIndex
,
size
.
U
+
tailIndex
-
dispatchIndex
)
val
emptyEntries
=
size
.
U
-
validEntries
// check whether valid uops are canceled
val
cancel
led
=
Wire
(
Vec
(
size
,
Bool
()))
val
cancel
=
Wire
(
Vec
(
size
,
Bool
()))
for
(
i
<-
0
until
size
)
{
cancel
led
(
i
)
:=
entries
(
i
)
.
brTag
.
needFlush
(
io
.
redirect
)
cancel
(
i
)
:=
entries
(
i
).
uop
.
brTag
.
needFlush
(
io
.
redirect
)
}
// ca
l
celled uops should be set to invalid from enqueue input
// ca
n
celled uops should be set to invalid from enqueue input
// we don't need to compare their brTags here
for
(
i
<-
0
until
enqnum
)
{
enq_count
(
i
)
:=
PopCount
(
io
.
enq
.
slice
(
0
,
i
+
1
).
map
(
_
.
valid
))
enq_index
(
i
)
:=
(
tail
+
enq_count
(
i
)
-
1.
U
)
%
size
.
U
when
(
io
.
enq
(
i
).
fire
())
{
entries
(
enq
_index
(
i
))
:=
io
.
enq
(
i
).
bits
entries
Valid
(
enq_index
(
i
))
:=
true
.
B
entries
(
enq
Index
(
i
)).
uop
:=
io
.
enq
(
i
).
bits
entries
(
enqIndex
(
i
)).
state
:=
s_valid
}
}
for
(
i
<-
0
until
deqnum
)
{
deq_index
(
i
)
:=
((
head
+
i
.
U
)
%
size
.
U
).
asUInt
()
when
(
io
.
deq
(
i
).
fire
())
{
entries
Valid
(
deq_index
(
i
))
:=
false
.
B
entries
(
deqIndex
(
i
)).
state
:=
s_dispatched
}
}
// cancel uops currently in the queue
for
(
i
<-
0
until
size
)
{
when
(
cancelled
(
i
)
&&
entriesValid
(
i
))
{
entriesValid
(
i
)
:=
false
.
B
val
needCancel
=
cancel
(
i
)
&&
entries
(
i
).
state
===
s_valid
when
(
needCancel
)
{
entries
(
i
).
state
:=
s_invalid
}
XSInfo
(
cancelled
(
i
)
&&
entriesValid
(
i
),
name
+
": valid entry(%d)(pc = %x) cancelled with brTag %x\n"
,
i
.
U
,
entries
(
i
).
cf
.
pc
,
io
.
redirect
.
bits
.
brTag
.
value
)
XSInfo
(
needCancel
,
p
"$name: valid entry($i)(pc = ${Hexadecimal(entries(i).uop.cf.pc)})"
+
p
"cancelled with brTag ${Hexadecimal(io.redirect.bits.brTag.value)}\n"
)
}
// enqueue
val
num
_enq_try
=
enq_count
(
enqnum
-
1
)
val
num
_enq
=
Mux
(
empty_entries
>
num_enq_try
,
num_enq_try
,
empty_e
ntries
)
(
0
until
enqnum
).
map
(
i
=>
io
.
enq
(
i
).
ready
:=
enq_count
(
i
)
<=
num_enq
)
tail
:=
(
tail
+
num_enq
)
%
size
.
U
tail
_direction
:=
((
Cat
(
0.
U
(
1.
W
),
tail
)
+
num_enq
)
>=
size
.
U
).
asUInt
()
^
tail_direction
val
num
EnqTry
=
PriorityEncoder
(
io
.
enq
.
map
(!
_
.
valid
)
:+
true
.
B
)
val
num
Enq
=
Mux
(
emptyEntries
>
numEnqTry
,
numEnqTry
,
emptyE
ntries
)
val
enqReadyBits
=
(
1.
U
<<
numEnq
).
asUInt
()
-
1.
U
(
0
until
enqnum
).
map
(
i
=>
io
.
enq
(
i
).
ready
:=
enqReadyBits
(
i
).
asBool
())
tail
Ptr
:=
tailPtr
+
numEnq
// dequeue
val
num
_deq_try
=
Mux
(
valid_entries
>
deqnum
.
U
,
deqnum
.
U
,
valid_e
ntries
)
val
num
_deq_f
ire
=
PriorityEncoder
((
io
.
deq
.
zipWithIndex
map
{
case
(
deq
,
i
)
=>
!
deq
.
fire
()
&&
entries
Valid
(
deq_index
(
i
))
val
num
DeqTry
=
Mux
(
dispatchEntries
>
deqnum
.
U
,
deqnum
.
U
,
dispatchE
ntries
)
val
num
DeqF
ire
=
PriorityEncoder
((
io
.
deq
.
zipWithIndex
map
{
case
(
deq
,
i
)
=>
!
deq
.
fire
()
&&
entries
(
deqIndex
(
i
)).
state
===
s_valid
})
:+
true
.
B
)
val
num
_deq
=
Mux
(
num_deq_try
>
num_deq_fire
,
num_deq_fire
,
num_deq_t
ry
)
val
num
Deq
=
Mux
(
numDeqTry
>
numDeqFire
,
numDeqFire
,
numDeqT
ry
)
for
(
i
<-
0
until
deqnum
)
{
io
.
deq
(
i
).
bits
:=
entries
(
deq
_index
(
i
))
io
.
deq
(
i
).
bits
:=
entries
(
deq
Index
(
i
)).
uop
// needs to cancel uops trying to dequeue
io
.
deq
(
i
).
valid
:=
(
i
.
U
<
num_deq_try
)
&&
entriesValid
(
deq_index
(
i
))
&&
!
cancelled
(
deq_index
(
i
))
io
.
deq
(
i
).
valid
:=
entries
(
deqIndex
(
i
)).
state
===
s_valid
&&
!
cancel
(
deqIndex
(
i
))
}
// replay
val
numReplay
=
0.
U
dispatchPtr
:=
dispatchPtr
+
numDeq
-
numReplay
// commit
val
numCommit
=
0.
U
val
commitBits
=
(
1.
U
<<
numCommit
).
asUInt
()
-
1.
U
for
(
i
<-
0
until
CommitWidth
)
{
when
(
commitBits
(
i
))
{
entries
(
commitIndex
(
i
)).
state
:=
s_invalid
}
}
head
:=
(
head
+
num_deq
)
%
size
.
U
head_direction
:=
((
Cat
(
0.
U
(
1.
W
),
head
)
+
num_deq
)
>=
size
.
U
).
asUInt
()
^
head_direction
headPtr
:=
headPtr
+
numCommit
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录