Merge pull request #276 from antmicro/rename-uhdm-plugin Rename the uhdm plugin to systemverilog
diff --git a/ql-qlf-plugin/qlf_k6n10f/arith_map.v b/ql-qlf-plugin/qlf_k6n10f/arith_map.v index c5dd221..0d97131 100644 --- a/ql-qlf-plugin/qlf_k6n10f/arith_map.v +++ b/ql-qlf-plugin/qlf_k6n10f/arith_map.v
@@ -60,7 +60,8 @@ ); endgenerate genvar i; - generate for (i = 0; i < Y_WIDTH-2; i = i + 1) begin:slice + generate if (Y_WIDTH > 2) begin + for (i = 0; i < Y_WIDTH-2; i = i + 1) begin:slice adder_carry my_adder ( .cin(C[i]), .g(AA[i]), @@ -68,6 +69,7 @@ .cout(C[i+1]), .sumout(Y[i]) ); + end end endgenerate generate adder_carry final_adder (
diff --git a/ql-qlf-plugin/qlf_k6n10f/brams.txt b/ql-qlf-plugin/qlf_k6n10f/brams.txt index b8ba985..6951a4a 100644 --- a/ql-qlf-plugin/qlf_k6n10f/brams.txt +++ b/ql-qlf-plugin/qlf_k6n10f/brams.txt
@@ -23,10 +23,49 @@ clkpol 1 1 1 1 endbram +bram $__QLF_FACTOR_BRAM36_SDP + init 1 + abits 10 @a10d36 + dbits 36 @a10d36 + abits 11 @a11d18 + dbits 18 @a11d18 + abits 12 @a12d9 + dbits 9 @a12d9 + abits 13 @a13d4 + dbits 4 @a13d4 + abits 14 @a14d2 + dbits 2 @a14d2 + abits 15 @a15d1 + dbits 1 @a15d1 + groups 2 + ports 1 1 + wrmode 0 1 + enable 1 4 @a10d36 + enable 1 2 @a11d18 + enable 1 1 @a12d9 @a13d4 @a14d2 @a15d1 + transp 0 0 + clocks 2 3 + clkpol 2 3 +endbram + match $__QLF_FACTOR_BRAM36_TDP - max dbits 36 - max abits 15 + min wports 1 + max wports 2 + min rports 1 + max rports 2 + min efficiency 1 + min bits 128 + shuffle_enable B + make_transp + or_next_if_better +endmatch + +match $__QLF_FACTOR_BRAM36_SDP + max wports 1 + max rports 1 + min efficiency 1 + min bits 128 shuffle_enable B make_transp endmatch
diff --git a/ql-qlf-plugin/qlf_k6n10f/brams_map.v b/ql-qlf-plugin/qlf_k6n10f/brams_map.v index 59fbdd7..a98d7f0 100644 --- a/ql-qlf-plugin/qlf_k6n10f/brams_map.v +++ b/ql-qlf-plugin/qlf_k6n10f/brams_map.v
@@ -109,8 +109,8 @@ end 4: begin - assign PORT_A_ADDR = A1EN ? (A1ADDR_TOTAL << 5) : (B1EN ? (B1ADDR_TOTAL << 5) : 15'd0); - assign PORT_B_ADDR = C1EN ? (C1ADDR_TOTAL << 5) : (D1EN ? (D1ADDR_TOTAL << 5) : 15'd0); + assign PORT_A_ADDR = A1EN ? (A1ADDR_TOTAL << 2) : (B1EN ? (B1ADDR_TOTAL << 2) : 15'd0); + assign PORT_B_ADDR = C1EN ? (C1ADDR_TOTAL << 2) : (D1EN ? (D1ADDR_TOTAL << 2) : 15'd0); defparam _TECHMAP_REPLACE_.WMODE_A1_i = `MODE_4; defparam _TECHMAP_REPLACE_.WMODE_A2_i = `MODE_4; defparam _TECHMAP_REPLACE_.RMODE_A1_i = `MODE_4; @@ -374,3 +374,248 @@ ); end endgenerate endmodule + +module \$__QLF_FACTOR_BRAM36_SDP (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN); + parameter CFG_ABITS = 10; + parameter CFG_DBITS = 36; + parameter CFG_ENABLE_B = 4; + + parameter CLKPOL2 = 1; + parameter CLKPOL3 = 1; + parameter [36863:0] INIT = 36864'bx; + + localparam MODE_36 = 3'b111; // 36 or 32-bit + localparam MODE_18 = 3'b110; // 18 or 16-bit + localparam MODE_9 = 3'b101; // 9 or 8-bit + localparam MODE_4 = 3'b100; // 4-bit + localparam MODE_2 = 3'b010; // 32-bit + localparam MODE_1 = 3'b001; // 32-bit + + input CLK2; + input CLK3; + + input [CFG_ABITS-1:0] A1ADDR; + output [CFG_DBITS-1:0] A1DATA; + input A1EN; + + input [CFG_ABITS-1:0] B1ADDR; + input [CFG_DBITS-1:0] B1DATA; + input [CFG_ENABLE_B-1:0] B1EN; + + wire [14:0] A1ADDR_15; + wire [14:0] B1ADDR_15; + + wire [35:0] DOBDO; + + wire [14:CFG_ABITS] A1ADDR_CMPL; + wire [14:CFG_ABITS] B1ADDR_CMPL; + wire [35:CFG_DBITS] A1DATA_CMPL; + wire [35:CFG_DBITS] B1DATA_CMPL; + + wire [14:0] A1ADDR_TOTAL; + wire [14:0] B1ADDR_TOTAL; + wire [35:0] A1DATA_TOTAL; + wire [35:0] B1DATA_TOTAL; + + wire FLUSH1; + wire FLUSH2; + wire [15:0] RAM_ID; + + wire PL_INIT_i; + wire PL_ENA_i; + wire PL_REN_i; + wire PL_CLK_i; + wire [1:0] PL_WEN_i; + wire [23:0] PL_ADDR_i; + wire [35:0] PL_DATA_i; + reg PL_INIT_o; + reg PL_ENA_o; + reg PL_REN_o; + reg PL_CLK_o; + reg [1:0] PL_WEN_o; + reg [23:0] PL_ADDR_o; + wire [35:0] PL_DATA_o; + + wire [2:0] WMODE; + wire [2:0] RMODE; + + assign A1ADDR_CMPL = {15-CFG_ABITS{1'b0}}; + assign B1ADDR_CMPL = {15-CFG_ABITS{1'b0}}; + + assign A1ADDR_TOTAL = {A1ADDR_CMPL, A1ADDR}; + assign B1ADDR_TOTAL = {B1ADDR_CMPL, B1ADDR}; + + assign A1DATA_TOTAL = {A1DATA_CMPL, A1DATA}; + assign B1DATA_TOTAL = {B1DATA_CMPL, B1DATA}; + + case (CFG_DBITS) + 1: begin + assign A1ADDR_15 = A1ADDR_TOTAL; + assign B1ADDR_15 = B1ADDR_TOTAL; + defparam _TECHMAP_REPLACE_.WMODE_A1_i = `MODE_1; + defparam _TECHMAP_REPLACE_.WMODE_A2_i = `MODE_1; + defparam _TECHMAP_REPLACE_.RMODE_A1_i = `MODE_1; + defparam _TECHMAP_REPLACE_.RMODE_A2_i = `MODE_1; + defparam _TECHMAP_REPLACE_.WMODE_B1_i = `MODE_1; + defparam _TECHMAP_REPLACE_.WMODE_B2_i = `MODE_1; + defparam _TECHMAP_REPLACE_.RMODE_B1_i = `MODE_1; + defparam _TECHMAP_REPLACE_.RMODE_B2_i = `MODE_1; + end + + 2: begin + assign A1ADDR_15 = A1ADDR_TOTAL << 1; + assign B1ADDR_15 = B1ADDR_TOTAL << 1; + defparam _TECHMAP_REPLACE_.WMODE_A1_i = `MODE_2; + defparam _TECHMAP_REPLACE_.WMODE_A2_i = `MODE_2; + defparam _TECHMAP_REPLACE_.RMODE_A1_i = `MODE_2; + defparam _TECHMAP_REPLACE_.RMODE_A2_i = `MODE_2; + defparam _TECHMAP_REPLACE_.WMODE_B1_i = `MODE_2; + defparam _TECHMAP_REPLACE_.WMODE_B2_i = `MODE_2; + defparam _TECHMAP_REPLACE_.RMODE_B1_i = `MODE_2; + defparam _TECHMAP_REPLACE_.RMODE_B2_i = `MODE_2; + end + + 4: begin + assign A1ADDR_15 = A1ADDR_TOTAL << 2; + assign B1ADDR_15 = B1ADDR_TOTAL << 2; + defparam _TECHMAP_REPLACE_.WMODE_A1_i = `MODE_4; + defparam _TECHMAP_REPLACE_.WMODE_A2_i = `MODE_4; + defparam _TECHMAP_REPLACE_.RMODE_A1_i = `MODE_4; + defparam _TECHMAP_REPLACE_.RMODE_A2_i = `MODE_4; + defparam _TECHMAP_REPLACE_.WMODE_B1_i = `MODE_4; + defparam _TECHMAP_REPLACE_.WMODE_B2_i = `MODE_4; + defparam _TECHMAP_REPLACE_.RMODE_B1_i = `MODE_4; + defparam _TECHMAP_REPLACE_.RMODE_B2_i = `MODE_4; + end + 8, 9: begin + assign A1ADDR_15 = A1ADDR_TOTAL << 3; + assign B1ADDR_15 = B1ADDR_TOTAL << 3; + defparam _TECHMAP_REPLACE_.WMODE_A1_i = `MODE_9; + defparam _TECHMAP_REPLACE_.WMODE_A2_i = `MODE_9; + defparam _TECHMAP_REPLACE_.RMODE_A1_i = `MODE_9; + defparam _TECHMAP_REPLACE_.RMODE_A2_i = `MODE_9; + defparam _TECHMAP_REPLACE_.WMODE_B1_i = `MODE_9; + defparam _TECHMAP_REPLACE_.WMODE_B2_i = `MODE_9; + defparam _TECHMAP_REPLACE_.RMODE_B1_i = `MODE_9; + defparam _TECHMAP_REPLACE_.RMODE_B2_i = `MODE_9; + end + + 16, 18: begin + assign A1ADDR_15 = A1ADDR_TOTAL << 4; + assign B1ADDR_15 = B1ADDR_TOTAL << 4; + defparam _TECHMAP_REPLACE_.WMODE_A1_i = `MODE_18; + defparam _TECHMAP_REPLACE_.WMODE_A2_i = `MODE_18; + defparam _TECHMAP_REPLACE_.RMODE_A1_i = `MODE_18; + defparam _TECHMAP_REPLACE_.RMODE_A2_i = `MODE_18; + defparam _TECHMAP_REPLACE_.WMODE_B1_i = `MODE_18; + defparam _TECHMAP_REPLACE_.WMODE_B2_i = `MODE_18; + defparam _TECHMAP_REPLACE_.RMODE_B1_i = `MODE_18; + defparam _TECHMAP_REPLACE_.RMODE_B2_i = `MODE_18; + end + 32, 36: begin + assign A1ADDR_15 = A1ADDR_TOTAL << 5; + assign B1ADDR_15 = B1ADDR_TOTAL << 5; + defparam _TECHMAP_REPLACE_.WMODE_A1_i = `MODE_36; + defparam _TECHMAP_REPLACE_.WMODE_A2_i = `MODE_36; + defparam _TECHMAP_REPLACE_.RMODE_A1_i = `MODE_36; + defparam _TECHMAP_REPLACE_.RMODE_A2_i = `MODE_36; + defparam _TECHMAP_REPLACE_.WMODE_B1_i = `MODE_36; + defparam _TECHMAP_REPLACE_.WMODE_B2_i = `MODE_36; + defparam _TECHMAP_REPLACE_.RMODE_B1_i = `MODE_36; + defparam _TECHMAP_REPLACE_.RMODE_B2_i = `MODE_36; + end + default: begin + assign A1ADDR_15 = A1ADDR_TOTAL; + assign B1ADDR_15 = B1ADDR_TOTAL; + defparam _TECHMAP_REPLACE_.WMODE_A1_i = `MODE_36; + defparam _TECHMAP_REPLACE_.WMODE_A2_i = `MODE_36; + defparam _TECHMAP_REPLACE_.RMODE_A1_i = `MODE_36; + defparam _TECHMAP_REPLACE_.RMODE_A2_i = `MODE_36; + defparam _TECHMAP_REPLACE_.WMODE_B1_i = `MODE_36; + defparam _TECHMAP_REPLACE_.WMODE_B2_i = `MODE_36; + defparam _TECHMAP_REPLACE_.RMODE_B1_i = `MODE_36; + defparam _TECHMAP_REPLACE_.RMODE_B2_i = `MODE_36; + end + endcase + + + assign FLUSH1 = 1'b0; + assign FLUSH2 = 1'b0; + assign RAM_ID = 16'b0; + assign PL_INIT_i = 1'b0; + assign PL_ENA_i = 1'b0; + assign PL_REN_i = 1'b0; + assign PL_CLK_i = 1'b0; + assign PL_WEN_i = 2'b0; + assign PL_ADDR_i = 24'b0; + assign PL_DATA_i = 36'b0; + + TDP_BRAM36 #( + .UPAE1_i(12'd10), + .UPAF1_i(12'd10), + .UPAE2_i(12'd10), + .UPAF2_i(12'd10), + .SYNC_FIFO1_i(1'b0), + .SYNC_FIFO2_i(1'b0), + .FMODE1_i(1'b0), + .FMODE2_i(1'b0), + .POWERDN1_i(1'b0), + .POWERDN2_i(1'b0), + .SLEEP1_i(1'b0), + .SLEEP2_i(1'b0), + .PROTECT1_i(1'b0), + .PROTECT2_i(1'b0), + .SPLIT_i(1'b0) + ) _TECHMAP_REPLACE_ ( + .WDATA_A1_i(18'h3FFFF), + .WDATA_A2_i(18'h3FFFF), + .RDATA_A1_o(A1DATA_TOTAL[17:0]), + .RDATA_A2_o(A1DATA_TOTAL[35:18]), + .ADDR_A1_i(A1ADDR_15), + .ADDR_A2_i(A1ADDR_15), + .CLK_A1_i(CLK2), + .CLK_A2_i(CLK2), + .REN_A1_i(A1EN), + .REN_A2_i(A1EN), + .WEN_A1_i(1'b0), + .WEN_A2_i(1'b0), + .BE_A1_i({A1EN, A1EN}), + .BE_A2_i({A1EN, A1EN}), + + .WDATA_B1_i(B1DATA[17:0]), + .WDATA_B2_i(B1DATA[35:18]), + .RDATA_B1_o(DOBDO[17:0]), + .RDATA_B2_o(DOBDO[35:18]), + .ADDR_B1_i(B1ADDR_15), + .ADDR_B2_i(B1ADDR_15), + .CLK_B1_i(CLK3), + .CLK_B2_i(CLK3), + .REN_B1_i(1'b0), + .REN_B2_i(1'b0), + .WEN_B1_i(B1EN[0]), + .WEN_B2_i(B1EN[0]), + .BE_B1_i(B1EN[1:0]), + .BE_B2_i(B1EN[3:2]), + + .FLUSH1_i(FLUSH1), + .FLUSH2_i(FLUSH2), + .RAM_ID_i(RAM_ID), + + .PL_INIT_i(PL_INIT_i), + .PL_ENA_i(PL_ENA_i), + .PL_WEN_i(PL_WEN_i), + .PL_REN_i(PL_REN_i), + .PL_CLK_i(PL_CLK_i), + .PL_ADDR_i(PL_ADDR_i), + .PL_DATA_i(PL_DATA_i), + .PL_INIT_o(PL_INIT_o), + .PL_ENA_o(PL_ENA_o), + .PL_WEN_o(PL_WEN_o), + .PL_REN_o(PL_REN_o), + .PL_CLK_o(PL_CLK_o), + .PL_ADDR_o(), + .PL_DATA_o(PL_DATA_o) + + ); +endmodule +
diff --git a/ql-qlf-plugin/tests/Makefile b/ql-qlf-plugin/tests/Makefile index 21b68b6..639fb63 100644 --- a/ql-qlf-plugin/tests/Makefile +++ b/ql-qlf-plugin/tests/Makefile
@@ -33,7 +33,8 @@ # Those tests perform synthesis and simulation of synthesis results POST_SYNTH_SIM_TESTS = \ - qlf_k6n10f/bram_tdp + qlf_k6n10f/bram_tdp \ + qlf_k6n10f/bram_sdp include $(shell pwd)/../../Makefile_test.common
diff --git a/ql-qlf-plugin/tests/qlf_k6n10f/bram_sdp/bram_sdp.tcl b/ql-qlf-plugin/tests/qlf_k6n10f/bram_sdp/bram_sdp.tcl new file mode 100644 index 0000000..5e9379e --- /dev/null +++ b/ql-qlf-plugin/tests/qlf_k6n10f/bram_sdp/bram_sdp.tcl
@@ -0,0 +1,50 @@ +yosys -import + +if { [info procs ql-qlf-k6n10f] == {} } { plugin -i ql-qlf } +yosys -import ; + +read_verilog $::env(DESIGN_TOP).v +design -save bram_sdp + +select BRAM_SDP_32x512 +select * +synth_quicklogic -family qlf_k6n10f -top BRAM_SDP_32x512 +opt_expr -undriven +opt_clean +stat +write_verilog sim/bram_sdp_32x512_post_synth.v +select -assert-count 1 t:TDP_BRAM36 + +select -clear +design -load bram_sdp +select BRAM_SDP_16x1024 +select * +synth_quicklogic -family qlf_k6n10f -top BRAM_SDP_16x1024 +opt_expr -undriven +opt_clean +stat +write_verilog sim/bram_sdp_16x1024_post_synth.v +select -assert-count 1 t:TDP_BRAM36 + +select -clear +design -load bram_sdp +select BRAM_SDP_8x2048 +select * +synth_quicklogic -family qlf_k6n10f -top BRAM_SDP_8x2048 +opt_expr -undriven +opt_clean +stat +write_verilog sim/bram_sdp_8x2048_post_synth.v +select -assert-count 1 t:TDP_BRAM36 + +select -clear +design -load bram_sdp +select BRAM_SDP_4x4096 +select * +synth_quicklogic -family qlf_k6n10f -top BRAM_SDP_4x4096 +opt_expr -undriven +opt_clean +stat +write_verilog sim/bram_sdp_4x4096_post_synth.v +select -assert-count 1 t:TDP_BRAM36 +
diff --git a/ql-qlf-plugin/tests/qlf_k6n10f/bram_sdp/bram_sdp.v b/ql-qlf-plugin/tests/qlf_k6n10f/bram_sdp/bram_sdp.v new file mode 100644 index 0000000..8433c56 --- /dev/null +++ b/ql-qlf-plugin/tests/qlf_k6n10f/bram_sdp/bram_sdp.v
@@ -0,0 +1,177 @@ +// Copyright (C) 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 + +module BRAM_SDP #(parameter AWIDTH = 9, +parameter DWIDTH = 32)( + clk, + rce, + ra, + rq, + wce, + wa, + wd +); + + input clk; + + input rce; + input [AWIDTH-1:0] ra; + output reg [DWIDTH-1:0] rq; + + input wce; + input [AWIDTH-1:0] wa; + input [DWIDTH-1:0] wd; + + reg [DWIDTH-1:0] memory[0:(1<<AWIDTH)-1]; + + always @(posedge clk) begin + if (rce) + rq <= memory[ra]; + + if (wce) + memory[wa] <= wd; + end + + integer i; + initial + begin + for(i = 0; i < (1<<AWIDTH)-1; i = i + 1) + memory[i] = 0; + end + +endmodule + +module BRAM_SDP_32x512( + clk, + rce, + ra, + rq, + wce, + wa, + wd +); + +parameter AWIDTH = 9; +parameter DWIDTH = 32; + + input clk; + input rce; + input [AWIDTH-1:0] ra; + output [DWIDTH-1:0] rq; + input wce; + input [AWIDTH-1:0] wa; + input [DWIDTH-1:0] wd; + +BRAM_SDP #(.AWIDTH(AWIDTH), .DWIDTH(DWIDTH)) + BRAM_32x512 (.clk(clk), + .rce(rce), + .ra(ra), + .rq(rq), + .wce(wce), + .wa(wa), + .wd(wd)); + +endmodule + +module BRAM_SDP_16x1024( + clk, + rce, + ra, + rq, + wce, + wa, + wd +); + +parameter AWIDTH = 10; +parameter DWIDTH = 16; + + input clk; + input rce; + input [AWIDTH-1:0] ra; + output [DWIDTH-1:0] rq; + input wce; + input [AWIDTH-1:0] wa; + input [DWIDTH-1:0] wd; + +BRAM_SDP #(.AWIDTH(AWIDTH), .DWIDTH(DWIDTH)) + BRAM_16x1024 (.clk(clk), + .rce(rce), + .ra(ra), + .rq(rq), + .wce(wce), + .wa(wa), + .wd(wd)); + + +endmodule + +module BRAM_SDP_8x2048( + clk, + rce, + ra, + rq, + wce, + wa, + wd +); + +parameter AWIDTH = 11; +parameter DWIDTH = 8; + + input clk; + input rce; + input [AWIDTH-1:0] ra; + output [DWIDTH-1:0] rq; + input wce; + input [AWIDTH-1:0] wa; + input [DWIDTH-1:0] wd; + +BRAM_SDP #(.AWIDTH(AWIDTH), .DWIDTH(DWIDTH)) + BRAM_8x2048 (.clk(clk), + .rce(rce), + .ra(ra), + .rq(rq), + .wce(wce), + .wa(wa), + .wd(wd)); + + +endmodule + +module BRAM_SDP_4x4096( + clk, + rce, + ra, + rq, + wce, + wa, + wd +); + +parameter AWIDTH = 12; +parameter DWIDTH = 4; + + input clk; + input rce; + input [AWIDTH-1:0] ra; + output [DWIDTH-1:0] rq; + input wce; + input [AWIDTH-1:0] wa; + input [DWIDTH-1:0] wd; + +BRAM_SDP #(.AWIDTH(AWIDTH), .DWIDTH(DWIDTH)) + BRAM_4x4096 (.clk(clk), + .rce(rce), + .ra(ra), + .rq(rq), + .wce(wce), + .wa(wa), + .wd(wd)); + +endmodule
diff --git a/ql-qlf-plugin/tests/qlf_k6n10f/bram_sdp/sim/Makefile b/ql-qlf-plugin/tests/qlf_k6n10f/bram_sdp/sim/Makefile new file mode 100644 index 0000000..0c9bab3 --- /dev/null +++ b/ql-qlf-plugin/tests/qlf_k6n10f/bram_sdp/sim/Makefile
@@ -0,0 +1,35 @@ +# Copyright (C) 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 = bram_sdp_tb.v +POST_SYNTH = bram_sdp_32x512_post_synth bram_sdp_16x1024_post_synth bram_sdp_8x2048_post_synth bram_sdp_4x4096_post_synth +ADDR_WIDTH = 9 10 11 12 +DATA_WIDTH = 32 16 8 4 +TOP = BRAM_SDP_32x512 BRAM_SDP_16x1024 BRAM_SDP_8x2048 BRAM_SDP_4x4096 +TEST_CASES = $(seq 0 3) +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 + +sim: + $(call simulate_post_synth,1) + $(call simulate_post_synth,2) + $(call simulate_post_synth,3) + $(call simulate_post_synth,4)
diff --git a/ql-qlf-plugin/tests/qlf_k6n10f/bram_sdp/sim/bram_sdp_tb.v b/ql-qlf-plugin/tests/qlf_k6n10f/bram_sdp/sim/bram_sdp_tb.v new file mode 100644 index 0000000..d5af767 --- /dev/null +++ b/ql-qlf-plugin/tests/qlf_k6n10f/bram_sdp/sim/bram_sdp_tb.v
@@ -0,0 +1,140 @@ +// Copyright (C) 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; + 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)) + "BRAM_SDP_32x512": begin + BRAM_SDP_32x512 #() bram ( + .clk(clk), + .rce(rce), + .ra(ra), + .rq(rq), + .wce(wce), + .wa(wa), + .wd(wd) + ); + end + "BRAM_SDP_16x1024": begin + BRAM_SDP_16x1024 #() bram ( + .clk(clk), + .rce(rce), + .ra(ra), + .rq(rq), + .wce(wce), + .wa(wa), + .wd(wd) + ); + end + "BRAM_SDP_8x2048": begin + BRAM_SDP_8x2048 #() bram ( + .clk(clk), + .rce(rce), + .ra(ra), + .rq(rq), + .wce(wce), + .wa(wa), + .wd(wd) + ); + end + "BRAM_SDP_4x4096": begin + BRAM_SDP_4x4096 #() bram ( + .clk(clk), + .rce(rce), + .ra(ra), + .rq(rq), + .wce(wce), + .wa(wa), + .wd(wd) + ); + end + endcase +endmodule