mirror of https://github.com/zachjs/sv2v.git
preliminary support for functions
This commit is contained in:
parent
6c88994ea9
commit
57630b77bd
|
|
@ -11,6 +11,10 @@ module Language.SystemVerilog.AST
|
|||
, BinOp (..)
|
||||
, Sense (..)
|
||||
, Call (..)
|
||||
, BlockItemDeclaration (..)
|
||||
, Parameter (..)
|
||||
, Localparam (..)
|
||||
, IntegerV (..)
|
||||
, PortBinding
|
||||
, Case
|
||||
, Range
|
||||
|
|
@ -74,35 +78,62 @@ instance Show Type where
|
|||
|
||||
data ModuleItem
|
||||
= Comment String
|
||||
| Parameter (Maybe Range) Identifier Expr
|
||||
| Localparam (Maybe Range) Identifier Expr
|
||||
| MIParameter Parameter
|
||||
| MILocalparam Localparam
|
||||
| MIIntegerV IntegerV
|
||||
| PortDecl Direction (Maybe Range) Identifier
|
||||
| LocalNet Type Identifier RangesOrAssignment
|
||||
| Integer Identifier RangesOrAssignment
|
||||
| Always (Maybe Sense) Stmt
|
||||
| Assign LHS Expr
|
||||
| Instance Identifier [PortBinding] Identifier [PortBinding]
|
||||
| Function (Maybe FuncRet) Identifier [(Bool, BlockItemDeclaration)] Stmt
|
||||
deriving Eq
|
||||
|
||||
-- "function inputs and outputs are inferred to be of type reg if no internal
|
||||
-- data types for the ports are declared"
|
||||
|
||||
type PortBinding = (Identifier, Maybe Expr)
|
||||
|
||||
data Parameter = Parameter (Maybe Range) Identifier Expr deriving Eq
|
||||
instance Show Parameter where
|
||||
show (Parameter r n e) = printf "parameter %s%s = %s;" (showRange r) n (showExprConst e)
|
||||
|
||||
data Localparam = Localparam (Maybe Range) Identifier Expr deriving Eq
|
||||
instance Show Localparam where
|
||||
show (Localparam r n e) = printf "localparam %s%s = %s;" (showRange r) n (showExprConst e)
|
||||
|
||||
data IntegerV = IntegerV Identifier RangesOrAssignment deriving Eq
|
||||
instance Show IntegerV where
|
||||
show (IntegerV x v ) = printf "integer %s%s;" x (showRangesOrAssignment v)
|
||||
|
||||
instance Show ModuleItem where
|
||||
show thing = case thing of
|
||||
Comment c -> "// " ++ c
|
||||
Parameter r n e -> printf "parameter %s%s = %s;" (showRange r) n (showExprConst e)
|
||||
Localparam r n e -> printf "localparam %s%s = %s;" (showRange r) n (showExprConst e)
|
||||
MIParameter nest -> show nest
|
||||
MILocalparam nest -> show nest
|
||||
MIIntegerV nest -> show nest
|
||||
PortDecl d r x -> printf "%s %s%s;" (show d) (showRange r) x
|
||||
LocalNet t x v -> printf "%s%s%s;" (show t) x (showRangesOrAssignment v)
|
||||
Integer x v -> printf "integer %s%s;" x (showRangesOrAssignment v)
|
||||
Always Nothing b -> printf "always\n%s" $ indent $ show b
|
||||
Always (Just a) b -> printf "always @(%s)\n%s" (show a) $ indent $ show b
|
||||
Assign a b -> printf "assign %s = %s;" (show a) (show b)
|
||||
Instance m params i ports
|
||||
| null params -> printf "%s %s %s;" m i (showPorts show ports)
|
||||
| otherwise -> printf "%s #%s %s %s;" m (showPorts showExprConst params) i (showPorts show ports)
|
||||
Function t x i b -> printf "function %s%s;\n%s\n%s\nendfunction" (showFuncRet t) x (indent $ unlines' $ map showFunctionItem i) (indent $ show b)
|
||||
where
|
||||
showPorts :: (Expr -> String) -> [(Identifier, Maybe Expr)] -> String
|
||||
showPorts s ports = indentedParenList [ if i == "" then show (fromJust arg) else printf ".%s(%s)" i (if isJust arg then s $ fromJust arg else "") | (i, arg) <- ports ]
|
||||
showFunctionItem :: (Bool, BlockItemDeclaration) -> String
|
||||
showFunctionItem (b, item) = prefix ++ (show item)
|
||||
where prefix = if b then "input " else ""
|
||||
|
||||
type FuncRet = Either Range ()
|
||||
|
||||
showFuncRet :: Maybe FuncRet -> String
|
||||
showFuncRet Nothing = ""
|
||||
showFuncRet (Just (Left r)) = showRange $ Just r
|
||||
showFuncRet (Just (Right ())) = "integer "
|
||||
|
||||
type RangesOrAssignment = Either [Range] (Maybe Expr)
|
||||
|
||||
|
|
@ -290,15 +321,12 @@ instance Show LHS where
|
|||
show (LHSConcat a ) = printf "{%s}" (commas $ map show a)
|
||||
|
||||
data Stmt
|
||||
= Block (Maybe Identifier) [Stmt]
|
||||
| StmtReg (Maybe Range) Identifier [Range]
|
||||
| StmtInteger Identifier RangesOrAssignment
|
||||
= Block (Maybe (Identifier, [BlockItemDeclaration])) [Stmt]
|
||||
| Case Expr [Case] (Maybe Stmt)
|
||||
| BlockingAssignment LHS Expr
|
||||
| NonBlockingAssignment LHS Expr
|
||||
| For (Identifier, Expr) Expr (Identifier, Expr) Stmt
|
||||
| If Expr Stmt Stmt
|
||||
| StmtCall Call
|
||||
| Null
|
||||
deriving Eq
|
||||
|
||||
|
|
@ -306,10 +334,8 @@ commas :: [String] -> String
|
|||
commas = intercalate ", "
|
||||
|
||||
instance Show Stmt where
|
||||
show (Block Nothing b ) = printf "begin\n%s\nend" $ indent $ unlines' $ map show b
|
||||
show (Block (Just a) b ) = printf "begin : %s\n%s\nend" a $ indent $ unlines' $ map show b
|
||||
show (StmtReg r x a ) = printf "reg %s%s%s;" (showRange r) x (showRanges a)
|
||||
show (StmtInteger x v ) = printf "integer %s%s;" x (showRangesOrAssignment v)
|
||||
show (Block Nothing b ) = printf "begin\n%s\nend" $ indent $ unlines' $ map show b
|
||||
show (Block (Just (a, i)) b ) = printf "begin : %s\n%s%s\nend" a $ indent $ unlines' $ (map show i ++ map show b)
|
||||
show (Case a b Nothing ) = printf "case (%s)\n%s\nendcase" (show a) (indent $ unlines' $ map showCase b)
|
||||
show (Case a b (Just c) ) = printf "case (%s)\n%s\n\tdefault:\n%s\nendcase" (show a) (indent $ unlines' $ map showCase b) (indent $ indent $ show c)
|
||||
show (BlockingAssignment a b ) = printf "%s = %s;" (show a) (show b)
|
||||
|
|
@ -317,9 +343,25 @@ instance Show Stmt where
|
|||
show (For (a, b) c (d, e) f) = printf "for (%s = %s; %s; %s = %s)\n%s" a (show b) (show c) d (show e) $ indent $ show f
|
||||
show (If a b Null ) = printf "if (%s)\n%s" (show a) (indent $ show b)
|
||||
show (If a b c ) = printf "if (%s)\n%s\nelse\n%s" (show a) (indent $ show b) (indent $ show c)
|
||||
show (StmtCall a ) = printf "%s;" (show a)
|
||||
show (Null ) = ";"
|
||||
|
||||
-- It's not obvious to me how this can be done in a top level
|
||||
--show (StmtCall a ) = printf "%s;" (show a)
|
||||
-- | StmtCall Call
|
||||
|
||||
data BlockItemDeclaration
|
||||
= BIDReg (Maybe Range) Identifier [Range]
|
||||
| BIDParameter Parameter
|
||||
| BIDLocalparam Localparam
|
||||
| BIDIntegerV IntegerV
|
||||
deriving Eq
|
||||
|
||||
instance Show BlockItemDeclaration where
|
||||
show (BIDReg mr x rs) = printf "reg %s%s%s;" (showRange mr) x (showRanges rs)
|
||||
show (BIDParameter nest) = show nest
|
||||
show (BIDLocalparam nest) = show nest
|
||||
show (BIDIntegerV nest) = show nest
|
||||
|
||||
type Case = ([Expr], Stmt)
|
||||
|
||||
showCase :: Case -> String
|
||||
|
|
|
|||
|
|
@ -66,6 +66,8 @@ tokens :-
|
|||
"end" { tok KW_end }
|
||||
"endcase" { tok KW_endcase }
|
||||
"endmodule" { tok KW_endmodule }
|
||||
"endfunction" { tok KW_endfunction}
|
||||
"function" { tok KW_function }
|
||||
"for" { tok KW_for }
|
||||
"if" { tok KW_if }
|
||||
"initial" { tok KW_initial }
|
||||
|
|
|
|||
|
|
@ -27,7 +27,9 @@ import Language.SystemVerilog.Parser.Tokens
|
|||
"else" { Token KW_else _ _ }
|
||||
"end" { Token KW_end _ _ }
|
||||
"endcase" { Token KW_endcase _ _ }
|
||||
"endfunction" { Token KW_endfunction _ _ }
|
||||
"endmodule" { Token KW_endmodule _ _ }
|
||||
"function" { Token KW_function _ _ }
|
||||
"for" { Token KW_for _ _ }
|
||||
"if" { Token KW_if _ _ }
|
||||
"initial" { Token KW_initial _ _ }
|
||||
|
|
@ -172,7 +174,7 @@ ParamDecls :: { [ModuleItem] }
|
|||
: ParamDecl(")") { $1 }
|
||||
| ParamDecl(",") ParamDecls { $1 ++ $2 }
|
||||
ParamDecl(delim) :: { [ModuleItem] }
|
||||
: "parameter" opt(Range) DeclAsgns delim { map (uncurry $ Parameter $2) $3 }
|
||||
: "parameter" opt(Range) DeclAsgns delim { map (MIParameter . (uncurry $ Parameter $2)) $3 }
|
||||
|
||||
Identifier :: { Identifier }
|
||||
: simpleIdentifier { tokenString $1 }
|
||||
|
|
@ -213,15 +215,45 @@ ModuleItems :: { [ModuleItem] }
|
|||
| ModuleItems ModuleItem { $1 ++ $2 }
|
||||
|
||||
ModuleItem :: { [ModuleItem] }
|
||||
: "parameter" opt(Range) DeclAsgns ";" { map (uncurry $ Parameter $2) $3 }
|
||||
| "localparam" opt(Range) DeclAsgns ";" { map (uncurry $ Localparam $2) $3 }
|
||||
| PortDecl(";") { $1 }
|
||||
: PortDecl(";") { $1 }
|
||||
| "reg" opt(Range) VariableIdentifiers ";" { map (uncurry $ LocalNet $ Reg $2) $3 }
|
||||
| "wire" opt(Range) VariableIdentifiers ";" { map (uncurry $ LocalNet $ Wire $2) $3 }
|
||||
| "integer" VariableIdentifiers ";" { map (uncurry Integer) $2 }
|
||||
| ParameterDeclaration { map MIParameter $1 }
|
||||
| LocalparamDeclaration { map MILocalparam $1 }
|
||||
| IntegerDeclaration { map MIIntegerV $1 }
|
||||
| "assign" LHS "=" Expr ";" { [Assign $2 $4] }
|
||||
| "always" opt(EventControl) Stmt { [Always $2 $3] }
|
||||
| Identifier ParameterBindings Identifier Bindings ";" { [Instance $1 $2 $3 $4] }
|
||||
| "function" opt(RangeOrType) Identifier FunctionItems Stmt "endfunction" { [Function $2 $3 $4 $5] }
|
||||
|
||||
FunctionItems :: { [(Bool, BlockItemDeclaration)] }
|
||||
: "(" FunctionPortList ";" BlockItemDeclarations { (map ((,) True) $2) ++ (map ((,) False) $4) }
|
||||
| ";" FunctionItemDeclarations { $2 }
|
||||
FunctionPortList :: { [BlockItemDeclaration] }
|
||||
: FunctionInputDeclaration(")") { $1 }
|
||||
| FunctionInputDeclaration(",") FunctionPortList { $1 ++ $2 }
|
||||
FunctionItemDeclarations :: { [(Bool, BlockItemDeclaration)] }
|
||||
: FunctionItemDeclaration { $1 }
|
||||
| FunctionItemDeclarations FunctionItemDeclaration { $1 ++ $2 }
|
||||
FunctionItemDeclaration :: { [(Bool, BlockItemDeclaration)] }
|
||||
: BlockItemDeclaration { map ((,) False) $1 }
|
||||
| FunctionInputDeclaration(";") { map ((,) True ) $1 }
|
||||
FunctionInputDeclaration(delim) :: { [BlockItemDeclaration] }
|
||||
: "input" opt("reg") opt(Range) Identifiers delim { map (\x -> BIDReg $3 x []) $4 }
|
||||
| "input" "integer" Identifiers delim { map (\x -> BIDIntegerV $ IntegerV x $ Left []) $3 }
|
||||
|
||||
ParameterDeclaration :: { [Parameter] }
|
||||
: "parameter" opt(Range) DeclAsgns ";" { map (uncurry $ Parameter $2) $3 }
|
||||
|
||||
LocalparamDeclaration :: { [Localparam] }
|
||||
: "localparam" opt(Range) DeclAsgns ";" { map (uncurry $ Localparam $2) $3 }
|
||||
|
||||
IntegerDeclaration :: { [IntegerV] }
|
||||
: "integer" VariableIdentifiers ";" { map (uncurry IntegerV) $2 }
|
||||
|
||||
RangeOrType :: { Either Range () }
|
||||
: Range { Left $1 }
|
||||
| "integer" { Right () }
|
||||
|
||||
EventControl :: { Sense }
|
||||
: "@" "(" Sense ")" { $3 }
|
||||
|
|
@ -291,22 +323,30 @@ Stmts :: { [Stmt] }
|
|||
|
||||
Stmt :: { Stmt }
|
||||
: ";" { Null }
|
||||
| "begin" Stmts "end" { Block Nothing $2 }
|
||||
| "begin" ":" Identifier Stmts "end" { Block (Just $3) $4 }
|
||||
| "reg" opt(Range) BlockRegIdentifiers ";" { stmtsToStmt $ map (uncurry $ StmtReg $2) $3 }
|
||||
| "integer" VariableIdentifiers ";" { stmtsToStmt $ map (uncurry StmtInteger) $2 }
|
||||
| "begin" Stmts "end" { Block Nothing $2 }
|
||||
| "begin" ":" Identifier Stmts "end" { Block (Just ($3, [])) $4 }
|
||||
| "begin" ":" Identifier BlockItemDeclarations Stmts "end" { Block (Just ($3, $4)) $5 }
|
||||
| "if" "(" Expr ")" Stmt "else" Stmt { If $3 $5 $7 }
|
||||
| "if" "(" Expr ")" Stmt %prec NoElse { If $3 $5 Null }
|
||||
| "for" "(" Identifier "=" Expr ";" Expr ";" Identifier "=" Expr ")" Stmt { For ($3, $5) $7 ($9, $11) $13 }
|
||||
| LHS "=" Expr ";" { BlockingAssignment $1 $3 }
|
||||
| LHS "<=" Expr ";" { NonBlockingAssignment $1 $3 }
|
||||
| Call ";" { StmtCall $1 }
|
||||
-- | Call ";" { StmtCall $1 }
|
||||
| "case" "(" Expr ")" Cases CaseDefault "endcase" { Case $3 $5 $6 }
|
||||
|
||||
BlockRegIdentifiers :: { [(Identifier, [Range])] }
|
||||
: BlockRegIdentifier { [$1] }
|
||||
| BlockRegIdentifiers "," BlockRegIdentifier { $1 ++ [$3] }
|
||||
BlockRegIdentifier :: { (Identifier, [Range]) }
|
||||
BlockItemDeclarations :: { [BlockItemDeclaration] }
|
||||
: BlockItemDeclaration { $1 }
|
||||
| BlockItemDeclarations BlockItemDeclaration { $1 ++ $2 }
|
||||
|
||||
BlockItemDeclaration :: { [BlockItemDeclaration] }
|
||||
: "reg" opt(Range) BlockVariableIdentifiers { map (uncurry $ BIDReg $2) $3 }
|
||||
| ParameterDeclaration { map BIDParameter $1 }
|
||||
| LocalparamDeclaration { map BIDLocalparam $1 }
|
||||
| IntegerDeclaration { map BIDIntegerV $1 }
|
||||
BlockVariableIdentifiers :: { [(Identifier, [Range])] }
|
||||
: BlockVariableType { [$1] }
|
||||
| BlockVariableIdentifiers "," BlockVariableType { $1 ++ [$3] }
|
||||
BlockVariableType :: { (Identifier, [Range]) }
|
||||
: Identifier { ($1, []) }
|
||||
| Identifier Dimensions { ($1, $2) }
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue