added tests for spram, dpram & fifo macros
diff --git a/ql-qlf-plugin/tests/Makefile b/ql-qlf-plugin/tests/Makefile
index 661e92e..cd1c7e1 100644
--- a/ql-qlf-plugin/tests/Makefile
+++ b/ql-qlf-plugin/tests/Makefile
@@ -37,26 +37,39 @@
 #	qlf_k6n10_bram \
 
 SIM_TESTS = \
-    qlf_k6n10f/sim_dsp_mult_cfg_ports \
-    qlf_k6n10f/sim_dsp_mult_cfg_params \
-    qlf_k6n10f/sim_dsp_mult_r_cfg_ports \
-    qlf_k6n10f/sim_dsp_mult_r_cfg_params \
-    qlf_k6n10f/sim_dsp_fir_cfg_ports \
-    qlf_k6n10f/sim_dsp_fir_cfg_params \
-    qlf_k6n10f/sim_dsp_simd_cfg_ports \
-    qlf_k6n10f/sim_dsp_simd_cfg_params \
-    qlf_k6n10f/sim_tc36fifo
+     qlf_k6n10f/sim_dsp_mult_cfg_ports \
+     qlf_k6n10f/sim_dsp_mult_cfg_ports \
+     qlf_k6n10f/sim_dsp_mult_cfg_params \
+     qlf_k6n10f/sim_dsp_mult_r_cfg_ports \
+     qlf_k6n10f/sim_dsp_mult_r_cfg_params \
+     qlf_k6n10f/sim_dsp_fir_cfg_ports \
+     qlf_k6n10f/sim_dsp_fir_cfg_params \
+     qlf_k6n10f/sim_dsp_simd_cfg_ports \
+     qlf_k6n10f/sim_dsp_simd_cfg_params \
+     qlf_k6n10f/sim_tc36fifo
 
 # Those tests perform synthesis and simulation of synthesis results
 POST_SYNTH_SIM_TESTS = \
-    qlf_k6n10f/bram_tdp \
-    qlf_k6n10f/bram_sdp \
-    qlf_k6n10f/bram_tdp_split \
-    qlf_k6n10f/bram_sdp_split \
-    qlf_k6n10f/dsp_mult_post_synth_sim \
-    qlf_k6n10f/dsp_simd_post_synth_sim \
-    qlf_k6n10f/bram_asymmetric_wider_write \
-    qlf_k6n10f/bram_asymmetric_wider_read
+     qlf_k6n10f/asymmetric_bram36k_sfifo \
+     qlf_k6n10f/asymmetric_bram36k_afifo \
+     qlf_k6n10f/bram36k_sfifo \
+     qlf_k6n10f/bram36k_afifo \
+     qlf_k6n10f/bram18k_afifo \
+     qlf_k6n10f/bram18k_sfifo \
+     qlf_k6n10f/bram18k_tdp \
+     qlf_k6n10f/bram36k_tdp \
+     qlf_k6n10f/bram18k_sdp \
+     qlf_k6n10f/bram36k_sdp \
+     qlf_k6n10f/asymmetric_bram36k_sdp \
+     qlf_k6n10f/asymmetric_bram18k_sdp \
+     qlf_k6n10f/bram_tdp \
+     qlf_k6n10f/bram_sdp \
+     qlf_k6n10f/bram_tdp_split \
+     qlf_k6n10f/bram_sdp_split \
+     qlf_k6n10f/dsp_mult_post_synth_sim \
+     qlf_k6n10f/dsp_simd_post_synth_sim \
+     qlf_k6n10f/bram_asymmetric_wider_write \
+     qlf_k6n10f/bram_asymmetric_wider_read
 
 include $(shell pwd)/../../Makefile_test.common
 
