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
8e1693d3
Commit
8e1693d3
authored
Jul 25, 2020
by
Zachary Snow
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
yosys-compatible unbased unsized binding conversion
parent
21ebbb5a
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
105 additions
and
87 deletions
+105
-87
src/Convert/UnbasedUnsized.hs
+105
-87
No files found.
src/Convert/UnbasedUnsized.hs
View file @
8e1693d3
{-# LANGUAGE PatternSynonyms #-}
{-# LANGUAGE TupleSections #-}
{- sv2v
- Author: Zachary Snow <zach@zachjs.com>
-
...
...
@@ -6,116 +7,133 @@
-
- The literals are given a binary base, a size of 1, and are made signed to
- allow sign extension. For context-determined expressions, the converted
- literals are
explicitly cast to the appropriat
e context-determined size.
- literals are
repeated to match th
e context-determined size.
-
- As a special case, unbased, unsized literals which take on the size of a
- module port binding are replaced with a hierarchical reference to an
- appropriately sized constant which is injected into the instantiated module's
- definition. This allows these literals to be used for parameterized ports
- without further complicating other conversions, as hierarchical references
- are not allowed within constant expressions.
- module's port are replaced as above, but with the size of the port being
- determined based on the parameter bindings of the instance and the definition
- of the instantiated module.
-}
module
Convert.UnbasedUnsized
(
convert
)
where
import
Control.Monad.Writer
import
Data.Maybe
(
catMaybes
)
import
qualified
Data.Map.Strict
as
Map
import
Convert.ExprUtils
import
Convert.Traverse
import
Language.SystemVerilog.AST
type
Part
=
([
Identifier
],
[
ModuleItem
])
type
Parts
=
Map
.
Map
Identifier
Part
data
ExprContext
=
SelfDetermined
|
ContextDetermined
Expr
deriving
(
Eq
,
Show
)
type
Port
=
Either
Identifier
Int
data
Bind
=
Bind
{
bModule
::
Identifier
,
bBit
::
Char
,
bPort
::
Port
}
deriving
(
Eq
,
Show
)
type
Binds
=
[
Bind
]
convert
::
[
AST
]
->
[
AST
]
convert
files
=
map
(
traverseDescriptions
$
convertDescription
binds
)
files'
map
(
traverseDescriptions
convertDescription
)
files
where
(
files'
,
binds
)
=
runWriter
$
mapM
(
mapM
$
traverseModuleItemsM
convertModuleItemM
)
file
s
parts
=
execWriter
$
mapM
(
collectDescriptionsM
collectPartsM
)
files
convertDescription
=
traverseModuleItems
$
convertModuleItem
part
s
convertDescription
::
Binds
->
Description
->
Description
convertDescription
[]
other
=
other
convertDescription
binds
(
Part
attrs
extern
kw
lifetime
name
ports
items
)
=
Part
attrs
extern
kw
lifetime
name
ports
items'
collectPartsM
::
Description
->
Writer
Parts
()
collectPartsM
(
Part
_
_
_
_
name
ports
items
)
=
tell
$
Map
.
singleton
name
(
ports
,
items
)
collectPartsM
_
=
return
()
convertModuleItem
::
Parts
->
ModuleItem
->
ModuleItem
convertModuleItem
parts
(
Instance
moduleName
params
instanceName
[]
bindings
)
=
convertModuleItem'
$
Instance
moduleName
params
instanceName
[]
bindings'
where
binds'
=
filter
((
==
name
)
.
bModule
)
binds
items'
=
removeDupes
[]
$
items
++
map
(
bindItem
ports
)
binds'
removeDupes
::
[
Identifier
]
->
[
ModuleItem
]
->
[
ModuleItem
]
removeDupes
_
[]
=
[]
removeDupes
existing
(
item
@
(
MIPackageItem
(
Decl
decl
))
:
is
)
=
case
decl
of
Param
Localparam
_
x
_
->
if
elem
x
existing
then
removeDupes
existing
is
else
item
:
removeDupes
(
x
:
existing
)
is
_
->
item
:
removeDupes
existing
is
removeDupes
existing
(
item
:
is
)
=
item
:
removeDupes
existing
is
convertDescription
_
other
=
other
bindName
::
Bind
->
Identifier
bindName
(
Bind
_
ch
(
Left
x
))
=
"sv2v_uub_"
++
ch
:
'_'
:
x
bindName
(
Bind
m
ch
(
Right
i
))
=
bindName
$
Bind
m
ch
(
Left
$
show
i
)
bindItem
::
[
Identifier
]
->
Bind
->
ModuleItem
bindItem
ports
bind
=
MIPackageItem
$
Decl
$
Param
Localparam
typ
name
expr
bindings'
=
zipWith
convertBinding
bindings
[
0
..
]
(
portNames
,
moduleItems
)
=
case
Map
.
lookup
moduleName
parts
of
Nothing
->
error
$
"could not find module: "
++
moduleName
Just
partInfo
->
partInfo
tag
=
Ident
"~~uub~~"
convertBinding
::
PortBinding
->
Int
->
PortBinding
convertBinding
(
portName
,
expr
)
idx
=
(
portName
,
)
$
traverseNestedExprs
(
replaceBindingExpr
portName
idx
)
$
convertExpr
(
ContextDetermined
tag
)
expr
replaceBindingExpr
::
Identifier
->
Int
->
Expr
->
Expr
replaceBindingExpr
portName
idx
(
orig
@
(
Repeat
_
[
ConvertedUU
a
b
]))
=
if
orig
==
sizedLiteralFor
tag
ch
then
Repeat
portSize
[
ConvertedUU
a
b
]
else
orig
where
portName
=
lookupPort
ports
(
bPort
bind
)
size
=
DimsFn
FnBits
$
Right
$
Ident
portName
rng
=
(
BinOp
Sub
size
(
RawNum
1
),
RawNum
0
)
typ
=
Implicit
Unspecified
[
rng
]
name
=
bindName
bind
expr
=
literalFor
$
bBit
bind
lookupPort
::
[
Identifier
]
->
Port
->
Identifier
lookupPort
_
(
Left
x
)
=
x
lookupPort
ports
(
Right
i
)
=
if
i
<
length
ports
then
ports
!!
i
else
error
$
"out of bounds bort binding "
++
show
(
ports
,
i
)
convertModuleItemM
::
ModuleItem
->
Writer
Binds
ModuleItem
convertModuleItemM
(
Instance
moduleName
params
instanceName
[]
bindings
)
=
do
bindings'
<-
mapM
(
uncurry
convertBinding
)
$
zip
bindings
[
0
..
]
let
item
=
Instance
moduleName
params
instanceName
[]
bindings'
return
$
convertModuleItem
item
ch
=
charForBit
a
b
portName'
=
if
null
portName
then
lookupBindingName
portNames
idx
else
portName
portSize
=
determinePortSize
portName'
params
moduleItems
replaceBindingExpr
_
_
other
=
other
convertModuleItem
_
other
=
convertModuleItem'
other
determinePortSize
::
Identifier
->
[
ParamBinding
]
->
[
ModuleItem
]
->
Expr
determinePortSize
portName
instanceParams
moduleItems
=
step
initialMapping
moduleItems
where
tag
=
Ident
":uub:"
convertBinding
::
PortBinding
->
Int
->
Writer
Binds
PortBinding
convertBinding
(
portName
,
expr
)
idx
=
do
let
port
=
if
null
portName
then
Right
idx
else
Left
portName
let
expr'
=
convertExpr
(
ContextDetermined
tag
)
expr
expr''
<-
traverseNestedExprsM
(
replaceBindingExpr
port
)
expr'
return
(
portName
,
expr''
)
replaceBindingExpr
::
Port
->
Expr
->
Writer
Binds
Expr
replaceBindingExpr
port
(
orig
@
(
Repeat
_
[
ConvertedUU
a
b
]))
=
do
let
ch
=
charForBit
a
b
if
orig
==
sizedLiteralFor
tag
ch
then
do
let
bind
=
Bind
moduleName
ch
port
tell
[
bind
]
let
expr
=
Dot
(
Ident
instanceName
)
(
bindName
bind
)
return
expr
else
return
orig
replaceBindingExpr
_
other
=
return
other
convertModuleItemM
other
=
return
$
convertModuleItem
other
convertModuleItem
::
ModuleItem
->
ModuleItem
convertModuleItem
=
moduleParams
=
parameterNames
moduleItems
initialMapping
=
catMaybes
$
zipWith
createParamReplacement
instanceParams
[
0
..
]
createParamReplacement
::
ParamBinding
->
Int
->
Maybe
(
Identifier
,
Expr
)
createParamReplacement
(
""
,
b
)
idx
=
createParamReplacement
(
paramName
,
b
)
idx
where
paramName
=
lookupBindingName
moduleParams
idx
createParamReplacement
(
_
,
Left
_
)
_
=
Nothing
createParamReplacement
(
paramName
,
Right
expr
)
_
=
Just
(
paramName
,
tagExpr
expr
)
step
::
[(
Identifier
,
Expr
)]
->
[
ModuleItem
]
->
Expr
step
mapping
(
MIPackageItem
(
Decl
(
Param
_
_
x
e
))
:
rest
)
=
step
(
mapping
++
[(
x
,
e
)])
rest
step
mapping
(
MIPackageItem
(
Decl
(
Variable
_
t
x
a
_
))
:
rest
)
=
if
x
==
portName
then
substituteExpr
mapping
size
else
step
mapping
rest
where
size
=
BinOp
Mul
(
dimensionsSize
a
)
(
DimsFn
FnBits
$
Left
t
)
step
mapping
(
_
:
rest
)
=
step
mapping
rest
step
_
[]
=
error
$
"could not find size of port "
++
portName
substituteExpr
::
[(
Identifier
,
Expr
)]
->
Expr
->
Expr
substituteExpr
_
(
Ident
(
':'
:
x
))
=
Ident
x
substituteExpr
mapping
(
Ident
x
)
=
case
lookup
x
mapping
of
Nothing
->
Ident
x
Just
expr
->
substituteExpr
mapping
expr
substituteExpr
mapping
expr
=
traverseSinglyNestedExprs
(
substituteExpr
mapping
)
expr
tagExpr
::
Expr
->
Expr
tagExpr
(
Ident
x
)
=
Ident
(
':'
:
x
)
tagExpr
expr
=
traverseSinglyNestedExprs
tagExpr
expr
-- given a list of module items, produces the parameter names in order
parameterNames
::
[
ModuleItem
]
->
[
Identifier
]
parameterNames
=
execWriter
.
mapM
(
collectNestedModuleItemsM
$
collectDeclsM
collectDeclM
)
where
collectDeclM
::
Decl
->
Writer
[
Identifier
]
()
collectDeclM
(
Param
Parameter
_
x
_
)
=
tell
[
x
]
collectDeclM
(
ParamType
Parameter
x
_
)
=
tell
[
x
]
collectDeclM
_
=
return
()
lookupBindingName
::
[
Identifier
]
->
Int
->
Identifier
lookupBindingName
names
idx
=
if
idx
<
length
names
then
names
!!
idx
else
error
$
"out of bounds binding "
++
show
(
names
,
idx
)
convertModuleItem'
::
ModuleItem
->
ModuleItem
convertModuleItem'
=
traverseExprs
(
convertExpr
SelfDetermined
)
.
traverseTypes
(
traverseNestedTypes
convertType
)
.
traverseAsgns
convertAsgn
...
...
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