Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
OpenXiangShan
XiangShan
提交
8a4dc19a
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 搜索 >>
提交
8a4dc19a
编写于
11月 08, 2020
作者:
L
LinJiawei
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Multiplier: add a array multiplier
上级
349d2fb5
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
140 addition
and
9 deletion
+140
-9
src/main/scala/xiangshan/backend/fu/FunctionUnit.scala
src/main/scala/xiangshan/backend/fu/FunctionUnit.scala
+1
-1
src/main/scala/xiangshan/backend/fu/Multiplier.scala
src/main/scala/xiangshan/backend/fu/Multiplier.scala
+139
-8
未找到文件。
src/main/scala/xiangshan/backend/fu/FunctionUnit.scala
浏览文件 @
8a4dc19a
...
...
@@ -129,7 +129,7 @@ trait HasPipelineReg { this: FunctionUnit =>
object
FunctionUnit
extends
HasXSParameter
{
def
multiplier
=
new
ArrayMultiplier
(
XLEN
+
1
)
def
multiplier
=
new
ArrayMultiplier
(
XLEN
+
1
,
Seq
(
0
,
2
)
)
def
divider
=
new
Divider
(
XLEN
)
def
alu
=
new
Alu
...
...
src/main/scala/xiangshan/backend/fu/Multiplier.scala
浏览文件 @
8a4dc19a
...
...
@@ -4,8 +4,7 @@ import chisel3._
import
chisel3.util._
import
xiangshan._
import
utils._
import
xiangshan.backend._
import
xiangshan.backend.fu.FunctionUnit._
import
xiangshan.backend.fu.fpu.util.
{
C22
,
C32
,
C53
}
class
MulDivCtrl
extends
Bundle
{
val
sign
=
Bool
()
...
...
@@ -13,14 +12,17 @@ class MulDivCtrl extends Bundle{
val
isHi
=
Bool
()
// return hi bits of result ?
}
class
ArrayMultiplier
(
len
:
Int
,
latency
:
Int
=
3
)
extends
FunctionUnit
(
FuConfig
(
FuType
.
mul
,
2
,
0
,
writeIntRf
=
true
,
writeFpRf
=
false
,
hasRedirect
=
false
,
CertainLatency
(
latency
)),
len
)
class
AbstractMultiplier
(
len
:
Int
,
latency
:
Int
=
2
)
extends
FunctionUnit
(
FuConfig
(
FuType
.
mul
,
2
,
0
,
writeIntRf
=
true
,
writeFpRf
=
false
,
hasRedirect
=
false
,
CertainLatency
(
latency
)),
len
){
val
ctrl
=
IO
(
Input
(
new
MulDivCtrl
))
}
class
NaiveMultiplier
(
len
:
Int
,
latency
:
Int
=
3
)
extends
AbstractMultiplier
(
len
,
latency
)
with
HasPipelineReg
{
val
ctrl
=
IO
(
Input
(
new
MulDivCtrl
))
val
(
src1
,
src2
)
=
(
io
.
in
.
bits
.
src
(
0
),
io
.
in
.
bits
.
src
(
1
))
...
...
@@ -38,5 +40,134 @@ class ArrayMultiplier(len: Int, latency: Int = 3)
val
res
=
Mux
(
ctrlVec
.
last
.
isHi
,
dataVec
.
last
(
2
*
xlen
-
1
,
xlen
),
dataVec
.
last
(
xlen
-
1
,
0
))
io
.
out
.
bits
.
data
:=
Mux
(
ctrlVec
.
last
.
isW
,
SignExt
(
res
(
31
,
0
),
xlen
),
res
)
XSDebug
(
p
"validVec:${Binary(Cat(validVec))} flushVec:${Binary(Cat(flushVec))}\n"
)
}
class
ArrayMultiplier
(
len
:
Int
,
doReg
:
Seq
[
Int
])
extends
AbstractMultiplier
(
len
,
doReg
.
size
)
with
HasPipelineReg
{
val
doRegSorted
=
doReg
.
sortWith
(
_
<
_
)
println
(
doRegSorted
)
val
(
a
,
b
)
=
(
io
.
in
.
bits
.
src
(
0
),
io
.
in
.
bits
.
src
(
1
))
val
b_sext
,
bx2
,
neg_b
,
neg_bx2
=
Wire
(
UInt
((
len
+
1
).
W
))
b_sext
:=
SignExt
(
b
,
len
+
1
)
bx2
:=
b_sext
<<
1
neg_b
:=
(~
b_sext
).
asUInt
()
neg_bx2
:=
neg_b
<<
1
val
columns
:
Array
[
Seq
[
Bool
]]
=
Array
.
fill
(
2
*
len
)(
Seq
())
var
last_x
=
WireInit
(
0.
U
(
3.
W
))
for
(
i
<-
Range
(
0
,
len
,
2
)){
val
x
=
if
(
i
==
0
)
Cat
(
a
(
1
,
0
),
0.
U
(
1.
W
))
else
if
(
i
+
1
==
len
)
SignExt
(
a
(
i
,
i
-
1
),
3
)
else
a
(
i
+
1
,
i
-
1
)
val
pp_temp
=
MuxLookup
(
x
,
0.
U
,
Seq
(
1.
U
->
b_sext
,
2.
U
->
b_sext
,
3.
U
->
bx2
,
4.
U
->
neg_bx2
,
5.
U
->
neg_b
,
6.
U
->
neg_b
))
val
s
=
pp_temp
(
len
)
val
t
=
MuxLookup
(
last_x
,
0.
U
(
2.
W
),
Seq
(
4.
U
->
2.
U
(
2.
W
),
5.
U
->
1.
U
(
2.
W
),
6.
U
->
1.
U
(
2.
W
)
))
last_x
=
x
val
(
pp
,
weight
)
=
i
match
{
case
0
=>
(
Cat
(~
s
,
s
,
s
,
pp_temp
),
0
)
case
n
if
(
n
==
len
-
1
)
||
(
n
==
len
-
2
)
=>
(
Cat
(~
s
,
pp_temp
,
t
),
i
-
2
)
case
_
=>
(
Cat
(
1.
U
(
1.
W
),
~
s
,
pp_temp
,
t
),
i
-
2
)
}
for
(
j
<-
columns
.
indices
){
if
(
j
>=
weight
&&
j
<
(
weight
+
pp
.
getWidth
)){
columns
(
j
)
=
columns
(
j
)
:+
pp
(
j
-
weight
)
}
}
}
def
addOneColumn
(
col
:
Seq
[
Bool
],
cin
:
Seq
[
Bool
])
:
(
Seq
[
Bool
],
Seq
[
Bool
],
Seq
[
Bool
])
=
{
var
sum
=
Seq
[
Bool
]()
var
cout1
=
Seq
[
Bool
]()
var
cout2
=
Seq
[
Bool
]()
col
.
size
match
{
case
1
=>
// do nothing
sum
=
col
++
cin
case
2
=>
val
c22
=
Module
(
new
C22
)
c22
.
io
.
in
:=
col
sum
=
c22
.
io
.
out
(
0
).
asBool
()
+:
cin
cout2
=
Seq
(
c22
.
io
.
out
(
1
).
asBool
())
case
3
=>
val
c32
=
Module
(
new
C32
)
c32
.
io
.
in
:=
col
sum
=
c32
.
io
.
out
(
0
).
asBool
()
+:
cin
cout2
=
Seq
(
c32
.
io
.
out
(
1
).
asBool
())
case
4
=>
val
c53
=
Module
(
new
C53
)
for
((
x
,
y
)
<-
c53
.
io
.
in
.
take
(
4
)
zip
col
){
x
:=
y
}
c53
.
io
.
in
.
last
:=
(
if
(
cin
.
nonEmpty
)
cin
.
head
else
0.
U
)
sum
=
Seq
(
c53
.
io
.
out
(
0
).
asBool
())
++
(
if
(
cin
.
nonEmpty
)
cin
.
drop
(
1
)
else
Nil
)
cout1
=
Seq
(
c53
.
io
.
out
(
1
).
asBool
())
cout2
=
Seq
(
c53
.
io
.
out
(
2
).
asBool
())
case
n
=>
val
cin_1
=
if
(
cin
.
nonEmpty
)
Seq
(
cin
.
head
)
else
Nil
val
cin_2
=
if
(
cin
.
nonEmpty
)
cin
.
drop
(
1
)
else
Nil
val
(
s_1
,
c_1_1
,
c_1_2
)
=
addOneColumn
(
col
take
4
,
cin_1
)
val
(
s_2
,
c_2_1
,
c_2_2
)
=
addOneColumn
(
col
drop
4
,
cin_2
)
sum
=
s_1
++
s_2
cout1
=
c_1_1
++
c_2_1
cout2
=
c_1_2
++
c_2_2
}
(
sum
,
cout1
,
cout2
)
}
def
max
(
in
:
Iterable
[
Int
])
:
Int
=
in
.
reduce
((
a
,
b
)
=>
if
(
a
>
b
)
a
else
b
)
def
addAll
(
cols
:
Array
[
Seq
[
Bool
]],
depth
:
Int
)
:
(
UInt
,
UInt
)
=
{
if
(
max
(
cols
.
map
(
_
.
size
))
<=
2
){
val
sum
=
Cat
(
cols
.
map
(
_
(
0
)).
reverse
)
var
k
=
0
while
(
cols
(
k
).
size
==
1
)
k
=
k
+
1
val
carry
=
Cat
(
cols
.
drop
(
k
).
map
(
_
(
1
)).
reverse
)
(
sum
,
Cat
(
carry
,
0.
U
(
k
.
W
)))
}
else
{
val
columns_next
=
Array
.
fill
(
2
*
len
)(
Seq
[
Bool
]())
var
cout1
,
cout2
=
Seq
[
Bool
]()
for
(
i
<-
cols
.
indices
){
val
(
s
,
c1
,
c2
)
=
addOneColumn
(
cols
(
i
),
cout1
)
columns_next
(
i
)
=
s
++
cout2
cout1
=
c1
cout2
=
c2
}
val
needReg
=
doRegSorted
.
contains
(
depth
)
val
toNextLayer
=
if
(
needReg
)
columns_next
.
map
(
_
.
map
(
PipelineReg
(
doRegSorted
.
indexOf
(
depth
)
+
1
)(
_
)))
else
columns_next
addAll
(
toNextLayer
,
depth
+
1
)
}
}
val
(
sum
,
carry
)
=
addAll
(
cols
=
columns
,
depth
=
0
)
val
result
=
sum
+
carry
var
ctrlVec
=
Seq
(
ctrl
)
for
(
i
<-
1
to
latency
){
ctrlVec
=
ctrlVec
:+
PipelineReg
(
i
)(
ctrlVec
(
i
-
1
))
}
val
xlen
=
io
.
out
.
bits
.
data
.
getWidth
val
res
=
Mux
(
ctrlVec
.
last
.
isHi
,
result
(
2
*
xlen
-
1
,
xlen
),
result
(
xlen
-
1
,
0
))
io
.
out
.
bits
.
data
:=
Mux
(
ctrlVec
.
last
.
isW
,
SignExt
(
res
(
31
,
0
),
xlen
),
res
)
XSDebug
(
p
"validVec:${Binary(Cat(validVec))} flushVec:${Binary(Cat(flushVec))}\n"
)
}
\ No newline at end of file
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录