calyx icon indicating copy to clipboard operation
calyx copied to clipboard

Refactor `std_fp_div_pipe` primitive to avoid Verilog features not supported by Icarus

Open KarlJoad opened this issue 1 year ago • 8 comments
trafficstars

It seems that portions of Calyx's standard library written in SystemVerilog is not able to be simulated by Icarus.

[nix-shell:~/Repos/calyx] 11:12:38 $ iverilog -v
Icarus Verilog version 12.0 (stable) ()

...

Taking a unit-test circuit from Cider and running it through fud2, we get the following plan, which I then execute.

[nix-shell:~/Repos/calyx] 11:25:19 $ ./target/debug/fud2 -m plan ./interp/tests/complex/unsigned-dot-product.futil --from calyx -o test.exe --through icarus -s sim.data=./interp/tests/complex/unsigned-dot-product.futil.data --keep
calyx-noverify: interp/tests/complex/unsigned-dot-product.futil -> verilog-noverify.sv
icarus: verilog-noverify.sv -> test.exe

[nix-shell:~/Repos/calyx] 11:25:31 $ ./target/debug/fud2 ./interp/tests/complex/unsigned-dot-product.futil --from calyx -o test.exe --through icarus -s sim.data=./interp/tests/complex/unsigned-dot-product.futil.data --keep
[WARN  calyx_frontend::attribute] The attribute @static is deprecated and will be ignored by the compiler.
[WARN  calyx_frontend::attribute] The attribute @static is deprecated and will be ignored by the compiler.
[WARN  calyx_frontend::attribute] The attribute @static is deprecated and will be ignored by the compiler.
[WARN  calyx_frontend::attribute] The attribute @static is deprecated and will be ignored by the compiler.
verilog-noverify.sv:149: sorry: constant selects in always_* processes are not currently supported (all bits will be included).

The error on line 149 is coming from:

/* verilator lint_off WIDTH */
module std_fp_div_pipe #(
  parameter WIDTH = 32,
  parameter INT_WIDTH = 16,
  parameter FRAC_WIDTH = 16
) (
    input  logic             go,
    input  logic             clk,
    input  logic             reset,
    input  logic [WIDTH-1:0] left,
    input  logic [WIDTH-1:0] right,
    output logic [WIDTH-1:0] out_remainder,
    output logic [WIDTH-1:0] out_quotient,
    output logic             done
);
    localparam ITERATIONS = WIDTH + FRAC_WIDTH;

    logic [WIDTH-1:0] quotient, quotient_next;
    logic [WIDTH:0] acc, acc_next;
    logic [$clog2(ITERATIONS)-1:0] idx;
    logic start, running, finished, dividend_is_zero;

    // Omitted for brevity

    // always_comb is the problem.
    always_comb begin
      if (acc >= {1'b0, right}) begin
        acc_next = acc - right;
        {acc_next, quotient_next} = {acc_next[WIDTH-1:0], quotient, 1'b1};
      end else begin
        {acc_next, quotient_next} = {acc, quotient} << 1;
      end
    end

    // Omitted for brevity
endmodule

The Calyx component's output Verilog that being simulated is attached below. (It is a .txt to allow me to upload to GitHub.) verilog-noverify.txt

KarlJoad avatar Aug 07 '24 18:08 KarlJoad