mirror of https://github.com/zachjs/sv2v.git
more consistent procedural assignment support
This commit is contained in:
parent
610d9abacf
commit
9694799a23
|
|
@ -32,6 +32,6 @@ convertStmt (For inits cc asgns stmt) =
|
||||||
convertAsgn (lhs, AsgnOp op, expr) =
|
convertAsgn (lhs, AsgnOp op, expr) =
|
||||||
(lhs, AsgnOpEq, BinOp op (lhsToExpr lhs) expr)
|
(lhs, AsgnOpEq, BinOp op (lhsToExpr lhs) expr)
|
||||||
convertAsgn other = other
|
convertAsgn other = other
|
||||||
convertStmt (AsgnBlk (AsgnOp op) lhs expr) =
|
convertStmt (Asgn (AsgnOp op) mt lhs expr) =
|
||||||
AsgnBlk AsgnOpEq lhs (BinOp op (lhsToExpr lhs) expr)
|
Asgn AsgnOpEq mt lhs (BinOp op (lhsToExpr lhs) expr)
|
||||||
convertStmt other = other
|
convertStmt other = other
|
||||||
|
|
|
||||||
|
|
@ -47,4 +47,4 @@ splitDecl (Variable d t ident a (Just e)) =
|
||||||
splitDecl other = (other, Nothing)
|
splitDecl other = (other, Nothing)
|
||||||
|
|
||||||
asgnStmt :: (LHS, Expr) -> Stmt
|
asgnStmt :: (LHS, Expr) -> Stmt
|
||||||
asgnStmt = uncurry $ AsgnBlk AsgnOpEq
|
asgnStmt = uncurry $ Asgn AsgnOpEq Nothing
|
||||||
|
|
|
||||||
|
|
@ -80,7 +80,7 @@ splitDecl other =
|
||||||
error $ "invalid for loop decl: " ++ show other
|
error $ "invalid for loop decl: " ++ show other
|
||||||
|
|
||||||
asgnStmt :: (LHS, Expr) -> Stmt
|
asgnStmt :: (LHS, Expr) -> Stmt
|
||||||
asgnStmt = uncurry $ AsgnBlk AsgnOpEq
|
asgnStmt = uncurry $ Asgn AsgnOpEq Nothing
|
||||||
|
|
||||||
dummyDecl :: Maybe Expr -> Decl
|
dummyDecl :: Maybe Expr -> Decl
|
||||||
dummyDecl = Variable Local (IntegerAtom TInteger Unspecified) "_sv2v_dummy" []
|
dummyDecl = Variable Local (IntegerAtom TInteger Unspecified) "_sv2v_dummy" []
|
||||||
|
|
|
||||||
|
|
@ -101,7 +101,7 @@ addJumpStateDeclStmt stmt =
|
||||||
where (decls, [stmt']) = addJumpStateDeclTF [] [stmt]
|
where (decls, [stmt']) = addJumpStateDeclTF [] [stmt]
|
||||||
|
|
||||||
removeJumpState :: Stmt -> Stmt
|
removeJumpState :: Stmt -> Stmt
|
||||||
removeJumpState (orig @ (AsgnBlk _ (LHSIdent ident) _)) =
|
removeJumpState (orig @ (Asgn _ _ (LHSIdent ident) _)) =
|
||||||
if ident == jumpState
|
if ident == jumpState
|
||||||
then Null
|
then Null
|
||||||
else orig
|
else orig
|
||||||
|
|
@ -298,4 +298,4 @@ assertMsg True _ = return ()
|
||||||
assertMsg False msg = error msg
|
assertMsg False msg = error msg
|
||||||
|
|
||||||
asgn :: Identifier -> Expr -> Stmt
|
asgn :: Identifier -> Expr -> Stmt
|
||||||
asgn x e = AsgnBlk AsgnOpEq (LHSIdent x) e
|
asgn x e = Asgn AsgnOpEq Nothing (LHSIdent x) e
|
||||||
|
|
|
||||||
|
|
@ -80,7 +80,7 @@ convertDescription ports orig =
|
||||||
fixModuleItem (Assign Nothing lhs expr) =
|
fixModuleItem (Assign Nothing lhs expr) =
|
||||||
if Set.disjoint usedIdents origIdents
|
if Set.disjoint usedIdents origIdents
|
||||||
then Assign Nothing lhs expr
|
then Assign Nothing lhs expr
|
||||||
else AlwaysC AlwaysComb $ AsgnBlk AsgnOpEq lhs expr
|
else AlwaysC AlwaysComb $ Asgn AsgnOpEq Nothing lhs expr
|
||||||
where
|
where
|
||||||
usedIdents = execWriter $ collectNestedLHSsM lhsIdents lhs
|
usedIdents = execWriter $ collectNestedLHSsM lhsIdents lhs
|
||||||
-- rewrite port bindings to use temporary nets where necessary
|
-- rewrite port bindings to use temporary nets where necessary
|
||||||
|
|
@ -109,7 +109,7 @@ convertDescription ports orig =
|
||||||
t = Net TWire Unspecified [(DimsFn FnBits $ Right expr, Number "1")]
|
t = Net TWire Unspecified [(DimsFn FnBits $ Right expr, Number "1")]
|
||||||
items =
|
items =
|
||||||
[ MIPackageItem $ Decl $ Variable Local t tmp [] Nothing
|
[ MIPackageItem $ Decl $ Variable Local t tmp [] Nothing
|
||||||
, AlwaysC AlwaysComb $ AsgnBlk AsgnOpEq lhs tmpExpr]
|
, AlwaysC AlwaysComb $ Asgn AsgnOpEq Nothing lhs tmpExpr]
|
||||||
lhs = case exprToLHS expr of
|
lhs = case exprToLHS expr of
|
||||||
Just l -> l
|
Just l -> l
|
||||||
Nothing ->
|
Nothing ->
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@ streamerBlock chunk size asgn output input =
|
||||||
, Variable Local (IntegerAtom TInteger Unspecified) bas [] Nothing
|
, Variable Local (IntegerAtom TInteger Unspecified) bas [] Nothing
|
||||||
]
|
]
|
||||||
[ For inits cmp incr stmt
|
[ For inits cmp incr stmt
|
||||||
, AsgnBlk AsgnOpEq (LHSIdent bas) (Ident idx)
|
, Asgn AsgnOpEq Nothing (LHSIdent bas) (Ident idx)
|
||||||
, For inits cmp2 incr2 stmt2
|
, For inits cmp2 incr2 stmt2
|
||||||
, asgn output (Ident out)
|
, asgn output (Ident out)
|
||||||
]
|
]
|
||||||
|
|
@ -55,23 +55,21 @@ streamerBlock chunk size asgn output input =
|
||||||
incr = [(LHSIdent idx, AsgnOp Add, chunk)]
|
incr = [(LHSIdent idx, AsgnOp Add, chunk)]
|
||||||
lhs = LHSRange (LHSIdent out) IndexedMinus (BinOp Sub hi (Ident idx), chunk)
|
lhs = LHSRange (LHSIdent out) IndexedMinus (BinOp Sub hi (Ident idx), chunk)
|
||||||
expr = Range (Ident inp) IndexedPlus (Ident idx, chunk)
|
expr = Range (Ident inp) IndexedPlus (Ident idx, chunk)
|
||||||
stmt = AsgnBlk AsgnOpEq lhs expr
|
stmt = Asgn AsgnOpEq Nothing lhs expr
|
||||||
-- final chunk loop
|
-- final chunk loop
|
||||||
cmp2 = BinOp Lt (Ident idx) (BinOp Sub size (Ident bas))
|
cmp2 = BinOp Lt (Ident idx) (BinOp Sub size (Ident bas))
|
||||||
incr2 = [(LHSIdent idx, AsgnOp Add, Number "1")]
|
incr2 = [(LHSIdent idx, AsgnOp Add, Number "1")]
|
||||||
lhs2 = LHSBit (LHSIdent out) (Ident idx)
|
lhs2 = LHSBit (LHSIdent out) (Ident idx)
|
||||||
expr2 = Bit (Ident inp) (BinOp Add (Ident idx) (Ident bas))
|
expr2 = Bit (Ident inp) (BinOp Add (Ident idx) (Ident bas))
|
||||||
stmt2 = AsgnBlk AsgnOpEq lhs2 expr2
|
stmt2 = Asgn AsgnOpEq Nothing lhs2 expr2
|
||||||
|
|
||||||
streamerBlockName :: Expr -> Expr -> Identifier
|
streamerBlockName :: Expr -> Expr -> Identifier
|
||||||
streamerBlockName chunk size =
|
streamerBlockName chunk size =
|
||||||
"_sv2v_strm_" ++ shortHash (chunk, size)
|
"_sv2v_strm_" ++ shortHash (chunk, size)
|
||||||
|
|
||||||
traverseStmtM :: Stmt -> Writer Funcs Stmt
|
traverseStmtM :: Stmt -> Writer Funcs Stmt
|
||||||
traverseStmtM (AsgnBlk op lhs expr) =
|
traverseStmtM (Asgn op mt lhs expr) =
|
||||||
traverseAsgnM (lhs, expr) (AsgnBlk op)
|
traverseAsgnM (lhs, expr) (Asgn op mt)
|
||||||
traverseStmtM (Asgn mt lhs expr) =
|
|
||||||
traverseAsgnM (lhs, expr) (Asgn mt)
|
|
||||||
traverseStmtM other = return other
|
traverseStmtM other = return other
|
||||||
|
|
||||||
traverseAsgnM :: (LHS, Expr) -> (LHS -> Expr -> Stmt) -> Writer Funcs Stmt
|
traverseAsgnM :: (LHS, Expr) -> (LHS -> Expr -> Stmt) -> Writer Funcs Stmt
|
||||||
|
|
|
||||||
|
|
@ -244,8 +244,7 @@ traverseSinglyNestedStmtsM fullMapper = cs
|
||||||
caseStmts <- mapM fullMapper $ map snd cases
|
caseStmts <- mapM fullMapper $ map snd cases
|
||||||
let cases' = zip (map fst cases) caseStmts
|
let cases' = zip (map fst cases) caseStmts
|
||||||
return $ Case u kw expr cases'
|
return $ Case u kw expr cases'
|
||||||
cs (AsgnBlk op lhs expr) = return $ AsgnBlk op lhs expr
|
cs (Asgn op mt lhs expr) = return $ Asgn op mt lhs expr
|
||||||
cs (Asgn mt lhs expr) = return $ Asgn mt lhs expr
|
|
||||||
cs (For a b c stmt) = fullMapper stmt >>= return . For a b c
|
cs (For a b c stmt) = fullMapper stmt >>= return . For a b c
|
||||||
cs (While e stmt) = fullMapper stmt >>= return . While e
|
cs (While e stmt) = fullMapper stmt >>= return . While e
|
||||||
cs (RepeatL e stmt) = fullMapper stmt >>= return . RepeatL e
|
cs (RepeatL e stmt) = fullMapper stmt >>= return . RepeatL e
|
||||||
|
|
@ -375,12 +374,12 @@ traverseStmtLHSsM mapper = stmtMapper
|
||||||
stmtMapper (Timing (Event sense) stmt) = do
|
stmtMapper (Timing (Event sense) stmt) = do
|
||||||
sense' <- senseMapper sense
|
sense' <- senseMapper sense
|
||||||
return $ Timing (Event sense') stmt
|
return $ Timing (Event sense') stmt
|
||||||
stmtMapper (Asgn (Just (Event sense)) lhs expr) = do
|
stmtMapper (Asgn op (Just (Event sense)) lhs expr) = do
|
||||||
lhs' <- fullMapper lhs
|
lhs' <- fullMapper lhs
|
||||||
sense' <- senseMapper sense
|
sense' <- senseMapper sense
|
||||||
return $ Asgn (Just $ Event sense') lhs' expr
|
return $ Asgn op (Just $ Event sense') lhs' expr
|
||||||
stmtMapper (AsgnBlk op lhs expr) = fullMapper lhs >>= \lhs' -> return $ AsgnBlk op lhs' expr
|
stmtMapper (Asgn op mt lhs expr) =
|
||||||
stmtMapper (Asgn mt lhs expr) = fullMapper lhs >>= \lhs' -> return $ Asgn mt lhs' expr
|
fullMapper lhs >>= \lhs' -> return $ Asgn op mt lhs' expr
|
||||||
stmtMapper (For inits me incrs stmt) = do
|
stmtMapper (For inits me incrs stmt) = do
|
||||||
inits' <- mapInits inits
|
inits' <- mapInits inits
|
||||||
let (lhss, asgnOps, exprs) = unzip3 incrs
|
let (lhss, asgnOps, exprs) = unzip3 incrs
|
||||||
|
|
@ -708,14 +707,10 @@ traverseStmtExprsM exprMapper = flatStmtMapper
|
||||||
e' <- exprMapper e
|
e' <- exprMapper e
|
||||||
cases' <- mapM caseMapper cases
|
cases' <- mapM caseMapper cases
|
||||||
return $ Case u kw e' cases'
|
return $ Case u kw e' cases'
|
||||||
flatStmtMapper (AsgnBlk op lhs expr) = do
|
flatStmtMapper (Asgn op mt lhs expr) = do
|
||||||
lhs' <- lhsMapper lhs
|
lhs' <- lhsMapper lhs
|
||||||
expr' <- exprMapper expr
|
expr' <- exprMapper expr
|
||||||
return $ AsgnBlk op lhs' expr'
|
return $ Asgn op mt lhs' expr'
|
||||||
flatStmtMapper (Asgn mt lhs expr) = do
|
|
||||||
lhs' <- lhsMapper lhs
|
|
||||||
expr' <- exprMapper expr
|
|
||||||
return $ Asgn mt lhs' expr'
|
|
||||||
flatStmtMapper (For inits cc asgns stmt) = do
|
flatStmtMapper (For inits cc asgns stmt) = do
|
||||||
inits' <- initsMapper inits
|
inits' <- initsMapper inits
|
||||||
cc' <- exprMapper cc
|
cc' <- exprMapper cc
|
||||||
|
|
@ -1028,12 +1023,9 @@ collectAsgnsM = collectAsgnsM' IncludeTFs
|
||||||
traverseStmtAsgnsM :: Monad m => MapperM m (LHS, Expr) -> MapperM m Stmt
|
traverseStmtAsgnsM :: Monad m => MapperM m (LHS, Expr) -> MapperM m Stmt
|
||||||
traverseStmtAsgnsM mapper = stmtMapper
|
traverseStmtAsgnsM mapper = stmtMapper
|
||||||
where
|
where
|
||||||
stmtMapper (AsgnBlk op lhs expr) = do
|
stmtMapper (Asgn op mt lhs expr) = do
|
||||||
(lhs', expr') <- mapper (lhs, expr)
|
(lhs', expr') <- mapper (lhs, expr)
|
||||||
return $ AsgnBlk op lhs' expr'
|
return $ Asgn op mt lhs' expr'
|
||||||
stmtMapper (Asgn mt lhs expr) = do
|
|
||||||
(lhs', expr') <- mapper (lhs, expr)
|
|
||||||
return $ Asgn mt lhs' expr'
|
|
||||||
stmtMapper other = return other
|
stmtMapper other = return other
|
||||||
|
|
||||||
traverseStmtAsgns :: Mapper (LHS, Expr) -> Mapper Stmt
|
traverseStmtAsgns :: Mapper (LHS, Expr) -> Mapper Stmt
|
||||||
|
|
|
||||||
|
|
@ -100,11 +100,13 @@ instance Show BinOp where
|
||||||
|
|
||||||
data AsgnOp
|
data AsgnOp
|
||||||
= AsgnOpEq
|
= AsgnOpEq
|
||||||
|
| AsgnOpNonBlocking
|
||||||
| AsgnOp BinOp
|
| AsgnOp BinOp
|
||||||
deriving (Eq, Ord)
|
deriving (Eq, Ord)
|
||||||
|
|
||||||
instance Show AsgnOp where
|
instance Show AsgnOp where
|
||||||
show AsgnOpEq = "="
|
show AsgnOpEq = "="
|
||||||
|
show AsgnOpNonBlocking = "<="
|
||||||
show (AsgnOp op) = (show op) ++ "="
|
show (AsgnOp op) = (show op) ++ "="
|
||||||
|
|
||||||
data StreamOp
|
data StreamOp
|
||||||
|
|
|
||||||
|
|
@ -38,8 +38,7 @@ data Stmt
|
||||||
| Block BlockKW Identifier [Decl] [Stmt]
|
| Block BlockKW Identifier [Decl] [Stmt]
|
||||||
| Case ViolationCheck CaseKW Expr [Case]
|
| Case ViolationCheck CaseKW Expr [Case]
|
||||||
| For (Either [Decl] [(LHS, Expr)]) Expr [(LHS, AsgnOp, Expr)] Stmt
|
| For (Either [Decl] [(LHS, Expr)]) Expr [(LHS, AsgnOp, Expr)] Stmt
|
||||||
| AsgnBlk AsgnOp LHS Expr
|
| Asgn AsgnOp (Maybe Timing) LHS Expr
|
||||||
| Asgn (Maybe Timing) LHS Expr
|
|
||||||
| While Expr Stmt
|
| While Expr Stmt
|
||||||
| RepeatL Expr Stmt
|
| RepeatL Expr Stmt
|
||||||
| DoWhile Expr Stmt
|
| DoWhile Expr Stmt
|
||||||
|
|
@ -83,8 +82,7 @@ instance Show Stmt where
|
||||||
showAssign (l, op, e) = printf "%s %s %s" (show l) (show op) (show e)
|
showAssign (l, op, e) = printf "%s %s %s" (show l) (show op) (show e)
|
||||||
show (Subroutine e a) = printf "%s%s;" (show e) aStr
|
show (Subroutine e a) = printf "%s%s;" (show e) aStr
|
||||||
where aStr = if a == Args [] [] then "" else show a
|
where aStr = if a == Args [] [] then "" else show a
|
||||||
show (AsgnBlk o v e) = printf "%s %s %s;" (show v) (show o) (show e)
|
show (Asgn o t v e) = printf "%s %s %s%s;" (show v) (show o) (maybe "" showPad t) (show e)
|
||||||
show (Asgn t v e) = printf "%s <= %s%s;" (show v) (maybe "" showPad t) (show e)
|
|
||||||
show (While e s) = printf "while (%s) %s" (show e) (show s)
|
show (While e s) = printf "while (%s) %s" (show e) (show s)
|
||||||
show (RepeatL e s) = printf "repeat (%s) %s" (show e) (show s)
|
show (RepeatL e s) = printf "repeat (%s) %s" (show e) (show s)
|
||||||
show (DoWhile e s) = printf "do %s while (%s);" (show s) (show e)
|
show (DoWhile e s) = printf "do %s while (%s);" (show s) (show e)
|
||||||
|
|
@ -134,7 +132,6 @@ showElseBranch (stmt @ If{}) = ' ' : show stmt
|
||||||
showElseBranch stmt = showBranch stmt
|
showElseBranch stmt = showBranch stmt
|
||||||
|
|
||||||
showShortBranch :: Stmt -> String
|
showShortBranch :: Stmt -> String
|
||||||
showShortBranch (stmt @ AsgnBlk{}) = ' ' : show stmt
|
|
||||||
showShortBranch (stmt @ Asgn{}) = ' ' : show stmt
|
showShortBranch (stmt @ Asgn{}) = ' ' : show stmt
|
||||||
showShortBranch stmt = showBranch stmt
|
showShortBranch stmt = showBranch stmt
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -593,8 +593,8 @@ DeclTokens(delim) :: { [DeclToken] }
|
||||||
: DeclToken delim { [$1] }
|
: DeclToken delim { [$1] }
|
||||||
| DeclToken DeclTokens(delim) { [$1] ++ $2 }
|
| DeclToken DeclTokens(delim) { [$1] ++ $2 }
|
||||||
| Identifier ParamBindings DeclTokens(delim) {% posInject \p -> [DTIdent p $1, DTParams p $2] ++ $3 }
|
| Identifier ParamBindings DeclTokens(delim) {% posInject \p -> [DTIdent p $1, DTParams p $2] ++ $3 }
|
||||||
| AsgnOp Expr "," DeclTokens(delim) {% posInject \p -> [DTAsgn p $1 $2, DTComma p] ++ $4 }
|
| DeclTokenAsgn "," DeclTokens(delim) {% posInject \p -> [$1, DTComma p] ++ $3 }
|
||||||
| AsgnOp Expr delim {% posInject \p -> [DTAsgn p $1 $2] }
|
| DeclTokenAsgn delim {% posInject \p -> [$1] }
|
||||||
DeclToken :: { DeclToken }
|
DeclToken :: { DeclToken }
|
||||||
: "," {% posInject \p -> DTComma p }
|
: "," {% posInject \p -> DTComma p }
|
||||||
| "[" "]" {% posInject \p -> DTAutoDim p }
|
| "[" "]" {% posInject \p -> DTAutoDim p }
|
||||||
|
|
@ -613,8 +613,11 @@ DeclToken :: { DeclToken }
|
||||||
| "{" StreamOp StreamSize Concat "}" {% posInject \p -> DTStream p $2 $3 (map toLHS $4) }
|
| "{" StreamOp StreamSize Concat "}" {% posInject \p -> DTStream p $2 $3 (map toLHS $4) }
|
||||||
| "{" StreamOp Concat "}" {% posInject \p -> DTStream p $2 (Number "1") (map toLHS $3) }
|
| "{" StreamOp Concat "}" {% posInject \p -> DTStream p $2 (Number "1") (map toLHS $3) }
|
||||||
| opt("var") "type" "(" Expr ")" {% posInject \p -> DTType p (\Unspecified -> \[] -> TypeOf $4) }
|
| opt("var") "type" "(" Expr ")" {% posInject \p -> DTType p (\Unspecified -> \[] -> TypeOf $4) }
|
||||||
| "<=" opt(DelayOrEventControl) Expr {% posInject \p -> DTAsgnNBlk p $2 $3 }
|
| "<=" opt(DelayOrEvent) Expr {% posInject \p -> DTAsgn p AsgnOpNonBlocking $2 $3 }
|
||||||
| IncOrDecOperator {% posInject \p -> DTAsgn p (AsgnOp $1) (Number "1") }
|
| IncOrDecOperator {% posInject \p -> DTAsgn p (AsgnOp $1) Nothing (Number "1") }
|
||||||
|
DeclTokenAsgn :: { DeclToken }
|
||||||
|
: "=" opt(DelayOrEvent) Expr {% posInject \p -> DTAsgn p AsgnOpEq $2 $3 }
|
||||||
|
| AsgnBinOp Expr {% posInject \p -> DTAsgn p $1 Nothing $2 }
|
||||||
|
|
||||||
VariablePortIdentifiers :: { [(Identifier, Maybe Expr)] }
|
VariablePortIdentifiers :: { [(Identifier, Maybe Expr)] }
|
||||||
: VariablePortIdentifier { [$1] }
|
: VariablePortIdentifier { [$1] }
|
||||||
|
|
@ -902,10 +905,11 @@ Stmt :: { Stmt }
|
||||||
| StmtTrace StmtNonAsgn { $2 }
|
| StmtTrace StmtNonAsgn { $2 }
|
||||||
|
|
||||||
StmtAsgn :: { Stmt }
|
StmtAsgn :: { Stmt }
|
||||||
: LHS AsgnOp Expr ";" { AsgnBlk $2 $1 $3 }
|
: LHS "=" opt(DelayOrEvent) Expr ";" { Asgn AsgnOpEq $3 $1 $4 }
|
||||||
| LHS IncOrDecOperator ";" { AsgnBlk (AsgnOp $2) $1 (Number "1") }
|
| LHS "<=" opt(DelayOrEvent) Expr ";" { Asgn AsgnOpNonBlocking $3 $1 $4 }
|
||||||
| IncOrDecOperator LHS ";" { AsgnBlk (AsgnOp $1) $2 (Number "1") }
|
| LHS AsgnBinOp Expr ";" { Asgn $2 Nothing $1 $3 }
|
||||||
| LHS "<=" opt(DelayOrEventControl) Expr ";" { Asgn $3 $1 $4 }
|
| LHS IncOrDecOperator ";" { Asgn (AsgnOp $2) Nothing $1 (Number "1") }
|
||||||
|
| IncOrDecOperator LHS ";" { Asgn (AsgnOp $1) Nothing $2 (Number "1") }
|
||||||
| LHS ";" { Subroutine (lhsToExpr $1) (Args [] []) }
|
| LHS ";" { Subroutine (lhsToExpr $1) (Args [] []) }
|
||||||
| LHS CallArgs ";" { Subroutine (lhsToExpr $1) $2 }
|
| LHS CallArgs ";" { Subroutine (lhsToExpr $1) $2 }
|
||||||
StmtNonAsgn :: { Stmt }
|
StmtNonAsgn :: { Stmt }
|
||||||
|
|
@ -1007,9 +1011,9 @@ ClockingEvent :: { Sense }
|
||||||
: "@" "(" Senses ")" { $3 }
|
: "@" "(" Senses ")" { $3 }
|
||||||
|
|
||||||
TimingControl :: { Timing }
|
TimingControl :: { Timing }
|
||||||
: DelayOrEventControl { $1 }
|
: DelayOrEvent { $1 }
|
||||||
| CycleDelay { Cycle $1 }
|
| CycleDelay { Cycle $1 }
|
||||||
DelayOrEventControl :: { Timing }
|
DelayOrEvent :: { Timing }
|
||||||
: DelayControl { Delay $1 }
|
: DelayControl { Delay $1 }
|
||||||
| EventControl { Event $1 }
|
| EventControl { Event $1 }
|
||||||
DelayControl :: { Expr }
|
DelayControl :: { Expr }
|
||||||
|
|
@ -1237,7 +1241,9 @@ GenvarIteration :: { (Identifier, AsgnOp, Expr) }
|
||||||
|
|
||||||
AsgnOp :: { AsgnOp }
|
AsgnOp :: { AsgnOp }
|
||||||
: "=" { AsgnOpEq }
|
: "=" { AsgnOpEq }
|
||||||
| "+=" { AsgnOp Add }
|
| AsgnBinOp { $1 }
|
||||||
|
AsgnBinOp :: { AsgnOp }
|
||||||
|
: "+=" { AsgnOp Add }
|
||||||
| "-=" { AsgnOp Sub }
|
| "-=" { AsgnOp Sub }
|
||||||
| "*=" { AsgnOp Mul }
|
| "*=" { AsgnOp Mul }
|
||||||
| "/=" { AsgnOp Div }
|
| "/=" { AsgnOp Div }
|
||||||
|
|
|
||||||
|
|
@ -55,8 +55,7 @@ import Language.SystemVerilog.Parser.Tokens (Position(..))
|
||||||
data DeclToken
|
data DeclToken
|
||||||
= DTComma Position
|
= DTComma Position
|
||||||
| DTAutoDim Position
|
| DTAutoDim Position
|
||||||
| DTAsgn Position AsgnOp Expr
|
| DTAsgn Position AsgnOp (Maybe Timing) Expr
|
||||||
| DTAsgnNBlk Position (Maybe Timing) Expr
|
|
||||||
| DTRange Position (PartSelectMode, Range)
|
| DTRange Position (PartSelectMode, Range)
|
||||||
| DTIdent Position Identifier
|
| DTIdent Position Identifier
|
||||||
| DTPSIdent Position Identifier Identifier
|
| DTPSIdent Position Identifier Identifier
|
||||||
|
|
@ -73,9 +72,9 @@ data DeclToken
|
||||||
deriving (Show, Eq)
|
deriving (Show, Eq)
|
||||||
|
|
||||||
|
|
||||||
-- entrypoints besides `parseDTsAsDeclOrStmt` use this to disallow `DTAsgnNBlk`
|
-- entrypoints besides `parseDTsAsDeclOrStmt` use this to disallow `DTAsgn` with
|
||||||
-- and `DTAsgn` with a binary assignment operator because we don't expect to see
|
-- a non-blocking operator, binary assignment operator, or a timing control
|
||||||
-- those assignment operators in declarations
|
-- because we don't expect to see those assignment operators in declarations
|
||||||
forbidNonEqAsgn :: [DeclToken] -> a -> a
|
forbidNonEqAsgn :: [DeclToken] -> a -> a
|
||||||
forbidNonEqAsgn tokens =
|
forbidNonEqAsgn tokens =
|
||||||
if any isNonEqAsgn tokens
|
if any isNonEqAsgn tokens
|
||||||
|
|
@ -83,8 +82,8 @@ forbidNonEqAsgn tokens =
|
||||||
else id
|
else id
|
||||||
where
|
where
|
||||||
isNonEqAsgn :: DeclToken -> Bool
|
isNonEqAsgn :: DeclToken -> Bool
|
||||||
isNonEqAsgn (DTAsgnNBlk _ _ _) = True
|
isNonEqAsgn (DTAsgn _ op mt _) =
|
||||||
isNonEqAsgn (DTAsgn _ (AsgnOp _) _) = True
|
op /= AsgnOpEq || mt /= Nothing
|
||||||
isNonEqAsgn _ = False
|
isNonEqAsgn _ = False
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -211,8 +210,8 @@ parseDTsAsDecl tokens =
|
||||||
parseDTsAsDeclOrStmt :: [DeclToken] -> ([Decl], [Stmt])
|
parseDTsAsDeclOrStmt :: [DeclToken] -> ([Decl], [Stmt])
|
||||||
parseDTsAsDeclOrStmt [DTIdent pos f] = ([], [traceStmt pos, Subroutine (Ident f) (Args [] [])])
|
parseDTsAsDeclOrStmt [DTIdent pos f] = ([], [traceStmt pos, Subroutine (Ident f) (Args [] [])])
|
||||||
parseDTsAsDeclOrStmt [DTPSIdent pos p f] = ([], [traceStmt pos, Subroutine (PSIdent p f) (Args [] [])])
|
parseDTsAsDeclOrStmt [DTPSIdent pos p f] = ([], [traceStmt pos, Subroutine (PSIdent p f) (Args [] [])])
|
||||||
parseDTsAsDeclOrStmt (DTAsgn pos (AsgnOp op) e : tok : toks) =
|
parseDTsAsDeclOrStmt (DTAsgn pos (AsgnOp op) mt e : tok : toks) =
|
||||||
parseDTsAsDeclOrStmt $ (tok : toks) ++ [DTAsgn pos (AsgnOp op) e]
|
parseDTsAsDeclOrStmt $ (tok : toks) ++ [DTAsgn pos (AsgnOp op) mt e]
|
||||||
parseDTsAsDeclOrStmt tokens =
|
parseDTsAsDeclOrStmt tokens =
|
||||||
if (isStmt (last tokens) || tripLookahead tokens) && maybeLhs /= Nothing
|
if (isStmt (last tokens) || tripLookahead tokens) && maybeLhs /= Nothing
|
||||||
then ([], [traceStmt pos, stmt])
|
then ([], [traceStmt pos, stmt])
|
||||||
|
|
@ -220,14 +219,12 @@ parseDTsAsDeclOrStmt tokens =
|
||||||
where
|
where
|
||||||
pos = tokPos $ last tokens
|
pos = tokPos $ last tokens
|
||||||
stmt = case last tokens of
|
stmt = case last tokens of
|
||||||
DTAsgn _ op e -> AsgnBlk op lhs e
|
DTAsgn _ op mt e -> Asgn op mt lhs e
|
||||||
DTAsgnNBlk _ mt e -> Asgn mt lhs e
|
|
||||||
DTInstance _ args -> Subroutine (lhsToExpr lhs) (instanceToArgs args)
|
DTInstance _ args -> Subroutine (lhsToExpr lhs) (instanceToArgs args)
|
||||||
_ -> error $ "invalid block item decl or stmt: " ++ (show tokens)
|
_ -> error $ "invalid block item decl or stmt: " ++ (show tokens)
|
||||||
maybeLhs = takeLHS $ init tokens
|
maybeLhs = takeLHS $ init tokens
|
||||||
Just lhs = maybeLhs
|
Just lhs = maybeLhs
|
||||||
isStmt :: DeclToken -> Bool
|
isStmt :: DeclToken -> Bool
|
||||||
isStmt (DTAsgnNBlk{}) = True
|
|
||||||
isStmt (DTAsgn{}) = True
|
isStmt (DTAsgn{}) = True
|
||||||
isStmt (DTInstance{}) = True
|
isStmt (DTInstance{}) = True
|
||||||
isStmt _ = False
|
isStmt _ = False
|
||||||
|
|
@ -272,20 +269,19 @@ parseDTsAsAsgns tokens =
|
||||||
lhs = case takeLHS lhsToks of
|
lhs = case takeLHS lhsToks of
|
||||||
Nothing -> error $ "could not parse as LHS: " ++ show lhsToks
|
Nothing -> error $ "could not parse as LHS: " ++ show lhsToks
|
||||||
Just l -> l
|
Just l -> l
|
||||||
DTAsgn _ AsgnOpEq expr : l1 = l0
|
DTAsgn _ AsgnOpEq Nothing expr : l1 = l0
|
||||||
asgn = (lhs, expr)
|
asgn = (lhs, expr)
|
||||||
|
|
||||||
isDTAsgn :: DeclToken -> Bool
|
isDTAsgn :: DeclToken -> Bool
|
||||||
isDTAsgn (DTAsgn{}) = True
|
isDTAsgn (DTAsgn _ _ Nothing _) = True
|
||||||
isDTAsgn _ = False
|
isDTAsgn _ = False
|
||||||
|
|
||||||
isAsgnToken :: DeclToken -> Bool
|
isAsgnToken :: DeclToken -> Bool
|
||||||
isAsgnToken (DTBit _ _) = True
|
isAsgnToken (DTBit{} ) = True
|
||||||
isAsgnToken (DTConcat _ _) = True
|
isAsgnToken (DTConcat{}) = True
|
||||||
isAsgnToken (DTStream _ _ _ _) = True
|
isAsgnToken (DTStream{}) = True
|
||||||
isAsgnToken (DTDot _ _) = True
|
isAsgnToken (DTDot{} ) = True
|
||||||
isAsgnToken (DTAsgnNBlk _ _ _) = True
|
isAsgnToken (DTAsgn _ op _ _) = op /= AsgnOpEq
|
||||||
isAsgnToken (DTAsgn _ (AsgnOp _) _) = True
|
|
||||||
isAsgnToken _ = False
|
isAsgnToken _ = False
|
||||||
|
|
||||||
takeLHS :: [DeclToken] -> Maybe LHS
|
takeLHS :: [DeclToken] -> Maybe LHS
|
||||||
|
|
@ -415,8 +411,8 @@ takeRanges (token : tokens) =
|
||||||
DTBit _ s -> (asRange s : rs, rest )
|
DTBit _ s -> (asRange s : rs, rest )
|
||||||
DTAutoDim _ ->
|
DTAutoDim _ ->
|
||||||
case rest of
|
case rest of
|
||||||
(DTAsgn _ AsgnOpEq (Pattern l) : _) -> autoDim l
|
(DTAsgn _ AsgnOpEq Nothing (Pattern l) : _) -> autoDim l
|
||||||
(DTAsgn _ AsgnOpEq (Concat l) : _) -> autoDim l
|
(DTAsgn _ AsgnOpEq Nothing (Concat l) : _) -> autoDim l
|
||||||
_ -> ([] , token : tokens)
|
_ -> ([] , token : tokens)
|
||||||
_ -> ([] , token : tokens)
|
_ -> ([] , token : tokens)
|
||||||
where
|
where
|
||||||
|
|
@ -430,13 +426,15 @@ takeRanges (token : tokens) =
|
||||||
lo = Number "0"
|
lo = Number "0"
|
||||||
hi = Number $ show (n - 1)
|
hi = Number $ show (n - 1)
|
||||||
|
|
||||||
-- Matching DTAsgnNBlk here allows tripLookahead to work both for standard
|
-- Matching `AsgnOpEq` and `AsgnOpNonBlocking` here allows tripLookahead to work
|
||||||
-- declarations and in `parseDTsAsDeclOrStmt`, where we're checking for an
|
-- both for standard declarations and in `parseDTsAsDeclOrStmt`, where we're
|
||||||
-- assignment statement. The other entry points disallow `DTAsgnNBlk`, so this
|
-- checking for an assignment statement. The other entry points disallow
|
||||||
-- doesn't liberalize the parser.
|
-- `AsgnOpNonBlocking`, so this doesn't liberalize the parser.
|
||||||
takeAsgn :: [DeclToken] -> (Maybe Expr, [DeclToken])
|
takeAsgn :: [DeclToken] -> (Maybe Expr, [DeclToken])
|
||||||
takeAsgn (DTAsgn _ AsgnOpEq e : rest) = (Just e , rest)
|
takeAsgn (DTAsgn _ op Nothing e : rest) =
|
||||||
takeAsgn (DTAsgnNBlk _ _ e : rest) = (Just e , rest)
|
if op == AsgnOpEq || op == AsgnOpNonBlocking
|
||||||
|
then (Just e , rest)
|
||||||
|
else (Nothing, rest)
|
||||||
takeAsgn rest = (Nothing, rest)
|
takeAsgn rest = (Nothing, rest)
|
||||||
|
|
||||||
takeComma :: [DeclToken] -> (Bool, [DeclToken])
|
takeComma :: [DeclToken] -> (Bool, [DeclToken])
|
||||||
|
|
@ -460,8 +458,7 @@ isComma _ = False
|
||||||
tokPos :: DeclToken -> Position
|
tokPos :: DeclToken -> Position
|
||||||
tokPos (DTComma p) = p
|
tokPos (DTComma p) = p
|
||||||
tokPos (DTAutoDim p) = p
|
tokPos (DTAutoDim p) = p
|
||||||
tokPos (DTAsgn p _ _) = p
|
tokPos (DTAsgn p _ _ _) = p
|
||||||
tokPos (DTAsgnNBlk p _ _) = p
|
|
||||||
tokPos (DTRange p _) = p
|
tokPos (DTRange p _) = p
|
||||||
tokPos (DTIdent p _) = p
|
tokPos (DTIdent p _) = p
|
||||||
tokPos (DTPSIdent p _ _) = p
|
tokPos (DTPSIdent p _ _) = p
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
module top;
|
||||||
|
logic [4] a, b;
|
||||||
|
always b = #5 a;
|
||||||
|
initial begin
|
||||||
|
a = #1 1;
|
||||||
|
$monitor("%2d %b %b", $time, a, b);
|
||||||
|
#1; a = 0;
|
||||||
|
#1; a = 'he;
|
||||||
|
#1;
|
||||||
|
#10; a = 'h5;
|
||||||
|
#10;
|
||||||
|
$finish;
|
||||||
|
end
|
||||||
|
endmodule
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
module top;
|
||||||
|
reg [0:3] a, b;
|
||||||
|
always b = #5 a;
|
||||||
|
initial begin
|
||||||
|
a = #1 1;
|
||||||
|
$monitor("%2d %b %b", $time, a, b);
|
||||||
|
#1; a = 0;
|
||||||
|
#1; a = 'he;
|
||||||
|
#1;
|
||||||
|
#10; a = 'h5;
|
||||||
|
#10;
|
||||||
|
$finish;
|
||||||
|
end
|
||||||
|
endmodule
|
||||||
Loading…
Reference in New Issue