R-value casted structs don't get converted
To recreate the issue clone the following repo and follow the provided build steps. The error arises because the particular cast type used in the design is not supported by Yosys's Verilog frontend, leading Yosys to throw an error. Note that the sv2v tool is used as a pre-build hook in FuseSoC to preprocess the source files before they are passed to Yosys. For the exact command line invocation, please refer to the script at sw/sv2vpre.py.
The issue is reocurring and not limited to the example provided below. I'm not sure if this is only a missing feature or a bug.
Example input:
assign axi_lite_resp_o = '{
aw_ready: axi_req_valid[WR] & axi_req_ready[WR], // if AXI AW & W valid & tree gnt_o[WR]
w_ready: axi_req_valid[WR] & axi_req_ready[WR], // if AXI AW & W valid & tree gnt_o[WR]
b: '{resp: axi_bresp}, // from spill reg
b_valid: axi_bresp_valid, // from spill reg
ar_ready: axi_req_valid[RD] & axi_req_ready[RD], // if AXI AR valid and tree gnt[RD]
r: '{data: axi_rresp.data, resp: axi_rresp.resp}, // from spill reg
r_valid: axi_rresp_valid // from spill reg
};
Example output:
assign axi_lite_resp_o = '{
aw_ready: axi_req_valid[WR] & axi_req_ready[WR],
w_ready: axi_req_valid[WR] & axi_req_ready[WR],
b: '{
resp: axi_bresp
},
b_valid: axi_bresp_valid,
ar_ready: axi_req_valid[RD] & axi_req_ready[RD],
r: '{
data: axi_rresp[DataWidth + 1-:((DataWidth + 1) >= 2 ? DataWidth + 0 : 3 - (DataWidth + 1))],
resp: axi_rresp[1-:2]
},
r_valid: axi_rresp_valid
};
Thank you for filing this issue! sv2v absolutely supports struct conversions, including the struct patterns demonstrated here. I would greatly appreciate it if you could narrow down the scale of this reproducer. Ideally, this reproducer would not require outside scripts or software, and would span at most a few files. Do you think that is doable here?
Here's a simple example for which sv2v carries out the same behavior. sv2v_test_case.zip.
@tarik-ibrahimovic Thank you for sharing this example!
There are a couple issues I spotted in the example (pasted below). Note that these issues aren't specific to sv2v; commercial tools complain too.
- sv2v doesn't know what the type is of the pattern assigned to
data_out. There are two ways to address this.- Replace
output logic data_outwithoutput struct_name_t data_out. - Explicitly cast the struct pattern to
struct_name_t.
- Replace
- The nested struct (
b_valid: '{b_valid: struct_name.b_valid}) is also untyped, and so can't be converted for the same reasons as (1). Is the type of that struct defined somewhere else? - Although not relevant to the struct conversion, note that
data_outis smaller than the value assigned to it.
module test(
input logic clk,
input logic rst_n,
input logic [7:0] data_in,
output logic data_out
);
typedef struct {
logic aw_ready;
logic w_ready;
logic b_valid;
} struct_name_t;
struct_name_t struct_name;
always_ff @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
struct_name.aw_ready <= 1'b0;
struct_name.w_ready <= 1'b0;
struct_name.b_valid <= 1'b0;
end else begin
struct_name.aw_ready <= data_in[2];
struct_name.w_ready <= data_in[1];
struct_name.b_valid <= data_in[0];
end
end
assign data_out = '{
aw_ready: struct_name.aw_ready,
w_ready: struct_name.w_ready,
b_valid: '{b_valid: struct_name.b_valid}
};
endmodule
All that said, it is of course still possible there is a bug in sv2v. (It wouldn't be the first!) However, I would still appreciate your help in creating a reproducer for the issue you've encountered. Thank you!