mirror of https://github.com/YosysHQ/yosys.git
Merge 13ab5d4a67 into 8eb3133076
This commit is contained in:
commit
2450a3636f
|
|
@ -456,21 +456,26 @@ void dump_wire(std::ostream &f, std::string indent, RTLIL::Wire *wire)
|
|||
if (wire->attributes.count(ID::single_bit_vector))
|
||||
range = stringf(" [%d:%d]", wire->start_offset, wire->start_offset);
|
||||
}
|
||||
// Emit `signed` for wires/ports whose RTLIL is_signed flag is set.
|
||||
// Without this, an `output signed [N:0] o` was silently demoted to plain
|
||||
// `output [N:0] o` on write, losing the declared signedness in a
|
||||
// read_verilog -> write_verilog round-trip.
|
||||
const char *signed_kw = wire->is_signed ? " signed" : "";
|
||||
if (wire->port_input && !wire->port_output)
|
||||
f << stringf("%s" "input%s %s;\n", indent, range, id(wire->name));
|
||||
f << stringf("%s" "input%s%s %s;\n", indent, signed_kw, range, id(wire->name));
|
||||
if (!wire->port_input && wire->port_output)
|
||||
f << stringf("%s" "output%s %s;\n", indent, range, id(wire->name));
|
||||
f << stringf("%s" "output%s%s %s;\n", indent, signed_kw, range, id(wire->name));
|
||||
if (wire->port_input && wire->port_output)
|
||||
f << stringf("%s" "inout%s %s;\n", indent, range, id(wire->name));
|
||||
f << stringf("%s" "inout%s%s %s;\n", indent, signed_kw, range, id(wire->name));
|
||||
if (reg_wires.count(wire->name)) {
|
||||
f << stringf("%s" "reg%s %s", indent, range, id(wire->name));
|
||||
f << stringf("%s" "reg%s%s %s", indent, signed_kw, range, id(wire->name));
|
||||
if (wire->attributes.count(ID::init)) {
|
||||
f << stringf(" = ");
|
||||
dump_const(f, wire->attributes.at(ID::init));
|
||||
}
|
||||
f << stringf(";\n");
|
||||
} else
|
||||
f << stringf("%s" "wire%s %s;\n", indent, range, id(wire->name));
|
||||
f << stringf("%s" "wire%s%s %s;\n", indent, signed_kw, range, id(wire->name));
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,33 @@
|
|||
# Roundtrip a module with `signed` ports / wires through read_verilog
|
||||
# and write_verilog and verify the `signed` keyword survives. Before
|
||||
# the fix, write_verilog silently dropped `signed` on every wire / port
|
||||
# declaration, even though wire->is_signed was tracked correctly
|
||||
# through the RTLIL. The IEEE 1364-2001 grammar (Annex A.2.1.2 /
|
||||
# A.2.1.3) allows `signed` after the direction / net-type, which is
|
||||
# the dialect write_verilog targets by default.
|
||||
|
||||
! mkdir -p temp
|
||||
read_verilog <<EOT
|
||||
module top(
|
||||
input signed [9:0] in,
|
||||
input signed s_in,
|
||||
output signed [31:0] o,
|
||||
output signed s_o
|
||||
);
|
||||
wire signed [15:0] w;
|
||||
assign w = in;
|
||||
assign o = w;
|
||||
assign s_o = s_in;
|
||||
endmodule
|
||||
EOT
|
||||
|
||||
write_verilog -noattr temp/write_verilog_signed_port.v
|
||||
|
||||
# Each `signed` declaration must round-trip exactly. Use a non-greedy
|
||||
# grep on the relevant slices (input / output / wire) so any drift
|
||||
# in the surrounding formatting doesn't mask the bug.
|
||||
! grep -E '^\s*input *signed *\[9:0\] +in;' temp/write_verilog_signed_port.v
|
||||
! grep -E '^\s*input *signed +s_in;' temp/write_verilog_signed_port.v
|
||||
! grep -E '^\s*output *signed *\[31:0\] +o;' temp/write_verilog_signed_port.v
|
||||
! grep -E '^\s*output *signed +s_o;' temp/write_verilog_signed_port.v
|
||||
! grep -E '^\s*wire *signed *\[15:0\] +w;' temp/write_verilog_signed_port.v
|
||||
Loading…
Reference in New Issue