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
6271e16b
Commit
6271e16b
authored
Sep 11, 2019
by
Zachary Snow
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
functional parameter type conversion
parent
4de585ec
Show whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
280 additions
and
30 deletions
+280
-30
src/Convert/ParamType.hs
+163
-26
src/Convert/Traverse.hs
+7
-0
src/Convert/Typedef.hs
+13
-4
test/basic/paramtype.sv
+1
-0
test/basic/paramtype.v
+2
-0
test/basic/paramtype_recurse.sv
+31
-0
test/basic/paramtype_recurse.v
+63
-0
No files found.
src/Convert/ParamType.hs
View file @
6271e16b
...
...
@@ -10,6 +10,7 @@ import Control.Monad.Writer
import
Data.Either
(
isLeft
)
import
Data.Maybe
(
isJust
,
isNothing
,
fromJust
)
import
qualified
Data.Map.Strict
as
Map
import
qualified
Data.Set
as
Set
import
Convert.Traverse
import
Language.SystemVerilog.AST
...
...
@@ -20,14 +21,17 @@ type Info = Map.Map Identifier ([Identifier], MaybeTypeMap)
type
Instance
=
Map
.
Map
Identifier
Type
type
Instances
=
[(
Identifier
,
Instance
)]
type
IdentSet
=
Set
.
Set
Identifier
type
UsageMap
=
[(
Identifier
,
Set
.
Set
Identifier
)]
convert
::
[
AST
]
->
[
AST
]
convert
files
=
concatMap
(
map
explodeDescription
)
files
'
files''
'
where
info
=
execWriter
$
mapM
(
collectDescriptionsM
collectDescriptionM
)
files
(
files'
,
instancesRaw
)
=
runWriter
$
mapM
(
mapM
$
traverseModuleItemsM
$
mapInstance
info
)
files
(
mapM
$
traverseModuleItemsM
$
convertModuleItemM
info
)
files
instances
=
reverse
$
uniq
[]
instancesRaw
-- TODO: use the unique package
uniq
curr
[]
=
curr
...
...
@@ -36,24 +40,113 @@ convert files =
then
uniq
curr
xs
else
uniq
(
x
:
curr
)
xs
-- add type parameter instantiations
files''
=
map
(
concatMap
explodeDescription
)
files'
explodeDescription
::
Description
->
[
Description
]
explodeDescription
(
part
@
(
Part
_
_
_
name
_
_
))
=
if
null
theseInstances
then
[
part
]
else
map
(
rewriteModule
part
)
theseInstances
where
theseInstances
=
map
snd
$
filter
((
==
name
)
.
fst
)
instances
if
null
theseInstances
then
[
part
]
else
(
:
)
part
$
filter
(
not
.
alreadyExists
)
$
filter
isNonDefault
$
map
(
rewriteModule
part
)
theseInstances
where
theseInstances
=
map
snd
$
filter
((
==
name
)
.
fst
)
instances
isNonDefault
=
(
name
/=
)
.
moduleName
alreadyExists
=
(
flip
Map
.
member
info
)
.
moduleName
moduleName
::
Description
->
Identifier
moduleName
(
Part
_
_
_
x
_
_
)
=
x
moduleName
_
=
error
"not possible"
explodeDescription
other
=
[
other
]
-- TODO FIXME: Need to keep around the default instance and not perform
-- substitutions in it.
-- remove or rewrite source modules that are no longer needed
files'''
=
map
(
reverse
.
uniq
[]
.
concatMap
replaceDefault
)
files''
(
usageMapRaw
,
usedTypedModulesRaw
)
=
execWriter
$
mapM
(
mapM
collectUsageInfoM
)
files''
usageMap
=
Map
.
unionsWith
Set
.
union
$
map
(
uncurry
Map
.
singleton
)
usageMapRaw
usedTypedModules
=
Map
.
unionsWith
Set
.
union
$
map
(
uncurry
Map
.
singleton
)
usedTypedModulesRaw
collectUsageInfoM
::
Description
->
Writer
(
UsageMap
,
UsageMap
)
()
collectUsageInfoM
(
part
@
(
Part
_
_
_
name
_
_
))
=
tell
(
makeList
used
,
makeList
usedTyped
)
where
makeList
s
=
zip
(
Set
.
toList
s
)
(
repeat
$
Set
.
singleton
name
)
(
usedUntyped
,
usedTyped
)
=
execWriter
$
(
collectModuleItemsM
collectModuleItemM
)
part
used
=
Set
.
union
usedUntyped
usedTyped
collectUsageInfoM
_
=
return
()
collectModuleItemM
::
ModuleItem
->
Writer
(
IdentSet
,
IdentSet
)
()
collectModuleItemM
(
Instance
m
bindings
_
_
_
)
=
do
case
Map
.
lookup
m
info
of
Nothing
->
tell
(
Set
.
singleton
m
,
Set
.
empty
)
Just
(
_
,
maybeTypeMap
)
->
if
any
(
flip
Map
.
member
maybeTypeMap
)
$
map
fst
bindings
then
tell
(
Set
.
empty
,
Set
.
singleton
m
)
else
tell
(
Set
.
singleton
m
,
Set
.
empty
)
collectModuleItemM
_
=
return
()
replaceDefault
::
Description
->
[
Description
]
replaceDefault
(
part
@
(
Part
_
_
_
name
_
_
))
=
if
Map
.
notMember
name
info
then
[
part
]
else
if
Map
.
null
maybeTypeMap
then
[
part
]
else
if
Map
.
member
name
usedTypedModules
&&
isUsed
name
then
[
part
]
else
if
all
isNothing
maybeTypeMap
then
[]
else
(
:
)
(
removeDefaultTypeParams
part
)
$
if
isNothing
typeMap
then
[]
else
[
rewriteModule
part
$
fromJust
typeMap
]
where
maybeTypeMap
=
snd
$
info
Map
.!
name
typeMap
=
defaultInstance
maybeTypeMap
replaceDefault
other
=
[
other
]
removeDefaultTypeParams
::
Description
->
Description
removeDefaultTypeParams
(
part
@
(
Part
_
_
_
_
_
_
))
=
Part
extern
kw
ml
(
moduleDefaultName
name
)
p
items
where
Part
extern
kw
ml
name
p
items
=
traverseModuleItems
(
traverseDecls
rewriteDecl
)
part
rewriteDecl
::
Decl
->
Decl
rewriteDecl
(
ParamType
Parameter
x
_
)
=
ParamType
Parameter
x
Nothing
rewriteDecl
other
=
other
removeDefaultTypeParams
_
=
error
"not possible"
isUsed
::
Identifier
->
Bool
isUsed
name
=
any
(
flip
Map
.
notMember
usedTypedModules
)
used
where
used
=
usageSet
$
expandSet
name
expandSet
::
Identifier
->
IdentSet
expandSet
ident
=
case
(
Map
.
lookup
ident
usedTypedModules
,
Map
.
lookup
name
usageMap
)
of
(
Just
x
,
_
)
->
x
(
Nothing
,
Just
x
)
->
x
_
->
Set
.
empty
usageSet
::
IdentSet
->
IdentSet
usageSet
names
=
if
names'
==
names
then
names
else
usageSet
names'
where
names'
=
Set
.
union
names
$
Set
.
unions
$
Set
.
map
expandSet
names
-- substitute in a particular instance's paramter types
-- substitute in a particular instance's param
e
ter types
rewriteModule
::
Description
->
Instance
->
Description
rewriteModule
part
typeMap
=
Part
extern
kw
ml
m'
p
items'
where
Part
extern
kw
ml
m
p
items
=
part
m'
=
renameModule
info
m
typeMap
m'
=
moduleInstanceName
m
typeMap
items'
=
map
rewriteDecl
items
rewriteDecl
::
ModuleItem
->
ModuleItem
rewriteDecl
(
MIPackageItem
(
Decl
(
ParamType
Parameter
x
_
)))
=
...
...
@@ -67,7 +160,6 @@ convert files =
----- ParamType Localparam x (Just $ typeMap Map.! x)
-----rewriteDecl other = other
-- write down module parameter names and type parameters
collectDescriptionM
::
Description
->
Writer
Info
()
collectDescriptionM
(
part
@
(
Part
_
_
_
name
_
_
))
=
...
...
@@ -93,24 +185,65 @@ defaultInstance maybeTypeMap =
else
Just
$
Map
.
map
fromJust
maybeTypeMap
-- generate a "unique" name for a particular module type instance
renameModule
::
Info
->
Identifier
->
Instance
->
Identifier
renameModule
info
m
inst
=
if
defaultInstance
maybeTypeMap
==
Just
inst
then
m
-- default instances keep the original module name
else
m
++
"_"
++
shortHash
(
m
,
inst
)
where
maybeTypeMap
=
snd
$
info
Map
.!
m
moduleInstanceName
::
Identifier
->
Instance
->
Identifier
moduleInstanceName
m
inst
=
m
++
"_"
++
shortHash
(
m
,
inst
)
-- name for the module without any default type parameters
moduleDefaultName
::
Identifier
->
Identifier
moduleDefaultName
m
=
m
++
defaultTag
isDefaultName
::
Identifier
->
Bool
isDefaultName
m
=
defaultTag
==
(
reverse
$
(
take
$
length
defaultTag
)
$
reverse
m
)
defaultTag
::
Identifier
defaultTag
=
"_sv2v_default"
mapInstance
::
Info
->
ModuleItem
->
Writer
Instances
ModuleItem
mapInstance
info
(
orig
@
(
Instance
m
bindings
x
r
p
))
=
-- attempt to convert an expression to syntactically equivalent type
exprToType
::
Expr
->
Maybe
Type
exprToType
(
Ident
x
)
=
Just
$
Alias
Nothing
x
[]
exprToType
(
PSIdent
x
y
)
=
Just
$
Alias
(
Just
x
)
y
[]
exprToType
(
Range
e
NonIndexed
r
)
=
case
exprToType
e
of
Nothing
->
Nothing
Just
t
->
Just
$
tf
(
rs
++
[
r
])
where
(
tf
,
rs
)
=
typeRanges
t
exprToType
(
Bit
e
i
)
=
case
exprToType
e
of
Nothing
->
Nothing
Just
t
->
Just
$
tf
(
rs
++
[
r
])
where
(
tf
,
rs
)
=
typeRanges
t
r
=
(
simplify
$
BinOp
Sub
i
(
Number
"1"
),
Number
"0"
)
exprToType
_
=
Nothing
-- checks where a type is sufficiently resolved to be substituted
-- TODO: If a type parameter contains an expression, that expression should be
-- substituted into the new module, or created as a new parameter.
isSimpleType
::
Type
->
Bool
isSimpleType
(
IntegerVector
_
_
_
)
=
True
isSimpleType
(
IntegerAtom
_
_
)
=
True
isSimpleType
(
NonInteger
_
)
=
True
isSimpleType
(
Net
_
_
)
=
True
isSimpleType
_
=
False
-- attempt to rewrite instantiations with type parameters
convertModuleItemM
::
Info
->
ModuleItem
->
Writer
Instances
ModuleItem
convertModuleItemM
info
(
orig
@
(
Instance
m
bindings
x
r
p
))
=
if
Map
.
notMember
m
info
then
return
orig
else
if
Map
.
null
maybeTypeMap
then
return
$
Instance
m
bindingsNamed
x
r
p
else
if
any
(
isLeft
.
snd
)
bindings'
then
error
$
"param type resolution left type params: "
++
show
orig
++
" converted to: "
++
show
bindings'
else
if
any
(
not
.
isSimpleType
)
resolvedTypes
then
do
let
defaults
=
Map
.
map
Left
resolvedTypes
let
bindingsDefaulted
=
Map
.
toList
$
Map
.
union
bindingsMap
defaults
if
isDefaultName
m
then
return
$
Instance
m
bindingsNamed
x
r
p
else
return
$
Instance
(
moduleDefaultName
m
)
bindingsDefaulted
x
r
p
else
do
tell
[(
m
,
resolvedTypes
)]
let
m'
=
renameModule
info
m
resolvedTypes
let
m'
=
moduleInstanceName
m
resolvedTypes
return
$
Instance
m'
bindings'
x
r
p
where
(
paramNames
,
maybeTypeMap
)
=
info
Map
.!
m
...
...
@@ -134,12 +267,16 @@ mapInstance info (orig @ (Instance m bindings x r p)) =
" is missing a type parameter: "
++
paramName
(
Just
(
Left
t
),
_
)
->
t
(
Just
(
Right
e
),
_
)
->
-- TODO: Some types could have been parsed as an expression
-- (i.e. aliases). Ideally we should have any such aliases
-- resolved before applying this conversion.
error
$
"instantiation "
++
show
orig
++
" has expr "
++
show
e
++
" for type param: "
++
paramName
-- Some types are parsed as expressions because of the
-- ambiguities of defined type names.
case
exprToType
e
of
Just
t
->
t
Nothing
->
error
$
"instantiation "
++
show
orig
++
" has expr "
++
show
e
++
" for type param: "
++
paramName
-- leave only the normal expression params behind
isParamType
=
flip
Map
.
member
maybeTypeMap
bindings'
=
filter
(
not
.
isParamType
.
fst
)
bindingsNamed
mapInstance
_
other
=
return
other
convertModuleItemM
_
other
=
return
other
src/Convert/Traverse.hs
View file @
6271e16b
...
...
@@ -849,6 +849,13 @@ traverseTypesM mapper item =
fullMapper
t
>>=
\
t'
->
return
$
MIPackageItem
$
Function
l
t'
x
d
s
miMapper
(
MIPackageItem
(
other
@
(
Task
_
_
_
_
)))
=
return
$
MIPackageItem
other
miMapper
(
Instance
m
params
x
r
p
)
=
do
params'
<-
mapM
mapParam
params
return
$
Instance
m
params'
x
r
p
where
mapParam
(
i
,
Left
t
)
=
fullMapper
t
>>=
\
t'
->
return
(
i
,
Left
t'
)
mapParam
(
i
,
Right
e
)
=
return
$
(
i
,
Right
e
)
miMapper
other
=
return
other
traverseTypes
::
Mapper
Type
->
Mapper
ModuleItem
...
...
src/Convert/Typedef.hs
View file @
6271e16b
...
...
@@ -36,6 +36,7 @@ convert =
convertDescription
::
Types
->
Description
->
Description
convertDescription
globalTypes
description
=
traverseModuleItems
removeTypedef
$
traverseModuleItems
convertModuleItem
$
traverseModuleItems
(
traverseExprs
$
traverseNestedExprs
$
convertExpr
)
$
traverseModuleItems
(
traverseTypes
$
resolveType
types
)
$
description
...
...
@@ -49,12 +50,20 @@ convertDescription globalTypes description =
removeTypedef
(
MIPackageItem
(
Typedef
_
x
))
=
MIPackageItem
$
Comment
$
"removed typedef: "
++
x
removeTypedef
other
=
other
convert
Expr
::
Expr
->
Expr
convert
Expr
(
Bits
(
Right
(
Ident
x
)
))
=
convert
TypeOrExpr
::
TypeOrExpr
->
TypeOr
Expr
convert
TypeOrExpr
(
Right
(
Ident
x
))
=
if
Map
.
member
x
types
then
Bits
$
Left
$
resolveType
types
(
Alias
Nothing
x
[]
)
else
Bits
$
Right
$
Ident
x
then
Left
$
resolveType
types
(
Alias
Nothing
x
[]
)
else
Right
$
Ident
x
convertTypeOrExpr
other
=
other
convertExpr
::
Expr
->
Expr
convertExpr
(
Bits
v
)
=
Bits
$
convertTypeOrExpr
v
convertExpr
other
=
other
convertModuleItem
::
ModuleItem
->
ModuleItem
convertModuleItem
(
Instance
m
params
x
r
p
)
=
Instance
m
(
map
mapParam
params
)
x
r
p
where
mapParam
(
i
,
v
)
=
(
i
,
convertTypeOrExpr
v
)
convertModuleItem
other
=
other
resolveItem
::
Types
->
(
Type
,
Identifier
)
->
(
Type
,
Identifier
)
resolveItem
types
(
t
,
x
)
=
(
resolveType
types
t
,
x
)
...
...
test/basic/paramtype.sv
View file @
6271e16b
...
...
@@ -88,6 +88,7 @@ module d_1; n_def #(logic [1:0], logic [2:0]) x(); endmodule
module
d_2
;
n_def
#(
.
T
(
logic
[
1
:
0
]))
x
()
;
endmodule
module
d_3
;
n_def
#(
.
U
(
logic
[
1
:
0
]))
x
()
;
endmodule
module
d_4
;
n_def
#(
.
U
(
logic
)
,
.
T
(
logic
[
1
:
0
]))
x
()
;
endmodule
module
d_5
;
n_def
x
()
;
endmodule
module
e_1
;
n_tdef
#(
logic
[
1
:
0
]
,
logic
[
2
:
0
])
x
()
;
endmodule
module
e_2
;
n_tdef
#(
.
T
(
logic
[
1
:
0
])
,
.
U
(
logic
))
x
()
;
endmodule
...
...
test/basic/paramtype.v
View file @
6271e16b
...
...
@@ -20,6 +20,8 @@ module top;
$
display
(
"n_def 01 00000000000000000000000000000010 2"
)
;
$
display
(
"n_def 00 00000000000000000000000000000001 2"
)
;
$
display
(
"n_def 1 00000000000000000000000000000010 1"
)
;
$
display
(
"n_def 0 00000000000000000000000000000001 1"
)
;
$
display
(
"n_def 1 00000000000000000000000000000010 1"
)
;
$
display
(
"n_tdef 00 00000000000000000000000000000001 2"
)
;
$
display
(
"n_tdef 001 00000000000000000000000000000010 3"
)
;
$
display
(
"n_tdef 00 00000000000000000000000000000001 2"
)
;
...
...
test/basic/paramtype_recurse.sv
0 → 100644
View file @
6271e16b
module
foo
#(
parameter
type
T
=
logic
,
parameter
size
=
0
)
;
generate
if
(
size
!=
0
)
begin
:
foo
bar
#(
T
,
size
-
1
)
x
()
;
end
endgenerate
initial
$
display
(
"foo %d %d"
,
$
bits
(
T
)
,
size
)
;
endmodule
module
bar
#(
parameter
type
U
=
logic
,
parameter
size
=
0
)
;
generate
if
(
size
!=
0
)
begin
:
bar
foo
#(
U
,
size
-
1
)
x
()
;
end
endgenerate
initial
$
display
(
"bar %d %d"
,
$
bits
(
U
)
,
size
)
;
endmodule
module
top_1
;
foo
#(
byte
,
2
)
x
()
;
endmodule
module
top_2
;
bar
#(
byte
,
3
)
x
()
;
endmodule
module
top_3
;
foo
#(
bit
,
4
)
x
()
;
endmodule
module
top_4
;
bar
#(
bit
,
5
)
x
()
;
endmodule
module
top
;
endmodule
test/basic/paramtype_recurse.v
0 → 100644
View file @
6271e16b
module
foo_default
#(
parameter
size
=
0
)
;
initial
$
display
(
"foo %d %d"
,
1
,
size
)
;
endmodule
module
bar_default
#(
parameter
size
=
0
)
;
initial
$
display
(
"bar %d %d"
,
1
,
size
)
;
endmodule
module
foo_byte
#(
parameter
size
=
0
)
;
generate
if
(
size
!=
0
)
begin
:
foo
bar_byte
#(
size
-
1
)
x
()
;
end
endgenerate
initial
$
display
(
"foo %d %d"
,
8
,
size
)
;
endmodule
module
bar_byte
#(
parameter
size
=
0
)
;
generate
if
(
size
!=
0
)
begin
:
bar
foo_byte
#(
size
-
1
)
x
()
;
end
endgenerate
initial
$
display
(
"bar %d %d"
,
8
,
size
)
;
endmodule
module
foo_bit
#(
parameter
size
=
0
)
;
generate
if
(
size
!=
0
)
begin
:
foo
bar_bit
#(
size
-
1
)
x
()
;
end
endgenerate
initial
$
display
(
"foo %d %d"
,
1
,
size
)
;
endmodule
module
bar_bit
#(
parameter
size
=
0
)
;
generate
if
(
size
!=
0
)
begin
:
bar
foo_bit
#(
size
-
1
)
x
()
;
end
endgenerate
initial
$
display
(
"bar %d %d"
,
1
,
size
)
;
endmodule
module
top_1
;
foo_byte
#(
2
)
x
()
;
endmodule
module
top_2
;
bar_byte
#(
3
)
x
()
;
endmodule
module
top_3
;
foo_bit
#(
4
)
x
()
;
endmodule
module
top_4
;
bar_bit
#(
5
)
x
()
;
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