Commit 460c0ee4 by Zachary Snow

broader operator support; other parser cleanup

parent 4394dc17
......@@ -13,10 +13,11 @@ import qualified Convert.AlwaysKW
import qualified Convert.CaseKW
import qualified Convert.Enum
import qualified Convert.Logic
import qualified Convert.Typedef
import qualified Convert.PackedArray
import qualified Convert.SplitPortDecl
import qualified Convert.StarPort
import qualified Convert.Typedef
import qualified Convert.Unique
type Phase = AST -> AST
......@@ -26,6 +27,7 @@ phases YOSYS =
, Convert.PackedArray.convert
, Convert.StarPort.convert
, Convert.Typedef.convert
, Convert.Unique.convert
]
phases VTR =
(phases YOSYS) ++
......
......@@ -46,8 +46,8 @@ expandExpr _ other = error $ "CaseKW conversion encountered case that was not a
-- Note that we don't have to convert the statements within the cases, as the
-- conversion template takes care of that for us.
convertStmt :: Stmt -> Stmt
convertStmt (Case kw expr cases def) =
Case CaseN expr cases' def
convertStmt (Case u kw expr cases def) =
Case u CaseN expr cases' def
where
wilds = wildcards kw
cases' = map convertCase cases
......
......@@ -158,7 +158,7 @@ unflattener writeToFlatVariant arr (t, (majorHi, majorLo)) =
, GenFor
(index, majorLo)
(BinOp Le (Ident index) majorHi)
(index, BinOp Add (Ident index) (Number "1"))
(index, AsgnOp Add, Number "1")
(prefix "unflatten")
[ localparam startBit
(simplify $ BinOp Add majorLo
......
......@@ -123,11 +123,11 @@ traverseNestedStmtsM mapper = fullMapper
where
fullMapper stmt = mapper stmt >>= cs
cs (Block decls stmts) = mapM fullMapper stmts >>= return . Block decls
cs (Case kw expr cases def) = do
cs (Case u kw expr cases def) = do
caseStmts <- mapM fullMapper $ map snd cases
let cases' = zip (map fst cases) caseStmts
def' <- maybeDo fullMapper def
return $ Case kw expr cases' def'
return $ Case u kw expr cases' def'
cs (AsgnBlk lhs expr) = return $ AsgnBlk lhs expr
cs (Asgn lhs expr) = return $ Asgn lhs expr
cs (For a b c stmt) = fullMapper stmt >>= return . For a b c
......@@ -233,10 +233,10 @@ traverseExprsM mapper = moduleItemMapper
let Just (name, decls) = header
decls' <- mapM declMapper decls
return $ Block (Just (name, decls')) stmts
flatStmtMapper (Case kw e cases def) = do
flatStmtMapper (Case u kw e cases def) = do
e' <- exprMapper e
cases' <- mapM caseMapper cases
return $ Case kw e' cases' def
return $ Case u kw e' cases' def
flatStmtMapper (AsgnBlk lhs expr) =
exprMapper expr >>= return . AsgnBlk lhs
flatStmtMapper (Asgn lhs expr) =
......
{- sv2v
- Author: Zachary Snow <zach@zachjs.com>
-
- Conversion for `unique`
-
- This conversion simply drops the `unique` keyword, as it is only used for
- optimization. There is no way to force toolchains which don't support the
- keyword to perform such optimization.
-}
module Convert.Unique (convert) where
import Convert.Traverse
import Language.SystemVerilog.AST
convert :: AST -> AST
convert = traverseDescriptions $ traverseModuleItems $ traverseStmts convertStmt
convertStmt :: Stmt -> Stmt
convertStmt (Case True kw expr cases def) =
Case False kw expr cases def
convertStmt other = other
......@@ -10,6 +10,7 @@ module Language.SystemVerilog.AST
, Expr (..)
, UniOp (..)
, BinOp (..)
, AsgnOp (..)
, Sense (..)
, GenItem (..)
, AlwaysKW (..)
......@@ -297,8 +298,13 @@ data BinOp
| Le
| Gt
| Ge
| Pow
| ShiftAL
| ShiftAR
| TEq
| TNe
| WEq
| WNe
deriving (Eq, Ord)
instance Show BinOp where
......@@ -321,8 +327,13 @@ instance Show BinOp where
Le -> "<="
Gt -> ">"
Ge -> ">="
Pow -> "**"
ShiftAL -> "<<<"
ShiftAR -> ">>>"
TEq -> "==="
TNe -> "!=="
WEq -> "==?"
WNe -> "!=?"
instance Show Expr where
show x = case x of
......@@ -348,6 +359,15 @@ instance Show Expr where
showPatternItem (Nothing, e) = show e
showPatternItem (Just n , e) = printf "%s: %s" n (show e)
data AsgnOp
= AsgnOpEq
| AsgnOp BinOp
deriving Eq
instance Show AsgnOp where
show AsgnOpEq = "="
show (AsgnOp op) = (show op) ++ "="
data LHS
= LHSIdent Identifier
| LHSBit LHS Expr
......@@ -376,7 +396,7 @@ instance Show CaseKW where
data Stmt
= Block (Maybe (Identifier, [Decl])) [Stmt]
| Case CaseKW Expr [Case] (Maybe Stmt)
| Case Bool CaseKW Expr [Case] (Maybe Stmt)
| For (Identifier, Expr) Expr (Identifier, Expr) Stmt
| AsgnBlk LHS Expr
| Asgn LHS Expr
......@@ -398,12 +418,13 @@ instance Show Stmt where
extra = case header of
Nothing -> ""
Just (x, i) -> printf " : %s\n%s" x (block i)
show (Case kw e cs def) =
printf "%s (%s)\n%s%s\nendcase" (show kw) (show e) (indent $ unlines' $ map showCase cs) defStr
show (Case u kw e cs def) =
printf "%s%s (%s)\n%s%s\nendcase" uniqStr (show kw) (show e) (indent $ unlines' $ map showCase cs) defStr
where
defStr = case def of
Nothing -> ""
Just c -> printf "\n\tdefault: %s" (show c)
uniqStr = if u then "unique " else ""
defStr = case def of
Nothing -> ""
Just c -> printf "\n\tdefault: %s" (show c)
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 (AsgnBlk v e) = printf "%s = %s;" (show v) (show e)
show (Asgn v e) = printf "%s <= %s;" (show v) (show e)
......@@ -450,7 +471,7 @@ type GenCase = ([Expr], GenItem)
data GenItem
= GenBlock (Maybe Identifier) [GenItem]
| GenCase Expr [GenCase] (Maybe GenItem)
| GenFor (Identifier, Expr) Expr (Identifier, Expr) Identifier [GenItem]
| GenFor (Identifier, Expr) Expr (Identifier, AsgnOp, Expr) Identifier [GenItem]
| GenIf Expr GenItem GenItem
| GenNull
| GenModuleItem ModuleItem
......@@ -464,7 +485,7 @@ instance Show GenItem where
show (GenCase e c (Just d)) = printf "case (%s)\n%s\n\tdefault:\n%s\nendcase" (show e) (indent $ unlines' $ map showCase c) (indent $ indent $ show d)
show (GenIf e a GenNull) = printf "if (%s) %s" (show e) (show a)
show (GenIf e a b ) = printf "if (%s) %s\nelse %s" (show e) (show a) (show b)
show (GenFor (x1, e1) c (x2, e2) x is) = printf "for (%s = %s; %s; %s = %s) %s" x1 (show e1) (show c) x2 (show e2) (show $ GenBlock (Just x) is)
show (GenFor (x1, e1) c (x2, o2, e2) x is) = printf "for (%s = %s; %s; %s %s %s) %s" x1 (show e1) (show c) x2 (show o2) (show e2) (show $ GenBlock (Just x) is)
show GenNull = ";"
show (GenModuleItem item) = show item
......
......@@ -56,48 +56,48 @@ tokens :-
"always_comb" { tok KW_always_comb }
"always_ff" { tok KW_always_ff }
"always_latch" { tok KW_always_latch }
"assign" { tok KW_assign }
"automatic" { tok KW_automatic }
"begin" { tok KW_begin }
"case" { tok KW_case }
"casex" { tok KW_casex }
"casez" { tok KW_casez }
"default" { tok KW_default }
"else" { tok KW_else }
"end" { tok KW_end }
"endcase" { tok KW_endcase }
"endmodule" { tok KW_endmodule }
"endfunction" { tok KW_endfunction}
"endgenerate" { tok KW_endgenerate}
"endinterface" { tok KW_endinterface}
"enum" { tok KW_enum }
"function" { tok KW_function }
"for" { tok KW_for }
"generate" { tok KW_generate }
"genvar" { tok KW_genvar }
"if" { tok KW_if }
"initial" { tok KW_initial }
"inout" { tok KW_inout }
"input" { tok KW_input }
"interface" { tok KW_interface }
"integer" { tok KW_integer }
"localparam" { tok KW_localparam }
"logic" { tok KW_logic }
"module" { tok KW_module }
"modport" { tok KW_modport }
"negedge" { tok KW_negedge }
"or" { tok KW_or }
"output" { tok KW_output }
"packed" { tok KW_packed }
"parameter" { tok KW_parameter }
"posedge" { tok KW_posedge }
"reg" { tok KW_reg }
"return" { tok KW_return }
"static" { tok KW_static }
"struct" { tok KW_struct }
"typedef" { tok KW_typedef }
"unique" { tok KW_unique }
"wire" { tok KW_wire }
"assign" { tok KW_assign }
"automatic" { tok KW_automatic }
"begin" { tok KW_begin }
"case" { tok KW_case }
"casex" { tok KW_casex }
"casez" { tok KW_casez }
"default" { tok KW_default }
"else" { tok KW_else }
"end" { tok KW_end }
"endcase" { tok KW_endcase }
"endmodule" { tok KW_endmodule }
"endfunction" { tok KW_endfunction }
"endgenerate" { tok KW_endgenerate }
"endinterface" { tok KW_endinterface }
"enum" { tok KW_enum }
"function" { tok KW_function }
"for" { tok KW_for }
"generate" { tok KW_generate }
"genvar" { tok KW_genvar }
"if" { tok KW_if }
"initial" { tok KW_initial }
"inout" { tok KW_inout }
"input" { tok KW_input }
"interface" { tok KW_interface }
"integer" { tok KW_integer }
"localparam" { tok KW_localparam }
"logic" { tok KW_logic }
"module" { tok KW_module }
"modport" { tok KW_modport }
"negedge" { tok KW_negedge }
"or" { tok KW_or }
"output" { tok KW_output }
"packed" { tok KW_packed }
"parameter" { tok KW_parameter }
"posedge" { tok KW_posedge }
"reg" { tok KW_reg }
"return" { tok KW_return }
"static" { tok KW_static }
"struct" { tok KW_struct }
"typedef" { tok KW_typedef }
"unique" { tok KW_unique }
"wire" { tok KW_wire }
@simpleIdentifier { tok Id_simple }
@escapedIdentifier { tok Id_escaped }
......@@ -176,8 +176,8 @@ tokens :-
"===" { tok Sym_eq_eq_eq }
"!==" { tok Sym_bang_eq_eq }
"=?=" { tok Sym_eq_question_eq }
"!?=" { tok Sym_bang_question_eq }
"==?" { tok Sym_eq_eq_question }
"!=?" { tok Sym_bang_eq_question }
">>>" { tok Sym_gt_gt_gt }
"<<<" { tok Sym_lt_lt_lt }
"<<=" { tok Sym_lt_lt_eq }
......
......@@ -21,54 +21,54 @@ import Language.SystemVerilog.Parser.Tokens
"always_comb" { Token KW_always_comb _ _ }
"always_ff" { Token KW_always_ff _ _ }
"always_latch" { Token KW_always_latch _ _ }
"assign" { Token KW_assign _ _ }
"automatic" { Token KW_automatic _ _ }
"begin" { Token KW_begin _ _ }
"case" { Token KW_case _ _ }
"casex" { Token KW_casex _ _ }
"casez" { Token KW_casez _ _ }
"default" { Token KW_default _ _ }
"else" { Token KW_else _ _ }
"end" { Token KW_end _ _ }
"endcase" { Token KW_endcase _ _ }
"endfunction" { Token KW_endfunction _ _ }
"endgenerate" { Token KW_endgenerate _ _ }
"assign" { Token KW_assign _ _ }
"automatic" { Token KW_automatic _ _ }
"begin" { Token KW_begin _ _ }
"case" { Token KW_case _ _ }
"casex" { Token KW_casex _ _ }
"casez" { Token KW_casez _ _ }
"default" { Token KW_default _ _ }
"else" { Token KW_else _ _ }
"end" { Token KW_end _ _ }
"endcase" { Token KW_endcase _ _ }
"endfunction" { Token KW_endfunction _ _ }
"endgenerate" { Token KW_endgenerate _ _ }
"endinterface" { Token KW_endinterface _ _ }
"endmodule" { Token KW_endmodule _ _ }
"enum" { Token KW_enum _ _ }
"function" { Token KW_function _ _ }
"for" { Token KW_for _ _ }
"generate" { Token KW_generate _ _ }
"genvar" { Token KW_genvar _ _ }
"if" { Token KW_if _ _ }
"initial" { Token KW_initial _ _ }
"inout" { Token KW_inout _ _ }
"input" { Token KW_input _ _ }
"integer" { Token KW_integer _ _ }
"interface" { Token KW_interface _ _ }
"localparam" { Token KW_localparam _ _ }
"logic" { Token KW_logic _ _ }
"module" { Token KW_module _ _ }
"modport" { Token KW_modport _ _ }
"negedge" { Token KW_negedge _ _ }
"or" { Token KW_or _ _ }
"output" { Token KW_output _ _ }
"packed" { Token KW_packed _ _ }
"parameter" { Token KW_parameter _ _ }
"posedge" { Token KW_posedge _ _ }
"reg" { Token KW_reg _ _ }
"return" { Token KW_return _ _ }
"static" { Token KW_static _ _ }
"struct" { Token KW_struct _ _ }
"typedef" { Token KW_typedef _ _ }
"unique" { Token KW_unique _ _ }
"wire" { Token KW_wire _ _ }
simpleIdentifier { Token Id_simple _ _ }
escapedIdentifier { Token Id_escaped _ _ }
systemIdentifier { Token Id_system _ _ }
number { Token Lit_number _ _ }
string { Token Lit_string _ _ }
"endmodule" { Token KW_endmodule _ _ }
"enum" { Token KW_enum _ _ }
"function" { Token KW_function _ _ }
"for" { Token KW_for _ _ }
"generate" { Token KW_generate _ _ }
"genvar" { Token KW_genvar _ _ }
"if" { Token KW_if _ _ }
"initial" { Token KW_initial _ _ }
"inout" { Token KW_inout _ _ }
"input" { Token KW_input _ _ }
"integer" { Token KW_integer _ _ }
"interface" { Token KW_interface _ _ }
"localparam" { Token KW_localparam _ _ }
"logic" { Token KW_logic _ _ }
"module" { Token KW_module _ _ }
"modport" { Token KW_modport _ _ }
"negedge" { Token KW_negedge _ _ }
"or" { Token KW_or _ _ }
"output" { Token KW_output _ _ }
"packed" { Token KW_packed _ _ }
"parameter" { Token KW_parameter _ _ }
"posedge" { Token KW_posedge _ _ }
"reg" { Token KW_reg _ _ }
"return" { Token KW_return _ _ }
"static" { Token KW_static _ _ }
"struct" { Token KW_struct _ _ }
"typedef" { Token KW_typedef _ _ }
"unique" { Token KW_unique _ _ }
"wire" { Token KW_wire _ _ }
simpleIdentifier { Token Id_simple _ _ }
escapedIdentifier { Token Id_escaped _ _ }
systemIdentifier { Token Id_system _ _ }
number { Token Lit_number _ _ }
string { Token Lit_string _ _ }
"(" { Token Sym_paren_l _ _ }
")" { Token Sym_paren_r _ _ }
......@@ -138,8 +138,8 @@ string { Token Lit_string _ _ }
"*>" { Token Sym_aster_gt _ _ }
"===" { Token Sym_eq_eq_eq _ _ }
"!==" { Token Sym_bang_eq_eq _ _ }
"=?=" { Token Sym_eq_question_eq _ _ }
"!?=" { Token Sym_bang_question_eq _ _ }
"==?" { Token Sym_eq_eq_question _ _ }
"!=?" { Token Sym_bang_eq_question _ _ }
">>>" { Token Sym_gt_gt_gt _ _ }
"<<<" { Token Sym_lt_lt_lt _ _ }
"<<=" { Token Sym_lt_lt_eq _ _ }
......@@ -154,6 +154,7 @@ string { Token Lit_string _ _ }
"<<<=" { Token Sym_lt_lt_lt_eq _ _ }
">>>=" { Token Sym_gt_gt_gt_eq _ _ }
-- operator precedences, from *lowest* to *highest*
%nonassoc NoElse
%nonassoc "else"
%right "?" ":"
......@@ -162,12 +163,13 @@ string { Token Lit_string _ _ }
%left "|" "~|"
%left "^" "^~"
%left "&" "~&"
%left "==" "!=" "===" "!=="
%left "==" "!=" "===" "!==" "==?" "!=?"
%left "<" "<=" ">" ">="
%left "<<" ">>" "<<<" ">>>"
%left "+" "-"
%left "*" "/" "%"
%left UPlus UMinus "!" "~" RedOps
%left "**"
%right UPlus UMinus "!" "~" RedOps "++" "--"
%left "(" ")" "[" "]" "."
......@@ -280,7 +282,6 @@ DeclToken :: { DeclToken }
| Identifier "." Identifier { DTType $ InterfaceT $1 (Just $3) }
| "[" Expr "]" { DTBit $2 }
| "{" LHSs "}" { DTConcat $2 }
-- | LHS "." Identifier { LHSDot $1 $3 }
VariablePortIdentifiers :: { [(Identifier, Maybe Expr)] }
: VariablePortIdentifier { [$1] }
......@@ -409,7 +410,7 @@ StmtNonAsgn :: { Stmt }
| "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 }
| CaseKW "(" Expr ")" Cases opt(CaseDefault) "endcase" { Case $1 $3 $5 $6 }
| Unique CaseKW "(" Expr ")" Cases opt(CaseDefault) "endcase" { Case $1 $2 $4 $6 $7 }
| EventControl Stmt { Timing $1 $2 }
| "return" Expr ";" { Return $2 }
......@@ -422,12 +423,14 @@ DeclOrStmt :: { ([Decl], [Stmt]) }
| "parameter" ParamType DeclAsgns ";" { (map (uncurry $ Parameter $2) $3, []) }
| "localparam" ParamType DeclAsgns ";" { (map (uncurry $ Localparam $2) $3, []) }
Unique :: { Bool }
: "unique" { True }
| {- empty -} { False }
CaseKW :: { CaseKW }
-- We just drop the unique keyword, for now. In the future, we should add it
-- to the AST and add a conversion phase for removing it.
: opt("unique") "case" { CaseN }
| opt("unique") "casex" { CaseX }
| opt("unique") "casez" { CaseZ }
: "case" { CaseN }
| "casex" { CaseX }
| "casez" { CaseZ }
Cases :: { [Case] }
: {- empty -} { [] }
......@@ -482,8 +485,13 @@ Expr :: { Expr }
| Expr "*" Expr { BinOp Mul $1 $3 }
| Expr "/" Expr { BinOp Div $1 $3 }
| Expr "%" Expr { BinOp Mod $1 $3 }
| Expr "**" Expr { BinOp Pow $1 $3 }
| Expr "<<<" Expr { BinOp ShiftAL $1 $3 }
| Expr ">>>" Expr { BinOp ShiftAR $1 $3 }
| Expr "===" Expr { BinOp TEq $1 $3 }
| Expr "!==" Expr { BinOp TNe $1 $3 }
| Expr "==?" Expr { BinOp WEq $1 $3 }
| Expr "!=?" Expr { BinOp WNe $1 $3 }
| "!" Expr { UniOp Not $2 }
| "~" Expr { UniOp BWNot $2 }
| "+" Expr %prec UPlus { UniOp UAdd $2 }
......@@ -525,7 +533,7 @@ GenItem :: { GenItem }
| "begin" GenItems "end" { GenBlock Nothing $2 }
| "begin" ":" Identifier GenItems "end" { GenBlock (Just $3) $4 }
| "case" "(" Expr ")" GenCases opt(GenCaseDefault) "endcase" { GenCase $3 $5 $6 }
| "for" "(" Identifier "=" Expr ";" Expr ";" Identifier "=" Expr ")" "begin" ":" Identifier GenItems "end" { GenFor ($3, $5) $7 ($9, $11) $15 $16 }
| "for" "(" Identifier "=" Expr ";" Expr ";" GenvarIteration ")" "begin" ":" Identifier GenItems "end" { GenFor ($3, $5) $7 $9 $13 $14 }
-- TODO: We should restrict it to the module items that are actually allowed.
| ModuleItem { genItemsToGenItem $ map GenModuleItem $1 }
......@@ -539,6 +547,29 @@ GenCase :: { GenCase }
GenCaseDefault :: { GenItem }
: "default" opt(":") GenItemOrNull { $3 }
GenvarIteration :: { (Identifier, AsgnOp, Expr) }
: Identifier AssignmentOperator Expr { ($1, $2, $3) }
| IncOrDecOperator Identifier { ($2, AsgnOp $1, Number "1") }
| Identifier IncOrDecOperator { ($1, AsgnOp $2, Number "1") }
AssignmentOperator :: { AsgnOp }
: "=" { AsgnOpEq }
| "+=" { AsgnOp Add }
| "-=" { AsgnOp Sub }
| "*=" { AsgnOp Mul }
| "/=" { AsgnOp Div }
| "%=" { AsgnOp Mod }
| "&=" { AsgnOp BWAnd }
| "|=" { AsgnOp BWOr }
| "^=" { AsgnOp BWXor }
| "<<=" { AsgnOp ShiftL }
| ">>=" { AsgnOp ShiftR }
| "<<<=" { AsgnOp ShiftAL }
| ">>>=" { AsgnOp ShiftAR }
IncOrDecOperator :: { BinOp }
: "++" { Add }
| "--" { Sub }
{
......
......@@ -318,8 +318,8 @@ data TokenName
| Sym_aster_gt
| Sym_eq_eq_eq
| Sym_bang_eq_eq
| Sym_eq_question_eq
| Sym_bang_question_eq
| Sym_eq_eq_question
| Sym_bang_eq_question
| Sym_gt_gt_gt
| Sym_lt_lt_lt
| Sym_lt_lt_eq
......
......@@ -49,6 +49,7 @@ executable sv2v
Convert.StarPort
Convert.Typedef
Convert.Traverse
Convert.Unique
-- sv2v CLI modules
Job
ghc-options:
......
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