diff --git a/src/Convert/Traverse.hs b/src/Convert/Traverse.hs index 5931cbe..58f640f 100644 --- a/src/Convert/Traverse.hs +++ b/src/Convert/Traverse.hs @@ -317,6 +317,11 @@ traverseExprsM mapper = moduleItemMapper return $ Instance m params x l' moduleItemMapper (Modport x l) = mapM modportDeclMapper l >>= return . Modport x + moduleItemMapper (NInputGate kw x lhs exprs) = do + exprs' <- mapM exprMapper exprs + return $ NInputGate kw x lhs exprs' + moduleItemMapper (NOutputGate kw x lhss expr) = + exprMapper expr >>= return . NOutputGate kw x lhss moduleItemMapper (Genvar x) = return $ Genvar x moduleItemMapper (Generate x) = return $ Generate x moduleItemMapper (MIPackageItem (Typedef t x)) = @@ -344,6 +349,12 @@ traverseLHSsM mapper item = traverseModuleItemLHSsM (Defparam lhs expr) = do lhs' <- mapper lhs return $ Defparam lhs' expr + traverseModuleItemLHSsM (NOutputGate kw x lhss expr) = do + lhss' <- mapM mapper lhss + return $ NOutputGate kw x lhss' expr + traverseModuleItemLHSsM (NInputGate kw x lhs exprs) = do + lhs' <- mapper lhs + return $ NInputGate kw x lhs' exprs traverseModuleItemLHSsM other = return other traverseLHSs :: Mapper LHS -> Mapper ModuleItem diff --git a/src/Language/SystemVerilog/AST.hs b/src/Language/SystemVerilog/AST.hs index 011c31c..224008d 100644 --- a/src/Language/SystemVerilog/AST.hs +++ b/src/Language/SystemVerilog/AST.hs @@ -20,6 +20,8 @@ module Language.SystemVerilog.AST , PartKW (..) , Decl (..) , Lifetime (..) + , NInputGateKW (..) + , NOutputGateKW (..) , AST , PortBinding , ModportDecl @@ -186,6 +188,8 @@ data ModuleItem | Modport Identifier [ModportDecl] | Initial Stmt | MIPackageItem PackageItem + | NInputGate NInputGateKW (Maybe Identifier) LHS [Expr] + | NOutputGate NOutputGateKW (Maybe Identifier) [LHS] Expr deriving Eq data AlwaysKW @@ -218,6 +222,8 @@ instance Show ModuleItem where Modport x l -> printf "modport %s(\n%s\n);" x (indent $ intercalate ",\n" $ map showModportDecl l) Initial s -> printf "initial %s" (show s) MIPackageItem i -> show i + NInputGate kw x lhs exprs -> printf "%s%s (%s, %s);" (show kw) (maybe "" (" " ++) x) (show lhs) (commas $ map show exprs) + NOutputGate kw x lhss expr -> printf "%s%s (%s, %s);" (show kw) (maybe "" (" " ++) x) (commas $ map show lhss) (show expr) where showPorts :: [PortBinding] -> String showPorts ports = indentedParenList $ map showPort ports @@ -233,6 +239,30 @@ instance Show ModuleItem where then printf "%s %s" (show dir) ident else printf "%s .%s(%s)" (show dir) ident (maybe "" show me) +data NInputGateKW + = GateAnd + | GateNand + | GateOr + | GateNor + | GateXor + | GateXnor + deriving Eq +data NOutputGateKW + = GateBuf + | GateNot + deriving Eq + +instance Show NInputGateKW where + show GateAnd = "and" + show GateNand = "nand" + show GateOr = "or" + show GateNor = "nor" + show GateXor = "xor" + show GateXnor = "xnor" +instance Show NOutputGateKW where + show GateBuf = "buf" + show GateNot = "not" + showAssignment :: Maybe Expr -> String showAssignment Nothing = "" showAssignment (Just val) = " = " ++ show val diff --git a/src/Language/SystemVerilog/Parser/Lex.x b/src/Language/SystemVerilog/Parser/Lex.x index 733f2dc..08c7d5d 100644 --- a/src/Language/SystemVerilog/Parser/Lex.x +++ b/src/Language/SystemVerilog/Parser/Lex.x @@ -78,9 +78,11 @@ tokens :- "always_comb" { tok KW_always_comb } "always_ff" { tok KW_always_ff } "always_latch" { tok KW_always_latch } + "and" { tok KW_and } "assign" { tok KW_assign } "automatic" { tok KW_automatic } "begin" { tok KW_begin } + "buf" { tok KW_buf } "case" { tok KW_case } "casex" { tok KW_casex } "casez" { tok KW_casez } @@ -111,7 +113,10 @@ tokens :- "logic" { tok KW_logic } "modport" { tok KW_modport } "module" { tok KW_module } + "nand" { tok KW_nand } "negedge" { tok KW_negedge } + "nor" { tok KW_nor } + "not" { tok KW_not } "or" { tok KW_or } "output" { tok KW_output } "packed" { tok KW_packed } @@ -127,6 +132,8 @@ tokens :- "unique" { tok KW_unique } "while" { tok KW_while } "wire" { tok KW_wire } + "xnor" { tok KW_xnor } + "xor" { tok KW_xor } @simpleIdentifier { tok Id_simple } @escapedIdentifier { tok Id_escaped } diff --git a/src/Language/SystemVerilog/Parser/Parse.y b/src/Language/SystemVerilog/Parser/Parse.y index 6873258..ae500bd 100644 --- a/src/Language/SystemVerilog/Parser/Parse.y +++ b/src/Language/SystemVerilog/Parser/Parse.y @@ -21,9 +21,11 @@ import Language.SystemVerilog.Parser.Tokens "always_comb" { Token KW_always_comb _ _ } "always_ff" { Token KW_always_ff _ _ } "always_latch" { Token KW_always_latch _ _ } +"and" { Token KW_and _ _ } "assign" { Token KW_assign _ _ } "automatic" { Token KW_automatic _ _ } "begin" { Token KW_begin _ _ } +"buf" { Token KW_buf _ _ } "case" { Token KW_case _ _ } "casex" { Token KW_casex _ _ } "casez" { Token KW_casez _ _ } @@ -54,7 +56,10 @@ import Language.SystemVerilog.Parser.Tokens "logic" { Token KW_logic _ _ } "modport" { Token KW_modport _ _ } "module" { Token KW_module _ _ } +"nand" { Token KW_nand _ _ } "negedge" { Token KW_negedge _ _ } +"nor" { Token KW_nor _ _ } +"not" { Token KW_not _ _ } "or" { Token KW_or _ _ } "output" { Token KW_output _ _ } "packed" { Token KW_packed _ _ } @@ -70,6 +75,8 @@ import Language.SystemVerilog.Parser.Tokens "unique" { Token KW_unique _ _ } "while" { Token KW_while _ _ } "wire" { Token KW_wire _ _ } +"xnor" { Token KW_xnor _ _ } +"xor" { Token KW_xor _ _ } simpleIdentifier { Token Id_simple _ _ } escapedIdentifier { Token Id_escaped _ _ } @@ -331,6 +338,34 @@ ModuleItem :: { [ModuleItem] } | "generate" GenItems "endgenerate" { [Generate $2] } | "modport" ModportItems ";" { map (uncurry Modport) $2 } | PackageItem { [MIPackageItem $1] } + | NInputGateKW NInputGates ";" { map (\(a, b, c) -> NInputGate $1 a b c) $2 } + | NOutputGateKW NOutputGates ";" { map (\(a, b, c) -> NOutputGate $1 a b c) $2 } + +NInputGates :: { [(Maybe Identifier, LHS, [Expr])] } + : NInputGate { [$1] } + | NInputGates "," NInputGate { $1 ++ [$3]} +NOutputGates :: { [(Maybe Identifier, [LHS], Expr)] } + : NOutputGate { [$1] } + | NOutputGates "," NOutputGate { $1 ++ [$3]} + +NInputGate :: { (Maybe Identifier, LHS, [Expr]) } + : opt(Identifier) "(" LHS "," Exprs ")" { ($1, $3, $5) } +NOutputGate :: { (Maybe Identifier, [LHS], Expr) } + : opt(Identifier) "(" NOutputGateItems { ($1, fst $3, snd $3) } +NOutputGateItems :: { ([LHS], Expr) } + : Expr ")" { ([], $1) } + | Expr "," NOutputGateItems { (fst $3 ++ [exprToLHS $1], snd $3) } + +NInputGateKW :: { NInputGateKW } + : "and" { GateAnd } + | "nand" { GateNand } + | "or" { GateOr } + | "nor" { GateNor } + | "xor" { GateXor } + | "xnor" { GateXnor } +NOutputGateKW :: { NOutputGateKW } + : "buf" { GateBuf } + | "not" { GateNot } DefparamAsgns :: { [(LHS, Expr)] } : DefparamAsgn { [$1] } @@ -655,4 +690,13 @@ combineTags (Just a) (Just b) = combineTags Nothing other = other combineTags other _ = other +exprToLHS :: Expr -> LHS +exprToLHS (Ident x) = LHSIdent x +exprToLHS (Bit e b) = LHSBit (exprToLHS e) b +exprToLHS (Range e r) = LHSRange (exprToLHS e) r +exprToLHS (Access e x) = LHSDot (exprToLHS e) x +exprToLHS (Concat es ) = LHSConcat (map exprToLHS es) +exprToLHS other = + error $ "Parse error: cannot convert expression to LHS: " ++ show other + }