Commit 57630b77 by Zachary Snow

preliminary support for functions

parent 6c88994e
......@@ -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
......@@ -307,9 +335,7 @@ 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 (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 }
......@@ -292,21 +324,29 @@ 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" ":" 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) }
......
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