Commit fb3d68e3 by Zachary Snow

propper support for indexed part select addressing

parent 011d88b5
...@@ -37,8 +37,8 @@ convertStmt (AsgnBlk (AsgnOp op) lhs expr) = ...@@ -37,8 +37,8 @@ convertStmt (AsgnBlk (AsgnOp op) lhs expr) =
convertStmt other = other convertStmt other = other
lhsToExpr :: LHS -> Expr lhsToExpr :: LHS -> Expr
lhsToExpr (LHSIdent x) = Ident x lhsToExpr (LHSIdent x ) = Ident x
lhsToExpr (LHSBit l e) = Bit (lhsToExpr l) e lhsToExpr (LHSBit l e ) = Bit (lhsToExpr l) e
lhsToExpr (LHSRange l r) = Range (lhsToExpr l) r lhsToExpr (LHSRange l m r) = Range (lhsToExpr l) m r
lhsToExpr (LHSDot l x) = Dot (lhsToExpr l) x lhsToExpr (LHSDot l x ) = Dot (lhsToExpr l) x
lhsToExpr (LHSConcat ls) = Concat $ map lhsToExpr ls lhsToExpr (LHSConcat ls ) = Concat $ map lhsToExpr ls
...@@ -167,8 +167,8 @@ convertDescription interfaces modules (Part extern Module lifetime name ports it ...@@ -167,8 +167,8 @@ convertDescription interfaces modules (Part extern Module lifetime name ports it
else orig else orig
convertLHS its mps (LHSBit l e) = convertLHS its mps (LHSBit l e) =
LHSBit l (traverseNestedExprs (convertExpr its mps) e) LHSBit l (traverseNestedExprs (convertExpr its mps) e)
convertLHS its mps (LHSRange l (e1, e2)) = convertLHS its mps (LHSRange l m (e1, e2)) =
LHSRange l (traverseNestedExprs (convertExpr its mps) e1, traverseNestedExprs (convertExpr its mps) e2) LHSRange l m (traverseNestedExprs (convertExpr its mps) e1, traverseNestedExprs (convertExpr its mps) e2)
convertLHS _ _ other = other convertLHS _ _ other = other
convertPort :: Identifier -> [Identifier] convertPort :: Identifier -> [Identifier]
convertPort ident = convertPort ident =
......
...@@ -105,14 +105,14 @@ collectExpr :: Expr -> State Info () ...@@ -105,14 +105,14 @@ collectExpr :: Expr -> State Info ()
collectExpr (Ident i) = recordSeqUsage i collectExpr (Ident i) = recordSeqUsage i
collectExpr other = collectNestedExprsM collectNestedExpr other collectExpr other = collectNestedExprsM collectNestedExpr other
collectNestedExpr :: Expr -> State Info () collectNestedExpr :: Expr -> State Info ()
collectNestedExpr (Range (Ident i) _) = recordSeqUsage i collectNestedExpr (Range (Ident i) _ _) = recordSeqUsage i
collectNestedExpr _ = return () collectNestedExpr _ = return ()
collectLHS :: LHS -> State Info () collectLHS :: LHS -> State Info ()
collectLHS (LHSIdent i) = recordSeqUsage i collectLHS (LHSIdent i) = recordSeqUsage i
collectLHS other = collectNestedLHSsM collectNestedLHS other collectLHS other = collectNestedLHSsM collectNestedLHS other
collectNestedLHS :: LHS -> State Info () collectNestedLHS :: LHS -> State Info ()
collectNestedLHS (LHSRange (LHSIdent i) _) = recordSeqUsage i collectNestedLHS (LHSRange (LHSIdent i) _ _) = recordSeqUsage i
collectNestedLHS (LHSBit (LHSIdent i) _) = recordIdxUsage i collectNestedLHS (LHSBit (LHSIdent i) _) = recordIdxUsage i
collectNestedLHS _ = return () collectNestedLHS _ = return ()
-- VCS doesn't like port declarations inside of `generate` blocks, so we hoist -- VCS doesn't like port declarations inside of `generate` blocks, so we hoist
...@@ -190,18 +190,18 @@ unflattener writeToFlatVariant arr (t, major @ (majorHi, majorLo)) = ...@@ -190,18 +190,18 @@ unflattener writeToFlatVariant arr (t, major @ (majorHi, majorLo)) =
, GenModuleItem $ MIDecl $ Variable Local (IntegerAtom TInteger Unspecified) (arrUnflat ++ "_repeater_index") [] Nothing , GenModuleItem $ MIDecl $ Variable Local (IntegerAtom TInteger Unspecified) (arrUnflat ++ "_repeater_index") [] Nothing
, GenFor , GenFor
(index, majorLo) (index, majorLo)
(ccExpr major (endianCondExpr major
(BinOp Le (Ident index) majorHi) (BinOp Le (Ident index) majorHi)
(BinOp Ge (Ident index) majorHi)) (BinOp Ge (Ident index) majorHi))
(index, AsgnOp Add, ccExpr major (Number "1") (Number "-1")) (index, AsgnOp Add, endianCondExpr major (Number "1") (Number "-1"))
(Just $ prefix "unflatten_" ++ arr) (Just $ prefix "unflatten_" ++ arr)
[ localparam startBit [ localparam startBit
(simplify $ BinOp Add (ccExpr major majorLo majorHi) (simplify $ BinOp Add (endianCondExpr major majorLo majorHi)
(BinOp Mul (Ident index) size)) (BinOp Mul (Ident index) size))
, GenModuleItem $ (uncurry $ Assign Nothing) $ , GenModuleItem $ (uncurry $ Assign Nothing) $
if not writeToFlatVariant if not writeToFlatVariant
then (LHSBit (LHSIdent arrUnflat) $ Ident index, Range (Ident arr) origRange) then (LHSBit (LHSIdent arrUnflat) $ Ident index, Range (Ident arr) NonIndexed origRange)
else (LHSRange (LHSIdent arr) origRange, Bit (Ident arrUnflat) (Ident index)) else (LHSRange (LHSIdent arr) NonIndexed origRange, Bit (Ident arrUnflat) (Ident index))
] ]
] ]
where where
...@@ -209,22 +209,13 @@ unflattener writeToFlatVariant arr (t, major @ (majorHi, majorLo)) = ...@@ -209,22 +209,13 @@ unflattener writeToFlatVariant arr (t, major @ (majorHi, majorLo)) =
arrUnflat = prefix arr arrUnflat = prefix arr
index = prefix "_tmp_index_" ++ arr index = prefix "_tmp_index_" ++ arr
minor = head $ snd $ typeRanges t minor = head $ snd $ typeRanges t
size = rangeSize $ ccRange minor minor (swap minor) size = rangeSize $ endianCondRange minor minor (swap minor)
localparam :: Identifier -> Expr -> GenItem localparam :: Identifier -> Expr -> GenItem
localparam x v = GenModuleItem $ MIDecl $ Localparam (Implicit Unspecified []) x v localparam x v = GenModuleItem $ MIDecl $ Localparam (Implicit Unspecified []) x v
origRangeAg = ( (BinOp Add (Ident startBit) origRangeAg = ( (BinOp Add (Ident startBit)
(BinOp Sub size (Number "1"))) (BinOp Sub size (Number "1")))
, Ident startBit ) , Ident startBit )
origRange = ccRange major origRangeAg (swap origRangeAg) origRange = endianCondRange major origRangeAg (swap origRangeAg)
ccExpr :: Range -> Expr -> Expr -> Expr
ccExpr r e1 e2 = simplify $ Mux (uncurry (BinOp Ge) r) e1 e2
ccRange :: Range -> Range -> Range -> Range
ccRange r r1 r2 =
( ccExpr r (fst r1) (fst r2)
, ccExpr r (snd r1) (snd r2)
)
typeIsImplicit :: Type -> Bool typeIsImplicit :: Type -> Bool
typeIsImplicit (Implicit _ _) = True typeIsImplicit (Implicit _ _) = True
...@@ -247,10 +238,10 @@ flattenRanges rs = ...@@ -247,10 +238,10 @@ flattenRanges rs =
rYN = flattenRangesHelp r1 (swap r2) rYN = flattenRangesHelp r1 (swap r2)
rNY = flattenRangesHelp (swap r1) r2 rNY = flattenRangesHelp (swap r1) r2
rNN = flattenRangesHelp (swap r1) (swap r2) rNN = flattenRangesHelp (swap r1) (swap r2)
rY = ccRange r2 rYY rYN rY = endianCondRange r2 rYY rYN
rN = ccRange r2 rNY rNN rN = endianCondRange r2 rNY rNN
rAg = ccRange r1 rY rN rAg = endianCondRange r1 rY rN
r = ccRange r1 rAg (swap rAg) r = endianCondRange r1 rAg (swap rAg)
rs' = (tail $ tail rs) ++ [r] rs' = (tail $ tail rs) ++ [r]
flattenRangesHelp :: Range -> Range -> Range flattenRangesHelp :: Range -> Range -> Range
...@@ -287,17 +278,17 @@ rewriteModuleItem info = ...@@ -287,17 +278,17 @@ rewriteModuleItem info =
rewriteExpr (Ident i) = Ident $ rewriteSeqIdent i rewriteExpr (Ident i) = Ident $ rewriteSeqIdent i
rewriteExpr (Bit (Ident i) e) = rewriteExpr (Bit (Ident i) e) =
if Map.member i typeDims && Set.member i seqUses && Set.notMember i idxUses if Map.member i typeDims && Set.member i seqUses && Set.notMember i idxUses
then Range (Ident $ rewriteSeqIdent i) (hi, lo) then Range (Ident $ rewriteSeqIdent i) NonIndexed (hi, lo)
else Bit (Ident $ rewriteIdxIdent i) e else Bit (Ident $ rewriteIdxIdent i) e
where where
r = head $ snd $ typeRanges $ fst $ typeDims Map.! i r = head $ snd $ typeRanges $ fst $ typeDims Map.! i
size = rangeSize r size = rangeSize r
lo = simplify $ BinOp Mul e size lo = simplify $ BinOp Mul e size
hi = simplify $ BinOp Add lo (BinOp Sub size (Number "1")) hi = simplify $ BinOp Add lo (BinOp Sub size (Number "1"))
rewriteExpr (Range (Ident i) (r @ (s, e))) = rewriteExpr (Range (Ident i) m (r @ (s, e))) =
if Map.member i typeDims if Map.member i typeDims
then Range (Ident i) r' then Range (Ident i) m r'
else Range (Ident i) r else Range (Ident i) m r
where where
(a, b) = head $ snd $ typeRanges $ fst $ typeDims Map.! i (a, b) = head $ snd $ typeRanges $ fst $ typeDims Map.! i
size = rangeSize (a, b) size = rangeSize (a, b)
...@@ -307,13 +298,13 @@ rewriteModuleItem info = ...@@ -307,13 +298,13 @@ rewriteModuleItem info =
rewriteExpr other = other rewriteExpr other = other
rewriteLHS :: LHS -> LHS rewriteLHS :: LHS -> LHS
rewriteLHS (LHSIdent x ) = LHSIdent (rewriteSeqIdent x) rewriteLHS (LHSIdent x ) = LHSIdent (rewriteSeqIdent x)
rewriteLHS (LHSBit (LHSIdent x) e) = rewriteLHS (LHSBit (LHSIdent x) e) =
LHSBit (LHSIdent $ rewriteIdxIdent x) e LHSBit (LHSIdent $ rewriteIdxIdent x) e
rewriteLHS (LHSBit l e) = LHSBit (rewriteLHS l) e rewriteLHS (LHSBit l e ) = LHSBit (rewriteLHS l) e
rewriteLHS (LHSRange l r) = LHSRange (rewriteLHS l) r rewriteLHS (LHSRange l m r) = LHSRange (rewriteLHS l) m r
rewriteLHS (LHSDot l x) = LHSDot (rewriteLHS l) x rewriteLHS (LHSDot l x ) = LHSDot (rewriteLHS l) x
rewriteLHS (LHSConcat ls) = LHSConcat $ map rewriteLHS ls rewriteLHS (LHSConcat ls ) = LHSConcat $ map rewriteLHS ls
rewriteStmt :: Stmt -> Stmt rewriteStmt :: Stmt -> Stmt
rewriteStmt (AsgnBlk op lhs expr) = convertAssignment (AsgnBlk op) lhs expr rewriteStmt (AsgnBlk op lhs expr) = convertAssignment (AsgnBlk op) lhs expr
......
...@@ -148,16 +148,16 @@ convertAsgn structs types (lhs, expr) = ...@@ -148,16 +148,16 @@ convertAsgn structs types (lhs, expr) =
(t, l') = convertLHS l (t, l') = convertLHS l
(tf, rs) = typeRanges t (tf, rs) = typeRanges t
e' = snd $ convertSubExpr e e' = snd $ convertSubExpr e
convertLHS (LHSRange l rOuterOrig) = convertLHS (LHSRange l m rOuterOrig) =
case l' of case l' of
LHSRange lInner (_, loI) -> LHSRange lInner NonIndexed (_, loI) ->
(t, LHSRange lInner (simplify hi, simplify lo)) (t, LHSRange lInner m (simplify hi, simplify lo))
where where
lo = BinOp Add loI loO lo = BinOp Add loI loO
hi = BinOp Add loI hiO hi = BinOp Add loI hiO
_ -> if null rs _ -> if null rs
then (Implicit Unspecified [], LHSRange l' rOuter) then (Implicit Unspecified [], LHSRange l' m rOuter)
else (tf rs', LHSRange l' rOuter) else (tf rs', LHSRange l' m rOuter)
where where
(t, l') = convertLHS l (t, l') = convertLHS l
(tf, rs) = typeRanges t (tf, rs) = typeRanges t
...@@ -170,7 +170,7 @@ convertAsgn structs types (lhs, expr) = ...@@ -170,7 +170,7 @@ convertAsgn structs types (lhs, expr) =
InterfaceT _ _ _ -> (Implicit Unspecified [], LHSDot l' x) InterfaceT _ _ _ -> (Implicit Unspecified [], LHSDot l' x)
Struct _ _ _ -> case Map.lookup structTf structs of Struct _ _ _ -> case Map.lookup structTf structs of
Nothing -> (fieldType, LHSDot l' x) Nothing -> (fieldType, LHSDot l' x)
Just (structT, m) -> (tf [tr], LHSRange l' r) Just (structT, m) -> (tf [tr], LHSRange l' NonIndexed r)
where where
(tf, _) = typeRanges structT (tf, _) = typeRanges structT
(r @ (hi, lo), base) = m Map.! x (r @ (hi, lo), base) = m Map.! x
...@@ -228,7 +228,7 @@ convertAsgn structs types (lhs, expr) = ...@@ -228,7 +228,7 @@ convertAsgn structs types (lhs, expr) =
Struct _ _ _ -> Struct _ _ _ ->
if Map.notMember structTf structs if Map.notMember structTf structs
then (fieldType, Dot e' x) then (fieldType, Dot e' x)
else (fieldType, Range e' r) else (fieldType, Range e' NonIndexed r)
_ -> (Implicit Unspecified [], Dot e' x) _ -> (Implicit Unspecified [], Dot e' x)
where where
(subExprType, e') = convertSubExpr e (subExprType, e') = convertSubExpr e
...@@ -236,17 +236,17 @@ convertAsgn structs types (lhs, expr) = ...@@ -236,17 +236,17 @@ convertAsgn structs types (lhs, expr) =
structTf = Struct p fields structTf = Struct p fields
fieldType = lookupFieldType fields x fieldType = lookupFieldType fields x
r = lookupUnstructRange structTf x r = lookupUnstructRange structTf x
convertSubExpr (Range eOuter (rOuter @ (hiO, loO))) = convertSubExpr (Range eOuter m (rOuter @ (hiO, loO))) =
-- VCS doesn't allow ranges to be cascaded, so we need to combine -- VCS doesn't allow ranges to be cascaded, so we need to combine
-- nested Ranges into a single range. My understanding of the -- nested Ranges into a single range. My understanding of the
-- semantics are that a range returns a new, zero-indexed sub-range. -- semantics are that a range returns a new, zero-indexed sub-range.
case eOuter' of case eOuter' of
Range eInner (_, loI) -> Range eInner NonIndexed (_, loI) ->
(t, Range eInner (simplify hi, simplify lo)) (t, Range eInner m (simplify hi, simplify lo))
where where
lo = BinOp Add loI loO lo = BinOp Add loI loO
hi = BinOp Add loI hiO hi = BinOp Add loI hiO
_ -> (t, Range eOuter' rOuter) _ -> (t, Range eOuter' m rOuter)
where (t, eOuter') = convertSubExpr eOuter where (t, eOuter') = convertSubExpr eOuter
convertSubExpr (Concat exprs) = convertSubExpr (Concat exprs) =
(Implicit Unspecified [], Concat $ map (snd . convertSubExpr) exprs) (Implicit Unspecified [], Concat $ map (snd . convertSubExpr) exprs)
...@@ -257,7 +257,7 @@ convertAsgn structs types (lhs, expr) = ...@@ -257,7 +257,7 @@ convertAsgn structs types (lhs, expr) =
(_, e2') = convertSubExpr e2 (_, e2') = convertSubExpr e2
convertSubExpr (Bit e i) = convertSubExpr (Bit e i) =
case e' of case e' of
Range eInner (_, loI) -> Range eInner NonIndexed (_, loI) ->
(t', Bit eInner (simplify $ BinOp Add loI i')) (t', Bit eInner (simplify $ BinOp Add loI i'))
_ -> (t', Bit e' i') _ -> (t', Bit e' i')
where where
......
...@@ -355,11 +355,11 @@ traverseNestedExprsM mapper = exprMapper ...@@ -355,11 +355,11 @@ traverseNestedExprsM mapper = exprMapper
em (String s) = return $ String s em (String s) = return $ String s
em (Number s) = return $ Number s em (Number s) = return $ Number s
em (Ident i) = return $ Ident i em (Ident i) = return $ Ident i
em (Range e (e1, e2)) = do em (Range e m (e1, e2)) = do
e' <- exprMapper e e' <- exprMapper e
e1' <- exprMapper e1 e1' <- exprMapper e1
e2' <- exprMapper e2 e2' <- exprMapper e2
return $ Range e' (e1', e2') return $ Range e' m (e1', e2')
em (Bit e1 e2) = do em (Bit e1 e2) = do
e1' <- exprMapper e1 e1' <- exprMapper e1
e2' <- exprMapper e2 e2' <- exprMapper e2
...@@ -611,11 +611,11 @@ traverseNestedLHSsM :: Monad m => MapperM m LHS -> MapperM m LHS ...@@ -611,11 +611,11 @@ traverseNestedLHSsM :: Monad m => MapperM m LHS -> MapperM m LHS
traverseNestedLHSsM mapper = fullMapper traverseNestedLHSsM mapper = fullMapper
where where
fullMapper lhs = tl lhs >>= mapper fullMapper lhs = tl lhs >>= mapper
tl (LHSIdent x ) = return $ LHSIdent x tl (LHSIdent x ) = return $ LHSIdent x
tl (LHSBit l e ) = fullMapper l >>= \l' -> return $ LHSBit l' e tl (LHSBit l e ) = fullMapper l >>= \l' -> return $ LHSBit l' e
tl (LHSRange l r ) = fullMapper l >>= \l' -> return $ LHSRange l' r tl (LHSRange l m r) = fullMapper l >>= \l' -> return $ LHSRange l' m r
tl (LHSDot l x ) = fullMapper l >>= \l' -> return $ LHSDot l' x tl (LHSDot l x ) = fullMapper l >>= \l' -> return $ LHSDot l' x
tl (LHSConcat lhss) = mapM fullMapper lhss >>= return . LHSConcat tl (LHSConcat lhss ) = mapM fullMapper lhss >>= return . LHSConcat
traverseNestedLHSs :: Mapper LHS -> Mapper LHS traverseNestedLHSs :: Mapper LHS -> Mapper LHS
traverseNestedLHSs = unmonad traverseNestedLHSsM traverseNestedLHSs = unmonad traverseNestedLHSsM
......
...@@ -9,10 +9,13 @@ module Language.SystemVerilog.AST.Expr ...@@ -9,10 +9,13 @@ module Language.SystemVerilog.AST.Expr
( Expr (..) ( Expr (..)
, Range , Range
, Args (..) , Args (..)
, PartSelectMode (..)
, showAssignment , showAssignment
, showRanges , showRanges
, simplify , simplify
, rangeSize , rangeSize
, endianCondExpr
, endianCondRange
) where ) where
import Data.List (intercalate) import Data.List (intercalate)
...@@ -29,7 +32,7 @@ data Expr ...@@ -29,7 +32,7 @@ data Expr
= String String = String String
| Number String | Number String
| Ident Identifier | Ident Identifier
| Range Expr Range | Range Expr PartSelectMode Range
| Bit Expr Expr | Bit Expr Expr
| Repeat Expr [Expr] | Repeat Expr [Expr]
| Concat [Expr] | Concat [Expr]
...@@ -48,7 +51,7 @@ instance Show Expr where ...@@ -48,7 +51,7 @@ instance Show Expr where
show (Ident str ) = str show (Ident str ) = str
show (String str ) = printf "\"%s\"" str show (String str ) = printf "\"%s\"" str
show (Bit e b ) = printf "%s[%s]" (show e) (show b) show (Bit e b ) = printf "%s[%s]" (show e) (show b)
show (Range e r ) = printf "%s%s" (show e) (showRange r) show (Range e m r) = printf "%s[%s%s%s]" (show e) (show $ fst r) (show m) (show $ snd r)
show (Repeat e l ) = printf "{%s {%s}}" (show e) (commas $ map show l) show (Repeat e l ) = printf "{%s {%s}}" (show e) (commas $ map show l)
show (Concat l ) = printf "{%s}" (commas $ map show l) show (Concat l ) = printf "{%s}" (commas $ map show l)
show (UniOp a b ) = printf "(%s %s)" (show a) (show b) show (UniOp a b ) = printf "(%s %s)" (show a) (show b)
...@@ -76,6 +79,17 @@ instance Show Args where ...@@ -76,6 +79,17 @@ instance Show Args where
showPnArg = maybe "" show showPnArg = maybe "" show
showKwArg (x, me) = printf ".%s(%s)" x (showPnArg me) showKwArg (x, me) = printf ".%s(%s)" x (showPnArg me)
data PartSelectMode
= NonIndexed
| IndexedPlus
| IndexedMinus
deriving (Eq, Ord)
instance Show PartSelectMode where
show NonIndexed = ":"
show IndexedPlus = "+:"
show IndexedMinus = "-:"
showAssignment :: Maybe Expr -> String showAssignment :: Maybe Expr -> String
showAssignment Nothing = "" showAssignment Nothing = ""
showAssignment (Just val) = " = " ++ show val showAssignment (Just val) = " = " ++ show val
...@@ -132,3 +146,18 @@ simplify other = other ...@@ -132,3 +146,18 @@ simplify other = other
rangeSize :: Range -> Expr rangeSize :: Range -> Expr
rangeSize (s, e) = rangeSize (s, e) =
simplify $ BinOp Add (BinOp Sub s e) (Number "1") simplify $ BinOp Add (BinOp Sub s e) (Number "1")
-- chooses one or the other expression based on the endianness of the given
-- range; [hi:lo] chooses the first expression
endianCondExpr :: Range -> Expr -> Expr -> Expr
endianCondExpr r e1 e2 = simplify $ Mux (uncurry (BinOp Ge) r) e1 e2
-- chooses one or the other range based on the endianness of the given range,
-- but in such a way that the result is itself also usable as a range even if
-- the endianness cannot be resolved during conversion, i.e. if it's dependent
-- on a parameter value; [hi:lo] chooses the first range
endianCondRange :: Range -> Range -> Range -> Range
endianCondRange r r1 r2 =
( endianCondExpr r (fst r1) (fst r2)
, endianCondExpr r (snd r1) (snd r2)
)
...@@ -13,19 +13,19 @@ import Text.Printf (printf) ...@@ -13,19 +13,19 @@ import Text.Printf (printf)
import Language.SystemVerilog.AST.ShowHelp (commas) import Language.SystemVerilog.AST.ShowHelp (commas)
import Language.SystemVerilog.AST.Type (Identifier) import Language.SystemVerilog.AST.Type (Identifier)
import Language.SystemVerilog.AST.Expr (Expr, Range) import Language.SystemVerilog.AST.Expr (Expr, PartSelectMode, Range)
data LHS data LHS
= LHSIdent Identifier = LHSIdent Identifier
| LHSBit LHS Expr | LHSBit LHS Expr
| LHSRange LHS Range | LHSRange LHS PartSelectMode Range
| LHSDot LHS Identifier | LHSDot LHS Identifier
| LHSConcat [LHS] | LHSConcat [LHS]
deriving Eq deriving Eq
instance Show LHS where instance Show LHS where
show (LHSIdent x ) = x show (LHSIdent x ) = x
show (LHSBit l e ) = printf "%s[%s]" (show l) (show e) show (LHSBit l e ) = printf "%s[%s]" (show l) (show e)
show (LHSRange l (a, b)) = printf "%s[%s:%s]" (show l) (show a) (show b) show (LHSRange l m (a, b)) = printf "%s[%s%s%s]" (show l) (show a) (show m) (show b)
show (LHSDot l x ) = printf "%s.%s" (show l) x show (LHSDot l x ) = printf "%s.%s" (show l) x
show (LHSConcat lhss ) = printf "{%s}" (commas $ map show lhss) show (LHSConcat lhss ) = printf "{%s}" (commas $ map show lhss)
...@@ -601,13 +601,15 @@ DeclAsgn :: { (Identifier, Expr) } ...@@ -601,13 +601,15 @@ DeclAsgn :: { (Identifier, Expr) }
Range :: { Range } Range :: { Range }
: "[" Expr ":" Expr "]" { ($2, $4) } : "[" Expr ":" Expr "]" { ($2, $4) }
-- TODO: This assumes the ranges are always [hi:lo]; See section 11.5.1!
| "[" Expr "+:" Expr "]" { (BinOp Sub (BinOp Add $2 $4) (Number "1"), $2) } PartSelect :: { (PartSelectMode, Range) }
| "[" Expr "-:" Expr "]" { ($2, BinOp Add (BinOp Sub $2 $4) (Number "1")) } : "[" Expr ":" Expr "]" { (NonIndexed , ($2, $4)) }
| "[" Expr "+:" Expr "]" { (IndexedPlus , ($2, $4)) }
| "[" Expr "-:" Expr "]" { (IndexedMinus, ($2, $4)) }
LHS :: { LHS } LHS :: { LHS }
: Identifier { LHSIdent $1 } : Identifier { LHSIdent $1 }
| LHS Range { LHSRange $1 $2 } | LHS PartSelect { LHSRange $1 (fst $2) (snd $2) }
| LHS "[" Expr "]" { LHSBit $1 $3 } | LHS "[" Expr "]" { LHSBit $1 $3 }
| LHS "." Identifier { LHSDot $1 $3 } | LHS "." Identifier { LHSDot $1 $3 }
| "{" LHSs "}" { LHSConcat $2 } | "{" LHSs "}" { LHSConcat $2 }
...@@ -782,7 +784,7 @@ Expr :: { Expr } ...@@ -782,7 +784,7 @@ Expr :: { Expr }
| Identifier "(" CallArgs ")" { Call $1 $3 } | Identifier "(" CallArgs ")" { Call $1 $3 }
| "$bits" "(" BitsArg ")" { Bits $3 } | "$bits" "(" BitsArg ")" { Bits $3 }
| Identifier { Ident $1 } | Identifier { Ident $1 }
| Expr Range { Range $1 $2 } | Expr PartSelect { Range $1 (fst $2) (snd $2) }
| Expr "[" Expr "]" { Bit $1 $3 } | Expr "[" Expr "]" { Bit $1 $3 }
| "{" Expr "{" Exprs "}" "}" { Repeat $2 $4 } | "{" Expr "{" Exprs "}" "}" { Repeat $2 $4 }
| "{" Exprs "}" { Concat $2 } | "{" Exprs "}" { Concat $2 }
...@@ -934,12 +936,11 @@ combineTags Nothing other = other ...@@ -934,12 +936,11 @@ combineTags Nothing other = other
combineTags other _ = other combineTags other _ = other
exprToLHS :: Expr -> LHS exprToLHS :: Expr -> LHS
exprToLHS (Ident x) = LHSIdent x exprToLHS (Ident x ) = LHSIdent x
exprToLHS (Bit e b) = LHSBit (exprToLHS e) b exprToLHS (Bit e b ) = LHSBit (exprToLHS e) b
exprToLHS (Range e r) = LHSRange (exprToLHS e) r exprToLHS (Range e m r) = LHSRange (exprToLHS e) m r
exprToLHS (Dot e x) = LHSDot (exprToLHS e) x exprToLHS (Dot e x ) = LHSDot (exprToLHS e) x
exprToLHS (Concat es) = LHSConcat (map exprToLHS es) exprToLHS (Concat es ) = LHSConcat (map exprToLHS es)
exprToLHS other = exprToLHS other =
error $ "Parse error: cannot convert expression to LHS: " ++ show other error $ "Parse error: cannot convert expression to LHS: " ++ show other
} }
...@@ -235,7 +235,7 @@ takeLHSStep :: Maybe LHS -> DeclToken -> Maybe LHS ...@@ -235,7 +235,7 @@ takeLHSStep :: Maybe LHS -> DeclToken -> Maybe LHS
takeLHSStep (Nothing ) (DTConcat lhss) = Just $ LHSConcat lhss takeLHSStep (Nothing ) (DTConcat lhss) = Just $ LHSConcat lhss
takeLHSStep (Nothing ) (DTIdent x ) = Just $ LHSIdent x takeLHSStep (Nothing ) (DTIdent x ) = Just $ LHSIdent x
takeLHSStep (Just curr) (DTBit e ) = Just $ LHSBit curr e takeLHSStep (Just curr) (DTBit e ) = Just $ LHSBit curr e
takeLHSStep (Just curr) (DTRange r ) = Just $ LHSRange curr r takeLHSStep (Just curr) (DTRange r ) = Just $ LHSRange curr NonIndexed r
takeLHSStep (Just curr) (DTDot x ) = Just $ LHSDot curr x takeLHSStep (Just curr) (DTDot x ) = Just $ LHSDot curr x
takeLHSStep (maybeCurr) token = takeLHSStep (maybeCurr) token =
error $ "unexpected token in LHS: " ++ show (maybeCurr, token) error $ "unexpected token in LHS: " ++ show (maybeCurr, token)
......
module top;
wire [31:0] a;
wire [0:31] b;
assign a = 'h64ded943;
assign b = 'hb7151d17;
initial begin
$display(a[0+:8]);
$display(a[15-:8]);
$display(b[0+:8]);
$display(b[15-:8]);
end
endmodule
module top;
wire [31:0] a;
wire [0:31] b;
assign a = 'h64ded943;
assign b = 'hb7151d17;
initial begin
$display(a[7:0]);
$display(a[15:8]);
$display(b[0:7]);
$display(b[8:15]);
end
endmodule
// intentionally empty
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