diff --git a/Convert/Typedef.hs b/Convert/Typedef.hs index 95bac01..956f761 100644 --- a/Convert/Typedef.hs +++ b/Convert/Typedef.hs @@ -35,20 +35,15 @@ convertDescription types (Module name ports items) = convertDescription _ other = other resolveType :: Types -> Type -> Type -resolveType _ (Reg mr) = Reg mr -resolveType _ (Wire mr) = Wire mr -resolveType _ (Logic mr) = Logic mr -resolveType types (Alias st mr1) = +resolveType _ (Reg rs) = Reg rs +resolveType _ (Wire rs) = Wire rs +resolveType _ (Logic rs) = Logic rs +resolveType types (Alias st rs1) = case resolveType types $ types Map.! st of - (Reg mr2) -> Reg $ combineRanges mr1 mr2 - (Wire mr2) -> Wire $ combineRanges mr1 mr2 - (Logic mr2) -> Logic $ combineRanges mr1 mr2 + (Reg rs2) -> Reg $ rs2 ++ rs1 + (Wire rs2) -> Wire $ rs2 ++ rs1 + (Logic rs2) -> Logic $ rs2 ++ rs1 (Alias _ _) -> error $ "resolveType invariant failed on " ++ st - where - combineRanges :: Maybe Range -> Maybe Range -> Maybe Range - combineRanges Nothing other = other - combineRanges other Nothing = other - combineRanges _ _ = error $ "alias " ++ st ++ " leads to 2-D vectorized type" convertModuleItem :: Types -> ModuleItem -> ModuleItem convertModuleItem types (LocalNet t ident val) = diff --git a/Language/SystemVerilog/AST.hs b/Language/SystemVerilog/AST.hs index 7bf0b26..0b149b6 100644 --- a/Language/SystemVerilog/AST.hs +++ b/Language/SystemVerilog/AST.hs @@ -71,24 +71,24 @@ instance Show Direction where show Inout = "inout" data Type - = Reg (Maybe Range) - | Wire (Maybe Range) - | Logic (Maybe Range) - | Alias String (Maybe Range) + = Reg [Range] + | Wire [Range] + | Logic [Range] + | Alias String [Range] deriving Eq instance Show Type where - show (Reg r) = "reg " ++ (showRange r) - show (Wire r) = "wire " ++ (showRange r) - show (Logic r) = "logic " ++ (showRange r) - show (Alias t r) = t ++ " " ++ (showRange r) + show (Reg r) = "reg " ++ (showRanges r) + show (Wire r) = "wire " ++ (showRanges r) + show (Logic r) = "logic " ++ (showRanges r) + show (Alias t r) = t ++ " " ++ (showRanges r) data ModuleItem = Comment String | MIParameter Parameter | MILocalparam Localparam | MIIntegerV IntegerV - | PortDecl Direction (Maybe Range) Identifier + | PortDecl Direction [Range] Identifier | LocalNet Type Identifier RangesOrAssignment | AlwaysC AlwaysKW Stmt | Assign LHS Expr @@ -134,7 +134,7 @@ instance Show ModuleItem where 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 + PortDecl d r x -> printf "%s %s%s;" (show d) (showRanges r) x LocalNet t x v -> printf "%s%s%s;" (show t) x (showRangesOrAssignment v) AlwaysC k b -> printf "%s %s" (show k) (show b) Assign a b -> printf "assign %s = %s;" (show a) (show b) @@ -334,6 +334,8 @@ instance Show Stmt where show (Null ) = ";" data BlockItemDeclaration + -- TODO: Maybe BIDReg should use [Range] for the first arg as well, but it's + -- really not clear to me what useful purpose this would have. = BIDReg (Maybe Range) Identifier [Range] | BIDParameter Parameter | BIDLocalparam Localparam diff --git a/Language/SystemVerilog/Parser/Parse.y b/Language/SystemVerilog/Parser/Parse.y index 0cd8bec..13d7c4a 100644 --- a/Language/SystemVerilog/Parser/Parse.y +++ b/Language/SystemVerilog/Parser/Parse.y @@ -177,10 +177,10 @@ Typedef :: { Description } : "typedef" Type Identifier ";" { Typedef $2 $3 } Type :: { Type } - : "wire" opt(Range) { Wire $2 } - | "reg" opt(Range) { Reg $2 } - | "logic" opt(Range) { Logic $2 } - | Identifier opt(Range) { Alias $1 $2 } + : "wire" Dimensions { Wire $2 } + | "reg" Dimensions { Reg $2 } + | "logic" Dimensions { Logic $2 } + | Identifier Dimensions { Alias $1 $2 } Module :: { Description } : "module" Identifier Params ";" ModuleItems "endmodule" { Module $2 [] ($3 ++ $5) } @@ -217,12 +217,12 @@ PortDeclsFollow :: { [ModuleItem] } | PortDecl(",") PortDeclsFollow { $1 ++ $2 } PortDecl(delim) :: { [ModuleItem] } - : "inout" opt(NetType) opt(Range) Identifiers delim { portDeclToModuleItems Inout $2 $3 (zip $4 (repeat Nothing)) } - | "input" opt(NetType) opt(Range) Identifiers delim { portDeclToModuleItems Input $2 $3 (zip $4 (repeat Nothing)) } - | "output" "wire" opt(Range) Identifiers delim { portDeclToModuleItems Output (Just Wire ) $3 (zip $4 (repeat Nothing)) } - | "output" "reg" opt(Range) VariablePortIdentifiers delim { portDeclToModuleItems Output (Just Reg ) $3 $4 } - | "output" "logic" opt(Range) VariablePortIdentifiers delim { portDeclToModuleItems Output (Just Logic) $3 $4 } -NetType :: { Maybe Range -> Type } + : "inout" opt(NetType) Dimensions Identifiers delim { portDeclToModuleItems Inout $2 $3 (zip $4 (repeat Nothing)) } + | "input" opt(NetType) Dimensions Identifiers delim { portDeclToModuleItems Input $2 $3 (zip $4 (repeat Nothing)) } + | "output" "wire" Dimensions Identifiers delim { portDeclToModuleItems Output (Just Wire ) $3 (zip $4 (repeat Nothing)) } + | "output" "reg" Dimensions VariablePortIdentifiers delim { portDeclToModuleItems Output (Just Reg ) $3 $4 } + | "output" "logic" Dimensions VariablePortIdentifiers delim { portDeclToModuleItems Output (Just Logic) $3 $4 } +NetType :: { [Range] -> Type } : "wire" { Wire } | "logic" { Logic } VariablePortIdentifiers :: { [(Identifier, Maybe Expr)] } @@ -239,10 +239,10 @@ ModuleItems :: { [ModuleItem] } ModuleItem :: { [ModuleItem] } : PortDecl(";") { $1 } -- TODO: Allowing Ranges on aliases creates conflicts - | Identifier VariableIdentifiers ";" { map (uncurry $ LocalNet (Alias $1 Nothing)) $2 } - | "wire" opt(Range) VariableIdentifiers ";" { map (uncurry $ LocalNet $ Wire $2) $3 } - | "reg" opt(Range) VariableIdentifiers ";" { map (uncurry $ LocalNet $ Reg $2) $3 } - | "logic" opt(Range) VariableIdentifiers ";" { map (uncurry $ LocalNet $ Logic $2) $3 } + | Identifier VariableIdentifiers ";" { map (uncurry $ LocalNet (Alias $1 [])) $2 } + | "wire" Dimensions VariableIdentifiers ";" { map (uncurry $ LocalNet $ Wire $2) $3 } + | "reg" Dimensions VariableIdentifiers ";" { map (uncurry $ LocalNet $ Reg $2) $3 } + | "logic" Dimensions VariableIdentifiers ";" { map (uncurry $ LocalNet $ Logic $2) $3 } | ParameterDeclaration { map MIParameter $1 } | LocalparamDeclaration { map MILocalparam $1 } | IntegerDeclaration { map MIIntegerV $1 } @@ -307,13 +307,16 @@ VariableIdentifiers :: { [(Identifier, Either [Range] (Maybe Expr))] } : VariableType { [$1] } | VariableIdentifiers "," VariableType { $1 ++ [$3] } VariableType :: { (Identifier, Either [Range] (Maybe Expr)) } - : Identifier { ($1, Right $ Nothing) } - | Identifier "=" Expr { ($1, Right $ Just $3) } - | Identifier Dimensions { ($1, Left $2) } + : Identifier { ($1, Right $ Nothing) } + | Identifier "=" Expr { ($1, Right $ Just $3) } + | Identifier DimensionsNonEmpty { ($1, Left $2) } Dimensions :: { [Range] } - : Range { [$1] } - | Dimensions Range { $1 ++ [$2] } + : {- empty -} { [] } + | DimensionsNonEmpty { $1 } +DimensionsNonEmpty :: { [Range] } + : Range { [$1] } + | DimensionsNonEmpty Range { $1 ++ [$2] } DeclAsgns :: { [(Identifier, Expr)] } : DeclAsgn { [$1] } @@ -387,8 +390,7 @@ BlockVariableIdentifiers :: { [(Identifier, [Range])] } : BlockVariableType { [$1] } | BlockVariableIdentifiers "," BlockVariableType { $1 ++ [$3] } BlockVariableType :: { (Identifier, [Range]) } - : Identifier { ($1, []) } - | Identifier Dimensions { ($1, $2) } + : Identifier Dimensions { ($1, $2) } Cases :: { [Case] } : {- empty -} { [] } @@ -501,21 +503,21 @@ toString = tail . init . tokenString portDeclToModuleItems :: Direction - -> (Maybe ((Maybe Range) -> Type)) - -> Maybe Range + -> (Maybe ([Range] -> Type)) + -> [Range] -> [(Identifier, Maybe Expr)] -> [ModuleItem] -portDeclToModuleItems dir Nothing mr l = - map (PortDecl dir mr) $ map toIdentifier $ l +portDeclToModuleItems dir Nothing rs l = + map (PortDecl dir rs) $ map toIdentifier $ l where toIdentifier (x, Just _) = error "ParseError: Incomplete port decl cannot have initialization" toIdentifier (x, Nothing) = x -portDeclToModuleItems dir (Just tf) mr l = +portDeclToModuleItems dir (Just tf) rs l = concat $ map toItems l where toItems (x, e) = - [ PortDecl dir mr x - , LocalNet (tf mr) x (Right e) ] + [ PortDecl dir rs x + , LocalNet (tf rs) x (Right e) ] getPortNames :: [ModuleItem] -> [Identifier] getPortNames items =