diff --git a/ql-qlf-plugin/tests/qlf_k6n10f/asymmetric_bram18k_sdp/asymmetric_bram18k_sdp.tcl b/ql-qlf-plugin/tests/qlf_k6n10f/asymmetric_bram18k_sdp/asymmetric_bram18k_sdp.tcl
new file mode 100644
index 0000000..0579462
--- /dev/null
+++ b/ql-qlf-plugin/tests/qlf_k6n10f/asymmetric_bram18k_sdp/asymmetric_bram18k_sdp.tcl
@@ -0,0 +1,27 @@
+yosys -import
+
+if { [info procs ql-qlf-k6n10f] == {} } { plugin -i ql-qlf }
+yosys -import  ;
+
+read_verilog $::env(DESIGN_TOP).v
+design -save asymmetric_bram18k_sdp
+
+select spram_9x2048_18x1024
+select *
+synth_quicklogic -family qlf_k6n10f -top spram_9x2048_18x1024 -bram_types
+opt_expr -undriven
+opt_clean
+stat
+write_verilog sim/spram_9x2048_18x1024_post_synth.v
+select -assert-count 1 t:TDP36K_BRAM_WR_X9_RD_X18_split
+
+select -clear
+design -load asymmetric_bram18k_sdp
+select spram_18x1024_9x2048
+select *
+synth_quicklogic -family qlf_k6n10f -top spram_18x1024_9x2048 -bram_types
+opt_expr -undriven
+opt_clean
+stat
+write_verilog sim/spram_18x1024_9x2048_post_synth.v
+select -assert-count 1 t:TDP36K_BRAM_WR_X18_RD_X9_split
\ No newline at end of file
diff --git a/ql-qlf-plugin/tests/qlf_k6n10f/asymmetric_bram18k_sdp/asymmetric_bram18k_sdp.v b/ql-qlf-plugin/tests/qlf_k6n10f/asymmetric_bram18k_sdp/asymmetric_bram18k_sdp.v
new file mode 100644
index 0000000..272696b
--- /dev/null
+++ b/ql-qlf-plugin/tests/qlf_k6n10f/asymmetric_bram18k_sdp/asymmetric_bram18k_sdp.v
@@ -0,0 +1,93 @@
+module spram_9x2048_18x1024 (
+    WEN_i,
+    REN_i,
+    clock0,
+    clock1,
+    WR_ADDR_i,
+    RD_ADDR_i,
+    WDATA_i,
+    RDATA_o
+);
+
+parameter WR_ADDR_WIDTH = 11;
+parameter RD_ADDR_WIDTH = 10;
+parameter WR_DATA_WIDTH = 9;
+parameter RD_DATA_WIDTH = 18;
+parameter BE_WIDTH = 1;
+
+input wire WEN_i;
+input wire REN_i;
+input wire clock0;
+input wire clock1;
+input wire [WR_ADDR_WIDTH-1 :0] WR_ADDR_i;
+input wire [RD_ADDR_WIDTH-1 :0] RD_ADDR_i;
+input wire [WR_DATA_WIDTH-1 :0] WDATA_i;
+output wire [RD_DATA_WIDTH-1 :0] RDATA_o;
+
+RAM_18K_BLK #(
+              .WR_ADDR_WIDTH(WR_ADDR_WIDTH),
+              .RD_ADDR_WIDTH(RD_ADDR_WIDTH),
+              .WR_DATA_WIDTH(WR_DATA_WIDTH),
+              .RD_DATA_WIDTH(RD_DATA_WIDTH),
+              .BE_WIDTH(BE_WIDTH)
+              ) spram_x18_inst (
+              
+              .WEN_i(WEN_i),
+              .WR_BE_i(1'b1),
+              .REN_i(REN_i),              
+              .WR_CLK_i(clock0),
+              .RD_CLK_i(clock1),
+              .WR_ADDR_i(WR_ADDR_i),
+              .RD_ADDR_i(RD_ADDR_i),
+              .WDATA_i(WDATA_i),
+              .RDATA_o(RDATA_o)
+              );
+              
+endmodule    
+
+module spram_18x1024_9x2048 (
+    WEN_i,
+    REN_i,
+    clock0,
+    clock1,
+    WR_ADDR_i,
+    RD_ADDR_i,
+    WDATA_i,
+    RDATA_o
+);
+
+parameter WR_ADDR_WIDTH = 10;
+parameter RD_ADDR_WIDTH = 11;
+parameter WR_DATA_WIDTH = 18;
+parameter RD_DATA_WIDTH = 9;
+parameter BE_WIDTH = 2;
+
+input wire WEN_i;
+input wire REN_i;
+input wire clock0;
+input wire clock1;
+input wire [WR_ADDR_WIDTH-1 :0] WR_ADDR_i;
+input wire [RD_ADDR_WIDTH-1 :0] RD_ADDR_i;
+input wire [WR_DATA_WIDTH-1 :0] WDATA_i;
+output wire [RD_DATA_WIDTH-1 :0] RDATA_o;
+
+RAM_18K_BLK #(
+              .WR_ADDR_WIDTH(WR_ADDR_WIDTH),
+              .RD_ADDR_WIDTH(RD_ADDR_WIDTH),
+              .WR_DATA_WIDTH(WR_DATA_WIDTH),
+              .RD_DATA_WIDTH(RD_DATA_WIDTH),
+              .BE_WIDTH(BE_WIDTH)
+              ) spram_x18_inst (
+              
+              .WEN_i(WEN_i),
+              .WR_BE_i(2'b11),
+              .REN_i(REN_i),              
+              .WR_CLK_i(clock0),
+              .RD_CLK_i(clock1),
+              .WR_ADDR_i(WR_ADDR_i),
+              .RD_ADDR_i(RD_ADDR_i),
+              .WDATA_i(WDATA_i),
+              .RDATA_o(RDATA_o)
+              );
+              
+endmodule    
\ No newline at end of file
diff --git a/ql-qlf-plugin/tests/qlf_k6n10f/asymmetric_bram18k_sdp/sim/Makefile b/ql-qlf-plugin/tests/qlf_k6n10f/asymmetric_bram18k_sdp/sim/Makefile
new file mode 100644
index 0000000..3c8c84a
--- /dev/null
+++ b/ql-qlf-plugin/tests/qlf_k6n10f/asymmetric_bram18k_sdp/sim/Makefile
@@ -0,0 +1,39 @@
+# Copyright (C) 2019-2022 The SymbiFlow Authors
+#
+# Use of this source code is governed by a ISC-style
+# license that can be found in the LICENSE file or at
+# https://opensource.org/licenses/ISC
+#
+# SPDX-License-Identifier: ISC
+
+TESTBENCH = asymmetric_bram18k_sdp_tb.v
+POST_SYNTH = spram_9x2048_18x1024_post_synth spram_18x1024_9x2048_post_synth
+ADDR_WIDTH0 = 11 10
+DATA_WIDTH0 = 9 18
+ADDR_WIDTH1 = 10 11
+DATA_WIDTH1 = 18 9
+TOP = spram_9x2048_18x1024 spram_18x1024_9x2048
+ADDR0_DEFINES = $(foreach awidth0, $(ADDR_WIDTH0),-DADDR_WIDTH0="$(awidth0)")
+ADDR1_DEFINES = $(foreach awidth1, $(ADDR_WIDTH1),-DADDR_WIDTH1="$(awidth1)")
+DATA0_DEFINES = $(foreach dwidth0, $(DATA_WIDTH0),-DDATA_WIDTH0="$(dwidth0)")
+DATA1_DEFINES = $(foreach dwidth1, $(DATA_WIDTH1),-DDATA_WIDTH1="$(dwidth1)")
+TOP_DEFINES = $(foreach top, $(TOP),-DTOP="$(top)")
+VCD_DEFINES = $(foreach vcd, $(POST_SYNTH),-DVCD="$(vcd).vcd")
+
+SIM_LIBS = $(shell find ../../../../qlf_k6n10f -name "*.v" -not -name "*_map.v")
+
+define simulate_post_synth
+	@iverilog  -vvvv -g2005 $(word $(1),$(ADDR0_DEFINES)) $(word $(1),$(ADDR1_DEFINES)) $(word $(1),$(DATA0_DEFINES)) $(word $(1),$(DATA1_DEFINES)) $(word $(1),$(TOP_DEFINES)) $(word $(1),$(VCD_DEFINES)) -o $(word $(1),$(POST_SYNTH)).vvp $(word $(1),$(POST_SYNTH)).v $(SIM_LIBS) $(TESTBENCH) > $(word $(1),$(POST_SYNTH)).vvp.log 2>&1
+	@vvp -vvvv $(word $(1),$(POST_SYNTH)).vvp > $(word $(1),$(POST_SYNTH)).vcd.log 2>&1
+endef
+
+define clean_post_synth_sim
+	@rm -rf  $(word $(1),$(POST_SYNTH)).vcd $(word $(1),$(POST_SYNTH)).vvp $(word $(1),$(POST_SYNTH)).vvp.log $(word $(1),$(POST_SYNTH)).vcd.log
+endef
+
+#FIXME: $(call simulate_post_synth,3)
+sim:
+	$(call simulate_post_synth,1)
+	$(call clean_post_synth_sim,1)
+	$(call simulate_post_synth,2)
+	$(call clean_post_synth_sim,2)
\ No newline at end of file
diff --git a/ql-qlf-plugin/tests/qlf_k6n10f/asymmetric_bram18k_sdp/sim/asymmetric_bram18k_sdp_tb.v b/ql-qlf-plugin/tests/qlf_k6n10f/asymmetric_bram18k_sdp/sim/asymmetric_bram18k_sdp_tb.v
new file mode 100644
index 0000000..86abcec
--- /dev/null
+++ b/ql-qlf-plugin/tests/qlf_k6n10f/asymmetric_bram18k_sdp/sim/asymmetric_bram18k_sdp_tb.v
@@ -0,0 +1,170 @@
+// Copyright (C) 2019-2022 The SymbiFlow Authors
+//
+// Use of this source code is governed by a ISC-style
+// license that can be found in the LICENSE file or at
+// https://opensource.org/licenses/ISC
+//
+// SPDX-License-Identifier: ISC
+
+`timescale 1ns/1ps
+
+`define STRINGIFY(x) `"x`"
+
+module TB;
+	localparam PERIOD = 50;
+	localparam ADDR_INCR = 1;
+
+	reg clk_0;
+  reg clk_1;
+	reg rce;
+	reg [`ADDR_WIDTH1-1:0] ra;
+	wire [`DATA_WIDTH1-1:0] rq;
+	reg wce;
+	reg [`ADDR_WIDTH0-1:0] wa;
+	reg [`DATA_WIDTH0-1:0] wd;
+
+	initial clk_0 = 0;
+	initial clk_1 = 0;
+	initial ra = 0;
+  initial wa = 0;
+  initial wd = 0;
+	initial rce = 0;
+  initial wce = 0;
+	initial forever #(PERIOD / 2.0) clk_0 = ~clk_0;
+  //initial forever #(PERIOD / 2.0) clk_1 = ~clk_1;
+	initial begin
+		#(PERIOD / 4.0);
+		forever #(PERIOD / 2.0) clk_1 = ~clk_1;
+	end
+	initial begin
+		$dumpfile(`STRINGIFY(`VCD));
+		$dumpvars;
+	end
+
+	integer a;
+	integer b;
+
+	reg done_0;
+	initial done_0 = 1'b0;
+	wire done_sim = done_0;
+
+	reg [`DATA_WIDTH1-1:0] expected_0;
+
+	reg read_test_0;
+	initial read_test_0 = 0;
+
+
+	wire error_0 = (read_test_0) ? (rq !== expected_0) : 0;
+
+	integer error_0_cnt = 0;
+
+	always @ (posedge clk_1)
+	begin
+		if (error_0)
+			error_0_cnt <= error_0_cnt + 1'b1;
+	end
+
+case (`STRINGIFY(`TOP))
+"spram_9x2048_18x1024": begin
+	initial #(1) begin
+		// Write data
+		for (a = 0; a < (1<<`ADDR_WIDTH0) ; a = a + ADDR_INCR) begin
+			@(negedge clk_0) begin
+				wa = a[`ADDR_WIDTH0-1:0];
+				wd = a[9:1];
+				wce = 1;
+			end
+			@(posedge clk_0) begin
+				#(PERIOD/10) wce = 0;
+			end
+		end
+		// Read data
+		read_test_0 = 1;
+		for (a = 0; a < (1<<`ADDR_WIDTH1); a = a + ADDR_INCR) begin
+			@(negedge clk_1) begin
+				ra = a;
+				rce = 1;
+			end
+			@(posedge clk_1) begin
+        expected_0 <= {a[8],a[8],a[7:0],a[7:0]};
+				#(PERIOD/10) rce = 0;
+				if ( rq !== expected_0) begin
+					$display("%d: PORT 0: FAIL: mismatch act=%x exp=%x at %x", $time, rq, expected_0, a);
+				end else begin
+					$display("%d: PORT 0: OK: act=%x exp=%x at %x", $time, rq, expected_0, a);
+				end
+			end
+		end
+		done_0 = 1'b1;
+    a = 0;
+	end
+end
+"spram_18x1024_9x2048": begin
+	initial #(1) begin
+		// Write data
+		for (a = 0; a < (1<<`ADDR_WIDTH0) ; a = a + ADDR_INCR) begin
+			@(negedge clk_0) begin
+				wa = a[`ADDR_WIDTH0-1:0];
+				wd = {a[8],a[8],a[7:0],a[7:0]};
+				wce = 1;
+			end
+			@(posedge clk_0) begin
+				#(PERIOD/10) wce = 0;
+			end
+		end
+		// Read data
+		read_test_0 = 1;
+		for (a = 0; a < (1<<`ADDR_WIDTH1); a = a + ADDR_INCR) begin
+			@(negedge clk_1) begin
+				ra = a;
+				rce = 1;
+			end
+			@(posedge clk_1) begin
+        expected_0 <= {a[9:1]};
+				#(PERIOD/10) rce = 0;
+				if ( rq !== expected_0) begin
+					$display("%d: PORT 0: FAIL: mismatch act=%x exp=%x at %x", $time, rq, expected_0, a);
+				end else begin
+					$display("%d: PORT 0: OK: act=%x exp=%x at %x", $time, rq, expected_0, a);
+				end
+			end
+		end
+		done_0 = 1'b1;
+    a = 0;
+	end
+end  
+endcase
+
+	// Scan for simulation finish
+	always @(posedge clk_1) begin
+		if (done_sim)
+			$finish_and_return( (error_0_cnt == 0) ? 0 : -1 );
+	end
+
+	case (`STRINGIFY(`TOP))
+		"spram_9x2048_18x1024": begin
+			spram_9x2048_18x1024 #() bram (
+				.clock0(clk_0),
+        .clock1(clk_1),        
+				.REN_i(rce),
+				.RD_ADDR_i(ra),
+				.RDATA_o(rq),
+				.WEN_i(wce),
+				.WR_ADDR_i(wa),
+				.WDATA_i(wd)
+			);
+		end
+		"spram_18x1024_9x2048": begin
+			spram_18x1024_9x2048 #() bram (
+				.clock0(clk_0),
+        .clock1(clk_1),        
+				.REN_i(rce),
+				.RD_ADDR_i(ra),
+				.RDATA_o(rq),
+				.WEN_i(wce),
+				.WR_ADDR_i(wa),
+				.WDATA_i(wd)
+			);
+		end
+	endcase
+endmodule
diff --git a/ql-qlf-plugin/tests/qlf_k6n10f/asymmetric_bram36k_afifo/asymmetric_bram36k_afifo.tcl b/ql-qlf-plugin/tests/qlf_k6n10f/asymmetric_bram36k_afifo/asymmetric_bram36k_afifo.tcl
new file mode 100644
index 0000000..66e2686
--- /dev/null
+++ b/ql-qlf-plugin/tests/qlf_k6n10f/asymmetric_bram36k_afifo/asymmetric_bram36k_afifo.tcl
@@ -0,0 +1,49 @@
+yosys -import
+
+if { [info procs ql-qlf-k6n10f] == {} } { plugin -i ql-qlf }
+yosys -import  ;
+
+read_verilog $::env(DESIGN_TOP).v
+design -save asymmetric_bram36k_afifo
+
+select af4096x9_1024x36
+select *
+synth_quicklogic -family qlf_k6n10f -top af4096x9_1024x36 -bram_types
+opt_expr -undriven
+opt_clean
+stat
+write_verilog sim/af4096x9_1024x36_post_synth.v
+select -assert-count 1 t:TDP36K_FIFO_ASYNC_WR_X9_RD_X36_nonsplit
+
+select -clear
+design -load asymmetric_bram36k_afifo
+select af2048x18_1024x36
+select *
+synth_quicklogic -family qlf_k6n10f -top af2048x18_1024x36 -bram_types
+opt_expr -undriven
+opt_clean
+stat
+write_verilog sim/af2048x18_1024x36_post_synth.v
+select -assert-count 1 t:TDP36K_FIFO_ASYNC_WR_X18_RD_X36_nonsplit
+
+select -clear
+design -load asymmetric_bram36k_afifo
+select af2048x18_4098x9
+select *
+synth_quicklogic -family qlf_k6n10f -top af2048x18_4098x9 -bram_types
+opt_expr -undriven
+opt_clean
+stat
+write_verilog sim/af2048x18_4098x9_post_synth.v
+select -assert-count 1 t:TDP36K_FIFO_ASYNC_WR_X18_RD_X9_nonsplit
+
+select -clear
+design -load asymmetric_bram36k_afifo
+select af1024x36_4098x9
+select *
+synth_quicklogic -family qlf_k6n10f -top af1024x36_4098x9 -bram_types
+opt_expr -undriven
+opt_clean
+stat
+write_verilog sim/af1024x36_4098x9_post_synth.v
+select -assert-count 1 t:TDP36K_FIFO_ASYNC_WR_X36_RD_X9_nonsplit
\ No newline at end of file
diff --git a/ql-qlf-plugin/tests/qlf_k6n10f/asymmetric_bram36k_afifo/asymmetric_bram36k_afifo.v b/ql-qlf-plugin/tests/qlf_k6n10f/asymmetric_bram36k_afifo/asymmetric_bram36k_afifo.v
new file mode 100644
index 0000000..81ceaa8
--- /dev/null
+++ b/ql-qlf-plugin/tests/qlf_k6n10f/asymmetric_bram36k_afifo/asymmetric_bram36k_afifo.v
@@ -0,0 +1,168 @@
+module af4096x9_1024x36 (DIN,PUSH,POP,clock0,clock1,Async_Flush,Almost_Full,Almost_Empty,Full,Empty,Full_Watermark,Empty_Watermark,Overrun_Error,Underrun_Error,DOUT);
+
+parameter WR_DATA_WIDTH = 9;
+parameter RD_DATA_WIDTH = 36;
+parameter UPAE_DBITS = 12'd10;
+parameter UPAF_DBITS = 12'd10;
+
+input clock0,clock1;
+input PUSH,POP;
+input [WR_DATA_WIDTH-1:0] DIN;
+input Async_Flush;
+output [RD_DATA_WIDTH-1:0] DOUT;
+output Almost_Full,Almost_Empty;
+output Full, Empty;
+output Full_Watermark, Empty_Watermark;
+output Overrun_Error, Underrun_Error;
+
+
+AFIFO_36K_BLK  # (.WR_DATA_WIDTH(WR_DATA_WIDTH),.RD_DATA_WIDTH(RD_DATA_WIDTH),.UPAE_DBITS(UPAE_DBITS),.UPAF_DBITS(UPAF_DBITS)
+        				 ) 
+  FIFO_INST    (
+                .DIN(DIN),
+                .PUSH(PUSH),
+                .POP(POP),
+                .Push_Clk(clock0),
+                .Pop_Clk(clock1),
+                .Async_Flush(Async_Flush),
+                
+                .Overrun_Error(Overrun_Error),
+                .Full_Watermark(Full_Watermark),
+                .Almost_Full(Almost_Full),
+                .Full(Full),
+                
+                .Underrun_Error(Underrun_Error),
+                .Empty_Watermark(Empty_Watermark),
+                .Almost_Empty(Almost_Empty),
+                .Empty(Empty),
+
+                .DOUT(DOUT)
+         				);
+
+endmodule
+
+module af2048x18_1024x36 (DIN,PUSH,POP,clock0,clock1,Async_Flush,Almost_Full,Almost_Empty,Full,Empty,Full_Watermark,Empty_Watermark,Overrun_Error,Underrun_Error,DOUT);
+
+parameter WR_DATA_WIDTH = 18;
+parameter RD_DATA_WIDTH = 36;
+parameter UPAE_DBITS = 12'd10;
+parameter UPAF_DBITS = 12'd10;
+
+input clock0,clock1;
+input PUSH,POP;
+input [WR_DATA_WIDTH-1:0] DIN;
+input Async_Flush;
+output [RD_DATA_WIDTH-1:0] DOUT;
+output Almost_Full,Almost_Empty;
+output Full, Empty;
+output Full_Watermark, Empty_Watermark;
+output Overrun_Error, Underrun_Error;
+
+AFIFO_36K_BLK  # (.WR_DATA_WIDTH(WR_DATA_WIDTH),.RD_DATA_WIDTH(RD_DATA_WIDTH),.UPAE_DBITS(UPAE_DBITS),.UPAF_DBITS(UPAF_DBITS)
+        				 ) 
+  FIFO_INST    (
+                .DIN(DIN),
+                .PUSH(PUSH),
+                .POP(POP),
+                .Push_Clk(clock0),
+                .Pop_Clk(clock1),
+                .Async_Flush(Async_Flush),
+                
+                .Overrun_Error(Overrun_Error),
+                .Full_Watermark(Full_Watermark),
+                .Almost_Full(Almost_Full),
+                .Full(Full),
+                
+                .Underrun_Error(Underrun_Error),
+                .Empty_Watermark(Empty_Watermark),
+                .Almost_Empty(Almost_Empty),
+                .Empty(Empty),
+
+                .DOUT(DOUT)
+         				);
+
+endmodule
+
+module af2048x18_4098x9 (DIN,PUSH,POP,clock0,clock1,Async_Flush,Almost_Full,Almost_Empty,Full,Empty,Full_Watermark,Empty_Watermark,Overrun_Error,Underrun_Error,DOUT);
+
+parameter WR_DATA_WIDTH = 18;
+parameter RD_DATA_WIDTH = 9;
+parameter UPAE_DBITS = 12'd10;
+parameter UPAF_DBITS = 12'd10;
+
+input clock0,clock1;
+input PUSH,POP;
+input [WR_DATA_WIDTH-1:0] DIN;
+input Async_Flush;
+output [RD_DATA_WIDTH-1:0] DOUT;
+output Almost_Full,Almost_Empty;
+output Full, Empty;
+output Full_Watermark, Empty_Watermark;
+output Overrun_Error, Underrun_Error;
+
+AFIFO_36K_BLK  # (.WR_DATA_WIDTH(WR_DATA_WIDTH),.RD_DATA_WIDTH(RD_DATA_WIDTH),.UPAE_DBITS(UPAE_DBITS),.UPAF_DBITS(UPAF_DBITS)
+        				 ) 
+  FIFO_INST    (
+                .DIN(DIN),
+                .PUSH(PUSH),
+                .POP(POP),
+                .Push_Clk(clock0),
+                .Pop_Clk(clock1),
+                .Async_Flush(Async_Flush),
+                
+                .Overrun_Error(Overrun_Error),
+                .Full_Watermark(Full_Watermark),
+                .Almost_Full(Almost_Full),
+                .Full(Full),
+                
+                .Underrun_Error(Underrun_Error),
+                .Empty_Watermark(Empty_Watermark),
+                .Almost_Empty(Almost_Empty),
+                .Empty(Empty),
+
+                .DOUT(DOUT)
+         				);
+
+endmodule
+
+module af1024x36_4098x9 (DIN,PUSH,POP,clock0,clock1,Async_Flush,Almost_Full,Almost_Empty,Full,Empty,Full_Watermark,Empty_Watermark,Overrun_Error,Underrun_Error,DOUT);
+
+parameter WR_DATA_WIDTH = 36;
+parameter RD_DATA_WIDTH = 9;
+parameter UPAE_DBITS = 12'd10;
+parameter UPAF_DBITS = 12'd10;
+
+input clock0,clock1;
+input PUSH,POP;
+input [WR_DATA_WIDTH-1:0] DIN;
+input Async_Flush;
+output [RD_DATA_WIDTH-1:0] DOUT;
+output Almost_Full,Almost_Empty;
+output Full, Empty;
+output Full_Watermark, Empty_Watermark;
+output Overrun_Error, Underrun_Error;
+
+AFIFO_36K_BLK  # (.WR_DATA_WIDTH(WR_DATA_WIDTH),.RD_DATA_WIDTH(RD_DATA_WIDTH),.UPAE_DBITS(UPAE_DBITS),.UPAF_DBITS(UPAF_DBITS)
+        				 ) 
+  FIFO_INST    (
+                .DIN(DIN),
+                .PUSH(PUSH),
+                .POP(POP),
+                .Push_Clk(clock0),
+                .Pop_Clk(clock1),
+                .Async_Flush(Async_Flush),
+                
+                .Overrun_Error(Overrun_Error),
+                .Full_Watermark(Full_Watermark),
+                .Almost_Full(Almost_Full),
+                .Full(Full),
+                
+                .Underrun_Error(Underrun_Error),
+                .Empty_Watermark(Empty_Watermark),
+                .Almost_Empty(Almost_Empty),
+                .Empty(Empty),
+
+                .DOUT(DOUT)
+         				);
+
+endmodule
\ No newline at end of file
diff --git a/ql-qlf-plugin/tests/qlf_k6n10f/asymmetric_bram36k_afifo/sim/Makefile b/ql-qlf-plugin/tests/qlf_k6n10f/asymmetric_bram36k_afifo/sim/Makefile
new file mode 100644
index 0000000..e3bd2bd
--- /dev/null
+++ b/ql-qlf-plugin/tests/qlf_k6n10f/asymmetric_bram36k_afifo/sim/Makefile
@@ -0,0 +1,43 @@
+# Copyright (C) 2019-2022 The SymbiFlow Authors
+#
+# Use of this source code is governed by a ISC-style
+# license that can be found in the LICENSE file or at
+# https://opensource.org/licenses/ISC
+#
+# SPDX-License-Identifier: ISC
+
+TESTBENCH = asymmetric_bram36k_afifo_tb.v
+POST_SYNTH = af4096x9_1024x36_post_synth af2048x18_1024x36_post_synth af2048x18_4098x9_post_synth af1024x36_4098x9_post_synth
+ADDR_WIDTH0 = 12 11 11 10
+DATA_WIDTH0 = 9 18 18 36
+ADDR_WIDTH1 = 10 10 12 12
+DATA_WIDTH1 = 36 36 9 9
+TOP = af4096x9_1024x36 af2048x18_1024x36 af2048x18_4098x9 af1024x36_4098x9
+ADDR0_DEFINES = $(foreach awidth0, $(ADDR_WIDTH0),-DADDR_WIDTH0="$(awidth0)")
+ADDR1_DEFINES = $(foreach awidth1, $(ADDR_WIDTH1),-DADDR_WIDTH1="$(awidth1)")
+DATA0_DEFINES = $(foreach dwidth0, $(DATA_WIDTH0),-DDATA_WIDTH0="$(dwidth0)")
+DATA1_DEFINES = $(foreach dwidth1, $(DATA_WIDTH1),-DDATA_WIDTH1="$(dwidth1)")
+TOP_DEFINES = $(foreach top, $(TOP),-DTOP="$(top)")
+VCD_DEFINES = $(foreach vcd, $(POST_SYNTH),-DVCD="$(vcd).vcd")
+
+SIM_LIBS = $(shell find ../../../../qlf_k6n10f -name "*.v" -not -name "*_map.v")
+
+define simulate_post_synth
+	@iverilog  -vvvv -g2005 $(word $(1),$(ADDR0_DEFINES)) $(word $(1),$(ADDR1_DEFINES)) $(word $(1),$(DATA0_DEFINES)) $(word $(1),$(DATA1_DEFINES)) $(word $(1),$(TOP_DEFINES)) $(word $(1),$(VCD_DEFINES)) -o $(word $(1),$(POST_SYNTH)).vvp $(word $(1),$(POST_SYNTH)).v $(SIM_LIBS) $(TESTBENCH) > $(word $(1),$(POST_SYNTH)).vvp.log 2>&1
+	@vvp -vvvv $(word $(1),$(POST_SYNTH)).vvp > $(word $(1),$(POST_SYNTH)).vcd.log 2>&1
+endef
+
+define clean_post_synth_sim
+	@rm -rf  $(word $(1),$(POST_SYNTH)).vcd $(word $(1),$(POST_SYNTH)).vvp $(word $(1),$(POST_SYNTH)).vvp.log $(word $(1),$(POST_SYNTH)).vcd.log
+endef
+
+#FIXME: $(call simulate_post_synth,3)
+sim:
+	$(call simulate_post_synth,1)
+	$(call clean_post_synth_sim,1)
+	$(call simulate_post_synth,2)
+	$(call clean_post_synth_sim,2)
+	$(call simulate_post_synth,3)
+	$(call clean_post_synth_sim,3)
+	$(call simulate_post_synth,4)
+	$(call clean_post_synth_sim,4)
\ No newline at end of file
diff --git a/ql-qlf-plugin/tests/qlf_k6n10f/asymmetric_bram36k_afifo/sim/asymmetric_bram36k_afifo_tb.v b/ql-qlf-plugin/tests/qlf_k6n10f/asymmetric_bram36k_afifo/sim/asymmetric_bram36k_afifo_tb.v
new file mode 100644
index 0000000..17ac3c0
--- /dev/null
+++ b/ql-qlf-plugin/tests/qlf_k6n10f/asymmetric_bram36k_afifo/sim/asymmetric_bram36k_afifo_tb.v
@@ -0,0 +1,284 @@
+// Copyright (C) 2019-2022 The SymbiFlow Authors
+//
+// Use of this source code is governed by a ISC-style
+// license that can be found in the LICENSE file or at
+// https://opensource.org/licenses/ISC
+//
+// SPDX-License-Identifier: ISC
+
+`timescale 1ns/1ps
+
+`define STRINGIFY(x) `"x`"
+
+module TB;
+	localparam PERIOD = 30;
+	localparam ADDR_INCR = 1;
+
+	reg clk0;
+  reg clk1;
+  reg flush;
+	reg pop;
+	wire [`DATA_WIDTH1-1:0] dout;
+	reg push;
+	reg [`DATA_WIDTH0-1:0] din;
+  wire almost_full,almost_empty;
+  wire full, empty;
+  wire full_watermark, empty_watermark;
+  wire overrun_error, underrun_error;
+
+  initial 
+  begin
+    clk0 = 0;
+    clk1 = 0;
+    pop = 0;
+    push = 0;
+    flush = 1;
+    din = 0;
+    #40
+    flush = 0;
+  end
+  
+	initial forever #(PERIOD / 3.0) clk0 = ~clk0;
+  initial forever #(PERIOD / 2.0) clk1 = ~clk1;
+  
+	initial begin
+		$dumpfile(`STRINGIFY(`VCD));
+		$dumpvars;
+	end
+
+	integer a;
+
+	reg done;
+	initial done = 1'b0;
+  
+  reg read_test;
+	initial read_test = 0;
+
+	reg [`DATA_WIDTH1-1:0] expected;
+  initial expected = 0;
+
+	wire error = (read_test) ? dout !== expected : 0;
+
+	integer error_cnt = 0;
+	always @ (posedge clk1)
+	begin
+		if (error)
+			error_cnt <= error_cnt + 1'b1; 
+	end
+
+case (`STRINGIFY(`TOP))
+"af4096x9_1024x36": begin
+	initial #(50) begin
+		// Write data
+		for (a = 0; a < (1<<`ADDR_WIDTH0) ; a = a + ADDR_INCR) begin
+			@(negedge clk0) begin
+				din = a[10:2];
+				push = 1;
+			end
+			@(posedge clk0) begin
+				#(PERIOD/10) push = 0;
+			end
+		end
+		// Read data
+		read_test = 1;
+		for (a = 0; a < (1<<`ADDR_WIDTH1); a = a + ADDR_INCR) begin
+			@(posedge clk1) begin
+        expected <= {a[8],a[8],a[7:0],a[7:0],a[8],a[8],a[7:0],a[7:0]};
+				#(PERIOD/10) pop = 0;
+				if ( dout !== expected) begin
+					$display("%d: PORT 0: FAIL: mismatch act=%x exp=%x at %x", $time, dout, expected, a);
+				end else begin
+					$display("%d: PORT 0: OK: act=%x exp=%x at %x", $time, dout, expected, a);
+				end
+			end
+      @(negedge clk1) begin
+				pop = 1;
+			end
+		end
+		done = 1'b1;
+    a = 0;
+	end
+end
+"af2048x18_1024x36": begin
+	initial #(50) begin
+		// Write data
+		for (a = 0; a < (1<<`ADDR_WIDTH0) ; a = a + ADDR_INCR) begin
+			@(negedge clk0) begin
+				din = a[18:1];
+				push = 1;
+			end
+			@(posedge clk0) begin
+				#(PERIOD/10) push = 0;
+			end
+		end
+		// Read data
+		read_test = 1;
+		for (a = 0; a < (1<<`ADDR_WIDTH1); a = a + ADDR_INCR) begin
+			@(posedge clk1) begin
+        expected <= {a[17:0],a[17:0]};
+				#(PERIOD/10) pop = 0;
+				if ( dout !== expected) begin
+					$display("%d: PORT 0: FAIL: mismatch act=%x exp=%x at %x", $time, dout, expected, a);
+				end else begin
+					$display("%d: PORT 0: OK: act=%x exp=%x at %x", $time, dout, expected, a);
+				end
+			end
+      @(negedge clk1) begin
+				pop = 1;
+			end
+		end
+		done = 1'b1;
+    a = 0;
+	end
+end  
+"af2048x18_4098x9": begin
+	initial #(50) begin
+		// Write data
+		for (a = 0; a < (1<<`ADDR_WIDTH0) ; a = a + ADDR_INCR) begin
+			@(negedge clk0) begin
+				din = {a[8],a[8],a[7:0],a[7:0]};
+				push = 1;
+			end
+			@(posedge clk0) begin
+				#(PERIOD/10) push = 0;
+			end
+		end
+		// Read data
+		read_test = 1;
+		for (a = 0; a < (1<<`ADDR_WIDTH1); a = a + ADDR_INCR) begin
+			@(posedge clk1) begin
+        expected <= {a[9:1]};
+				#(PERIOD/10) pop = 0;
+				if ( dout !== expected) begin
+					$display("%d: PORT 0: FAIL: mismatch act=%x exp=%x at %x", $time, dout, expected, a);
+				end else begin
+					$display("%d: PORT 0: OK: act=%x exp=%x at %x", $time, dout, expected, a);
+				end
+			end
+      @(negedge clk1) begin
+				pop = 1;
+			end
+		end
+		done = 1'b1;
+    a = 0;
+	end
+end
+"af1024x36_4098x9": begin
+	initial #(50) begin
+		// Write data
+		for (a = 0; a < (1<<`ADDR_WIDTH0) ; a = a + ADDR_INCR) begin
+			@(negedge clk0) begin
+				din = {a[8],a[8],a[7:0],a[7:0],a[8],a[8],a[7:0],a[7:0]};
+				push = 1;
+			end
+			@(posedge clk0) begin
+				#(PERIOD/10) push = 0;
+			end
+		end
+		// Read data
+		read_test = 1;
+		for (a = 0; a < (1<<`ADDR_WIDTH1); a = a + ADDR_INCR) begin
+			@(posedge clk1) begin
+        expected <= {a[10:2]};
+				#(PERIOD/10) pop = 0;
+				if ( dout !== expected) begin
+					$display("%d: PORT 0: FAIL: mismatch act=%x exp=%x at %x", $time, dout, expected, a);
+				end else begin
+					$display("%d: PORT 0: OK: act=%x exp=%x at %x", $time, dout, expected, a);
+				end
+			end
+      @(negedge clk1) begin
+				pop = 1;
+			end
+		end
+		done = 1'b1;
+    a = 0;
+  end
+end
+endcase
+
+	// Scan for simulation finish
+	always @(posedge clk1) begin
+		if (done)
+			$finish_and_return( (error_cnt == 0) ? 0 : -1 );
+	end
+
+	case (`STRINGIFY(`TOP))
+		"af4096x9_1024x36": begin
+			af4096x9_1024x36 #() afifo (
+        .DIN(din),
+        .PUSH(push),
+        .POP(pop),
+        .clock0(clk0),
+        .clock1(clk1),
+        .Async_Flush(flush),
+        .Almost_Full(almost_full),
+        .Almost_Empty(almost_empty),
+        .Full(full),
+        .Empty(empty),
+        .Full_Watermark(full_watermark),
+        .Empty_Watermark(empty_watermark),
+        .Overrun_Error(overrun_error),
+        .Underrun_Error(underrun_error),
+        .DOUT(dout)
+			);
+		end
+		"af2048x18_1024x36": begin
+			af2048x18_1024x36 #() afifo (
+        .DIN(din),
+        .PUSH(push),
+        .POP(pop),
+        .clock0(clk0),
+        .clock1(clk1),
+        .Async_Flush(flush),
+        .Almost_Full(almost_full),
+        .Almost_Empty(almost_empty),
+        .Full(full),
+        .Empty(empty),
+        .Full_Watermark(full_watermark),
+        .Empty_Watermark(empty_watermark),
+        .Overrun_Error(overrun_error),
+        .Underrun_Error(underrun_error),
+        .DOUT(dout)
+			);
+		end
+		"af2048x18_4098x9": begin
+			af2048x18_4098x9 #() afifo (
+        .DIN(din),
+        .PUSH(push),
+        .POP(pop),
+        .clock0(clk0),
+        .clock1(clk1),
+        .Async_Flush(flush),
+        .Almost_Full(almost_full),
+        .Almost_Empty(almost_empty),
+        .Full(full),
+        .Empty(empty),
+        .Full_Watermark(full_watermark),
+        .Empty_Watermark(empty_watermark),
+        .Overrun_Error(overrun_error),
+        .Underrun_Error(underrun_error),
+        .DOUT(dout)
+			);
+		end
+		"af1024x36_4098x9": begin
+			af1024x36_4098x9 #() afifo (
+        .DIN(din),
+        .PUSH(push),
+        .POP(pop),
+        .clock0(clk0),
+        .clock1(clk1),
+        .Async_Flush(flush),
+        .Almost_Full(almost_full),
+        .Almost_Empty(almost_empty),
+        .Full(full),
+        .Empty(empty),
+        .Full_Watermark(full_watermark),
+        .Empty_Watermark(empty_watermark),
+        .Overrun_Error(overrun_error),
+        .Underrun_Error(underrun_error),
+        .DOUT(dout)
+			);
+		end
+	endcase
+endmodule
diff --git a/ql-qlf-plugin/tests/qlf_k6n10f/asymmetric_bram36k_sdp/asymmetric_bram36k_sdp.tcl b/ql-qlf-plugin/tests/qlf_k6n10f/asymmetric_bram36k_sdp/asymmetric_bram36k_sdp.tcl
new file mode 100644
index 0000000..827914a
--- /dev/null
+++ b/ql-qlf-plugin/tests/qlf_k6n10f/asymmetric_bram36k_sdp/asymmetric_bram36k_sdp.tcl
@@ -0,0 +1,49 @@
+yosys -import
+
+if { [info procs ql-qlf-k6n10f] == {} } { plugin -i ql-qlf }
+yosys -import  ;
+
+read_verilog $::env(DESIGN_TOP).v
+design -save asymmetric_bram36k_sdp
+
+select spram_9x4096_36x1024
+select *
+synth_quicklogic -family qlf_k6n10f -top spram_9x4096_36x1024 -bram_types
+opt_expr -undriven
+opt_clean
+stat
+write_verilog sim/spram_9x4096_36x1024_post_synth.v
+select -assert-count 1 t:TDP36K_BRAM_WR_X9_RD_X36_nonsplit
+
+select -clear
+design -load asymmetric_bram36k_sdp
+select spram_18x2048_36x1024
+select *
+synth_quicklogic -family qlf_k6n10f -top spram_18x2048_36x1024 -bram_types
+opt_expr -undriven
+opt_clean
+stat
+write_verilog sim/spram_18x2048_36x1024_post_synth.v
+select -assert-count 1 t:TDP36K_BRAM_WR_X18_RD_X36_nonsplit
+
+select -clear
+design -load asymmetric_bram36k_sdp
+select spram_18x2048_9x4096
+select *
+synth_quicklogic -family qlf_k6n10f -top spram_18x2048_9x4096 -bram_types
+opt_expr -undriven
+opt_clean
+stat
+write_verilog sim/spram_18x2048_9x4096_post_synth.v
+select -assert-count 1 t:TDP36K_BRAM_WR_X18_RD_X9_nonsplit
+
+select -clear
+design -load asymmetric_bram36k_sdp
+select spram_36x1024_18x2048
+select *
+synth_quicklogic -family qlf_k6n10f -top spram_36x1024_18x2048 -bram_types
+opt_expr -undriven
+opt_clean
+stat
+write_verilog sim/spram_36x1024_18x2048_post_synth.v
+select -assert-count 1 t:TDP36K_BRAM_WR_X36_RD_X18_nonsplit
\ No newline at end of file
diff --git a/ql-qlf-plugin/tests/qlf_k6n10f/asymmetric_bram36k_sdp/asymmetric_bram36k_sdp.v b/ql-qlf-plugin/tests/qlf_k6n10f/asymmetric_bram36k_sdp/asymmetric_bram36k_sdp.v
new file mode 100644
index 0000000..e964b23
--- /dev/null
+++ b/ql-qlf-plugin/tests/qlf_k6n10f/asymmetric_bram36k_sdp/asymmetric_bram36k_sdp.v
@@ -0,0 +1,187 @@
+module spram_9x4096_36x1024 (
+    WEN_i,
+    REN_i,
+    clock0,
+    clock1,
+    WR_ADDR_i,
+    RD_ADDR_i,
+    WDATA_i,
+    RDATA_o
+);
+
+parameter WR_ADDR_WIDTH = 12;
+parameter RD_ADDR_WIDTH = 10;
+parameter WR_DATA_WIDTH = 9;
+parameter RD_DATA_WIDTH = 36;
+parameter BE_WIDTH = 1;
+
+input wire WEN_i;
+input wire REN_i;
+input wire clock0;
+input wire clock1;
+input wire [WR_ADDR_WIDTH-1 :0] WR_ADDR_i;
+input wire [RD_ADDR_WIDTH-1 :0] RD_ADDR_i;
+input wire [WR_DATA_WIDTH-1 :0] WDATA_i;
+output wire [RD_DATA_WIDTH-1 :0] RDATA_o;
+
+RAM_36K_BLK #(
+              .WR_ADDR_WIDTH(WR_ADDR_WIDTH),
+              .RD_ADDR_WIDTH(RD_ADDR_WIDTH),
+              .WR_DATA_WIDTH(WR_DATA_WIDTH),
+              .RD_DATA_WIDTH(RD_DATA_WIDTH),
+              .BE_WIDTH(BE_WIDTH)
+              ) spram_x36_inst (
+              
+              .WEN_i(WEN_i),
+              .WR_BE_i(1'b1),
+              .REN_i(REN_i),              
+              .WR_CLK_i(clock0),
+              .RD_CLK_i(clock1),
+              .WR_ADDR_i(WR_ADDR_i),
+              .RD_ADDR_i(RD_ADDR_i),
+              .WDATA_i(WDATA_i),
+              .RDATA_o(RDATA_o)
+              );
+              
+endmodule    
+
+module spram_18x2048_36x1024 (
+    WEN_i,
+    REN_i,
+    clock0,
+    clock1,
+    WR_ADDR_i,
+    RD_ADDR_i,
+    WDATA_i,
+    RDATA_o
+);
+
+parameter WR_ADDR_WIDTH = 11;
+parameter RD_ADDR_WIDTH = 10;
+parameter WR_DATA_WIDTH = 18;
+parameter RD_DATA_WIDTH = 36;
+parameter BE_WIDTH = 2;
+
+input wire WEN_i;
+input wire REN_i;
+input wire clock0;
+input wire clock1;
+input wire [WR_ADDR_WIDTH-1 :0] WR_ADDR_i;
+input wire [RD_ADDR_WIDTH-1 :0] RD_ADDR_i;
+input wire [WR_DATA_WIDTH-1 :0] WDATA_i;
+output wire [RD_DATA_WIDTH-1 :0] RDATA_o;
+
+RAM_36K_BLK #(
+              .WR_ADDR_WIDTH(WR_ADDR_WIDTH),
+              .RD_ADDR_WIDTH(RD_ADDR_WIDTH),
+              .WR_DATA_WIDTH(WR_DATA_WIDTH),
+              .RD_DATA_WIDTH(RD_DATA_WIDTH),
+              .BE_WIDTH(BE_WIDTH)
+              ) spram_x36_inst (
+              
+              .WEN_i(WEN_i),
+              .WR_BE_i(2'b11),
+              .REN_i(REN_i),              
+              .WR_CLK_i(clock0),
+              .RD_CLK_i(clock1),
+              .WR_ADDR_i(WR_ADDR_i),
+              .RD_ADDR_i(RD_ADDR_i),
+              .WDATA_i(WDATA_i),
+              .RDATA_o(RDATA_o)
+              );
+              
+endmodule   
+
+module spram_18x2048_9x4096 (
+    WEN_i,
+    REN_i,
+    clock0,
+    clock1,
+    WR_ADDR_i,
+    RD_ADDR_i,
+    WDATA_i,
+    RDATA_o
+);
+
+parameter WR_ADDR_WIDTH = 11;
+parameter RD_ADDR_WIDTH = 12;
+parameter WR_DATA_WIDTH = 18;
+parameter RD_DATA_WIDTH = 9;
+parameter BE_WIDTH = 2;
+
+input wire WEN_i;
+input wire REN_i;
+input wire clock0;
+input wire clock1;
+input wire [WR_ADDR_WIDTH-1 :0] WR_ADDR_i;
+input wire [RD_ADDR_WIDTH-1 :0] RD_ADDR_i;
+input wire [WR_DATA_WIDTH-1 :0] WDATA_i;
+output wire [RD_DATA_WIDTH-1 :0] RDATA_o;
+
+RAM_36K_BLK #(
+              .WR_ADDR_WIDTH(WR_ADDR_WIDTH),
+              .RD_ADDR_WIDTH(RD_ADDR_WIDTH),
+              .WR_DATA_WIDTH(WR_DATA_WIDTH),
+              .RD_DATA_WIDTH(RD_DATA_WIDTH),
+              .BE_WIDTH(BE_WIDTH)
+              ) spram_x36_inst (
+              
+              .WEN_i(WEN_i),
+              .WR_BE_i(2'b11),
+              .REN_i(REN_i),              
+              .WR_CLK_i(clock0),
+              .RD_CLK_i(clock1),
+              .WR_ADDR_i(WR_ADDR_i),
+              .RD_ADDR_i(RD_ADDR_i),
+              .WDATA_i(WDATA_i),
+              .RDATA_o(RDATA_o)
+              );
+              
+endmodule    
+
+module spram_36x1024_18x2048 (
+    WEN_i,
+    REN_i,
+    clock0,
+    clock1,
+    WR_ADDR_i,
+    RD_ADDR_i,
+    WDATA_i,
+    RDATA_o
+);
+
+parameter WR_ADDR_WIDTH = 10;
+parameter RD_ADDR_WIDTH = 11;
+parameter WR_DATA_WIDTH = 36;
+parameter RD_DATA_WIDTH = 18;
+parameter BE_WIDTH = 4;
+
+input wire WEN_i;
+input wire REN_i;
+input wire clock0;
+input wire clock1;
+input wire [WR_ADDR_WIDTH-1 :0] WR_ADDR_i;
+input wire [RD_ADDR_WIDTH-1 :0] RD_ADDR_i;
+input wire [WR_DATA_WIDTH-1 :0] WDATA_i;
+output wire [RD_DATA_WIDTH-1 :0] RDATA_o;
+
+RAM_36K_BLK #(
+              .WR_ADDR_WIDTH(WR_ADDR_WIDTH),
+              .RD_ADDR_WIDTH(RD_ADDR_WIDTH),
+              .WR_DATA_WIDTH(WR_DATA_WIDTH),
+              .RD_DATA_WIDTH(RD_DATA_WIDTH),
+              .BE_WIDTH(BE_WIDTH)
+              ) spram_x36_inst (
+              
+              .WEN_i(WEN_i),
+              .WR_BE_i(4'b1111),
+              .REN_i(REN_i),              
+              .WR_CLK_i(clock0),
+              .RD_CLK_i(clock1),
+              .WR_ADDR_i(WR_ADDR_i),
+              .RD_ADDR_i(RD_ADDR_i),
+              .WDATA_i(WDATA_i),
+              .RDATA_o(RDATA_o)
+              );
+              
+endmodule     
\ No newline at end of file
diff --git a/ql-qlf-plugin/tests/qlf_k6n10f/asymmetric_bram36k_sdp/sim/Makefile b/ql-qlf-plugin/tests/qlf_k6n10f/asymmetric_bram36k_sdp/sim/Makefile
new file mode 100644
index 0000000..fc7c0e9
--- /dev/null
+++ b/ql-qlf-plugin/tests/qlf_k6n10f/asymmetric_bram36k_sdp/sim/Makefile
@@ -0,0 +1,43 @@
+# Copyright (C) 2019-2022 The SymbiFlow Authors
+#
+# Use of this source code is governed by a ISC-style
+# license that can be found in the LICENSE file or at
+# https://opensource.org/licenses/ISC
+#
+# SPDX-License-Identifier: ISC
+
+TESTBENCH = asymmetric_bram36k_sdp_tb.v
+POST_SYNTH = spram_9x4096_36x1024_post_synth spram_18x2048_36x1024_post_synth spram_18x2048_9x4096_post_synth spram_36x1024_18x2048_post_synth
+ADDR_WIDTH0 = 12 11 11 10
+DATA_WIDTH0 = 9 18 18 36
+ADDR_WIDTH1 = 10 10 12 11
+DATA_WIDTH1 = 36 36 9 18
+TOP = spram_9x4096_36x1024 spram_18x2048_36x1024 spram_18x2048_9x4096 spram_36x1024_18x2048
+ADDR0_DEFINES = $(foreach awidth0, $(ADDR_WIDTH0),-DADDR_WIDTH0="$(awidth0)")
+ADDR1_DEFINES = $(foreach awidth1, $(ADDR_WIDTH1),-DADDR_WIDTH1="$(awidth1)")
+DATA0_DEFINES = $(foreach dwidth0, $(DATA_WIDTH0),-DDATA_WIDTH0="$(dwidth0)")
+DATA1_DEFINES = $(foreach dwidth1, $(DATA_WIDTH1),-DDATA_WIDTH1="$(dwidth1)")
+TOP_DEFINES = $(foreach top, $(TOP),-DTOP="$(top)")
+VCD_DEFINES = $(foreach vcd, $(POST_SYNTH),-DVCD="$(vcd).vcd")
+
+SIM_LIBS = $(shell find ../../../../qlf_k6n10f -name "*.v" -not -name "*_map.v")
+
+define simulate_post_synth
+	@iverilog  -vvvv -g2005 $(word $(1),$(ADDR0_DEFINES)) $(word $(1),$(ADDR1_DEFINES)) $(word $(1),$(DATA0_DEFINES)) $(word $(1),$(DATA1_DEFINES)) $(word $(1),$(TOP_DEFINES)) $(word $(1),$(VCD_DEFINES)) -o $(word $(1),$(POST_SYNTH)).vvp $(word $(1),$(POST_SYNTH)).v $(SIM_LIBS) $(TESTBENCH) > $(word $(1),$(POST_SYNTH)).vvp.log 2>&1
+	@vvp -vvvv $(word $(1),$(POST_SYNTH)).vvp > $(word $(1),$(POST_SYNTH)).vcd.log 2>&1
+endef
+
+define clean_post_synth_sim
+	@rm -rf  $(word $(1),$(POST_SYNTH)).vcd $(word $(1),$(POST_SYNTH)).vvp $(word $(1),$(POST_SYNTH)).vvp.log $(word $(1),$(POST_SYNTH)).vcd.log
+endef
+
+#FIXME: $(call simulate_post_synth,3)
+sim:
+	$(call simulate_post_synth,1)
+	$(call clean_post_synth_sim,1)
+	$(call simulate_post_synth,2)
+	$(call clean_post_synth_sim,2)
+	$(call simulate_post_synth,3)
+	$(call clean_post_synth_sim,3)
+	$(call simulate_post_synth,4)
+	$(call clean_post_synth_sim,4)
\ No newline at end of file
diff --git a/ql-qlf-plugin/tests/qlf_k6n10f/asymmetric_bram36k_sdp/sim/asymmetric_bram36k_sdp_tb.v b/ql-qlf-plugin/tests/qlf_k6n10f/asymmetric_bram36k_sdp/sim/asymmetric_bram36k_sdp_tb.v
new file mode 100644
index 0000000..87cab86
--- /dev/null
+++ b/ql-qlf-plugin/tests/qlf_k6n10f/asymmetric_bram36k_sdp/sim/asymmetric_bram36k_sdp_tb.v
@@ -0,0 +1,262 @@
+// Copyright (C) 2019-2022 The SymbiFlow Authors
+//
+// Use of this source code is governed by a ISC-style
+// license that can be found in the LICENSE file or at
+// https://opensource.org/licenses/ISC
+//
+// SPDX-License-Identifier: ISC
+
+`timescale 1ns/1ps
+
+`define STRINGIFY(x) `"x`"
+
+module TB;
+	localparam PERIOD = 50;
+	localparam ADDR_INCR = 1;
+
+	reg clk_0;
+  reg clk_1;
+	reg rce;
+	reg [`ADDR_WIDTH1-1:0] ra;
+	wire [`DATA_WIDTH1-1:0] rq;
+	reg wce;
+	reg [`ADDR_WIDTH0-1:0] wa;
+	reg [`DATA_WIDTH0-1:0] wd;
+
+	initial clk_0 = 0;
+	initial clk_1 = 0;
+	initial ra = 0;
+  initial wa = 0;
+  initial wd = 0;
+	initial rce = 0;
+  initial wce = 0;
+	initial forever #(PERIOD / 2.0) clk_0 = ~clk_0;
+  //initial forever #(PERIOD / 2.0) clk_1 = ~clk_1;
+	initial begin
+		#(PERIOD / 4.0);
+		forever #(PERIOD / 2.0) clk_1 = ~clk_1;
+	end
+	initial begin
+		$dumpfile(`STRINGIFY(`VCD));
+		$dumpvars;
+	end
+
+	integer a;
+	integer b;
+
+	reg done_0;
+	initial done_0 = 1'b0;
+	wire done_sim = done_0;
+
+	reg [`DATA_WIDTH1-1:0] expected_0;
+
+	reg read_test_0;
+	initial read_test_0 = 0;
+
+
+	wire error_0 = (read_test_0) ? (rq !== expected_0) : 0;
+
+	integer error_0_cnt = 0;
+
+	always @ (posedge clk_1)
+	begin
+		if (error_0)
+			error_0_cnt <= error_0_cnt + 1'b1;
+	end
+
+case (`STRINGIFY(`TOP))
+"spram_9x4096_36x1024": begin
+	initial #(1) begin
+		// Write data
+		for (a = 0; a < (1<<`ADDR_WIDTH0) ; a = a + ADDR_INCR) begin
+			@(negedge clk_0) begin
+				wa = a[`ADDR_WIDTH0-1:0];
+				wd = a[10:2];
+				wce = 1;
+			end
+			@(posedge clk_0) begin
+				#(PERIOD/10) wce = 0;
+			end
+		end
+		// Read data
+		read_test_0 = 1;
+		for (a = 0; a < (1<<`ADDR_WIDTH1); a = a + ADDR_INCR) begin
+			@(negedge clk_1) begin
+				ra = a;
+				rce = 1;
+			end
+			@(posedge clk_1) begin
+        expected_0 <= {a[8],a[8],a[7:0],a[7:0],a[8],a[8],a[7:0],a[7:0]};
+				#(PERIOD/10) rce = 0;
+				if ( rq !== expected_0) begin
+					$display("%d: PORT 0: FAIL: mismatch act=%x exp=%x at %x", $time, rq, expected_0, a);
+				end else begin
+					$display("%d: PORT 0: OK: act=%x exp=%x at %x", $time, rq, expected_0, a);
+				end
+			end
+		end
+		done_0 = 1'b1;
+    a = 0;
+	end
+end
+"spram_18x2048_36x1024": begin
+	initial #(1) begin
+		// Write data
+		for (a = 0; a < (1<<`ADDR_WIDTH0) ; a = a + ADDR_INCR) begin
+			@(negedge clk_0) begin
+				wa = a[`ADDR_WIDTH0-1:0];
+				wd = a[18:1];
+				wce = 1;
+			end
+			@(posedge clk_0) begin
+				#(PERIOD/10) wce = 0;
+			end
+		end
+		// Read data
+		read_test_0 = 1;
+		for (a = 0; a < (1<<`ADDR_WIDTH1); a = a + ADDR_INCR) begin
+			@(negedge clk_1) begin
+				ra = a;
+				rce = 1;
+			end
+			@(posedge clk_1) begin
+        expected_0 <= {a[17:0],a[17:0]};
+				#(PERIOD/10) rce = 0;
+				if ( rq !== expected_0) begin
+					$display("%d: PORT 0: FAIL: mismatch act=%x exp=%x at %x", $time, rq, expected_0, a);
+				end else begin
+					$display("%d: PORT 0: OK: act=%x exp=%x at %x", $time, rq, expected_0, a);
+				end
+			end
+		end
+		done_0 = 1'b1;
+    a = 0;
+	end
+end  
+"spram_18x2048_9x4096": begin
+	initial #(1) begin
+		// Write data
+		for (a = 0; a < (1<<`ADDR_WIDTH0) ; a = a + ADDR_INCR) begin
+			@(negedge clk_0) begin
+				wa = a[`ADDR_WIDTH0-1:0];
+				wd = {a[8],a[8],a[7:0],a[7:0]};
+				wce = 1;
+			end
+			@(posedge clk_0) begin
+				#(PERIOD/10) wce = 0;
+			end
+		end
+		// Read data
+		read_test_0 = 1;
+		for (a = 0; a < (1<<`ADDR_WIDTH1); a = a + ADDR_INCR) begin
+			@(negedge clk_1) begin
+				ra = a;
+				rce = 1;
+			end
+			@(posedge clk_1) begin
+        expected_0 <= {a[9:1]};
+				#(PERIOD/10) rce = 0;
+				if ( rq !== expected_0) begin
+					$display("%d: PORT 0: FAIL: mismatch act=%x exp=%x at %x", $time, rq, expected_0, a);
+				end else begin
+					$display("%d: PORT 0: OK: act=%x exp=%x at %x", $time, rq, expected_0, a);
+				end
+			end
+		end
+		done_0 = 1'b1;
+    a = 0;
+	end
+end
+"spram_36x1024_18x2048": begin
+	initial #(1) begin
+		// Write data
+		for (a = 0; a < (1<<`ADDR_WIDTH0) ; a = a + ADDR_INCR) begin
+			@(negedge clk_0) begin
+				wa = a[`ADDR_WIDTH0-1:0];
+				wd = {a[17:0],a[17:0]};
+				wce = 1;
+			end
+			@(posedge clk_0) begin
+				#(PERIOD/10) wce = 0;
+			end
+		end
+		// Read data
+		read_test_0 = 1;
+		for (a = 0; a < (1<<`ADDR_WIDTH1); a = a + ADDR_INCR) begin
+			@(negedge clk_1) begin
+				ra = a;
+				rce = 1;
+			end
+			@(posedge clk_1) begin
+        expected_0 <= {a[18:1]};
+				#(PERIOD/10) rce = 0;
+				if ( rq !== expected_0) begin
+					$display("%d: PORT 0: FAIL: mismatch act=%x exp=%x at %x", $time, rq, expected_0, a);
+				end else begin
+					$display("%d: PORT 0: OK: act=%x exp=%x at %x", $time, rq, expected_0, a);
+				end
+			end
+		end
+		done_0 = 1'b1;
+    a = 0;
+  end
+end
+endcase
+
+	// Scan for simulation finish
+	always @(posedge clk_1) begin
+		if (done_sim)
+			$finish_and_return( (error_0_cnt == 0) ? 0 : -1 );
+	end
+
+	case (`STRINGIFY(`TOP))
+		"spram_9x4096_36x1024": begin
+			spram_9x4096_36x1024 #() bram (
+				.clock0(clk_0),
+        .clock1(clk_1),        
+				.REN_i(rce),
+				.RD_ADDR_i(ra),
+				.RDATA_o(rq),
+				.WEN_i(wce),
+				.WR_ADDR_i(wa),
+				.WDATA_i(wd)
+			);
+		end
+		"spram_18x2048_36x1024": begin
+			spram_18x2048_36x1024 #() bram (
+				.clock0(clk_0),
+        .clock1(clk_1),        
+				.REN_i(rce),
+				.RD_ADDR_i(ra),
+				.RDATA_o(rq),
+				.WEN_i(wce),
+				.WR_ADDR_i(wa),
+				.WDATA_i(wd)
+			);
+		end
+		"spram_18x2048_9x4096": begin
+			spram_18x2048_9x4096 #() bram (
+				.clock0(clk_0),
+        .clock1(clk_1),        
+				.REN_i(rce),
+				.RD_ADDR_i(ra),
+				.RDATA_o(rq),
+				.WEN_i(wce),
+				.WR_ADDR_i(wa),
+				.WDATA_i(wd)
+			);
+		end
+		"spram_36x1024_18x2048": begin
+			spram_36x1024_18x2048 #() bram (
+				.clock0(clk_0),
+        .clock1(clk_1),        
+				.REN_i(rce),
+				.RD_ADDR_i(ra),
+				.RDATA_o(rq),
+				.WEN_i(wce),
+				.WR_ADDR_i(wa),
+				.WDATA_i(wd)
+			);
+		end
+	endcase
+endmodule
diff --git a/ql-qlf-plugin/tests/qlf_k6n10f/asymmetric_bram36k_sfifo/asymmetric_bram36k_sfifo.tcl b/ql-qlf-plugin/tests/qlf_k6n10f/asymmetric_bram36k_sfifo/asymmetric_bram36k_sfifo.tcl
new file mode 100644
index 0000000..4b24470
--- /dev/null
+++ b/ql-qlf-plugin/tests/qlf_k6n10f/asymmetric_bram36k_sfifo/asymmetric_bram36k_sfifo.tcl
@@ -0,0 +1,49 @@
+yosys -import
+
+if { [info procs ql-qlf-k6n10f] == {} } { plugin -i ql-qlf }
+yosys -import  ;
+
+read_verilog $::env(DESIGN_TOP).v
+design -save asymmetric_bram36k_sfifo
+
+select f4096x9_1024x36
+select *
+synth_quicklogic -family qlf_k6n10f -top f4096x9_1024x36 -bram_types
+opt_expr -undriven
+opt_clean
+stat
+write_verilog sim/f4096x9_1024x36_post_synth.v
+select -assert-count 1 t:TDP36K_FIFO_SYNC_WR_X9_RD_X36_nonsplit
+
+select -clear
+design -load asymmetric_bram36k_sfifo
+select f2048x18_1024x36
+select *
+synth_quicklogic -family qlf_k6n10f -top f2048x18_1024x36 -bram_types
+opt_expr -undriven
+opt_clean
+stat
+write_verilog sim/f2048x18_1024x36_post_synth.v
+select -assert-count 1 t:TDP36K_FIFO_SYNC_WR_X18_RD_X36_nonsplit
+
+select -clear
+design -load asymmetric_bram36k_sfifo
+select f2048x18_4098x9
+select *
+synth_quicklogic -family qlf_k6n10f -top f2048x18_4098x9 -bram_types
+opt_expr -undriven
+opt_clean
+stat
+write_verilog sim/f2048x18_4098x9_post_synth.v
+select -assert-count 1 t:TDP36K_FIFO_SYNC_WR_X18_RD_X9_nonsplit
+
+select -clear
+design -load asymmetric_bram36k_sfifo
+select f1024x36_2048x18
+select *
+synth_quicklogic -family qlf_k6n10f -top f1024x36_2048x18 -bram_types
+opt_expr -undriven
+opt_clean
+stat
+write_verilog sim/f1024x36_2048x18_post_synth.v
+select -assert-count 1 t:TDP36K_FIFO_SYNC_WR_X36_RD_X18_nonsplit
\ No newline at end of file
diff --git a/ql-qlf-plugin/tests/qlf_k6n10f/asymmetric_bram36k_sfifo/asymmetric_bram36k_sfifo.v b/ql-qlf-plugin/tests/qlf_k6n10f/asymmetric_bram36k_sfifo/asymmetric_bram36k_sfifo.v
new file mode 100644
index 0000000..15274bb
--- /dev/null
+++ b/ql-qlf-plugin/tests/qlf_k6n10f/asymmetric_bram36k_sfifo/asymmetric_bram36k_sfifo.v
@@ -0,0 +1,163 @@
+module f4096x9_1024x36 (DIN,PUSH,POP,clock0,Async_Flush,Almost_Full,Almost_Empty,Full,Empty,Full_Watermark,Empty_Watermark,Overrun_Error,Underrun_Error,DOUT);
+
+parameter WR_DATA_WIDTH = 9;
+parameter RD_DATA_WIDTH = 36;
+parameter UPAE_DBITS = 12'd10;
+parameter UPAF_DBITS = 12'd10;
+
+input clock0;
+input PUSH,POP;
+input [WR_DATA_WIDTH-1:0] DIN;
+input Async_Flush;
+output [RD_DATA_WIDTH-1:0] DOUT;
+output Almost_Full,Almost_Empty;
+output Full, Empty;
+output Full_Watermark, Empty_Watermark;
+output Overrun_Error, Underrun_Error;
+
+SFIFO_36K_BLK  # (.WR_DATA_WIDTH(WR_DATA_WIDTH),.RD_DATA_WIDTH(RD_DATA_WIDTH),.UPAE_DBITS(UPAE_DBITS),.UPAF_DBITS(UPAF_DBITS)
+        				 ) 
+  FIFO_INST    (
+                .DIN(DIN),
+                .PUSH(PUSH),
+                .POP(POP),
+                .CLK(clock0),
+                .Async_Flush(Async_Flush),
+                
+                .Overrun_Error(Overrun_Error),
+                .Full_Watermark(Full_Watermark),
+                .Almost_Full(Almost_Full),
+                .Full(Full),
+                
+                .Underrun_Error(Underrun_Error),
+                .Empty_Watermark(Empty_Watermark),
+                .Almost_Empty(Almost_Empty),
+                .Empty(Empty),
+
+                .DOUT(DOUT)
+         				);
+
+endmodule
+
+module f2048x18_1024x36 (DIN,PUSH,POP,clock0,Async_Flush,Almost_Full,Almost_Empty,Full,Empty,Full_Watermark,Empty_Watermark,Overrun_Error,Underrun_Error,DOUT);
+
+parameter WR_DATA_WIDTH = 18;
+parameter RD_DATA_WIDTH = 36;
+parameter UPAE_DBITS = 12'd10;
+parameter UPAF_DBITS = 12'd10;
+
+input clock0;
+input PUSH,POP;
+input [WR_DATA_WIDTH-1:0] DIN;
+input Async_Flush;
+output [RD_DATA_WIDTH-1:0] DOUT;
+output Almost_Full,Almost_Empty;
+output Full, Empty;
+output Full_Watermark, Empty_Watermark;
+output Overrun_Error, Underrun_Error;
+
+SFIFO_36K_BLK  # (.WR_DATA_WIDTH(WR_DATA_WIDTH),.RD_DATA_WIDTH(RD_DATA_WIDTH),.UPAE_DBITS(UPAE_DBITS),.UPAF_DBITS(UPAF_DBITS)
+        				 ) 
+  FIFO_INST    (
+                .DIN(DIN),
+                .PUSH(PUSH),
+                .POP(POP),
+                .CLK(clock0),
+                .Async_Flush(Async_Flush),
+                
+                .Overrun_Error(Overrun_Error),
+                .Full_Watermark(Full_Watermark),
+                .Almost_Full(Almost_Full),
+                .Full(Full),
+                
+                .Underrun_Error(Underrun_Error),
+                .Empty_Watermark(Empty_Watermark),
+                .Almost_Empty(Almost_Empty),
+                .Empty(Empty),
+
+                .DOUT(DOUT)
+         				);
+
+endmodule
+
+module f2048x18_4098x9 (DIN,PUSH,POP,clock0,Async_Flush,Almost_Full,Almost_Empty,Full,Empty,Full_Watermark,Empty_Watermark,Overrun_Error,Underrun_Error,DOUT);
+
+parameter WR_DATA_WIDTH = 18;
+parameter RD_DATA_WIDTH = 9;
+parameter UPAE_DBITS = 12'd10;
+parameter UPAF_DBITS = 12'd10;
+
+input clock0;
+input PUSH,POP;
+input [WR_DATA_WIDTH-1:0] DIN;
+input Async_Flush;
+output [RD_DATA_WIDTH-1:0] DOUT;
+output Almost_Full,Almost_Empty;
+output Full, Empty;
+output Full_Watermark, Empty_Watermark;
+output Overrun_Error, Underrun_Error;
+
+SFIFO_36K_BLK  # (.WR_DATA_WIDTH(WR_DATA_WIDTH),.RD_DATA_WIDTH(RD_DATA_WIDTH),.UPAE_DBITS(UPAE_DBITS),.UPAF_DBITS(UPAF_DBITS)
+        				 ) 
+  FIFO_INST    (
+                .DIN(DIN),
+                .PUSH(PUSH),
+                .POP(POP),
+                .CLK(clock0),
+                .Async_Flush(Async_Flush),
+                
+                .Overrun_Error(Overrun_Error),
+                .Full_Watermark(Full_Watermark),
+                .Almost_Full(Almost_Full),
+                .Full(Full),
+                
+                .Underrun_Error(Underrun_Error),
+                .Empty_Watermark(Empty_Watermark),
+                .Almost_Empty(Almost_Empty),
+                .Empty(Empty),
+
+                .DOUT(DOUT)
+         				);
+
+endmodule
+
+module f1024x36_2048x18 (DIN,PUSH,POP,clock0,Async_Flush,Almost_Full,Almost_Empty,Full,Empty,Full_Watermark,Empty_Watermark,Overrun_Error,Underrun_Error,DOUT);
+
+parameter WR_DATA_WIDTH = 36;
+parameter RD_DATA_WIDTH = 18;
+parameter UPAE_DBITS = 12'd10;
+parameter UPAF_DBITS = 12'd10;
+
+input clock0;
+input PUSH,POP;
+input [WR_DATA_WIDTH-1:0] DIN;
+input Async_Flush;
+output [RD_DATA_WIDTH-1:0] DOUT;
+output Almost_Full,Almost_Empty;
+output Full, Empty;
+output Full_Watermark, Empty_Watermark;
+output Overrun_Error, Underrun_Error;
+
+SFIFO_36K_BLK  # (.WR_DATA_WIDTH(WR_DATA_WIDTH),.RD_DATA_WIDTH(RD_DATA_WIDTH),.UPAE_DBITS(UPAE_DBITS),.UPAF_DBITS(UPAF_DBITS)
+        				 ) 
+  FIFO_INST    (
+                .DIN(DIN),
+                .PUSH(PUSH),
+                .POP(POP),
+                .CLK(clock0),
+                .Async_Flush(Async_Flush),
+                
+                .Overrun_Error(Overrun_Error),
+                .Full_Watermark(Full_Watermark),
+                .Almost_Full(Almost_Full),
+                .Full(Full),
+                
+                .Underrun_Error(Underrun_Error),
+                .Empty_Watermark(Empty_Watermark),
+                .Almost_Empty(Almost_Empty),
+                .Empty(Empty),
+
+                .DOUT(DOUT)
+         				);
+
+endmodule
\ No newline at end of file
diff --git a/ql-qlf-plugin/tests/qlf_k6n10f/asymmetric_bram36k_sfifo/sim/Makefile b/ql-qlf-plugin/tests/qlf_k6n10f/asymmetric_bram36k_sfifo/sim/Makefile
new file mode 100644
index 0000000..71bef81
--- /dev/null
+++ b/ql-qlf-plugin/tests/qlf_k6n10f/asymmetric_bram36k_sfifo/sim/Makefile
@@ -0,0 +1,43 @@
+# Copyright (C) 2019-2022 The SymbiFlow Authors
+#
+# Use of this source code is governed by a ISC-style
+# license that can be found in the LICENSE file or at
+# https://opensource.org/licenses/ISC
+#
+# SPDX-License-Identifier: ISC
+
+TESTBENCH = asymmetric_bram36k_sfifo_tb.v
+POST_SYNTH = f4096x9_1024x36_post_synth f2048x18_1024x36_post_synth f2048x18_4098x9_post_synth f1024x36_2048x18_post_synth
+ADDR_WIDTH0 = 12 11 11 10
+DATA_WIDTH0 = 9 18 18 36
+ADDR_WIDTH1 = 10 10 12 11
+DATA_WIDTH1 = 36 36 9 18
+TOP = f4096x9_1024x36 f2048x18_1024x36 f2048x18_4098x9 f1024x36_2048x18
+ADDR0_DEFINES = $(foreach awidth0, $(ADDR_WIDTH0),-DADDR_WIDTH0="$(awidth0)")
+ADDR1_DEFINES = $(foreach awidth1, $(ADDR_WIDTH1),-DADDR_WIDTH1="$(awidth1)")
+DATA0_DEFINES = $(foreach dwidth0, $(DATA_WIDTH0),-DDATA_WIDTH0="$(dwidth0)")
+DATA1_DEFINES = $(foreach dwidth1, $(DATA_WIDTH1),-DDATA_WIDTH1="$(dwidth1)")
+TOP_DEFINES = $(foreach top, $(TOP),-DTOP="$(top)")
+VCD_DEFINES = $(foreach vcd, $(POST_SYNTH),-DVCD="$(vcd).vcd")
+
+SIM_LIBS = $(shell find ../../../../qlf_k6n10f -name "*.v" -not -name "*_map.v")
+
+define simulate_post_synth
+	@iverilog  -vvvv -g2005 $(word $(1),$(ADDR0_DEFINES)) $(word $(1),$(ADDR1_DEFINES)) $(word $(1),$(DATA0_DEFINES)) $(word $(1),$(DATA1_DEFINES)) $(word $(1),$(TOP_DEFINES)) $(word $(1),$(VCD_DEFINES)) -o $(word $(1),$(POST_SYNTH)).vvp $(word $(1),$(POST_SYNTH)).v $(SIM_LIBS) $(TESTBENCH) > $(word $(1),$(POST_SYNTH)).vvp.log 2>&1
+	@vvp -vvvv $(word $(1),$(POST_SYNTH)).vvp > $(word $(1),$(POST_SYNTH)).vcd.log 2>&1
+endef
+
+define clean_post_synth_sim
+	@rm -rf  $(word $(1),$(POST_SYNTH)).vcd $(word $(1),$(POST_SYNTH)).vvp $(word $(1),$(POST_SYNTH)).vvp.log $(word $(1),$(POST_SYNTH)).vcd.log
+endef
+
+#FIXME: $(call simulate_post_synth,3)
+sim:
+	$(call simulate_post_synth,1)
+	$(call clean_post_synth_sim,1)
+	$(call simulate_post_synth,2)
+	$(call clean_post_synth_sim,2)
+	$(call simulate_post_synth,3)
+	$(call clean_post_synth_sim,3)
+	$(call simulate_post_synth,4)
+	$(call clean_post_synth_sim,4)
\ No newline at end of file
diff --git a/ql-qlf-plugin/tests/qlf_k6n10f/asymmetric_bram36k_sfifo/sim/asymmetric_bram36k_sfifo_tb.v b/ql-qlf-plugin/tests/qlf_k6n10f/asymmetric_bram36k_sfifo/sim/asymmetric_bram36k_sfifo_tb.v
new file mode 100644
index 0000000..d2fcbbd
--- /dev/null
+++ b/ql-qlf-plugin/tests/qlf_k6n10f/asymmetric_bram36k_sfifo/sim/asymmetric_bram36k_sfifo_tb.v
@@ -0,0 +1,277 @@
+// Copyright (C) 2019-2022 The SymbiFlow Authors
+//
+// Use of this source code is governed by a ISC-style
+// license that can be found in the LICENSE file or at
+// https://opensource.org/licenses/ISC
+//
+// SPDX-License-Identifier: ISC
+
+`timescale 1ns/1ps
+
+`define STRINGIFY(x) `"x`"
+
+module TB;
+	localparam PERIOD = 30;
+	localparam ADDR_INCR = 1;
+
+	reg clk0;
+  reg flush;
+	reg pop;
+	wire [`DATA_WIDTH1-1:0] dout;
+	reg push;
+	reg [`DATA_WIDTH0-1:0] din;
+  wire almost_full,almost_empty;
+  wire full, empty;
+  wire full_watermark, empty_watermark;
+  wire overrun_error, underrun_error;
+
+  initial 
+  begin
+    clk0 = 0;
+    pop = 0;
+    push = 0;
+    flush = 1;
+    din = 0;
+    #40
+    flush = 0;
+  end
+  
+	initial forever #(PERIOD / 3.0) clk0 = ~clk0;
+  
+	initial begin
+		$dumpfile(`STRINGIFY(`VCD));
+		$dumpvars;
+	end
+
+	integer a;
+
+	reg done;
+	initial done = 1'b0;
+  
+  reg read_test;
+	initial read_test = 0;
+
+	reg [`DATA_WIDTH1-1:0] expected;
+  initial expected = 0;
+
+	wire error = (read_test) ? dout !== expected : 0;
+
+	integer error_cnt = 0;
+	always @ (posedge clk0)
+	begin
+		if (error)
+			error_cnt <= error_cnt + 1'b1; 
+	end
+
+case (`STRINGIFY(`TOP))
+"f4096x9_1024x36": begin
+	initial #(50) begin
+		// Write data
+		for (a = 0; a < (1<<`ADDR_WIDTH0) ; a = a + ADDR_INCR) begin
+			@(negedge clk0) begin
+				din = a[10:2];
+				push = 1;
+			end
+			@(posedge clk0) begin
+				#(PERIOD/10) push = 0;
+			end
+		end
+		// Read data
+		read_test = 1;
+		for (a = 0; a < (1<<`ADDR_WIDTH1); a = a + ADDR_INCR) begin
+			@(posedge clk0) begin
+        expected <= {a[8],a[8],a[7:0],a[7:0],a[8],a[8],a[7:0],a[7:0]};
+				#(PERIOD/10) pop = 0;
+				if ( dout !== expected) begin
+					$display("%d: PORT 0: FAIL: mismatch act=%x exp=%x at %x", $time, dout, expected, a);
+				end else begin
+					$display("%d: PORT 0: OK: act=%x exp=%x at %x", $time, dout, expected, a);
+				end
+			end
+      @(negedge clk0) begin
+				pop = 1;
+			end
+		end
+		done = 1'b1;
+    a = 0;
+	end
+end
+"f2048x18_1024x36": begin
+	initial #(50) begin
+		// Write data
+		for (a = 0; a < (1<<`ADDR_WIDTH0) ; a = a + ADDR_INCR) begin
+			@(negedge clk0) begin
+				din = a[18:1];
+				push = 1;
+			end
+			@(posedge clk0) begin
+				#(PERIOD/10) push = 0;
+			end
+		end
+		// Read data
+		read_test = 1;
+		for (a = 0; a < (1<<`ADDR_WIDTH1); a = a + ADDR_INCR) begin
+			@(posedge clk0) begin
+        expected <= {a[17:0],a[17:0]};
+				#(PERIOD/10) pop = 0;
+				if ( dout !== expected) begin
+					$display("%d: PORT 0: FAIL: mismatch act=%x exp=%x at %x", $time, dout, expected, a);
+				end else begin
+					$display("%d: PORT 0: OK: act=%x exp=%x at %x", $time, dout, expected, a);
+				end
+			end
+      @(negedge clk0) begin
+				pop = 1;
+			end
+		end
+		done = 1'b1;
+    a = 0;
+	end
+end  
+"f2048x18_4098x9": begin
+	initial #(50) begin
+		// Write data
+		for (a = 0; a < (1<<`ADDR_WIDTH0) ; a = a + ADDR_INCR) begin
+			@(negedge clk0) begin
+				din = {a[8],a[8],a[7:0],a[7:0]};
+				push = 1;
+			end
+			@(posedge clk0) begin
+				#(PERIOD/10) push = 0;
+			end
+		end
+		// Read data
+		read_test = 1;
+		for (a = 0; a < (1<<`ADDR_WIDTH1); a = a + ADDR_INCR) begin
+			@(posedge clk0) begin
+        expected <= {a[9:1]};
+				#(PERIOD/10) pop = 0;
+				if ( dout !== expected) begin
+					$display("%d: PORT 0: FAIL: mismatch act=%x exp=%x at %x", $time, dout, expected, a);
+				end else begin
+					$display("%d: PORT 0: OK: act=%x exp=%x at %x", $time, dout, expected, a);
+				end
+			end
+      @(negedge clk0) begin
+				pop = 1;
+			end
+		end
+		done = 1'b1;
+    a = 0;
+	end
+end
+"f1024x36_2048x18": begin
+	initial #(50) begin
+		// Write data
+		for (a = 0; a < (1<<`ADDR_WIDTH0) ; a = a + ADDR_INCR) begin
+			@(negedge clk0) begin
+				din = {a[17:0],a[17:0]};
+				push = 1;
+			end
+			@(posedge clk0) begin
+				#(PERIOD/10) push = 0;
+			end
+		end
+		// Read data
+		read_test = 1;
+		for (a = 0; a < (1<<`ADDR_WIDTH1); a = a + ADDR_INCR) begin
+			@(posedge clk0) begin
+        expected <= {a[18:1]};
+				#(PERIOD/10) pop = 0;
+				if ( dout !== expected) begin
+					$display("%d: PORT 0: FAIL: mismatch act=%x exp=%x at %x", $time, dout, expected, a);
+				end else begin
+					$display("%d: PORT 0: OK: act=%x exp=%x at %x", $time, dout, expected, a);
+				end
+			end
+      @(negedge clk0) begin
+				pop = 1;
+			end
+		end
+		done = 1'b1;
+    a = 0;
+  end
+end
+endcase
+
+	// Scan for simulation finish
+	always @(posedge clk0) begin
+		if (done)
+			$finish_and_return( (error_cnt == 0) ? 0 : -1 );
+	end
+
+	case (`STRINGIFY(`TOP))
+		"f4096x9_1024x36": begin
+			f4096x9_1024x36 #() afifo (
+        .DIN(din),
+        .PUSH(push),
+        .POP(pop),
+        .clock0(clk0),
+        .Async_Flush(flush),
+        .Almost_Full(almost_full),
+        .Almost_Empty(almost_empty),
+        .Full(full),
+        .Empty(empty),
+        .Full_Watermark(full_watermark),
+        .Empty_Watermark(empty_watermark),
+        .Overrun_Error(overrun_error),
+        .Underrun_Error(underrun_error),
+        .DOUT(dout)
+			);
+		end
+		"f2048x18_1024x36": begin
+			f2048x18_1024x36 #() afifo (
+        .DIN(din),
+        .PUSH(push),
+        .POP(pop),
+        .clock0(clk0),
+        .Async_Flush(flush),
+        .Almost_Full(almost_full),
+        .Almost_Empty(almost_empty),
+        .Full(full),
+        .Empty(empty),
+        .Full_Watermark(full_watermark),
+        .Empty_Watermark(empty_watermark),
+        .Overrun_Error(overrun_error),
+        .Underrun_Error(underrun_error),
+        .DOUT(dout)
+			);
+		end
+		"f2048x18_4098x9": begin
+			f2048x18_4098x9 #() afifo (
+        .DIN(din),
+        .PUSH(push),
+        .POP(pop),
+        .clock0(clk0),
+        .Async_Flush(flush),
+        .Almost_Full(almost_full),
+        .Almost_Empty(almost_empty),
+        .Full(full),
+        .Empty(empty),
+        .Full_Watermark(full_watermark),
+        .Empty_Watermark(empty_watermark),
+        .Overrun_Error(overrun_error),
+        .Underrun_Error(underrun_error),
+        .DOUT(dout)
+			);
+		end
+		"f1024x36_2048x18": begin
+			f1024x36_2048x18 #() afifo (
+        .DIN(din),
+        .PUSH(push),
+        .POP(pop),
+        .clock0(clk0),
+        .Async_Flush(flush),
+        .Almost_Full(almost_full),
+        .Almost_Empty(almost_empty),
+        .Full(full),
+        .Empty(empty),
+        .Full_Watermark(full_watermark),
+        .Empty_Watermark(empty_watermark),
+        .Overrun_Error(overrun_error),
+        .Underrun_Error(underrun_error),
+        .DOUT(dout)
+			);
+		end
+	endcase
+endmodule
diff --git a/ql-qlf-plugin/tests/qlf_k6n10f/bram18k_afifo/bram18k_afifo.tcl b/ql-qlf-plugin/tests/qlf_k6n10f/bram18k_afifo/bram18k_afifo.tcl
new file mode 100644
index 0000000..99c7405
--- /dev/null
+++ b/ql-qlf-plugin/tests/qlf_k6n10f/bram18k_afifo/bram18k_afifo.tcl
@@ -0,0 +1,49 @@
+yosys -import
+
+if { [info procs ql-qlf-k6n10f] == {} } { plugin -i ql-qlf }
+yosys -import  ;
+
+read_verilog $::env(DESIGN_TOP).v
+design -save bram18k_afifo
+
+select af1024x18_1024x18
+select *
+synth_quicklogic -family qlf_k6n10f -top af1024x18_1024x18 -bram_types
+opt_expr -undriven
+opt_clean
+stat
+write_verilog sim/af1024x18_1024x18_post_synth.v
+select -assert-count 1 t:TDP36K_FIFO_ASYNC_WR_X18_RD_X18_split
+
+select -clear
+design -load bram18k_afifo
+select af1024x16_1024x16
+select *
+synth_quicklogic -family qlf_k6n10f -top af1024x16_1024x16 -bram_types
+opt_expr -undriven
+opt_clean
+stat
+write_verilog sim/af1024x16_1024x16_post_synth.v
+select -assert-count 1 t:TDP36K_FIFO_ASYNC_WR_X18_RD_X18_split
+
+select -clear
+design -load bram18k_afifo
+select af2048x9_2048x9
+select *
+synth_quicklogic -family qlf_k6n10f -top af2048x9_2048x9 -bram_types
+opt_expr -undriven
+opt_clean
+stat
+write_verilog sim/af2048x9_2048x9_post_synth.v
+select -assert-count 1 t:TDP36K_FIFO_ASYNC_WR_X9_RD_X9_split
+
+select -clear
+design -load bram18k_afifo
+select af2048x8_2048x8
+select *
+synth_quicklogic -family qlf_k6n10f -top af2048x8_2048x8 -bram_types
+opt_expr -undriven
+opt_clean
+stat
+write_verilog sim/af2048x8_2048x8_post_synth.v
+select -assert-count 1 t:TDP36K_FIFO_ASYNC_WR_X9_RD_X9_split
diff --git a/ql-qlf-plugin/tests/qlf_k6n10f/bram18k_afifo/bram18k_afifo.v b/ql-qlf-plugin/tests/qlf_k6n10f/bram18k_afifo/bram18k_afifo.v
new file mode 100644
index 0000000..69d4f32
--- /dev/null
+++ b/ql-qlf-plugin/tests/qlf_k6n10f/bram18k_afifo/bram18k_afifo.v
@@ -0,0 +1,167 @@
+module af1024x18_1024x18 (DIN,PUSH,POP,clock0,clock1,Async_Flush,Almost_Full,Almost_Empty,Full,Empty,Full_Watermark,Empty_Watermark,Overrun_Error,Underrun_Error,DOUT);
+
+parameter WR_DATA_WIDTH = 18;
+parameter RD_DATA_WIDTH = 18;
+parameter UPAE_DBITS = 11'd10;
+parameter UPAF_DBITS = 11'd10;
+
+input clock0,clock1;
+input PUSH,POP;
+input [WR_DATA_WIDTH-1:0] DIN;
+input Async_Flush;
+output [RD_DATA_WIDTH-1:0] DOUT;
+output Almost_Full,Almost_Empty;
+output Full, Empty;
+output Full_Watermark, Empty_Watermark;
+output Overrun_Error, Underrun_Error;
+
+AFIFO_18K_BLK  # (.WR_DATA_WIDTH(WR_DATA_WIDTH),.RD_DATA_WIDTH(RD_DATA_WIDTH),.UPAE_DBITS(UPAE_DBITS),.UPAF_DBITS(UPAF_DBITS)
+        				 ) 
+  FIFO_INST    (
+                .DIN(DIN),
+                .PUSH(PUSH),
+                .POP(POP),
+                .Push_Clk(clock0),
+                .Pop_Clk(clock1),
+                .Async_Flush(Async_Flush),
+                
+                .Overrun_Error(Overrun_Error),
+                .Full_Watermark(Full_Watermark),
+                .Almost_Full(Almost_Full),
+                .Full(Full),
+                
+                .Underrun_Error(Underrun_Error),
+                .Empty_Watermark(Empty_Watermark),
+                .Almost_Empty(Almost_Empty),
+                .Empty(Empty),
+
+                .DOUT(DOUT)
+         				);
+
+endmodule
+
+module af1024x16_1024x16 (DIN,PUSH,POP,clock0,clock1,Async_Flush,Almost_Full,Almost_Empty,Full,Empty,Full_Watermark,Empty_Watermark,Overrun_Error,Underrun_Error,DOUT);
+
+parameter WR_DATA_WIDTH = 16;
+parameter RD_DATA_WIDTH = 16;
+parameter UPAE_DBITS = 11'd10;
+parameter UPAF_DBITS = 11'd10;
+
+input clock0,clock1;
+input PUSH,POP;
+input [WR_DATA_WIDTH-1:0] DIN;
+input Async_Flush;
+output [RD_DATA_WIDTH-1:0] DOUT;
+output Almost_Full,Almost_Empty;
+output Full, Empty;
+output Full_Watermark, Empty_Watermark;
+output Overrun_Error, Underrun_Error;
+
+AFIFO_18K_BLK  # (.WR_DATA_WIDTH(WR_DATA_WIDTH),.RD_DATA_WIDTH(RD_DATA_WIDTH),.UPAE_DBITS(UPAE_DBITS),.UPAF_DBITS(UPAF_DBITS)
+        				 ) 
+  FIFO_INST    (
+                .DIN(DIN),
+                .PUSH(PUSH),
+                .POP(POP),
+                .Push_Clk(clock0),
+                .Pop_Clk(clock1),
+                .Async_Flush(Async_Flush),
+                
+                .Overrun_Error(Overrun_Error),
+                .Full_Watermark(Full_Watermark),
+                .Almost_Full(Almost_Full),
+                .Full(Full),
+                
+                .Underrun_Error(Underrun_Error),
+                .Empty_Watermark(Empty_Watermark),
+                .Almost_Empty(Almost_Empty),
+                .Empty(Empty),
+
+                .DOUT(DOUT)
+         				);
+
+endmodule
+
+module af2048x9_2048x9 (DIN,PUSH,POP,clock0,clock1,Async_Flush,Almost_Full,Almost_Empty,Full,Empty,Full_Watermark,Empty_Watermark,Overrun_Error,Underrun_Error,DOUT);
+
+parameter WR_DATA_WIDTH = 9;
+parameter RD_DATA_WIDTH = 9;
+parameter UPAE_DBITS = 11'd10;
+parameter UPAF_DBITS = 11'd10;
+
+input clock0,clock1;
+input PUSH,POP;
+input [WR_DATA_WIDTH-1:0] DIN;
+input Async_Flush;
+output [RD_DATA_WIDTH-1:0] DOUT;
+output Almost_Full,Almost_Empty;
+output Full, Empty;
+output Full_Watermark, Empty_Watermark;
+output Overrun_Error, Underrun_Error;
+
+AFIFO_18K_BLK  # (.WR_DATA_WIDTH(WR_DATA_WIDTH),.RD_DATA_WIDTH(RD_DATA_WIDTH),.UPAE_DBITS(UPAE_DBITS),.UPAF_DBITS(UPAF_DBITS)
+        				 ) 
+  FIFO_INST    (
+                .DIN(DIN),
+                .PUSH(PUSH),
+                .POP(POP),
+                .Push_Clk(clock0),
+                .Pop_Clk(clock1),
+                .Async_Flush(Async_Flush),
+                
+                .Overrun_Error(Overrun_Error),
+                .Full_Watermark(Full_Watermark),
+                .Almost_Full(Almost_Full),
+                .Full(Full),
+                
+                .Underrun_Error(Underrun_Error),
+                .Empty_Watermark(Empty_Watermark),
+                .Almost_Empty(Almost_Empty),
+                .Empty(Empty),
+
+                .DOUT(DOUT)
+         				);
+
+endmodule
+
+module af2048x8_2048x8 (DIN,PUSH,POP,clock0,clock1,Async_Flush,Almost_Full,Almost_Empty,Full,Empty,Full_Watermark,Empty_Watermark,Overrun_Error,Underrun_Error,DOUT);
+
+parameter WR_DATA_WIDTH = 8;
+parameter RD_DATA_WIDTH = 8;
+parameter UPAE_DBITS = 11'd10;
+parameter UPAF_DBITS = 11'd10;
+
+input clock0,clock1;
+input PUSH,POP;
+input [WR_DATA_WIDTH-1:0] DIN;
+input Async_Flush;
+output [RD_DATA_WIDTH-1:0] DOUT;
+output Almost_Full,Almost_Empty;
+output Full, Empty;
+output Full_Watermark, Empty_Watermark;
+output Overrun_Error, Underrun_Error;
+
+AFIFO_18K_BLK  # (.WR_DATA_WIDTH(WR_DATA_WIDTH),.RD_DATA_WIDTH(RD_DATA_WIDTH),.UPAE_DBITS(UPAE_DBITS),.UPAF_DBITS(UPAF_DBITS)
+        				 ) 
+  FIFO_INST    (
+                .DIN(DIN),
+                .PUSH(PUSH),
+                .POP(POP),
+                .Push_Clk(clock0),
+                .Pop_Clk(clock1),
+                .Async_Flush(Async_Flush),
+                
+                .Overrun_Error(Overrun_Error),
+                .Full_Watermark(Full_Watermark),
+                .Almost_Full(Almost_Full),
+                .Full(Full),
+                
+                .Underrun_Error(Underrun_Error),
+                .Empty_Watermark(Empty_Watermark),
+                .Almost_Empty(Almost_Empty),
+                .Empty(Empty),
+
+                .DOUT(DOUT)
+         				);
+
+endmodule
\ No newline at end of file
diff --git a/ql-qlf-plugin/tests/qlf_k6n10f/bram18k_afifo/sim/Makefile b/ql-qlf-plugin/tests/qlf_k6n10f/bram18k_afifo/sim/Makefile
new file mode 100644
index 0000000..0153897
--- /dev/null
+++ b/ql-qlf-plugin/tests/qlf_k6n10f/bram18k_afifo/sim/Makefile
@@ -0,0 +1,51 @@
+# Copyright 2020-2022 F4PGA Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-License-Identifier: Apache-2.0
+
+TESTBENCH = bram18k_afifo_tb.v
+POST_SYNTH = af1024x18_1024x18_post_synth af1024x16_1024x16_post_synth af2048x9_2048x9_post_synth af2048x8_2048x8_post_synth
+ADDR_WIDTH0 = 10 10 11 11
+DATA_WIDTH0 = 18 16 9 8
+ADDR_WIDTH1 = 10 10 11 11
+DATA_WIDTH1 = 18 16 9 8
+TOP = af1024x18_1024x18 af1024x16_1024x16 af2048x9_2048x9 af2048x8_2048x8
+ADDR0_DEFINES = $(foreach awidth0, $(ADDR_WIDTH0),-DADDR_WIDTH0="$(awidth0)")
+ADDR1_DEFINES = $(foreach awidth1, $(ADDR_WIDTH1),-DADDR_WIDTH1="$(awidth1)")
+DATA0_DEFINES = $(foreach dwidth0, $(DATA_WIDTH0),-DDATA_WIDTH0="$(dwidth0)")
+DATA1_DEFINES = $(foreach dwidth1, $(DATA_WIDTH1),-DDATA_WIDTH1="$(dwidth1)")
+TOP_DEFINES = $(foreach top, $(TOP),-DTOP="$(top)")
+VCD_DEFINES = $(foreach vcd, $(POST_SYNTH),-DVCD="$(vcd).vcd")
+
+SIM_LIBS = $(shell find ../../../../qlf_k6n10f -name "*.v" -not -name "*_map.v")
+
+define simulate_post_synth
+	@iverilog  -vvvv -g2005 $(word $(1),$(ADDR0_DEFINES)) $(word $(1),$(ADDR1_DEFINES)) $(word $(1),$(DATA0_DEFINES)) $(word $(1),$(DATA1_DEFINES)) $(word $(1),$(TOP_DEFINES)) $(word $(1),$(VCD_DEFINES)) -o $(word $(1),$(POST_SYNTH)).vvp $(word $(1),$(POST_SYNTH)).v $(SIM_LIBS) $(TESTBENCH) > $(word $(1),$(POST_SYNTH)).vvp.log 2>&1
+	@vvp -vvvv $(word $(1),$(POST_SYNTH)).vvp > $(word $(1),$(POST_SYNTH)).vcd.log 2>&1
+endef
+
+define clean_post_synth_sim
+	@rm -rf  $(word $(1),$(POST_SYNTH)).vcd $(word $(1),$(POST_SYNTH)).vvp $(word $(1),$(POST_SYNTH)).vvp.log $(word $(1),$(POST_SYNTH)).vcd.log
+endef
+
+# FIXME: $(call simulate_post_synth,5)
+sim:
+	$(call simulate_post_synth,1)
+	$(call clean_post_synth_sim,1)
+	$(call simulate_post_synth,2)
+	$(call clean_post_synth_sim,2)
+	$(call simulate_post_synth,3)
+	$(call clean_post_synth_sim,3)
+	$(call simulate_post_synth,4)
+	$(call clean_post_synth_sim,4)
\ No newline at end of file
diff --git a/ql-qlf-plugin/tests/qlf_k6n10f/bram18k_afifo/sim/bram18k_afifo_tb.v b/ql-qlf-plugin/tests/qlf_k6n10f/bram18k_afifo/sim/bram18k_afifo_tb.v
new file mode 100644
index 0000000..62460b1
--- /dev/null
+++ b/ql-qlf-plugin/tests/qlf_k6n10f/bram18k_afifo/sim/bram18k_afifo_tb.v
@@ -0,0 +1,195 @@
+// Copyright 2020-2022 F4PGA Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: Apache-2.0
+
+`timescale 1ns/1ps
+
+`define STRINGIFY(x) `"x`"
+
+module TB;
+	localparam PERIOD = 30;
+	localparam ADDR_INCR = 1;
+
+	reg clk0;
+  reg clk1;
+  reg flush;
+	reg pop;
+	wire [`DATA_WIDTH1-1:0] dout;
+	reg push;
+	reg [`DATA_WIDTH0-1:0] din;
+  wire almost_full,almost_empty;
+  wire full, empty;
+  wire full_watermark, empty_watermark;
+  wire overrun_error, underrun_error;
+
+  initial 
+  begin
+    clk0 = 0;
+    clk1 = 0;
+    pop = 0;
+    push = 0;
+    flush = 1;
+    din = 0;
+    #40
+    flush = 0;
+  end
+  
+	initial forever #(PERIOD / 3.0) clk0 = ~clk0;
+  initial forever #(PERIOD / 2.0) clk1 = ~clk1;
+  
+	initial begin
+		$dumpfile(`STRINGIFY(`VCD));
+		$dumpvars;
+	end
+
+	integer a;
+
+	reg done;
+	initial done = 1'b0;
+ 
+	reg read_test;
+	initial read_test = 0;
+
+	reg [`DATA_WIDTH1-1:0] expected;
+  initial expected = 0;
+
+	always @(posedge clk1) begin
+		expected <= (a | (a << 20) | 20'h55000) & {`DATA_WIDTH1{1'b1}};
+	end
+
+	wire error = ((a != 0) && read_test) ? dout !== expected : 0;
+
+	integer error_cnt = 0;
+	always @ (posedge clk1)
+	begin
+		if (error)
+			error_cnt <= error_cnt + 1'b1; 
+	end
+
+	initial #(50) begin
+    @(posedge clk0)
+		// Write data
+		for (a = 0; a < (1<<`ADDR_WIDTH0); a = a + ADDR_INCR) begin
+			@(negedge clk0) begin
+				din = a | (a << 20) | 20'h55000;
+				push = 1;
+			end
+			@(posedge clk0) begin
+				#(PERIOD/10) push = 0;
+			end
+		end
+		// Read data
+		read_test = 1;
+		for (a = 0; a < (1<<`ADDR_WIDTH1); a = a + ADDR_INCR) begin
+			@(posedge clk1) begin
+				#(PERIOD/10) pop = 0;
+				if ( dout !== expected) begin
+					$display("%d: FAIL: mismatch act=%x exp=%x at %x", $time, dout, expected, a);
+				end else begin
+					$display("%d: OK: act=%x exp=%x at %x", $time, dout, expected, a);
+				end
+			end
+			@(negedge clk1) begin
+				pop = 1;
+			end
+		end
+		done = 1'b1;
+	end
+
+	// Scan for simulation finish
+	always @(posedge clk1) begin
+		if (done)
+			$finish_and_return( (error_cnt == 0) ? 0 : -1 );
+	end
+
+	case (`STRINGIFY(`TOP))
+		"af1024x18_1024x18": begin
+			af1024x18_1024x18 #() afifo (
+        .DIN(din),
+        .PUSH(push),
+        .POP(pop),
+        .clock0(clk0),
+        .clock1(clk1),
+        .Async_Flush(flush),
+        .Almost_Full(almost_full),
+        .Almost_Empty(almost_empty),
+        .Full(full),
+        .Empty(empty),
+        .Full_Watermark(full_watermark),
+        .Empty_Watermark(empty_watermark),
+        .Overrun_Error(overrun_error),
+        .Underrun_Error(underrun_error),
+        .DOUT(dout)
+			);
+		end
+		"af1024x16_1024x16": begin
+			af1024x16_1024x16 #() afifo (
+        .DIN(din),
+        .PUSH(push),
+        .POP(pop),
+        .clock0(clk0),
+        .clock1(clk1),
+        .Async_Flush(flush),
+        .Almost_Full(almost_full),
+        .Almost_Empty(almost_empty),
+        .Full(full),
+        .Empty(empty),
+        .Full_Watermark(full_watermark),
+        .Empty_Watermark(empty_watermark),
+        .Overrun_Error(overrun_error),
+        .Underrun_Error(underrun_error),
+        .DOUT(dout)
+			);
+		end
+		"af2048x9_2048x9": begin
+			af2048x9_2048x9 #() afifo (
+        .DIN(din),
+        .PUSH(push),
+        .POP(pop),
+        .clock0(clk0),
+        .clock1(clk1),
+        .Async_Flush(flush),
+        .Almost_Full(almost_full),
+        .Almost_Empty(almost_empty),
+        .Full(full),
+        .Empty(empty),
+        .Full_Watermark(full_watermark),
+        .Empty_Watermark(empty_watermark),
+        .Overrun_Error(overrun_error),
+        .Underrun_Error(underrun_error),
+        .DOUT(dout)
+			);
+		end		
+		"af2048x8_2048x8": begin
+			af2048x8_2048x8 #() afifo (
+        .DIN(din),
+        .PUSH(push),
+        .POP(pop),
+        .clock0(clk0),
+        .clock1(clk1),
+        .Async_Flush(flush),
+        .Almost_Full(almost_full),
+        .Almost_Empty(almost_empty),
+        .Full(full),
+        .Empty(empty),
+        .Full_Watermark(full_watermark),
+        .Empty_Watermark(empty_watermark),
+        .Overrun_Error(overrun_error),
+        .Underrun_Error(underrun_error),
+        .DOUT(dout)
+			);
+		end	
+	endcase
+endmodule
diff --git a/ql-qlf-plugin/tests/qlf_k6n10f/bram18k_sdp/bram18k_sdp.tcl b/ql-qlf-plugin/tests/qlf_k6n10f/bram18k_sdp/bram18k_sdp.tcl
new file mode 100644
index 0000000..092d4c2
--- /dev/null
+++ b/ql-qlf-plugin/tests/qlf_k6n10f/bram18k_sdp/bram18k_sdp.tcl
@@ -0,0 +1,39 @@
+yosys -import
+
+if { [info procs ql-qlf-k6n10f] == {} } { plugin -i ql-qlf }
+yosys -import  ;
+
+read_verilog $::env(DESIGN_TOP).v
+design -save bram18k_sdp
+
+select spram_18x1024_2x
+select *
+synth_quicklogic -family qlf_k6n10f -top spram_18x1024_2x -bram_types
+opt_expr -undriven
+opt_clean
+stat
+write_verilog sim/spram_18x1024_2x_post_synth.v
+select -assert-count 2 t:TDP36K_BRAM_WR_X18_RD_X18_split
+
+select -clear
+design -load bram18k_sdp
+select spram_9x2048_x2
+select *
+synth_quicklogic -family qlf_k6n10f -top spram_9x2048_x2 -bram_types
+opt_expr -undriven
+opt_clean
+stat
+write_verilog sim/spram_9x2048_x2_post_synth.v
+select -assert-count 2 t:TDP36K_BRAM_WR_X9_RD_X9_split
+
+select -clear
+design -load bram18k_sdp
+select spram_9x2048_18x1024
+select *
+synth_quicklogic -family qlf_k6n10f -top spram_9x2048_18x1024 -bram_types
+opt_expr -undriven
+opt_clean
+stat
+write_verilog sim/spram_9x2048_18x1024_post_synth.v
+select -assert-count 1 t:TDP36K_BRAM_WR_X9_RD_X9_split
+select -assert-count 1 t:TDP36K_BRAM_WR_X18_RD_X18_split
\ No newline at end of file
diff --git a/ql-qlf-plugin/tests/qlf_k6n10f/bram18k_sdp/bram18k_sdp.v b/ql-qlf-plugin/tests/qlf_k6n10f/bram18k_sdp/bram18k_sdp.v
new file mode 100644
index 0000000..e014d7f
--- /dev/null
+++ b/ql-qlf-plugin/tests/qlf_k6n10f/bram18k_sdp/bram18k_sdp.v
@@ -0,0 +1,260 @@
+module spram_18x1024_2x (   
+    WEN0_i,
+    REN0_i,
+    clock0,
+    WR_ADDR0_i,
+    RD_ADDR0_i,
+    WDATA0_i,
+    RDATA0_o,
+    
+    WEN1_i,
+    REN1_i,
+    clock1,
+    WR_ADDR1_i,
+    RD_ADDR1_i,
+    WDATA1_i,
+    RDATA1_o
+);
+
+parameter WR_ADDR_WIDTH0 = 10;
+parameter RD_ADDR_WIDTH0 = 10;
+parameter WR_DATA_WIDTH0 = 18;
+parameter RD_DATA_WIDTH0 = 18;
+parameter BE_WIDTH0 = 2;
+
+parameter WR_ADDR_WIDTH1 = 10;
+parameter RD_ADDR_WIDTH1 = 10;
+parameter WR_DATA_WIDTH1 = 18;
+parameter RD_DATA_WIDTH1 = 18;
+parameter BE_WIDTH1 = 2;
+
+input wire WEN0_i;
+input wire REN0_i;
+input wire clock0;
+input wire [WR_ADDR_WIDTH0-1 :0] WR_ADDR0_i;
+input wire [RD_ADDR_WIDTH0-1 :0] RD_ADDR0_i;
+input wire [WR_DATA_WIDTH0-1 :0] WDATA0_i;
+output wire [RD_DATA_WIDTH0-1 :0] RDATA0_o;
+
+input wire WEN1_i;
+input wire REN1_i;
+input wire clock1;
+input wire [WR_ADDR_WIDTH0-1 :0] WR_ADDR1_i;
+input wire [RD_ADDR_WIDTH0-1 :0] RD_ADDR1_i;
+input wire [WR_DATA_WIDTH0-1 :0] WDATA1_i;
+output wire [RD_DATA_WIDTH0-1 :0] RDATA1_o;
+
+
+RAM_18K_BLK #(
+              .WR_ADDR_WIDTH(WR_ADDR_WIDTH0),
+              .RD_ADDR_WIDTH(RD_ADDR_WIDTH0),
+              .WR_DATA_WIDTH(WR_DATA_WIDTH0),
+              .RD_DATA_WIDTH(RD_DATA_WIDTH0),
+              .BE_WIDTH(BE_WIDTH0)
+              ) spram_x18_inst1 (
+              
+              .WEN_i(WEN0_i),
+              .WR_BE_i(2'b11),
+              .REN_i(REN0_i),              
+              .WR_CLK_i(clock0),
+              .RD_CLK_i(clock0),
+              .WR_ADDR_i(WR_ADDR0_i),
+              .RD_ADDR_i(RD_ADDR0_i),
+              .WDATA_i(WDATA0_i),
+              .RDATA_o(RDATA0_o)
+              );
+              
+RAM_18K_BLK #(
+              .WR_ADDR_WIDTH(WR_ADDR_WIDTH1),
+              .RD_ADDR_WIDTH(RD_ADDR_WIDTH1),
+              .WR_DATA_WIDTH(WR_DATA_WIDTH1),
+              .RD_DATA_WIDTH(RD_DATA_WIDTH1),
+              .BE_WIDTH(BE_WIDTH1)
+              ) spram_x18_inst2 (
+              
+              .WEN_i(WEN1_i),
+              .WR_BE_i(2'b11),
+              .REN_i(REN1_i),              
+              .WR_CLK_i(clock1),
+              .RD_CLK_i(clock1),
+              .WR_ADDR_i(WR_ADDR1_i),
+              .RD_ADDR_i(RD_ADDR1_i),
+              .WDATA_i(WDATA1_i),
+              .RDATA_o(RDATA1_o)
+              );
+              
+endmodule    
+
+module spram_9x2048_x2 (
+    WEN0_i,
+    REN0_i,
+    clock0,
+    WR_ADDR0_i,
+    RD_ADDR0_i,
+    WDATA0_i,
+    RDATA0_o,
+    
+    WEN1_i,
+    REN1_i,
+    clock1,
+    WR_ADDR1_i,
+    RD_ADDR1_i,
+    WDATA1_i,
+    RDATA1_o
+);
+
+parameter WR_ADDR_WIDTH0 = 11;
+parameter RD_ADDR_WIDTH0 = 11;
+parameter WR_DATA_WIDTH0 = 9;
+parameter RD_DATA_WIDTH0 = 9;
+parameter BE_WIDTH0 = 1;
+
+parameter WR_ADDR_WIDTH1 = 11;
+parameter RD_ADDR_WIDTH1 = 11;
+parameter WR_DATA_WIDTH1 = 9;
+parameter RD_DATA_WIDTH1 = 9;
+parameter BE_WIDTH1 = 1;
+
+input wire WEN0_i;
+input wire REN0_i;
+input wire clock0;
+input wire [WR_ADDR_WIDTH0-1 :0] WR_ADDR0_i;
+input wire [RD_ADDR_WIDTH0-1 :0] RD_ADDR0_i;
+input wire [WR_DATA_WIDTH0-1 :0] WDATA0_i;
+output wire [RD_DATA_WIDTH0-1 :0] RDATA0_o;
+
+input wire WEN1_i;
+input wire REN1_i;
+input wire clock1;
+input wire [WR_ADDR_WIDTH1-1 :0] WR_ADDR1_i;
+input wire [RD_ADDR_WIDTH1-1 :0] RD_ADDR1_i;
+input wire [WR_DATA_WIDTH1-1 :0] WDATA1_i;
+output wire [RD_DATA_WIDTH1-1 :0] RDATA1_o;
+
+
+RAM_18K_BLK #(
+              .WR_ADDR_WIDTH(WR_ADDR_WIDTH0),
+              .RD_ADDR_WIDTH(RD_ADDR_WIDTH0),
+              .WR_DATA_WIDTH(WR_DATA_WIDTH0),
+              .RD_DATA_WIDTH(RD_DATA_WIDTH0),
+              .BE_WIDTH(BE_WIDTH0)
+              ) spram_x18_inst1 (
+              
+              .WEN_i(WEN0_i),
+              .WR_BE_i(2'b11),
+              .REN_i(REN0_i),              
+              .WR_CLK_i(clock0),
+              .RD_CLK_i(clock0),
+              .WR_ADDR_i(WR_ADDR0_i),
+              .RD_ADDR_i(RD_ADDR0_i),
+              .WDATA_i(WDATA0_i),
+              .RDATA_o(RDATA0_o)
+              );
+              
+RAM_18K_BLK #(
+              .WR_ADDR_WIDTH(WR_ADDR_WIDTH1),
+              .RD_ADDR_WIDTH(RD_ADDR_WIDTH1),
+              .WR_DATA_WIDTH(WR_DATA_WIDTH1),
+              .RD_DATA_WIDTH(RD_DATA_WIDTH1),
+              .BE_WIDTH(BE_WIDTH1)
+              ) spram_x18_inst2 (
+              
+              .WEN_i(WEN1_i),
+              .WR_BE_i(2'b11),
+              .REN_i(REN1_i),              
+              .WR_CLK_i(clock1),
+              .RD_CLK_i(clock1),
+              .WR_ADDR_i(WR_ADDR1_i),
+              .RD_ADDR_i(RD_ADDR1_i),
+              .WDATA_i(WDATA1_i),
+              .RDATA_o(RDATA1_o)
+              );
+              
+endmodule    
+
+module spram_9x2048_18x1024 (
+    WEN0_i,
+    REN0_i,
+    clock0,
+    WR_ADDR0_i,
+    RD_ADDR0_i,
+    WDATA0_i,
+    RDATA0_o,
+    
+    WEN1_i,
+    REN1_i,
+    clock1,
+    WR_ADDR1_i,
+    RD_ADDR1_i,
+    WDATA1_i,
+    RDATA1_o
+);
+
+parameter WR_ADDR_WIDTH0 = 11;
+parameter RD_ADDR_WIDTH0 = 11;
+parameter WR_DATA_WIDTH0 = 9;
+parameter RD_DATA_WIDTH0 = 9;
+parameter BE_WIDTH0 = 1;
+
+parameter WR_ADDR_WIDTH1 = 10;
+parameter RD_ADDR_WIDTH1 = 10;
+parameter WR_DATA_WIDTH1 = 18;
+parameter RD_DATA_WIDTH1 = 18;
+parameter BE_WIDTH1 = 2;
+
+input wire WEN0_i;
+input wire REN0_i;
+input wire clock0;
+input wire [WR_ADDR_WIDTH0-1 :0] WR_ADDR0_i;
+input wire [RD_ADDR_WIDTH0-1 :0] RD_ADDR0_i;
+input wire [WR_DATA_WIDTH0-1 :0] WDATA0_i;
+output wire [RD_DATA_WIDTH0-1 :0] RDATA0_o;
+
+input wire WEN1_i;
+input wire REN1_i;
+input wire clock1;
+input wire [WR_ADDR_WIDTH1-1 :0] WR_ADDR1_i;
+input wire [RD_ADDR_WIDTH1-1 :0] RD_ADDR1_i;
+input wire [WR_DATA_WIDTH1-1 :0] WDATA1_i;
+output wire [RD_DATA_WIDTH1-1 :0] RDATA1_o;
+
+
+RAM_18K_BLK #(
+              .WR_ADDR_WIDTH(WR_ADDR_WIDTH0),
+              .RD_ADDR_WIDTH(RD_ADDR_WIDTH0),
+              .WR_DATA_WIDTH(WR_DATA_WIDTH0),
+              .RD_DATA_WIDTH(RD_DATA_WIDTH0),
+              .BE_WIDTH(BE_WIDTH0)
+              ) spram_x18_inst1 (
+              
+              .WEN_i(WEN0_i),
+              .WR_BE_i(1'b1),
+              .REN_i(REN0_i),              
+              .WR_CLK_i(clock0),
+              .RD_CLK_i(clock0),
+              .WR_ADDR_i(WR_ADDR0_i),
+              .RD_ADDR_i(RD_ADDR0_i),
+              .WDATA_i(WDATA0_i),
+              .RDATA_o(RDATA0_o)
+              );
+              
+RAM_18K_BLK #(
+              .WR_ADDR_WIDTH(WR_ADDR_WIDTH1),
+              .RD_ADDR_WIDTH(RD_ADDR_WIDTH1),
+              .WR_DATA_WIDTH(WR_DATA_WIDTH1),
+              .RD_DATA_WIDTH(RD_DATA_WIDTH1),
+              .BE_WIDTH(BE_WIDTH1)
+              ) spram_x18_inst2 (
+              
+              .WEN_i(WEN1_i),
+              .WR_BE_i(2'b11),
+              .REN_i(REN1_i),              
+              .WR_CLK_i(clock1),
+              .RD_CLK_i(clock1),
+              .WR_ADDR_i(WR_ADDR1_i),
+              .RD_ADDR_i(RD_ADDR1_i),
+              .WDATA_i(WDATA1_i),
+              .RDATA_o(RDATA1_o)
+              );
+              
+endmodule    
\ No newline at end of file
diff --git a/ql-qlf-plugin/tests/qlf_k6n10f/bram18k_sdp/sim/Makefile b/ql-qlf-plugin/tests/qlf_k6n10f/bram18k_sdp/sim/Makefile
new file mode 100644
index 0000000..184c0a5
--- /dev/null
+++ b/ql-qlf-plugin/tests/qlf_k6n10f/bram18k_sdp/sim/Makefile
@@ -0,0 +1,41 @@
+# Copyright (C) 2019-2022 The SymbiFlow Authors
+#
+# Use of this source code is governed by a ISC-style
+# license that can be found in the LICENSE file or at
+# https://opensource.org/licenses/ISC
+#
+# SPDX-License-Identifier: ISC
+
+TESTBENCH = bram18k_sdp_tb.v
+POST_SYNTH = spram_18x1024_2x_post_synth spram_9x2048_x2_post_synth spram_9x2048_18x1024_post_synth
+ADDR_WIDTH0 = 10 11 11
+DATA_WIDTH0 = 18 9 9
+ADDR_WIDTH1 = 10 11 10
+DATA_WIDTH1 = 18 9 18
+TOP = spram_18x1024_2x spram_9x2048_x2 spram_9x2048_18x1024
+ADDR0_DEFINES = $(foreach awidth0, $(ADDR_WIDTH0),-DADDR_WIDTH0="$(awidth0)")
+ADDR1_DEFINES = $(foreach awidth1, $(ADDR_WIDTH1),-DADDR_WIDTH1="$(awidth1)")
+DATA0_DEFINES = $(foreach dwidth0, $(DATA_WIDTH0),-DDATA_WIDTH0="$(dwidth0)")
+DATA1_DEFINES = $(foreach dwidth1, $(DATA_WIDTH1),-DDATA_WIDTH1="$(dwidth1)")
+TOP_DEFINES = $(foreach top, $(TOP),-DTOP="$(top)")
+VCD_DEFINES = $(foreach vcd, $(POST_SYNTH),-DVCD="$(vcd).vcd")
+
+SIM_LIBS = $(shell find ../../../../qlf_k6n10f -name "*.v" -not -name "*_map.v")
+
+define simulate_post_synth
+	@iverilog  -vvvv -g2005 $(word $(1),$(ADDR0_DEFINES)) $(word $(1),$(ADDR1_DEFINES)) $(word $(1),$(DATA0_DEFINES)) $(word $(1),$(DATA1_DEFINES)) $(word $(1),$(TOP_DEFINES)) $(word $(1),$(VCD_DEFINES)) -o $(word $(1),$(POST_SYNTH)).vvp $(word $(1),$(POST_SYNTH)).v $(SIM_LIBS) $(TESTBENCH) > $(word $(1),$(POST_SYNTH)).vvp.log 2>&1
+	@vvp -vvvv $(word $(1),$(POST_SYNTH)).vvp > $(word $(1),$(POST_SYNTH)).vcd.log 2>&1
+endef
+
+define clean_post_synth_sim
+	@rm -rf  $(word $(1),$(POST_SYNTH)).vcd $(word $(1),$(POST_SYNTH)).vvp $(word $(1),$(POST_SYNTH)).vvp.log $(word $(1),$(POST_SYNTH)).vcd.log
+endef
+
+#FIXME: $(call simulate_post_synth,3)
+sim:
+	$(call simulate_post_synth,1)
+	$(call clean_post_synth_sim,1)
+	$(call simulate_post_synth,2)
+	$(call clean_post_synth_sim,2)
+	$(call simulate_post_synth,3)
+	$(call clean_post_synth_sim,3)
\ No newline at end of file
diff --git a/ql-qlf-plugin/tests/qlf_k6n10f/bram18k_sdp/sim/bram18k_sdp_tb.v b/ql-qlf-plugin/tests/qlf_k6n10f/bram18k_sdp/sim/bram18k_sdp_tb.v
new file mode 100644
index 0000000..aa8616a
--- /dev/null
+++ b/ql-qlf-plugin/tests/qlf_k6n10f/bram18k_sdp/sim/bram18k_sdp_tb.v
@@ -0,0 +1,222 @@
+// Copyright (C) 2019-2022 The SymbiFlow Authors
+//
+// Use of this source code is governed by a ISC-style
+// license that can be found in the LICENSE file or at
+// https://opensource.org/licenses/ISC
+//
+// SPDX-License-Identifier: ISC
+
+`timescale 1ns/1ps
+
+`define STRINGIFY(x) `"x`"
+
+module TB;
+	localparam PERIOD = 50;
+	localparam ADDR_INCR = 1;
+
+	reg clk_0;
+	reg rce_0;
+	reg [`ADDR_WIDTH0-1:0] ra_0;
+	wire [`DATA_WIDTH0-1:0] rq_0;
+	reg wce_0;
+	reg [`ADDR_WIDTH0-1:0] wa_0;
+	reg [`DATA_WIDTH0-1:0] wd_0;
+
+	reg clk_1;
+	reg rce_1;
+	reg [`ADDR_WIDTH1-1:0] ra_1;
+	wire [`DATA_WIDTH1-1:0] rq_1;
+	reg wce_1;
+	reg [`ADDR_WIDTH1-1:0] wa_1;
+	reg [`DATA_WIDTH1-1:0] wd_1;
+
+
+	initial clk_0 = 0;
+	initial clk_1 = 0;
+	initial ra_0 = 0;
+	initial ra_1 = 0;
+	initial rce_0 = 0;
+	initial rce_1 = 0;
+	initial forever #(PERIOD / 2.0) clk_0 = ~clk_0;
+	initial begin
+		#(PERIOD / 4.0);
+		forever #(PERIOD / 2.0) clk_1 = ~clk_1;
+	end
+	initial begin
+		$dumpfile(`STRINGIFY(`VCD));
+		$dumpvars;
+	end
+
+	integer a;
+	integer b;
+
+	reg done_0;
+	reg done_1;
+	initial done_0 = 1'b0;
+	initial done_1 = 1'b0;
+	wire done_sim = done_0 & done_1;
+
+	reg [`DATA_WIDTH0-1:0] expected_0;
+	reg [`DATA_WIDTH1-1:0] expected_1;
+
+	reg read_test_0;
+	reg read_test_1;
+	initial read_test_0 = 0;
+	initial read_test_1 = 0;
+
+	always @(posedge clk_0) begin
+		expected_0 <= (a | (a << 20) | 20'h55000) & {`DATA_WIDTH0{1'b1}};
+	end
+	always @(posedge clk_1) begin
+		expected_1 <= ((b+1) | ((b+1) << 20) | 20'h55000) & {`DATA_WIDTH1{1'b1}};
+	end
+
+	wire error_0 = ((a != 0) && read_test_0) ? (rq_0 !== expected_0) : 0;
+	wire error_1 = ((b != (1<<`ADDR_WIDTH1) / 2) && read_test_1) ? (rq_1 !== expected_1) : 0;
+
+	integer error_0_cnt = 0;
+	integer error_1_cnt = 0;
+
+	always @ (posedge clk_0)
+	begin
+		if (error_0)
+			error_0_cnt <= error_0_cnt + 1'b1;
+	end
+	always @ (posedge clk_1)
+	begin
+		if (error_1)
+			error_1_cnt <= error_1_cnt + 1'b1;
+	end
+
+	// PART 0
+	initial #(1) begin
+		// Write data
+		for (a = 0; a < (1<<`ADDR_WIDTH0) / 2; a = a + ADDR_INCR) begin
+			@(negedge clk_0) begin
+				wa_0 = a;
+				wd_0 = a | (a << 20) | 20'h55000;
+				wce_0 = 1;
+			end
+			@(posedge clk_0) begin
+				#(PERIOD/10) wce_0 = 0;
+			end
+		end
+		// Read data
+		read_test_0 = 1;
+		for (a = 0; a < (1<<`ADDR_WIDTH0) / 2; a = a + ADDR_INCR) begin
+			@(negedge clk_0) begin
+				ra_0 = a;
+				rce_0 = 1;
+			end
+			@(posedge clk_0) begin
+				#(PERIOD/10) rce_0 = 0;
+				if ( rq_0 !== expected_0) begin
+					$display("%d: PORT 0: FAIL: mismatch act=%x exp=%x at %x", $time, rq_0, expected_0, a);
+				end else begin
+					$display("%d: PORT 0: OK: act=%x exp=%x at %x", $time, rq_0, expected_0, a);
+				end
+			end
+		end
+		done_0 = 1'b1;
+    a = 0;
+	end
+
+	// PART 1
+	initial #(1) begin
+		// Write data
+		for (b = (1<<`ADDR_WIDTH1) / 2; b < (1<<`ADDR_WIDTH1); b = b + ADDR_INCR) begin
+			@(negedge clk_1) begin
+				wa_1 = b;
+				wd_1 = (b+1) | ((b+1) << 20) | 20'h55000;
+				wce_1 = 1;
+			end
+			@(posedge clk_1) begin
+				#(PERIOD/10) wce_1 = 0;
+			end
+		end
+		// Read data
+		read_test_1 = 1;
+		for (b = (1<<`ADDR_WIDTH1) / 2; b < (1<<`ADDR_WIDTH1); b = b + ADDR_INCR) begin
+			@(negedge clk_1) begin
+				ra_1 = b;
+				rce_1 = 1;
+			end
+			@(posedge clk_1) begin
+				#(PERIOD/10) rce_1 = 0;
+				if ( rq_1 !== expected_1) begin
+					$display("%d: PORT 1: FAIL: mismatch act=%x exp=%x at %x", $time, rq_1, expected_1, b);
+				end else begin
+					$display("%d: PORT 1: OK: act=%x exp=%x at %x", $time, rq_1, expected_1, b);
+				end
+			end
+		end
+		done_1 = 1'b1;
+    b = (1<<`ADDR_WIDTH1) / 2;
+	end
+
+	// Scan for simulation finish
+	always @(posedge clk_0, posedge clk_1) begin
+		if (done_sim)
+			$finish_and_return( (error_0_cnt == 0 & error_1_cnt == 0) ? 0 : -1 );
+	end
+
+	case (`STRINGIFY(`TOP))
+		"spram_18x1024_2x": begin
+			spram_18x1024_2x #() bram (
+				.clock0(clk_0),
+				.REN0_i(rce_0),
+				.RD_ADDR0_i(ra_0),
+				.RDATA0_o(rq_0),
+				.WEN0_i(wce_0),
+				.WR_ADDR0_i(wa_0),
+				.WDATA0_i(wd_0),
+
+				.clock1(clk_1),
+				.REN1_i(rce_1),
+				.RD_ADDR1_i(ra_1),
+				.RDATA1_o(rq_1),
+				.WEN1_i(wce_1),
+				.WR_ADDR1_i(wa_1),
+				.WDATA1_i(wd_1)
+			);
+		end
+		"spram_9x2048_x2": begin
+			spram_9x2048_x2 #() bram (
+				.clock0(clk_0),
+				.REN0_i(rce_0),
+				.RD_ADDR0_i(ra_0),
+				.RDATA0_o(rq_0),
+				.WEN0_i(wce_0),
+				.WR_ADDR0_i(wa_0),
+				.WDATA0_i(wd_0),
+
+				.clock1(clk_1),
+				.REN1_i(rce_1),
+				.RD_ADDR1_i(ra_1),
+				.RDATA1_o(rq_1),
+				.WEN1_i(wce_1),
+				.WR_ADDR1_i(wa_1),
+				.WDATA1_i(wd_1)
+			);
+		end
+		"spram_9x2048_18x1024": begin
+			spram_9x2048_18x1024 #() bram (
+				.clock0(clk_0),
+				.REN0_i(rce_0),
+				.RD_ADDR0_i(ra_0),
+				.RDATA0_o(rq_0),
+				.WEN0_i(wce_0),
+				.WR_ADDR0_i(wa_0),
+				.WDATA0_i(wd_0),
+
+				.clock1(clk_1),
+				.REN1_i(rce_1),
+				.RD_ADDR1_i(ra_1),
+				.RDATA1_o(rq_1),
+				.WEN1_i(wce_1),
+				.WR_ADDR1_i(wa_1),
+				.WDATA1_i(wd_1)
+			);
+		end
+	endcase
+endmodule
diff --git a/ql-qlf-plugin/tests/qlf_k6n10f/bram18k_sfifo/bram18k_sfifo.tcl b/ql-qlf-plugin/tests/qlf_k6n10f/bram18k_sfifo/bram18k_sfifo.tcl
new file mode 100644
index 0000000..a5ff276
--- /dev/null
+++ b/ql-qlf-plugin/tests/qlf_k6n10f/bram18k_sfifo/bram18k_sfifo.tcl
@@ -0,0 +1,49 @@
+yosys -import
+
+if { [info procs ql-qlf-k6n10f] == {} } { plugin -i ql-qlf }
+yosys -import  ;
+
+read_verilog $::env(DESIGN_TOP).v
+design -save bram18k_sfifo
+
+select f1024x18_1024x18
+select *
+synth_quicklogic -family qlf_k6n10f -top f1024x18_1024x18 -bram_types
+opt_expr -undriven
+opt_clean
+stat
+write_verilog sim/f1024x18_1024x18_post_synth.v
+select -assert-count 1 t:TDP36K_FIFO_SYNC_WR_X18_RD_X18_split
+
+select -clear
+design -load bram18k_sfifo
+select f1024x16_1024x16
+select *
+synth_quicklogic -family qlf_k6n10f -top f1024x16_1024x16 -bram_types
+opt_expr -undriven
+opt_clean
+stat
+write_verilog sim/f1024x16_1024x16_post_synth.v
+select -assert-count 1 t:TDP36K_FIFO_SYNC_WR_X18_RD_X18_split
+
+select -clear
+design -load bram18k_sfifo
+select f2048x9_2048x9
+select *
+synth_quicklogic -family qlf_k6n10f -top f2048x9_2048x9 -bram_types
+opt_expr -undriven
+opt_clean
+stat
+write_verilog sim/f2048x9_2048x9_post_synth.v
+select -assert-count 1 t:TDP36K_FIFO_SYNC_WR_X9_RD_X9_split
+
+select -clear
+design -load bram18k_sfifo
+select f2048x8_2048x8
+select *
+synth_quicklogic -family qlf_k6n10f -top f2048x8_2048x8 -bram_types
+opt_expr -undriven
+opt_clean
+stat
+write_verilog sim/f2048x8_2048x8_post_synth.v
+select -assert-count 1 t:TDP36K_FIFO_SYNC_WR_X9_RD_X9_split
diff --git a/ql-qlf-plugin/tests/qlf_k6n10f/bram18k_sfifo/bram18k_sfifo.v b/ql-qlf-plugin/tests/qlf_k6n10f/bram18k_sfifo/bram18k_sfifo.v
new file mode 100644
index 0000000..7930804
--- /dev/null
+++ b/ql-qlf-plugin/tests/qlf_k6n10f/bram18k_sfifo/bram18k_sfifo.v
@@ -0,0 +1,163 @@
+module f1024x18_1024x18 (DIN,PUSH,POP,clock0,Async_Flush,Almost_Full,Almost_Empty,Full,Empty,Full_Watermark,Empty_Watermark,Overrun_Error,Underrun_Error,DOUT);
+
+parameter WR_DATA_WIDTH = 18;
+parameter RD_DATA_WIDTH = 18;
+parameter UPAE_DBITS = 11'd10;
+parameter UPAF_DBITS = 11'd10;
+
+input clock0;
+input PUSH,POP;
+input [WR_DATA_WIDTH-1:0] DIN;
+input Async_Flush;
+output [RD_DATA_WIDTH-1:0] DOUT;
+output Almost_Full,Almost_Empty;
+output Full, Empty;
+output Full_Watermark, Empty_Watermark;
+output Overrun_Error, Underrun_Error;
+
+SFIFO_18K_BLK  # (.WR_DATA_WIDTH(WR_DATA_WIDTH),.RD_DATA_WIDTH(RD_DATA_WIDTH),.UPAE_DBITS(UPAE_DBITS),.UPAF_DBITS(UPAF_DBITS)
+        				 ) 
+  FIFO_INST    (
+                .DIN(DIN),
+                .PUSH(PUSH),
+                .POP(POP),
+                .CLK(clock0),
+                .Async_Flush(Async_Flush),
+                
+                .Overrun_Error(Overrun_Error),
+                .Full_Watermark(Full_Watermark),
+                .Almost_Full(Almost_Full),
+                .Full(Full),
+                
+                .Underrun_Error(Underrun_Error),
+                .Empty_Watermark(Empty_Watermark),
+                .Almost_Empty(Almost_Empty),
+                .Empty(Empty),
+
+                .DOUT(DOUT)
+         				);
+
+endmodule
+
+module f1024x16_1024x16 (DIN,PUSH,POP,clock0,Async_Flush,Almost_Full,Almost_Empty,Full,Empty,Full_Watermark,Empty_Watermark,Overrun_Error,Underrun_Error,DOUT);
+
+parameter WR_DATA_WIDTH = 16;
+parameter RD_DATA_WIDTH = 16;
+parameter UPAE_DBITS = 11'd10;
+parameter UPAF_DBITS = 11'd10;
+
+input clock0;
+input PUSH,POP;
+input [WR_DATA_WIDTH-1:0] DIN;
+input Async_Flush;
+output [RD_DATA_WIDTH-1:0] DOUT;
+output Almost_Full,Almost_Empty;
+output Full, Empty;
+output Full_Watermark, Empty_Watermark;
+output Overrun_Error, Underrun_Error;
+
+SFIFO_18K_BLK  # (.WR_DATA_WIDTH(WR_DATA_WIDTH),.RD_DATA_WIDTH(RD_DATA_WIDTH),.UPAE_DBITS(UPAE_DBITS),.UPAF_DBITS(UPAF_DBITS)
+        				 ) 
+  FIFO_INST    (
+                .DIN(DIN),
+                .PUSH(PUSH),
+                .POP(POP),
+                .CLK(clock0),
+                .Async_Flush(Async_Flush),
+                
+                .Overrun_Error(Overrun_Error),
+                .Full_Watermark(Full_Watermark),
+                .Almost_Full(Almost_Full),
+                .Full(Full),
+                
+                .Underrun_Error(Underrun_Error),
+                .Empty_Watermark(Empty_Watermark),
+                .Almost_Empty(Almost_Empty),
+                .Empty(Empty),
+
+                .DOUT(DOUT)
+         				);
+
+endmodule
+
+module f2048x9_2048x9 (DIN,PUSH,POP,clock0,Async_Flush,Almost_Full,Almost_Empty,Full,Empty,Full_Watermark,Empty_Watermark,Overrun_Error,Underrun_Error,DOUT);
+
+parameter WR_DATA_WIDTH = 9;
+parameter RD_DATA_WIDTH = 9;
+parameter UPAE_DBITS = 11'd10;
+parameter UPAF_DBITS = 11'd10;
+
+input clock0;
+input PUSH,POP;
+input [WR_DATA_WIDTH-1:0] DIN;
+input Async_Flush;
+output [RD_DATA_WIDTH-1:0] DOUT;
+output Almost_Full,Almost_Empty;
+output Full, Empty;
+output Full_Watermark, Empty_Watermark;
+output Overrun_Error, Underrun_Error;
+
+SFIFO_18K_BLK  # (.WR_DATA_WIDTH(WR_DATA_WIDTH),.RD_DATA_WIDTH(RD_DATA_WIDTH),.UPAE_DBITS(UPAE_DBITS),.UPAF_DBITS(UPAF_DBITS)
+        				 ) 
+  FIFO_INST    (
+                .DIN(DIN),
+                .PUSH(PUSH),
+                .POP(POP),
+                .CLK(clock0),
+                .Async_Flush(Async_Flush),
+                
+                .Overrun_Error(Overrun_Error),
+                .Full_Watermark(Full_Watermark),
+                .Almost_Full(Almost_Full),
+                .Full(Full),
+                
+                .Underrun_Error(Underrun_Error),
+                .Empty_Watermark(Empty_Watermark),
+                .Almost_Empty(Almost_Empty),
+                .Empty(Empty),
+
+                .DOUT(DOUT)
+         				);
+
+endmodule
+
+module f2048x8_2048x8 (DIN,PUSH,POP,clock0,Async_Flush,Almost_Full,Almost_Empty,Full,Empty,Full_Watermark,Empty_Watermark,Overrun_Error,Underrun_Error,DOUT);
+
+parameter WR_DATA_WIDTH = 8;
+parameter RD_DATA_WIDTH = 8;
+parameter UPAE_DBITS = 11'd10;
+parameter UPAF_DBITS = 11'd10;
+
+input clock0;
+input PUSH,POP;
+input [WR_DATA_WIDTH-1:0] DIN;
+input Async_Flush;
+output [RD_DATA_WIDTH-1:0] DOUT;
+output Almost_Full,Almost_Empty;
+output Full, Empty;
+output Full_Watermark, Empty_Watermark;
+output Overrun_Error, Underrun_Error;
+
+SFIFO_18K_BLK  # (.WR_DATA_WIDTH(WR_DATA_WIDTH),.RD_DATA_WIDTH(RD_DATA_WIDTH),.UPAE_DBITS(UPAE_DBITS),.UPAF_DBITS(UPAF_DBITS)
+        				 ) 
+  FIFO_INST    (
+                .DIN(DIN),
+                .PUSH(PUSH),
+                .POP(POP),
+                .CLK(clock0),
+                .Async_Flush(Async_Flush),
+                
+                .Overrun_Error(Overrun_Error),
+                .Full_Watermark(Full_Watermark),
+                .Almost_Full(Almost_Full),
+                .Full(Full),
+                
+                .Underrun_Error(Underrun_Error),
+                .Empty_Watermark(Empty_Watermark),
+                .Almost_Empty(Almost_Empty),
+                .Empty(Empty),
+
+                .DOUT(DOUT)
+         				);
+
+endmodule
\ No newline at end of file
diff --git a/ql-qlf-plugin/tests/qlf_k6n10f/bram18k_sfifo/sim/Makefile b/ql-qlf-plugin/tests/qlf_k6n10f/bram18k_sfifo/sim/Makefile
new file mode 100644
index 0000000..2a46d29
--- /dev/null
+++ b/ql-qlf-plugin/tests/qlf_k6n10f/bram18k_sfifo/sim/Makefile
@@ -0,0 +1,51 @@
+# Copyright 2020-2022 F4PGA Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-License-Identifier: Apache-2.0
+
+TESTBENCH = bram18k_sfifo_tb.v
+POST_SYNTH = f1024x18_1024x18_post_synth f1024x16_1024x16_post_synth f2048x9_2048x9_post_synth f2048x8_2048x8_post_synth
+ADDR_WIDTH0 = 10 10 11 11
+DATA_WIDTH0 = 18 16 9 8
+ADDR_WIDTH1 = 10 10 11 11
+DATA_WIDTH1 = 18 16 9 8
+TOP = f1024x18_1024x18 f1024x16_1024x16 f2048x9_2048x9 f2048x8_2048x8
+ADDR0_DEFINES = $(foreach awidth0, $(ADDR_WIDTH0),-DADDR_WIDTH0="$(awidth0)")
+ADDR1_DEFINES = $(foreach awidth1, $(ADDR_WIDTH1),-DADDR_WIDTH1="$(awidth1)")
+DATA0_DEFINES = $(foreach dwidth0, $(DATA_WIDTH0),-DDATA_WIDTH0="$(dwidth0)")
+DATA1_DEFINES = $(foreach dwidth1, $(DATA_WIDTH1),-DDATA_WIDTH1="$(dwidth1)")
+TOP_DEFINES = $(foreach top, $(TOP),-DTOP="$(top)")
+VCD_DEFINES = $(foreach vcd, $(POST_SYNTH),-DVCD="$(vcd).vcd")
+
+SIM_LIBS = $(shell find ../../../../qlf_k6n10f -name "*.v" -not -name "*_map.v")
+
+define simulate_post_synth
+	@iverilog  -vvvv -g2005 $(word $(1),$(ADDR0_DEFINES)) $(word $(1),$(ADDR1_DEFINES)) $(word $(1),$(DATA0_DEFINES)) $(word $(1),$(DATA1_DEFINES)) $(word $(1),$(TOP_DEFINES)) $(word $(1),$(VCD_DEFINES)) -o $(word $(1),$(POST_SYNTH)).vvp $(word $(1),$(POST_SYNTH)).v $(SIM_LIBS) $(TESTBENCH) > $(word $(1),$(POST_SYNTH)).vvp.log 2>&1
+	@vvp -vvvv $(word $(1),$(POST_SYNTH)).vvp > $(word $(1),$(POST_SYNTH)).vcd.log 2>&1
+endef
+
+define clean_post_synth_sim
+	@rm -rf  $(word $(1),$(POST_SYNTH)).vcd $(word $(1),$(POST_SYNTH)).vvp $(word $(1),$(POST_SYNTH)).vvp.log $(word $(1),$(POST_SYNTH)).vcd.log
+endef
+
+# FIXME: $(call simulate_post_synth,5)
+sim:
+	$(call simulate_post_synth,1)
+	$(call clean_post_synth_sim,1)
+	$(call simulate_post_synth,2)
+	$(call clean_post_synth_sim,2)
+	$(call simulate_post_synth,3)
+	$(call clean_post_synth_sim,3)
+	$(call simulate_post_synth,4)
+	$(call clean_post_synth_sim,4)
\ No newline at end of file
diff --git a/ql-qlf-plugin/tests/qlf_k6n10f/bram18k_sfifo/sim/bram18k_sfifo_tb.v b/ql-qlf-plugin/tests/qlf_k6n10f/bram18k_sfifo/sim/bram18k_sfifo_tb.v
new file mode 100644
index 0000000..f5c56cf
--- /dev/null
+++ b/ql-qlf-plugin/tests/qlf_k6n10f/bram18k_sfifo/sim/bram18k_sfifo_tb.v
@@ -0,0 +1,188 @@
+// Copyright 2020-2022 F4PGA Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: Apache-2.0
+
+`timescale 1ns/1ps
+
+`define STRINGIFY(x) `"x`"
+
+module TB;
+	localparam PERIOD = 30;
+	localparam ADDR_INCR = 1;
+
+	reg clk;
+  reg flush;
+	reg pop;
+	wire [`DATA_WIDTH1-1:0] dout;
+	reg push;
+	reg [`DATA_WIDTH0-1:0] din;
+  wire almost_full,almost_empty;
+  wire full, empty;
+  wire full_watermark, empty_watermark;
+  wire overrun_error, underrun_error;
+
+  initial 
+  begin
+    clk = 0;
+    pop = 0;
+    push = 0;
+    flush = 1;
+    din = 0;
+    #40
+    flush = 0;
+  end
+  
+	initial forever #(PERIOD / 3.0) clk = ~clk;
+  
+	initial begin
+		$dumpfile(`STRINGIFY(`VCD));
+		$dumpvars;
+	end
+
+	integer a;
+
+	reg done;
+	initial done = 1'b0;
+  
+	reg read_test;
+	initial read_test = 0;
+
+	reg [`DATA_WIDTH1-1:0] expected;
+  initial expected = 0;
+
+	always @(posedge clk) begin
+		expected <= (a | (a << 20) | 20'h55000) & {`DATA_WIDTH1{1'b1}};
+	end
+
+	wire error = ((a != 0) && read_test) ? dout !== expected : 0;
+
+	integer error_cnt = 0;
+	always @ (posedge clk)
+	begin
+		if (error)
+			error_cnt <= error_cnt + 1'b1; 
+	end
+
+	initial #(50) begin
+    @(posedge clk)
+		// Write data
+		for (a = 0; a < (1<<`ADDR_WIDTH0); a = a + ADDR_INCR) begin
+			@(negedge clk) begin
+				din = a | (a << 20) | 20'h55000;
+				push = 1;
+			end
+			@(posedge clk) begin
+				#(PERIOD/10) push = 0;
+			end
+		end
+		// Read data
+		read_test = 1;
+		for (a = 0; a < (1<<`ADDR_WIDTH1); a = a + ADDR_INCR) begin
+			@(posedge clk) begin
+				#(PERIOD/10) pop = 0;
+				if ( dout !== expected) begin
+					$display("%d: FAIL: mismatch act=%x exp=%x at %x", $time, dout, expected, a);
+				end else begin
+					$display("%d: OK: act=%x exp=%x at %x", $time, dout, expected, a);
+				end
+			end
+			@(negedge clk) begin
+				pop = 1;
+			end
+		end
+		done = 1'b1;
+	end
+
+	// Scan for simulation finish
+	always @(posedge clk) begin
+		if (done)
+			$finish_and_return( (error_cnt == 0) ? 0 : -1 );
+	end
+
+	case (`STRINGIFY(`TOP))
+		"f1024x18_1024x18": begin
+			f1024x18_1024x18 #() afifo (
+        .DIN(din),
+        .PUSH(push),
+        .POP(pop),
+        .clock0(clk),
+        .Async_Flush(flush),
+        .Almost_Full(almost_full),
+        .Almost_Empty(almost_empty),
+        .Full(full),
+        .Empty(empty),
+        .Full_Watermark(full_watermark),
+        .Empty_Watermark(empty_watermark),
+        .Overrun_Error(overrun_error),
+        .Underrun_Error(underrun_error),
+        .DOUT(dout)
+			);
+		end
+		"f1024x16_1024x16": begin
+			f1024x16_1024x16 #() afifo (
+        .DIN(din),
+        .PUSH(push),
+        .POP(pop),
+        .clock0(clk),
+        .Async_Flush(flush),
+        .Almost_Full(almost_full),
+        .Almost_Empty(almost_empty),
+        .Full(full),
+        .Empty(empty),
+        .Full_Watermark(full_watermark),
+        .Empty_Watermark(empty_watermark),
+        .Overrun_Error(overrun_error),
+        .Underrun_Error(underrun_error),
+        .DOUT(dout)
+			);
+		end
+		"f2048x9_2048x9": begin
+			f2048x9_2048x9 #() afifo (
+        .DIN(din),
+        .PUSH(push),
+        .POP(pop),
+        .clock0(clk),
+        .Async_Flush(flush),
+        .Almost_Full(almost_full),
+        .Almost_Empty(almost_empty),
+        .Full(full),
+        .Empty(empty),
+        .Full_Watermark(full_watermark),
+        .Empty_Watermark(empty_watermark),
+        .Overrun_Error(overrun_error),
+        .Underrun_Error(underrun_error),
+        .DOUT(dout)
+			);
+		end	
+		"f2048x8_2048x8": begin
+			f2048x8_2048x8 #() afifo (
+        .DIN(din),
+        .PUSH(push),
+        .POP(pop),
+        .clock0(clk),
+        .Async_Flush(flush),
+        .Almost_Full(almost_full),
+        .Almost_Empty(almost_empty),
+        .Full(full),
+        .Empty(empty),
+        .Full_Watermark(full_watermark),
+        .Empty_Watermark(empty_watermark),
+        .Overrun_Error(overrun_error),
+        .Underrun_Error(underrun_error),
+        .DOUT(dout)
+			);
+		end	    
+	endcase
+endmodule
diff --git a/ql-qlf-plugin/tests/qlf_k6n10f/bram18k_tdp/bram18k_tdp.tcl b/ql-qlf-plugin/tests/qlf_k6n10f/bram18k_tdp/bram18k_tdp.tcl
new file mode 100644
index 0000000..e42cd16
--- /dev/null
+++ b/ql-qlf-plugin/tests/qlf_k6n10f/bram18k_tdp/bram18k_tdp.tcl
@@ -0,0 +1,39 @@
+yosys -import
+
+if { [info procs ql-qlf-k6n10f] == {} } { plugin -i ql-qlf }
+yosys -import  ;
+
+read_verilog $::env(DESIGN_TOP).v
+design -save bram18k_tdp
+
+select dpram_18x1024_x2
+select *
+synth_quicklogic -family qlf_k6n10f -top dpram_18x1024_x2 -bram_types
+opt_expr -undriven
+opt_clean
+stat
+write_verilog sim/dpram_18x1024_x2_post_synth.v
+select -assert-count 2 t:TDP36K_BRAM_WR_X18_RD_X18_split
+
+select -clear
+design -load bram18k_tdp
+select dpram_9x2048_x2
+select *
+synth_quicklogic -family qlf_k6n10f -top dpram_9x2048_x2 -bram_types
+opt_expr -undriven
+opt_clean
+stat
+write_verilog sim/dpram_9x2048_x2_post_synth.v
+select -assert-count 2 t:TDP36K_BRAM_WR_X9_RD_X9_split
+
+select -clear
+design -load bram18k_tdp
+select dpram_18x1024_9x2048
+select *
+synth_quicklogic -family qlf_k6n10f -top dpram_18x1024_9x2048 -bram_types
+opt_expr -undriven
+opt_clean
+stat
+write_verilog sim/dpram_18x1024_9x2048_post_synth.v
+select -assert-count 1 t:TDP36K_BRAM_WR_X18_RD_X18_split
+select -assert-count 1 t:TDP36K_BRAM_WR_X9_RD_X9_split
diff --git a/ql-qlf-plugin/tests/qlf_k6n10f/bram18k_tdp/bram18k_tdp.v b/ql-qlf-plugin/tests/qlf_k6n10f/bram18k_tdp/bram18k_tdp.v
new file mode 100644
index 0000000..8fb7d00
--- /dev/null
+++ b/ql-qlf-plugin/tests/qlf_k6n10f/bram18k_tdp/bram18k_tdp.v
@@ -0,0 +1,380 @@
+module dpram_18x1024_x2 (   
+    clk_a_0,
+    WEN_a_0,
+    REN_a_0,
+    WR_ADDR_a_0,
+    RD_ADDR_a_0,
+    WDATA_a_0,
+    RDATA_a_0,
+    
+    clk_b_0,
+    WEN_b_0,
+    REN_b_0,
+    WR_ADDR_b_0,
+    RD_ADDR_b_0,
+    WDATA_b_0,
+    RDATA_b_0,
+    
+    clk_a_1,
+    WEN_a_1,
+    REN_a_1,
+    WR_ADDR_a_1,
+    RD_ADDR_a_1,
+    WDATA_a_1,
+    RDATA_a_1,
+    
+    clk_b_1,
+    WEN_b_1,
+    REN_b_1,
+    WR_ADDR_b_1,
+    RD_ADDR_b_1,
+    WDATA_b_1,
+    RDATA_b_1
+);
+
+parameter ADDR_WIDTH0 = 10;
+parameter DATA_WIDTH0 = 18;
+parameter BE1_WIDTH0 = 2;
+parameter BE2_WIDTH0 = 2;
+
+parameter ADDR_WIDTH1 = 10;
+parameter DATA_WIDTH1 = 18;
+parameter BE1_WIDTH1 = 2;
+parameter BE2_WIDTH1 = 2;
+
+input wire clk_a_0;
+input wire WEN_a_0;
+input wire REN_a_0;
+input wire [ADDR_WIDTH0-1 :0] WR_ADDR_a_0;
+input wire [ADDR_WIDTH0-1 :0] RD_ADDR_a_0;
+input wire [DATA_WIDTH0-1 :0] WDATA_a_0;
+output wire [DATA_WIDTH0-1 :0] RDATA_a_0;
+
+input wire clk_b_0;
+input wire WEN_b_0;
+input wire REN_b_0;
+input wire [ADDR_WIDTH0-1 :0] WR_ADDR_b_0;
+input wire [ADDR_WIDTH0-1 :0] RD_ADDR_b_0;
+input wire [DATA_WIDTH0-1 :0] WDATA_b_0;
+output wire [DATA_WIDTH0-1 :0] RDATA_b_0;
+
+input wire clk_a_1;
+input wire WEN_a_1;
+input wire REN_a_1;
+input wire [ADDR_WIDTH1-1 :0] WR_ADDR_a_1;
+input wire [ADDR_WIDTH1-1 :0] RD_ADDR_a_1;
+input wire [DATA_WIDTH1-1 :0] WDATA_a_1;
+output wire [DATA_WIDTH1-1 :0] RDATA_a_1;
+
+input wire clk_b_1;
+input wire WEN_b_1;
+input wire REN_b_1;
+input wire [ADDR_WIDTH1-1 :0] WR_ADDR_b_1;
+input wire [ADDR_WIDTH1-1 :0] RD_ADDR_b_1;
+input wire [DATA_WIDTH1-1 :0] WDATA_b_1;
+output wire [DATA_WIDTH1-1 :0] RDATA_b_1;
+ 
+DPRAM_18K_BLK #(
+              .ADDR_WIDTH(ADDR_WIDTH0),
+              .DATA_WIDTH(DATA_WIDTH0),
+              .BE1_WIDTH(BE1_WIDTH0),
+              .BE2_WIDTH(BE2_WIDTH0)
+              ) dpram_x18_inst0 ( 
+              
+              .CLK1_i(clk_a_0),
+              .WEN1_i(WEN_a_0),
+              .REN1_i(REN_a_0),
+              .WR1_ADDR_i(WR_ADDR_a_0),
+              .RD1_ADDR_i(RD_ADDR_a_0),
+              .WDATA1_i(WDATA_a_0),
+              .RDATA1_o(RDATA_a_0),
+              
+              .CLK2_i(clk_b_0),
+              .WEN2_i(WEN_b_0),
+              .REN2_i(REN_b_0),
+              .WR2_ADDR_i(WR_ADDR_b_0),
+              .RD2_ADDR_i(RD_ADDR_b_0),
+              .WDATA2_i(WDATA_b_0),
+              .RDATA2_o(RDATA_b_0)
+              );
+              
+ 
+DPRAM_18K_BLK #(
+              .ADDR_WIDTH(ADDR_WIDTH1),
+              .DATA_WIDTH(DATA_WIDTH1),
+              .BE1_WIDTH(BE1_WIDTH1),
+              .BE2_WIDTH(BE2_WIDTH1)
+              ) dpram_x18_inst1 ( 
+              
+              .CLK1_i(clk_a_1),
+              .WEN1_i(WEN_a_1),
+              .REN1_i(REN_a_1),
+              .WR1_ADDR_i(WR_ADDR_a_1),
+              .RD1_ADDR_i(RD_ADDR_a_1),
+              .WDATA1_i(WDATA_a_1),
+              .RDATA1_o(RDATA_a_1),
+              
+              .CLK2_i(clk_b_1),
+              .WEN2_i(WEN_b_1),
+              .REN2_i(REN_b_1),
+              .WR2_ADDR_i(WR_ADDR_b_1),
+              .RD2_ADDR_i(RD_ADDR_b_1),
+              .WDATA2_i(WDATA_b_1),
+              .RDATA2_o(RDATA_b_1)
+              );
+              
+endmodule    
+
+module dpram_9x2048_x2 (   
+    clk_a_0,
+    WEN_a_0,
+    REN_a_0,
+    WR_ADDR_a_0,
+    RD_ADDR_a_0,
+    WDATA_a_0,
+    RDATA_a_0,
+    
+    clk_b_0,
+    WEN_b_0,
+    REN_b_0,
+    WR_ADDR_b_0,
+    RD_ADDR_b_0,
+    WDATA_b_0,
+    RDATA_b_0,
+    
+    clk_a_1,
+    WEN_a_1,
+    REN_a_1,
+    WR_ADDR_a_1,
+    RD_ADDR_a_1,
+    WDATA_a_1,
+    RDATA_a_1,
+    
+    clk_b_1,
+    WEN_b_1,
+    REN_b_1,
+    WR_ADDR_b_1,
+    RD_ADDR_b_1,
+    WDATA_b_1,
+    RDATA_b_1
+);
+
+parameter ADDR_WIDTH0 = 11;
+parameter DATA_WIDTH0 = 9;
+parameter BE1_WIDTH0 = 1;
+parameter BE2_WIDTH0 = 1;
+
+parameter ADDR_WIDTH1 = 11;
+parameter DATA_WIDTH1 = 9;
+parameter BE1_WIDTH1 = 1;
+parameter BE2_WIDTH1 = 1;
+
+input wire clk_a_0;
+input wire WEN_a_0;
+input wire REN_a_0;
+input wire [ADDR_WIDTH0-1 :0] WR_ADDR_a_0;
+input wire [ADDR_WIDTH0-1 :0] RD_ADDR_a_0;
+input wire [DATA_WIDTH0-1 :0] WDATA_a_0;
+output wire [DATA_WIDTH0-1 :0] RDATA_a_0;
+
+input wire clk_b_0;
+input wire WEN_b_0;
+input wire REN_b_0;
+input wire [ADDR_WIDTH0-1 :0] WR_ADDR_b_0;
+input wire [ADDR_WIDTH0-1 :0] RD_ADDR_b_0;
+input wire [DATA_WIDTH0-1 :0] WDATA_b_0;
+output wire [DATA_WIDTH0-1 :0] RDATA_b_0;
+
+input wire clk_a_1;
+input wire WEN_a_1;
+input wire REN_a_1;
+input wire [ADDR_WIDTH1-1 :0] WR_ADDR_a_1;
+input wire [ADDR_WIDTH1-1 :0] RD_ADDR_a_1;
+input wire [DATA_WIDTH1-1 :0] WDATA_a_1;
+output wire [DATA_WIDTH1-1 :0] RDATA_a_1;
+
+input wire clk_b_1;
+input wire WEN_b_1;
+input wire REN_b_1;
+input wire [ADDR_WIDTH1-1 :0] WR_ADDR_b_1;
+input wire [ADDR_WIDTH1-1 :0] RD_ADDR_b_1;
+input wire [DATA_WIDTH1-1 :0] WDATA_b_1;
+output wire [DATA_WIDTH1-1 :0] RDATA_b_1;
+ 
+DPRAM_18K_BLK #(
+              .ADDR_WIDTH(ADDR_WIDTH0),
+              .DATA_WIDTH(DATA_WIDTH0),
+              .BE1_WIDTH(BE1_WIDTH0),
+              .BE2_WIDTH(BE2_WIDTH0)
+              ) dpram_x18_inst0 ( 
+              
+              .CLK1_i(clk_a_0),
+              .WEN1_i(WEN_a_0),
+              .REN1_i(REN_a_0),
+              .WR1_ADDR_i(WR_ADDR_a_0),
+              .RD1_ADDR_i(RD_ADDR_a_0),
+              .WDATA1_i(WDATA_a_0),
+              .RDATA1_o(RDATA_a_0),
+              
+              .CLK2_i(clk_b_0),
+              .WEN2_i(WEN_b_0),
+              .REN2_i(REN_b_0),
+              .WR2_ADDR_i(WR_ADDR_b_0),
+              .RD2_ADDR_i(RD_ADDR_b_0),
+              .WDATA2_i(WDATA_b_0),
+              .RDATA2_o(RDATA_b_0)
+              );
+              
+ 
+DPRAM_18K_BLK #(
+              .ADDR_WIDTH(ADDR_WIDTH1),
+              .DATA_WIDTH(DATA_WIDTH1),
+              .BE1_WIDTH(BE1_WIDTH1),
+              .BE2_WIDTH(BE2_WIDTH1)
+              ) dpram_x18_inst1 ( 
+              
+              .CLK1_i(clk_a_1),
+              .WEN1_i(WEN_a_1),
+              .REN1_i(REN_a_1),
+              .WR1_ADDR_i(WR_ADDR_a_1),
+              .RD1_ADDR_i(RD_ADDR_a_1),
+              .WDATA1_i(WDATA_a_1),
+              .RDATA1_o(RDATA_a_1),
+              
+              .CLK2_i(clk_b_1),
+              .WEN2_i(WEN_b_1),
+              .REN2_i(REN_b_1),
+              .WR2_ADDR_i(WR_ADDR_b_1),
+              .RD2_ADDR_i(RD_ADDR_b_1),
+              .WDATA2_i(WDATA_b_1),
+              .RDATA2_o(RDATA_b_1)
+              );
+              
+endmodule    
+
+module dpram_18x1024_9x2048 (   
+    clk_a_0,
+    WEN_a_0,
+    REN_a_0,
+    WR_ADDR_a_0,
+    RD_ADDR_a_0,
+    WDATA_a_0,
+    RDATA_a_0,
+    
+    clk_b_0,
+    WEN_b_0,
+    REN_b_0,
+    WR_ADDR_b_0,
+    RD_ADDR_b_0,
+    WDATA_b_0,
+    RDATA_b_0,
+    
+    clk_a_1,
+    WEN_a_1,
+    REN_a_1,
+    WR_ADDR_a_1,
+    RD_ADDR_a_1,
+    WDATA_a_1,
+    RDATA_a_1,
+    
+    clk_b_1,
+    WEN_b_1,
+    REN_b_1,
+    WR_ADDR_b_1,
+    RD_ADDR_b_1,
+    WDATA_b_1,
+    RDATA_b_1
+);
+
+parameter ADDR_WIDTH0 = 10;
+parameter DATA_WIDTH0 = 18;
+parameter BE1_WIDTH0 = 2;
+parameter BE2_WIDTH0 = 2;
+
+parameter ADDR_WIDTH1 = 11;
+parameter DATA_WIDTH1 = 9;
+parameter BE1_WIDTH1 = 1;
+parameter BE2_WIDTH1 = 1;
+
+input wire clk_a_0;
+input wire WEN_a_0;
+input wire REN_a_0;
+input wire [ADDR_WIDTH0-1 :0] WR_ADDR_a_0;
+input wire [ADDR_WIDTH0-1 :0] RD_ADDR_a_0;
+input wire [DATA_WIDTH0-1 :0] WDATA_a_0;
+output wire [DATA_WIDTH0-1 :0] RDATA_a_0;
+
+input wire clk_b_0;
+input wire WEN_b_0;
+input wire REN_b_0;
+input wire [ADDR_WIDTH0-1 :0] WR_ADDR_b_0;
+input wire [ADDR_WIDTH0-1 :0] RD_ADDR_b_0;
+input wire [DATA_WIDTH0-1 :0] WDATA_b_0;
+output wire [DATA_WIDTH0-1 :0] RDATA_b_0;
+
+input wire clk_a_1;
+input wire WEN_a_1;
+input wire REN_a_1;
+input wire [ADDR_WIDTH1-1 :0] WR_ADDR_a_1;
+input wire [ADDR_WIDTH1-1 :0] RD_ADDR_a_1;
+input wire [DATA_WIDTH1-1 :0] WDATA_a_1;
+output wire [DATA_WIDTH1-1 :0] RDATA_a_1;
+
+input wire clk_b_1;
+input wire WEN_b_1;
+input wire REN_b_1;
+input wire [ADDR_WIDTH1-1 :0] WR_ADDR_b_1;
+input wire [ADDR_WIDTH1-1 :0] RD_ADDR_b_1;
+input wire [DATA_WIDTH1-1 :0] WDATA_b_1;
+output wire [DATA_WIDTH1-1 :0] RDATA_b_1;
+ 
+DPRAM_18K_BLK #(
+              .ADDR_WIDTH(ADDR_WIDTH0),
+              .DATA_WIDTH(DATA_WIDTH0),
+              .BE1_WIDTH(BE1_WIDTH0),
+              .BE2_WIDTH(BE2_WIDTH0)
+              ) dpram_x18_inst0 ( 
+              
+              .CLK1_i(clk_a_0),
+              .WEN1_i(WEN_a_0),
+              .REN1_i(REN_a_0),
+              .WR1_ADDR_i(WR_ADDR_a_0),
+              .RD1_ADDR_i(RD_ADDR_a_0),
+              .WDATA1_i(WDATA_a_0),
+              .RDATA1_o(RDATA_a_0),
+              
+              .CLK2_i(clk_b_0),
+              .WEN2_i(WEN_b_0),
+              .REN2_i(REN_b_0),
+              .WR2_ADDR_i(WR_ADDR_b_0),
+              .RD2_ADDR_i(RD_ADDR_b_0),
+              .WDATA2_i(WDATA_b_0),
+              .RDATA2_o(RDATA_b_0)
+              );
+              
+ 
+DPRAM_18K_BLK #(
+              .ADDR_WIDTH(ADDR_WIDTH1),
+              .DATA_WIDTH(DATA_WIDTH1),
+              .BE1_WIDTH(BE1_WIDTH1),
+              .BE2_WIDTH(BE2_WIDTH1)
+              ) dpram_x18_inst1 ( 
+              
+              .CLK1_i(clk_a_1),
+              .WEN1_i(WEN_a_1),
+              .REN1_i(REN_a_1),
+              .WR1_ADDR_i(WR_ADDR_a_1),
+              .RD1_ADDR_i(RD_ADDR_a_1),
+              .WDATA1_i(WDATA_a_1),
+              .RDATA1_o(RDATA_a_1),
+              
+              .CLK2_i(clk_b_1),
+              .WEN2_i(WEN_b_1),
+              .REN2_i(REN_b_1),
+              .WR2_ADDR_i(WR_ADDR_b_1),
+              .RD2_ADDR_i(RD_ADDR_b_1),
+              .WDATA2_i(WDATA_b_1),
+              .RDATA2_o(RDATA_b_1)
+              );
+              
+endmodule    
\ No newline at end of file
diff --git a/ql-qlf-plugin/tests/qlf_k6n10f/bram18k_tdp/sim/Makefile b/ql-qlf-plugin/tests/qlf_k6n10f/bram18k_tdp/sim/Makefile
new file mode 100644
index 0000000..3d9d866
--- /dev/null
+++ b/ql-qlf-plugin/tests/qlf_k6n10f/bram18k_tdp/sim/Makefile
@@ -0,0 +1,41 @@
+# Copyright (C) 2019-2022 The SymbiFlow Authors
+#
+# Use of this source code is governed by a ISC-style
+# license that can be found in the LICENSE file or at
+# https://opensource.org/licenses/ISC
+#
+# SPDX-License-Identifier: ISC
+
+TESTBENCH = bram18k_tdp_tb.v
+POST_SYNTH = dpram_18x1024_9x2048_post_synth dpram_9x2048_x2_post_synth dpram_18x1024_x2_post_synth   
+ADDR_WIDTH0 = 10 11 10
+DATA_WIDTH0 = 18 9 18
+ADDR_WIDTH1 = 11 11 10
+DATA_WIDTH1 = 9 9 18
+TOP = dpram_18x1024_9x2048 dpram_9x2048_x2 dpram_18x1024_x2
+ADDR_DEFINES0 = $(foreach awidth0, $(ADDR_WIDTH0),-DADDR_WIDTH0="$(awidth0)")
+ADDR_DEFINES1 = $(foreach awidth1, $(ADDR_WIDTH1),-DADDR_WIDTH1="$(awidth1)")
+DATA_DEFINES0 = $(foreach dwidth0, $(DATA_WIDTH0),-DDATA_WIDTH0="$(dwidth0)")
+DATA_DEFINES1 = $(foreach dwidth1, $(DATA_WIDTH1),-DDATA_WIDTH1="$(dwidth1)")
+TOP_DEFINES = $(foreach top, $(TOP),-DTOP="$(top)")
+VCD_DEFINES = $(foreach vcd, $(POST_SYNTH),-DVCD="$(vcd).vcd")
+
+SIM_LIBS = $(shell find ../../../../qlf_k6n10f -name "*.v" -not -name "*_map.v")
+
+define simulate_post_synth
+	@iverilog  -vvvv -g2005 $(word $(1),$(ADDR_DEFINES0)) $(word $(1),$(ADDR_DEFINES1)) $(word $(1),$(DATA_DEFINES0)) $(word $(1),$(DATA_DEFINES1)) $(word $(1),$(TOP_DEFINES)) $(word $(1),$(VCD_DEFINES)) -o $(word $(1),$(POST_SYNTH)).vvp $(word $(1),$(POST_SYNTH)).v $(SIM_LIBS) $(TESTBENCH) > $(word $(1),$(POST_SYNTH)).vvp.log 2>&1
+	@vvp -vvvv $(word $(1),$(POST_SYNTH)).vvp > $(word $(1),$(POST_SYNTH)).vcd.log 2>&1
+endef
+
+define clean_post_synth_sim
+	@rm -rf  $(word $(1),$(POST_SYNTH)).vcd $(word $(1),$(POST_SYNTH)).vvp $(word $(1),$(POST_SYNTH)).vvp.log $(word $(1),$(POST_SYNTH)).vcd.log
+endef
+
+#FIXME: $(call simulate_post_synth,3)
+sim:
+	$(call simulate_post_synth,1)
+	$(call clean_post_synth_sim,1)
+	$(call simulate_post_synth,2)
+	$(call clean_post_synth_sim,2)
+	$(call simulate_post_synth,3)
+	$(call clean_post_synth_sim,3)
\ No newline at end of file
diff --git a/ql-qlf-plugin/tests/qlf_k6n10f/bram18k_tdp/sim/bram18k_tdp_tb.v b/ql-qlf-plugin/tests/qlf_k6n10f/bram18k_tdp/sim/bram18k_tdp_tb.v
new file mode 100644
index 0000000..1e5baa7
--- /dev/null
+++ b/ql-qlf-plugin/tests/qlf_k6n10f/bram18k_tdp/sim/bram18k_tdp_tb.v
@@ -0,0 +1,356 @@
+// Copyright (C) 2019-2022 The SymbiFlow Authors
+//
+// Use of this source code is governed by a ISC-style
+// license that can be found in the LICENSE file or at
+// https://opensource.org/licenses/ISC
+//
+// SPDX-License-Identifier: ISC
+
+`timescale 1ns/1ps
+
+`define STRINGIFY(x) `"x`"
+
+module TB;
+	localparam PERIOD = 50;
+	localparam ADDR_INCR = 1;
+
+	reg clk_a;
+	reg rce_a_0;
+  reg rce_a_1;
+	reg [`ADDR_WIDTH0-1:0] ra_a_0;
+  reg [`ADDR_WIDTH1-1:0] ra_a_1;
+	wire [`DATA_WIDTH0-1:0] rq_a_0;
+	wire [`DATA_WIDTH1-1:0] rq_a_1;
+	reg wce_a_0;
+  reg wce_a_1;
+	reg [`ADDR_WIDTH0-1:0] wa_a_0;
+  reg [`ADDR_WIDTH1-1:0] wa_a_1;
+	reg [`DATA_WIDTH0-1:0] wd_a_0;
+	reg [`DATA_WIDTH1-1:0] wd_a_1;
+
+	reg clk_b;
+	reg rce_b_0;
+  reg rce_b_1;
+	reg [`ADDR_WIDTH0-1:0] ra_b_0;
+  reg [`ADDR_WIDTH1-1:0] ra_b_1;
+	wire [`DATA_WIDTH0-1:0] rq_b_0;
+	wire [`DATA_WIDTH1-1:0] rq_b_1;
+	reg wce_b_0;
+  reg wce_b_1;
+	reg [`ADDR_WIDTH0-1:0] wa_b_0;
+  reg [`ADDR_WIDTH1-1:0] wa_b_1;
+	reg [`DATA_WIDTH0-1:0] wd_b_0;
+	reg [`DATA_WIDTH1-1:0] wd_b_1;
+
+
+	initial clk_a = 0;
+	initial clk_b = 0;
+	initial ra_a_0 = 0;
+  initial ra_a_1 = 0;
+	initial ra_b_0 = 0;
+  initial ra_b_1 = 0;
+	initial rce_a_0 = 0;
+  initial rce_a_1 = 0;
+	initial rce_b_0 = 0;
+  initial rce_b_1 = 0;
+	initial wce_a_0 = 0;
+  initial wce_a_1 = 0;
+	initial wce_b_0 = 0;
+  initial wce_b_1 = 0;
+	initial forever #(PERIOD / 2.0) clk_a = ~clk_a;
+	initial begin
+		#(PERIOD / 4.0);
+		forever #(PERIOD / 2.0) clk_b = ~clk_b;
+	end  
+	initial begin
+		$dumpfile(`STRINGIFY(`VCD));
+		$dumpvars;
+	end
+
+	integer a0;
+	integer b0;
+	integer a1;
+	integer b1;
+
+	reg done_a0;
+	reg done_b0;
+	reg done_a1;
+	reg done_b1;
+	initial done_a0 = 1'b0;
+	initial done_b0 = 1'b0;
+	initial done_a1 = 1'b0;
+	initial done_b1 = 1'b0;
+	wire done_sim = done_a0 & done_b0 & done_a1 & done_b1;
+
+	reg [`DATA_WIDTH0-1:0] expected_a_0;
+	reg [`DATA_WIDTH1-1:0] expected_a_1;
+	reg [`DATA_WIDTH0-1:0] expected_b_0;
+	reg [`DATA_WIDTH1-1:0] expected_b_1;
+
+	always @(posedge clk_a) begin
+      expected_a_0 <= (a0 | (a0 << 20) | 20'h55000) & {`DATA_WIDTH0{1'b1}};
+      expected_a_1 <= ((a1+1) | ((a1+1) << 20) | 20'h55000) & {`DATA_WIDTH1{1'b1}};
+	end
+	always @(posedge clk_b) begin
+      expected_b_0 <= ((b0+2) | ((b0+2) << 20) | 20'h55000) & {`DATA_WIDTH0{1'b1}};
+      expected_b_1 <= ((b1+3) | ((b1+3) << 20) | 20'h55000) & {`DATA_WIDTH1{1'b1}};
+	end
+
+	wire error_a_0 = a0 != 0 ? (rq_a_0 !== expected_a_0) : 0;
+	wire error_a_1 = a1 != 0 ? (rq_a_1 !== expected_a_1) : 0;
+	wire error_b_0 = b0 != (1<<`ADDR_WIDTH0) / 2 ? (rq_b_0 !== expected_b_0) : 0;
+	wire error_b_1 = b1 != (1<<`ADDR_WIDTH1) / 2 ? (rq_b_1 !== expected_b_1) : 0;
+
+	integer error_a_0_cnt = 0;
+	integer error_a_1_cnt = 0;
+	integer error_b_0_cnt = 0;
+	integer error_b_1_cnt = 0;
+
+	always @ (posedge clk_a)
+	begin
+		if (error_a_0)
+			error_a_0_cnt <= error_a_0_cnt + 1'b1;
+		if (error_a_1)
+			error_a_1_cnt <= error_a_1_cnt + 1'b1;
+	end
+	always @ (posedge clk_b)
+	begin
+		if (error_b_0)
+			error_b_0_cnt <= error_b_0_cnt + 1'b1;
+		if (error_b_1)
+			error_b_1_cnt <= error_b_1_cnt + 1'b1;
+	end
+
+	// PORTs A0
+	initial #(1) begin
+		// Write data
+		for (a0 = 0; a0 < (1<<`ADDR_WIDTH0) / 2; a0 = a0 + ADDR_INCR) begin
+			@(negedge clk_a) begin
+				wa_a_0 = a0;
+				wd_a_0 = a0 | (a0 << 20) | 20'h55000;
+				wce_a_0 = 1;
+			end
+			@(posedge clk_a) begin
+				#(PERIOD/10) wce_a_0 = 0;
+			end
+		end
+		// Read data
+		for (a0 = 0; a0 < (1<<`ADDR_WIDTH0) / 2; a0 = a0 + ADDR_INCR) begin
+			@(negedge clk_a) begin
+				ra_a_0 = a0;
+				rce_a_0 = 1;
+			end
+			@(posedge clk_a) begin
+				#(PERIOD/10) rce_a_0 = 0;
+				if ( rq_a_0 !== expected_a_0) begin
+					$display("%d: PORT A0: FAIL: mismatch act=%x exp=%x at %x", $time, rq_a_0, expected_a_0, a0);
+				end else begin
+					$display("%d: PORT A0: OK: act=%x exp=%x at %x", $time, rq_a_0, expected_a_0, a0);
+				end
+			end
+		end
+		done_a0 = 1'b1;
+    a0 = 0;
+	  // PORTs B0
+    @(posedge clk_b)
+    #2;
+		// Write data
+		for (b0 = (1<<`ADDR_WIDTH0) / 2; b0 < (1<<`ADDR_WIDTH0); b0 = b0 + ADDR_INCR) begin
+			@(negedge clk_b) begin
+				wa_b_0 = b0;
+				wd_b_0 = (b0+2) | ((b0+2) << 20) | 20'h55000;
+				wce_b_0 = 1;
+			end
+			@(posedge clk_b) begin
+				#(PERIOD/10) wce_b_0 = 0;
+			end
+		end
+		// Read data
+		for (b0 = (1<<`ADDR_WIDTH0) / 2; b0 < (1<<`ADDR_WIDTH0); b0 = b0 + ADDR_INCR) begin
+			@(negedge clk_b) begin
+				ra_b_0 = b0;
+				rce_b_0 = 1;
+			end
+			@(posedge clk_b) begin
+				#(PERIOD/10) rce_b_0 = 0;
+				if ( rq_b_0 !== expected_b_0) begin
+					$display("%d: PORT B0: FAIL: mismatch act=%x exp=%x at %x", $time, rq_b_0, expected_b_0, b0);
+				end else begin
+					$display("%d: PORT B0: OK: act=%x exp=%x at %x", $time, rq_b_0, expected_b_0, b0);
+				end
+			end
+		end
+		done_b0 = 1'b1;
+	  b0 = (1<<`ADDR_WIDTH0) / 2;
+	  // PORTs A1
+    @(posedge clk_a)
+    #2;
+		// Write data
+		for (a1 = 0; a1 < (1<<`ADDR_WIDTH1) / 2; a1 = a1 + ADDR_INCR) begin
+			@(negedge clk_a) begin
+				wa_a_1 = a1;
+				wd_a_1 = (a1+1) | ((a1+1) << 20) | 20'h55000;
+				wce_a_1 = 1;
+			end
+			@(posedge clk_a) begin
+				#(PERIOD/10) wce_a_1 = 0;
+			end
+		end
+		// Read data
+		for (a1 = 0; a1 < (1<<`ADDR_WIDTH1) / 2; a1 = a1 + ADDR_INCR) begin
+			@(negedge clk_a) begin
+				ra_a_1 = a1;
+				rce_a_1 = 1;
+			end
+			@(posedge clk_a) begin
+				#(PERIOD/10) rce_a_1 = 0;
+				if ( rq_a_1 !== expected_a_1) begin
+					$display("%d: PORT A1: FAIL: mismatch act=%x exp=%x at %x", $time, rq_a_1, expected_a_1, a1);
+				end else begin
+					$display("%d: PORT A1: OK: act=%x exp=%x at %x", $time, rq_a_1, expected_a_1, a1);
+				end
+			end
+		end
+		done_a1 = 1'b1;
+    a1 = 0;
+	  // PORTs B1
+    @(posedge clk_b)
+    #2;
+		// Write data
+		for (b1 = (1<<`ADDR_WIDTH1) / 2; b1 < (1<<`ADDR_WIDTH1); b1 = b1 + ADDR_INCR) begin
+			@(negedge clk_b) begin
+				wa_b_1 = b1;
+				wd_b_1 = (b1+3) | ((b1+3) << 20) | 20'h55000;
+				wce_b_1 = 1;
+			end
+			@(posedge clk_b) begin
+				#(PERIOD/10) wce_b_1 = 0;
+			end
+		end
+		// Read data
+		for (b1 = (1<<`ADDR_WIDTH1) / 2; b1 < (1<<`ADDR_WIDTH1); b1 = b1 + ADDR_INCR) begin
+			@(negedge clk_b) begin
+				ra_b_1 = b1;
+				rce_b_1 = 1;
+			end
+			@(posedge clk_b) begin
+				#(PERIOD/10) rce_b_1 = 0;
+				if ( rq_b_1 !== expected_b_1) begin
+					$display("%d: PORT B1: FAIL: mismatch act=%x exp=%x at %x", $time, rq_b_1, expected_b_1, b1);
+				end else begin
+					$display("%d: PORT B1: OK: act=%x exp=%x at %x", $time, rq_b_1, expected_b_1, b1);
+				end
+			end
+		end
+		done_b1 = 1'b1;
+    b1 = (1<<`ADDR_WIDTH1) / 2;
+	end
+
+	// Scan for simulation finish
+	always @(posedge clk_a, posedge clk_b) begin
+		if (done_sim)
+			$finish_and_return( (error_a_0_cnt == 0 & error_b_0_cnt == 0 & error_a_1_cnt == 0 & error_b_1_cnt == 0) ? 0 : -1 );
+	end
+  
+	case (`STRINGIFY(`TOP))
+		"dpram_18x1024_9x2048": begin
+			dpram_18x1024_9x2048 #() bram (
+				.clk_a_0(clk_a),
+				.REN_a_0(rce_a_0),
+				.RD_ADDR_a_0(ra_a_0),
+				.RDATA_a_0(rq_a_0),
+				.WEN_a_0(wce_a_0),
+				.WR_ADDR_a_0(wa_a_0),
+				.WDATA_a_0(wd_a_0),
+				.clk_b_0(clk_b),
+				.REN_b_0(rce_b_0),
+				.RD_ADDR_b_0(ra_b_0),
+				.RDATA_b_0(rq_b_0),
+				.WEN_b_0(wce_b_0),
+				.WR_ADDR_b_0(wa_b_0),
+				.WDATA_b_0(wd_b_0),
+
+				.clk_a_1(clk_a),
+				.REN_a_1(rce_a_1),
+				.RD_ADDR_a_1(ra_a_1),
+				.RDATA_a_1(rq_a_1),
+				.WEN_a_1(wce_a_1),
+				.WR_ADDR_a_1(wa_a_1),
+				.WDATA_a_1(wd_a_1),
+				.clk_b_1(clk_b),
+				.REN_b_1(rce_b_1),
+				.RD_ADDR_b_1(ra_b_1),
+				.RDATA_b_1(rq_b_1),
+				.WEN_b_1(wce_b_1),
+				.WR_ADDR_b_1(wa_b_1),
+				.WDATA_b_1(wd_b_1)
+			);
+		end
+		"dpram_9x2048_x2": begin
+			dpram_9x2048_x2 #() bram (
+				.clk_a_0(clk_a),
+				.REN_a_0(rce_a_0),
+				.RD_ADDR_a_0(ra_a_0),
+				.RDATA_a_0(rq_a_0),
+				.WEN_a_0(wce_a_0),
+				.WR_ADDR_a_0(wa_a_0),
+				.WDATA_a_0(wd_a_0),
+				.clk_b_0(clk_b),
+				.REN_b_0(rce_b_0),
+				.RD_ADDR_b_0(ra_b_0),
+				.RDATA_b_0(rq_b_0),
+				.WEN_b_0(wce_b_0),
+				.WR_ADDR_b_0(wa_b_0),
+				.WDATA_b_0(wd_b_0),
+
+				.clk_a_1(clk_a),
+				.REN_a_1(rce_a_1),
+				.RD_ADDR_a_1(ra_a_1),
+				.RDATA_a_1(rq_a_1),
+				.WEN_a_1(wce_a_1),
+				.WR_ADDR_a_1(wa_a_1),
+				.WDATA_a_1(wd_a_1),
+				.clk_b_1(clk_b),
+				.REN_b_1(rce_b_1),
+				.RD_ADDR_b_1(ra_b_1),
+				.RDATA_b_1(rq_b_1),
+				.WEN_b_1(wce_b_1),
+				.WR_ADDR_b_1(wa_b_1),
+				.WDATA_b_1(wd_b_1)
+			);
+		end
+		"dpram_18x1024_x2": begin
+			dpram_18x1024_x2 #() bram (
+				.clk_a_0(clk_a),
+				.REN_a_0(rce_a_0),
+				.RD_ADDR_a_0(ra_a_0),
+				.RDATA_a_0(rq_a_0),
+				.WEN_a_0(wce_a_0),
+				.WR_ADDR_a_0(wa_a_0),
+				.WDATA_a_0(wd_a_0),
+				.clk_b_0(clk_b),
+				.REN_b_0(rce_b_0),
+				.RD_ADDR_b_0(ra_b_0),
+				.RDATA_b_0(rq_b_0),
+				.WEN_b_0(wce_b_0),
+				.WR_ADDR_b_0(wa_b_0),
+				.WDATA_b_0(wd_b_0),
+
+				.clk_a_1(clk_a),
+				.REN_a_1(rce_a_1),
+				.RD_ADDR_a_1(ra_a_1),
+				.RDATA_a_1(rq_a_1),
+				.WEN_a_1(wce_a_1),
+				.WR_ADDR_a_1(wa_a_1),
+				.WDATA_a_1(wd_a_1),
+				.clk_b_1(clk_b),
+				.REN_b_1(rce_b_1),
+				.RD_ADDR_b_1(ra_b_1),
+				.RDATA_b_1(rq_b_1),
+				.WEN_b_1(wce_b_1),
+				.WR_ADDR_b_1(wa_b_1),
+				.WDATA_b_1(wd_b_1)
+			);
+		end
+	endcase
+endmodule
diff --git a/ql-qlf-plugin/tests/qlf_k6n10f/bram36k_afifo/bram36k_afifo.tcl b/ql-qlf-plugin/tests/qlf_k6n10f/bram36k_afifo/bram36k_afifo.tcl
new file mode 100644
index 0000000..dacbe77
--- /dev/null
+++ b/ql-qlf-plugin/tests/qlf_k6n10f/bram36k_afifo/bram36k_afifo.tcl
@@ -0,0 +1,38 @@
+yosys -import
+
+if { [info procs ql-qlf-k6n10f] == {} } { plugin -i ql-qlf }
+yosys -import  ;
+
+read_verilog $::env(DESIGN_TOP).v
+design -save bram36k_afifo
+
+select af1024x36_1024x36
+select *
+synth_quicklogic -family qlf_k6n10f -top af1024x36_1024x36 -bram_types
+opt_expr -undriven
+opt_clean
+stat
+write_verilog sim/af1024x36_1024x36_post_synth.v
+select -assert-count 1 t:TDP36K_FIFO_ASYNC_WR_X36_RD_X36_nonsplit
+
+select -clear
+design -load bram36k_afifo
+select af2048x18_2048x18
+select *
+synth_quicklogic -family qlf_k6n10f -top af2048x18_2048x18 -bram_types
+opt_expr -undriven
+opt_clean
+stat
+write_verilog sim/af2048x18_2048x18_post_synth.v
+select -assert-count 1 t:TDP36K_FIFO_ASYNC_WR_X18_RD_X18_nonsplit
+
+select -clear
+design -load bram36k_afifo
+select af4096x9_4096x9
+select *
+synth_quicklogic -family qlf_k6n10f -top af4096x9_4096x9 -bram_types
+opt_expr -undriven
+opt_clean
+stat
+write_verilog sim/af4096x9_4096x9_post_synth.v
+select -assert-count 1 t:TDP36K_FIFO_ASYNC_WR_X9_RD_X9_nonsplit
diff --git a/ql-qlf-plugin/tests/qlf_k6n10f/bram36k_afifo/bram36k_afifo.v b/ql-qlf-plugin/tests/qlf_k6n10f/bram36k_afifo/bram36k_afifo.v
new file mode 100644
index 0000000..bdd8077
--- /dev/null
+++ b/ql-qlf-plugin/tests/qlf_k6n10f/bram36k_afifo/bram36k_afifo.v
@@ -0,0 +1,125 @@
+module af1024x36_1024x36 (DIN,PUSH,POP,clock0,clock1,Async_Flush,Almost_Full,Almost_Empty,Full,Empty,Full_Watermark,Empty_Watermark,Overrun_Error,Underrun_Error,DOUT);
+
+parameter WR_DATA_WIDTH = 36;
+parameter RD_DATA_WIDTH = 36;
+parameter UPAE_DBITS = 12'd10;
+parameter UPAF_DBITS = 12'd10;
+
+input clock0,clock1;
+input PUSH,POP;
+input [WR_DATA_WIDTH-1:0] DIN;
+input Async_Flush;
+output [RD_DATA_WIDTH-1:0] DOUT;
+output Almost_Full,Almost_Empty;
+output Full, Empty;
+output Full_Watermark, Empty_Watermark;
+output Overrun_Error, Underrun_Error;
+
+AFIFO_36K_BLK  # (.WR_DATA_WIDTH(WR_DATA_WIDTH),.RD_DATA_WIDTH(RD_DATA_WIDTH),.UPAE_DBITS(UPAE_DBITS),.UPAF_DBITS(UPAF_DBITS)
+        				 ) 
+  FIFO_INST    (
+                .DIN(DIN),
+                .PUSH(PUSH),
+                .POP(POP),
+                .Push_Clk(clock0),
+                .Pop_Clk(clock1),
+                .Async_Flush(Async_Flush),
+                
+                .Overrun_Error(Overrun_Error),
+                .Full_Watermark(Full_Watermark),
+                .Almost_Full(Almost_Full),
+                .Full(Full),
+                
+                .Underrun_Error(Underrun_Error),
+                .Empty_Watermark(Empty_Watermark),
+                .Almost_Empty(Almost_Empty),
+                .Empty(Empty),
+
+                .DOUT(DOUT)
+         				);
+
+endmodule
+
+module af2048x18_2048x18 (DIN,PUSH,POP,clock0,clock1,Async_Flush,Almost_Full,Almost_Empty,Full,Empty,Full_Watermark,Empty_Watermark,Overrun_Error,Underrun_Error,DOUT);
+
+parameter WR_DATA_WIDTH = 18;
+parameter RD_DATA_WIDTH = 18;
+parameter UPAE_DBITS = 12'd10;
+parameter UPAF_DBITS = 12'd10;
+
+input clock0,clock1;
+input PUSH,POP;
+input [WR_DATA_WIDTH-1:0] DIN;
+input Async_Flush;
+output [RD_DATA_WIDTH-1:0] DOUT;
+output Almost_Full,Almost_Empty;
+output Full, Empty;
+output Full_Watermark, Empty_Watermark;
+output Overrun_Error, Underrun_Error;
+
+AFIFO_36K_BLK  # (.WR_DATA_WIDTH(WR_DATA_WIDTH),.RD_DATA_WIDTH(RD_DATA_WIDTH),.UPAE_DBITS(UPAE_DBITS),.UPAF_DBITS(UPAF_DBITS)
+        				 ) 
+  FIFO_INST    (
+                .DIN(DIN),
+                .PUSH(PUSH),
+                .POP(POP),
+                .Push_Clk(clock0),
+                .Pop_Clk(clock1),
+                .Async_Flush(Async_Flush),
+                
+                .Overrun_Error(Overrun_Error),
+                .Full_Watermark(Full_Watermark),
+                .Almost_Full(Almost_Full),
+                .Full(Full),
+                
+                .Underrun_Error(Underrun_Error),
+                .Empty_Watermark(Empty_Watermark),
+                .Almost_Empty(Almost_Empty),
+                .Empty(Empty),
+
+                .DOUT(DOUT)
+         				);
+
+endmodule
+
+module af4096x9_4096x9 (DIN,PUSH,POP,clock0,clock1,Async_Flush,Almost_Full,Almost_Empty,Full,Empty,Full_Watermark,Empty_Watermark,Overrun_Error,Underrun_Error,DOUT);
+
+parameter WR_DATA_WIDTH = 9;
+parameter RD_DATA_WIDTH = 9;
+parameter UPAE_DBITS = 12'd10;
+parameter UPAF_DBITS = 12'd10;
+
+input clock0,clock1;
+input PUSH,POP;
+input [WR_DATA_WIDTH-1:0] DIN;
+input Async_Flush;
+output [RD_DATA_WIDTH-1:0] DOUT;
+output Almost_Full,Almost_Empty;
+output Full, Empty;
+output Full_Watermark, Empty_Watermark;
+output Overrun_Error, Underrun_Error;
+
+AFIFO_36K_BLK  # (.WR_DATA_WIDTH(WR_DATA_WIDTH),.RD_DATA_WIDTH(RD_DATA_WIDTH),.UPAE_DBITS(UPAE_DBITS),.UPAF_DBITS(UPAF_DBITS)
+        				 ) 
+  FIFO_INST    (
+                .DIN(DIN),
+                .PUSH(PUSH),
+                .POP(POP),
+                .Push_Clk(clock0),
+                .Pop_Clk(clock1),
+                .Async_Flush(Async_Flush),
+                
+                .Overrun_Error(Overrun_Error),
+                .Full_Watermark(Full_Watermark),
+                .Almost_Full(Almost_Full),
+                .Full(Full),
+                
+                .Underrun_Error(Underrun_Error),
+                .Empty_Watermark(Empty_Watermark),
+                .Almost_Empty(Almost_Empty),
+                .Empty(Empty),
+
+                .DOUT(DOUT)
+         				);
+
+endmodule
\ No newline at end of file
diff --git a/ql-qlf-plugin/tests/qlf_k6n10f/bram36k_afifo/sim/Makefile b/ql-qlf-plugin/tests/qlf_k6n10f/bram36k_afifo/sim/Makefile
new file mode 100644
index 0000000..8b777b5
--- /dev/null
+++ b/ql-qlf-plugin/tests/qlf_k6n10f/bram36k_afifo/sim/Makefile
@@ -0,0 +1,49 @@
+# Copyright 2020-2022 F4PGA Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-License-Identifier: Apache-2.0
+
+TESTBENCH = bram36k_afifo_tb.v
+POST_SYNTH = af1024x36_1024x36_post_synth af2048x18_2048x18_post_synth af4096x9_4096x9_post_synth
+ADDR_WIDTH0 = 10 11 12
+DATA_WIDTH0 = 36 18 9
+ADDR_WIDTH1 = 10 11 12
+DATA_WIDTH1 = 36 18 9
+TOP = af1024x36_1024x36 af2048x18_2048x18 af4096x9_4096x9
+ADDR0_DEFINES = $(foreach awidth0, $(ADDR_WIDTH0),-DADDR_WIDTH0="$(awidth0)")
+ADDR1_DEFINES = $(foreach awidth1, $(ADDR_WIDTH1),-DADDR_WIDTH1="$(awidth1)")
+DATA0_DEFINES = $(foreach dwidth0, $(DATA_WIDTH0),-DDATA_WIDTH0="$(dwidth0)")
+DATA1_DEFINES = $(foreach dwidth1, $(DATA_WIDTH1),-DDATA_WIDTH1="$(dwidth1)")
+TOP_DEFINES = $(foreach top, $(TOP),-DTOP="$(top)")
+VCD_DEFINES = $(foreach vcd, $(POST_SYNTH),-DVCD="$(vcd).vcd")
+
+SIM_LIBS = $(shell find ../../../../qlf_k6n10f -name "*.v" -not -name "*_map.v")
+
+define simulate_post_synth
+	@iverilog  -vvvv -g2005 $(word $(1),$(ADDR0_DEFINES)) $(word $(1),$(ADDR1_DEFINES)) $(word $(1),$(DATA0_DEFINES)) $(word $(1),$(DATA1_DEFINES)) $(word $(1),$(TOP_DEFINES)) $(word $(1),$(VCD_DEFINES)) -o $(word $(1),$(POST_SYNTH)).vvp $(word $(1),$(POST_SYNTH)).v $(SIM_LIBS) $(TESTBENCH) > $(word $(1),$(POST_SYNTH)).vvp.log 2>&1
+	@vvp -vvvv $(word $(1),$(POST_SYNTH)).vvp > $(word $(1),$(POST_SYNTH)).vcd.log 2>&1
+endef
+
+define clean_post_synth_sim
+	@rm -rf  $(word $(1),$(POST_SYNTH)).vcd $(word $(1),$(POST_SYNTH)).vvp $(word $(1),$(POST_SYNTH)).vvp.log $(word $(1),$(POST_SYNTH)).vcd.log
+endef
+
+# FIXME: $(call simulate_post_synth,5)
+sim:
+	$(call simulate_post_synth,1)
+	$(call clean_post_synth_sim,1)
+	$(call simulate_post_synth,2)
+	$(call clean_post_synth_sim,2)
+	$(call simulate_post_synth,3)
+	$(call clean_post_synth_sim,3)
\ No newline at end of file
diff --git a/ql-qlf-plugin/tests/qlf_k6n10f/bram36k_afifo/sim/bram36k_afifo_tb.v b/ql-qlf-plugin/tests/qlf_k6n10f/bram36k_afifo/sim/bram36k_afifo_tb.v
new file mode 100644
index 0000000..addf547
--- /dev/null
+++ b/ql-qlf-plugin/tests/qlf_k6n10f/bram36k_afifo/sim/bram36k_afifo_tb.v
@@ -0,0 +1,177 @@
+// Copyright 2020-2022 F4PGA Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: Apache-2.0
+
+`timescale 1ns/1ps
+
+`define STRINGIFY(x) `"x`"
+
+module TB;
+	localparam PERIOD = 30;
+	localparam ADDR_INCR = 1;
+
+	reg clk0;
+  reg clk1;
+  reg flush;
+	reg pop;
+	wire [`DATA_WIDTH1-1:0] dout;
+	reg push;
+	reg [`DATA_WIDTH0-1:0] din;
+  wire almost_full,almost_empty;
+  wire full, empty;
+  wire full_watermark, empty_watermark;
+  wire overrun_error, underrun_error;
+
+  initial 
+  begin
+    clk0 = 0;
+    clk1 = 0;
+    pop = 0;
+    push = 0;
+    flush = 1;
+    din = 0;
+    #40
+    flush = 0;
+  end
+  
+	initial forever #(PERIOD / 3.0) clk0 = ~clk0;
+  initial forever #(PERIOD / 2.0) clk1 = ~clk1;
+  
+	initial begin
+		$dumpfile(`STRINGIFY(`VCD));
+		$dumpvars;
+	end
+
+	integer a;
+
+	reg done;
+	initial done = 1'b0;
+  
+  reg read_test;
+	initial read_test = 0;
+
+	reg [`DATA_WIDTH1-1:0] expected;
+  initial expected = 0;
+
+	always @(posedge clk1) begin
+		expected <= (a | (a << 20) | 20'h55000) & {`DATA_WIDTH1{1'b1}};
+	end
+
+	wire error = ((a != 0) && read_test) ? dout !== expected : 0;
+
+	integer error_cnt = 0;
+	always @ (posedge clk1)
+	begin
+		if (error)
+			error_cnt <= error_cnt + 1'b1; 
+	end
+
+
+	initial #(50) begin
+    @(posedge clk0)
+		// Write data
+		for (a = 0; a < (1<<`ADDR_WIDTH0); a = a + ADDR_INCR) begin
+			@(negedge clk0) begin
+				din = a | (a << 20) | 20'h55000;
+				push = 1;
+			end
+			@(posedge clk0) begin
+				#(PERIOD/10) push = 0;
+			end
+		end
+		// Read data
+		read_test = 1;
+		for (a = 0; a < (1<<`ADDR_WIDTH1); a = a + ADDR_INCR) begin
+			@(posedge clk1) begin
+				#(PERIOD/10) pop = 0;
+				if ( dout !== expected) begin
+					$display("%d: FAIL: mismatch act=%x exp=%x at %x", $time, dout, expected, a);
+				end else begin
+					$display("%d: OK: act=%x exp=%x at %x", $time, dout, expected, a);
+				end
+			end
+			@(negedge clk1) begin
+				pop = 1;
+			end
+		end
+		done = 1'b1;
+	end
+
+	// Scan for simulation finish
+	always @(posedge clk1) begin
+		if (done)
+			$finish_and_return( (error_cnt == 0) ? 0 : -1 );
+	end
+
+	case (`STRINGIFY(`TOP))
+		"af1024x36_1024x36": begin
+			af1024x36_1024x36 #() afifo (
+        .DIN(din),
+        .PUSH(push),
+        .POP(pop),
+        .clock0(clk0),
+        .clock1(clk1),
+        .Async_Flush(flush),
+        .Almost_Full(almost_full),
+        .Almost_Empty(almost_empty),
+        .Full(full),
+        .Empty(empty),
+        .Full_Watermark(full_watermark),
+        .Empty_Watermark(empty_watermark),
+        .Overrun_Error(overrun_error),
+        .Underrun_Error(underrun_error),
+        .DOUT(dout)
+			);
+		end
+		"af2048x18_2048x18": begin
+			af2048x18_2048x18 #() afifo (
+        .DIN(din),
+        .PUSH(push),
+        .POP(pop),
+        .clock0(clk0),
+        .clock1(clk1),
+        .Async_Flush(flush),
+        .Almost_Full(almost_full),
+        .Almost_Empty(almost_empty),
+        .Full(full),
+        .Empty(empty),
+        .Full_Watermark(full_watermark),
+        .Empty_Watermark(empty_watermark),
+        .Overrun_Error(overrun_error),
+        .Underrun_Error(underrun_error),
+        .DOUT(dout)
+			);
+		end
+		"af4096x9_4096x9": begin
+			af4096x9_4096x9 #() afifo (
+        .DIN(din),
+        .PUSH(push),
+        .POP(pop),
+        .clock0(clk0),
+        .clock1(clk1),
+        .Async_Flush(flush),
+        .Almost_Full(almost_full),
+        .Almost_Empty(almost_empty),
+        .Full(full),
+        .Empty(empty),
+        .Full_Watermark(full_watermark),
+        .Empty_Watermark(empty_watermark),
+        .Overrun_Error(overrun_error),
+        .Underrun_Error(underrun_error),
+        .DOUT(dout)
+			);
+		end		
+	endcase
+endmodule
diff --git a/ql-qlf-plugin/tests/qlf_k6n10f/bram36k_sdp/bram36k_sdp.tcl b/ql-qlf-plugin/tests/qlf_k6n10f/bram36k_sdp/bram36k_sdp.tcl
new file mode 100644
index 0000000..b5d38b0
--- /dev/null
+++ b/ql-qlf-plugin/tests/qlf_k6n10f/bram36k_sdp/bram36k_sdp.tcl
@@ -0,0 +1,71 @@
+yosys -import
+
+if { [info procs ql-qlf-k6n10f] == {} } { plugin -i ql-qlf }
+yosys -import  ;
+
+read_verilog $::env(DESIGN_TOP).v
+design -save bram36_sdp
+
+select spram_36x1024
+select *
+synth_quicklogic -family qlf_k6n10f -top spram_36x1024 -bram_types
+opt_expr -undriven
+opt_clean
+stat
+write_verilog sim/spram_36x1024_post_synth.v
+select -assert-count 1 t:TDP36K_BRAM_WR_X36_RD_X36_nonsplit
+
+select -clear
+design -load bram36_sdp
+select spram_32x1024
+select *
+synth_quicklogic -family qlf_k6n10f -top spram_32x1024 -bram_types
+opt_expr -undriven
+opt_clean
+stat
+write_verilog sim/spram_32x1024_post_synth.v
+select -assert-count 1 t:TDP36K_BRAM_WR_X36_RD_X36_nonsplit
+
+select -clear
+design -load bram36_sdp
+select spram_18x2048
+select *
+synth_quicklogic -family qlf_k6n10f -top spram_18x2048 -bram_types
+opt_expr -undriven
+opt_clean
+stat
+write_verilog sim/spram_18x2048_post_synth.v
+select -assert-count 1 t:TDP36K_BRAM_WR_X18_RD_X18_nonsplit
+
+select -clear
+design -load bram36_sdp
+select spram_16x2048
+select *
+synth_quicklogic -family qlf_k6n10f -top spram_16x2048 -bram_types
+opt_expr -undriven
+opt_clean
+stat
+write_verilog sim/spram_16x2048_post_synth.v
+select -assert-count 1 t:TDP36K_BRAM_WR_X18_RD_X18_nonsplit
+
+select -clear
+design -load bram36_sdp
+select spram_9x4096
+select *
+synth_quicklogic -family qlf_k6n10f -top spram_9x4096 -bram_types
+opt_expr -undriven
+opt_clean
+stat
+write_verilog sim/spram_9x4096_post_synth.v
+select -assert-count 1 t:TDP36K_BRAM_WR_X9_RD_X9_nonsplit
+
+select -clear
+design -load bram36_sdp
+select spram_8x4096
+select *
+synth_quicklogic -family qlf_k6n10f -top spram_8x4096 -bram_types
+opt_expr -undriven
+opt_clean
+stat
+write_verilog sim/spram_8x4096_post_synth.v
+select -assert-count 1 t:TDP36K_BRAM_WR_X9_RD_X9_nonsplit
diff --git a/ql-qlf-plugin/tests/qlf_k6n10f/bram36k_sdp/bram36k_sdp.v b/ql-qlf-plugin/tests/qlf_k6n10f/bram36k_sdp/bram36k_sdp.v
new file mode 100644
index 0000000..3860511
--- /dev/null
+++ b/ql-qlf-plugin/tests/qlf_k6n10f/bram36k_sdp/bram36k_sdp.v
@@ -0,0 +1,281 @@
+module spram_36x1024 (
+    WEN_i,
+    REN_i,
+    clock0,
+    clock1,
+    WR_ADDR_i,
+    RD_ADDR_i,
+    WDATA_i,
+    RDATA_o
+);
+
+parameter WR_ADDR_WIDTH = 10;
+parameter RD_ADDR_WIDTH = 10;
+parameter WR_DATA_WIDTH = 36;
+parameter RD_DATA_WIDTH = 36;
+parameter BE_WIDTH = 4;
+
+input wire WEN_i;
+input wire REN_i;
+input wire clock0;
+input wire clock1;
+input wire [WR_ADDR_WIDTH-1 :0] WR_ADDR_i;
+input wire [RD_ADDR_WIDTH-1 :0] RD_ADDR_i;
+input wire [WR_DATA_WIDTH-1 :0] WDATA_i;
+output wire [RD_DATA_WIDTH-1 :0] RDATA_o;
+
+RAM_36K_BLK #(
+              .WR_ADDR_WIDTH(WR_ADDR_WIDTH),
+              .RD_ADDR_WIDTH(RD_ADDR_WIDTH),
+              .WR_DATA_WIDTH(WR_DATA_WIDTH),
+              .RD_DATA_WIDTH(RD_DATA_WIDTH),
+              .BE_WIDTH(BE_WIDTH)
+              ) spram_x36_inst (
+              
+              .WEN_i(WEN_i),
+              .WR_BE_i(4'b1111),
+              .REN_i(REN_i),              
+              .WR_CLK_i(clock0),
+              .RD_CLK_i(clock1),
+              .WR_ADDR_i(WR_ADDR_i),
+              .RD_ADDR_i(RD_ADDR_i),
+              .WDATA_i(WDATA_i),
+              .RDATA_o(RDATA_o)
+              );
+              
+endmodule    
+
+module spram_32x1024 (
+    WEN_i,
+    REN_i,
+    clock0,
+    clock1,
+    WR_ADDR_i,
+    RD_ADDR_i,
+    WDATA_i,
+    RDATA_o
+);
+
+parameter WR_ADDR_WIDTH = 10;
+parameter RD_ADDR_WIDTH = 10;
+parameter WR_DATA_WIDTH = 32;
+parameter RD_DATA_WIDTH = 32;
+parameter BE_WIDTH = 4;
+
+input wire WEN_i;
+input wire REN_i;
+input wire clock0;
+input wire clock1;
+input wire [WR_ADDR_WIDTH-1 :0] WR_ADDR_i;
+input wire [RD_ADDR_WIDTH-1 :0] RD_ADDR_i;
+input wire [WR_DATA_WIDTH-1 :0] WDATA_i;
+output wire [RD_DATA_WIDTH-1 :0] RDATA_o;
+
+RAM_36K_BLK #(
+              .WR_ADDR_WIDTH(WR_ADDR_WIDTH),
+              .RD_ADDR_WIDTH(RD_ADDR_WIDTH),
+              .WR_DATA_WIDTH(WR_DATA_WIDTH),
+              .RD_DATA_WIDTH(RD_DATA_WIDTH),
+              .BE_WIDTH(BE_WIDTH)
+              ) spram_x36_inst (
+              
+              .WEN_i(WEN_i),
+              .WR_BE_i(4'b1111),
+              .REN_i(REN_i),              
+              .WR_CLK_i(clock0),
+              .RD_CLK_i(clock1),
+              .WR_ADDR_i(WR_ADDR_i),
+              .RD_ADDR_i(RD_ADDR_i),
+              .WDATA_i(WDATA_i),
+              .RDATA_o(RDATA_o)
+              );
+              
+endmodule   
+
+module spram_18x2048 (
+    WEN_i,
+    REN_i,
+    clock0,
+    clock1,
+    WR_ADDR_i,
+    RD_ADDR_i,
+    WDATA_i,
+    RDATA_o
+);
+
+parameter WR_ADDR_WIDTH = 11;
+parameter RD_ADDR_WIDTH = 11;
+parameter WR_DATA_WIDTH = 18;
+parameter RD_DATA_WIDTH = 18;
+parameter BE_WIDTH = 2;
+
+input wire WEN_i;
+input wire REN_i;
+input wire clock0;
+input wire clock1;
+input wire [WR_ADDR_WIDTH-1 :0] WR_ADDR_i;
+input wire [RD_ADDR_WIDTH-1 :0] RD_ADDR_i;
+input wire [WR_DATA_WIDTH-1 :0] WDATA_i;
+output wire [RD_DATA_WIDTH-1 :0] RDATA_o;
+
+RAM_36K_BLK #(
+              .WR_ADDR_WIDTH(WR_ADDR_WIDTH),
+              .RD_ADDR_WIDTH(RD_ADDR_WIDTH),
+              .WR_DATA_WIDTH(WR_DATA_WIDTH),
+              .RD_DATA_WIDTH(RD_DATA_WIDTH),
+              .BE_WIDTH(BE_WIDTH)
+              ) spram_x36_inst (
+              
+              .WEN_i(WEN_i),
+              .WR_BE_i(2'b11),
+              .REN_i(REN_i),              
+              .WR_CLK_i(clock0),
+              .RD_CLK_i(clock1),
+              .WR_ADDR_i(WR_ADDR_i),
+              .RD_ADDR_i(RD_ADDR_i),
+              .WDATA_i(WDATA_i),
+              .RDATA_o(RDATA_o)
+              );
+              
+endmodule    
+
+module spram_16x2048 (
+    WEN_i,
+    REN_i,
+    clock0,
+    clock1,
+    WR_ADDR_i,
+    RD_ADDR_i,
+    WDATA_i,
+    RDATA_o
+);
+
+parameter WR_ADDR_WIDTH = 11;
+parameter RD_ADDR_WIDTH = 11;
+parameter WR_DATA_WIDTH = 16;
+parameter RD_DATA_WIDTH = 16;
+parameter BE_WIDTH = 2;
+
+input wire WEN_i;
+input wire REN_i;
+input wire clock0;
+input wire clock1;
+input wire [WR_ADDR_WIDTH-1 :0] WR_ADDR_i;
+input wire [RD_ADDR_WIDTH-1 :0] RD_ADDR_i;
+input wire [WR_DATA_WIDTH-1 :0] WDATA_i;
+output wire [RD_DATA_WIDTH-1 :0] RDATA_o;
+
+RAM_36K_BLK #(
+              .WR_ADDR_WIDTH(WR_ADDR_WIDTH),
+              .RD_ADDR_WIDTH(RD_ADDR_WIDTH),
+              .WR_DATA_WIDTH(WR_DATA_WIDTH),
+              .RD_DATA_WIDTH(RD_DATA_WIDTH),
+              .BE_WIDTH(BE_WIDTH)
+              ) spram_x36_inst (
+              
+              .WEN_i(WEN_i),
+              .WR_BE_i(2'b11),
+              .REN_i(REN_i),              
+              .WR_CLK_i(clock0),
+              .RD_CLK_i(clock1),
+              .WR_ADDR_i(WR_ADDR_i),
+              .RD_ADDR_i(RD_ADDR_i),
+              .WDATA_i(WDATA_i),
+              .RDATA_o(RDATA_o)
+              );
+              
+endmodule    
+
+module spram_9x4096 (
+    WEN_i,
+    REN_i,
+    clock0,
+    clock1,
+    WR_ADDR_i,
+    RD_ADDR_i,
+    WDATA_i,
+    RDATA_o
+);
+
+parameter WR_ADDR_WIDTH = 12;
+parameter RD_ADDR_WIDTH = 12;
+parameter WR_DATA_WIDTH = 9;
+parameter RD_DATA_WIDTH = 9;
+parameter BE_WIDTH = 1;
+
+input wire WEN_i;
+input wire REN_i;
+input wire clock0;
+input wire clock1;
+input wire [WR_ADDR_WIDTH-1 :0] WR_ADDR_i;
+input wire [RD_ADDR_WIDTH-1 :0] RD_ADDR_i;
+input wire [WR_DATA_WIDTH-1 :0] WDATA_i;
+output wire [RD_DATA_WIDTH-1 :0] RDATA_o;
+
+RAM_36K_BLK #(
+              .WR_ADDR_WIDTH(WR_ADDR_WIDTH),
+              .RD_ADDR_WIDTH(RD_ADDR_WIDTH),
+              .WR_DATA_WIDTH(WR_DATA_WIDTH),
+              .RD_DATA_WIDTH(RD_DATA_WIDTH),
+              .BE_WIDTH(BE_WIDTH)
+              ) spram_x36_inst (
+              
+              .WEN_i(WEN_i),
+              .WR_BE_i(1'b1),
+              .REN_i(REN_i),              
+              .WR_CLK_i(clock0),
+              .RD_CLK_i(clock1),
+              .WR_ADDR_i(WR_ADDR_i),
+              .RD_ADDR_i(RD_ADDR_i),
+              .WDATA_i(WDATA_i),
+              .RDATA_o(RDATA_o)
+              );
+              
+endmodule    
+
+module spram_8x4096 (
+    WEN_i,
+    REN_i,
+    clock0,
+    clock1,
+    WR_ADDR_i,
+    RD_ADDR_i,
+    WDATA_i,
+    RDATA_o
+);
+
+parameter WR_ADDR_WIDTH = 12;
+parameter RD_ADDR_WIDTH = 12;
+parameter WR_DATA_WIDTH = 8;
+parameter RD_DATA_WIDTH = 8;
+parameter BE_WIDTH = 1;
+
+input wire WEN_i;
+input wire REN_i;
+input wire clock0;
+input wire clock1;
+input wire [WR_ADDR_WIDTH-1 :0] WR_ADDR_i;
+input wire [RD_ADDR_WIDTH-1 :0] RD_ADDR_i;
+input wire [WR_DATA_WIDTH-1 :0] WDATA_i;
+output wire [RD_DATA_WIDTH-1 :0] RDATA_o;
+
+RAM_36K_BLK #(
+              .WR_ADDR_WIDTH(WR_ADDR_WIDTH),
+              .RD_ADDR_WIDTH(RD_ADDR_WIDTH),
+              .WR_DATA_WIDTH(WR_DATA_WIDTH),
+              .RD_DATA_WIDTH(RD_DATA_WIDTH),
+              .BE_WIDTH(BE_WIDTH)
+              ) spram_x36_inst (
+              
+              .WEN_i(WEN_i),
+              .WR_BE_i(1'b1),
+              .REN_i(REN_i),              
+              .WR_CLK_i(clock0),
+              .RD_CLK_i(clock1),
+              .WR_ADDR_i(WR_ADDR_i),
+              .RD_ADDR_i(RD_ADDR_i),
+              .WDATA_i(WDATA_i),
+              .RDATA_o(RDATA_o)
+              );
+              
+endmodule    
\ No newline at end of file
diff --git a/ql-qlf-plugin/tests/qlf_k6n10f/bram36k_sdp/sim/Makefile b/ql-qlf-plugin/tests/qlf_k6n10f/bram36k_sdp/sim/Makefile
new file mode 100644
index 0000000..ca7d1af
--- /dev/null
+++ b/ql-qlf-plugin/tests/qlf_k6n10f/bram36k_sdp/sim/Makefile
@@ -0,0 +1,51 @@
+# Copyright 2020-2022 F4PGA Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-License-Identifier: Apache-2.0
+
+TESTBENCH = bram36k_sdp_tb.v
+POST_SYNTH = spram_36x1024_post_synth spram_32x1024_post_synth spram_18x2048_post_synth spram_16x2048_post_synth spram_9x4096_post_synth spram_8x4096_post_synth
+ADDR_WIDTH = 10 10 11 11 12 12
+DATA_WIDTH = 36 32 18 16 9 8
+TOP = spram_36x1024 spram_32x1024 spram_18x2048 spram_16x2048 spram_9x4096 spram_8x4096
+ADDR_DEFINES = $(foreach awidth, $(ADDR_WIDTH),-DADDR_WIDTH="$(awidth)")
+DATA_DEFINES = $(foreach dwidth, $(DATA_WIDTH),-DDATA_WIDTH="$(dwidth)")
+TOP_DEFINES = $(foreach top, $(TOP),-DTOP="$(top)")
+VCD_DEFINES = $(foreach vcd, $(POST_SYNTH),-DVCD="$(vcd).vcd")
+
+SIM_LIBS = $(shell find ../../../../qlf_k6n10f -name "*.v" -not -name "*_map.v")
+
+define simulate_post_synth
+	@iverilog  -vvvv -g2005 $(word $(1),$(ADDR_DEFINES)) $(word $(1),$(DATA_DEFINES)) $(word $(1),$(TOP_DEFINES)) $(word $(1),$(VCD_DEFINES)) -o $(word $(1),$(POST_SYNTH)).vvp $(word $(1),$(POST_SYNTH)).v $(SIM_LIBS) $(TESTBENCH) > $(word $(1),$(POST_SYNTH)).vvp.log 2>&1
+	@vvp -vvvv $(word $(1),$(POST_SYNTH)).vvp > $(word $(1),$(POST_SYNTH)).vcd.log 2>&1
+endef
+
+define clean_post_synth_sim
+	@rm -rf  $(word $(1),$(POST_SYNTH)).vcd $(word $(1),$(POST_SYNTH)).vvp $(word $(1),$(POST_SYNTH)).vvp.log $(word $(1),$(POST_SYNTH)).vcd.log
+endef
+
+# FIXME: $(call simulate_post_synth,5)
+sim:
+	$(call simulate_post_synth,1)
+	$(call clean_post_synth_sim,1)
+	$(call simulate_post_synth,2)
+	$(call clean_post_synth_sim,2)
+	$(call simulate_post_synth,3)
+	$(call clean_post_synth_sim,3)
+	$(call simulate_post_synth,4)
+	$(call clean_post_synth_sim,4)
+	$(call simulate_post_synth,5)
+	$(call clean_post_synth_sim,5)
+	$(call simulate_post_synth,6)
+	$(call clean_post_synth_sim,6)
\ No newline at end of file
diff --git a/ql-qlf-plugin/tests/qlf_k6n10f/bram36k_sdp/sim/bram36k_sdp_tb.v b/ql-qlf-plugin/tests/qlf_k6n10f/bram36k_sdp/sim/bram36k_sdp_tb.v
new file mode 100644
index 0000000..1c003ec
--- /dev/null
+++ b/ql-qlf-plugin/tests/qlf_k6n10f/bram36k_sdp/sim/bram36k_sdp_tb.v
@@ -0,0 +1,176 @@
+// Copyright 2020-2022 F4PGA Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: Apache-2.0
+
+`timescale 1ns/1ps
+
+`define STRINGIFY(x) `"x`"
+
+module TB;
+	localparam PERIOD = 50;
+	localparam ADDR_INCR = 1;
+
+	reg clk;
+	reg rce;
+	reg [`ADDR_WIDTH-1:0] ra;
+	wire [`DATA_WIDTH-1:0] rq;
+	reg wce;
+	reg [`ADDR_WIDTH-1:0] wa;
+	reg [`DATA_WIDTH-1:0] wd;
+
+	initial clk = 0;
+	initial ra = 0;
+	initial rce = 0;
+	initial forever #(PERIOD / 2.0) clk = ~clk;
+	initial begin
+		$dumpfile(`STRINGIFY(`VCD));
+		$dumpvars;
+	end
+
+	integer a;
+
+	reg done;
+	initial done = 1'b0;
+
+	reg [`DATA_WIDTH-1:0] expected;
+
+	always @(posedge clk) begin
+		expected <= (a | (a << 20) | 20'h55000) & {`DATA_WIDTH{1'b1}};
+	end
+
+	wire error = ((a != 0) && read_test) ? rq !== expected : 0;
+
+	integer error_cnt = 0;
+	always @ (posedge clk)
+	begin
+		if (error)
+			error_cnt <= error_cnt + 1'b1;
+	end
+
+	reg read_test;
+	initial read_test = 0;
+
+	initial #(1) begin
+		// Write data
+		for (a = 0; a < (1<<`ADDR_WIDTH); a = a + ADDR_INCR) begin
+			@(negedge clk) begin
+				wa = a;
+				wd = a | (a << 20) | 20'h55000;
+				wce = 1;
+			end
+			@(posedge clk) begin
+				#(PERIOD/10) wce = 0;
+			end
+		end
+		// Read data
+		read_test = 1;
+		for (a = 0; a < (1<<`ADDR_WIDTH); a = a + ADDR_INCR) begin
+			@(negedge clk) begin
+				ra = a;
+				rce = 1;
+			end
+			@(posedge clk) begin
+				#(PERIOD/10) rce = 0;
+				if ( rq !== expected) begin
+					$display("%d: FAIL: mismatch act=%x exp=%x at %x", $time, rq, expected, a);
+				end else begin
+					$display("%d: OK: act=%x exp=%x at %x", $time, rq, expected, a);
+				end
+			end
+		end
+		done = 1'b1;
+	end
+
+	// Scan for simulation finish
+	always @(posedge clk) begin
+		if (done)
+			$finish_and_return( (error_cnt == 0) ? 0 : -1 );
+	end
+
+	case (`STRINGIFY(`TOP))
+		"spram_36x1024": begin
+			spram_36x1024 #() bram (
+				.clock0(clk),
+        .clock1(clk),        
+				.REN_i(rce),
+				.RD_ADDR_i(ra),
+				.RDATA_o(rq),
+				.WEN_i(wce),
+				.WR_ADDR_i(wa),
+				.WDATA_i(wd)
+			);
+		end
+		"spram_32x1024": begin
+			spram_32x1024 #() bram (
+				.clock0(clk),
+        .clock1(clk),        
+				.REN_i(rce),
+				.RD_ADDR_i(ra),
+				.RDATA_o(rq),
+				.WEN_i(wce),
+				.WR_ADDR_i(wa),
+				.WDATA_i(wd)
+			);
+		end
+		"spram_18x2048": begin
+			spram_18x2048 #() bram (
+				.clock0(clk),
+        .clock1(clk),        
+				.REN_i(rce),
+				.RD_ADDR_i(ra),
+				.RDATA_o(rq),
+				.WEN_i(wce),
+				.WR_ADDR_i(wa),
+				.WDATA_i(wd)
+			);
+		end
+		"spram_16x2048": begin
+			spram_16x2048 #() bram (
+				.clock0(clk),
+        .clock1(clk),        
+				.REN_i(rce),
+				.RD_ADDR_i(ra),
+				.RDATA_o(rq),
+				.WEN_i(wce),
+				.WR_ADDR_i(wa),
+				.WDATA_i(wd)
+			);
+		end
+		"spram_9x4096": begin
+			spram_9x4096 #() bram (
+				.clock0(clk),
+        .clock1(clk),        
+				.REN_i(rce),
+				.RD_ADDR_i(ra),
+				.RDATA_o(rq),
+				.WEN_i(wce),
+				.WR_ADDR_i(wa),
+				.WDATA_i(wd)
+			);
+		end
+		"spram_8x4096": begin
+			spram_8x4096 #() bram (
+				.clock0(clk),
+        .clock1(clk),        
+				.REN_i(rce),
+				.RD_ADDR_i(ra),
+				.RDATA_o(rq),
+				.WEN_i(wce),
+				.WR_ADDR_i(wa),
+				.WDATA_i(wd)
+			);
+		end
+	endcase
+endmodule
diff --git a/ql-qlf-plugin/tests/qlf_k6n10f/bram36k_sfifo/bram36k_sfifo.tcl b/ql-qlf-plugin/tests/qlf_k6n10f/bram36k_sfifo/bram36k_sfifo.tcl
new file mode 100644
index 0000000..8ffd95f
--- /dev/null
+++ b/ql-qlf-plugin/tests/qlf_k6n10f/bram36k_sfifo/bram36k_sfifo.tcl
@@ -0,0 +1,38 @@
+yosys -import
+
+if { [info procs ql-qlf-k6n10f] == {} } { plugin -i ql-qlf }
+yosys -import  ;
+
+read_verilog $::env(DESIGN_TOP).v
+design -save bram36k_sfifo
+
+select f1024x36_1024x36
+select *
+synth_quicklogic -family qlf_k6n10f -top f1024x36_1024x36 -bram_types
+opt_expr -undriven
+opt_clean
+stat
+write_verilog sim/f1024x36_1024x36_post_synth.v
+select -assert-count 1 t:TDP36K_FIFO_SYNC_WR_X36_RD_X36_nonsplit
+
+select -clear
+design -load bram36k_sfifo
+select f2048x18_2048x18
+select *
+synth_quicklogic -family qlf_k6n10f -top f2048x18_2048x18 -bram_types
+opt_expr -undriven
+opt_clean
+stat
+write_verilog sim/f2048x18_2048x18_post_synth.v
+select -assert-count 1 t:TDP36K_FIFO_SYNC_WR_X18_RD_X18_nonsplit
+
+select -clear
+design -load bram36k_sfifo
+select f4096x9_4096x9
+select *
+synth_quicklogic -family qlf_k6n10f -top f4096x9_4096x9 -bram_types
+opt_expr -undriven
+opt_clean
+stat
+write_verilog sim/f4096x9_4096x9_post_synth.v
+select -assert-count 1 t:TDP36K_FIFO_SYNC_WR_X9_RD_X9_nonsplit
diff --git a/ql-qlf-plugin/tests/qlf_k6n10f/bram36k_sfifo/bram36k_sfifo.v b/ql-qlf-plugin/tests/qlf_k6n10f/bram36k_sfifo/bram36k_sfifo.v
new file mode 100644
index 0000000..7cb07fa
--- /dev/null
+++ b/ql-qlf-plugin/tests/qlf_k6n10f/bram36k_sfifo/bram36k_sfifo.v
@@ -0,0 +1,122 @@
+module f1024x36_1024x36 (DIN,PUSH,POP,clock0,Async_Flush,Almost_Full,Almost_Empty,Full,Empty,Full_Watermark,Empty_Watermark,Overrun_Error,Underrun_Error,DOUT);
+
+parameter WR_DATA_WIDTH = 36;
+parameter RD_DATA_WIDTH = 36;
+parameter UPAE_DBITS = 12'd10;
+parameter UPAF_DBITS = 12'd10;
+
+input clock0;
+input PUSH,POP;
+input [WR_DATA_WIDTH-1:0] DIN;
+input Async_Flush;
+output [RD_DATA_WIDTH-1:0] DOUT;
+output Almost_Full,Almost_Empty;
+output Full, Empty;
+output Full_Watermark, Empty_Watermark;
+output Overrun_Error, Underrun_Error;
+
+SFIFO_36K_BLK  # (.WR_DATA_WIDTH(WR_DATA_WIDTH),.RD_DATA_WIDTH(RD_DATA_WIDTH),.UPAE_DBITS(UPAE_DBITS),.UPAF_DBITS(UPAF_DBITS)
+        				 ) 
+  FIFO_INST    (
+                .DIN(DIN),
+                .PUSH(PUSH),
+                .POP(POP),
+                .CLK(clock0),
+                .Async_Flush(Async_Flush),
+                
+                .Overrun_Error(Overrun_Error),
+                .Full_Watermark(Full_Watermark),
+                .Almost_Full(Almost_Full),
+                .Full(Full),
+                
+                .Underrun_Error(Underrun_Error),
+                .Empty_Watermark(Empty_Watermark),
+                .Almost_Empty(Almost_Empty),
+                .Empty(Empty),
+
+                .DOUT(DOUT)
+         				);
+
+endmodule
+
+module f2048x18_2048x18 (DIN,PUSH,POP,clock0,Async_Flush,Almost_Full,Almost_Empty,Full,Empty,Full_Watermark,Empty_Watermark,Overrun_Error,Underrun_Error,DOUT);
+
+parameter WR_DATA_WIDTH = 18;
+parameter RD_DATA_WIDTH = 18;
+parameter UPAE_DBITS = 12'd10;
+parameter UPAF_DBITS = 12'd10;
+
+input clock0;
+input PUSH,POP;
+input [WR_DATA_WIDTH-1:0] DIN;
+input Async_Flush;
+output [RD_DATA_WIDTH-1:0] DOUT;
+output Almost_Full,Almost_Empty;
+output Full, Empty;
+output Full_Watermark, Empty_Watermark;
+output Overrun_Error, Underrun_Error;
+
+SFIFO_36K_BLK  # (.WR_DATA_WIDTH(WR_DATA_WIDTH),.RD_DATA_WIDTH(RD_DATA_WIDTH),.UPAE_DBITS(UPAE_DBITS),.UPAF_DBITS(UPAF_DBITS)
+        				 ) 
+  FIFO_INST    (
+                .DIN(DIN),
+                .PUSH(PUSH),
+                .POP(POP),
+                .CLK(clock0),
+                .Async_Flush(Async_Flush),
+                
+                .Overrun_Error(Overrun_Error),
+                .Full_Watermark(Full_Watermark),
+                .Almost_Full(Almost_Full),
+                .Full(Full),
+                
+                .Underrun_Error(Underrun_Error),
+                .Empty_Watermark(Empty_Watermark),
+                .Almost_Empty(Almost_Empty),
+                .Empty(Empty),
+
+                .DOUT(DOUT)
+         				);
+
+endmodule
+
+module f4096x9_4096x9 (DIN,PUSH,POP,clock0,Async_Flush,Almost_Full,Almost_Empty,Full,Empty,Full_Watermark,Empty_Watermark,Overrun_Error,Underrun_Error,DOUT);
+
+parameter WR_DATA_WIDTH = 9;
+parameter RD_DATA_WIDTH = 9;
+parameter UPAE_DBITS = 12'd10;
+parameter UPAF_DBITS = 12'd10;
+
+input clock0;
+input PUSH,POP;
+input [WR_DATA_WIDTH-1:0] DIN;
+input Async_Flush;
+output [RD_DATA_WIDTH-1:0] DOUT;
+output Almost_Full,Almost_Empty;
+output Full, Empty;
+output Full_Watermark, Empty_Watermark;
+output Overrun_Error, Underrun_Error;
+
+SFIFO_36K_BLK  # (.WR_DATA_WIDTH(WR_DATA_WIDTH),.RD_DATA_WIDTH(RD_DATA_WIDTH),.UPAE_DBITS(UPAE_DBITS),.UPAF_DBITS(UPAF_DBITS)
+        				 ) 
+  FIFO_INST    (
+                .DIN(DIN),
+                .PUSH(PUSH),
+                .POP(POP),
+                .CLK(clock0),
+                .Async_Flush(Async_Flush),
+                
+                .Overrun_Error(Overrun_Error),
+                .Full_Watermark(Full_Watermark),
+                .Almost_Full(Almost_Full),
+                .Full(Full),
+                
+                .Underrun_Error(Underrun_Error),
+                .Empty_Watermark(Empty_Watermark),
+                .Almost_Empty(Almost_Empty),
+                .Empty(Empty),
+
+                .DOUT(DOUT)
+         				);
+
+endmodule
\ No newline at end of file
diff --git a/ql-qlf-plugin/tests/qlf_k6n10f/bram36k_sfifo/sim/Makefile b/ql-qlf-plugin/tests/qlf_k6n10f/bram36k_sfifo/sim/Makefile
new file mode 100644
index 0000000..1cb26f3
--- /dev/null
+++ b/ql-qlf-plugin/tests/qlf_k6n10f/bram36k_sfifo/sim/Makefile
@@ -0,0 +1,49 @@
+# Copyright 2020-2022 F4PGA Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-License-Identifier: Apache-2.0
+
+TESTBENCH = bram36k_sfifo_tb.v
+POST_SYNTH = f1024x36_1024x36_post_synth f2048x18_2048x18_post_synth f4096x9_4096x9_post_synth
+ADDR_WIDTH0 = 10 11 12
+DATA_WIDTH0 = 36 18 9
+ADDR_WIDTH1 = 10 11 12
+DATA_WIDTH1 = 36 18 9
+TOP = f1024x36_1024x36 f2048x18_2048x18 f4096x9_4096x9
+ADDR0_DEFINES = $(foreach awidth0, $(ADDR_WIDTH0),-DADDR_WIDTH0="$(awidth0)")
+ADDR1_DEFINES = $(foreach awidth1, $(ADDR_WIDTH1),-DADDR_WIDTH1="$(awidth1)")
+DATA0_DEFINES = $(foreach dwidth0, $(DATA_WIDTH0),-DDATA_WIDTH0="$(dwidth0)")
+DATA1_DEFINES = $(foreach dwidth1, $(DATA_WIDTH1),-DDATA_WIDTH1="$(dwidth1)")
+TOP_DEFINES = $(foreach top, $(TOP),-DTOP="$(top)")
+VCD_DEFINES = $(foreach vcd, $(POST_SYNTH),-DVCD="$(vcd).vcd")
+
+SIM_LIBS = $(shell find ../../../../qlf_k6n10f -name "*.v" -not -name "*_map.v")
+
+define simulate_post_synth
+	@iverilog  -vvvv -g2005 $(word $(1),$(ADDR0_DEFINES)) $(word $(1),$(ADDR1_DEFINES)) $(word $(1),$(DATA0_DEFINES)) $(word $(1),$(DATA1_DEFINES)) $(word $(1),$(TOP_DEFINES)) $(word $(1),$(VCD_DEFINES)) -o $(word $(1),$(POST_SYNTH)).vvp $(word $(1),$(POST_SYNTH)).v $(SIM_LIBS) $(TESTBENCH) > $(word $(1),$(POST_SYNTH)).vvp.log 2>&1
+	@vvp -vvvv $(word $(1),$(POST_SYNTH)).vvp > $(word $(1),$(POST_SYNTH)).vcd.log 2>&1
+endef
+
+define clean_post_synth_sim
+	@rm -rf  $(word $(1),$(POST_SYNTH)).vcd $(word $(1),$(POST_SYNTH)).vvp $(word $(1),$(POST_SYNTH)).vvp.log $(word $(1),$(POST_SYNTH)).vcd.log
+endef
+
+# FIXME: $(call simulate_post_synth,5)
+sim:
+	$(call simulate_post_synth,1)
+	$(call clean_post_synth_sim,1)
+	$(call simulate_post_synth,2)
+	$(call clean_post_synth_sim,2)
+	$(call simulate_post_synth,3)
+	$(call clean_post_synth_sim,3)
\ No newline at end of file
diff --git a/ql-qlf-plugin/tests/qlf_k6n10f/bram36k_sfifo/sim/bram36k_sfifo_tb.v b/ql-qlf-plugin/tests/qlf_k6n10f/bram36k_sfifo/sim/bram36k_sfifo_tb.v
new file mode 100644
index 0000000..df2362c
--- /dev/null
+++ b/ql-qlf-plugin/tests/qlf_k6n10f/bram36k_sfifo/sim/bram36k_sfifo_tb.v
@@ -0,0 +1,170 @@
+// Copyright 2020-2022 F4PGA Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: Apache-2.0
+
+`timescale 1ns/1ps
+
+`define STRINGIFY(x) `"x`"
+
+module TB;
+	localparam PERIOD = 30;
+	localparam ADDR_INCR = 1;
+
+	reg clk;
+  reg flush;
+	reg pop;
+	wire [`DATA_WIDTH1-1:0] dout;
+	reg push;
+	reg [`DATA_WIDTH0-1:0] din;
+  wire almost_full,almost_empty;
+  wire full, empty;
+  wire full_watermark, empty_watermark;
+  wire overrun_error, underrun_error;
+
+  initial 
+  begin
+    clk = 0;
+    pop = 0;
+    push = 0;
+    flush = 1;
+    din = 0;
+    #40
+    flush = 0;
+  end
+  
+	initial forever #(PERIOD / 3.0) clk = ~clk;
+  
+	initial begin
+		$dumpfile(`STRINGIFY(`VCD));
+		$dumpvars;
+	end
+
+	integer a;
+
+	reg done;
+	initial done = 1'b0;
+  
+	reg read_test;
+	initial read_test = 0;
+
+	reg [`DATA_WIDTH1-1:0] expected;
+  initial expected = 0;
+
+	always @(posedge clk) begin
+		expected <= (a | (a << 20) | 20'h55000) & {`DATA_WIDTH1{1'b1}};
+	end
+
+	wire error = ((a != 0) && read_test) ? dout !== expected : 0;
+
+	integer error_cnt = 0;
+	always @ (posedge clk)
+	begin
+		if (error)
+			error_cnt <= error_cnt + 1'b1; 
+	end
+
+	initial #(50) begin
+    @(posedge clk)
+		// Write data
+		for (a = 0; a < (1<<`ADDR_WIDTH0); a = a + ADDR_INCR) begin
+			@(negedge clk) begin
+				din = a | (a << 20) | 20'h55000;
+				push = 1;
+			end
+			@(posedge clk) begin
+				#(PERIOD/10) push = 0;
+			end
+		end
+		// Read data
+		read_test = 1;
+		for (a = 0; a < (1<<`ADDR_WIDTH1); a = a + ADDR_INCR) begin
+			@(posedge clk) begin
+				#(PERIOD/10) pop = 0;
+				if ( dout !== expected) begin
+					$display("%d: FAIL: mismatch act=%x exp=%x at %x", $time, dout, expected, a);
+				end else begin
+					$display("%d: OK: act=%x exp=%x at %x", $time, dout, expected, a);
+				end
+			end
+			@(negedge clk) begin
+				pop = 1;
+			end
+		end
+		done = 1'b1;
+	end
+
+	// Scan for simulation finish
+	always @(posedge clk) begin
+		if (done)
+			$finish_and_return( (error_cnt == 0) ? 0 : -1 );
+	end
+
+	case (`STRINGIFY(`TOP))
+		"f1024x36_1024x36": begin
+			f1024x36_1024x36 #() afifo (
+        .DIN(din),
+        .PUSH(push),
+        .POP(pop),
+        .clock0(clk),
+        .Async_Flush(flush),
+        .Almost_Full(almost_full),
+        .Almost_Empty(almost_empty),
+        .Full(full),
+        .Empty(empty),
+        .Full_Watermark(full_watermark),
+        .Empty_Watermark(empty_watermark),
+        .Overrun_Error(overrun_error),
+        .Underrun_Error(underrun_error),
+        .DOUT(dout)
+			);
+		end
+		"f2048x18_2048x18": begin
+			f2048x18_2048x18 #() afifo (
+        .DIN(din),
+        .PUSH(push),
+        .POP(pop),
+        .clock0(clk),
+        .Async_Flush(flush),
+        .Almost_Full(almost_full),
+        .Almost_Empty(almost_empty),
+        .Full(full),
+        .Empty(empty),
+        .Full_Watermark(full_watermark),
+        .Empty_Watermark(empty_watermark),
+        .Overrun_Error(overrun_error),
+        .Underrun_Error(underrun_error),
+        .DOUT(dout)
+			);
+		end
+		"f4096x9_4096x9": begin
+			f4096x9_4096x9 #() afifo (
+        .DIN(din),
+        .PUSH(push),
+        .POP(pop),
+        .clock0(clk),
+        .Async_Flush(flush),
+        .Almost_Full(almost_full),
+        .Almost_Empty(almost_empty),
+        .Full(full),
+        .Empty(empty),
+        .Full_Watermark(full_watermark),
+        .Empty_Watermark(empty_watermark),
+        .Overrun_Error(overrun_error),
+        .Underrun_Error(underrun_error),
+        .DOUT(dout)
+			);
+		end		
+	endcase
+endmodule
diff --git a/ql-qlf-plugin/tests/qlf_k6n10f/bram36k_tdp/bram36k_tdp.tcl b/ql-qlf-plugin/tests/qlf_k6n10f/bram36k_tdp/bram36k_tdp.tcl
new file mode 100644
index 0000000..df4591e
--- /dev/null
+++ b/ql-qlf-plugin/tests/qlf_k6n10f/bram36k_tdp/bram36k_tdp.tcl
@@ -0,0 +1,38 @@
+yosys -import
+
+if { [info procs ql-qlf-k6n10f] == {} } { plugin -i ql-qlf }
+yosys -import  ;
+
+read_verilog $::env(DESIGN_TOP).v
+design -save bram36k_tdp
+
+select dpram_36x1024
+select *
+synth_quicklogic -family qlf_k6n10f -top dpram_36x1024 -bram_types
+opt_expr -undriven
+opt_clean
+stat
+write_verilog sim/dpram_36x1024_post_synth.v
+select -assert-count 1 t:TDP36K_BRAM_WR_X36_RD_X36_nonsplit
+
+select -clear
+design -load bram36k_tdp
+select dpram_18x2048
+select *
+synth_quicklogic -family qlf_k6n10f -top dpram_18x2048 -bram_types
+opt_expr -undriven
+opt_clean
+stat
+write_verilog sim/dpram_18x2048_post_synth.v
+select -assert-count 1 t:TDP36K_BRAM_WR_X18_RD_X18_nonsplit
+
+select -clear
+design -load bram36k_tdp
+select dpram_9x4096
+select *
+synth_quicklogic -family qlf_k6n10f -top dpram_9x4096 -bram_types
+opt_expr -undriven
+opt_clean
+stat
+write_verilog sim/dpram_9x4096_post_synth.v
+select -assert-count 1 t:TDP36K_BRAM_WR_X9_RD_X9_nonsplit
\ No newline at end of file
diff --git a/ql-qlf-plugin/tests/qlf_k6n10f/bram36k_tdp/bram36k_tdp.v b/ql-qlf-plugin/tests/qlf_k6n10f/bram36k_tdp/bram36k_tdp.v
new file mode 100644
index 0000000..b353a2f
--- /dev/null
+++ b/ql-qlf-plugin/tests/qlf_k6n10f/bram36k_tdp/bram36k_tdp.v
@@ -0,0 +1,197 @@
+module dpram_36x1024 (
+    clock0,
+    WEN1_i,
+    REN1_i,
+    WR1_ADDR_i,
+    RD1_ADDR_i,
+    WDATA1_i,
+    RDATA1_o,
+    
+    clock1,
+    WEN2_i,
+    REN2_i,
+    WR2_ADDR_i,
+    RD2_ADDR_i,
+    WDATA2_i,
+    RDATA2_o
+);
+
+parameter ADDR_WIDTH = 10;
+parameter DATA_WIDTH = 36;
+parameter BE1_WIDTH = 4;
+parameter BE2_WIDTH = 4;
+
+input wire clock0;
+input wire WEN1_i;
+input wire REN1_i;
+input wire [ADDR_WIDTH-1 :0] WR1_ADDR_i;
+input wire [ADDR_WIDTH-1 :0] RD1_ADDR_i;
+input wire [DATA_WIDTH-1 :0] WDATA1_i;
+output wire [DATA_WIDTH-1 :0] RDATA1_o;
+
+input wire clock1;
+input wire WEN2_i;
+input wire REN2_i;
+input wire [ADDR_WIDTH-1 :0] WR2_ADDR_i;
+input wire [ADDR_WIDTH-1 :0] RD2_ADDR_i;
+input wire [DATA_WIDTH-1 :0] WDATA2_i;
+output wire [DATA_WIDTH-1 :0] RDATA2_o;
+
+DPRAM_36K_BLK #(
+              .ADDR_WIDTH(ADDR_WIDTH),
+              .DATA_WIDTH(DATA_WIDTH),
+              .BE1_WIDTH(BE1_WIDTH),
+              .BE2_WIDTH(BE2_WIDTH)
+              ) dpram_x36_inst (             
+              .CLK1_i(clock0),
+              .WEN1_i(WEN1_i),
+              .WR1_BE_i(4'b1111),
+              .REN1_i(REN1_i),
+              .WR1_ADDR_i(WR1_ADDR_i),
+              .RD1_ADDR_i(RD1_ADDR_i),
+              .WDATA1_i(WDATA1_i),
+              .RDATA1_o(RDATA1_o),
+              
+              .CLK2_i(clock1),
+              .WEN2_i(WEN2_i),
+              .WR2_BE_i(4'b1111),
+              .REN2_i(REN2_i),
+              .WR2_ADDR_i(WR2_ADDR_i),
+              .RD2_ADDR_i(RD2_ADDR_i),
+              .WDATA2_i(WDATA2_i),
+              .RDATA2_o(RDATA2_o)
+              );
+
+endmodule
+
+module dpram_18x2048 (
+    clock0,
+    WEN1_i,
+    REN1_i,
+    WR1_ADDR_i,
+    RD1_ADDR_i,
+    WDATA1_i,
+    RDATA1_o,
+    
+    clock1,
+    WEN2_i,
+    REN2_i,
+    WR2_ADDR_i,
+    RD2_ADDR_i,
+    WDATA2_i,
+    RDATA2_o
+);
+
+parameter ADDR_WIDTH = 11;
+parameter DATA_WIDTH = 18;
+parameter BE1_WIDTH = 2;
+parameter BE2_WIDTH = 2;
+
+input wire clock0;
+input wire WEN1_i;
+input wire REN1_i;
+input wire [ADDR_WIDTH-1 :0] WR1_ADDR_i;
+input wire [ADDR_WIDTH-1 :0] RD1_ADDR_i;
+input wire [DATA_WIDTH-1 :0] WDATA1_i;
+output wire [DATA_WIDTH-1 :0] RDATA1_o;
+
+input wire clock1;
+input wire WEN2_i;
+input wire REN2_i;
+input wire [ADDR_WIDTH-1 :0] WR2_ADDR_i;
+input wire [ADDR_WIDTH-1 :0] RD2_ADDR_i;
+input wire [DATA_WIDTH-1 :0] WDATA2_i;
+output wire [DATA_WIDTH-1 :0] RDATA2_o;
+
+DPRAM_36K_BLK #(
+              .ADDR_WIDTH(ADDR_WIDTH),
+              .DATA_WIDTH(DATA_WIDTH),
+              .BE1_WIDTH(BE1_WIDTH),
+              .BE2_WIDTH(BE2_WIDTH)
+              ) dpram_x36_inst (             
+              .CLK1_i(clock0),
+              .WEN1_i(WEN1_i),
+              .WR1_BE_i(2'b11),
+              .REN1_i(REN1_i),
+              .WR1_ADDR_i(WR1_ADDR_i),
+              .RD1_ADDR_i(RD1_ADDR_i),
+              .WDATA1_i(WDATA1_i),
+              .RDATA1_o(RDATA1_o),
+              
+              .CLK2_i(clock1),
+              .WEN2_i(WEN2_i),
+              .WR2_BE_i(2'b11),
+              .REN2_i(REN2_i),
+              .WR2_ADDR_i(WR2_ADDR_i),
+              .RD2_ADDR_i(RD2_ADDR_i),
+              .WDATA2_i(WDATA2_i),
+              .RDATA2_o(RDATA2_o)
+              );
+
+endmodule
+
+module dpram_9x4096 (
+    clock0,
+    WEN1_i,
+    REN1_i,
+    WR1_ADDR_i,
+    RD1_ADDR_i,
+    WDATA1_i,
+    RDATA1_o,
+    
+    clock1,
+    WEN2_i,
+    REN2_i,
+    WR2_ADDR_i,
+    RD2_ADDR_i,
+    WDATA2_i,
+    RDATA2_o
+);
+
+parameter ADDR_WIDTH = 12;
+parameter DATA_WIDTH = 9;
+parameter BE1_WIDTH = 1;
+parameter BE2_WIDTH = 1;
+
+input wire clock0;
+input wire WEN1_i;
+input wire REN1_i;
+input wire [ADDR_WIDTH-1 :0] WR1_ADDR_i;
+input wire [ADDR_WIDTH-1 :0] RD1_ADDR_i;
+input wire [DATA_WIDTH-1 :0] WDATA1_i;
+output wire [DATA_WIDTH-1 :0] RDATA1_o;
+
+input wire clock1;
+input wire WEN2_i;
+input wire REN2_i;
+input wire [ADDR_WIDTH-1 :0] WR2_ADDR_i;
+input wire [ADDR_WIDTH-1 :0] RD2_ADDR_i;
+input wire [DATA_WIDTH-1 :0] WDATA2_i;
+output wire [DATA_WIDTH-1 :0] RDATA2_o;
+
+DPRAM_36K_BLK #(
+              .ADDR_WIDTH(ADDR_WIDTH),
+              .DATA_WIDTH(DATA_WIDTH),
+              .BE1_WIDTH(BE1_WIDTH),
+              .BE2_WIDTH(BE2_WIDTH)
+              ) dpram_x36_inst (             
+              .CLK1_i(clock0),
+              .WEN1_i(WEN1_i),
+              .WR1_BE_i(1'b1),
+              .REN1_i(REN1_i),
+              .WR1_ADDR_i(WR1_ADDR_i),
+              .RD1_ADDR_i(RD1_ADDR_i),
+              .WDATA1_i(WDATA1_i),
+              .RDATA1_o(RDATA1_o),
+              
+              .CLK2_i(clock1),
+              .WEN2_i(WEN2_i),
+              .WR2_BE_i(1'b1),
+              .REN2_i(REN2_i),
+              .WR2_ADDR_i(WR2_ADDR_i),
+              .RD2_ADDR_i(RD2_ADDR_i),
+              .WDATA2_i(WDATA2_i),
+              .RDATA2_o(RDATA2_o)
+              );
+
+endmodule
diff --git a/ql-qlf-plugin/tests/qlf_k6n10f/bram36k_tdp/sim/Makefile b/ql-qlf-plugin/tests/qlf_k6n10f/bram36k_tdp/sim/Makefile
new file mode 100644
index 0000000..2a0c20d
--- /dev/null
+++ b/ql-qlf-plugin/tests/qlf_k6n10f/bram36k_tdp/sim/Makefile
@@ -0,0 +1,45 @@
+# Copyright 2020-2022 F4PGA Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-License-Identifier: Apache-2.0
+
+TESTBENCH = bram36k_tdp_tb.v
+POST_SYNTH = dpram_36x1024_post_synth dpram_18x2048_post_synth dpram_9x4096_post_synth
+ADDR_WIDTH = 10 11 12
+DATA_WIDTH = 36 18 9
+TOP = dpram_36x1024 dpram_18x2048 dpram_9x4096
+ADDR_DEFINES = $(foreach awidth, $(ADDR_WIDTH),-DADDR_WIDTH="$(awidth)")
+DATA_DEFINES = $(foreach dwidth, $(DATA_WIDTH),-DDATA_WIDTH="$(dwidth)")
+TOP_DEFINES = $(foreach top, $(TOP),-DTOP="$(top)")
+VCD_DEFINES = $(foreach vcd, $(POST_SYNTH),-DVCD="$(vcd).vcd")
+
+SIM_LIBS = $(shell find ../../../../qlf_k6n10f -name "*.v" -not -name "*_map.v")
+
+define simulate_post_synth
+	@iverilog  -vvvv -g2005 $(word $(1),$(ADDR_DEFINES)) $(word $(1),$(DATA_DEFINES)) $(word $(1),$(TOP_DEFINES)) $(word $(1),$(VCD_DEFINES)) -o $(word $(1),$(POST_SYNTH)).vvp $(word $(1),$(POST_SYNTH)).v $(SIM_LIBS) $(TESTBENCH) > $(word $(1),$(POST_SYNTH)).vvp.log 2>&1
+	@vvp -vvvv $(word $(1),$(POST_SYNTH)).vvp > $(word $(1),$(POST_SYNTH)).vcd.log 2>&1
+endef
+
+define clean_post_synth_sim
+	@rm -rf  $(word $(1),$(POST_SYNTH)).vcd $(word $(1),$(POST_SYNTH)).vvp $(word $(1),$(POST_SYNTH)).vvp.log $(word $(1),$(POST_SYNTH)).vcd.log
+endef
+
+# FIXME: $(call simulate_post_synth,5)
+sim:
+	$(call simulate_post_synth,1)
+	$(call clean_post_synth_sim,1)
+	$(call simulate_post_synth,2)
+	$(call clean_post_synth_sim,2)
+	$(call simulate_post_synth,3)
+	$(call clean_post_synth_sim,3)
diff --git a/ql-qlf-plugin/tests/qlf_k6n10f/bram36k_tdp/sim/bram36k_tdp_tb.v b/ql-qlf-plugin/tests/qlf_k6n10f/bram36k_tdp/sim/bram36k_tdp_tb.v
new file mode 100644
index 0000000..01de7e7
--- /dev/null
+++ b/ql-qlf-plugin/tests/qlf_k6n10f/bram36k_tdp/sim/bram36k_tdp_tb.v
@@ -0,0 +1,220 @@
+// Copyright 2020-2022 F4PGA Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: Apache-2.0
+
+`timescale 1ns/1ps
+
+`define STRINGIFY(x) `"x`"
+
+module TB;
+	localparam PERIOD = 50;
+	localparam ADDR_INCR = 1;
+
+	reg clk_a;
+	reg rce_a;
+	reg [`ADDR_WIDTH-1:0] ra_a;
+	wire [`DATA_WIDTH-1:0] rq_a;
+	reg wce_a;
+	reg [`ADDR_WIDTH-1:0] wa_a;
+	reg [`DATA_WIDTH-1:0] wd_a;
+
+	reg clk_b;
+	reg rce_b;
+	reg [`ADDR_WIDTH-1:0] ra_b;
+	wire [`DATA_WIDTH-1:0] rq_b;
+	reg wce_b;
+	reg [`ADDR_WIDTH-1:0] wa_b;
+	reg [`DATA_WIDTH-1:0] wd_b;
+
+
+	initial clk_a = 0;
+	initial clk_b = 0;
+	initial ra_a = 0;
+	initial ra_b = 0;
+	initial rce_a = 0;
+	initial rce_b = 0;
+	initial forever #(PERIOD / 2.0) clk_a = ~clk_a;
+	initial begin
+		#(PERIOD / 4.0);
+		forever #(PERIOD / 2.0) clk_b = ~clk_b;
+	end
+	initial begin
+		$dumpfile(`STRINGIFY(`VCD));
+		$dumpvars;
+	end
+
+	integer a;
+	integer b;
+
+	reg done_a;
+	reg done_b;
+	initial done_a = 1'b0;
+	initial done_b = 1'b0;
+	wire done_sim = done_a & done_b;
+
+	reg [`DATA_WIDTH-1:0] expected_a;
+	reg [`DATA_WIDTH-1:0] expected_b;
+
+	always @(posedge clk_a) begin
+		expected_a <= (a | (a << 20) | 20'h55000) & {`DATA_WIDTH{1'b1}};
+	end
+	always @(posedge clk_b) begin
+		expected_b <= (b | (b << 20) | 20'h55000) & {`DATA_WIDTH{1'b1}};
+	end
+
+	wire error_a = a != 0 ? rq_a !== expected_a : 0;
+	wire error_b = b != (1<<`ADDR_WIDTH) / 2 ? rq_b !== expected_b : 0;
+
+	integer error_a_cnt = 0;
+	integer error_b_cnt = 0;
+
+	always @ (posedge clk_a)
+	begin
+		if (error_a)
+			error_a_cnt <= error_a_cnt + 1'b1;
+	end
+	always @ (posedge clk_b)
+	begin
+		if (error_b)
+			error_b_cnt <= error_b_cnt + 1'b1;
+	end
+	// PORT A
+	initial #(1) begin
+		// Write data
+		for (a = 0; a < (1<<`ADDR_WIDTH) / 2; a = a + ADDR_INCR) begin
+			@(negedge clk_a) begin
+				wa_a = a;
+				wd_a = a | (a << 20) | 20'h55000;
+				wce_a = 1;
+			end
+			@(posedge clk_a) begin
+				#(PERIOD/10) wce_a = 0;
+			end
+		end
+		// Read data
+		for (a = 0; a < (1<<`ADDR_WIDTH) / 2; a = a + ADDR_INCR) begin
+			@(negedge clk_a) begin
+				ra_a = a;
+				rce_a = 1;
+			end
+			@(posedge clk_a) begin
+				#(PERIOD/10) rce_a = 0;
+				if ( rq_a !== expected_a) begin
+					$display("%d: PORT A: FAIL: mismatch act=%x exp=%x at %x", $time, rq_a, expected_a, a);
+				end else begin
+					$display("%d: PORT A: OK: act=%x exp=%x at %x", $time, rq_a, expected_a, a);
+				end
+			end
+		end
+		done_a = 1'b1;
+	end
+
+	// PORT B
+	initial #(1) begin
+		// Write data
+		for (b = (1<<`ADDR_WIDTH) / 2; b < (1<<`ADDR_WIDTH); b = b + ADDR_INCR) begin
+			@(negedge clk_b) begin
+				wa_b = b;
+				wd_b = b | (b << 20) | 20'h55000;
+				wce_b = 1;
+			end
+			@(posedge clk_b) begin
+				#(PERIOD/10) wce_b = 0;
+			end
+		end
+		// Read data
+		for (b = (1<<`ADDR_WIDTH) / 2; b < (1<<`ADDR_WIDTH); b = b + ADDR_INCR) begin
+			@(negedge clk_b) begin
+				ra_b = b;
+				rce_b = 1;
+			end
+			@(posedge clk_b) begin
+				#(PERIOD/10) rce_b = 0;
+				if ( rq_b !== expected_b) begin
+					$display("%d: PORT B: FAIL: mismatch act=%x exp=%x at %x", $time, rq_b, expected_b, b);
+				end else begin
+					$display("%d: PORT B: OK: act=%x exp=%x at %x", $time, rq_b, expected_b, b);
+				end
+			end
+		end
+		done_b = 1'b1;
+	end
+
+	// Scan for simulation finish
+	always @(posedge clk_a, posedge clk_b) begin
+		if (done_sim)
+			$finish_and_return( (error_a_cnt == 0 & error_b_cnt == 0) ? 0 : -1 );
+	end
+  
+	case (`STRINGIFY(`TOP))
+		"dpram_36x1024": begin
+			dpram_36x1024 #() bram (
+				.clock0(clk_a),
+				.REN1_i(rce_a),
+				.RD1_ADDR_i(ra_a),
+				.RDATA1_o(rq_a),
+				.WEN1_i(wce_a),
+				.WR1_ADDR_i(wa_a),
+				.WDATA1_i(wd_a),
+        
+				.clock1(clk_b),
+				.REN2_i(rce_b),
+				.RD2_ADDR_i(ra_b),
+				.RDATA2_o(rq_b),
+				.WEN2_i(wce_b),
+				.WR2_ADDR_i(wa_b),
+				.WDATA2_i(wd_b)
+			);
+		end
+		"dpram_18x2048": begin
+			dpram_18x2048 #() bram (
+				.clock0(clk_a),
+				.REN1_i(rce_a),
+				.RD1_ADDR_i(ra_a),
+				.RDATA1_o(rq_a),
+				.WEN1_i(wce_a),
+				.WR1_ADDR_i(wa_a),
+				.WDATA1_i(wd_a),
+        
+				.clock1(clk_b),
+				.REN2_i(rce_b),
+				.RD2_ADDR_i(ra_b),
+				.RDATA2_o(rq_b),
+				.WEN2_i(wce_b),
+				.WR2_ADDR_i(wa_b),
+				.WDATA2_i(wd_b)
+			);
+		end
+		"dpram_9x4096": begin
+			dpram_9x4096 #() bram (
+				.clock0(clk_a),
+				.REN1_i(rce_a),
+				.RD1_ADDR_i(ra_a),
+				.RDATA1_o(rq_a),
+				.WEN1_i(wce_a),
+				.WR1_ADDR_i(wa_a),
+				.WDATA1_i(wd_a),
+        
+				.clock1(clk_b),
+				.REN2_i(rce_b),
+				.RD2_ADDR_i(ra_b),
+				.RDATA2_o(rq_b),
+				.WEN2_i(wce_b),
+				.WR2_ADDR_i(wa_b),
+				.WDATA2_i(wd_b)
+			);
+		end
+	endcase
+endmodule