support procedural continuous assignments

This commit is contained in:
Zachary Snow 2022-05-10 12:11:32 -04:00
parent e778a671e1
commit effeded6d1
5 changed files with 44 additions and 1 deletions

View File

@ -13,6 +13,8 @@
* Added support for complex event expressions (e.g., `@(x ^ y)`)
* Added support for the SystemVerilog `edge` event
* Added support for cycle delay ranges in assertion sequence expressions
* Added support for procedural continuous assignments (`assign`/`deassign` and
`force`/`release`)
* Added conversion for `do` `while` loops
* Added support for passing through DPI imports and exports
* Added support for passing through functions with output ports

View File

@ -255,6 +255,7 @@ traverseSinglyNestedStmtsM fullMapper = cs
cs (Return expr) = return $ Return expr
cs (Subroutine expr exprs) = return $ Subroutine expr exprs
cs (Trigger blocks x) = return $ Trigger blocks x
cs stmt@Force{} = return stmt
cs (Assertion a) =
traverseAssertionStmtsM fullMapper a >>= return . Assertion
cs (Continue) = return Continue
@ -374,6 +375,8 @@ traverseStmtLHSsM mapper = stmtMapper
lhss' <- mapM fullMapper lhss
let incrs' = zip3 lhss' asgnOps exprs
return $ For inits' me incrs' stmt
stmtMapper (Force kw l e) =
fullMapper l >>= \l' -> return $ Force kw l' e
stmtMapper other = return other
traverseStmtLHSs :: Mapper LHS -> Mapper Stmt
@ -682,6 +685,10 @@ traverseStmtExprsM exprMapper = flatStmtMapper
flatStmtMapper (Return expr) =
exprMapper expr >>= return . Return
flatStmtMapper (Trigger blocks x) = return $ Trigger blocks x
flatStmtMapper (Force kw l e) = do
l' <- lhsMapper l
e' <- exprMapper e
return $ Force kw l' e'
flatStmtMapper (Assertion a) =
traverseAssertionExprsM exprMapper a >>= return . Assertion
flatStmtMapper (Continue) = return Continue
@ -1075,6 +1082,9 @@ traverseStmtAsgnsM mapper = stmtMapper
stmtMapper (Asgn op mt lhs expr) = do
(lhs', expr') <- mapper (lhs, expr)
return $ Asgn op mt lhs' expr'
stmtMapper (Force kw lhs expr) | expr /= Nil = do
(lhs', expr') <- mapper (lhs, expr)
return $ Force kw lhs' expr'
stmtMapper other = return other
traverseStmtAsgns :: Mapper (LHS, Expr) -> Mapper Stmt

View File

@ -31,7 +31,7 @@ import Text.Printf (printf)
import Language.SystemVerilog.AST.ShowHelp (commas, indent, unlines', showPad, showBlock)
import Language.SystemVerilog.AST.Attr (Attr)
import Language.SystemVerilog.AST.Decl (Decl)
import Language.SystemVerilog.AST.Expr (Expr(Call, Ident, Nil), Args(..), Range, showRange)
import Language.SystemVerilog.AST.Expr (Expr(Call, Ident, Nil), Args(..), Range, showRange, showAssignment)
import Language.SystemVerilog.AST.LHS (LHS)
import Language.SystemVerilog.AST.Op (AsgnOp(AsgnOpEq))
import Language.SystemVerilog.AST.Type (Identifier)
@ -53,6 +53,7 @@ data Stmt
| Subroutine Expr Args
| Trigger Bool Identifier
| Assertion Assertion
| Force Bool LHS Expr
| Continue
| Break
| Null
@ -98,6 +99,13 @@ instance Show Stmt where
show (Timing t s) = printf "%s%s" (show t) (showShortBranch s)
show (Trigger b x) = printf "->%s %s;" (if b then "" else ">") x
show (Assertion a) = show a
show (Force kw l e) = printf "%s %s%s;" kwStr (show l) (showAssignment e)
where
kwStr = case (kw, e /= Nil) of
(True , True ) -> "force"
(True , False) -> "release"
(False, True ) -> "assign"
(False, False) -> "deassign"
show (Continue ) = "continue;"
show (Break ) = "break;"
show (Null ) = ";"

View File

@ -1134,6 +1134,10 @@ StmtNonBlock :: { Stmt }
| AttributeInstance Stmt { StmtAttr $1 $2 }
| ProceduralAssertionStatement { Assertion $1 }
| "void" "'" "(" Expr CallArgs ")" ";" { Subroutine $4 $5 }
| "assign" LHS "=" Expr ";" { Force False $2 $4 }
| "deassign" LHS ";" { Force False $2 Nil }
| "force" LHS "=" Expr ";" { Force True $2 $4 }
| "release" LHS ";" { Force True $2 Nil }
OptDelayOrEvent :: { Maybe Timing }
: DelayOrEvent { Just $1 }

19
test/basic/force.sv Normal file
View File

@ -0,0 +1,19 @@
module top;
reg [1:0] a, b;
wire [1:0] c, d;
initial begin
$monitor("%2d %b %b %b %b", $time, a, b, c, d);
#1 force c = 1;
#1 release c;
#1 force c = b;
#1 force d = a;
#1 release c;
#1 assign a = 1;
#1 assign a = 3;
#1 assign b = 2;
#1 a = 0;
#1 deassign a;
#1 a = 0;
#1 release d;
end
endmodule