Skip to content
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

R-value casted structs don't get converted #305

Open
tarik-ibrahimovic opened this issue Feb 14, 2025 · 3 comments
Open

R-value casted structs don't get converted #305

tarik-ibrahimovic opened this issue Feb 14, 2025 · 3 comments

Comments

@tarik-ibrahimovic
Copy link

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
	};
@zachjs
Copy link
Owner

zachjs commented Feb 17, 2025

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?

@tarik-ibrahimovic
Copy link
Author

Here's a simple example for which sv2v carries out the same behavior. sv2v_test_case.zip.

@zachjs
Copy link
Owner

zachjs commented Apr 6, 2025

@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.

  1. sv2v doesn't know what the type is of the pattern assigned to data_out. There are two ways to address this.
    1. Replace output logic data_out with output struct_name_t data_out.
    2. Explicitly cast the struct pattern to struct_name_t.
  2. 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?
  3. Although not relevant to the struct conversion, note that data_out is 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!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants