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
e9f96963
Commit
e9f96963
authored
Sep 28, 2020
by
Zachary Snow
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
extend typeof operator support
parent
5eaecc66
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
149 additions
and
40 deletions
+149
-40
src/Convert/Scoper.hs
+1
-0
src/Convert/TypeOf.hs
+92
-40
test/basic/typeof_op.sv
+55
-0
test/basic/typeof_op.v
+1
-0
No files found.
src/Convert/Scoper.hs
View file @
e9f96963
...
@@ -40,6 +40,7 @@ module Convert.Scoper
...
@@ -40,6 +40,7 @@ module Convert.Scoper
,
withinProcedure
,
withinProcedure
,
withinProcedureM
,
withinProcedureM
,
scopeModuleItemT
,
scopeModuleItemT
,
Replacements
)
where
)
where
import
Control.Monad.State.Strict
import
Control.Monad.State.Strict
...
...
src/Convert/TypeOf.hs
View file @
e9f96963
...
@@ -3,6 +3,14 @@
...
@@ -3,6 +3,14 @@
- Author: Zachary Snow <zach@zachjs.com>
- Author: Zachary Snow <zach@zachjs.com>
-
-
- Conversion for the `type` operator
- Conversion for the `type` operator
-
- This conversion is responsible for explicit type resolution throughout sv2v.
- It uses Scoper to resolve hierarchical expressions in a scope-aware manner.
-
- Some other conversions, such as the dimension query and streaming
- concatenation conversions, defer the resolution of type information to this
- conversion pass by producing nodes with the `type` operator during
- elaboration.
-}
-}
module
Convert.TypeOf
(
convert
)
where
module
Convert.TypeOf
(
convert
)
where
...
@@ -19,9 +27,15 @@ convert :: [AST] -> [AST]
...
@@ -19,9 +27,15 @@ convert :: [AST] -> [AST]
convert
=
map
$
traverseDescriptions
$
partScoper
convert
=
map
$
traverseDescriptions
$
partScoper
traverseDeclM
traverseModuleItemM
traverseGenItemM
traverseStmtM
traverseDeclM
traverseModuleItemM
traverseGenItemM
traverseStmtM
-- internal representation of a fully implicit type
pattern
UnknownType
::
Type
pattern
UnknownType
::
Type
pattern
UnknownType
=
Implicit
Unspecified
[]
pattern
UnknownType
=
Implicit
Unspecified
[]
-- single bit 4-state `logic` type
pattern
UnitType
::
Type
pattern
UnitType
=
IntegerVector
TLogic
Unspecified
[]
-- insert the given declaration into the scope, and convert an TypeOfs within
traverseDeclM
::
Decl
->
Scoper
Type
Decl
traverseDeclM
::
Decl
->
Scoper
Type
Decl
traverseDeclM
decl
=
do
traverseDeclM
decl
=
do
item
<-
traverseModuleItemM
(
MIPackageItem
$
Decl
decl
)
item
<-
traverseModuleItemM
(
MIPackageItem
$
Decl
decl
)
...
@@ -29,7 +43,7 @@ traverseDeclM decl = do
...
@@ -29,7 +43,7 @@ traverseDeclM decl = do
case
decl'
of
case
decl'
of
Variable
Local
UnknownType
ident
[]
Nil
->
do
Variable
Local
UnknownType
ident
[]
Nil
->
do
-- functions with no return type implicitly return a single bit
-- functions with no return type implicitly return a single bit
insertElem
ident
$
IntegerVector
TLogic
Unspecified
[]
insertElem
ident
UnitType
return
decl'
return
decl'
Variable
d
t
ident
a
e
->
do
Variable
d
t
ident
a
e
->
do
let
t'
=
injectRanges
t
a
let
t'
=
injectRanges
t
a
...
@@ -46,6 +60,7 @@ traverseDeclM decl = do
...
@@ -46,6 +60,7 @@ traverseDeclM decl = do
ParamType
{}
->
return
decl'
ParamType
{}
->
return
decl'
CommentDecl
{}
->
return
decl'
CommentDecl
{}
->
return
decl'
-- convert TypeOf in a ModuleItem
traverseModuleItemM
::
ModuleItem
->
Scoper
Type
ModuleItem
traverseModuleItemM
::
ModuleItem
->
Scoper
Type
ModuleItem
traverseModuleItemM
(
Genvar
x
)
=
do
traverseModuleItemM
(
Genvar
x
)
=
do
insertElem
x
$
IntegerAtom
TInteger
Unspecified
insertElem
x
$
IntegerAtom
TInteger
Unspecified
...
@@ -53,12 +68,15 @@ traverseModuleItemM (Genvar x) = do
...
@@ -53,12 +68,15 @@ traverseModuleItemM (Genvar x) = do
traverseModuleItemM
item
=
traverseModuleItemM
item
=
traverseTypesM
(
traverseNestedTypesM
traverseTypeM
)
item
traverseTypesM
(
traverseNestedTypesM
traverseTypeM
)
item
-- convert TypeOf in a GenItem
traverseGenItemM
::
GenItem
->
Scoper
Type
GenItem
traverseGenItemM
::
GenItem
->
Scoper
Type
GenItem
traverseGenItemM
=
traverseGenItemExprsM
traverseExprM
traverseGenItemM
=
traverseGenItemExprsM
traverseExprM
-- convert TypeOf in a Stmt
traverseStmtM
::
Stmt
->
Scoper
Type
Stmt
traverseStmtM
::
Stmt
->
Scoper
Type
Stmt
traverseStmtM
=
traverseStmtExprsM
traverseExprM
traverseStmtM
=
traverseStmtExprsM
traverseExprM
-- convert TypeOf in a Expr
traverseExprM
::
Expr
->
Scoper
Type
Expr
traverseExprM
::
Expr
->
Scoper
Type
Expr
traverseExprM
=
traverseNestedExprsM
$
traverseExprTypesM
$
traverseExprM
=
traverseNestedExprsM
$
traverseExprTypesM
$
traverseNestedTypesM
traverseTypeM
traverseNestedTypesM
traverseTypeM
...
@@ -67,6 +85,8 @@ traverseTypeM :: Type -> Scoper Type Type
...
@@ -67,6 +85,8 @@ traverseTypeM :: Type -> Scoper Type Type
traverseTypeM
(
TypeOf
expr
)
=
typeof
expr
traverseTypeM
(
TypeOf
expr
)
=
typeof
expr
traverseTypeM
other
=
return
other
traverseTypeM
other
=
return
other
-- attempts to find the given (potentially hierarchical or generate-scoped)
-- expression in the available scope information
lookupTypeOf
::
Expr
->
Scoper
Type
Type
lookupTypeOf
::
Expr
->
Scoper
Type
Type
lookupTypeOf
expr
=
do
lookupTypeOf
expr
=
do
details
<-
lookupElemM
expr
details
<-
lookupElemM
expr
...
@@ -75,15 +95,18 @@ lookupTypeOf expr = do
...
@@ -75,15 +95,18 @@ lookupTypeOf expr = do
Just
(
_
,
replacements
,
typ
)
->
Just
(
_
,
replacements
,
typ
)
->
return
$
if
Map
.
null
replacements
return
$
if
Map
.
null
replacements
then
typ
then
typ
else
rewriteType
typ
else
rewriteType
replacements
typ
where
where
rewriteType
=
traverseNestedTypes
$
traverseTypeExprs
$
rewriteType
::
Replacements
->
Type
->
Type
traverseNestedExprs
replace
rewriteType
replacements
=
traverseNestedTypes
$
traverseTypeExprs
$
replace
::
Expr
->
Expr
traverseNestedExprs
(
replace
replacements
)
replace
(
Ident
x
)
=
replace
::
Replacements
->
Expr
->
Expr
replace
replacements
(
Ident
x
)
=
Map
.
findWithDefault
(
Ident
x
)
x
replacements
Map
.
findWithDefault
(
Ident
x
)
x
replacements
replace
other
=
other
replace
_
other
=
other
-- determines the type of an expression based on the available scope information
-- according the semantics defined in IEEE 1800-2017, especially Section 11.6
typeof
::
Expr
->
Scoper
Type
Type
typeof
::
Expr
->
Scoper
Type
Type
typeof
(
Number
n
)
=
typeof
(
Number
n
)
=
return
$
IntegerVector
TLogic
sg
[
r
]
return
$
IntegerVector
TLogic
sg
[
r
]
...
@@ -91,14 +114,7 @@ typeof (Number n) =
...
@@ -91,14 +114,7 @@ typeof (Number n) =
r
=
(
RawNum
$
size
-
1
,
RawNum
0
)
r
=
(
RawNum
$
size
-
1
,
RawNum
0
)
size
=
numberBitLength
n
size
=
numberBitLength
n
sg
=
if
numberIsSigned
n
then
Signed
else
Unspecified
sg
=
if
numberIsSigned
n
then
Signed
else
Unspecified
typeof
(
Call
(
Ident
"$unsigned"
)
(
Args
[
e
]
[]
))
=
typeof
(
Call
(
Ident
x
)
args
)
=
typeofCall
x
args
typeof
e
typeof
(
Call
(
Ident
"$signed"
)
(
Args
[
e
]
[]
))
=
typeof
e
typeof
(
Call
(
Ident
"$clog2"
)
(
Args
[
_
]
[]
))
=
return
$
IntegerAtom
TInteger
Unspecified
typeof
(
Call
(
Ident
x
)
_
)
=
typeof
$
Ident
x
typeof
(
orig
@
(
Bit
e
_
))
=
do
typeof
(
orig
@
(
Bit
e
_
))
=
do
t
<-
typeof
e
t
<-
typeof
e
case
t
of
case
t
of
...
@@ -120,10 +136,8 @@ typeof (orig @ (Range e mode r)) = do
...
@@ -120,10 +136,8 @@ typeof (orig @ (Range e mode r)) = do
typeof
(
orig
@
(
Dot
e
x
))
=
do
typeof
(
orig
@
(
Dot
e
x
))
=
do
t
<-
typeof
e
t
<-
typeof
e
case
t
of
case
t
of
Struct
_
fields
[]
->
Struct
_
fields
[]
->
return
$
fieldsType
fields
return
$
fieldsType
fields
Union
_
fields
[]
->
return
$
fieldsType
fields
Union
_
fields
[]
->
return
$
fieldsType
fields
_
->
lookupTypeOf
orig
_
->
lookupTypeOf
orig
where
where
fieldsType
::
[
Field
]
->
Type
fieldsType
::
[
Field
]
->
Type
...
@@ -132,23 +146,8 @@ typeof (orig @ (Dot e x)) = do
...
@@ -132,23 +146,8 @@ typeof (orig @ (Dot e x)) = do
Just
typ
->
typ
Just
typ
->
typ
Nothing
->
TypeOf
orig
Nothing
->
TypeOf
orig
typeof
(
Cast
(
Right
s
)
_
)
=
return
$
typeOfSize
s
typeof
(
Cast
(
Right
s
)
_
)
=
return
$
typeOfSize
s
typeof
(
UniOp
UniSub
e
)
=
typeof
e
typeof
(
UniOp
op
expr
)
=
typeofUniOp
op
expr
typeof
(
UniOp
BitNot
e
)
=
typeof
e
typeof
(
BinOp
op
a
b
)
=
typeofBinOp
op
a
b
typeof
(
UniOp
LogNot
_
)
=
return
$
IntegerVector
TLogic
Unspecified
[]
typeof
(
BinOp
Pow
e
_
)
=
typeof
e
typeof
(
BinOp
ShiftL
e
_
)
=
typeof
e
typeof
(
BinOp
ShiftR
e
_
)
=
typeof
e
typeof
(
BinOp
ShiftAL
e
_
)
=
typeof
e
typeof
(
BinOp
ShiftAR
e
_
)
=
typeof
e
typeof
(
BinOp
Add
a
b
)
=
largerSizeType
a
b
typeof
(
BinOp
Sub
a
b
)
=
largerSizeType
a
b
typeof
(
BinOp
Mul
a
b
)
=
largerSizeType
a
b
typeof
(
BinOp
Div
a
b
)
=
largerSizeType
a
b
typeof
(
BinOp
Mod
a
b
)
=
largerSizeType
a
b
typeof
(
BinOp
BitAnd
a
b
)
=
largerSizeType
a
b
typeof
(
BinOp
BitXor
a
b
)
=
largerSizeType
a
b
typeof
(
BinOp
BitXnor
a
b
)
=
largerSizeType
a
b
typeof
(
BinOp
BitOr
a
b
)
=
largerSizeType
a
b
typeof
(
Mux
_
a
b
)
=
largerSizeType
a
b
typeof
(
Mux
_
a
b
)
=
largerSizeType
a
b
typeof
(
Concat
exprs
)
=
return
$
typeOfSize
$
concatSize
exprs
typeof
(
Concat
exprs
)
=
return
$
typeOfSize
$
concatSize
exprs
typeof
(
Repeat
reps
exprs
)
=
return
$
typeOfSize
size
typeof
(
Repeat
reps
exprs
)
=
return
$
typeOfSize
size
...
@@ -158,12 +157,65 @@ typeof (String str) =
...
@@ -158,12 +157,65 @@ typeof (String str) =
where
where
r
=
(
RawNum
$
len
-
1
,
RawNum
0
)
r
=
(
RawNum
$
len
-
1
,
RawNum
0
)
len
=
if
null
str
then
1
else
8
*
unescapedLength
str
len
=
if
null
str
then
1
else
8
*
unescapedLength
str
unescapedLength
::
String
->
Integer
unescapedLength
[]
=
0
unescapedLength
(
'
\\
'
:
_
:
rest
)
=
1
+
unescapedLength
rest
unescapedLength
(
_
:
rest
)
=
1
+
unescapedLength
rest
typeof
other
=
lookupTypeOf
other
typeof
other
=
lookupTypeOf
other
-- length of a string literal in characters
unescapedLength
::
String
->
Integer
unescapedLength
[]
=
0
unescapedLength
(
'
\\
'
:
_
:
rest
)
=
1
+
unescapedLength
rest
unescapedLength
(
_
:
rest
)
=
1
+
unescapedLength
rest
-- type of a standard (non-member) function call
typeofCall
::
String
->
Args
->
Scoper
Type
Type
typeofCall
"$unsigned"
(
Args
[
e
]
[]
)
=
typeof
e
typeofCall
"$signed"
(
Args
[
e
]
[]
)
=
typeof
e
typeofCall
"$clog2"
(
Args
[
_
]
[]
)
=
return
$
IntegerAtom
TInteger
Unspecified
typeofCall
fnName
_
=
typeof
$
Ident
fnName
-- type of a unary operator expression
typeofUniOp
::
UniOp
->
Expr
->
Scoper
Type
Type
typeofUniOp
UniAdd
e
=
typeof
e
typeofUniOp
UniSub
e
=
typeof
e
typeofUniOp
BitNot
e
=
typeof
e
typeofUniOp
_
_
=
-- unary reductions and logical negation
return
UnitType
-- type of a binary operator expression (Section 11.6.1)
typeofBinOp
::
BinOp
->
Expr
->
Expr
->
Scoper
Type
Type
typeofBinOp
op
a
b
=
case
op
of
LogAnd
->
unitType
LogOr
->
unitType
LogImp
->
unitType
LogEq
->
unitType
Eq
->
unitType
Ne
->
unitType
TEq
->
unitType
TNe
->
unitType
WEq
->
unitType
WNe
->
unitType
Lt
->
unitType
Le
->
unitType
Gt
->
unitType
Ge
->
unitType
Pow
->
typeof
a
ShiftL
->
typeof
a
ShiftR
->
typeof
a
ShiftAL
->
typeof
a
ShiftAR
->
typeof
a
Add
->
largerSizeType
a
b
Sub
->
largerSizeType
a
b
Mul
->
largerSizeType
a
b
Div
->
largerSizeType
a
b
Mod
->
largerSizeType
a
b
BitAnd
->
largerSizeType
a
b
BitXor
->
largerSizeType
a
b
BitXnor
->
largerSizeType
a
b
BitOr
->
largerSizeType
a
b
where
unitType
=
return
UnitType
-- produces a type large enough to hold either expression
-- produces a type large enough to hold either expression
largerSizeType
::
Expr
->
Expr
->
Scoper
Type
Type
largerSizeType
::
Expr
->
Expr
->
Scoper
Type
Type
largerSizeType
a
(
Number
(
Based
1
_
_
_
_
))
=
typeof
a
largerSizeType
a
(
Number
(
Based
1
_
_
_
_
))
=
typeof
a
...
...
test/basic/typeof_op.sv
0 → 100644
View file @
e9f96963
`define
TEST
(
expr
)
\
$
display
(
`
"expr = %b; $bits(expr) = %0d`"
,
(
expr
)
,
$
bits
(
expr
))
;
module
top
;
initial
begin
`TEST
(
4'b1011
)
`TEST
(
5'b01110
)
`TEST
(
!
3'b101
)
`TEST
(
~
3'b101
)
`TEST
(
+
3'b101
)
`TEST
(
-
3'b101
)
`TEST
(
&
3'b101
)
`TEST
(
~&
3'b101
)
`TEST
(
|
3'b101
)
`TEST
(
~|
3'b101
)
`TEST
(
^
3'b101
)
`TEST
(
~^
3'b101
)
`TEST
(
4'b1011
&&
5'b01110
)
`TEST
(
4'b1011
||
5'b01110
)
`TEST
(
4'b1011
&
5'b01110
)
`TEST
(
4'b1011
^
5'b01110
)
`TEST
(
4'b1011
~^
5'b01110
)
`TEST
(
4'b1011
|
5'b01110
)
`TEST
(
4'b1011
<<
5'b01110
)
`TEST
(
4'b1011
>>
5'b01110
)
`TEST
(
4'b1011
<<<
5'b01110
)
`TEST
(
4'b1011
>>>
5'b01110
)
`TEST
(
4'b1011
==
5'b01110
)
`TEST
(
4'b1011
!=
5'b01110
)
`TEST
(
4'b1011
===
5'b01110
)
`TEST
(
4'b1011
!==
5'b01110
)
`TEST
(
4'b1011
<
5'b01110
)
`TEST
(
4'b1011
<=
5'b01110
)
`TEST
(
4'b1011
>
5'b01110
)
`TEST
(
4'b1011
>=
5'b01110
)
// TODO: iverilog incorrectly handles width of these
// `TEST(4'b1011 * 5'b01110)
// `TEST(4'b1011 / 5'b01110)
// `TEST(4'b1011 % 5'b01110)
// `TEST(4'b1011 + 5'b01110)
// `TEST(4'b1011 - 5'b01110)
// `TEST(4'b1011 ** 5'b01110)
// TODO: not yet supported by iverilog
// `TEST(4'b1011 -> 5'b01110)
// `TEST(4'b1011 <-> 5'b01110)
// `TEST(4'b1011 ==? 5'b01110)
// `TEST(4'b1011 !=? 5'b01110)
end
endmodule
test/basic/typeof_op.v
0 → 100644
View file @
e9f96963
`include
"typeof_op.sv"
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