YosysHQ / yosys

Yosys Open SYnthesis Suite
https://yosyshq.net/yosys/
ISC License
3.31k stars 860 forks source link

Extreme logic usage #4293

Closed rowanG077 closed 3 months ago

rowanG077 commented 3 months ago

Version

Yosys 0.39+124 (git sha1 d73f71e813d, g++ 12.2.0 -fPIC -Os)

On which OS did this happen?

Linux

Reproduction Steps

I was very surprised to see an extremely high logic usage for a CRC32 validator generated via litex. I have cut it down to the essentials. Synthesize the following module using synth_ecp5 -top crc32_validator

module crc32_validator (
    input  wire   [31:0] data,
    output reg           error,
    input  wire    [3:0] last_be,
    input  wire          sys_clock,
    input  wire          sys_reset,
    input  wire          valid
);

reg           ce = 1'd0;
reg    [31:0] data0 = 32'd0;
reg    [31:0] data1 = 32'd0;
reg           error_1 = 1'd0;
reg     [3:0] last_be0 = 4'd0;
reg     [3:0] last_be1 = 4'd0;
reg    [31:0] next = 32'd0;
reg    [31:0] crc_reg = 32'd4294967295;
reg          sys_rst;

always @(*) begin
    last_be1 <= 4'd0;
    if ((last_be0 != 1'd0)) begin
        last_be1 <= last_be0;
    end else begin
        last_be1 <= 4'd8;
    end

    data1 <= 32'd0;
    error_1 <= 1'd0;

    if (last_be1[0]) begin
        data1 <= data0[7:0];
        error_1 <= (next != 32'd2164574534);
    end
    if (last_be1[1]) begin
        data1 <= data0[15:0];
        error_1 <= (next != 30'd981122162);
    end
    if (last_be1[2]) begin
        data1 <= data0[23:0];
        error_1 <= (next != 31'd1192278940);
    end
    if (last_be1[3]) begin
        data1 <= data0[31:0];
        error_1 <= (next != 32'd3338984827);
    end

    next[0] <= crc_reg[0] ^ crc_reg[24] ^ data1[7] ^ crc_reg[29] ^ data1[2] ^ crc_reg[28] ^ data1[3] ^ crc_reg[10] ^ crc_reg[26] ^ data1[5] ^ data1[21] ^ crc_reg[9] ^ crc_reg[25] ^ data1[6] ^ data1[22] ^ crc_reg[6] ^ crc_reg[30] ^ data1[1] ^ crc_reg[16] ^ data1[15] ^ crc_reg[31] ^ data1[0] ^ crc_reg[12] ^ data1[19] ^ data1[25] ^ data1[31];
    next[1] <= crc_reg[1] ^ crc_reg[11] ^ crc_reg[27] ^ data1[4] ^ data1[20] ^ crc_reg[7] ^ crc_reg[17] ^ data1[14] ^ crc_reg[13] ^ data1[18] ^ data1[24] ^ data1[30] ^ crc_reg[0] ^ crc_reg[24] ^ data1[7] ^ crc_reg[28] ^ data1[3] ^ crc_reg[9] ^ data1[22] ^ crc_reg[6] ^ crc_reg[16] ^ data1[15] ^ crc_reg[12] ^ data1[19] ^ data1[25] ^ data1[31];
    next[2] <= crc_reg[2] ^ crc_reg[8] ^ crc_reg[18] ^ data1[13] ^ crc_reg[14] ^ data1[17] ^ data1[23] ^ data1[29] ^ crc_reg[1] ^ crc_reg[7] ^ crc_reg[17] ^ data1[14] ^ crc_reg[13] ^ data1[18] ^ data1[24] ^ data1[30] ^ crc_reg[0] ^ crc_reg[24] ^ data1[7] ^ crc_reg[26] ^ data1[5] ^ crc_reg[9] ^ data1[22] ^ crc_reg[6] ^ crc_reg[30] ^ data1[1] ^ crc_reg[16] ^ data1[15] ^ crc_reg[31] ^ data1[0] ^ data1[25] ^ data1[31];
    next[3] <= crc_reg[3] ^ crc_reg[9] ^ crc_reg[19] ^ data1[12] ^ crc_reg[15] ^ data1[16] ^ data1[22] ^ data1[28] ^ crc_reg[2] ^ crc_reg[8] ^ crc_reg[18] ^ data1[13] ^ crc_reg[14] ^ data1[17] ^ data1[23] ^ data1[29] ^ crc_reg[1] ^ crc_reg[25] ^ data1[6] ^ crc_reg[27] ^ data1[4] ^ crc_reg[10] ^ data1[21] ^ crc_reg[7] ^ crc_reg[31] ^ data1[0] ^ crc_reg[17] ^ data1[14] ^ data1[24] ^ data1[30];
    next[4] <= crc_reg[4] ^ crc_reg[20] ^ data1[11] ^ data1[27] ^ crc_reg[3] ^ crc_reg[19] ^ data1[12] ^ crc_reg[15] ^ data1[16] ^ data1[28] ^ crc_reg[2] ^ crc_reg[11] ^ data1[20] ^ crc_reg[8] ^ crc_reg[18] ^ data1[13] ^ data1[23] ^ data1[29] ^ crc_reg[0] ^ crc_reg[24] ^ data1[7] ^ crc_reg[29] ^ data1[2] ^ crc_reg[25] ^ data1[6] ^ crc_reg[6] ^ crc_reg[30] ^ data1[1] ^ crc_reg[31] ^ data1[0] ^ crc_reg[12] ^ data1[19] ^ data1[25] ^ data1[31];
    next[5] <= crc_reg[5] ^ crc_reg[21] ^ data1[10] ^ data1[26] ^ crc_reg[4] ^ crc_reg[20] ^ data1[11] ^ data1[27] ^ crc_reg[3] ^ crc_reg[19] ^ data1[12] ^ data1[28] ^ crc_reg[1] ^ crc_reg[7] ^ crc_reg[13] ^ data1[18] ^ data1[24] ^ data1[30] ^ crc_reg[0] ^ crc_reg[24] ^ data1[7] ^ crc_reg[29] ^ data1[2] ^ crc_reg[28] ^ data1[3] ^ crc_reg[10] ^ data1[21] ^ crc_reg[6] ^ data1[25] ^ data1[31];
    next[6] <= crc_reg[6] ^ crc_reg[22] ^ data1[9] ^ data1[25] ^ crc_reg[5] ^ crc_reg[21] ^ data1[10] ^ data1[26] ^ crc_reg[4] ^ crc_reg[20] ^ data1[11] ^ data1[27] ^ crc_reg[2] ^ crc_reg[8] ^ crc_reg[14] ^ data1[17] ^ data1[23] ^ data1[29] ^ crc_reg[1] ^ crc_reg[25] ^ data1[6] ^ crc_reg[30] ^ data1[1] ^ crc_reg[29] ^ data1[2] ^ crc_reg[11] ^ data1[20] ^ crc_reg[7] ^ data1[24] ^ data1[30];
    next[7] <= crc_reg[7] ^ crc_reg[23] ^ data1[8] ^ data1[24] ^ crc_reg[22] ^ data1[9] ^ crc_reg[5] ^ crc_reg[21] ^ data1[10] ^ data1[26] ^ crc_reg[3] ^ crc_reg[15] ^ data1[16] ^ data1[28] ^ crc_reg[2] ^ crc_reg[8] ^ data1[23] ^ data1[29] ^ crc_reg[0] ^ crc_reg[24] ^ data1[7] ^ crc_reg[29] ^ data1[2] ^ crc_reg[28] ^ data1[3] ^ crc_reg[10] ^ data1[21] ^ crc_reg[25] ^ data1[6] ^ crc_reg[16] ^ data1[15] ^ data1[31];
    next[8] <= crc_reg[8] ^ data1[23] ^ crc_reg[23] ^ data1[8] ^ crc_reg[22] ^ data1[9] ^ crc_reg[4] ^ data1[27] ^ crc_reg[3] ^ data1[28] ^ crc_reg[1] ^ crc_reg[11] ^ data1[20] ^ crc_reg[17] ^ data1[14] ^ data1[30] ^ crc_reg[0] ^ crc_reg[28] ^ data1[3] ^ crc_reg[10] ^ data1[21] ^ crc_reg[31] ^ data1[0] ^ crc_reg[12] ^ data1[19] ^ data1[31];
    next[9] <= crc_reg[9] ^ data1[22] ^ crc_reg[24] ^ data1[7] ^ crc_reg[23] ^ data1[8] ^ crc_reg[5] ^ data1[26] ^ crc_reg[4] ^ data1[27] ^ crc_reg[2] ^ crc_reg[12] ^ data1[19] ^ crc_reg[18] ^ data1[13] ^ data1[29] ^ crc_reg[1] ^ crc_reg[29] ^ data1[2] ^ crc_reg[11] ^ data1[20] ^ crc_reg[13] ^ data1[18] ^ data1[30];
    next[10] <= crc_reg[5] ^ data1[26] ^ crc_reg[3] ^ crc_reg[13] ^ data1[18] ^ crc_reg[19] ^ data1[12] ^ data1[28] ^ crc_reg[2] ^ crc_reg[14] ^ data1[17] ^ data1[29] ^ crc_reg[0] ^ crc_reg[29] ^ data1[2] ^ crc_reg[28] ^ data1[3] ^ crc_reg[26] ^ data1[5] ^ crc_reg[9] ^ data1[22] ^ crc_reg[16] ^ data1[15] ^ crc_reg[31] ^ data1[0] ^ data1[31];
    next[11] <= crc_reg[4] ^ crc_reg[14] ^ data1[17] ^ crc_reg[20] ^ data1[11] ^ data1[27] ^ crc_reg[3] ^ crc_reg[15] ^ data1[16] ^ data1[28] ^ crc_reg[1] ^ crc_reg[27] ^ data1[4] ^ crc_reg[17] ^ data1[14] ^ data1[30] ^ crc_reg[0] ^ crc_reg[24] ^ data1[7] ^ crc_reg[28] ^ data1[3] ^ crc_reg[26] ^ data1[5] ^ crc_reg[9] ^ crc_reg[25] ^ data1[6] ^ data1[22] ^ crc_reg[16] ^ data1[15] ^ crc_reg[31] ^ data1[0] ^ crc_reg[12] ^ data1[19] ^ data1[31];
    next[12] <= crc_reg[5] ^ crc_reg[15] ^ data1[16] ^ crc_reg[21] ^ data1[10] ^ data1[26] ^ crc_reg[4] ^ data1[27] ^ crc_reg[2] ^ crc_reg[18] ^ data1[13] ^ data1[29] ^ crc_reg[1] ^ crc_reg[27] ^ data1[4] ^ crc_reg[17] ^ data1[14] ^ crc_reg[13] ^ data1[18] ^ data1[30] ^ crc_reg[0] ^ crc_reg[24] ^ data1[7] ^ crc_reg[9] ^ data1[22] ^ crc_reg[6] ^ crc_reg[30] ^ data1[1] ^ crc_reg[31] ^ data1[0] ^ crc_reg[12] ^ data1[19] ^ data1[25] ^ data1[31];
    next[13] <= crc_reg[6] ^ crc_reg[16] ^ data1[15] ^ crc_reg[22] ^ data1[9] ^ data1[25] ^ crc_reg[5] ^ data1[26] ^ crc_reg[3] ^ crc_reg[19] ^ data1[12] ^ data1[28] ^ crc_reg[2] ^ crc_reg[28] ^ data1[3] ^ crc_reg[18] ^ data1[13] ^ crc_reg[14] ^ data1[17] ^ data1[29] ^ crc_reg[1] ^ crc_reg[25] ^ data1[6] ^ crc_reg[10] ^ data1[21] ^ crc_reg[7] ^ crc_reg[31] ^ data1[0] ^ crc_reg[13] ^ data1[18] ^ data1[24] ^ data1[30];
    next[14] <= crc_reg[7] ^ crc_reg[17] ^ data1[14] ^ crc_reg[23] ^ data1[8] ^ data1[24] ^ crc_reg[6] ^ data1[25] ^ crc_reg[4] ^ crc_reg[20] ^ data1[11] ^ data1[27] ^ crc_reg[3] ^ crc_reg[29] ^ data1[2] ^ crc_reg[19] ^ data1[12] ^ crc_reg[15] ^ data1[16] ^ data1[28] ^ crc_reg[2] ^ crc_reg[26] ^ data1[5] ^ crc_reg[11] ^ data1[20] ^ crc_reg[8] ^ crc_reg[14] ^ data1[17] ^ data1[23] ^ data1[29];
    next[15] <= crc_reg[8] ^ crc_reg[18] ^ data1[13] ^ crc_reg[24] ^ data1[7] ^ data1[23] ^ crc_reg[7] ^ data1[24] ^ crc_reg[5] ^ crc_reg[21] ^ data1[10] ^ data1[26] ^ crc_reg[4] ^ crc_reg[30] ^ data1[1] ^ crc_reg[20] ^ data1[11] ^ crc_reg[16] ^ data1[15] ^ data1[27] ^ crc_reg[3] ^ crc_reg[27] ^ data1[4] ^ crc_reg[12] ^ data1[19] ^ crc_reg[9] ^ crc_reg[15] ^ data1[16] ^ data1[22] ^ data1[28];
    next[16] <= crc_reg[19] ^ data1[12] ^ crc_reg[8] ^ data1[23] ^ crc_reg[22] ^ data1[9] ^ crc_reg[5] ^ crc_reg[21] ^ data1[10] ^ crc_reg[17] ^ data1[14] ^ data1[26] ^ crc_reg[4] ^ crc_reg[13] ^ data1[18] ^ data1[27] ^ crc_reg[0] ^ crc_reg[24] ^ data1[7] ^ crc_reg[29] ^ data1[2] ^ crc_reg[26] ^ data1[5] ^ crc_reg[30] ^ data1[1] ^ crc_reg[12] ^ data1[19] ^ data1[31];
    next[17] <= crc_reg[20] ^ data1[11] ^ crc_reg[9] ^ data1[22] ^ crc_reg[23] ^ data1[8] ^ crc_reg[6] ^ crc_reg[22] ^ data1[9] ^ crc_reg[18] ^ data1[13] ^ data1[25] ^ crc_reg[5] ^ crc_reg[14] ^ data1[17] ^ data1[26] ^ crc_reg[1] ^ crc_reg[25] ^ data1[6] ^ crc_reg[30] ^ data1[1] ^ crc_reg[27] ^ data1[4] ^ crc_reg[31] ^ data1[0] ^ crc_reg[13] ^ data1[18] ^ data1[30];
    next[18] <= crc_reg[21] ^ data1[10] ^ crc_reg[10] ^ data1[21] ^ crc_reg[24] ^ data1[7] ^ crc_reg[7] ^ crc_reg[23] ^ data1[8] ^ crc_reg[19] ^ data1[12] ^ data1[24] ^ crc_reg[6] ^ crc_reg[15] ^ data1[16] ^ data1[25] ^ crc_reg[2] ^ crc_reg[26] ^ data1[5] ^ crc_reg[31] ^ data1[0] ^ crc_reg[28] ^ data1[3] ^ crc_reg[14] ^ data1[17] ^ data1[29];
    next[19] <= crc_reg[22] ^ data1[9] ^ crc_reg[11] ^ data1[20] ^ crc_reg[25] ^ data1[6] ^ crc_reg[8] ^ crc_reg[24] ^ data1[7] ^ crc_reg[20] ^ data1[11] ^ data1[23] ^ crc_reg[7] ^ crc_reg[16] ^ data1[15] ^ data1[24] ^ crc_reg[3] ^ crc_reg[27] ^ data1[4] ^ crc_reg[29] ^ data1[2] ^ crc_reg[15] ^ data1[16] ^ data1[28];
    next[20] <= crc_reg[23] ^ data1[8] ^ crc_reg[12] ^ data1[19] ^ crc_reg[26] ^ data1[5] ^ crc_reg[9] ^ crc_reg[25] ^ data1[6] ^ crc_reg[21] ^ data1[10] ^ data1[22] ^ crc_reg[8] ^ crc_reg[17] ^ data1[14] ^ data1[23] ^ crc_reg[4] ^ crc_reg[28] ^ data1[3] ^ crc_reg[30] ^ data1[1] ^ crc_reg[16] ^ data1[15] ^ data1[27];
    next[21] <= crc_reg[24] ^ data1[7] ^ crc_reg[13] ^ data1[18] ^ crc_reg[27] ^ data1[4] ^ crc_reg[10] ^ crc_reg[26] ^ data1[5] ^ crc_reg[22] ^ data1[9] ^ data1[21] ^ crc_reg[9] ^ crc_reg[18] ^ data1[13] ^ data1[22] ^ crc_reg[5] ^ crc_reg[29] ^ data1[2] ^ crc_reg[31] ^ data1[0] ^ crc_reg[17] ^ data1[14] ^ data1[26];
    next[22] <= crc_reg[14] ^ data1[17] ^ crc_reg[11] ^ crc_reg[27] ^ data1[4] ^ crc_reg[23] ^ data1[8] ^ data1[20] ^ crc_reg[19] ^ data1[12] ^ crc_reg[18] ^ data1[13] ^ crc_reg[0] ^ crc_reg[24] ^ data1[7] ^ crc_reg[29] ^ data1[2] ^ crc_reg[26] ^ data1[5] ^ crc_reg[9] ^ data1[22] ^ crc_reg[16] ^ data1[15] ^ crc_reg[31] ^ data1[0] ^ crc_reg[12] ^ data1[19] ^ data1[31];
    next[23] <= crc_reg[15] ^ data1[16] ^ crc_reg[20] ^ data1[11] ^ crc_reg[19] ^ data1[12] ^ crc_reg[1] ^ crc_reg[27] ^ data1[4] ^ crc_reg[17] ^ data1[14] ^ crc_reg[13] ^ data1[18] ^ data1[30] ^ crc_reg[0] ^ crc_reg[29] ^ data1[2] ^ crc_reg[26] ^ data1[5] ^ crc_reg[9] ^ data1[22] ^ crc_reg[6] ^ crc_reg[16] ^ data1[15] ^ crc_reg[31] ^ data1[0] ^ data1[25] ^ data1[31];
    next[24] <= crc_reg[16] ^ data1[15] ^ crc_reg[21] ^ data1[10] ^ crc_reg[20] ^ data1[11] ^ crc_reg[2] ^ crc_reg[28] ^ data1[3] ^ crc_reg[18] ^ data1[13] ^ crc_reg[14] ^ data1[17] ^ data1[29] ^ crc_reg[1] ^ crc_reg[30] ^ data1[1] ^ crc_reg[27] ^ data1[4] ^ crc_reg[10] ^ data1[21] ^ crc_reg[7] ^ crc_reg[17] ^ data1[14] ^ data1[24] ^ data1[30];
    next[25] <= crc_reg[17] ^ data1[14] ^ crc_reg[22] ^ data1[9] ^ crc_reg[21] ^ data1[10] ^ crc_reg[3] ^ crc_reg[29] ^ data1[2] ^ crc_reg[19] ^ data1[12] ^ crc_reg[15] ^ data1[16] ^ data1[28] ^ crc_reg[2] ^ crc_reg[31] ^ data1[0] ^ crc_reg[28] ^ data1[3] ^ crc_reg[11] ^ data1[20] ^ crc_reg[8] ^ crc_reg[18] ^ data1[13] ^ data1[23] ^ data1[29];
    next[26] <= crc_reg[18] ^ data1[13] ^ crc_reg[23] ^ data1[8] ^ crc_reg[22] ^ data1[9] ^ crc_reg[4] ^ crc_reg[20] ^ data1[11] ^ data1[27] ^ crc_reg[3] ^ crc_reg[19] ^ data1[12] ^ data1[28] ^ crc_reg[0] ^ crc_reg[24] ^ data1[7] ^ crc_reg[28] ^ data1[3] ^ crc_reg[10] ^ crc_reg[26] ^ data1[5] ^ data1[21] ^ crc_reg[25] ^ data1[6] ^ crc_reg[6] ^ crc_reg[31] ^ data1[0] ^ data1[25] ^ data1[31];
    next[27] <= crc_reg[19] ^ data1[12] ^ crc_reg[24] ^ data1[7] ^ crc_reg[23] ^ data1[8] ^ crc_reg[5] ^ crc_reg[21] ^ data1[10] ^ data1[26] ^ crc_reg[4] ^ crc_reg[20] ^ data1[11] ^ data1[27] ^ crc_reg[1] ^ crc_reg[25] ^ data1[6] ^ crc_reg[29] ^ data1[2] ^ crc_reg[11] ^ crc_reg[27] ^ data1[4] ^ data1[20] ^ crc_reg[26] ^ data1[5] ^ crc_reg[7] ^ data1[24] ^ data1[30];
    next[28] <= crc_reg[20] ^ data1[11] ^ crc_reg[25] ^ data1[6] ^ crc_reg[24] ^ data1[7] ^ crc_reg[6] ^ crc_reg[22] ^ data1[9] ^ data1[25] ^ crc_reg[5] ^ crc_reg[21] ^ data1[10] ^ data1[26] ^ crc_reg[2] ^ crc_reg[26] ^ data1[5] ^ crc_reg[30] ^ data1[1] ^ crc_reg[12] ^ crc_reg[28] ^ data1[3] ^ data1[19] ^ crc_reg[27] ^ data1[4] ^ crc_reg[8] ^ data1[23] ^ data1[29];
    next[29] <= crc_reg[21] ^ data1[10] ^ crc_reg[26] ^ data1[5] ^ crc_reg[25] ^ data1[6] ^ crc_reg[7] ^ crc_reg[23] ^ data1[8] ^ data1[24] ^ crc_reg[6] ^ crc_reg[22] ^ data1[9] ^ data1[25] ^ crc_reg[3] ^ crc_reg[27] ^ data1[4] ^ crc_reg[31] ^ data1[0] ^ crc_reg[13] ^ crc_reg[29] ^ data1[2] ^ data1[18] ^ crc_reg[28] ^ data1[3] ^ crc_reg[9] ^ data1[22] ^ data1[28];
    next[30] <= crc_reg[22] ^ data1[9] ^ crc_reg[27] ^ data1[4] ^ crc_reg[26] ^ data1[5] ^ crc_reg[8] ^ crc_reg[24] ^ data1[7] ^ data1[23] ^ crc_reg[7] ^ crc_reg[23] ^ data1[8] ^ data1[24] ^ crc_reg[4] ^ crc_reg[28] ^ data1[3] ^ crc_reg[14] ^ crc_reg[30] ^ data1[1] ^ data1[17] ^ crc_reg[29] ^ data1[2] ^ crc_reg[10] ^ data1[21] ^ data1[27];
    next[31] <= crc_reg[23] ^ data1[8] ^ crc_reg[28] ^ data1[3] ^ crc_reg[27] ^ data1[4] ^ crc_reg[9] ^ crc_reg[25] ^ data1[6] ^ data1[22] ^ crc_reg[8] ^ crc_reg[24] ^ data1[7] ^ data1[23] ^ crc_reg[5] ^ crc_reg[29] ^ data1[2] ^ crc_reg[15] ^ crc_reg[31] ^ data1[0] ^ data1[16] ^ crc_reg[30] ^ data1[1] ^ crc_reg[11] ^ data1[20] ^ data1[26];
end

always @(posedge sys_clock) begin
    sys_rst <= sys_reset;

    ce <= valid;
    data0 <= data;
    last_be0 <= last_be;
    error <= error_1;
    if (ce) begin
        crc_reg <= next;
    end

    if (sys_rst) begin
        data0 <= 32'd0;
        last_be0 <= 4'd0;
        crc_reg <= 32'd4294967295;
        ce <= 1'd0;
        error <= 1'd0;
    end
end

endmodule

Expected Behavior

I expect the circuit to synthesize to around 500 LUT4:

I'm definitely not a verilog expert so maybe some constructs are doing different things then I expect. But still over a 1000 LUT4 seems way off.

Actual Behavior

Yosys synthesizes it to a circuit with the following resource usage:

   Number of cells:               1733
     L6MUX21                       222
     LUT4                         1019
     PFUMX                         421
     TRELLIS_FF                     71

I also tried -abc2 flag to try and optimize it further. While this helps a bit it's still way too large. In addition adding -abc2 results in a very long synthesis time. It's stuck on:

2.42.1.1. Executing ABC.
Running ABC command: "/nix/store/i3m465gzpnzwrdqq3zdvwaa6ys7g2x7q-abc-verifier-2023.10.05/bin/abc" -s -f <abc-temp-dir>/abc.script 2>&1
ABC: ABC command line: "source <abc-temp-dir>/abc.script".
ABC: 
ABC: + read_blif <abc-temp-dir>/input.blif 
ABC: + read_library <abc-temp-dir>/stdcells.genlib 
ABC: Entered genlib library with 13 gates from file "<abc-temp-dir>/stdcells.genlib".
ABC: + strash 
ABC: + &get -n 
ABC: + &fraig -x 

Interestingly just the XOR tree does synthesize well:

module crc32_validator (
    input  wire sys_clock,
    input wire sys_reset,
    input  wire   [31:0] data,
    output wire   [31:0] out
);
;
reg    [31:0] crc_reg = 32'd4294967295;

always @(posedge sys_clock) begin
    crc_reg[0] <= crc_reg[0] ^ crc_reg[24] ^ data[7] ^ crc_reg[29] ^ data[2] ^ crc_reg[28] ^ data[3] ^ crc_reg[10] ^ crc_reg[26] ^ data[5] ^ data[21] ^ crc_reg[9] ^ crc_reg[25] ^ data[6] ^ data[22] ^ crc_reg[6] ^ crc_reg[30] ^ data[1] ^ crc_reg[16] ^ data[15] ^ crc_reg[31] ^ data[0] ^ crc_reg[12] ^ data[19] ^ data[25] ^ data[31];
    crc_reg[1] <= crc_reg[1] ^ crc_reg[11] ^ crc_reg[27] ^ data[4] ^ data[20] ^ crc_reg[7] ^ crc_reg[17] ^ data[14] ^ crc_reg[13] ^ data[18] ^ data[24] ^ data[30] ^ crc_reg[0] ^ crc_reg[24] ^ data[7] ^ crc_reg[28] ^ data[3] ^ crc_reg[9] ^ data[22] ^ crc_reg[6] ^ crc_reg[16] ^ data[15] ^ crc_reg[12] ^ data[19] ^ data[25] ^ data[31];
    crc_reg[2] <= crc_reg[2] ^ crc_reg[8] ^ crc_reg[18] ^ data[13] ^ crc_reg[14] ^ data[17] ^ data[23] ^ data[29] ^ crc_reg[1] ^ crc_reg[7] ^ crc_reg[17] ^ data[14] ^ crc_reg[13] ^ data[18] ^ data[24] ^ data[30] ^ crc_reg[0] ^ crc_reg[24] ^ data[7] ^ crc_reg[26] ^ data[5] ^ crc_reg[9] ^ data[22] ^ crc_reg[6] ^ crc_reg[30] ^ data[1] ^ crc_reg[16] ^ data[15] ^ crc_reg[31] ^ data[0] ^ data[25] ^ data[31];
    crc_reg[3] <= crc_reg[3] ^ crc_reg[9] ^ crc_reg[19] ^ data[12] ^ crc_reg[15] ^ data[16] ^ data[22] ^ data[28] ^ crc_reg[2] ^ crc_reg[8] ^ crc_reg[18] ^ data[13] ^ crc_reg[14] ^ data[17] ^ data[23] ^ data[29] ^ crc_reg[1] ^ crc_reg[25] ^ data[6] ^ crc_reg[27] ^ data[4] ^ crc_reg[10] ^ data[21] ^ crc_reg[7] ^ crc_reg[31] ^ data[0] ^ crc_reg[17] ^ data[14] ^ data[24] ^ data[30];
    crc_reg[4] <= crc_reg[4] ^ crc_reg[20] ^ data[11] ^ data[27] ^ crc_reg[3] ^ crc_reg[19] ^ data[12] ^ crc_reg[15] ^ data[16] ^ data[28] ^ crc_reg[2] ^ crc_reg[11] ^ data[20] ^ crc_reg[8] ^ crc_reg[18] ^ data[13] ^ data[23] ^ data[29] ^ crc_reg[0] ^ crc_reg[24] ^ data[7] ^ crc_reg[29] ^ data[2] ^ crc_reg[25] ^ data[6] ^ crc_reg[6] ^ crc_reg[30] ^ data[1] ^ crc_reg[31] ^ data[0] ^ crc_reg[12] ^ data[19] ^ data[25] ^ data[31];
    crc_reg[5] <= crc_reg[5] ^ crc_reg[21] ^ data[10] ^ data[26] ^ crc_reg[4] ^ crc_reg[20] ^ data[11] ^ data[27] ^ crc_reg[3] ^ crc_reg[19] ^ data[12] ^ data[28] ^ crc_reg[1] ^ crc_reg[7] ^ crc_reg[13] ^ data[18] ^ data[24] ^ data[30] ^ crc_reg[0] ^ crc_reg[24] ^ data[7] ^ crc_reg[29] ^ data[2] ^ crc_reg[28] ^ data[3] ^ crc_reg[10] ^ data[21] ^ crc_reg[6] ^ data[25] ^ data[31];
    crc_reg[6] <= crc_reg[6] ^ crc_reg[22] ^ data[9] ^ data[25] ^ crc_reg[5] ^ crc_reg[21] ^ data[10] ^ data[26] ^ crc_reg[4] ^ crc_reg[20] ^ data[11] ^ data[27] ^ crc_reg[2] ^ crc_reg[8] ^ crc_reg[14] ^ data[17] ^ data[23] ^ data[29] ^ crc_reg[1] ^ crc_reg[25] ^ data[6] ^ crc_reg[30] ^ data[1] ^ crc_reg[29] ^ data[2] ^ crc_reg[11] ^ data[20] ^ crc_reg[7] ^ data[24] ^ data[30];
    crc_reg[7] <= crc_reg[7] ^ crc_reg[23] ^ data[8] ^ data[24] ^ crc_reg[22] ^ data[9] ^ crc_reg[5] ^ crc_reg[21] ^ data[10] ^ data[26] ^ crc_reg[3] ^ crc_reg[15] ^ data[16] ^ data[28] ^ crc_reg[2] ^ crc_reg[8] ^ data[23] ^ data[29] ^ crc_reg[0] ^ crc_reg[24] ^ data[7] ^ crc_reg[29] ^ data[2] ^ crc_reg[28] ^ data[3] ^ crc_reg[10] ^ data[21] ^ crc_reg[25] ^ data[6] ^ crc_reg[16] ^ data[15] ^ data[31];
    crc_reg[8] <= crc_reg[8] ^ data[23] ^ crc_reg[23] ^ data[8] ^ crc_reg[22] ^ data[9] ^ crc_reg[4] ^ data[27] ^ crc_reg[3] ^ data[28] ^ crc_reg[1] ^ crc_reg[11] ^ data[20] ^ crc_reg[17] ^ data[14] ^ data[30] ^ crc_reg[0] ^ crc_reg[28] ^ data[3] ^ crc_reg[10] ^ data[21] ^ crc_reg[31] ^ data[0] ^ crc_reg[12] ^ data[19] ^ data[31];
    crc_reg[9] <= crc_reg[9] ^ data[22] ^ crc_reg[24] ^ data[7] ^ crc_reg[23] ^ data[8] ^ crc_reg[5] ^ data[26] ^ crc_reg[4] ^ data[27] ^ crc_reg[2] ^ crc_reg[12] ^ data[19] ^ crc_reg[18] ^ data[13] ^ data[29] ^ crc_reg[1] ^ crc_reg[29] ^ data[2] ^ crc_reg[11] ^ data[20] ^ crc_reg[13] ^ data[18] ^ data[30];
    crc_reg[10] <= crc_reg[5] ^ data[26] ^ crc_reg[3] ^ crc_reg[13] ^ data[18] ^ crc_reg[19] ^ data[12] ^ data[28] ^ crc_reg[2] ^ crc_reg[14] ^ data[17] ^ data[29] ^ crc_reg[0] ^ crc_reg[29] ^ data[2] ^ crc_reg[28] ^ data[3] ^ crc_reg[26] ^ data[5] ^ crc_reg[9] ^ data[22] ^ crc_reg[16] ^ data[15] ^ crc_reg[31] ^ data[0] ^ data[31];
    crc_reg[11] <= crc_reg[4] ^ crc_reg[14] ^ data[17] ^ crc_reg[20] ^ data[11] ^ data[27] ^ crc_reg[3] ^ crc_reg[15] ^ data[16] ^ data[28] ^ crc_reg[1] ^ crc_reg[27] ^ data[4] ^ crc_reg[17] ^ data[14] ^ data[30] ^ crc_reg[0] ^ crc_reg[24] ^ data[7] ^ crc_reg[28] ^ data[3] ^ crc_reg[26] ^ data[5] ^ crc_reg[9] ^ crc_reg[25] ^ data[6] ^ data[22] ^ crc_reg[16] ^ data[15] ^ crc_reg[31] ^ data[0] ^ crc_reg[12] ^ data[19] ^ data[31];
    crc_reg[12] <= crc_reg[5] ^ crc_reg[15] ^ data[16] ^ crc_reg[21] ^ data[10] ^ data[26] ^ crc_reg[4] ^ data[27] ^ crc_reg[2] ^ crc_reg[18] ^ data[13] ^ data[29] ^ crc_reg[1] ^ crc_reg[27] ^ data[4] ^ crc_reg[17] ^ data[14] ^ crc_reg[13] ^ data[18] ^ data[30] ^ crc_reg[0] ^ crc_reg[24] ^ data[7] ^ crc_reg[9] ^ data[22] ^ crc_reg[6] ^ crc_reg[30] ^ data[1] ^ crc_reg[31] ^ data[0] ^ crc_reg[12] ^ data[19] ^ data[25] ^ data[31];
    crc_reg[13] <= crc_reg[6] ^ crc_reg[16] ^ data[15] ^ crc_reg[22] ^ data[9] ^ data[25] ^ crc_reg[5] ^ data[26] ^ crc_reg[3] ^ crc_reg[19] ^ data[12] ^ data[28] ^ crc_reg[2] ^ crc_reg[28] ^ data[3] ^ crc_reg[18] ^ data[13] ^ crc_reg[14] ^ data[17] ^ data[29] ^ crc_reg[1] ^ crc_reg[25] ^ data[6] ^ crc_reg[10] ^ data[21] ^ crc_reg[7] ^ crc_reg[31] ^ data[0] ^ crc_reg[13] ^ data[18] ^ data[24] ^ data[30];
    crc_reg[14] <= crc_reg[7] ^ crc_reg[17] ^ data[14] ^ crc_reg[23] ^ data[8] ^ data[24] ^ crc_reg[6] ^ data[25] ^ crc_reg[4] ^ crc_reg[20] ^ data[11] ^ data[27] ^ crc_reg[3] ^ crc_reg[29] ^ data[2] ^ crc_reg[19] ^ data[12] ^ crc_reg[15] ^ data[16] ^ data[28] ^ crc_reg[2] ^ crc_reg[26] ^ data[5] ^ crc_reg[11] ^ data[20] ^ crc_reg[8] ^ crc_reg[14] ^ data[17] ^ data[23] ^ data[29];
    crc_reg[15] <= crc_reg[8] ^ crc_reg[18] ^ data[13] ^ crc_reg[24] ^ data[7] ^ data[23] ^ crc_reg[7] ^ data[24] ^ crc_reg[5] ^ crc_reg[21] ^ data[10] ^ data[26] ^ crc_reg[4] ^ crc_reg[30] ^ data[1] ^ crc_reg[20] ^ data[11] ^ crc_reg[16] ^ data[15] ^ data[27] ^ crc_reg[3] ^ crc_reg[27] ^ data[4] ^ crc_reg[12] ^ data[19] ^ crc_reg[9] ^ crc_reg[15] ^ data[16] ^ data[22] ^ data[28];
    crc_reg[16] <= crc_reg[19] ^ data[12] ^ crc_reg[8] ^ data[23] ^ crc_reg[22] ^ data[9] ^ crc_reg[5] ^ crc_reg[21] ^ data[10] ^ crc_reg[17] ^ data[14] ^ data[26] ^ crc_reg[4] ^ crc_reg[13] ^ data[18] ^ data[27] ^ crc_reg[0] ^ crc_reg[24] ^ data[7] ^ crc_reg[29] ^ data[2] ^ crc_reg[26] ^ data[5] ^ crc_reg[30] ^ data[1] ^ crc_reg[12] ^ data[19] ^ data[31];
    crc_reg[17] <= crc_reg[20] ^ data[11] ^ crc_reg[9] ^ data[22] ^ crc_reg[23] ^ data[8] ^ crc_reg[6] ^ crc_reg[22] ^ data[9] ^ crc_reg[18] ^ data[13] ^ data[25] ^ crc_reg[5] ^ crc_reg[14] ^ data[17] ^ data[26] ^ crc_reg[1] ^ crc_reg[25] ^ data[6] ^ crc_reg[30] ^ data[1] ^ crc_reg[27] ^ data[4] ^ crc_reg[31] ^ data[0] ^ crc_reg[13] ^ data[18] ^ data[30];
    crc_reg[18] <= crc_reg[21] ^ data[10] ^ crc_reg[10] ^ data[21] ^ crc_reg[24] ^ data[7] ^ crc_reg[7] ^ crc_reg[23] ^ data[8] ^ crc_reg[19] ^ data[12] ^ data[24] ^ crc_reg[6] ^ crc_reg[15] ^ data[16] ^ data[25] ^ crc_reg[2] ^ crc_reg[26] ^ data[5] ^ crc_reg[31] ^ data[0] ^ crc_reg[28] ^ data[3] ^ crc_reg[14] ^ data[17] ^ data[29];
    crc_reg[19] <= crc_reg[22] ^ data[9] ^ crc_reg[11] ^ data[20] ^ crc_reg[25] ^ data[6] ^ crc_reg[8] ^ crc_reg[24] ^ data[7] ^ crc_reg[20] ^ data[11] ^ data[23] ^ crc_reg[7] ^ crc_reg[16] ^ data[15] ^ data[24] ^ crc_reg[3] ^ crc_reg[27] ^ data[4] ^ crc_reg[29] ^ data[2] ^ crc_reg[15] ^ data[16] ^ data[28];
    crc_reg[20] <= crc_reg[23] ^ data[8] ^ crc_reg[12] ^ data[19] ^ crc_reg[26] ^ data[5] ^ crc_reg[9] ^ crc_reg[25] ^ data[6] ^ crc_reg[21] ^ data[10] ^ data[22] ^ crc_reg[8] ^ crc_reg[17] ^ data[14] ^ data[23] ^ crc_reg[4] ^ crc_reg[28] ^ data[3] ^ crc_reg[30] ^ data[1] ^ crc_reg[16] ^ data[15] ^ data[27];
    crc_reg[21] <= crc_reg[24] ^ data[7] ^ crc_reg[13] ^ data[18] ^ crc_reg[27] ^ data[4] ^ crc_reg[10] ^ crc_reg[26] ^ data[5] ^ crc_reg[22] ^ data[9] ^ data[21] ^ crc_reg[9] ^ crc_reg[18] ^ data[13] ^ data[22] ^ crc_reg[5] ^ crc_reg[29] ^ data[2] ^ crc_reg[31] ^ data[0] ^ crc_reg[17] ^ data[14] ^ data[26];
    crc_reg[22] <= crc_reg[14] ^ data[17] ^ crc_reg[11] ^ crc_reg[27] ^ data[4] ^ crc_reg[23] ^ data[8] ^ data[20] ^ crc_reg[19] ^ data[12] ^ crc_reg[18] ^ data[13] ^ crc_reg[0] ^ crc_reg[24] ^ data[7] ^ crc_reg[29] ^ data[2] ^ crc_reg[26] ^ data[5] ^ crc_reg[9] ^ data[22] ^ crc_reg[16] ^ data[15] ^ crc_reg[31] ^ data[0] ^ crc_reg[12] ^ data[19] ^ data[31];
    crc_reg[23] <= crc_reg[15] ^ data[16] ^ crc_reg[20] ^ data[11] ^ crc_reg[19] ^ data[12] ^ crc_reg[1] ^ crc_reg[27] ^ data[4] ^ crc_reg[17] ^ data[14] ^ crc_reg[13] ^ data[18] ^ data[30] ^ crc_reg[0] ^ crc_reg[29] ^ data[2] ^ crc_reg[26] ^ data[5] ^ crc_reg[9] ^ data[22] ^ crc_reg[6] ^ crc_reg[16] ^ data[15] ^ crc_reg[31] ^ data[0] ^ data[25] ^ data[31];
    crc_reg[24] <= crc_reg[16] ^ data[15] ^ crc_reg[21] ^ data[10] ^ crc_reg[20] ^ data[11] ^ crc_reg[2] ^ crc_reg[28] ^ data[3] ^ crc_reg[18] ^ data[13] ^ crc_reg[14] ^ data[17] ^ data[29] ^ crc_reg[1] ^ crc_reg[30] ^ data[1] ^ crc_reg[27] ^ data[4] ^ crc_reg[10] ^ data[21] ^ crc_reg[7] ^ crc_reg[17] ^ data[14] ^ data[24] ^ data[30];
    crc_reg[25] <= crc_reg[17] ^ data[14] ^ crc_reg[22] ^ data[9] ^ crc_reg[21] ^ data[10] ^ crc_reg[3] ^ crc_reg[29] ^ data[2] ^ crc_reg[19] ^ data[12] ^ crc_reg[15] ^ data[16] ^ data[28] ^ crc_reg[2] ^ crc_reg[31] ^ data[0] ^ crc_reg[28] ^ data[3] ^ crc_reg[11] ^ data[20] ^ crc_reg[8] ^ crc_reg[18] ^ data[13] ^ data[23] ^ data[29];
    crc_reg[26] <= crc_reg[18] ^ data[13] ^ crc_reg[23] ^ data[8] ^ crc_reg[22] ^ data[9] ^ crc_reg[4] ^ crc_reg[20] ^ data[11] ^ data[27] ^ crc_reg[3] ^ crc_reg[19] ^ data[12] ^ data[28] ^ crc_reg[0] ^ crc_reg[24] ^ data[7] ^ crc_reg[28] ^ data[3] ^ crc_reg[10] ^ crc_reg[26] ^ data[5] ^ data[21] ^ crc_reg[25] ^ data[6] ^ crc_reg[6] ^ crc_reg[31] ^ data[0] ^ data[25] ^ data[31];
    crc_reg[27] <= crc_reg[19] ^ data[12] ^ crc_reg[24] ^ data[7] ^ crc_reg[23] ^ data[8] ^ crc_reg[5] ^ crc_reg[21] ^ data[10] ^ data[26] ^ crc_reg[4] ^ crc_reg[20] ^ data[11] ^ data[27] ^ crc_reg[1] ^ crc_reg[25] ^ data[6] ^ crc_reg[29] ^ data[2] ^ crc_reg[11] ^ crc_reg[27] ^ data[4] ^ data[20] ^ crc_reg[26] ^ data[5] ^ crc_reg[7] ^ data[24] ^ data[30];
    crc_reg[28] <= crc_reg[20] ^ data[11] ^ crc_reg[25] ^ data[6] ^ crc_reg[24] ^ data[7] ^ crc_reg[6] ^ crc_reg[22] ^ data[9] ^ data[25] ^ crc_reg[5] ^ crc_reg[21] ^ data[10] ^ data[26] ^ crc_reg[2] ^ crc_reg[26] ^ data[5] ^ crc_reg[30] ^ data[1] ^ crc_reg[12] ^ crc_reg[28] ^ data[3] ^ data[19] ^ crc_reg[27] ^ data[4] ^ crc_reg[8] ^ data[23] ^ data[29];
    crc_reg[29] <= crc_reg[21] ^ data[10] ^ crc_reg[26] ^ data[5] ^ crc_reg[25] ^ data[6] ^ crc_reg[7] ^ crc_reg[23] ^ data[8] ^ data[24] ^ crc_reg[6] ^ crc_reg[22] ^ data[9] ^ data[25] ^ crc_reg[3] ^ crc_reg[27] ^ data[4] ^ crc_reg[31] ^ data[0] ^ crc_reg[13] ^ crc_reg[29] ^ data[2] ^ data[18] ^ crc_reg[28] ^ data[3] ^ crc_reg[9] ^ data[22] ^ data[28];
    crc_reg[30] <= crc_reg[22] ^ data[9] ^ crc_reg[27] ^ data[4] ^ crc_reg[26] ^ data[5] ^ crc_reg[8] ^ crc_reg[24] ^ data[7] ^ data[23] ^ crc_reg[7] ^ crc_reg[23] ^ data[8] ^ data[24] ^ crc_reg[4] ^ crc_reg[28] ^ data[3] ^ crc_reg[14] ^ crc_reg[30] ^ data[1] ^ data[17] ^ crc_reg[29] ^ data[2] ^ crc_reg[10] ^ data[21] ^ data[27];
    crc_reg[31] <= crc_reg[23] ^ data[8] ^ crc_reg[28] ^ data[3] ^ crc_reg[27] ^ data[4] ^ crc_reg[9] ^ crc_reg[25] ^ data[6] ^ data[22] ^ crc_reg[8] ^ crc_reg[24] ^ data[7] ^ data[23] ^ crc_reg[5] ^ crc_reg[29] ^ data[2] ^ crc_reg[15] ^ crc_reg[31] ^ data[0] ^ data[16] ^ crc_reg[30] ^ data[1] ^ crc_reg[11] ^ data[20] ^ data[26];

    if (sys_reset) begin
        crc_reg <= 32'd4294967295;
    end
end

assign out = crc_reg;

endmodule

result:

   Number of cells:                348
     L6MUX21                         4
     LUT4                          280
     PFUMX                          32
     TRELLIS_FF                     32
Ravenslofty commented 3 months ago

TL;DR: add -nowidelut to get it to synthesise in 417 LUT4s, which is the number you expect here.

This is a classic case of delay-area tradeoff. There are some hints in the ABC9 output about what it's doing:

ABC: + &if -W 300 -v
ABC: K = 7. Memory (bytes): Truth =    0. Cut =   60. Obj =  140. Set =  636. CutMin = no
ABC: Node =    4426.  Ch =   472.  Total mem =    0.68 MB. Peak cut mem =    0.07 MB.
ABC: P:  Del = 4041.00.  Ar =    2030.0.  Edge =     2363.  Cut =    87308.  T =     0.01 sec
ABC: P:  Del = 4041.00.  Ar =    1974.0.  Edge =     2292.  Cut =    86974.  T =     0.01 sec
ABC: P:  Del = 4041.00.  Ar =    1742.0.  Edge =     2290.  Cut =   174418.  T =     0.02 sec
ABC: F:  Del = 4041.00.  Ar =    1129.0.  Edge =     1898.  Cut =    87285.  T =     0.01 sec
ABC: A:  Del = 4041.00.  Ar =    1036.0.  Edge =     1717.  Cut =    85301.  T =     0.01 sec
ABC: A:  Del = 4041.00.  Ar =    1019.0.  Edge =     1708.  Cut =    85032.  T =     0.01 sec
[snip]
ABC: + &ps -l
ABC: <abc-temp-dir>/input : i/o =    110/     36  and =    3230  lev =   26 (14.42)  mem = 0.04 MB  box = 0  bb = 0
ABC: Mapping (K=7)  :  lut =    376  edge =    1708  lev =    8 (3.64)  mem = 0.02 MB
ABC: LUT = 376 : 2=59 15.7 %  3=45 12.0 %  4=73 19.4 %  5=85 22.6 %  6=60 16.0 %  7=54 14.4 %  Ave = 4.54

ABC9 will map first for minimum delay, then attempt to recover area. The lowest-delay solution it finds is 4.041ns, which needs a lot of large LUTs: 54 LUT7s, where each LUT7 is made up of 8 LUT4s (and ABC9 is aware of this; its best area is 1019 LUT4s).

Let's compare to the output with -nowidelut.

ABC: + &if -W 300 -v
ABC: K = 4. Memory (bytes): Truth =    0. Cut =   48. Obj =  128. Set =  528. CutMin = no
ABC: Node =    4426.  Ch =   472.  Total mem =    0.63 MB. Peak cut mem =    0.06 MB.
ABC: P:  Del = 4748.00.  Ar =     480.0.  Edge =     1728.  Cut =    48240.  T =     0.01 sec
ABC: P:  Del = 4718.00.  Ar =     495.0.  Edge =     1828.  Cut =    46528.  T =     0.01 sec
ABC: P:  Del = 4718.00.  Ar =     461.0.  Edge =     1644.  Cut =    50842.  T =     0.01 sec
ABC: F:  Del = 4718.00.  Ar =     422.0.  Edge =     1516.  Cut =    31685.  T =     0.00 sec
ABC: A:  Del = 4718.00.  Ar =     418.0.  Edge =     1433.  Cut =    33285.  T =     0.01 sec
ABC: A:  Del = 4718.00.  Ar =     417.0.  Edge =     1431.  Cut =    32689.  T =     0.01 sec
[snip]
ABC: + &ps -l
ABC: <abc-temp-dir>/input : i/o =    110/     36  and =    2514  lev =   26 (14.28)  mem = 0.03 MB  box = 0  bb = 0
ABC: Mapping (K=4)  :  lut =    417  edge =    1431  lev =   10 (4.31)  mem = 0.02 MB
ABC: LUT = 417 : 2=71 17.0 %  3=95 22.8 %  4=251 60.2 %  Ave = 3.43

Here the solution is slower - 4.718ns - but uses significantly less area (417 LUT4s) because it is not considering the large LUTs that are enabled by default.

Ravenslofty commented 3 months ago

As for -abc2; it seems you've discovered a scalability problem in &fraig -x; it might be worth reporting to ABC, although don't get your hopes up that it'll ever be fixed.

Ravenslofty commented 3 months ago

This actually turned out to be a catalyst for YosysHQ/abc#30 which fixes an issue in the &mfs postprocessing pass. The downside of doing that is that &mfs is...slow on this, likely because XORs are pretty awful.

So now the relevant numbers look like this: LUT7: 15 LUT4s fewer

   Number of cells:               1707
     L6MUX21                       218
     LUT4                         1004
     PFUMX                         414
     TRELLIS_FF                     71

LUT4 (-nowidelut): 9 LUT4s fewer

   Number of cells:                479
     LUT4                          408
     TRELLIS_FF                     71
rowanG077 commented 3 months ago

Thanks for the very clear explanation! I guess the only question I have is whether there is some way to enable/disable nowidelut on specific nets or maybe even module? Disabling it wholesale is quite a sledgehammer if this is the only affected module.

Ravenslofty commented 3 months ago

There's no direct way to perform such a thing, because the LUT library passed to ABC9 is a global thing.

However, there are a few implicit ways to reduce area here:

whitequark commented 3 months ago
  • related to the above, there's a poorly-documented scratchpad setting called abc9.D, which allows you to set the critical path delay for the entire mapping to something slower than "best possible delay".

Is this an actual API Yosys provides or just something that happens to work today?

Ravenslofty commented 3 months ago

It's an API that ABC provides and the Yosys side exposes, so if you're asking if it can be relied on, yes.

Ravenslofty commented 3 months ago

By the way, since it appears you wrote this code for liteeth, would you be okay with me including this in the Yosys-internal benchmark suite?

As a benchmark that benefits from &mfs but initially exposes an ABC bug, it might be a useful smoke test to have in case the issue reappears.

Further, the heavy use of XOR makes this near-worst-case for an AND-Inverter Graph representation like ABC, and that contributes to a noticeable runtime from &mfs, which could be tracked.

rowanG077 commented 3 months ago

I'm fine with that. It is based on the existing CRC validator in liteeth so It's not fully my work. Pinging @enjoy-digital.

enjoy-digital commented 3 months ago

@rowanG077: No problem on my end.