verilog-to-routing / vtr-verilog-to-routing

Verilog to Routing -- Open Source CAD Flow for FPGA Research
https://verilogtorouting.org
Other
999 stars 385 forks source link

ODIN_II: segfault on 2d array #570

Closed j-b-1-7 closed 5 years ago

j-b-1-7 commented 5 years ago

Current Behaviour

segfault when accessing 2d arrays in local param table

Possible Solution

check sc_spot is not negative

Steps to Reproduce

see bellow

Context

tried to compile the matmul.v file but 2d arrays seems to segfault due to sc_spot being negative in odin. would probably need a check

uname -a

Linux JBpc 5.0.13-arch1-1-ARCH #1 SMP PREEMPT Sun May 5 18:05:41 UTC 2019 x86_64 GNU/Linux

gcc -v

Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-pc-linux-gnu/8.3.0/lto-wrapper
Target: x86_64-pc-linux-gnu
Configured with: /build/gcc/src/gcc/configure --prefix=/usr --libdir=/usr/lib --libexecdir=/usr/lib --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=https://bugs.archlinux.org/ --enable-languages=c,c++,ada,fortran,go,lto,objc,obj-c++ --enable-shared --enable-threads=posix --enable-libmpx --with-system-zlib --with-isl --enable-__cxa_atexit --disable-libunwind-exceptions --enable-clocale=gnu --disable-libstdcxx-pch --disable-libssp --enable-gnu-unique-object --enable-linker-build-id --enable-lto --enable-plugin --enable-install-libiberty --with-linker-hash-style=gnu --enable-gnu-indirect-function --enable-multilib --disable-werror --enable-checking=release --enable-default-pie --enable-default-ssp --enable-cet=auto
Thread model: posix
gcc version 8.3.0 (GCC) 

matmul.v

//Single Port RAM
module my_single_port_ram (addr0, ce0, d0, we0, q0,  clk);

  parameter DWIDTH = 16;
  parameter AWIDTH = 4;
  parameter MEM_SIZE = 16;

  input [AWIDTH-1:0] addr0;
  input ce0;
  input [DWIDTH-1:0] d0;
  input we0;
  output [DWIDTH-1:0] q0;
  input clk;

  reg [DWIDTH-1:0] q0;
  reg [DWIDTH-1:0] ram[MEM_SIZE-1:0];

  always @(posedge clk)  
  begin 
      if (ce0) 
      begin
          if (we0) 
          begin 
              ram[addr0] <= d0; 
          end 
          q0 <= ram[addr0];
      end
  end

endmodule

//Multiplier module (just wraps the * operator in a module
//so that we can use verilog style 'for generate' stmts in
//the main matrix multiplier module)
module qmult(i_multiplicand,i_multiplier,o_result);

  input [17:0] i_multiplicand;
  input [17:0] i_multiplier;
  output [17:0] o_result;

  assign o_result = i_multiplicand * i_multiplier;

endmodule

//Adder module (just wraps the + operator in a module
//so that we can use verilog style 'for generate' stmts in
//the main matrix multiplier module)
module qadd(a,b,c);

  input [17:0] a;
  input [17:0] b;
  output [17:0] c;

  assign c = a + b;
endmodule

