lakeroad icon indicating copy to clipboard operation
lakeroad copied to clipboard

yosys-plugin segfaults on multi-module designs

Open cknizek opened this issue 5 months ago • 5 comments

When Lakeroad is used to synthesize a design with multiple modules, lakeroad.so experiences a segmentation fault.

image

The issue seems to be some logic in either lakeroad.cc or possibly in Yosys.

This is particularly problematic when non-synthesizable modules are included in a design.

I think the fix is to re-write lakeroad.cc such that it doesn't expect only a single module to be present in the Lakeroad design. Here's a log of the error occuring when manually using yosys:

 colinknizek@colins-macbook-pro yosys-plugin % yosys -m lakeroad.so

 /----------------------------------------------------------------------------\
 |  yosys -- Yosys Open SYnthesis Suite                                       |
 |  Copyright (C) 2012 - 2024  Claire Xenia Wolf          |
 |  Distributed under an ISC-like license, type "license" to see terms        |
 \----------------------------------------------------------------------------/
 Yosys 0.42 (git sha1 9b6afcf3f, clang++ 15.0.0 -fPIC -Os)

yosys> read_verilog -sv /Users/colinknizek/dev/lakeroad_bitbit/lakeroad/integration_tests/lakeroad/bsg_muladd_synth.sv

1. Executing Verilog-2005 frontend: /Users/colinknizek/dev/lakeroad_bitbit/lakeroad/integration_tests/lakeroad/bsg_muladd_synth.sv
Parsing SystemVerilog input from `/Users/colinknizek/dev/lakeroad_bitbit/lakeroad/integration_tests/lakeroad/bsg_muladd_synth.sv' to AST representation.
Generating RTLIL representation for module `\bsg_dff'.
Generating RTLIL representation for module `\bsg_dff_chain'.
Generating RTLIL representation for module `\in_module'.
Successfully finished Verilog frontend.

yosys> hierarchy -top in_module

2. Executing HIERARCHY pass (managing design hierarchy).

2.1. Analyzing design hierarchy..
Top module:  \in_module
Used module:     \bsg_dff_chain
Used module:         \bsg_dff
Parameter \width_p = 27

2.2. Executing AST frontend in derive mode using pre-parsed AST for module `\bsg_dff'.
Parameter \width_p = 27
Generating RTLIL representation for module `$paramod\bsg_dff\width_p=s32'00000000000000000000000000011011'.
Parameter 1 (\width_p) = 27
Parameter 2 (\num_stages_p) = 1

2.3. Executing AST frontend in derive mode using pre-parsed AST for module `\bsg_dff_chain'.
Parameter 1 (\width_p) = 27
Parameter 2 (\num_stages_p) = 1
Generating RTLIL representation for module `$paramod$fbbfd766ffebd65a066ca57f2e47cd4227591125\bsg_dff_chain'.
Parameter 1 (\width_p) = 52
Parameter 2 (\num_stages_p) = 0

2.4. Executing AST frontend in derive mode using pre-parsed AST for module `\bsg_dff_chain'.
Parameter 1 (\width_p) = 52
Parameter 2 (\num_stages_p) = 0
Generating RTLIL representation for module `$paramod$171e8baada6630a6b17606ff4996a28a7711b116\bsg_dff_chain'.

2.5. Analyzing design hierarchy..
Top module:  \in_module
Used module:     $paramod$fbbfd766ffebd65a066ca57f2e47cd4227591125\bsg_dff_chain
Used module:         \bsg_dff
Used module:     $paramod$171e8baada6630a6b17606ff4996a28a7711b116\bsg_dff_chain
Parameter \width_p = 27
Found cached RTLIL representation for module `$paramod\bsg_dff\width_p=s32'00000000000000000000000000011011'.

2.6. Analyzing design hierarchy..
Top module:  \in_module
Used module:     $paramod$fbbfd766ffebd65a066ca57f2e47cd4227591125\bsg_dff_chain
Used module:         $paramod\bsg_dff\width_p=s32'00000000000000000000000000011011
Used module:     $paramod$171e8baada6630a6b17606ff4996a28a7711b116\bsg_dff_chain

2.7. Analyzing design hierarchy..
Top module:  \in_module
Used module:     $paramod$fbbfd766ffebd65a066ca57f2e47cd4227591125\bsg_dff_chain
Used module:         $paramod\bsg_dff\width_p=s32'00000000000000000000000000011011
Used module:     $paramod$171e8baada6630a6b17606ff4996a28a7711b116\bsg_dff_chain
Removing unused module `\bsg_dff_chain'.
Removing unused module `\bsg_dff'.
Removed 2 unused modules.

yosys> proc

3. Executing PROC pass (convert processes to netlists).

3.1. Executing PROC_CLEAN pass (remove empty switches from decision trees).
Cleaned up 0 empty switches.

3.2. Executing PROC_RMDEAD pass (remove dead branches from decision trees).
Removed a total of 0 dead cases.

3.3. Executing PROC_PRUNE pass (remove redundant assignments in processes).
Removed 0 redundant assignments.
Promoted 1 assignment to connection.

3.4. Executing PROC_INIT pass (extract init attributes).

3.5. Executing PROC_ARST pass (detect async resets in processes).

3.6. Executing PROC_ROM pass (convert switches to ROMs).
Converted 0 switches.

3.7. Executing PROC_MUX pass (convert decision trees to multiplexers).
Creating decoders for process `$paramod\bsg_dff\width_p=s32'00000000000000000000000000011011.$proc$/Users/colinknizek/dev/lakeroad_bitbit/lakeroad/integration_tests/lakeroad/bsg_muladd_synth.sv:23$4'.

