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
f9d46d54
Commit
f9d46d54
authored
Apr 03, 2019
by
Zachary Snow
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
cleanup of Enum conversion; additional test
parent
383754fa
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
136 additions
and
30 deletions
+136
-30
src/Convert/Enum.hs
+47
-30
test/basic/enum.sv
+56
-0
test/basic/enum.v
+30
-0
test/basic/run.sh
+3
-0
No files found.
src/Convert/Enum.hs
View file @
f9d46d54
...
@@ -3,17 +3,25 @@
...
@@ -3,17 +3,25 @@
-
-
- Conversion for `enum`
- Conversion for `enum`
-
-
- TODO: We do not yet properly support enums which specify the value for some,
- This conversion replaces the enum items with localparams declared within any
- but not all items. My understanding is that they should continue in order
- modules in which that enum type appears. This is not necessarily foolproof,
- from the previous value.
- as some tools do allow the use of an enum item even if the actual enum type
- does not appear in that description.
-
- SystemVerilog allows for enums to have any number of the items' values
- specified or unspecified. If the first one is unspecified, it is 0. All other
- values take on the value of the previous item, plus 1.
-
- It is an error for multiple items of the same enum to take on the same value,
- whether implicitly or explicitly. We catch try to catch "obvious" instances
- of conflicts.
-}
-}
module
Convert.Enum
(
convert
)
where
module
Convert.Enum
(
convert
)
where
import
Text.Read
(
readMaybe
)
import
Data.Maybe
(
fromMaybe
)
import
Data.List
(
sortOn
)
import
Control.Monad.Writer
import
Control.Monad.Writer
import
Data.List
(
elemIndices
,
sortOn
)
import
Data.Maybe
(
fromMaybe
)
import
qualified
Data.Set
as
Set
import
qualified
Data.Set
as
Set
import
Convert.Traverse
import
Convert.Traverse
...
@@ -32,36 +40,45 @@ convertDescription :: Description -> Description
...
@@ -32,36 +40,45 @@ convertDescription :: Description -> Description
convertDescription
(
description
@
(
Part
_
_
_
_
_
_
))
=
convertDescription
(
description
@
(
Part
_
_
_
_
_
_
))
=
Part
extern
kw
lifetime
name
ports
(
enumItems
++
items
)
Part
extern
kw
lifetime
name
ports
(
enumItems
++
items
)
where
where
enumPairs
=
sortOn
snd
$
concatMap
(
uncurry
enumVals
)
$
Set
.
toList
enums
-- replace and collect the enum types in this description
enumItems
=
map
(
\
(
x
,
v
)
->
MIDecl
$
Localparam
(
Implicit
Unspecified
[]
)
x
v
)
enumPairs
(
Part
extern
kw
lifetime
name
ports
items
,
enums
)
=
(
Part
extern
kw
lifetime
name
ports
items
,
enums
)
=
runWriter
$
traverseModuleItemsM
(
traverseTypesM
traverseType
)
$
runWriter
$
traverseModuleItemsM
(
traverseTypesM
traverseType
)
$
traverseModuleItems
(
traverseExprs
$
traverseNestedExprs
traverseExpr
)
$
traverseModuleItems
(
traverseExprs
$
traverseNestedExprs
traverseExpr
)
$
description
description
traverseType
::
Type
->
Writer
Enums
Type
-- convert the collected enums into their corresponding localparams
traverseType
(
Enum
t
v
r
)
=
do
itemType
=
Implicit
Unspecified
[]
()
<-
tell
$
Set
.
singleton
(
t
,
v
)
enumPairs
=
sortOn
snd
$
concatMap
(
enumVals
.
snd
)
$
Set
.
toList
enums
let
baseType
=
fromMaybe
defaultType
t
enumItems
=
map
(
\
(
x
,
v
)
->
MIDecl
$
Localparam
itemType
x
v
)
enumPairs
let
(
tf
,
rs
)
=
typeRanges
baseType
return
$
tf
(
rs
++
r
)
traverseType
other
=
return
other
-- drop any enum type casts in favor of implicit conversion from the
-- converted type
traverseExpr
::
Expr
->
Expr
traverseExpr
(
Cast
(
Left
(
Enum
_
_
_
))
e
)
=
e
traverseExpr
other
=
other
convertDescription
other
=
other
convertDescription
other
=
other
enumVals
::
Maybe
Type
->
[(
Identifier
,
Maybe
Expr
)]
->
[(
Identifier
,
Expr
)]
-- replace, but write down, enum types
enumVals
_
l
=
zip
traverseType
::
Type
->
Writer
Enums
Type
(
map
fst
l
)
traverseType
(
Enum
t
v
r
)
=
do
(
tail
$
scanl
step
(
Number
"-1"
)
(
map
snd
l
))
()
<-
tell
$
Set
.
singleton
(
t
,
v
)
let
baseType
=
fromMaybe
defaultType
t
let
(
tf
,
rs
)
=
typeRanges
baseType
return
$
tf
(
rs
++
r
)
traverseType
other
=
return
other
-- drop any enum type casts in favor of implicit conversion from the
-- converted type
traverseExpr
::
Expr
->
Expr
traverseExpr
(
Cast
(
Left
(
Enum
_
_
_
))
e
)
=
e
traverseExpr
other
=
other
enumVals
::
[(
Identifier
,
Maybe
Expr
)]
->
[(
Identifier
,
Expr
)]
enumVals
l
=
-- check for obviously duplicate values
if
noDuplicates
then
res
else
error
$
"enum conversion has duplicate vals: "
++
show
res
where
where
keys
=
map
fst
l
vals
=
tail
$
scanl
step
(
Number
"-1"
)
(
map
snd
l
)
res
=
zip
keys
vals
noDuplicates
=
all
(
null
.
tail
.
flip
elemIndices
vals
)
vals
step
::
Expr
->
Maybe
Expr
->
Expr
step
::
Expr
->
Maybe
Expr
->
Expr
step
_
(
Just
expr
)
=
expr
step
_
(
Just
expr
)
=
expr
step
(
Number
n
)
Nothing
=
case
(
readMaybe
n
)
::
Maybe
Int
of
Just
value
->
Number
(
show
$
value
+
1
)
Nothing
->
BinOp
Add
(
Number
n
)
(
Number
"1"
)
step
expr
Nothing
=
step
expr
Nothing
=
BinOp
Add
expr
(
Number
"1"
)
simplify
$
BinOp
Add
expr
(
Number
"1"
)
test/basic/enum.sv
0 → 100644
View file @
f9d46d54
typedef
enum
{
A_1
,
A_2
,
A_3
}
EnumA
;
typedef
enum
{
B_1
=
2
,
B_2
=
1
,
B_3
=
3
}
EnumB
;
typedef
enum
{
C_1
=
20
,
C_2
=
0
,
C_3
=
19
}
EnumC
;
typedef
enum
{
D_1
=
'h10
,
D_2
,
D_3
}
EnumD
;
typedef
enum
{
E_1
,
E_2
=
'h10
,
E_3
,
E_4
,
E_5
=
'b10
,
E_6
}
EnumE
;
`define
PRINT
(
val
)
$
display
("%
02d
",
val
)
;
module
top
;
EnumA
dummyA
;
EnumB
dummyB
;
EnumC
dummyC
;
EnumD
dummyD
;
EnumE
dummyE
;
initial
begin
`PRINT
(
A_1
)
`PRINT
(
A_2
)
`PRINT
(
A_3
)
`PRINT
(
B_1
)
`PRINT
(
B_2
)
`PRINT
(
B_3
)
`PRINT
(
C_1
)
`PRINT
(
C_2
)
`PRINT
(
C_3
)
`PRINT
(
D_1
)
`PRINT
(
D_2
)
`PRINT
(
D_3
)
`PRINT
(
E_1
)
`PRINT
(
E_2
)
`PRINT
(
E_3
)
`PRINT
(
E_4
)
`PRINT
(
E_5
)
`PRINT
(
E_6
)
end
endmodule
test/basic/enum.v
0 → 100644
View file @
f9d46d54
`define
PRINT
(
val
)
$
display
(
"%02d"
,
val
)
;
module
top
;
initial
begin
`PRINT
(
0
)
`PRINT
(
1
)
`PRINT
(
2
)
`PRINT
(
2
)
`PRINT
(
1
)
`PRINT
(
3
)
`PRINT
(
20
)
`PRINT
(
0
)
`PRINT
(
19
)
`PRINT
(
16
)
`PRINT
(
17
)
`PRINT
(
18
)
`PRINT
(
0
)
`PRINT
(
16
)
`PRINT
(
17
)
`PRINT
(
18
)
`PRINT
(
2
)
`PRINT
(
3
)
end
endmodule
test/basic/run.sh
0 → 100755
View file @
f9d46d54
#!/bin/sh
NO_SEPARATE_TBS
=
1
source
../lib/runner.sh
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