Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
S
sv2v
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
lvzhengyang
sv2v
Commits
95299c6f
Commit
95299c6f
authored
Nov 19, 2019
by
Zachary Snow
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
conversion of structs with multi-dim fields (resolves #53)
parent
49e4f787
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
183 additions
and
50 deletions
+183
-50
src/Convert/MultiplePacked.hs
+54
-26
src/Convert/Struct.hs
+52
-24
test/basic/flatten_tb.v
+3
-0
test/basic/struct_array_field.sv
+34
-0
test/basic/struct_array_field.v
+40
-0
No files found.
src/Convert/MultiplePacked.hs
View file @
95299c6f
...
@@ -33,7 +33,8 @@ import qualified Data.Map.Strict as Map
...
@@ -33,7 +33,8 @@ import qualified Data.Map.Strict as Map
import
Convert.Traverse
import
Convert.Traverse
import
Language.SystemVerilog.AST
import
Language.SystemVerilog.AST
type
Info
=
Map
.
Map
Identifier
([
Range
],
[
Range
])
type
TypeInfo
=
(
Type
,
[
Range
])
type
Info
=
Map
.
Map
Identifier
TypeInfo
convert
::
[
AST
]
->
[
AST
]
convert
::
[
AST
]
->
[
AST
]
convert
=
map
$
traverseDescriptions
convertDescription
convert
=
map
$
traverseDescriptions
convertDescription
...
@@ -55,16 +56,27 @@ traverseDeclM (ParamType s ident mt) =
...
@@ -55,16 +56,27 @@ traverseDeclM (ParamType s ident mt) =
traverseTypeM
::
Type
->
[
Range
]
->
Identifier
->
State
Info
Type
traverseTypeM
::
Type
->
[
Range
]
->
Identifier
->
State
Info
Type
traverseTypeM
t
a
ident
=
do
traverseTypeM
t
a
ident
=
do
let
(
tf
,
rs
)
=
typeRanges
t
modify
$
Map
.
insert
ident
(
t
,
a
)
t'
<-
case
t
of
Struct
pk
fields
rs
->
do
fields'
<-
flattenFields
fields
return
$
Struct
pk
fields'
rs
Union
pk
fields
rs
->
do
fields'
<-
flattenFields
fields
return
$
Union
pk
fields'
rs
_
->
return
t
let
(
tf
,
rs
)
=
typeRanges
t'
if
length
rs
<=
1
if
length
rs
<=
1
then
do
then
return
t'
modify
$
Map
.
delete
ident
return
t
else
do
else
do
modify
$
Map
.
insert
ident
(
rs
,
a
)
let
r1
:
r2
:
rest
=
rs
let
r1
:
r2
:
rest
=
rs
let
rs'
=
(
combineRanges
r1
r2
)
:
rest
let
rs'
=
(
combineRanges
r1
r2
)
:
rest
return
$
tf
rs'
return
$
tf
rs'
where
flattenFields
fields
=
do
let
(
fieldTypes
,
fieldNames
)
=
unzip
fields
fieldTypes'
<-
mapM
(
\
x
->
traverseTypeM
x
[]
""
)
fieldTypes
return
$
zip
fieldTypes'
fieldNames
-- combines two ranges into one flattened range
-- combines two ranges into one flattened range
combineRanges
::
Range
->
Range
->
Range
combineRanges
::
Range
->
Range
->
Range
...
@@ -110,33 +122,46 @@ traverseLHSM lhs = do
...
@@ -110,33 +122,46 @@ traverseLHSM lhs = do
return
$
fromJust
$
exprToLHS
expr'
return
$
fromJust
$
exprToLHS
expr'
traverseExpr
::
Info
->
Expr
->
Expr
traverseExpr
::
Info
->
Expr
->
Expr
traverseExpr
type
Dims
=
traverseExpr
type
Map
=
rewriteExpr
rewriteExpr
where
where
-- removes the innermost dimensions of the given packed and unpacked
-- removes the innermost dimensions of the given type information, and
-- dimensions, and applies the given transformation to the expression
-- applies the given transformation to the expression
dropLevel
dropLevel
::
(
Expr
->
Expr
)
->
(
TypeInfo
,
Expr
)
->
(
TypeInfo
,
Expr
)
::
(
Expr
->
Expr
)
dropLevel
nest
((
t
,
a
),
expr
)
=
->
([
Range
],
[
Range
],
Expr
)
((
tf
rs'
,
a'
),
nest
expr
)
->
([
Range
],
[
Range
],
Expr
)
where
dropLevel
nest
(
[]
,
[]
,
expr
)
=
(
tf
,
rs
)
=
typeRanges
t
(
[]
,
[]
,
nest
expr
)
(
rs'
,
a'
)
=
case
(
rs
,
a
)
of
dropLevel
nest
(
packed
,
[]
,
expr
)
=
(
[]
,
[]
)
->
(
[]
,
[]
)
(
tail
packed
,
[]
,
nest
expr
)
(
packed
,
[]
)
->
(
tail
packed
,
[]
)
dropLevel
nest
(
packed
,
unpacked
,
expr
)
=
(
packed
,
unpacked
)
->
(
packed
,
tail
unpacked
)
(
packed
,
tail
unpacked
,
nest
expr
)
-- given an expression, returns its type information and a tagged
-- given an expression, returns the packed and unpacked dimensions and a
-- version of the expression, if possible
-- tagged version of the expression, if possible
levels
::
Expr
->
Maybe
(
TypeInfo
,
Expr
)
levels
::
Expr
->
Maybe
([
Range
],
[
Range
],
Expr
)
levels
(
Ident
x
)
=
levels
(
Ident
x
)
=
case
Map
.
lookup
x
type
Dims
of
case
Map
.
lookup
x
type
Map
of
Just
(
a
,
b
)
->
Just
(
a
,
b
,
Ident
$
tag
:
x
)
Just
a
->
Just
(
a
,
Ident
$
tag
:
x
)
Nothing
->
Nothing
Nothing
->
Nothing
levels
(
Bit
expr
a
)
=
levels
(
Bit
expr
a
)
=
fmap
(
dropLevel
$
\
expr'
->
Bit
expr'
a
)
(
levels
expr
)
fmap
(
dropLevel
$
\
expr'
->
Bit
expr'
a
)
(
levels
expr
)
levels
(
Range
expr
a
b
)
=
levels
(
Range
expr
a
b
)
=
fmap
(
dropLevel
$
\
expr'
->
Range
expr'
a
b
)
(
levels
expr
)
fmap
(
dropLevel
$
\
expr'
->
Range
expr'
a
b
)
(
levels
expr
)
levels
(
Dot
expr
x
)
=
case
levels
expr
of
Just
((
Struct
_
fields
[]
,
[]
),
expr'
)
->
dropDot
fields
expr'
Just
((
Union
_
fields
[]
,
[]
),
expr'
)
->
dropDot
fields
expr'
_
->
Nothing
where
dropDot
::
[
Field
]
->
Expr
->
Maybe
(
TypeInfo
,
Expr
)
dropDot
fields
expr'
=
if
Map
.
member
x
fieldMap
then
Just
((
fieldType
,
[]
),
Dot
expr'
x
)
else
Nothing
where
fieldMap
=
Map
.
fromList
$
map
swap
fields
fieldType
=
fieldMap
Map
.!
x
levels
_
=
Nothing
levels
_
=
Nothing
-- given an expression, returns the two innermost packed dimensions and a
-- given an expression, returns the two innermost packed dimensions and a
...
@@ -144,9 +169,12 @@ traverseExpr typeDims =
...
@@ -144,9 +169,12 @@ traverseExpr typeDims =
dims
::
Expr
->
Maybe
(
Range
,
Range
,
Expr
)
dims
::
Expr
->
Maybe
(
Range
,
Range
,
Expr
)
dims
expr
=
dims
expr
=
case
levels
expr
of
case
levels
expr
of
Just
(
dimInner
:
dimOuter
:
_
,
[]
,
expr'
)
->
Just
((
t
,
[]
),
expr'
)
->
case
snd
$
typeRanges
t
of
dimInner
:
dimOuter
:
_
->
Just
(
dimInner
,
dimOuter
,
expr'
)
Just
(
dimInner
,
dimOuter
,
expr'
)
_
->
Nothing
_
->
Nothing
_
->
Nothing
-- if the given range is flipped, the result will flip around the given
-- if the given range is flipped, the result will flip around the given
-- indexing expression
-- indexing expression
...
...
src/Convert/Struct.hs
View file @
95299c6f
...
@@ -97,7 +97,10 @@ collectStructM' constructor isStruct sg fields = do
...
@@ -97,7 +97,10 @@ collectStructM' constructor isStruct sg fields = do
zero
=
Number
"0"
zero
=
Number
"0"
typeRange
::
Type
->
Range
typeRange
::
Type
->
Range
typeRange
t
=
typeRange
t
=
if
null
ranges
then
(
zero
,
zero
)
else
head
ranges
case
ranges
of
[]
->
(
zero
,
zero
)
[
range
]
->
range
_
->
error
"Struct.hs invariant failure"
where
ranges
=
snd
$
typeRanges
t
where
ranges
=
snd
$
typeRanges
t
-- extract info about the fields
-- extract info about the fields
...
@@ -132,13 +135,13 @@ collectStructM' constructor isStruct sg fields = do
...
@@ -132,13 +135,13 @@ collectStructM' constructor isStruct sg fields = do
packedRange
=
(
simplify
$
BinOp
Sub
structSize
(
Number
"1"
),
zero
)
packedRange
=
(
simplify
$
BinOp
Sub
structSize
(
Number
"1"
),
zero
)
unstructType
=
IntegerVector
TLogic
sg
[
packedRange
]
unstructType
=
IntegerVector
TLogic
sg
[
packedRange
]
-- check if this struct can be packed into an integer vector;
integer
-- check if this struct can be packed into an integer vector;
we only
--
atoms and non-integers do not have a definitive size, and so cannot
--
pack flat integer vector types; the fields will be flattened and
--
be packed; net types are not permitted as struct field
s
--
converted by other phase
s
isIntVec
::
Type
->
Bool
is
Flat
IntVec
::
Type
->
Bool
is
IntVec
(
IntegerVector
_
_
_
)
=
True
is
FlatIntVec
(
IntegerVector
_
_
rs
)
=
length
rs
<=
1
isIntVec
_
=
False
is
Flat
IntVec
_
=
False
canUnstructure
=
all
isIntVec
fieldTypes
canUnstructure
=
all
is
Flat
IntVec
fieldTypes
-- convert a struct type to its unstructured equivalent
-- convert a struct type to its unstructured equivalent
...
@@ -221,6 +224,13 @@ packerFnName :: TypeFunc -> Identifier
...
@@ -221,6 +224,13 @@ packerFnName :: TypeFunc -> Identifier
packerFnName
structTf
=
packerFnName
structTf
=
"sv2v_struct_"
++
shortHash
structTf
"sv2v_struct_"
++
shortHash
structTf
-- removes the innermost range from the given type, if possible
dropInnerTypeRange
::
Type
->
Type
dropInnerTypeRange
t
=
case
typeRanges
t
of
(
_
,
[]
)
->
Implicit
Unspecified
[]
(
tf
,
rs
)
->
tf
$
tail
rs
-- This is where the magic happens. This is responsible for converting struct
-- This is where the magic happens. This is responsible for converting struct
-- accesses, assignments, and literals, given appropriate information about the
-- accesses, assignments, and literals, given appropriate information about the
-- structs and the current declaration context. The general strategy involves
-- structs and the current declaration context. The general strategy involves
...
@@ -249,9 +259,7 @@ convertAsgn structs types (lhs, expr) =
...
@@ -249,9 +259,7 @@ convertAsgn structs types (lhs, expr) =
_
->
(
t'
,
LHSBit
l'
e
)
_
->
(
t'
,
LHSBit
l'
e
)
where
where
(
t
,
l'
)
=
convertLHS
l
(
t
,
l'
)
=
convertLHS
l
t'
=
case
typeRanges
t
of
t'
=
dropInnerTypeRange
t
(
_
,
[]
)
->
Implicit
Unspecified
[]
(
tf
,
rs
)
->
tf
$
tail
rs
convertLHS
(
LHSRange
lOuter
NonIndexed
rOuter
)
=
convertLHS
(
LHSRange
lOuter
NonIndexed
rOuter
)
=
case
lOuter'
of
case
lOuter'
of
LHSRange
lInner
NonIndexed
(
_
,
loI
)
->
LHSRange
lInner
NonIndexed
(
_
,
loI
)
->
...
@@ -268,13 +276,23 @@ convertAsgn structs types (lhs, expr) =
...
@@ -268,13 +276,23 @@ convertAsgn structs types (lhs, expr) =
where
where
(
hiO
,
loO
)
=
rOuter
(
hiO
,
loO
)
=
rOuter
(
t
,
lOuter'
)
=
convertLHS
lOuter
(
t
,
lOuter'
)
=
convertLHS
lOuter
convertLHS
(
LHSRange
lOuter
IndexedPlus
(
rOuter
@
(
baseO
,
lenO
)))
=
case
lOuter'
of
LHSRange
lInner
NonIndexed
(
hiI
,
loI
)
->
(
t'
,
LHSRange
lInner
IndexedPlus
(
simplify
base
,
simplify
len
))
where
base
=
BinOp
Add
baseO
$
endianCondExpr
(
hiI
,
loI
)
loI
hiI
len
=
lenO
_
->
(
t'
,
LHSRange
lOuter'
IndexedPlus
rOuter
)
where
(
t
,
lOuter'
)
=
convertLHS
lOuter
t'
=
dropInnerTypeRange
t
convertLHS
(
LHSRange
l
m
r
)
=
convertLHS
(
LHSRange
l
m
r
)
=
(
t'
,
LHSRange
l'
m
r
)
(
t'
,
LHSRange
l'
m
r
)
where
where
(
t
,
l'
)
=
convertLHS
l
(
t
,
l'
)
=
convertLHS
l
t'
=
case
typeRanges
t
of
t'
=
dropInnerTypeRange
t
(
_
,
[]
)
->
Implicit
Unspecified
[]
(
tf
,
rs
)
->
tf
$
tail
rs
convertLHS
(
LHSDot
l
x
)
=
convertLHS
(
LHSDot
l
x
)
=
case
t
of
case
t
of
InterfaceT
_
_
_
->
(
Implicit
Unspecified
[]
,
LHSDot
l'
x
)
InterfaceT
_
_
_
->
(
Implicit
Unspecified
[]
,
LHSDot
l'
x
)
...
@@ -421,24 +439,36 @@ convertAsgn structs types (lhs, expr) =
...
@@ -421,24 +439,36 @@ convertAsgn structs types (lhs, expr) =
-- semantics are that a range returns a new, zero-indexed sub-range.
-- semantics are that a range returns a new, zero-indexed sub-range.
case
eOuter'
of
case
eOuter'
of
Range
eInner
NonIndexed
(
_
,
loI
)
->
Range
eInner
NonIndexed
(
_
,
loI
)
->
(
t
,
Range
eInner
NonIndexed
(
simplify
hi
,
simplify
lo
))
(
t
'
,
Range
eInner
NonIndexed
(
simplify
hi
,
simplify
lo
))
where
where
lo
=
BinOp
Add
loI
loO
lo
=
BinOp
Add
loI
loO
hi
=
BinOp
Add
loI
hiO
hi
=
BinOp
Add
loI
hiO
Range
eInner
IndexedPlus
(
baseI
,
_
)
->
Range
eInner
IndexedPlus
(
baseI
,
_
)
->
(
t
,
Range
eInner
IndexedPlus
(
simplify
base
,
simplify
len
))
(
t
'
,
Range
eInner
IndexedPlus
(
simplify
base
,
simplify
len
))
where
where
base
=
BinOp
Add
baseI
loO
base
=
BinOp
Add
baseI
loO
len
=
rangeSize
rOuter
len
=
rangeSize
rOuter
_
->
(
t
,
Range
eOuter'
NonIndexed
rOuter
)
_
->
(
t'
,
Range
eOuter'
NonIndexed
rOuter
)
where
(
t
,
eOuter'
)
=
convertSubExpr
eOuter
where
(
t
,
eOuter'
)
=
convertSubExpr
eOuter
t'
=
dropInnerTypeRange
t
convertSubExpr
(
Range
eOuter
IndexedPlus
(
rOuter
@
(
baseO
,
lenO
)))
=
case
eOuter'
of
Range
eInner
NonIndexed
(
hiI
,
loI
)
->
(
t'
,
Range
eInner
IndexedPlus
(
simplify
base
,
simplify
len
))
where
base
=
BinOp
Add
baseO
$
endianCondExpr
(
hiI
,
loI
)
loI
hiI
len
=
lenO
_
->
(
t'
,
Range
eOuter'
IndexedPlus
rOuter
)
where
(
t
,
eOuter'
)
=
convertSubExpr
eOuter
t'
=
dropInnerTypeRange
t
convertSubExpr
(
Range
e
m
r
)
=
convertSubExpr
(
Range
e
m
r
)
=
(
t'
,
Range
e'
m
r
)
(
t'
,
Range
e'
m
r
)
where
where
(
t
,
e'
)
=
convertSubExpr
e
(
t
,
e'
)
=
convertSubExpr
e
t'
=
case
typeRanges
t
of
t'
=
dropInnerTypeRange
t
(
_
,
[]
)
->
Implicit
Unspecified
[]
(
tf
,
rs
)
->
tf
$
tail
rs
convertSubExpr
(
Concat
exprs
)
=
convertSubExpr
(
Concat
exprs
)
=
(
Implicit
Unspecified
[]
,
Concat
$
map
(
snd
.
convertSubExpr
)
exprs
)
(
Implicit
Unspecified
[]
,
Concat
$
map
(
snd
.
convertSubExpr
)
exprs
)
convertSubExpr
(
Stream
o
e
exprs
)
=
convertSubExpr
(
Stream
o
e
exprs
)
=
...
@@ -460,9 +490,7 @@ convertAsgn structs types (lhs, expr) =
...
@@ -460,9 +490,7 @@ convertAsgn structs types (lhs, expr) =
_
->
(
t'
,
Bit
e'
i'
)
_
->
(
t'
,
Bit
e'
i'
)
where
where
(
t
,
e'
)
=
convertSubExpr
e
(
t
,
e'
)
=
convertSubExpr
e
t'
=
case
typeRanges
t
of
t'
=
dropInnerTypeRange
t
(
_
,
[]
)
->
Implicit
Unspecified
[]
(
tf
,
rs
)
->
tf
$
tail
rs
(
_
,
i'
)
=
convertSubExpr
i
(
_
,
i'
)
=
convertSubExpr
i
convertSubExpr
(
Call
e
args
)
=
convertSubExpr
(
Call
e
args
)
=
(
retType
,
Call
e
$
convertCall
structs
types
e'
args
)
(
retType
,
Call
e
$
convertCall
structs
types
e'
args
)
...
...
test/basic/flatten_tb.v
View file @
95299c6f
...
@@ -35,5 +35,8 @@ module top;
...
@@ -35,5 +35,8 @@ module top;
`FOO
(
B
)
`FOO
(
B
)
`FOO
(
C
)
`FOO
(
C
)
`FOO
(
D
)
`FOO
(
D
)
`FOO
(
E
)
`FOO
(
F
)
`FOO
(
G
)
endmodule
endmodule
test/basic/struct_array_field.sv
0 → 100644
View file @
95299c6f
module
main
;
typedef
struct
packed
{
logic
[
1
:
0
][
2
:
0
]
x
;
logic
[
0
:
2
][
1
:
0
]
y
;
logic
z
;
}
foo_t
;
foo_t
foo
;
initial
begin
$
monitor
($
time
,
" %b %b %b %b %b %b %b %b"
,
foo
,
foo
.
x
,
foo
.
y
,
foo
.
z
,
foo
.
x
[
0
]
,
foo
.
x
[
0
][
0
]
,
foo
.
y
[
0
]
,
foo
.
y
[
0
][
0
])
;
#
1
;
foo
.
z
=
0
;
#
1
;
foo
.
y
=
0
;
#
1
;
foo
.
y
[
0
]
=
'1
;
#
1
;
foo
.
y
[
1
]
=
'1
;
#
1
;
foo
.
y
[
1
][
1
]
=
0
;
#
1
;
foo
.
y
[
0
][
0
]
=
1
;
#
1
;
foo
.
y
[
0
][
1
]
=
1
;
#
1
;
foo
.
x
=
0
;
#
1
;
foo
.
x
[
0
]
=
'1
;
#
1
;
foo
.
x
[
1
]
=
'1
;
#
1
;
foo
.
x
[
1
][
1
]
=
0
;
#
1
;
foo
.
x
[
0
][
0
]
=
1
;
#
1
;
foo
.
x
[
0
][
1
]
=
1
;
end
endmodule
module
top
;
endmodule
test/basic/struct_array_field.v
0 → 100644
View file @
95299c6f
module
main
;
reg
[
2
:
0
]
foo_x_1
;
reg
[
2
:
0
]
foo_x_0
;
reg
[
1
:
0
]
foo_y_2
;
reg
[
1
:
0
]
foo_y_1
;
reg
[
1
:
0
]
foo_y_0
;
wire
[
5
:
0
]
foo_x
;
wire
[
5
:
0
]
foo_y
;
assign
foo_x
=
{
foo_x_1
,
foo_x_0
};
assign
foo_y
=
{
foo_y_0
,
foo_y_1
,
foo_y_2
};
reg
foo_z
;
wire
[
12
:
0
]
foo
;
assign
foo
=
{
foo_x
,
foo_y
,
foo_z
};
initial
begin
$
monitor
($
time
,
" %b %b %b %b %b %b %b %b"
,
foo
,
foo_x
,
foo_y
,
foo_z
,
foo_x_0
,
foo_x_0
[
0
]
,
foo_y_0
,
foo_y_0
[
0
])
;
#
1
;
foo_z
=
0
;
#
1
;
{
foo_y_0
,
foo_y_1
,
foo_y_2
}
=
0
;
#
1
;
foo_y_0
=
1
'
sb1
;
#
1
;
foo_y_1
=
1
'
sb1
;
#
1
;
foo_y_1
[
1
]
=
0
;
#
1
;
foo_y_0
[
0
]
=
1
;
#
1
;
foo_y_0
[
1
]
=
1
;
#
1
;
{
foo_x_1
,
foo_x_0
}
=
0
;
#
1
;
foo_x_0
=
1
'
sb1
;
#
1
;
foo_x_1
=
1
'
sb1
;
#
1
;
foo_x_1
[
1
]
=
0
;
#
1
;
foo_x_0
[
0
]
=
1
;
#
1
;
foo_x_0
[
1
]
=
1
;
end
endmodule
module
top
;
endmodule
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment