Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
OpenXiangShan
XiangShan
提交
cafc71ed
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,发现更多精彩内容 >>
提交
cafc71ed
编写于
7月 30, 2020
作者:
L
LinJiawei
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Wbu: update arbiter
上级
74fe9f47
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
122 addition
and
54 deletion
+122
-54
src/main/scala/xiangshan/backend/Backend.scala
src/main/scala/xiangshan/backend/Backend.scala
+1
-3
src/main/scala/xiangshan/backend/exu/Exu.scala
src/main/scala/xiangshan/backend/exu/Exu.scala
+3
-0
src/main/scala/xiangshan/backend/exu/Wbu.scala
src/main/scala/xiangshan/backend/exu/Wbu.scala
+118
-51
未找到文件。
src/main/scala/xiangshan/backend/Backend.scala
浏览文件 @
cafc71ed
...
...
@@ -208,10 +208,8 @@ class Backend(implicit val p: XSConfig) extends XSModule
fpRf
.
io
.
readPorts
<>
dispatch
.
io
.
readFpRf
++
issueQueues
.
flatMap
(
_
.
io
.
readFpRf
)
memRf
.
io
.
readPorts
<>
issueQueues
.
flatMap
(
_
.
io
.
readIntRf
)
val
wbIntIdx
=
exuConfigs
.
zipWithIndex
.
filter
(
_
.
_1
.
writeIntRf
).
map
(
_
.
_2
)
val
wbFpIdx
=
exuConfigs
.
zipWithIndex
.
filter
(
_
.
_1
.
writeFpRf
).
map
(
_
.
_2
)
val
wbu
=
Module
(
new
Wbu
(
wbIntIdx
,
wbFpIdx
))
val
wbu
=
Module
(
new
Wbu
(
exuConfigs
))
wbu
.
io
.
in
<>
exeWbReqs
val
wbIntResults
=
wbu
.
io
.
toIntRf
...
...
src/main/scala/xiangshan/backend/exu/Exu.scala
浏览文件 @
cafc71ed
...
...
@@ -64,4 +64,7 @@ object Exu {
val
mulDivExeUnitCfg
=
ExuConfig
(
"MulDivExu"
,
Array
(
mulCfg
,
divCfg
),
enableBypass
=
false
)
val
ldExeUnitCfg
=
ExuConfig
(
"LoadExu"
,
Array
(
lduCfg
),
enableBypass
=
false
)
val
stExeUnitCfg
=
ExuConfig
(
"StoreExu"
,
Array
(
stuCfg
),
enableBypass
=
false
)
val
fmacExeUnitCfg
=
ExuConfig
(
"FmacExu"
,
Array
(
fmacCfg
),
enableBypass
=
false
)
val
fmiscExeUnitCfg
=
ExuConfig
(
"FmiscExu"
,
Array
(
fmiscCfg
),
enableBypass
=
false
)
val
fmiscDivExeUnitCfg
=
ExuConfig
(
"FmiscDivExu"
,
Array
(
fmiscCfg
,
fDivSqrtCfg
),
enableBypass
=
false
)
}
src/main/scala/xiangshan/backend/exu/Wbu.scala
浏览文件 @
cafc71ed
...
...
@@ -38,7 +38,7 @@ class WriteBackArbMtoN(m: Int, n: Int) extends XSModule {
}
class
Wbu
(
wbIntIdx
:
Array
[
Int
],
wbFpIdx
:
Array
[
Int
])
extends
XSModule
{
class
Wbu
(
exuConfigs
:
Array
[
ExuConfig
])
extends
XSModule
{
val
io
=
IO
(
new
Bundle
()
{
val
in
=
Vec
(
exuParameters
.
ExuCnt
,
Flipped
(
DecoupledIO
(
new
ExuOutput
)))
...
...
@@ -47,33 +47,42 @@ class Wbu(wbIntIdx: Array[Int], wbFpIdx: Array[Int]) extends XSModule{
val
toFpRf
=
Vec
(
NRFpWritePorts
,
ValidIO
(
new
ExuOutput
))
})
require
(
io
.
in
.
length
==
exuConfigs
.
length
)
def
exuOutToRfReq
(
exuOutVec
:
Vec
[
DecoupledIO
[
ExuOutput
]],
fp
:
Boolean
)
:
Seq
[(
DecoupledIO
[
ExuOutput
]
,
Int
)]
=
{
val
wbIdxSet
=
if
(
fp
)
wbFpIdx
else
wbIntIdx
exuOutVec
.
zipWithIndex
.
filter
(
x
=>
wbIdxSet
.
contains
(
x
.
_2
)).
map
({
case
(
exuOut
,
idx
)
=>
val
req
=
Wire
(
Decoupled
(
new
ExuOutput
))
req
.
valid
:=
exuOut
.
valid
&&
{
if
(
fp
)
exuOut
.
bits
.
uop
.
ctrl
.
fpWen
else
exuOut
.
bits
.
uop
.
ctrl
.
rfWen
}
req
.
bits
:=
exuOut
.
bits
(
req
,
idx
)
})
(
exuOut
:
DecoupledIO
[
ExuOutput
],
fp
:
Boolean
)
:
DecoupledIO
[
ExuOutput
]
=
{
val
req
=
Wire
(
Decoupled
(
new
ExuOutput
))
req
.
valid
:=
exuOut
.
valid
&&
{
if
(
fp
)
exuOut
.
bits
.
uop
.
ctrl
.
fpWen
else
exuOut
.
bits
.
uop
.
ctrl
.
rfWen
}
req
.
bits
:=
exuOut
.
bits
req
}
val
wbIntReq
=
exuOutToRfReq
(
io
.
in
,
fp
=
false
)
// ((ExuOutput, ExuConfig), index) => ((WbReq, ExuConfig), index)
val
wbInt
=
io
.
in
.
zip
(
exuConfigs
).
zipWithIndex
.
filter
(
_
.
_1
.
_2
.
writeIntRf
).
map
(
x
=>
((
exuOutToRfReq
(
x
.
_1
.
_1
,
fp
=
false
),
x
.
_1
.
_2
),
x
.
_2
))
val
wb
FpReq
=
exuOutToRfReq
(
io
.
in
,
fp
=
true
)
val
wb
IntReq
=
wbInt
.
map
(
_
.
_1
)
for
(
i
<-
io
.
in
.
indices
){
val
intReqIdx
=
wbIntReq
.
map
(
_
.
_2
).
indexOf
(
i
)
val
fpReqIdx
=
wbFpReq
.
map
(
_
.
_2
).
indexOf
(
i
)
val
wbFp
=
io
.
in
.
zip
(
exuConfigs
).
zipWithIndex
.
filter
(
_
.
_1
.
_2
.
writeFpRf
).
map
(
x
=>
((
exuOutToRfReq
(
x
.
_1
.
_1
,
fp
=
true
),
x
.
_1
.
_2
),
x
.
_2
))
val
wbFpReq
=
wbFp
.
map
(
_
.
_1
)
val
wbInt
=
intReqIdx
>=
0
val
wbFp
=
fpReqIdx
>=
0
for
(
i
<-
io
.
in
.
indices
){
val
writeIntReqIdx
=
wbInt
.
map
(
_
.
_2
).
indexOf
(
i
)
val
writeFpReqIdx
=
wbFp
.
map
(
_
.
_2
).
indexOf
(
i
)
val
writeIntRf
=
writeIntReqIdx
>=
0
val
writeFpRf
=
writeFpReqIdx
>=
0
val
iReq
=
if
(
w
bInt
)
wbIntReq
(
i
ntReqIdx
).
_1
else
null
val
fReq
=
if
(
w
bFp
)
wbFpReq
(
f
pReqIdx
).
_1
else
null
val
iReq
=
if
(
w
riteIntRf
)
wbIntReq
(
writeI
ntReqIdx
).
_1
else
null
val
fReq
=
if
(
w
riteFpRf
)
wbFpReq
(
writeF
pReqIdx
).
_1
else
null
if
(
w
bInt
&&
wbFp
){
if
(
w
riteIntRf
&&
writeFpRf
){
io
.
in
(
i
).
ready
:=
Mux
(
iReq
.
valid
,
iReq
.
ready
,
Mux
(
fReq
.
valid
,
...
...
@@ -82,46 +91,104 @@ class Wbu(wbIntIdx: Array[Int], wbFpIdx: Array[Int]) extends XSModule{
)
)
assert
(!(
iReq
.
valid
&&
fReq
.
valid
),
s
"Error: iReq and fReq valid at same time, idx=$i"
)
}
else
if
(
w
bInt
){
io
.
in
(
i
).
ready
:=
Mux
(
iReq
.
valid
,
iReq
.
ready
,
true
.
B
)
}
else
if
(
w
bFp
){
io
.
in
(
i
).
ready
:=
Mux
(
fReq
.
valid
,
fReq
.
ready
,
true
.
B
)
}
else
if
(
w
riteIntRf
){
io
.
in
(
i
).
ready
:=
iReq
.
ready
}
else
if
(
w
riteFpRf
){
io
.
in
(
i
).
ready
:=
fReq
.
ready
}
else
{
// store
io
.
in
(
i
).
ready
:=
true
.
B
}
exuConfigs
(
i
)
match
{
case
Exu
.
aluExeUnitCfg
=>
io
.
toRoq
(
i
).
valid
:=
io
.
in
(
i
).
fire
()
&&
!
io
.
in
(
i
).
bits
.
redirectValid
case
Exu
.
jmpExeUnitCfg
=>
io
.
toRoq
(
i
).
valid
:=
io
.
in
(
i
).
fire
()
&&
!
io
.
in
(
i
).
bits
.
redirectValid
case
_
=>
io
.
toRoq
(
i
).
valid
:=
io
.
in
(
i
).
fire
()
}
io
.
toRoq
(
i
).
bits
:=
io
.
in
(
i
).
bits
}
if
(
wbIntIdx
.
length
<
NRIntWritePorts
){
io
.
toIntRf
.
take
(
wbIntIdx
.
length
).
zip
(
wbIntReq
.
map
(
_
.
_1
)).
foreach
(
x
=>
{
x
.
_1
.
bits
:=
x
.
_2
.
bits
x
.
_1
.
valid
:=
x
.
_2
.
valid
x
.
_2
.
ready
:=
true
.
B
})
io
.
toIntRf
.
drop
(
wbIntIdx
.
length
).
foreach
(
_
<>
DontCare
)
}
else
{
val
intArb
=
Module
(
new
WriteBackArbMtoN
(
wbIntIdx
.
length
,
NRIntWritePorts
))
intArb
.
io
.
in
<>
wbIntReq
.
map
(
_
.
_1
)
io
.
toIntRf
<>
intArb
.
io
.
out
def
directConnect
(
rfWrite
:
Valid
[
ExuOutput
],
wbReq
:
DecoupledIO
[
ExuOutput
])
=
{
rfWrite
.
bits
:=
wbReq
.
bits
rfWrite
.
valid
:=
wbReq
.
valid
wbReq
.
ready
:=
true
.
B
}
def
splitN
[
T
](
in
:
Seq
[
T
],
n
:
Int
)
:
Seq
[
Option
[
Seq
[
T
]]]
=
{
require
(
n
>
0
)
if
(
in
.
size
<
n
)
Seq
(
Some
(
in
))
++
Seq
.
fill
(
n
-
1
)(
None
)
else
{
val
m
=
in
.
size
/
n
Some
(
in
.
take
(
m
))
+:
splitN
(
in
.
drop
(
m
),
n
-
1
)
}
}
if
(
wbFpIdx
.
length
<
NRFpWritePorts
){
io
.
toFpRf
.
take
(
wbFpIdx
.
length
).
zip
(
wbFpReq
.
map
(
_
.
_1
)).
foreach
(
x
=>
{
x
.
_1
.
bits
:=
x
.
_2
.
bits
x
.
_1
.
valid
:=
x
.
_2
.
valid
x
.
_2
.
ready
:=
true
.
B
})
io
.
toFpRf
.
drop
(
wbFpIdx
.
length
).
foreach
(
_
<>
DontCare
)
if
(
wbIntReq
.
size
<=
NRIntWritePorts
){
// write ports are enough
io
.
toIntRf
.
take
(
wbIntReq
.
size
).
zip
(
wbIntReq
).
foreach
(
x
=>
directConnect
(
x
.
_1
,
x
.
_2
.
_1
))
if
(
wbIntReq
.
size
<
NRIntWritePorts
){
println
(
s
"Warrning: ${NRIntWritePorts-wbIntReq.size} int write ports are not used!"
)
io
.
toIntRf
.
drop
(
wbIntReq
.
size
).
foreach
(
_
<>
DontCare
)
}
}
else
{
val
fpArb
=
Module
(
new
WriteBackArbMtoN
(
wbFpIdx
.
length
,
NRFpWritePorts
))
fpArb
.
io
.
in
<>
wbFpReq
.
map
(
_
.
_1
)
io
.
toFpRf
<>
fpArb
.
io
.
out
val
directReq
=
wbIntReq
.
filter
(
w
=>
Seq
(
Exu
.
ldExeUnitCfg
,
Exu
.
aluExeUnitCfg
).
contains
(
w
.
_2
))
val
mulReq
=
wbIntReq
.
filter
(
w
=>
Seq
(
Exu
.
mulExeUnitCfg
,
Exu
.
mulDivExeUnitCfg
).
contains
(
w
.
_2
))
val
otherReq
=
splitN
(
wbIntReq
.
filterNot
(
w
=>
Seq
(
Exu
.
ldExeUnitCfg
,
Exu
.
aluExeUnitCfg
,
Exu
.
mulDivExeUnitCfg
,
Exu
.
mulExeUnitCfg
).
contains
(
w
.
_2
)),
mulReq
.
size
)
require
(
directReq
.
size
+
mulReq
.
size
<=
NRIntWritePorts
)
// alu && load: direct connect
io
.
toIntRf
.
take
(
directReq
.
size
).
zip
(
directReq
).
foreach
(
x
=>
directConnect
(
x
.
_1
,
x
.
_2
.
_1
))
for
(
i
<-
mulReq
.
indices
){
val
arbiter
=
Module
(
new
Arbiter
(
new
ExuOutput
,
1
+
otherReq
(
i
).
getOrElse
(
Seq
()).
size
))
arbiter
.
io
.
in
<>
(
mulReq
(
i
)
+:
otherReq
(
i
).
getOrElse
(
Seq
())).
map
(
_
.
_1
)
io
.
toIntRf
.
drop
(
directReq
.
size
)(
i
)
:=
arbiter
.
io
.
out
arbiter
.
io
.
out
.
ready
:=
true
.
B
}
if
(
directReq
.
size
+
mulReq
.
size
<
NRIntWritePorts
){
println
(
s
"Warrning: ${NRIntWritePorts-directReq.size-mulReq.size} int write ports are not used!"
)
io
.
toIntRf
.
drop
(
directReq
.
size
+
mulReq
.
size
).
foreach
(
_
<>
DontCare
)
}
}
i
o
.
toRoq
.
zip
(
io
.
in
).
foreach
(
{
case
(
roq
,
in
)
=>
roq
.
valid
:=
in
.
fire
()
&&
!
in
.
bits
.
redirectValid
roq
.
bits
:=
in
.
bits
}
)
i
f
(
wbFpReq
.
size
<=
NRFpWritePorts
)
{
io
.
toFpRf
.
take
(
wbFpReq
.
size
).
zip
(
wbFpReq
).
foreach
(
x
=>
directConnect
(
x
.
_1
,
x
.
_2
.
_1
)
)
if
(
wbFpReq
.
size
<
NRFpWritePorts
){
println
(
s
"Warrning: ${NRFpWritePorts-wbFpReq.size} fp write ports are not used!"
)
io
.
toFpRf
.
drop
(
wbFpReq
.
size
).
foreach
(
_
<>
DontCare
)
}
}
else
{
val
directReq
=
wbFpReq
.
filter
(
w
=>
Seq
(
Exu
.
ldExeUnitCfg
,
Exu
.
fmacExeUnitCfg
).
contains
(
w
.
_2
))
val
fmiscReq
=
wbFpReq
.
filter
(
w
=>
Seq
(
Exu
.
fmiscExeUnitCfg
,
Exu
.
fmiscDivExeUnitCfg
).
contains
(
w
.
_2
))
val
otherReq
=
splitN
(
wbFpReq
.
filterNot
(
w
=>
Seq
(
Exu
.
ldExeUnitCfg
,
Exu
.
fmacExeUnitCfg
,
Exu
.
fmiscExeUnitCfg
,
Exu
.
fmiscDivExeUnitCfg
).
contains
(
w
.
_2
)),
fmiscReq
.
size
)
require
(
directReq
.
size
+
fmiscReq
.
size
<=
NRFpWritePorts
)
io
.
toFpRf
.
take
(
directReq
.
size
).
zip
(
directReq
).
foreach
(
x
=>
directConnect
(
x
.
_1
,
x
.
_2
.
_1
))
for
(
i
<-
fmiscReq
.
indices
){
val
arbiter
=
Module
(
new
Arbiter
(
new
ExuOutput
,
1
+
otherReq
(
i
).
getOrElse
(
Seq
()).
size
))
arbiter
.
io
.
in
<>
(
fmiscReq
(
i
)
+:
otherReq
(
i
).
getOrElse
(
Seq
())).
map
(
_
.
_1
)
io
.
toFpRf
.
drop
(
directReq
.
size
)(
i
)
:=
arbiter
.
io
.
out
arbiter
.
io
.
out
.
ready
:=
true
.
B
}
if
(
directReq
.
size
+
fmiscReq
.
size
<
NRFpWritePorts
){
println
(
s
"Warrning: ${NRFpWritePorts-directReq.size-fmiscReq.size} fp write ports are not used!"
)
io
.
toFpRf
.
drop
(
directReq
.
size
+
fmiscReq
.
size
).
foreach
(
_
<>
DontCare
)
}
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录