Commit 4c3dcf52 by Zachary Snow

support for enumerated type ranges

parent 03a913ad
......@@ -4,6 +4,7 @@
* Added support for excluding the conversion of unbased unsized literals (e.g.,
`'1`, `'x`) via `--exclude UnbasedUniszed`
* Added support for enumerated type ranges (e.g., `enum { X[3:5] }`)
### Other Enhancements
......
......@@ -9,6 +9,7 @@
module Language.SystemVerilog.AST.Type
( Identifier
, EnumItem
, Field
, Type (..)
, Signing (..)
......@@ -33,7 +34,7 @@ import Language.SystemVerilog.AST.ShowHelp
type Identifier = String
type Item = (Identifier, Expr)
type EnumItem = (Identifier, Expr)
type Field = (Type, Identifier)
data Type
......@@ -44,7 +45,7 @@ data Type
| Alias Identifier [Range]
| PSAlias Identifier Identifier [Range]
| CSAlias Identifier [ParamBinding] Identifier [Range]
| Enum Type [Item] [Range]
| Enum Type [EnumItem] [Range]
| Struct Packing [Field] [Range]
| Union Packing [Field] [Range]
| InterfaceT Identifier Identifier [Range]
......@@ -66,7 +67,7 @@ instance Show Type where
show (Enum t vals r) = printf "enum %s{%s}%s" tStr (commas $ map showVal vals) (showRanges r)
where
tStr = showPad t
showVal :: (Identifier, Expr) -> String
showVal :: EnumItem -> String
showVal (x, e) = x ++ (showAssignment e)
show (Struct p items r) = printf "struct %s{\n%s\n}%s" (showPad p) (showFields items) (showRanges r)
show (Union p items r) = printf "union %s{\n%s\n}%s" (showPad p) (showFields items) (showRanges r)
......
......@@ -519,8 +519,17 @@ NonIntegerTypeP :: { (Position, NonIntegerType) }
| "string" { withPos $1 TString }
| "event" { withPos $1 TEvent }
EnumItems :: { [(Identifier, Expr)] }
: VariablePortIdentifiers { $1 }
EnumItems :: { [EnumItem] }
: EnumItem { $1 }
| EnumItem "," EnumItems { $1 ++ $3 }
EnumItem :: { [EnumItem] }
: Identifier OptAsgn { [($1, $2)] }
| IdentifierP IntegralDimension OptAsgn {% makeEnumItems $1 $2 $3 }
IntegralDimension :: { (Integer, Integer) }
: "[" IntegralNumber "]" { ( 0, $2 - 1) }
| "[" IntegralNumber ":" IntegralNumber "]" { ($2, $4) }
IntegralNumber :: { Integer }
: number {% readIntegralNumber (tokenPosition $1) (tokenString $1) }
StructItems :: { [(Type, Identifier)] }
: StructItem { $1 }
......@@ -672,12 +681,6 @@ ParamDeclToken :: { [DeclToken] }
| "type" IdentifierP { [DTTypeDecl (tokenPosition $1), uncurry DTIdent $2] }
| ParameterDeclKW { [uncurry DTParamKW $1] }
VariablePortIdentifiers :: { [(Identifier, Expr)] }
: VariablePortIdentifier { [$1] }
| VariablePortIdentifiers "," VariablePortIdentifier { $1 ++ [$3] }
VariablePortIdentifier :: { (Identifier, Expr) }
: Identifier OptAsgn { ($1,$2) }
Direction :: { Direction }
: DirectionP { snd $1 }
DirectionP :: { (Position, Direction) }
......@@ -1714,4 +1717,29 @@ expectZeroDelay tok a = do
_ -> parseError pos $ "expected 0 after #, but found " ++ str
where Token { tokenString = str, tokenPosition = pos } = tok
readIntegralNumber :: Position -> String -> ParseState Integer
readIntegralNumber pos str = do
num <- readNumber pos str
case numberToInteger num of
Nothing ->
parseError pos $ "expected an integral number, but found " ++ str
Just integer | integer < 0 ->
parseError pos $ "expected a non-negative number, but found " ++ str
Just integer ->
return integer
makeEnumItems :: (Position, Identifier) -> (Integer, Integer) -> Expr
-> ParseState [EnumItem]
makeEnumItems (pos, _) (0, -1) _ =
parseError pos "expected a positive number, but found zero"
makeEnumItems (_, root) (l, r) base =
return $ (name, base) : map (, Nil) names
where
name : names =
map (root ++) $
map show $
if l >= r
then reverse [r..l]
else [l..r]
}
......@@ -43,6 +43,18 @@ typedef enum int {
Z_1, Z_2, Z_3
} EnumZ;
typedef enum int {
K_A,
K_B = 10,
K_C[3],
K_D[3] = 20,
K_E[4:6],
K_F[4:6] = 30,
K_G[6:4],
K_H[6:4] = 40,
K_I[3:3] = 50
} EnumK;
`define PRINT(name, val) \
dummy``name = name``_``val; \
$display(`"name %h %h %0d %0d`", \
......@@ -58,6 +70,7 @@ module top;
EnumG dummyG;
EnumH dummyH;
EnumI dummyI;
EnumK dummyK;
initial begin
......@@ -96,6 +109,28 @@ module top;
`PRINT(I, 1)
`PRINT(I, 2)
`PRINT(K, A)
`PRINT(K, B)
`PRINT(K, C0)
`PRINT(K, C1)
`PRINT(K, C2)
`PRINT(K, D0)
`PRINT(K, D1)
`PRINT(K, D2)
`PRINT(K, E4)
`PRINT(K, E5)
`PRINT(K, E6)
`PRINT(K, F4)
`PRINT(K, F5)
`PRINT(K, F6)
`PRINT(K, G6)
`PRINT(K, G5)
`PRINT(K, G4)
`PRINT(K, H6)
`PRINT(K, H5)
`PRINT(K, H4)
`PRINT(K, I3)
end
parameter USE_J = 1;
......
......@@ -14,6 +14,7 @@ module top;
reg [0:0] dummyG;
reg [3:0] dummyH;
reg [31:0] dummyI;
reg [31:0] dummyK;
initial begin
......@@ -52,6 +53,28 @@ module top;
`PRINT(I, 'b0)
`PRINT(I, 'b1)
`PRINT(K, 0)
`PRINT(K, 10)
`PRINT(K, 11)
`PRINT(K, 12)
`PRINT(K, 13)
`PRINT(K, 20)
`PRINT(K, 21)
`PRINT(K, 22)
`PRINT(K, 23)
`PRINT(K, 24)
`PRINT(K, 25)
`PRINT(K, 30)
`PRINT(K, 31)
`PRINT(K, 32)
`PRINT(K, 33)
`PRINT(K, 34)
`PRINT(K, 35)
`PRINT(K, 40)
`PRINT(K, 41)
`PRINT(K, 42)
`PRINT(K, 50)
end
parameter USE_J = 1;
......
// pattern: expected a non-negative number, but found 1'sd1
module top;
enum {
A[1'sd1]
} x;
endmodule
// pattern: expected an integral number, but found 'x
module top;
enum {
A['x]
} x;
endmodule
// pattern: expected a positive number, but found zero
module top;
enum {
A[0]
} x;
endmodule
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment