Skip to content

Commit

Permalink
verilog: indirect AST_CONCAT and AST_TO_UNSIGNED port connections
Browse files Browse the repository at this point in the history
- AST_CONCAT and AST_TO_UNSIGNED are always unsigned, but may generate
  RTLIL that exclusively reference a signed wire.
- AST_CONCAT may also contain a memory write.
  • Loading branch information
zachjs committed Apr 14, 2024
1 parent b827b98 commit bfb88f3
Show file tree
Hide file tree
Showing 6 changed files with 73 additions and 9 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@ List of major changes and improvements between releases
Yosys 0.40 .. Yosys 0.41-dev
--------------------------

* Verilog
- Fixed an issue that prevented using `{<expr>}` or `$unsigned(<expr>)` for
certain signed expressions in port connections
- Fixed an issue that prevented writing to a memory word via a concatenation
in an output port connection

Yosys 0.39 .. Yosys 0.40
--------------------------
* New commands and options
Expand Down
8 changes: 3 additions & 5 deletions frontends/ast/genrtlil.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2124,11 +2124,9 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
if (sig.is_wire()) {
// if the resulting SigSpec is a wire, its
// signedness should match that of the AstNode
if (arg->type == AST_IDENTIFIER && arg->id2ast && arg->id2ast->is_signed && !arg->is_signed)
// fully-sliced signed wire will be resolved
// once the module becomes available
log_assert(attributes.count(ID::reprocess_after));
else
// unless this instantiation depends on module
// information that isn't available yet
if (!attributes.count(ID::reprocess_after))
log_assert(arg->is_signed == sig.as_wire()->is_signed);
} else if (arg->is_signed) {
// non-trivial signed nodes are indirected through
Expand Down
6 changes: 6 additions & 0 deletions frontends/ast/simplify.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1292,6 +1292,12 @@ bool AstNode::simplify(bool const_fold, int stage, int width_hint, bool sign_hin
else if (contains_unbased_unsized(value))
// unbased unsized literals extend to width of the context
lookup_suggested = true;
else if (value->type == AST_TO_UNSIGNED)
// inner expression may be signed by default
lookup_suggested = true;
else if (value->type == AST_CONCAT && value->children.size() == 1)
// concat of a single expression is equivalent to $unsigned
lookup_suggested = true;
}
}

Expand Down
10 changes: 6 additions & 4 deletions tests/simple/memwr_port_connection.sv
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@ module producer(
endmodule

module top(
output logic [3:0] out
output logic [3:0] out0, out1
);
logic [3:0] v[0:0];
producer p(v[0]);
assign out = v[0];
logic [3:0] v[1:0];
producer p0(v[0]);
producer p1({v[1]});
assign out0 = v[0];
assign out1 = v[1];
endmodule
45 changes: 45 additions & 0 deletions tests/verilog/signed_concat.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
`define OUTPUTS(mode) \
o``mode``0, \
o``mode``1, \
o``mode``2, \
o``mode``3, \
o``mode``4

module gate(
input [1:0] iu,
input signed [1:0] is,
output [2:0] `OUTPUTS(u),
output signed [2:0] `OUTPUTS(s)
);
`define INSTANCES(mode) \
mod m``mode``0({i``mode}, {o``mode``0}); \
mod m``mode``1($unsigned(i``mode), o``mode``1); \
mod m``mode``2({i``mode[1:0]}, o``mode``2); \
mod m``mode``3({$signed(i``mode)}, o``mode``3); \
mod m``mode``4($unsigned({i``mode}), o``mode``4);
`INSTANCES(u)
`INSTANCES(s)
`undef INSTANCES
endmodule

module gold(
input [1:0] iu, is,
output [2:0] `OUTPUTS(u), `OUTPUTS(s)
);
`define INSTANCES(mode) \
assign o``mode``0 = i``mode; \
assign o``mode``1 = i``mode; \
assign o``mode``2 = i``mode; \
assign o``mode``3 = i``mode; \
assign o``mode``4 = i``mode;
`INSTANCES(u)
`INSTANCES(s)
`undef INSTANCES
endmodule

module mod(
input [2:0] inp,
output [2:0] out
);
assign out = inp;
endmodule
7 changes: 7 additions & 0 deletions tests/verilog/signed_concat.ys
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
read_verilog signed_concat.v
hierarchy
proc
flatten gate
equiv_make gold gate equiv
equiv_simple
equiv_status -assert

0 comments on commit bfb88f3

Please sign in to comment.