3.8. Executing PROC_DLATCH pass (convert process syncs to latches).

3.9. Executing PROC_DFF pass (convert process syncs to FFs).
Creating register for signal `$paramod\bsg_dff\width_p=s32'00000000000000000000000000011011.\data_r' using process `$paramod\bsg_dff\width_p=s32'00000000000000000000000000011011.$proc$/Users/colinknizek/dev/lakeroad_bitbit/lakeroad/integration_tests/lakeroad/bsg_muladd_synth.sv:23$4'.
  created $dff cell `$procdff$5' with positive edge clock.

3.10. Executing PROC_MEMWR pass (convert process memory writes to cells).

3.11. Executing PROC_CLEAN pass (remove empty switches from decision trees).
Removing empty process `$paramod\bsg_dff\width_p=s32'00000000000000000000000000011011.$proc$/Users/colinknizek/dev/lakeroad_bitbit/lakeroad/integration_tests/lakeroad/bsg_muladd_synth.sv:23$4'.
Cleaned up 0 empty switches.

3.12. Executing OPT_EXPR pass (perform const folding).
Optimizing module $paramod\bsg_dff\width_p=s32'00000000000000000000000000011011.
Optimizing module in_module.
Optimizing module $paramod$171e8baada6630a6b17606ff4996a28a7711b116\bsg_dff_chain.
Optimizing module $paramod$fbbfd766ffebd65a066ca57f2e47cd4227591125\bsg_dff_chain.

yosys> lakeroad in_module

4. Executing Lakeroad pass (technology mapping using Lakeroad).

4.1. Executing Verilog backend.

4.1.1. Executing BMUXMAP pass.


4.1.2. Executing DEMUXMAP pass.
Dumping module `$paramod$171e8baada6630a6b17606ff4996a28a7711b116\bsg_dff_chain'.
Dumping module `$paramod$fbbfd766ffebd65a066ca57f2e47cd4227591125\bsg_dff_chain'.
Dumping module `$paramod\bsg_dff\width_p=s32'00000000000000000000000000011011'.
Dumping module `\in_module'.
zsh: segmentation fault  yosys -m lakeroad.so
colinknizek@colins-macbook-pro yosys-plugin % 

Here is the file that Lakeroad is being applied to (variant 1 / modules directly inserted into file)

bsg_muladd_synth.sv

// RUN: outfile=$(mktemp)
// RUN: yosys -m "$LAKEROAD_DIR/yosys-plugin/lakeroad.so" -p " \
// RUN:  read_verilog -sv %s; \
// RUN:  hierarchy -top in_module; \
// RUN:  lakeroad in_module; \
// RUN:  rename in_module out_module; \
// RUN:  write_verilog $outfile"
// RUN: FileCheck %s  2 ? 1 : 0;
    localparam post_pipeline_lp = pipeline_p > 2 ? pipeline_p -1 : pipeline_p; 
    
    wire [width_a_p-1:0] a_r;
    wire [width_b_p-1:0] b_r;
    wire [width_c_p-1:0] c_r;

    bsg_dff_chain #(width_a_p + width_b_p + width_c_p, pre_pipeline_lp)
        pre_mul_add (
            .clk_i(clk_i)
            ,.data_i({a_i, b_i, c_i})
            ,.data_o({a_r, b_r, c_r})
        );

    wire [width_o_p-1:0] o_r = a_r * b_r + c_r;

    bsg_dff_chain #(width_o_p, post_pipeline_lp)
        post_mul_add (
            .clk_i(clk_i)
            ,.data_i(o_r)
            ,.data_o(o)
        );
endmodule

// CHECK: module out_module(a_i, b_i, c_i, clk_i, o);
// CHECK:   DSP48E2 #(
// CHECK: endmodule

Here is the 2nd variant (include statements used, modules in separate files)

bsg_muladd_synth.sv

// RUN: outfile=$(mktemp)
// RUN: yosys -m "$LAKEROAD_DIR/yosys-plugin/lakeroad.so" -p " \
// RUN:  read_verilog -sv %s; \
// RUN:  hierarchy -top top; \
// RUN:  lakeroad top; \
// RUN:  rename top test_module; \
// RUN:  write_verilog $outfile"
// RUN: FileCheck %s  2 ? 1 : 0;
    localparam post_pipeline_lp = pipeline_p > 2 ? pipeline_p -1 : pipeline_p; //for excess

    wire [width_a_p-1:0] a_r;
    wire [width_b_p-1:0] b_r;
    wire [width_c_p-1:0] c_r;

    bsg_dff_chain #(width_a_p + width_b_p + width_c_p, pre_pipeline_lp)
        pre_mul_add (
            .clk_i(clk_i)
            ,.data_i({a_i, b_i, c_i})
            ,.data_o({a_r, b_r, c_r})
        );

    wire [width_o_p-1:0] o_r = a_r * b_r + c_r;

    bsg_dff_chain #(width_o_p, post_pipeline_lp)
        post_mul_add (
            .clk_i(clk_i)
            ,.data_i(o_r)
            ,.data_o(o)
        );
endmodule

// CHECK: module test_module(a_i, b_i, c_i, clk_i, o);
// CHECK:   DSP48E2 #(
// CHECK: endmodule

cknizek avatar Sep 06 '24 11:09 cknizek