Commit 0c08b9ae by Zachary Snow

preliminary support for multi-dimensional vector types

parent 2ee5b6e0
......@@ -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) =
......
......@@ -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
......
......@@ -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 =
......
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