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
7ea5b60d
Commit
7ea5b60d
authored
Dec 21, 2019
by
Zachary Snow
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
support for inside case statements
parent
ba79b17b
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
121 additions
and
31 deletions
+121
-31
src/Convert/Inside.hs
+40
-5
src/Language/SystemVerilog/AST/Expr.hs
+5
-3
src/Language/SystemVerilog/AST/Stmt.hs
+6
-2
src/Language/SystemVerilog/Parser/Parse.y
+41
-21
test/basic/inside_expr.sv
+14
-0
test/basic/inside_expr.v
+15
-0
No files found.
src/Convert/Inside.hs
View file @
7ea5b60d
{- sv2v
- Author: Zachary Snow <zach@zachjs.com>
-
- Conversion for `inside` expressions
- Conversion for `inside` expressions
and cases
-
- The expressions are compared to each candidate using the wildcard comparison
- operator. Note that if expression has any Xs or Zs that are not wildcarded in
- the candidate, the results is `1'bx`. As required by the specification, the
- result of each comparison is combined using an OR reduction.
-
- `case ... inside` statements are converted to an equivalent if-else cascade.
-
- TODO: Add support for array value ranges.
- TODO: This conversion may cause an expression with side effects to be
- evaluated more than once.
-}
module
Convert.Inside
(
convert
)
where
...
...
@@ -16,13 +20,20 @@ module Convert.Inside (convert) where
import
Convert.Traverse
import
Language.SystemVerilog.AST
import
Data.Maybe
(
fromMaybe
)
convert
::
[
AST
]
->
[
AST
]
convert
=
map
$
traverseDescriptions
$
traverseModuleItems
$
traverseExprs
$
traverseNestedExprs
convertExpr
convert
=
map
$
traverseDescriptions
$
traverseModuleItems
convertModuleItem
convertModuleItem
::
ModuleItem
->
ModuleItem
convertModuleItem
item
=
traverseExprs
(
traverseNestedExprs
convertExpr
)
$
traverseStmts
convertStmt
$
item
convertExpr
::
Expr
->
Expr
convertExpr
(
Inside
Nil
valueRanges
)
=
Inside
Nil
valueRanges
convertExpr
(
Inside
expr
valueRanges
)
=
if
length
checks
==
1
then
head
checks
...
...
@@ -44,3 +55,27 @@ convertExpr (Inside expr valueRanges) =
(
BinOp
Le
lo
expr
)
(
BinOp
Ge
hi
expr
)
convertExpr
other
=
other
convertStmt
::
Stmt
->
Stmt
convertStmt
(
Case
u
kw
expr
items
)
=
if
not
$
any
isSpecialInside
exprs
then
Case
u
kw
expr
items
else
if
kw
/=
CaseN
then
error
$
"cannot use inside with "
++
show
kw
else
foldr
(
$
)
defaultStmt
$
map
(
uncurry
$
If
NoCheck
)
$
zip
comps
stmts
where
exprs
=
map
fst
items
itemsNonDefault
=
filter
(
not
.
null
.
fst
)
items
isSpecialInside
::
[
Expr
]
->
Bool
isSpecialInside
[
Inside
Nil
_
]
=
True
isSpecialInside
_
=
False
makeComp
::
[
Expr
]
->
Expr
makeComp
[
Inside
Nil
ovr
]
=
Inside
expr
ovr
makeComp
_
=
error
"internal invariant violated"
comps
=
map
(
makeComp
.
fst
)
itemsNonDefault
stmts
=
map
snd
itemsNonDefault
defaultStmt
=
fromMaybe
Null
(
lookup
[]
items
)
convertStmt
other
=
other
src/Language/SystemVerilog/AST/Expr.hs
View file @
7ea5b60d
...
...
@@ -16,6 +16,7 @@ module Language.SystemVerilog.AST.Expr
,
DimFn
(
..
)
,
showAssignment
,
showRanges
,
showExprOrRange
,
simplify
,
rangeSize
,
endianCondExpr
...
...
@@ -85,9 +86,6 @@ instance Show Expr where
show
(
Inside
e
l
)
=
printf
"(%s inside { %s })"
(
show
e
)
(
intercalate
", "
strs
)
where
strs
=
map
showExprOrRange
l
showExprOrRange
::
ExprOrRange
->
String
showExprOrRange
(
Left
x
)
=
show
x
showExprOrRange
(
Right
x
)
=
show
x
show
(
Pattern
l
)
=
printf
"'{
\n
%s
\n
}"
(
indent
$
intercalate
",
\n
"
$
map
showPatternItem
l
)
where
...
...
@@ -159,6 +157,10 @@ showRanges l = " " ++ (concatMap showRange l)
showRange
::
Range
->
String
showRange
(
h
,
l
)
=
printf
"[%s:%s]"
(
show
h
)
(
show
l
)
showExprOrRange
::
ExprOrRange
->
String
showExprOrRange
(
Left
x
)
=
show
x
showExprOrRange
(
Right
x
)
=
show
x
clog2Help
::
Int
->
Int
->
Int
clog2Help
p
n
=
if
p
>=
n
then
0
else
1
+
clog2Help
(
p
*
2
)
n
clog2
::
Int
->
Int
...
...
src/Language/SystemVerilog/AST/Stmt.hs
View file @
7ea5b60d
...
...
@@ -28,7 +28,7 @@ import Text.Printf (printf)
import
Language.SystemVerilog.AST.ShowHelp
(
commas
,
indent
,
unlines'
,
showPad
)
import
Language.SystemVerilog.AST.Attr
(
Attr
)
import
Language.SystemVerilog.AST.Decl
(
Decl
)
import
Language.SystemVerilog.AST.Expr
(
Expr
,
Args
(
..
)
)
import
Language.SystemVerilog.AST.Expr
(
Expr
(
Inside
,
Nil
),
Args
(
..
),
showExprOrRange
)
import
Language.SystemVerilog.AST.LHS
(
LHS
)
import
Language.SystemVerilog.AST.Op
(
AsgnOp
(
AsgnOpEq
))
import
Language.SystemVerilog.AST.Type
(
Identifier
)
...
...
@@ -132,7 +132,11 @@ showShortBranch stmt = showBranch stmt
showCase
::
Case
->
String
showCase
(
a
,
b
)
=
printf
"%s:%s"
exprStr
(
showShortBranch
b
)
where
exprStr
=
if
null
a
then
"default"
else
commas
$
map
show
a
where
exprStr
=
case
a
of
[]
->
"default"
[
Inside
Nil
c
]
->
commas
$
map
showExprOrRange
c
_
->
commas
$
map
show
a
data
CaseKW
=
CaseN
...
...
src/Language/SystemVerilog/Parser/Parse.y
View file @
7ea5b60d
...
...
@@ -1046,17 +1046,13 @@ CaseKW :: { CaseKW }
| "casez" { CaseZ }
Cases :: { [Case] }
: {- empty -} { [] }
| Case Cases { $1 : $2 }
| CaseDefault CasesNoDefault { ([], $1) : $2 }
CasesNoDefault :: { [Case] }
: {- empty -} { [] }
| CasesNoDefault Case { $1 ++ [$2] }
Case :: { Case }
: Exprs ":" Stmt { ($1, $3) }
CaseDefault :: { Stmt }
: "default" opt(":") Stmt { $3 }
: opt("inside") InsideCases { validateCases $1 $2 }
InsideCases :: { [([ExprOrRange], Stmt)] }
: InsideCase { [$1] }
| InsideCases InsideCase { $1 ++ [$2] }
InsideCase :: { ([ExprOrRange], Stmt) }
: OpenRangeList ":" Stmt { ($1, $3) }
| "default" opt(":") Stmt { ([], $3) }
Number :: { String }
: number { tokenString $1 }
...
...
@@ -1223,17 +1219,11 @@ GenBlock :: { (Identifier, [GenItem]) }
: "begin" StrTag GenItems "end" StrTag { (combineTags $2 $5, $3) }
GenCases :: { [GenCase] }
: {- empty -} { [] }
| GenCase GenCases { $1 : $2 }
| GenCaseDefault GenCasesNoDefault { ([], $1) : $2 }
GenCasesNoDefault :: { [GenCase] }
: {- empty -} { [] }
| GenCasesNoDefault GenCase { $1 ++ [$2] }
: GenCase { [$1] }
| GenCases GenCase { validateGenCases $ $1 ++ [$2] }
GenCase :: { GenCase }
: Exprs ":" GenItemOrNull { ($1, $3) }
GenCaseDefault :: { GenItem }
: "default" opt(":") GenItemOrNull { $3 }
: Exprs ":" GenItemOrNull { ($1, $3) }
| "default" opt(":") GenItemOrNull { ([], $3) }
GenvarInitialization :: { (Bool, Identifier, Expr) }
: "genvar" Identifier "=" Expr { (True , $2, $4) }
...
...
@@ -1335,4 +1325,34 @@ fieldDecl t (x, rs2) =
(tf $ rs2 ++ rs1, x)
where (tf, rs1) = typeRanges t
validateCases :: Maybe Token -> [([ExprOrRange], Stmt)] -> [Case]
validateCases Nothing items =
if length (filter null exprs) <= 1
then zip exprs' stmts
else error $ "multiple default cases: " ++ show items
where
(exprs, stmts) = unzip items
exprs' = map (map unwrap) exprs
unwrap (Left expr) = expr
unwrap (Right range) =
error $ "illegal use of a range (" ++ show range
++ ") in a non-inside case"
validateCases (Just _) items =
if length (filter null sets) <= 1
then zip sets' stmts
else error $ "multiple default cases: " ++ show items
where
(sets, stmts) = unzip items
sets' = map unwrap sets
unwrap [] = []
unwrap ls = [Inside Nil ls]
validateGenCases :: [GenCase] -> [GenCase]
validateGenCases items =
if length (filter null exprs) <= 1
then items
else error $ "multiple default generate cases: " ++ show items
where
(exprs, _) = unzip items
}
test/basic/inside_expr.sv
View file @
7ea5b60d
...
...
@@ -46,4 +46,18 @@ module top;
$
display
(
"test2(%02d) = %b"
,
i
,
test2
(
i
))
;
end
function
integer
test3
;
input
integer
inp
;
case
(
inp
)
inside
[
16
:
23
]
:
return
1
;
[
32
:
47
]
:
return
2
;
default:
return
0
;
0
,
[
60
:
61
]
,
4
:
return
3
;
endcase
endfunction
initial
begin
for
(
integer
i
=
0
;
i
<
64
;
++
i
)
$
display
(
"test3(%02d) = %b"
,
i
,
test3
(
i
))
;
end
endmodule
test/basic/inside_expr.v
View file @
7ea5b60d
...
...
@@ -51,4 +51,19 @@ module top;
$
display
(
"test2(%02d) = %b"
,
i
,
test2
(
i
))
;
end
function
[
0
:
31
]
test3
;
input
integer
inp
;
begin
if
(
16
<=
inp
&&
inp
<=
23
)
test3
=
1
;
else
if
(
32
<=
inp
&&
inp
<=
47
)
test3
=
2
;
else
if
(
inp
==
0
||
(
60
<=
inp
&&
inp
<=
61
)
||
inp
==
4
)
test3
=
3
;
else
test3
=
0
;
end
endfunction
initial
begin
:
block3
integer
i
;
for
(
i
=
0
;
i
<
64
;
++
i
)
$
display
(
"test3(%02d) = %b"
,
i
,
test3
(
i
))
;
end
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