-
Notifications
You must be signed in to change notification settings - Fork 439
[ImportVerilog] Implement procedural continuous assignment #9795
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -390,6 +390,14 @@ class DelayedAssignOpBase<string mnemonic, list<Trait> traits = []> : | |
| }]; | ||
| } | ||
|
|
||
| class DeassignOpBase<string mnemonic, list<Trait> traits = []> : | ||
| MooreOp<mnemonic, traits> { | ||
| let arguments = (ins RefType:$dst); | ||
| let assemblyFormat = [{ | ||
| $dst attr-dict `:` type($dst) | ||
| }]; | ||
| } | ||
|
|
||
| // Continuous assignment | ||
|
|
||
| def ContinuousAssignOp : AssignOpBase<"assign", [HasParent<"SVModuleOp">]> { | ||
|
|
@@ -459,6 +467,68 @@ def DelayedNonBlockingAssignOp : | |
| }]; | ||
| } | ||
|
|
||
| // Procedural continuous assignment | ||
|
|
||
| def ProceduralContinuousAssignOp : AssignOpBase<"procedural_assign", [ | ||
| HasParent<"ProcedureOp"> | ||
| ]> { | ||
| let summary = "Procedural continuous assignment (keyword: assign)"; | ||
| let description = [{ | ||
| A continuous assignment in procedure scope, such as `assign x = y;`, which | ||
| continuously drives the value on the right-hand side onto the LHS. | ||
|
|
||
| LHS of assignment is a variable reference or a concatenation of variables. | ||
|
|
||
| See IEEE 1800-2023 § 10.6.1 "The assign and deassign procedural statements". | ||
| }]; | ||
| } | ||
|
|
||
| def ProceduralContinuousForceOp : AssignOpBase<"force", [ | ||
| HasParent<"ProcedureOp"> | ||
| ]> { | ||
| let summary = "Procedural continuous assignment (keyword: force)"; | ||
| let description = [{ | ||
| A continuous assignment in procedure scope, such as `force x = y;`, which | ||
| continuously drives the value on the right-hand side onto the LHS. | ||
|
|
||
| LHS of assignment is a variable reference, a net, a constant bit-select or | ||
| part-select of a vector net, or a concatenation of these. | ||
|
|
||
| It overrides an `assign` procedural continuous assignment. | ||
|
|
||
| See IEEE 1800-2023 § 10.6.2 "The force and release procedural statements". | ||
| }]; | ||
| } | ||
|
|
||
| def ProceduralContinuousDeassignOp : DeassignOpBase<"procedural_deassign", [ | ||
| HasParent<"ProcedureOp"> | ||
| ]> { | ||
| let summary = "Procedural continuous deassignment (keyword: deassign)"; | ||
| let description = [{ | ||
| Deassignment of a continuous assignment in procedure scope, such as `deassign x;`. | ||
|
|
||
| The value of the variable shall remain the same until the variable is assigned a | ||
| new value (through a procedural or procedural continuous assignment). | ||
|
|
||
| See IEEE 1800-2023 § 10.6.1 "The assign and deassign procedural statements". | ||
| }]; | ||
| } | ||
|
|
||
| def ProceduralContinuousReleaseOp : DeassignOpBase<"release", [ | ||
| HasParent<"ProcedureOp"> | ||
| ]> { | ||
| let summary = "Procedural continuous deassignment (keyword: release)"; | ||
| let description = [{ | ||
| Deassignment of a continuous assignment in procedure scope, such as `release x;`. | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As above, could we clarify the semantic difference between this and deassign in this paragraph? |
||
|
|
||
| If the variable is driven by a continuous assignment or currently has an active | ||
| `assign` procedural continuous assignment, then it shall re-establish that | ||
| assignment. Otherwise, | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Looks like there's some missing text here? |
||
|
|
||
| See IEEE 1800-2023 § 10.6.2 "The force and release procedural statements". | ||
| }]; | ||
| } | ||
|
|
||
| //===----------------------------------------------------------------------===// | ||
| // Statements | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -1088,6 +1088,46 @@ struct StmtVisitor { | |
| return success(); | ||
| } | ||
|
|
||
| // Handle procedural continuous assignment. | ||
| LogicalResult visit(const slang::ast::ProceduralAssignStatement &assignNode) { | ||
| const auto &expr = | ||
| assignNode.assignment.as<slang::ast::AssignmentExpression>(); | ||
|
|
||
| auto lhs = context.convertLvalueExpression(expr.left()); | ||
| if (!lhs) | ||
| return failure(); | ||
|
|
||
| auto rhs = context.convertRvalueExpression( | ||
| expr.right(), cast<moore::RefType>(lhs.getType()).getNestedType()); | ||
| if (!rhs) | ||
| return failure(); | ||
|
|
||
| if (assignNode.isForce) { | ||
| moore::ProceduralContinuousForceOp::create(builder, loc, lhs, rhs); | ||
| } else { | ||
| // TODO: prohibit net-type lhs | ||
| moore::ProceduralContinuousAssignOp::create(builder, loc, lhs, rhs); | ||
| } | ||
|
|
||
| return success(); | ||
| } | ||
|
|
||
| // Handle procedural continuous deassignment. | ||
| LogicalResult | ||
| visit(const slang::ast::ProceduralDeassignStatement &deassignNode) { | ||
| auto lhs = context.convertLvalueExpression(deassignNode.lvalue); | ||
| if (!lhs) | ||
| return failure(); | ||
|
|
||
| if (deassignNode.isRelease) { | ||
| moore::ProceduralContinuousReleaseOp::create(builder, loc, lhs); | ||
| } else { | ||
| moore::ProceduralContinuousDeassignOp::create(builder, loc, lhs); | ||
| } | ||
|
Comment on lines
+1122
to
+1126
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nit: we can drop the braces here |
||
|
|
||
| return success(); | ||
| } | ||
|
|
||
| /// Emit an error for all other statements. | ||
| template <typename T> | ||
| LogicalResult visit(T &&stmt) { | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: could we move this up to the first sentence to make the semantic difference a bit clearer?