YosysHQ / yosys

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

Single-port memory inference error (Yosys + ISE) #1810

Closed rodrigomelo9 closed 3 years ago

rodrigomelo9 commented 4 years ago

I was comparing Yosys against ISE and Vivado, using examples provided by Xilinx. I found only this problem related to a Single-port memory inference when synth_xilinx with -ise- option is used with ISE as backend.

// Single-Port BRAM with Byte-wide Write Enable
// Read-First mode
// Single-process description
// Compact description of the write with a generate-for 
//   statement
// Column width and number of columns easily configurable
//
// bytewrite_ram_1b.v
//

module bytewrite_ram_1b (clk, we, addr, di, do);

parameter SIZE = 1024; 
parameter ADDR_WIDTH = 10; 
parameter COL_WIDTH = 8; 
parameter NB_COL = 4;

input clk;
input [NB_COL-1:0] we;
input [ADDR_WIDTH-1:0] addr;
input [NB_COL*COL_WIDTH-1:0] di;
output reg [NB_COL*COL_WIDTH-1:0] do;

reg [NB_COL*COL_WIDTH-1:0] RAM [SIZE-1:0];

always @(posedge clk)
begin
    do <= RAM[addr];
end

generate genvar i;
for (i = 0; i < NB_COL; i = i+1)
begin
always @(posedge clk)
begin
    if (we[i])
        RAM[addr][(i+1)*COL_WIDTH-1:i*COL_WIDTH] <= di[(i+1)*COL_WIDTH-1:i*COL_WIDTH];
    end 
end
endgenerate

endmodule

The Yosys command:

yosys -Q -p "read_verilog bytewrite_ram_1b; synth_xilinx -top bytewrite_ram_1b -family xc7 -ise; write_edif -pvector bra yosys.edif"

The ISE error message (when mapping):

...
Phase 12.34  Placement Validation (Checksum:847cfe79) REAL time: 26 secs 

Total REAL time to Placer completion: 26 secs 
Total CPU  time to Placer completion: 26 secs 
Running post-placement packing...
Writing output files...
ERROR:PhysDesignRules:2378 - Issue with pin connections and/or configuration on
   block:<RAM.0.0.0>:<RAMB36E1_RAMB36E1>.  The cascadable BlockRam feature is
   not used for port A (RAM_EXTENSION_A set to NONE). The highest order port A
   address bit (ADDRARDADDRL15) must be tied to LOGIC 1.
ERROR:PhysDesignRules:2379 - Issue with pin connections and/or configuration on
   block:<RAM.0.0.0>:<RAMB36E1_RAMB36E1>.  The cascadable BlockRam feature is
   not used for port B (RAM_EXTENSION_B set to NONE). The highest order port B
   address bit (ADDRBWRADDRL15) must be tied to LOGIC 1.
ERROR:Pack:1642 - Errors in physical DRC.

Mapping completed.
See MAP report file "bytewrite_ram_1b_map.mrp" for details.
Problem encountered during the packing phase.

Design Summary
--------------
Number of errors   :   3
Number of warnings :  81

Process "Map" failed
...
rodrigomelo9 commented 4 years ago

There are other (very similar, but no-change instead of read-first) file with exactly the same problem.

//
// Single-Port BRAM with Byte-wide Write Enable
//   4x9-bit write
//   No-Change mode
//   Single-process description
//   Compact description of the write with a generate-for statement
//   Column width and number of columns easily configurable 
//
// Download: ftp://ftp.xilinx.com/pub/documentation/misc/xstug_examples.zip
// File: HDL_Coding_Techniques/rams/bytewrite_nochange.v
//
module v_bytewrite_nochange (clk, we, addr, di, do);

  parameter SIZE    = 1024;
  parameter ADDR_WIDTH  = 10;
  parameter COL_WIDTH   = 9;
  parameter NB_COL  = 4;

  input                  clk;
  input      [NB_COL-1:0]        we;
  input      [ADDR_WIDTH-1:0]        addr;
  input      [NB_COL*COL_WIDTH-1:0]  di;
  output reg [NB_COL*COL_WIDTH-1:0]  do;

  reg        [NB_COL*COL_WIDTH-1:0]  RAM [SIZE-1:0];

  always @(posedge clk)
  begin
    if (~|we)
      do <= RAM[addr];
  end

  generate
  genvar i;
    for (i = 0; i < NB_COL; i = i+1)
    begin
      always @(posedge clk)
      begin  
        if (we[i]) 
          RAM[addr][(i+1)*COL_WIDTH-1:i*COL_WIDTH]
        <= di[(i+1)*COL_WIDTH-1:i*COL_WIDTH];
      end
    end
  endgenerate

endmodule

Here a similar write-first example which works (is implemented without errors):

//
// Single-Port BRAM with Byte-wide Write Enable
//   4x9-bit write
//   Write-First mode
//   Single-process description
//   Compact description of the write with a generate-for statement
//   Column width and number of columns easily configurable 
//
// Download: ftp://ftp.xilinx.com/pub/documentation/misc/xstug_examples.zip
// File: HDL_Coding_Techniques/rams/bytewrite_writefirst.v
//
module v_bytewrite_writefirst (clk, we, addr, di, do);

  parameter SIZE    = 1024;
  parameter ADDR_WIDTH  = 10;
  parameter COL_WIDTH   = 9;
  parameter NB_COL  = 4;

  input                  clk;
  input      [NB_COL-1:0]        we;
  input      [ADDR_WIDTH-1:0]        addr;
  input      [NB_COL*COL_WIDTH-1:0]  di;
  output reg [NB_COL*COL_WIDTH-1:0]  do;

  reg        [NB_COL*COL_WIDTH-1:0]  RAM [SIZE-1:0];

  generate
  genvar i;
    for (i = 0; i < NB_COL; i = i+1)
    begin
      always @(posedge clk)
      begin
        if (we[i])
     begin
          RAM[addr][(i+1)*COL_WIDTH-1:i*COL_WIDTH]
        <= di[(i+1)*COL_WIDTH-1:i*COL_WIDTH];
          do[(i+1)*COL_WIDTH-1:i*COL_WIDTH]
        <= di[(i+1)*COL_WIDTH-1:i*COL_WIDTH];
         end
        else
          do[(i+1)*COL_WIDTH-1:i*COL_WIDTH]
        <= RAM[addr][(i+1)*COL_WIDTH-1:i*COL_WIDTH];
      end
    end
  endgenerate

endmodule
rodrigomelo9 commented 4 years ago

@mwkmwkmwk these are examples from Xilinx, let me know if I can help you, providing own made minimalistic examples. Maybe I could put them somewhere under tests/memories. The same offer for #1809. I can provide the Verilog files and the scripts to run automatically from the command-line.

mwkmwkmwk commented 3 years ago

I think that one should be closed by #2900