//The main module. Multiplies two 4x4 matrices.
//The two inputs matrices (A and B) are stored
//in BRAMs first. The output matrix (C) is also
//stored in a BRAM.
module matrix_multiplication(clk, reset, we1, we2, start, data_in1, data_in2, data_out);
  input clk;
  input reset;
  input we1;  
  input we2;  
  input start;
  input [17:0] data_in1;
  input [17:0] data_in2;
  output [17:0] data_out;  

 wire [17:0] mat_A;  
 wire [17:0] mat_B;  
 reg wen;  
 reg [17:0] data_in;  
 reg [3:0] addr_in;  
 reg [4:0] address;  

 //Local (distributed) memory
 reg [17:0] matrixA[3:0][3:0];
 reg [17:0] matrixB[3:0][3:0];  

 wire [17:0] tmp1[3:0][3:0];
 wire [17:0] tmp2[3:0][3:0];
 wire [17:0] tmp3[3:0][3:0];
 wire [17:0] tmp4[3:0][3:0];
 wire [17:0] tmp5[3:0][3:0];
 wire [17:0] tmp6[3:0][3:0];
 wire [17:0] tmp7[3:0][3:0];  

  // BRAM matrix A  
  my_single_port_ram matrix_A_u (
    .addr0(addr_in),
    .ce0(1'b1), 
    .d0(data_in1), 
    .we0(we1), 
    .q0(mat_A), 
    .clk(clk));

  // BRAM matrix B  
  my_single_port_ram matrix_B_u(
    .addr0(addr_in),
    .ce0(1'b1), 
    .d0(data_in2), 
    .we0(we2), 
    .q0(mat_B), 
    .clk(clk));

    always @(posedge clk or posedge reset)  
      begin  
           if(reset && !start) begin  
                addr_in <= 0;  
           end  
           else begin  
                if(addr_in<15) begin
                  addr_in <= addr_in + 1;  
                end else begin
                  addr_in <= addr_in;  
                end  

                matrixA[addr_in/4][addr_in-(addr_in/4)*4] <= mat_A ;  
                matrixB[addr_in/4][addr_in-(addr_in/4)*4] <= mat_B ;  
           end  
      end  

    //   genvar i,j,k;  
    //   generate  
    //   for(i=0;i<4;i=i+1) begin:gen1  
    //   for(j=0;j<4;j=j+1) begin:gen2  
           // fixed point multiplication  
           qmult mult_u1(.i_multiplicand(matrixA[0][0]),.i_multiplier(matrixB[0][0]),.o_result(tmp1[0][0]));  
           qmult mult_u2(.i_multiplicand(matrixA[0][1]),.i_multiplier(matrixB[1][0]),.o_result(tmp2[0][0]));  
           qmult mult_u3(.i_multiplicand(matrixA[0][2]),.i_multiplier(matrixB[2][0]),.o_result(tmp3[0][0]));  
           qmult mult_u4(.i_multiplicand(matrixA[0][3]),.i_multiplier(matrixB[3][0]),.o_result(tmp4[0][0]));  
           // fixed point addition  
           qadd  Add_u1(.a(tmp1[0][0]),.b(tmp2[0][0]),.c(tmp5[0][0]));  
           qadd  Add_u2(.a(tmp3[0][0]),.b(tmp4[0][0]),.c(tmp6[0][0]));  
           qadd  Add_u3(.a(tmp5[0][0]),.b(tmp6[0][0]),.c(tmp7[0][0]));  
    //   end  
    //   end  
    //   endgenerate  

      always @(posedge clk or posedge reset)  
      begin  
           if(reset && !start) begin  
                address <= 0;  
                wen <= 0;  
                end  
           else begin  
                address <= address + 1;  
                if(address<16) begin  
                     wen <= 1;  
                     data_in <= tmp7[address/4][address-(address/4)*4];  
                end  
                else  
                begin  
                     wen <= 0;            
                end  
           end  
      end  

      // BRAM matrix C  
      my_single_port_ram matrix_out_u(
        .addr0(address[3:0]),
        .ce0(1'b1), 
        .d0(data_in), 
        .we0(wen), 
        .q0(data_out), 
        .clk(clk));      
 endmodule

gdb --args ./odin_II -V regression_test/benchmark/my_bugs/matmul.v

 ✔  269  11:14:06
GNU gdb (GDB) 8.2.1
Copyright (C) 2018 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-pc-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
    <http://www.gnu.org/software/gdb/documentation/>.

For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from ./odin_II...done.
(gdb) r
Starting program: /home/jbrown17/workspace/vtr-verilog-to-routing/ODIN_II/odin_II -V regression_test/benchmark/my_bugs/matmul.v
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/usr/lib/libthread_db.so.1".
--------------------------------------------------------------------
Welcome to ODIN II version 0.1 - the better High level synthesis tools++ targetting FPGAs (mainly VPR)
Email: jamieson.peter@gmail.com and ken@unb.ca for support issues

--------------------------------------------------------------------
High-level synthesis Begin
Parser starting - we'll create an abstract syntax tree. Note this tree can be viewed using Grap Viz (see documentation)
Preprocessing verilog.
Optimizing module by AST based optimizations
Converting AST into a Netlist. Note this netlist can be viewed using GraphViz (see documentation)
--------------
Odin has decided you MAY fail ... :

WARNING (1):NETLIST_ERROR Rounding memory <matrixA> of size <15> to closest power of two: 16.
WARNING (2):NETLIST_ERROR Rounding memory <matrixB> of size <15> to closest power of two: 16.
WARNING (3):NETLIST_ERROR Rounding memory <tmp1> of size <15> to closest power of two: 16.
WARNING (4):NETLIST_ERROR Rounding memory <tmp2> of size <15> to closest power of two: 16.
WARNING (5):NETLIST_ERROR Rounding memory <tmp3> of size <15> to closest power of two: 16.
WARNING (6):NETLIST_ERROR Rounding memory <tmp4> of size <15> to closest power of two: 16.
WARNING (7):NETLIST_ERROR Rounding memory <tmp5> of size <15> to closest power of two: 16.
WARNING (8):NETLIST_ERROR Rounding memory <tmp6> of size <15> to closest power of two: 16.
WARNING (9):NETLIST_ERROR Rounding memory <tmp7> of size <15> to closest power of two: 16.

Program received signal SIGSEGV, Segmentation fault.
convert_multi_to_single_dimentional_array (node=0x5555558a46e0) at /home/jbrown17/workspace/vtr-verilog-to-routing/ODIN_II/SRC/netlist_create_from_ast.cpp:5976
5976            array_row = local_symbol_table[sc_spot]->types.variable.initial_value;
(gdb) bt
#0  convert_multi_to_single_dimentional_array (node=0x5555558a46e0) at /home/jbrown17/workspace/vtr-verilog-to-routing/ODIN_II/SRC/netlist_create_from_ast.cpp:5976
#1  0x0000555555702fa6 in assignment_alias (assignment=0x5555558a4a20, instance_name_prefix=0x7fffffffddc4 "top") at /home/jbrown17/workspace/vtr-verilog-to-routing/ODIN_II/SRC/netlist_create_from_ast.cpp:3273
#2  0x00005555556fa38c in netlist_expand_ast_of_module (node=0x5555558a4a20, instance_name_prefix=0x7fffffffddc4 "top") at /home/jbrown17/workspace/vtr-verilog-to-routing/ODIN_II/SRC/netlist_create_from_ast.cpp:815
#3  0x00005555556fa4d6 in netlist_expand_ast_of_module (node=0x5555558a38c0, instance_name_prefix=0x7fffffffddc4 "top") at /home/jbrown17/workspace/vtr-verilog-to-routing/ODIN_II/SRC/netlist_create_from_ast.cpp:855
#4  0x000055555570682d in create_if_mux_statements (if_ast=0x5555558a5a80, if_node=0x555555977ae0, instance_name_prefix=0x7fffffffddc4 "top") at /home/jbrown17/workspace/vtr-verilog-to-routing/ODIN_II/SRC/netlist_create_from_ast.cpp:4433
#5  0x00005555557065a0 in create_if (if_ast=0x5555558a5a80, instance_name_prefix=0x7fffffffddc4 "top") at /home/jbrown17/workspace/vtr-verilog-to-routing/ODIN_II/SRC/netlist_create_from_ast.cpp:4348
#6  0x00005555556fa3ff in netlist_expand_ast_of_module (node=0x5555558a5a80, instance_name_prefix=0x7fffffffddc4 "top") at /home/jbrown17/workspace/vtr-verilog-to-routing/ODIN_II/SRC/netlist_create_from_ast.cpp:829
#7  0x00005555556fa4d6 in netlist_expand_ast_of_module (node=0x5555558a5b80, instance_name_prefix=0x7fffffffddc4 "top") at /home/jbrown17/workspace/vtr-verilog-to-routing/ODIN_II/SRC/netlist_create_from_ast.cpp:855
#8  0x00005555556fa4d6 in netlist_expand_ast_of_module (node=0x5555558a5c80, instance_name_prefix=0x7fffffffddc4 "top") at /home/jbrown17/workspace/vtr-verilog-to-routing/ODIN_II/SRC/netlist_create_from_ast.cpp:855
#9  0x00005555556fa4d6 in netlist_expand_ast_of_module (node=0x5555558932b0, instance_name_prefix=0x7fffffffddc4 "top") at /home/jbrown17/workspace/vtr-verilog-to-routing/ODIN_II/SRC/netlist_create_from_ast.cpp:855
#10 0x00005555556fa4d6 in netlist_expand_ast_of_module (node=0x5555558b9ce0, instance_name_prefix=0x7fffffffddc4 "top") at /home/jbrown17/workspace/vtr-verilog-to-routing/ODIN_II/SRC/netlist_create_from_ast.cpp:855
#11 0x00005555556f9e0c in convert_ast_to_netlist_recursing_via_modules (current_module=0x5555558b9ce0, instance_name=0x7fffffffddc4 "top", level=0)
    at /home/jbrown17/workspace/vtr-verilog-to-routing/ODIN_II/SRC/netlist_create_from_ast.cpp:613
#12 0x00005555556f9187 in create_netlist () at /home/jbrown17/workspace/vtr-verilog-to-routing/ODIN_II/SRC/netlist_create_from_ast.cpp:394
#13 0x0000555555654a4e in synthesize_verilog () at /home/jbrown17/workspace/vtr-verilog-to-routing/ODIN_II/SRC/odin_ii.cpp:125
#14 0x0000555555654ddf in start_odin_ii (argc=3, argv=0x7fffffffe058) at /home/jbrown17/workspace/vtr-verilog-to-routing/ODIN_II/SRC/odin_ii.cpp:254
#15 0x00005555556545bb in main ()
(gdb) fr 0
#0  convert_multi_to_single_dimentional_array (node=0x5555558a46e0) at /home/jbrown17/workspace/vtr-verilog-to-routing/ODIN_II/SRC/netlist_create_from_ast.cpp:5976
5976            array_row = local_symbol_table[sc_spot]->types.variable.initial_value;
(gdb) print local_symbol_table
$1 = (ast_node_t **) 0x555555971c10
(gdb) print local_symbol_table[sc_spot]
$2 = (ast_node_t *) 0xc1
(gdb) print local_symbol_table[sc_spot]->types
Cannot access memory at address 0xd9
(gdb) print sc_spot
$3 = -1
(gdb) print sc_spot
$4 = -1
(gdb) 
jeanlego commented 5 years ago

fixed