m-labs / migen

A Python toolbox for building complex digital hardware
https://m-labs.hk/migen
Other
1.23k stars 210 forks source link

Subvector of Cat() incorrect assignment #275

Closed noiuynoise closed 1 year ago

noiuynoise commented 1 year ago

When a subvector of a Cat is assigned a value, the rest of the vector is written over with zeros. This results in only the last assignment actually taking effect.

Here is an example:

from migen import *
from migen.fhdl import verilog

class Example(Module):
    def __init__(self):

        a = Signal(4)
        b = Signal(4)
        c = Signal(4)

        z = Cat(a, b, c)
        self.comb += z[:7].eq(1)
        self.comb += z[7:].eq(1)

if __name__ == "__main__":
    print(verilog.convert(Example()))

generates the output :

/* Machine-generated using Migen */
module top(

);

reg [3:0] a;
reg [3:0] b;
reg [3:0] c;
wire [11:0] slice_proxy0;
wire [11:0] slice_proxy1;

// synthesis translate_off
reg dummy_s;
initial dummy_s <= 1'd0;
// synthesis translate_on

assign slice_proxy0[6:0] = 1'd1;
assign slice_proxy1[11:7] = 1'd1;

// synthesis translate_off
reg dummy_d;
// synthesis translate_on
always @(*) begin
    a <= 4'd0;
    b <= 4'd0;
    c <= 4'd0;
    {c, b, a} <= slice_proxy0;
    {c, b, a} <= slice_proxy1;
// synthesis translate_off
    dummy_d <= dummy_s;
// synthesis translate_on
end

endmodule

Since slice_proxy0 and slice_proxy1 are the same length as the concatenated vector and filled in with zeros the first assignment is overwritten by the second and the lower bits in this example do not change correctly.

If a proxy signal is inserted in place of the raw concatenation the python code the generated output will behave correctly but I believe this also inserts an unnecessary register vector depending on the synthesis tools.

jordens commented 1 year ago

20