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
1dfa9a9e
Commit
1dfa9a9e
authored
Jul 01, 2020
by
Zachary Snow
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
simplify struct conversion
parent
6b81f87a
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
48 additions
and
83 deletions
+48
-83
src/Convert/Struct.hs
+48
-83
No files found.
src/Convert/Struct.hs
View file @
1dfa9a9e
...
...
@@ -18,36 +18,23 @@ import Language.SystemVerilog.AST
type
TypeFunc
=
[
Range
]
->
Type
type
StructInfo
=
(
Type
,
Map
.
Map
Identifier
(
Range
,
Expr
))
type
Structs
=
Map
.
Map
TypeFunc
StructInfo
type
Types
=
Map
.
Map
Identifier
Type
type
Idents
=
Set
.
Set
Identifier
convert
::
[
AST
]
->
[
AST
]
convert
=
map
$
traverseDescriptions
convertDescription
convertDescription
::
Description
->
Description
convertDescription
(
description
@
(
Part
_
_
Module
_
_
_
_
))
=
traverseModuleItems
(
traverseTypes'
ExcludeParamTypes
$
convertType
structs
)
$
Part
attrs
extern
kw
lifetime
name
ports
(
items
++
funcs
)
where
description'
@
(
Part
attrs
extern
kw
lifetime
name
ports
items
)
=
traverseModuleItems
(
traverseTypes'
ExcludeParamTypes
convertType
)
$
scopedConversion
traverseDeclM'
traverseModuleItemM
traverseStmtM
tfArgTypes
description
where
-- collect information about this description
structs
=
execWriter
$
collectModuleItemsM
(
collectTypesM
collectStructM
)
description
tfArgTypes
=
execWriter
$
collectModuleItemsM
collectTFArgsM
description
-- determine which of the packer functions we actually need
calledFuncs
=
execWriter
$
collectModuleItemsM
(
collectExprsM
$
collectNestedExprsM
collectCallsM
)
description'
packerFuncs
=
Set
.
map
packerFnName
$
Map
.
keysSet
structs
calledPackedFuncs
=
Set
.
intersection
calledFuncs
packerFuncs
funcs
=
map
packerFn
$
filter
isNeeded
$
Map
.
keys
structs
isNeeded
tf
=
Set
.
member
(
packerFnName
tf
)
calledPackedFuncs
-- helpers for the scoped traversal
traverseDeclM'
::
Decl
->
State
Types
Decl
traverseDeclM'
decl
=
do
decl'
<-
traverseDeclM
structs
decl
decl'
<-
traverseDeclM
decl
res
<-
traverseModuleItemM
$
MIPackageItem
$
Decl
decl'
let
MIPackageItem
(
Decl
decl''
)
=
res
return
decl''
...
...
@@ -59,8 +46,7 @@ convertDescription (description @ (Part _ _ Module _ _ _ _)) =
traverseStmtM
::
Stmt
->
State
Types
Stmt
traverseStmtM
(
Subroutine
expr
args
)
=
do
stateTypes
<-
get
let
stmt'
=
Subroutine
expr
$
convertCall
structs
stateTypes
expr
args
let
stmt'
=
Subroutine
expr
$
convertCall
stateTypes
expr
args
traverseStmtM'
stmt'
traverseStmtM
stmt
=
traverseStmtM'
stmt
traverseStmtM'
::
Stmt
->
State
Types
Stmt
...
...
@@ -73,35 +59,32 @@ convertDescription (description @ (Part _ _ Module _ _ _ _)) =
where
converter
::
Types
->
Expr
->
Expr
converter
types
expr
=
snd
$
convertAsgn
structs
types
(
LHSIdent
""
,
expr
)
snd
$
convertAsgn
types
(
LHSIdent
""
,
expr
)
traverseLHSM
=
traverseNestedLHSsM
$
stately
converter
where
converter
::
Types
->
LHS
->
LHS
converter
types
lhs
=
fst
$
convertAsgn
structs
types
(
lhs
,
Ident
""
)
traverseAsgnM
=
stately
$
convertAsgn
structs
fst
$
convertAsgn
types
(
lhs
,
Ident
""
)
traverseAsgnM
=
stately
convertAsgn
convertDescription
other
=
other
-- write down unstructured versions of packed struct types
collectStructM
::
Type
->
Writer
Structs
()
collectStructM
(
Struct
Unpacked
fields
_
)
=
collectStructM'
(
Struct
Unpacked
)
True
Unspecified
fields
collectStructM
(
Struct
(
Packed
sg
)
fields
_
)
=
collectStructM'
(
Struct
$
Packed
sg
)
True
sg
fields
collectStructM
(
Union
(
Packed
sg
)
fields
_
)
=
collectStructM'
(
Union
$
Packed
sg
)
False
sg
fields
collectStructM
_
=
return
()
collectStructM'
::
([
Field
]
->
[
Range
]
->
Type
)
->
Bool
->
Signing
->
[
Field
]
->
Writer
Structs
()
collectStructM'
constructor
isStruct
sg
fields
=
do
convertStruct
::
Type
->
Maybe
StructInfo
convertStruct
(
Struct
Unpacked
fields
_
)
=
convertStruct'
True
Unspecified
fields
convertStruct
(
Struct
(
Packed
sg
)
fields
_
)
=
convertStruct'
True
sg
fields
convertStruct
(
Union
(
Packed
sg
)
fields
_
)
=
convertStruct'
False
sg
fields
convertStruct
_
=
Nothing
convertStruct'
::
Bool
->
Signing
->
[
Field
]
->
Maybe
StructInfo
convertStruct'
isStruct
sg
fields
=
if
canUnstructure
then
tell
$
Map
.
singleton
(
constructor
fields
)
(
unstructType
,
unstructFields
)
else
return
()
then
Just
(
unstructType
,
unstructFields
)
else
Nothing
where
zero
=
Number
"0"
typeRange
::
Type
->
Range
...
...
@@ -152,20 +135,18 @@ collectStructM' constructor isStruct sg fields = do
isFlatIntVec
_
=
False
canUnstructure
=
all
isFlatIntVec
fieldTypes
isReadyStruct
::
Type
->
Bool
isReadyStruct
=
(
Nothing
/=
)
.
convertStruct
-- convert a struct type to its unstructured equivalent
convertType
::
Structs
->
Type
->
Type
convertType
structs
t1
=
case
Map
.
lookup
tf1
structs
of
convertType
::
Type
->
Type
convertType
t1
=
case
convertStruct
t1
of
Nothing
->
t1
Just
(
t2
,
_
)
->
tf2
(
rs1
++
rs2
)
where
(
tf2
,
rs2
)
=
typeRanges
t2
where
(
tf1
,
rs1
)
=
typeRanges
t1
-- writes down the names of called functions
collectCallsM
::
Expr
->
Writer
Idents
()
collectCallsM
(
Call
(
Ident
f
)
_
)
=
tell
$
Set
.
singleton
f
collectCallsM
_
=
return
()
where
(
_
,
rs1
)
=
typeRanges
t1
collectTFArgsM
::
ModuleItem
->
Writer
Types
()
collectTFArgsM
(
MIPackageItem
item
)
=
do
...
...
@@ -186,8 +167,8 @@ collectTFArgsM (MIPackageItem item) = do
collectTFArgsM
_
=
return
()
-- write down the types of declarations
traverseDeclM
::
Structs
->
Decl
->
State
Types
Decl
traverseDeclM
structs
origDecl
=
do
traverseDeclM
::
Decl
->
State
Types
Decl
traverseDeclM
origDecl
=
do
case
origDecl
of
Variable
d
t
x
a
e
->
do
let
(
tf
,
rs
)
=
typeRanges
t
...
...
@@ -206,30 +187,13 @@ traverseDeclM structs origDecl = do
convertDeclExpr
::
Identifier
->
Expr
->
State
Types
Expr
convertDeclExpr
x
e
=
do
types
<-
get
let
(
LHSIdent
_
,
e'
)
=
convertAsgn
structs
types
(
LHSIdent
x
,
e
)
let
(
LHSIdent
_
,
e'
)
=
convertAsgn
types
(
LHSIdent
x
,
e
)
return
e'
isRangeable
::
Type
->
Bool
isRangeable
(
IntegerAtom
_
_
)
=
False
isRangeable
(
NonInteger
_
)
=
False
isRangeable
_
=
True
-- produces a function which packs the components of a struct literal
packerFn
::
TypeFunc
->
ModuleItem
packerFn
structTf
=
MIPackageItem
$
Function
Automatic
(
structTf
[]
)
fnName
decls
[
retStmt
]
where
Struct
_
fields
[]
=
structTf
[]
toInput
(
t
,
x
)
=
Variable
Input
t
x
[]
Nil
decls
=
map
toInput
fields
retStmt
=
Return
$
Concat
$
map
(
Ident
.
snd
)
fields
fnName
=
packerFnName
structTf
-- returns a "unique" name for the packer for a given struct type
packerFnName
::
TypeFunc
->
Identifier
packerFnName
structTf
=
"sv2v_struct_"
++
shortHash
structTf
-- removes the innermost range from the given type, if possible
dropInnerTypeRange
::
Type
->
Type
dropInnerTypeRange
t
=
...
...
@@ -243,8 +207,8 @@ dropInnerTypeRange t =
-- looking at the innermost type of a node to convert outer uses of fields, and
-- then using the outermost type to figure out the corresponding struct
-- definition for struct literals that are encountered.
convertAsgn
::
Structs
->
Types
->
(
LHS
,
Expr
)
->
(
LHS
,
Expr
)
convertAsgn
structs
types
(
lhs
,
expr
)
=
convertAsgn
::
Types
->
(
LHS
,
Expr
)
->
(
LHS
,
Expr
)
convertAsgn
types
(
lhs
,
expr
)
=
(
lhs'
,
expr'
)
where
(
typ
,
lhs'
)
=
convertLHS
lhs
...
...
@@ -311,10 +275,10 @@ convertAsgn structs types (lhs, expr) =
" has extra named fields: "
++
show
(
Set
.
toList
extraNames
)
++
" that are not in "
++
show
structTf
else
if
Map
.
member
structTf
structs
then
C
all
(
Ident
$
packerFnName
structTf
)
(
Args
(
map
snd
items
)
[]
)
else
if
isReadyStruct
(
structTf
[]
)
then
C
oncat
$
map
(
uncurry
$
Cast
.
Left
)
$
zip
(
map
fst
fields
)
(
map
snd
items
)
else
Pattern
items
where
...
...
@@ -397,7 +361,7 @@ convertAsgn structs types (lhs, expr) =
convertSubExpr
(
Dot
e
x
)
=
if
maybeFields
==
Nothing
then
(
Implicit
Unspecified
[]
,
Dot
e'
x
)
else
if
Map
.
notMember
structTf
structs
else
if
not
$
isReadyStruct
(
structTf
[]
)
then
(
fieldType
,
Dot
e'
x
)
else
(
dropInnerTypeRange
fieldType
,
undotted
)
where
...
...
@@ -414,7 +378,7 @@ convertAsgn structs types (lhs, expr) =
convertSubExpr
(
Range
(
Dot
e
x
)
NonIndexed
rOuter
)
=
if
maybeFields
==
Nothing
then
(
Implicit
Unspecified
[]
,
orig'
)
else
if
Map
.
notMember
structTf
structs
else
if
not
$
isReadyStruct
(
structTf
[]
)
then
(
fieldType
,
orig'
)
else
(
dropInnerTypeRange
fieldType
,
undotted
)
where
...
...
@@ -435,7 +399,7 @@ convertAsgn structs types (lhs, expr) =
convertSubExpr
(
Range
(
Dot
e
x
)
mode
(
baseO
,
lenO
))
=
if
maybeFields
==
Nothing
then
(
Implicit
Unspecified
[]
,
orig'
)
else
if
Map
.
notMember
structTf
structs
else
if
not
$
isReadyStruct
(
structTf
[]
)
then
(
fieldType
,
orig'
)
else
(
dropInnerTypeRange
fieldType
,
undotted
)
where
...
...
@@ -463,7 +427,7 @@ convertAsgn structs types (lhs, expr) =
convertSubExpr
(
Bit
(
Dot
e
x
)
i
)
=
if
maybeFields
==
Nothing
then
(
Implicit
Unspecified
[]
,
Bit
(
Dot
e'
x
)
i
)
else
if
Map
.
notMember
structTf
structs
else
if
not
$
isReadyStruct
(
structTf
[]
)
then
(
dropInnerTypeRange
fieldType
,
Bit
(
Dot
e'
x
)
i
)
else
(
dropInnerTypeRange
fieldType
,
Bit
e'
i'
)
where
...
...
@@ -481,7 +445,7 @@ convertAsgn structs types (lhs, expr) =
(
t
,
e'
)
=
convertSubExpr
e
t'
=
dropInnerTypeRange
t
convertSubExpr
(
Call
e
args
)
=
(
retType
,
Call
e
$
convertCall
structs
types
e'
args
)
(
retType
,
Call
e
$
convertCall
types
e'
args
)
where
(
_
,
e'
)
=
convertSubExpr
e
retType
=
case
e'
of
...
...
@@ -514,7 +478,9 @@ convertAsgn structs types (lhs, expr) =
Nothing
->
error
$
"field '"
++
fieldName
++
"' not found in struct: "
++
show
structTf
Just
r
->
r
where
fieldRangeMap
=
Map
.
map
fst
$
snd
$
structs
Map
.!
structTf
where
Just
structInfo
=
convertStruct
$
structTf
[]
fieldRangeMap
=
Map
.
map
fst
$
snd
structInfo
-- lookup the type of a field in the given field list
lookupFieldType
::
[(
Type
,
Identifier
)]
->
Identifier
->
Type
...
...
@@ -538,8 +504,8 @@ convertAsgn structs types (lhs, expr) =
dims
=
snd
$
typeRanges
fieldType
-- attempts to convert based on the assignment-like contexts of TF arguments
convertCall
::
Structs
->
Types
->
Expr
->
Args
->
Args
convertCall
structs
types
fn
(
Args
pnArgs
kwArgs
)
=
convertCall
::
Types
->
Expr
->
Args
->
Args
convertCall
types
fn
(
Args
pnArgs
kwArgs
)
=
case
fn
of
Ident
_
->
args
_
->
Args
pnArgs
kwArgs
...
...
@@ -552,6 +518,5 @@ convertCall structs types fn (Args pnArgs kwArgs) =
convertArg
::
(
Identifier
,
Expr
)
->
(
Identifier
,
Expr
)
convertArg
(
x
,
e
)
=
(
x
,
e'
)
where
(
_
,
e'
)
=
convertAsgn
structs
types
(
_
,
e'
)
=
convertAsgn
types
(
LHSIdent
$
f
++
":"
++
x
,
e
)
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