Fixed bugs / added warning prints to PP3 BRAM initialization pass, added test for PP3 BRAM inference and initialization

Signed-off-by: Maciej Kurc <mkurc@antmicro.com>
diff --git a/ql-qlf-plugin/pp3/pp3_brams_map.v b/ql-qlf-plugin/pp3/pp3_brams_map.v
index 60422e1..7038333 100644
--- a/ql-qlf-plugin/pp3/pp3_brams_map.v
+++ b/ql-qlf-plugin/pp3/pp3_brams_map.v
@@ -463,8 +463,8 @@
 endgenerate
 
 	ram8k_2x1_cell_macro # (
-                       `include "pp3_bram_init_8_16.vh"
-                         )
+        .INIT(INIT)
+    )
     	_TECHMAP_REPLACE_ (
                        .A1_0(addr_wr0) , 
                        .A1_1(addr_wr1), 
@@ -666,8 +666,8 @@
 	if (data_width_int <=16)  begin
 
     	    ram8k_2x1_cell_macro # (
-                        `include "pp3_bram_init_32.vh"
-                            )
+                .INIT(INIT)
+            )
 			_TECHMAP_REPLACE_ (
                         .A1_0(addr_wr0) , 
                         .A1_1(addr_wr1), 
@@ -741,9 +741,9 @@
   	end
 	else if (data_width_int > 16)  begin
 
-    	     ram8k_2x1_cell_macro # (
-                        `include "pp3_bram_init_32.vh"
-                           )
+            ram8k_2x1_cell_macro # (
+                .INIT(INIT)
+            )
 			_TECHMAP_REPLACE_ (
                         .A1_0(addr_wr0) , 
                         .A1_1(addr_wr1), 
diff --git a/ql-qlf-plugin/pp3_braminit.cc b/ql-qlf-plugin/pp3_braminit.cc
index f521fa1..eb6362b 100644
--- a/ql-qlf-plugin/pp3_braminit.cc
+++ b/ql-qlf-plugin/pp3_braminit.cc
@@ -120,10 +120,17 @@
 			}
 		}
 
+        // TODO: Support RAM initialization for other widths than 8, 16 and 32
+        if (ramDataWidth != 8 && ramDataWidth != 16 && ramDataWidth != 32) {
+            log("WARNING: The RAM cell '%s' has data width of %d. Initialization of this width from a file is not supported yet!\n",
+                RTLIL::id2cstr(cell->name), ramDataWidth
+            );
+            continue;
+        }
+
 		/* Set attributes */
 		std::string val = "";
 		for (int i=ramDataDepth-1; i>=0; i--) {
-			//std::string val = "";
 			if (ramDataWidth == 8)
 	                     val += std::bitset<8>(mem[i]).to_string();
 			else if (ramDataWidth == 16)
@@ -131,7 +138,7 @@
 			else if (ramDataWidth == 32)
 	                     val += std::bitset<32>(mem[i]).to_string();
 		}
-		cell->setParam("\\INIT", RTLIL::Const::from_string(val));
+		cell->setParam(RTLIL::escape_id("INIT"), RTLIL::Const::from_string(val));
 	}
 }
 
diff --git a/ql-qlf-plugin/tests/Makefile b/ql-qlf-plugin/tests/Makefile
index 0fb5572..12fab91 100644
--- a/ql-qlf-plugin/tests/Makefile
+++ b/ql-qlf-plugin/tests/Makefile
@@ -19,7 +19,8 @@
 	logic \
 	mux \
 	tribuf \
-	fsm #\
+	fsm \
+	pp3_bram #\
 #	qlf_k6n10_bram \
 
 include $(shell pwd)/../../Makefile_test.common
@@ -36,4 +37,5 @@
 mux_verify = true
 tribuf_verify = true
 fsm_verify = true
+pp3_bram_verify = true
 #qlf_k6n10_bram_verify = true
diff --git a/ql-qlf-plugin/tests/pp3_bram/init.txt b/ql-qlf-plugin/tests/pp3_bram/init.txt
new file mode 100644
index 0000000..9d8fb6f
--- /dev/null
+++ b/ql-qlf-plugin/tests/pp3_bram/init.txt
@@ -0,0 +1,6 @@
+@000
+1234
+5678
+ABCD
+EFFF
+
diff --git a/ql-qlf-plugin/tests/pp3_bram/pp3_bram.tcl b/ql-qlf-plugin/tests/pp3_bram/pp3_bram.tcl
new file mode 100644
index 0000000..8c9dde1
--- /dev/null
+++ b/ql-qlf-plugin/tests/pp3_bram/pp3_bram.tcl
@@ -0,0 +1,47 @@
+yosys -import
+if { [info procs synth_quicklogic] == {} } { plugin -i ql-qlf }
+yosys -import  ;# ingest plugin commands
+
+read_verilog $::env(DESIGN_TOP).v
+design -save read
+
+design -load read
+synth_quicklogic -family pp3 -top top_bram_9_16
+yosys cd top_bram_9_16
+stat
+select -assert-count 1 t:ckpad
+select -assert-count 35 t:inpad
+select -assert-count 16 t:outpad
+select -assert-count 1 t:ram8k_2x1_cell_macro
+
+design -load read
+synth_quicklogic -family pp3 -top top_bram_9_32
+yosys cd top_bram_9_32
+stat
+select -assert-count 1 t:ckpad
+select -assert-count 51 t:inpad
+select -assert-count 32 t:outpad
+select -assert-count 1 t:ram8k_2x1_cell_macro
+
+design -load read
+synth_quicklogic -family pp3 -top top_bram_10_16
+yosys cd top_bram_10_16
+stat
+select -assert-count 1 t:ckpad
+select -assert-count 37 t:inpad
+select -assert-count 16 t:outpad
+select -assert-count 1 t:ram8k_2x1_cell_macro
+
+# BRAM initialization from file using pp3_braminig pass test
+design -load read
+synth_quicklogic -family pp3 -top top_bram_init
+yosys cd top_bram_init
+stat
+select -assert-count 1 t:ckpad
+select -assert-count 39 t:inpad
+select -assert-count 18 t:outpad
+select -assert-count 1 t:ram8k_2x1_cell_macro
+
+set INIT 8192'h0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000efffabcd56781234
+select -assert-count 1 t:ram8k_2x1_cell_macro r:INIT=$INIT \%i
+
diff --git a/ql-qlf-plugin/tests/pp3_bram/pp3_bram.v b/ql-qlf-plugin/tests/pp3_bram/pp3_bram.v
new file mode 100644
index 0000000..b7cd54b
--- /dev/null
+++ b/ql-qlf-plugin/tests/pp3_bram/pp3_bram.v
@@ -0,0 +1,129 @@
+module my_ram (CLK, WADR, WDAT, WEN, RADR, RDAT, REN);
+
+    parameter DBITS = 36;
+    parameter ABITS = 9;
+
+    input  wire CLK;
+
+    input  wire [ABITS-1:0] WADR;
+    input  wire [DBITS-1:0] WDAT;
+    input  wire             WEN;
+
+    input  wire [ABITS-1:0] RADR;
+    output reg  [DBITS-1:0] RDAT;
+    input  wire             REN;
+
+    localparam SIZE = 1 << ABITS;
+    reg [DBITS-1:0] mem[0:SIZE-1];
+
+    always @(posedge CLK) begin
+        if (WEN) mem[WADR] <= WDAT;
+    end
+
+    always @(posedge CLK) begin
+        RDAT <= mem[RADR];
+    end
+
+endmodule
+
+// ============================================================================
+
+module top_bram_9_16 (CLK, WADR, WDAT, WEN, RADR, RDAT);
+
+    input  wire        CLK;
+
+    input  wire [8 :0] WADR;
+    input  wire [15:0] WDAT;
+    input  wire        WEN;
+
+    input  wire [8 :0] RADR;
+    output wire [15:0] RDAT;
+
+    my_ram #(.DBITS(16), .ABITS(9)) the_ram (
+        .CLK    (CLK),
+        .WADR   (WADR),
+        .WDAT   (WDAT),
+        .WEN    (WEN),
+        .RADR   (RADR),
+        .RDAT   (RDAT),
+        .REN    (1'b0)
+    );
+
+endmodule
+
+module top_bram_9_32 (CLK, WADR, WDAT, WEN, RADR, RDAT);
+
+    input  wire        CLK;
+
+    input  wire [8 :0] WADR;
+    input  wire [31:0] WDAT;
+    input  wire        WEN;
+
+    input  wire [8 :0] RADR;
+    output wire [31:0] RDAT;
+
+    my_ram #(.DBITS(32), .ABITS(9)) the_ram (
+        .CLK    (CLK),
+        .WADR   (WADR),
+        .WDAT   (WDAT),
+        .WEN    (WEN),
+        .RADR   (RADR),
+        .RDAT   (RDAT),
+        .REN    (1'b0)
+    );
+
+endmodule
+
+module top_bram_10_16 (CLK, WADR, WDAT, WEN, RADR, RDAT);
+
+    input  wire        CLK;
+
+    input  wire [9 :0] WADR;
+    input  wire [15:0] WDAT;
+    input  wire        WEN;
+
+    input  wire [9 :0] RADR;
+    output wire [15:0] RDAT;
+
+    my_ram #(.DBITS(16), .ABITS(10)) the_ram (
+        .CLK    (CLK),
+        .WADR   (WADR),
+        .WDAT   (WDAT),
+        .WEN    (WEN),
+        .RADR   (RADR),
+        .RDAT   (RDAT),
+        .REN    (1'b0)
+    );
+
+endmodule
+
+module top_bram_init (CLK, WADR, WDAT, WEN, RADR, RDAT);
+
+    input  wire        CLK;
+
+    input  wire [9 :0] WADR;
+    input  wire [17:0] WDAT;
+    input  wire        WEN;
+
+    input  wire [9 :0] RADR;
+    output wire [17:0] RDAT;
+
+    RAM_8K_BLK # (
+        .INIT_FILE      ("init.txt"),
+        .addr_int       (9),
+        .data_depth_int (1 << 9),
+        .data_width_int (16)
+    ) the_ram (
+        .WClk       (CLK),
+        .RClk       (CLK),
+        .WClk_En    (1'b1),
+        .RClk_En    (1'b1),
+        .WA         (WADR),
+        .WD         (WDAT),
+        .WEN        (WEN),
+        .RA         (RADR),
+        .RD         (RDAT)
+    );
+
+endmodule
+