diff options
Diffstat (limited to 'techlibs')
131 files changed, 13882 insertions, 4388 deletions
diff --git a/techlibs/anlogic/Makefile.inc b/techlibs/anlogic/Makefile.inc index 2d8d65e2e..669e8bea5 100644 --- a/techlibs/anlogic/Makefile.inc +++ b/techlibs/anlogic/Makefile.inc @@ -9,4 +9,5 @@ $(eval $(call add_share_file,share/anlogic,techlibs/anlogic/cells_sim.v)) $(eval $(call add_share_file,share/anlogic,techlibs/anlogic/eagle_bb.v)) $(eval $(call add_share_file,share/anlogic,techlibs/anlogic/lutrams.txt)) $(eval $(call add_share_file,share/anlogic,techlibs/anlogic/lutrams_map.v)) -$(eval $(call add_share_file,share/anlogic,techlibs/anlogic/lutram_init_16x4.vh)) +$(eval $(call add_share_file,share/anlogic,techlibs/anlogic/brams.txt)) +$(eval $(call add_share_file,share/anlogic,techlibs/anlogic/brams_map.v)) diff --git a/techlibs/anlogic/brams.txt b/techlibs/anlogic/brams.txt new file mode 100644 index 000000000..910cdebe1 --- /dev/null +++ b/techlibs/anlogic/brams.txt @@ -0,0 +1,69 @@ +ram block $__ANLOGIC_BRAM_TDP_ { + abits 13; + widths 1 2 4 9 per_port; + cost 64; + init no_undef; + port srsw "A" "B" { + clock anyedge; + clken; + portoption "WRITEMODE" "NORMAL" { + rdwr no_change; + } + portoption "WRITEMODE" "WRITETHROUGH" { + rdwr new; + } + portoption "WRITEMODE" "READBEFOREWRITE" { + rdwr old; + } + option "RESETMODE" "SYNC" { + rdsrst zero ungated block_wr; + } + option "RESETMODE" "ASYNC" { + rdarst zero; + } + rdinit zero; + } +} + +ram block $__ANLOGIC_BRAM_SDP_ { + abits 13; + widths 1 2 4 9 18 per_port; + byte 9; + cost 64; + init no_undef; + port sr "R" { + clock anyedge; + clken; + option "RESETMODE" "SYNC" { + rdsrst zero ungated; + } + option "RESETMODE" "ASYNC" { + rdarst zero; + } + rdinit zero; + } + port sw "W" { + clock anyedge; + clken; + } +} + +ram block $__ANLOGIC_BRAM32K_ { + abits 12; + widths 8 16 per_port; + byte 8; + cost 192; + init no_undef; + port srsw "A" "B" { + clock anyedge; + clken; + portoption "WRITEMODE" "NORMAL" { + rdwr no_change; + } + portoption "WRITEMODE" "WRITETHROUGH" { + rdwr new; + } + # no reset - it doesn't really work without the pipeline + # output registers + } +} diff --git a/techlibs/anlogic/brams_map.v b/techlibs/anlogic/brams_map.v new file mode 100644 index 000000000..7e2642d65 --- /dev/null +++ b/techlibs/anlogic/brams_map.v @@ -0,0 +1,474 @@ +module $__ANLOGIC_BRAM_TDP_ (...); + +parameter INIT = 0; +parameter OPTION_RESETMODE = "SYNC"; + +parameter PORT_A_WIDTH = 9; +parameter PORT_A_CLK_POL = 1; +parameter PORT_A_OPTION_WRITEMODE = "NORMAL"; + +input PORT_A_CLK; +input PORT_A_CLK_EN; +input PORT_A_WR_EN; +input PORT_A_RD_SRST; +input PORT_A_RD_ARST; +input [12:0] PORT_A_ADDR; +input [PORT_A_WIDTH-1:0] PORT_A_WR_DATA; +output [PORT_A_WIDTH-1:0] PORT_A_RD_DATA; + +parameter PORT_B_WIDTH = 9; +parameter PORT_B_CLK_POL = 1; +parameter PORT_B_OPTION_WRITEMODE = "NORMAL"; + +input PORT_B_CLK; +input PORT_B_CLK_EN; +input PORT_B_WR_EN; +input PORT_B_RD_SRST; +input PORT_B_RD_ARST; +input [12:0] PORT_B_ADDR; +input [PORT_B_WIDTH-1:0] PORT_B_WR_DATA; +output [PORT_B_WIDTH-1:0] PORT_B_RD_DATA; + +function [255:0] init_slice; + input integer idx; + integer i; + for (i = 0; i < 32; i = i + 1) begin + init_slice[i*8+:8] = INIT[(idx * 32 + i) * 9 +: 8]; + end +endfunction + +function [255:0] initp_slice; + input integer idx; + integer i; + for (i = 0; i < 256; i = i + 1) begin + initp_slice[i] = INIT[(idx * 256 + i) * 9 + 8]; + end +endfunction + +wire [8:0] DOA; +wire [8:0] DOB; +// the replication is important — the BRAM behaves in... unexpected ways for +// width 1 and 2 +wire [8:0] DIA = {9{PORT_A_WR_DATA}}; +wire [8:0] DIB = {9{PORT_B_WR_DATA}}; + +assign PORT_A_RD_DATA = DOA; +assign PORT_B_RD_DATA = DOB; + +EG_PHY_BRAM #( + .INIT_00(init_slice('h00)), + .INIT_01(init_slice('h01)), + .INIT_02(init_slice('h02)), + .INIT_03(init_slice('h03)), + .INIT_04(init_slice('h04)), + .INIT_05(init_slice('h05)), + .INIT_06(init_slice('h06)), + .INIT_07(init_slice('h07)), + .INIT_08(init_slice('h08)), + .INIT_09(init_slice('h09)), + .INIT_0A(init_slice('h0a)), + .INIT_0B(init_slice('h0b)), + .INIT_0C(init_slice('h0c)), + .INIT_0D(init_slice('h0d)), + .INIT_0E(init_slice('h0e)), + .INIT_0F(init_slice('h0f)), + .INIT_10(init_slice('h10)), + .INIT_11(init_slice('h11)), + .INIT_12(init_slice('h12)), + .INIT_13(init_slice('h13)), + .INIT_14(init_slice('h14)), + .INIT_15(init_slice('h15)), + .INIT_16(init_slice('h16)), + .INIT_17(init_slice('h17)), + .INIT_18(init_slice('h18)), + .INIT_19(init_slice('h19)), + .INIT_1A(init_slice('h1a)), + .INIT_1B(init_slice('h1b)), + .INIT_1C(init_slice('h1c)), + .INIT_1D(init_slice('h1d)), + .INIT_1E(init_slice('h1e)), + .INIT_1F(init_slice('h1f)), + .INITP_00(initp_slice('h00)), + .INITP_01(initp_slice('h01)), + .INITP_02(initp_slice('h02)), + .INITP_03(initp_slice('h03)), + .MODE("DP8K"), + .DATA_WIDTH_A($sformatf("%d", PORT_A_WIDTH)), + .DATA_WIDTH_B($sformatf("%d", PORT_B_WIDTH)), + .REGMODE_A("NOREG"), + .REGMODE_B("NOREG"), + .RESETMODE(OPTION_RESETMODE), + .ASYNC_RESET_RELEASE(OPTION_RESETMODE), + .CLKAMUX(PORT_A_CLK_POL ? "SIG" : "INV"), + .CLKBMUX(PORT_B_CLK_POL ? "SIG" : "INV"), + .WRITEMODE_A(PORT_A_OPTION_WRITEMODE), + .WRITEMODE_B(PORT_B_OPTION_WRITEMODE), +) _TECHMAP_REPLACE_ ( + .clka(PORT_A_CLK), + .wea(PORT_A_WR_EN), + .cea(PORT_A_CLK_EN), + .ocea(1'b1), + .rsta(OPTION_RESETMODE == "SYNC" ? PORT_A_RD_SRST : PORT_A_RD_ARST), + .csa(3'b111), + .addra(PORT_A_WIDTH == 9 ? {PORT_A_ADDR[12:1], 1'b1} : PORT_A_ADDR), + .dia(DIA), + .doa(DOA), + + .clkb(PORT_B_CLK), + .web(PORT_B_WR_EN), + .ceb(PORT_B_CLK_EN), + .oceb(1'b1), + .rstb(OPTION_RESETMODE == "SYNC" ? PORT_B_RD_SRST : PORT_B_RD_ARST), + .csb(3'b111), + .addrb(PORT_B_WIDTH == 9 ? {PORT_B_ADDR[12:1], 1'b1} : PORT_B_ADDR), + .dib(DIB), + .dob(DOB), +); + +endmodule + + +module $__ANLOGIC_BRAM_SDP_ (...); + +parameter INIT = 0; +parameter OPTION_RESETMODE = "SYNC"; + +parameter PORT_R_WIDTH = 18; +parameter PORT_R_CLK_POL = 1; + +input PORT_R_CLK; +input PORT_R_CLK_EN; +input PORT_R_RD_SRST; +input PORT_R_RD_ARST; +input [12:0] PORT_R_ADDR; +output [PORT_R_WIDTH-1:0] PORT_R_RD_DATA; + +parameter PORT_W_WIDTH = 18; +parameter PORT_W_WR_EN_WIDTH = 2; +parameter PORT_W_CLK_POL = 1; + +input PORT_W_CLK; +input PORT_W_CLK_EN; +input [12:0] PORT_W_ADDR; +input [PORT_W_WR_EN_WIDTH-1:0] PORT_W_WR_EN; +input [PORT_W_WIDTH-1:0] PORT_W_WR_DATA; + +function [255:0] init_slice; + input integer idx; + integer i; + for (i = 0; i < 32; i = i + 1) begin + init_slice[i*8+:8] = INIT[(idx * 32 + i) * 9 +: 8]; + end +endfunction + +function [255:0] initp_slice; + input integer idx; + integer i; + for (i = 0; i < 256; i = i + 1) begin + initp_slice[i] = INIT[(idx * 256 + i) * 9 + 8]; + end +endfunction + +wire [17:0] DI = {18{PORT_W_WR_DATA}}; +wire [17:0] DO; + +assign PORT_R_RD_DATA = PORT_R_WIDTH == 18 ? DO : DO[17:9]; + +EG_PHY_BRAM #( + .INIT_00(init_slice('h00)), + .INIT_01(init_slice('h01)), + .INIT_02(init_slice('h02)), + .INIT_03(init_slice('h03)), + .INIT_04(init_slice('h04)), + .INIT_05(init_slice('h05)), + .INIT_06(init_slice('h06)), + .INIT_07(init_slice('h07)), + .INIT_08(init_slice('h08)), + .INIT_09(init_slice('h09)), + .INIT_0A(init_slice('h0a)), + .INIT_0B(init_slice('h0b)), + .INIT_0C(init_slice('h0c)), + .INIT_0D(init_slice('h0d)), + .INIT_0E(init_slice('h0e)), + .INIT_0F(init_slice('h0f)), + .INIT_10(init_slice('h10)), + .INIT_11(init_slice('h11)), + .INIT_12(init_slice('h12)), + .INIT_13(init_slice('h13)), + .INIT_14(init_slice('h14)), + .INIT_15(init_slice('h15)), + .INIT_16(init_slice('h16)), + .INIT_17(init_slice('h17)), + .INIT_18(init_slice('h18)), + .INIT_19(init_slice('h19)), + .INIT_1A(init_slice('h1a)), + .INIT_1B(init_slice('h1b)), + .INIT_1C(init_slice('h1c)), + .INIT_1D(init_slice('h1d)), + .INIT_1E(init_slice('h1e)), + .INIT_1F(init_slice('h1f)), + .INITP_00(initp_slice('h00)), + .INITP_01(initp_slice('h01)), + .INITP_02(initp_slice('h02)), + .INITP_03(initp_slice('h03)), + .MODE("PDPW8K"), + .DATA_WIDTH_A($sformatf("%d", PORT_W_WIDTH)), + .DATA_WIDTH_B($sformatf("%d", PORT_R_WIDTH)), + .REGMODE_A("NOREG"), + .REGMODE_B("NOREG"), + .RESETMODE(OPTION_RESETMODE), + .ASYNC_RESET_RELEASE(OPTION_RESETMODE), + .CLKAMUX(PORT_W_CLK_POL ? "SIG" : "INV"), + .CLKBMUX(PORT_R_CLK_POL ? "SIG" : "INV"), +) _TECHMAP_REPLACE_ ( + .clka(PORT_W_CLK), + .wea(PORT_W_WIDTH >= 9 ? 1'b1 : PORT_W_WR_EN[0]), + .cea(PORT_W_CLK_EN), + .ocea(1'b1), + .rsta(1'b0), + .csa(3'b111), + .addra(PORT_W_WIDTH == 18 ? {PORT_W_ADDR[12:2], PORT_W_WR_EN[1:0]} : (PORT_W_WIDTH == 9 ? {PORT_W_ADDR[12:1], PORT_W_WR_EN[0]} : PORT_W_ADDR)), + .dia(DI[8:0]), + .doa(DO[8:0]), + + .clkb(PORT_R_CLK), + .web(1'b0), + .ceb(PORT_R_CLK_EN), + .oceb(1'b1), + .rstb(OPTION_RESETMODE == "SYNC" ? PORT_R_RD_SRST : PORT_R_RD_ARST), + .csb(3'b111), + .addrb(PORT_R_ADDR), + .dib(DI[17:9]), + .dob(DO[17:9]), +); + +endmodule + + +module $__ANLOGIC_BRAM32K_ (...); + +parameter INIT = 0; + +parameter PORT_A_WIDTH = 16; +parameter PORT_A_WR_EN_WIDTH = 2; +parameter PORT_A_CLK_POL = 1; +parameter PORT_A_OPTION_WRITEMODE = "NORMAL"; + +input PORT_A_CLK; +input PORT_A_CLK_EN; +input [PORT_A_WR_EN_WIDTH-1:0] PORT_A_WR_EN; +input [11:0] PORT_A_ADDR; +input [PORT_A_WIDTH-1:0] PORT_A_WR_DATA; +output [PORT_A_WIDTH-1:0] PORT_A_RD_DATA; + +parameter PORT_B_WIDTH = 16; +parameter PORT_B_WR_EN_WIDTH = 2; +parameter PORT_B_CLK_POL = 1; +parameter PORT_B_OPTION_WRITEMODE = "NORMAL"; + +input PORT_B_CLK; +input PORT_B_CLK_EN; +input [PORT_B_WR_EN_WIDTH-1:0] PORT_B_WR_EN; +input [11:0] PORT_B_ADDR; +input [PORT_B_WIDTH-1:0] PORT_B_WR_DATA; +output [PORT_B_WIDTH-1:0] PORT_B_RD_DATA; + +function [255:0] init_slice; + input integer idx; + init_slice = INIT[256 * idx +: 256]; +endfunction + +wire [15:0] DOA; +wire [15:0] DOB; +wire [15:0] DIA = PORT_A_WR_DATA; +wire [15:0] DIB = PORT_B_WR_DATA; + +assign PORT_A_RD_DATA = DOA; +assign PORT_B_RD_DATA = DOB; + +wire BYTE_A, BYTEWE_A; +wire BYTE_B, BYTEWE_B; + +generate + +if (PORT_A_WIDTH == 8) begin + assign BYTE_A = PORT_A_ADDR[0]; + assign BYTEWE_A = 1; +end else begin + assign BYTE_A = PORT_A_WR_EN == 2; + assign BYTEWE_A = ^PORT_A_WR_EN; +end + +if (PORT_B_WIDTH == 8) begin + assign BYTE_B = PORT_B_ADDR[0]; + assign BYTEWE_B = 1; +end else begin + assign BYTE_B = PORT_B_WR_EN == 2; + assign BYTEWE_B = ^PORT_B_WR_EN; +end + +endgenerate + +EG_PHY_BRAM32K #( + .INIT_00(init_slice('h00)), + .INIT_01(init_slice('h01)), + .INIT_02(init_slice('h02)), + .INIT_03(init_slice('h03)), + .INIT_04(init_slice('h04)), + .INIT_05(init_slice('h05)), + .INIT_06(init_slice('h06)), + .INIT_07(init_slice('h07)), + .INIT_08(init_slice('h08)), + .INIT_09(init_slice('h09)), + .INIT_0A(init_slice('h0a)), + .INIT_0B(init_slice('h0b)), + .INIT_0C(init_slice('h0c)), + .INIT_0D(init_slice('h0d)), + .INIT_0E(init_slice('h0e)), + .INIT_0F(init_slice('h0f)), + .INIT_10(init_slice('h10)), + .INIT_11(init_slice('h11)), + .INIT_12(init_slice('h12)), + .INIT_13(init_slice('h13)), + .INIT_14(init_slice('h14)), + .INIT_15(init_slice('h15)), + .INIT_16(init_slice('h16)), + .INIT_17(init_slice('h17)), + .INIT_18(init_slice('h18)), + .INIT_19(init_slice('h19)), + .INIT_1A(init_slice('h1a)), + .INIT_1B(init_slice('h1b)), + .INIT_1C(init_slice('h1c)), + .INIT_1D(init_slice('h1d)), + .INIT_1E(init_slice('h1e)), + .INIT_1F(init_slice('h1f)), + .INIT_20(init_slice('h20)), + .INIT_21(init_slice('h21)), + .INIT_22(init_slice('h22)), + .INIT_23(init_slice('h23)), + .INIT_24(init_slice('h24)), + .INIT_25(init_slice('h25)), + .INIT_26(init_slice('h26)), + .INIT_27(init_slice('h27)), + .INIT_28(init_slice('h28)), + .INIT_29(init_slice('h29)), + .INIT_2A(init_slice('h2a)), + .INIT_2B(init_slice('h2b)), + .INIT_2C(init_slice('h2c)), + .INIT_2D(init_slice('h2d)), + .INIT_2E(init_slice('h2e)), + .INIT_2F(init_slice('h2f)), + .INIT_30(init_slice('h30)), + .INIT_31(init_slice('h31)), + .INIT_32(init_slice('h32)), + .INIT_33(init_slice('h33)), + .INIT_34(init_slice('h34)), + .INIT_35(init_slice('h35)), + .INIT_36(init_slice('h36)), + .INIT_37(init_slice('h37)), + .INIT_38(init_slice('h38)), + .INIT_39(init_slice('h39)), + .INIT_3A(init_slice('h3a)), + .INIT_3B(init_slice('h3b)), + .INIT_3C(init_slice('h3c)), + .INIT_3D(init_slice('h3d)), + .INIT_3E(init_slice('h3e)), + .INIT_3F(init_slice('h3f)), + .INIT_40(init_slice('h40)), + .INIT_41(init_slice('h41)), + .INIT_42(init_slice('h42)), + .INIT_43(init_slice('h43)), + .INIT_44(init_slice('h44)), + .INIT_45(init_slice('h45)), + .INIT_46(init_slice('h46)), + .INIT_47(init_slice('h47)), + .INIT_48(init_slice('h48)), + .INIT_49(init_slice('h49)), + .INIT_4A(init_slice('h4a)), + .INIT_4B(init_slice('h4b)), + .INIT_4C(init_slice('h4c)), + .INIT_4D(init_slice('h4d)), + .INIT_4E(init_slice('h4e)), + .INIT_4F(init_slice('h4f)), + .INIT_50(init_slice('h50)), + .INIT_51(init_slice('h51)), + .INIT_52(init_slice('h52)), + .INIT_53(init_slice('h53)), + .INIT_54(init_slice('h54)), + .INIT_55(init_slice('h55)), + .INIT_56(init_slice('h56)), + .INIT_57(init_slice('h57)), + .INIT_58(init_slice('h58)), + .INIT_59(init_slice('h59)), + .INIT_5A(init_slice('h5a)), + .INIT_5B(init_slice('h5b)), + .INIT_5C(init_slice('h5c)), + .INIT_5D(init_slice('h5d)), + .INIT_5E(init_slice('h5e)), + .INIT_5F(init_slice('h5f)), + .INIT_60(init_slice('h60)), + .INIT_61(init_slice('h61)), + .INIT_62(init_slice('h62)), + .INIT_63(init_slice('h63)), + .INIT_64(init_slice('h64)), + .INIT_65(init_slice('h65)), + .INIT_66(init_slice('h66)), + .INIT_67(init_slice('h67)), + .INIT_68(init_slice('h68)), + .INIT_69(init_slice('h69)), + .INIT_6A(init_slice('h6a)), + .INIT_6B(init_slice('h6b)), + .INIT_6C(init_slice('h6c)), + .INIT_6D(init_slice('h6d)), + .INIT_6E(init_slice('h6e)), + .INIT_6F(init_slice('h6f)), + .INIT_70(init_slice('h70)), + .INIT_71(init_slice('h71)), + .INIT_72(init_slice('h72)), + .INIT_73(init_slice('h73)), + .INIT_74(init_slice('h74)), + .INIT_75(init_slice('h75)), + .INIT_76(init_slice('h76)), + .INIT_77(init_slice('h77)), + .INIT_78(init_slice('h78)), + .INIT_79(init_slice('h79)), + .INIT_7A(init_slice('h7a)), + .INIT_7B(init_slice('h7b)), + .INIT_7C(init_slice('h7c)), + .INIT_7D(init_slice('h7d)), + .INIT_7E(init_slice('h7e)), + .INIT_7F(init_slice('h7f)), + .MODE("DP16K"), + .DATA_WIDTH_A($sformatf("%d", PORT_A_WIDTH)), + .DATA_WIDTH_B($sformatf("%d", PORT_B_WIDTH)), + .REGMODE_A("NOREG"), + .REGMODE_B("NOREG"), + .WRITEMODE_A(PORT_A_OPTION_WRITEMODE), + .WRITEMODE_B(PORT_B_OPTION_WRITEMODE), + .CLKAMUX(PORT_A_CLK_POL ? "SIG" : "INV"), + .CLKBMUX(PORT_B_CLK_POL ? "SIG" : "INV"), +) _TECHMAP_REPLACE_ ( + .clka(PORT_A_CLK), + .csa(PORT_A_CLK_EN), + .wea(|PORT_A_WR_EN), + .ocea(1'b1), + .rsta(1'b0), + .addra(PORT_A_ADDR[11:1]), + .bytea(BYTE_A), + .bytewea(BYTEWE_A), + .dia(DIA), + .doa(DOA), + + .clkb(PORT_B_CLK), + .csb(PORT_B_CLK_EN), + .web(|PORT_B_WR_EN), + .ocea(1'b1), + .rsta(1'b0), + .addrb(PORT_B_ADDR[11:1]), + .byteb(BYTE_B), + .byteweb(BYTEWE_B), + .dib(DIB), + .dob(DOB), +); + +endmodule diff --git a/techlibs/anlogic/lutram_init_16x4.vh b/techlibs/anlogic/lutram_init_16x4.vh deleted file mode 100644 index 32fb1578c..000000000 --- a/techlibs/anlogic/lutram_init_16x4.vh +++ /dev/null @@ -1,16 +0,0 @@ -.INIT_D0({INIT[15*4+0], INIT[14*4+0], INIT[13*4+0], INIT[12*4+0], - INIT[11*4+0], INIT[10*4+0], INIT[9*4+0], INIT[8*4+0], - INIT[7*4+0], INIT[6*4+0], INIT[5*4+0], INIT[4*4+0], - INIT[3*4+0], INIT[2*4+0], INIT[1*4+0], INIT[0*4+0]}), -.INIT_D1({INIT[15*4+1], INIT[14*4+1], INIT[13*4+1], INIT[12*4+1], - INIT[11*4+1], INIT[10*4+1], INIT[9*4+1], INIT[8*4+1], - INIT[7*4+1], INIT[6*4+1], INIT[5*4+1], INIT[4*4+1], - INIT[3*4+1], INIT[2*4+1], INIT[1*4+1], INIT[0*4+1]}), -.INIT_D2({INIT[15*4+2], INIT[14*4+2], INIT[13*4+2], INIT[12*4+2], - INIT[11*4+2], INIT[10*4+2], INIT[9*4+2], INIT[8*4+2], - INIT[7*4+2], INIT[6*4+2], INIT[5*4+2], INIT[4*4+2], - INIT[3*4+2], INIT[2*4+2], INIT[1*4+2], INIT[0*4+2]}), -.INIT_D3({INIT[15*4+3], INIT[14*4+3], INIT[13*4+3], INIT[12*4+3], - INIT[11*4+3], INIT[10*4+3], INIT[9*4+3], INIT[8*4+3], - INIT[7*4+3], INIT[6*4+3], INIT[5*4+3], INIT[4*4+3], - INIT[3*4+3], INIT[2*4+3], INIT[1*4+3], INIT[0*4+3]}) diff --git a/techlibs/anlogic/lutrams.txt b/techlibs/anlogic/lutrams.txt index 4e903c0a2..ef6fec24e 100644 --- a/techlibs/anlogic/lutrams.txt +++ b/techlibs/anlogic/lutrams.txt @@ -1,16 +1,12 @@ -bram $__ANLOGIC_DRAM16X4 - init 1 - abits 4 - dbits 4 - groups 2 - ports 1 1 - wrmode 0 1 - enable 0 1 - transp 0 0 - clocks 0 1 - clkpol 0 1 -endbram - -match $__ANLOGIC_DRAM16X4 - make_outreg -endmatch +ram distributed $__ANLOGIC_DRAM16X4_ { + abits 4; + width 4; + cost 4; + init no_undef; + prune_rom; + port sw "W" { + clock posedge; + } + port ar "R" { + } +} diff --git a/techlibs/anlogic/lutrams_map.v b/techlibs/anlogic/lutrams_map.v index 5a464cafc..6314da22a 100644 --- a/techlibs/anlogic/lutrams_map.v +++ b/techlibs/anlogic/lutrams_map.v @@ -1,22 +1,32 @@ -module \$__ANLOGIC_DRAM16X4 (CLK1, A1ADDR, A1DATA, B1ADDR, B1DATA, B1EN); - parameter [63:0]INIT = 64'bx; - input CLK1; +module $__ANLOGIC_DRAM16X4_ (...); + parameter INIT = 64'b0; - input [3:0] A1ADDR; - output [3:0] A1DATA; + input PORT_W_CLK; + input [3:0] PORT_W_ADDR; + input [3:0] PORT_W_WR_DATA; + input PORT_W_WR_EN; - input [3:0] B1ADDR; - input [3:0] B1DATA; - input B1EN; + input [3:0] PORT_R_ADDR; + output [3:0] PORT_R_RD_DATA; + + function [15:0] init_slice; + input integer idx; + integer i; + for (i = 0; i < 16; i = i + 1) + init_slice[i] = INIT[i * 4 + idx]; + endfunction EG_LOGIC_DRAM16X4 #( - `include "lutram_init_16x4.vh" + .INIT_D0(init_slice(0)), + .INIT_D1(init_slice(1)), + .INIT_D2(init_slice(2)), + .INIT_D3(init_slice(3)) ) _TECHMAP_REPLACE_ ( - .di(B1DATA), - .waddr(B1ADDR), - .wclk(CLK1), - .we(B1EN), - .raddr(A1ADDR), - .do(A1DATA) + .di(PORT_W_WR_DATA), + .waddr(PORT_W_ADDR), + .wclk(PORT_W_CLK), + .we(PORT_W_WR_EN), + .raddr(PORT_R_ADDR), + .do(PORT_R_RD_DATA) ); endmodule diff --git a/techlibs/anlogic/synth_anlogic.cc b/techlibs/anlogic/synth_anlogic.cc index 039cae00e..a3c1e0434 100644 --- a/techlibs/anlogic/synth_anlogic.cc +++ b/techlibs/anlogic/synth_anlogic.cc @@ -63,6 +63,9 @@ struct SynthAnlogicPass : public ScriptPass log(" -nolutram\n"); log(" do not use EG_LOGIC_DRAM16X4 cells in output netlist\n"); log("\n"); + log(" -nobram\n"); + log(" do not use EG_PHY_BRAM or EG_PHY_BRAM32K cells in output netlist\n"); + log("\n"); log("\n"); log("The following commands are executed by this synthesis command:\n"); help_script(); @@ -70,7 +73,7 @@ struct SynthAnlogicPass : public ScriptPass } string top_opt, edif_file, json_file; - bool flatten, retime, nolutram; + bool flatten, retime, nolutram, nobram; void clear_flags() override { @@ -80,6 +83,7 @@ struct SynthAnlogicPass : public ScriptPass flatten = true; retime = false; nolutram = false; + nobram = false; } void execute(std::vector<std::string> args, RTLIL::Design *design) override @@ -118,6 +122,10 @@ struct SynthAnlogicPass : public ScriptPass nolutram = true; continue; } + if (args[argidx] == "-nobram") { + nobram = true; + continue; + } if (args[argidx] == "-retime") { retime = true; continue; @@ -158,11 +166,17 @@ struct SynthAnlogicPass : public ScriptPass run("synth -run coarse"); } - if (!nolutram && check_label("map_lutram", "(skip if -nolutram)")) + if (check_label("map_ram")) { - run("memory_bram -rules +/anlogic/lutrams.txt"); - run("techmap -map +/anlogic/lutrams_map.v"); - run("setundef -zero -params t:EG_LOGIC_DRAM16X4"); + std::string args = ""; + if (nobram) + args += " -no-auto-block"; + if (nolutram) + args += " -no-auto-distributed"; + if (help_mode) + args += " [-no-auto-block] [-no-auto-distributed]"; + run("memory_libmap -lib +/anlogic/lutrams.txt -lib +/anlogic/brams.txt" + args, "(-no-auto-block if -nobram, -no-auto-distributed if -nolutram)"); + run("techmap -map +/anlogic/lutrams_map.v -map +/anlogic/brams_map.v"); } if (check_label("map_ffram")) diff --git a/techlibs/common/gen_fine_ffs.py b/techlibs/common/gen_fine_ffs.py index 5d331e767..25c6ef171 100644 --- a/techlibs/common/gen_fine_ffs.py +++ b/techlibs/common/gen_fine_ffs.py @@ -133,6 +133,55 @@ endmodule """ // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| //- +//- $_ALDFF_{C:N|P}{L:N|P}_ (D, C, L, AD, Q) +//- +//- A {C:negative|positive} edge D-type flip-flop with {L:negative|positive} polarity async load. +//- +//- Truth table: D C L AD | Q +//- ----------+--- +//- - - {L:0|1} a | a +//- d {C:\\|/} - - | d +//- - - - - | q +//- +module \$_ALDFF_{C:N|P}{L:N|P}_ (D, C, L, AD, Q); +input D, C, L, AD; +output reg Q; +always @({C:neg|pos}edge C or {L:neg|pos}edge L) begin + if (L == {L:0|1}) + Q <= AD; + else + Q <= D; +end +endmodule +""", +""" +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $_ALDFFE_{C:N|P}{L:N|P}{E:N|P}_ (D, C, L, AD, E, Q) +//- +//- A {C:negative|positive} edge D-type flip-flop with {L:negative|positive} polarity async load and {E:negative|positive} +//- polarity clock enable. +//- +//- Truth table: D C L AD E | Q +//- ------------+--- +//- - - {L:0|1} a - | a +//- d {C:\\|/} - - {E:0|1} | d +//- - - - - - | q +//- +module \$_ALDFFE_{C:N|P}{L:N|P}{E:N|P}_ (D, C, L, AD, E, Q); +input D, C, L, AD, E; +output reg Q; +always @({C:neg|pos}edge C or {L:neg|pos}edge L) begin + if (L == {L:0|1}) + Q <= AD; + else if (E == {E:0|1}) + Q <= D; +end +endmodule +""", +""" +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- //- $_DFFSR_{C:N|P}{S:N|P}{R:N|P}_ (C, S, R, D, Q) //- //- A {C:negative|positive} edge D-type flip-flop with {S:negative|positive} polarity set and {R:negative|positive} diff --git a/techlibs/common/simcells.v b/techlibs/common/simcells.v index 7d9bebe2a..ad1fdc817 100644 --- a/techlibs/common/simcells.v +++ b/techlibs/common/simcells.v @@ -1254,6 +1254,290 @@ endmodule // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| //- +//- $_ALDFF_NN_ (D, C, L, AD, Q) +//- +//- A negative edge D-type flip-flop with negative polarity async load. +//- +//- Truth table: D C L AD | Q +//- ----------+--- +//- - - 0 a | a +//- d \ - - | d +//- - - - - | q +//- +module \$_ALDFF_NN_ (D, C, L, AD, Q); +input D, C, L, AD; +output reg Q; +always @(negedge C or negedge L) begin + if (L == 0) + Q <= AD; + else + Q <= D; +end +endmodule + +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $_ALDFF_NP_ (D, C, L, AD, Q) +//- +//- A negative edge D-type flip-flop with positive polarity async load. +//- +//- Truth table: D C L AD | Q +//- ----------+--- +//- - - 1 a | a +//- d \ - - | d +//- - - - - | q +//- +module \$_ALDFF_NP_ (D, C, L, AD, Q); +input D, C, L, AD; +output reg Q; +always @(negedge C or posedge L) begin + if (L == 1) + Q <= AD; + else + Q <= D; +end +endmodule + +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $_ALDFF_PN_ (D, C, L, AD, Q) +//- +//- A positive edge D-type flip-flop with negative polarity async load. +//- +//- Truth table: D C L AD | Q +//- ----------+--- +//- - - 0 a | a +//- d / - - | d +//- - - - - | q +//- +module \$_ALDFF_PN_ (D, C, L, AD, Q); +input D, C, L, AD; +output reg Q; +always @(posedge C or negedge L) begin + if (L == 0) + Q <= AD; + else + Q <= D; +end +endmodule + +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $_ALDFF_PP_ (D, C, L, AD, Q) +//- +//- A positive edge D-type flip-flop with positive polarity async load. +//- +//- Truth table: D C L AD | Q +//- ----------+--- +//- - - 1 a | a +//- d / - - | d +//- - - - - | q +//- +module \$_ALDFF_PP_ (D, C, L, AD, Q); +input D, C, L, AD; +output reg Q; +always @(posedge C or posedge L) begin + if (L == 1) + Q <= AD; + else + Q <= D; +end +endmodule + +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $_ALDFFE_NNN_ (D, C, L, AD, E, Q) +//- +//- A negative edge D-type flip-flop with negative polarity async load and negative +//- polarity clock enable. +//- +//- Truth table: D C L AD E | Q +//- ------------+--- +//- - - 0 a - | a +//- d \ - - 0 | d +//- - - - - - | q +//- +module \$_ALDFFE_NNN_ (D, C, L, AD, E, Q); +input D, C, L, AD, E; +output reg Q; +always @(negedge C or negedge L) begin + if (L == 0) + Q <= AD; + else if (E == 0) + Q <= D; +end +endmodule + +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $_ALDFFE_NNP_ (D, C, L, AD, E, Q) +//- +//- A negative edge D-type flip-flop with negative polarity async load and positive +//- polarity clock enable. +//- +//- Truth table: D C L AD E | Q +//- ------------+--- +//- - - 0 a - | a +//- d \ - - 1 | d +//- - - - - - | q +//- +module \$_ALDFFE_NNP_ (D, C, L, AD, E, Q); +input D, C, L, AD, E; +output reg Q; +always @(negedge C or negedge L) begin + if (L == 0) + Q <= AD; + else if (E == 1) + Q <= D; +end +endmodule + +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $_ALDFFE_NPN_ (D, C, L, AD, E, Q) +//- +//- A negative edge D-type flip-flop with positive polarity async load and negative +//- polarity clock enable. +//- +//- Truth table: D C L AD E | Q +//- ------------+--- +//- - - 1 a - | a +//- d \ - - 0 | d +//- - - - - - | q +//- +module \$_ALDFFE_NPN_ (D, C, L, AD, E, Q); +input D, C, L, AD, E; +output reg Q; +always @(negedge C or posedge L) begin + if (L == 1) + Q <= AD; + else if (E == 0) + Q <= D; +end +endmodule + +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $_ALDFFE_NPP_ (D, C, L, AD, E, Q) +//- +//- A negative edge D-type flip-flop with positive polarity async load and positive +//- polarity clock enable. +//- +//- Truth table: D C L AD E | Q +//- ------------+--- +//- - - 1 a - | a +//- d \ - - 1 | d +//- - - - - - | q +//- +module \$_ALDFFE_NPP_ (D, C, L, AD, E, Q); +input D, C, L, AD, E; +output reg Q; +always @(negedge C or posedge L) begin + if (L == 1) + Q <= AD; + else if (E == 1) + Q <= D; +end +endmodule + +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $_ALDFFE_PNN_ (D, C, L, AD, E, Q) +//- +//- A positive edge D-type flip-flop with negative polarity async load and negative +//- polarity clock enable. +//- +//- Truth table: D C L AD E | Q +//- ------------+--- +//- - - 0 a - | a +//- d / - - 0 | d +//- - - - - - | q +//- +module \$_ALDFFE_PNN_ (D, C, L, AD, E, Q); +input D, C, L, AD, E; +output reg Q; +always @(posedge C or negedge L) begin + if (L == 0) + Q <= AD; + else if (E == 0) + Q <= D; +end +endmodule + +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $_ALDFFE_PNP_ (D, C, L, AD, E, Q) +//- +//- A positive edge D-type flip-flop with negative polarity async load and positive +//- polarity clock enable. +//- +//- Truth table: D C L AD E | Q +//- ------------+--- +//- - - 0 a - | a +//- d / - - 1 | d +//- - - - - - | q +//- +module \$_ALDFFE_PNP_ (D, C, L, AD, E, Q); +input D, C, L, AD, E; +output reg Q; +always @(posedge C or negedge L) begin + if (L == 0) + Q <= AD; + else if (E == 1) + Q <= D; +end +endmodule + +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $_ALDFFE_PPN_ (D, C, L, AD, E, Q) +//- +//- A positive edge D-type flip-flop with positive polarity async load and negative +//- polarity clock enable. +//- +//- Truth table: D C L AD E | Q +//- ------------+--- +//- - - 1 a - | a +//- d / - - 0 | d +//- - - - - - | q +//- +module \$_ALDFFE_PPN_ (D, C, L, AD, E, Q); +input D, C, L, AD, E; +output reg Q; +always @(posedge C or posedge L) begin + if (L == 1) + Q <= AD; + else if (E == 0) + Q <= D; +end +endmodule + +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $_ALDFFE_PPP_ (D, C, L, AD, E, Q) +//- +//- A positive edge D-type flip-flop with positive polarity async load and positive +//- polarity clock enable. +//- +//- Truth table: D C L AD E | Q +//- ------------+--- +//- - - 1 a - | a +//- d / - - 1 | d +//- - - - - - | q +//- +module \$_ALDFFE_PPP_ (D, C, L, AD, E, Q); +input D, C, L, AD, E; +output reg Q; +always @(posedge C or posedge L) begin + if (L == 1) + Q <= AD; + else if (E == 1) + Q <= D; +end +endmodule + +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- //- $_DFFSR_NNN_ (C, S, R, D, Q) //- //- A negative edge D-type flip-flop with negative polarity set and negative diff --git a/techlibs/common/simlib.v b/techlibs/common/simlib.v index cf0839ebe..b14488ff4 100644 --- a/techlibs/common/simlib.v +++ b/techlibs/common/simlib.v @@ -1292,6 +1292,33 @@ endmodule // -------------------------------------------------------- +module \$bmux (A, S, Y); + +parameter WIDTH = 0; +parameter S_WIDTH = 0; + +input [(WIDTH << S_WIDTH)-1:0] A; +input [S_WIDTH-1:0] S; +output [WIDTH-1:0] Y; + +wire [WIDTH-1:0] bm0_out, bm1_out; + +generate + if (S_WIDTH > 1) begin:muxlogic + \$bmux #(.WIDTH(WIDTH), .S_WIDTH(S_WIDTH-1)) bm0 (.A(A), .S(S[S_WIDTH-2:0]), .Y(bm0_out)); + \$bmux #(.WIDTH(WIDTH), .S_WIDTH(S_WIDTH-1)) bm1 (.A(A[(WIDTH << S_WIDTH)-1:WIDTH << (S_WIDTH - 1)]), .S(S[S_WIDTH-2:0]), .Y(bm1_out)); + assign Y = S[S_WIDTH-1] ? bm1_out : bm0_out; + end else if (S_WIDTH == 1) begin:simple + assign Y = S ? A[1] : A[0]; + end else begin:passthru + assign Y = A; + end +endgenerate + +endmodule + +// -------------------------------------------------------- + module \$pmux (A, B, S, Y); parameter WIDTH = 0; @@ -1318,6 +1345,26 @@ end endmodule // -------------------------------------------------------- + +module \$demux (A, S, Y); + +parameter WIDTH = 1; +parameter S_WIDTH = 1; + +input [WIDTH-1:0] A; +input [S_WIDTH-1:0] S; +output [(WIDTH << S_WIDTH)-1:0] Y; + +genvar i; +generate + for (i = 0; i < (1 << S_WIDTH); i = i + 1) begin:slices + assign Y[i*WIDTH+:WIDTH] = (S == i) ? A : 0; + end +endgenerate + +endmodule + +// -------------------------------------------------------- `ifndef SIMLIB_NOLUT module \$lut (A, Y); @@ -1326,30 +1373,9 @@ parameter WIDTH = 0; parameter LUT = 0; input [WIDTH-1:0] A; -output reg Y; - -wire lut0_out, lut1_out; +output Y; -generate - if (WIDTH <= 1) begin:simple - assign {lut1_out, lut0_out} = LUT; - end else begin:complex - \$lut #( .WIDTH(WIDTH-1), .LUT(LUT ) ) lut0 ( .A(A[WIDTH-2:0]), .Y(lut0_out) ); - \$lut #( .WIDTH(WIDTH-1), .LUT(LUT >> (2**(WIDTH-1))) ) lut1 ( .A(A[WIDTH-2:0]), .Y(lut1_out) ); - end - - if (WIDTH > 0) begin:lutlogic - always @* begin - casez ({A[WIDTH-1], lut0_out, lut1_out}) - 3'b?11: Y = 1'b1; - 3'b?00: Y = 1'b0; - 3'b0??: Y = lut0_out; - 3'b1??: Y = lut1_out; - default: Y = 1'bx; - endcase - end - end -endgenerate +\$bmux #(.WIDTH(1), .S_WIDTH(WIDTH)) mux(.A(LUT), .S(A), .Y(Y)); endmodule @@ -1890,6 +1916,30 @@ endmodule // -------------------------------------------------------- +module \$aldff (CLK, ALOAD, AD, D, Q); + +parameter WIDTH = 0; +parameter CLK_POLARITY = 1'b1; +parameter ALOAD_POLARITY = 1'b1; + +input CLK, ALOAD; +input [WIDTH-1:0] AD; +input [WIDTH-1:0] D; +output reg [WIDTH-1:0] Q; +wire pos_clk = CLK == CLK_POLARITY; +wire pos_aload = ALOAD == ALOAD_POLARITY; + +always @(posedge pos_clk, posedge pos_aload) begin + if (pos_aload) + Q <= AD; + else + Q <= D; +end + +endmodule + +// -------------------------------------------------------- + module \$sdff (CLK, SRST, D, Q); parameter WIDTH = 0; @@ -1939,6 +1989,31 @@ endmodule // -------------------------------------------------------- +module \$aldffe (CLK, ALOAD, AD, EN, D, Q); + +parameter WIDTH = 0; +parameter CLK_POLARITY = 1'b1; +parameter EN_POLARITY = 1'b1; +parameter ALOAD_POLARITY = 1'b1; + +input CLK, ALOAD, EN; +input [WIDTH-1:0] D; +input [WIDTH-1:0] AD; +output reg [WIDTH-1:0] Q; +wire pos_clk = CLK == CLK_POLARITY; +wire pos_aload = ALOAD == ALOAD_POLARITY; + +always @(posedge pos_clk, posedge pos_aload) begin + if (pos_aload) + Q <= AD; + else if (EN == EN_POLARITY) + Q <= D; +end + +endmodule + +// -------------------------------------------------------- + module \$sdffe (CLK, SRST, EN, D, Q); parameter WIDTH = 0; diff --git a/techlibs/common/techmap.v b/techlibs/common/techmap.v index d3dc85f24..91d385b80 100644 --- a/techlibs/common/techmap.v +++ b/techlibs/common/techmap.v @@ -59,12 +59,12 @@ module _90_simplemap_compare_ops; endmodule (* techmap_simplemap *) -(* techmap_celltype = "$pos $slice $concat $mux $tribuf" *) +(* techmap_celltype = "$pos $slice $concat $mux $tribuf $bmux" *) module _90_simplemap_various; endmodule (* techmap_simplemap *) -(* techmap_celltype = "$sr $ff $dff $dffe $adff $adffe $sdff $sdffe $sdffce $dffsr $dffsre $dlatch $adlatch $dlatchsr" *) +(* techmap_celltype = "$sr $ff $dff $dffe $adff $adffe $aldff $aldffe $sdff $sdffe $sdffce $dffsr $dffsre $dlatch $adlatch $dlatchsr" *) module _90_simplemap_registers; endmodule @@ -597,6 +597,43 @@ module _90_pmux (A, B, S, Y); assign Y = |S ? Y_B : A; endmodule +// -------------------------------------------------------- +// Demultiplexers +// -------------------------------------------------------- + +(* techmap_celltype = "$demux" *) +module _90_demux (A, S, Y); + parameter WIDTH = 1; + parameter S_WIDTH = 1; + + (* force_downto *) + input [WIDTH-1:0] A; + (* force_downto *) + input [S_WIDTH-1:0] S; + (* force_downto *) + output [(WIDTH << S_WIDTH)-1:0] Y; + + generate + if (S_WIDTH == 0) begin + assign Y = A; + end else if (S_WIDTH == 1) begin + assign Y[0+:WIDTH] = S ? 0 : A; + assign Y[WIDTH+:WIDTH] = S ? A : 0; + end else begin + localparam SPLIT = S_WIDTH / 2; + wire [(1 << (S_WIDTH-SPLIT))-1:0] YH; + wire [(1 << SPLIT)-1:0] YL; + $demux #(.WIDTH(1), .S_WIDTH(SPLIT)) lo (.A(1'b1), .S(S[SPLIT-1:0]), .Y(YL)); + $demux #(.WIDTH(1), .S_WIDTH(S_WIDTH-SPLIT)) hi (.A(1'b1), .S(S[S_WIDTH-1:SPLIT]), .Y(YH)); + genvar i; + for (i = 0; i < (1 << S_WIDTH); i = i + 1) begin + localparam [S_WIDTH-1:0] IDX = i; + assign Y[i*WIDTH+:WIDTH] = (YL[IDX[SPLIT-1:0]] & YH[IDX[S_WIDTH-1:SPLIT]]) ? A : 0; + end + end + endgenerate +endmodule + // -------------------------------------------------------- // LUTs diff --git a/techlibs/ecp5/.gitignore b/techlibs/ecp5/.gitignore deleted file mode 100644 index 9d4723264..000000000 --- a/techlibs/ecp5/.gitignore +++ /dev/null @@ -1,10 +0,0 @@ -bram_init_1_2_4.vh -bram_init_9_18_36.vh -brams_init.mk -bram_conn_1.vh -bram_conn_2.vh -bram_conn_4.vh -bram_conn_9.vh -bram_conn_18.vh -bram_conn_36.vh -brams_connect.mk diff --git a/techlibs/ecp5/Makefile.inc b/techlibs/ecp5/Makefile.inc index 4c1bc23b5..f9fa79ab9 100644 --- a/techlibs/ecp5/Makefile.inc +++ b/techlibs/ecp5/Makefile.inc @@ -1,15 +1,6 @@ OBJS += techlibs/ecp5/synth_ecp5.o techlibs/ecp5/ecp5_gsr.o -GENFILES += techlibs/ecp5/bram_init_1_2_4.vh -GENFILES += techlibs/ecp5/bram_init_9_18_36.vh -GENFILES += techlibs/ecp5/bram_conn_1.vh -GENFILES += techlibs/ecp5/bram_conn_2.vh -GENFILES += techlibs/ecp5/bram_conn_4.vh -GENFILES += techlibs/ecp5/bram_conn_9.vh -GENFILES += techlibs/ecp5/bram_conn_18.vh -GENFILES += techlibs/ecp5/bram_conn_36.vh - $(eval $(call add_share_file,share/ecp5,techlibs/ecp5/cells_ff.vh)) $(eval $(call add_share_file,share/ecp5,techlibs/ecp5/cells_io.vh)) $(eval $(call add_share_file,share/ecp5,techlibs/ecp5/cells_map.v)) @@ -22,37 +13,3 @@ $(eval $(call add_share_file,share/ecp5,techlibs/ecp5/brams.txt)) $(eval $(call add_share_file,share/ecp5,techlibs/ecp5/arith_map.v)) $(eval $(call add_share_file,share/ecp5,techlibs/ecp5/latches_map.v)) $(eval $(call add_share_file,share/ecp5,techlibs/ecp5/dsp_map.v)) - -EXTRA_OBJS += techlibs/ecp5/brams_init.mk techlibs/ecp5/brams_connect.mk -.SECONDARY: techlibs/ecp5/brams_init.mk techlibs/ecp5/brams_connect.mk - -techlibs/ecp5/brams_init.mk: techlibs/ecp5/brams_init.py - $(Q) mkdir -p techlibs/ecp5 - $(P) $(PYTHON_EXECUTABLE) $< - $(Q) touch $@ - -techlibs/ecp5/brams_connect.mk: techlibs/ecp5/brams_connect.py - $(Q) mkdir -p techlibs/ecp5 - $(P) $(PYTHON_EXECUTABLE) $< - $(Q) touch $@ - - -techlibs/ecp5/bram_init_1_2_4.vh: techlibs/ecp5/brams_init.mk -techlibs/ecp5/bram_init_9_18_36.vh: techlibs/ecp5/brams_init.mk - -techlibs/ecp5/bram_conn_1.vh: techlibs/ecp5/brams_connect.mk -techlibs/ecp5/bram_conn_2.vh: techlibs/ecp5/brams_connect.mk -techlibs/ecp5/bram_conn_4.vh: techlibs/ecp5/brams_connect.mk -techlibs/ecp5/bram_conn_9.vh: techlibs/ecp5/brams_connect.mk -techlibs/ecp5/bram_conn_18.vh: techlibs/ecp5/brams_connect.mk -techlibs/ecp5/bram_conn_36.vh: techlibs/ecp5/brams_connect.mk - -$(eval $(call add_gen_share_file,share/ecp5,techlibs/ecp5/bram_init_1_2_4.vh)) -$(eval $(call add_gen_share_file,share/ecp5,techlibs/ecp5/bram_init_9_18_36.vh)) - -$(eval $(call add_gen_share_file,share/ecp5,techlibs/ecp5/bram_conn_1.vh)) -$(eval $(call add_gen_share_file,share/ecp5,techlibs/ecp5/bram_conn_2.vh)) -$(eval $(call add_gen_share_file,share/ecp5,techlibs/ecp5/bram_conn_4.vh)) -$(eval $(call add_gen_share_file,share/ecp5,techlibs/ecp5/bram_conn_9.vh)) -$(eval $(call add_gen_share_file,share/ecp5,techlibs/ecp5/bram_conn_18.vh)) -$(eval $(call add_gen_share_file,share/ecp5,techlibs/ecp5/bram_conn_36.vh)) diff --git a/techlibs/ecp5/brams.txt b/techlibs/ecp5/brams.txt index 615d8b2e5..db28a40d7 100644 --- a/techlibs/ecp5/brams.txt +++ b/techlibs/ecp5/brams.txt @@ -1,114 +1,52 @@ -bram $__ECP5_PDPW16KD - init 1 - - abits 9 - dbits 36 - - groups 2 - ports 1 1 - wrmode 1 0 - enable 4 1 - transp 0 0 - clocks 2 3 - clkpol 2 3 -endbram - -bram $__ECP5_DP16KD - init 1 - - abits 10 @a10d18 - dbits 18 @a10d18 - abits 11 @a11d9 - dbits 9 @a11d9 - abits 12 @a12d4 - dbits 4 @a12d4 - abits 13 @a13d2 - dbits 2 @a13d2 - abits 14 @a14d1 - dbits 1 @a14d1 - - groups 2 - ports 1 1 - wrmode 1 0 - enable 2 1 @a10d18 - enable 1 1 @a11d9 @a12d4 @a13d2 @a14d1 - transp 0 2 - clocks 2 3 - clkpol 2 3 -endbram - -# The syn_* attributes are described in: -# https://www.latticesemi.com/view_document?document_id=51556 -attr_icase 1 - -match $__ECP5_PDPW16KD - # implicitly requested RAM or ROM - attribute !syn_ramstyle syn_ramstyle=auto - attribute !syn_romstyle syn_romstyle=auto - attribute !ram_block - attribute !rom_block - attribute !logic_block - min bits 2048 - min efficiency 5 - shuffle_enable A - make_transp - or_next_if_better -endmatch - -match $__ECP5_PDPW16KD - # explicitly requested RAM - attribute syn_ramstyle=block_ram ram_block - attribute !syn_romstyle - attribute !rom_block - attribute !logic_block - min wports 1 - shuffle_enable A - make_transp - or_next_if_better -endmatch - -match $__ECP5_PDPW16KD - # explicitly requested ROM - attribute syn_romstyle=ebr rom_block - attribute !syn_ramstyle - attribute !ram_block - attribute !logic_block - max wports 0 - shuffle_enable A - make_transp - or_next_if_better -endmatch - -match $__ECP5_DP16KD - # implicitly requested RAM or ROM - attribute !syn_ramstyle syn_ramstyle=auto - attribute !syn_romstyle syn_romstyle=auto - attribute !ram_block - attribute !rom_block - attribute !logic_block - min bits 2048 - min efficiency 5 - shuffle_enable A - or_next_if_better -endmatch - -match $__ECP5_DP16KD - # explicitly requested RAM - attribute syn_ramstyle=block_ram ram_block - attribute !syn_romstyle - attribute !rom_block - attribute !logic_block - min wports 1 - shuffle_enable A - or_next_if_better -endmatch - -match $__ECP5_DP16KD - # explicitly requested ROM - attribute syn_romstyle=ebr rom_block - attribute !syn_ramstyle - attribute !ram_block - attribute !logic_block - max wports 0 - shuffle_enable A -endmatch +ram block $__ECP5_DP16KD_ { + abits 14; + widths 1 2 4 9 18 per_port; + byte 9; + cost 128; + init no_undef; + port srsw "A" "B" { + clock anyedge; + clken; + wrbe_separate; + portoption "WRITEMODE" "NORMAL" { + rdwr no_change; + } + portoption "WRITEMODE" "WRITETHROUGH" { + rdwr new; + } + portoption "WRITEMODE" "READBEFOREWRITE" { + rdwr old; + } + option "RESETMODE" "SYNC" { + rdsrst zero ungated block_wr; + } + option "RESETMODE" "ASYNC" { + rdarst zero; + } + rdinit zero; + } +} + +ram block $__ECP5_PDPW16KD_ { + abits 14; + widths 1 2 4 9 18 36 per_port; + byte 9; + cost 128; + init no_undef; + port sr "R" { + clock anyedge; + clken; + option "RESETMODE" "SYNC" { + rdsrst zero ungated; + } + option "RESETMODE" "ASYNC" { + rdarst zero; + } + rdinit zero; + } + port sw "W" { + width 36; + clock anyedge; + clken; + } +} diff --git a/techlibs/ecp5/brams_connect.py b/techlibs/ecp5/brams_connect.py deleted file mode 100755 index 098607c59..000000000 --- a/techlibs/ecp5/brams_connect.py +++ /dev/null @@ -1,66 +0,0 @@ -#!/usr/bin/env python3 - -def write_bus_ports(f, ada_bits, adb_bits, dia_bits, dob_bits): - ada_conn = [".ADA%d(%s)" % (i, ada_bits[i]) for i in range(len(ada_bits))] - adb_conn = [".ADB%d(%s)" % (i, adb_bits[i]) for i in range(len(adb_bits))] - dia_conn = [".DIA%d(%s)" % (i, dia_bits[i]) for i in range(len(dia_bits))] - dob_conn = [".DOB%d(%s)" % (i, dob_bits[i]) for i in range(len(dob_bits))] - print(" %s," % ", ".join(ada_conn), file=f) - print(" %s," % ", ".join(adb_conn), file=f) - print(" %s," % ", ".join(dia_conn), file=f) - print(" %s," % ", ".join(dob_conn), file=f) - -def write_bus_ports_pdp(f, adw_bits, adr_bits, di_bits, do_bits, be_bits): - adw_conn = [".ADW%d(%s)" % (i, adw_bits[i]) for i in range(len(adw_bits))] - adr_conn = [".ADR%d(%s)" % (i, adr_bits[i]) for i in range(len(adr_bits))] - di_conn = [".DI%d(%s)" % (i, di_bits[i]) for i in range(len(di_bits))] - do_conn = [".DO%d(%s)" % (i, do_bits[i]) for i in range(len(do_bits))] - be_conn = [".BE%d(%s)" % (i, be_bits[i]) for i in range(len(be_bits))] - print(" %s," % ", ".join(adw_conn), file=f) - print(" %s," % ", ".join(adr_conn), file=f) - print(" %s," % ", ".join(di_conn), file=f) - print(" %s," % ", ".join(do_conn), file=f) - print(" %s," % ", ".join(be_conn), file=f) - -with open("techlibs/ecp5/bram_conn_1.vh", "w") as f: - ada_bits = ["A1ADDR[%d]" % i for i in range(14)] - adb_bits = ["B1ADDR[%d]" % i for i in range(14)] - dia_bits = ["A1DATA[0]"] + ["1'b0" for i in range(17)] - dob_bits = ["B1DATA[0]"] - write_bus_ports(f, ada_bits, adb_bits, dia_bits, dob_bits) - -with open("techlibs/ecp5/bram_conn_2.vh", "w") as f: - ada_bits = ["1'b0"] + ["A1ADDR[%d]" % i for i in range(13)] - adb_bits = ["1'b0"] + ["B1ADDR[%d]" % i for i in range(13)] - dia_bits = ["A1DATA[%d]" % i for i in range(2)] + ["1'b0" for i in range(16)] - dob_bits = ["B1DATA[%d]" % i for i in range(2)] - write_bus_ports(f, ada_bits, adb_bits, dia_bits, dob_bits) - -with open("techlibs/ecp5/bram_conn_4.vh", "w") as f: - ada_bits = ["1'b0", "1'b0"] + ["A1ADDR[%d]" % i for i in range(12)] - adb_bits = ["1'b0", "1'b0"] + ["B1ADDR[%d]" % i for i in range(12)] - dia_bits = ["A1DATA[%d]" % i for i in range(4)] + ["1'b0" for i in range(14)] - dob_bits = ["B1DATA[%d]" % i for i in range(4)] - write_bus_ports(f, ada_bits, adb_bits, dia_bits, dob_bits) - -with open("techlibs/ecp5/bram_conn_9.vh", "w") as f: - ada_bits = ["1'b0", "1'b0", "1'b0"] + ["A1ADDR[%d]" % i for i in range(11)] - adb_bits = ["1'b0", "1'b0", "1'b0"] + ["B1ADDR[%d]" % i for i in range(11)] - dia_bits = ["A1DATA[%d]" % i for i in range(9)] + ["1'b0" for i in range(9)] - dob_bits = ["B1DATA[%d]" % i for i in range(9)] - write_bus_ports(f, ada_bits, adb_bits, dia_bits, dob_bits) - -with open("techlibs/ecp5/bram_conn_18.vh", "w") as f: - ada_bits = ["A1EN[0]", "A1EN[1]", "1'b0", "1'b0"] + ["A1ADDR[%d]" % i for i in range(10)] - adb_bits = ["1'b0", "1'b0", "1'b0", "1'b0"] + ["B1ADDR[%d]" % i for i in range(10)] - dia_bits = ["A1DATA[%d]" % i for i in range(18)] - dob_bits = ["B1DATA[%d]" % i for i in range(18)] - write_bus_ports(f, ada_bits, adb_bits, dia_bits, dob_bits) - -with open("techlibs/ecp5/bram_conn_36.vh", "w") as f: - adw_bits = ["A1ADDR[%d]" % i for i in range(9)] - adr_bits = ["1'b0", "1'b0", "1'b0", "1'b0", "1'b0"] + ["B1ADDR[%d]" % i for i in range(9)] - di_bits = ["A1DATA[%d]" % i for i in range(36)] - do_bits = ["B1DATA[%d]" % (i + 18) for i in range(18)] + ["B1DATA[%d]" % i for i in range(18)] - be_bits = ["A1EN[%d]" % i for i in range(4)] - write_bus_ports_pdp(f, adw_bits, adr_bits, di_bits, do_bits, be_bits) diff --git a/techlibs/ecp5/brams_init.py b/techlibs/ecp5/brams_init.py deleted file mode 100755 index 96a47bdcd..000000000 --- a/techlibs/ecp5/brams_init.py +++ /dev/null @@ -1,22 +0,0 @@ -#!/usr/bin/env python3 -with open("techlibs/ecp5/bram_init_1_2_4.vh", "w") as f: - for i in range(0, 0x40): - init_snippets = [] - for j in range(32): - init_snippets.append("INIT[%4d*8 +: 8]" % (32 * i + j)) - init_snippets.append("3'b000" if (j % 2 == 1) else "1'b0") - init_snippets = list(reversed(init_snippets)) - for k in range(8, 64, 8): - init_snippets[k] = "\n " + init_snippets[k] - print(".INITVAL_%02X({%s})," % (i, ", ".join(init_snippets)), file=f) - -with open("techlibs/ecp5/bram_init_9_18_36.vh", "w") as f: - for i in range(0, 0x40): - init_snippets = [] - for j in range(16): - init_snippets.append("INIT[%3d*18 +: 18]" % (16 * i + j)) - init_snippets.append("2'b00") - init_snippets = list(reversed(init_snippets)) - for k in range(8, 32, 8): - init_snippets[k] = "\n " + init_snippets[k] - print(".INITVAL_%02X({%s})," % (i, ", ".join(init_snippets)), file=f) diff --git a/techlibs/ecp5/brams_map.v b/techlibs/ecp5/brams_map.v index edda17c02..22e6e068e 100644 --- a/techlibs/ecp5/brams_map.v +++ b/techlibs/ecp5/brams_map.v @@ -1,155 +1,489 @@ -module \$__ECP5_DP16KD (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN); - parameter CFG_ABITS = 10; - parameter CFG_DBITS = 18; - parameter CFG_ENABLE_A = 2; - - parameter CLKPOL2 = 1; - parameter CLKPOL3 = 1; - parameter [18431:0] INIT = 18432'bx; - parameter TRANSP2 = 0; - - input CLK2; - input CLK3; - - input [CFG_ABITS-1:0] A1ADDR; - input [CFG_DBITS-1:0] A1DATA; - input [CFG_ENABLE_A-1:0] A1EN; - - input [CFG_ABITS-1:0] B1ADDR; - output [CFG_DBITS-1:0] B1DATA; - input B1EN; - - localparam CLKAMUX = CLKPOL2 ? "CLKA" : "INV"; - localparam CLKBMUX = CLKPOL3 ? "CLKB" : "INV"; - - localparam WRITEMODE_A = TRANSP2 ? "WRITETHROUGH" : "READBEFOREWRITE"; - - generate if (CFG_DBITS == 1) begin - DP16KD #( - `include "bram_init_1_2_4.vh" - .DATA_WIDTH_A(1), - .DATA_WIDTH_B(1), - .CLKAMUX(CLKAMUX), - .CLKBMUX(CLKBMUX), - .WRITEMODE_A(WRITEMODE_A), - .WRITEMODE_B("READBEFOREWRITE"), - .GSR("AUTO") - ) _TECHMAP_REPLACE_ ( - `include "bram_conn_1.vh" - .CLKA(CLK2), .CLKB(CLK3), - .WEA(|A1EN), .CEA(1'b1), .OCEA(1'b1), - .WEB(1'b0), .CEB(B1EN), .OCEB(1'b1), - .RSTA(1'b0), .RSTB(1'b0) - ); - end else if (CFG_DBITS == 2) begin - DP16KD #( - `include "bram_init_1_2_4.vh" - .DATA_WIDTH_A(2), - .DATA_WIDTH_B(2), - .CLKAMUX(CLKAMUX), - .CLKBMUX(CLKBMUX), - .WRITEMODE_A(WRITEMODE_A), - .WRITEMODE_B("READBEFOREWRITE"), - .GSR("AUTO") - ) _TECHMAP_REPLACE_ ( - `include "bram_conn_2.vh" - .CLKA(CLK2), .CLKB(CLK3), - .WEA(|A1EN), .CEA(1'b1), .OCEA(1'b1), - .WEB(1'b0), .CEB(B1EN), .OCEB(1'b1), - .RSTA(1'b0), .RSTB(1'b0) - ); - end else if (CFG_DBITS <= 4) begin - DP16KD #( - `include "bram_init_1_2_4.vh" - .DATA_WIDTH_A(4), - .DATA_WIDTH_B(4), - .CLKAMUX(CLKAMUX), - .CLKBMUX(CLKBMUX), - .WRITEMODE_A(WRITEMODE_A), - .WRITEMODE_B("READBEFOREWRITE"), - .GSR("AUTO") - ) _TECHMAP_REPLACE_ ( - `include "bram_conn_4.vh" - .CLKA(CLK2), .CLKB(CLK3), - .WEA(|A1EN), .CEA(1'b1), .OCEA(1'b1), - .WEB(1'b0), .CEB(B1EN), .OCEB(1'b1), - .RSTA(1'b0), .RSTB(1'b0) - ); - end else if (CFG_DBITS <= 9) begin - DP16KD #( - `include "bram_init_9_18_36.vh" - .DATA_WIDTH_A(9), - .DATA_WIDTH_B(9), - .CLKAMUX(CLKAMUX), - .CLKBMUX(CLKBMUX), - .WRITEMODE_A(WRITEMODE_A), - .WRITEMODE_B("READBEFOREWRITE"), - .GSR("AUTO") - ) _TECHMAP_REPLACE_ ( - `include "bram_conn_9.vh" - .CLKA(CLK2), .CLKB(CLK3), - .WEA(|A1EN), .CEA(1'b1), .OCEA(1'b1), - .WEB(1'b0), .CEB(B1EN), .OCEB(1'b1), - .RSTA(1'b0), .RSTB(1'b0) - ); - end else if (CFG_DBITS <= 18) begin - DP16KD #( - `include "bram_init_9_18_36.vh" - .DATA_WIDTH_A(18), - .DATA_WIDTH_B(18), - .CLKAMUX(CLKAMUX), - .CLKBMUX(CLKBMUX), - .WRITEMODE_A(WRITEMODE_A), - .WRITEMODE_B("READBEFOREWRITE"), - .GSR("AUTO") - ) _TECHMAP_REPLACE_ ( - `include "bram_conn_18.vh" - .CLKA(CLK2), .CLKB(CLK3), - .WEA(|A1EN), .CEA(1'b1), .OCEA(1'b1), - .WEB(1'b0), .CEB(B1EN), .OCEB(1'b1), - .RSTA(1'b0), .RSTB(1'b0) - ); - end else begin - wire TECHMAP_FAIL = 1'b1; - end endgenerate +module $__ECP5_DP16KD_ (...); + +parameter INIT = 0; +parameter OPTION_RESETMODE = "SYNC"; + +parameter PORT_A_WIDTH = 18; +parameter PORT_A_WR_BE_WIDTH = 2; +parameter PORT_A_CLK_POL = 1; +parameter PORT_A_OPTION_WRITEMODE = "NORMAL"; + +input PORT_A_CLK; +input PORT_A_CLK_EN; +input PORT_A_WR_EN; +input PORT_A_RD_SRST; +input PORT_A_RD_ARST; +input [13:0] PORT_A_ADDR; +input [PORT_A_WR_BE_WIDTH-1:0] PORT_A_WR_BE; +input [PORT_A_WIDTH-1:0] PORT_A_WR_DATA; +output [PORT_A_WIDTH-1:0] PORT_A_RD_DATA; + +parameter PORT_B_WIDTH = 18; +parameter PORT_B_WR_BE_WIDTH = 2; +parameter PORT_B_CLK_POL = 1; +parameter PORT_B_OPTION_WRITEMODE = "NORMAL"; + +input PORT_B_CLK; +input PORT_B_CLK_EN; +input PORT_B_WR_EN; +input PORT_B_RD_SRST; +input PORT_B_RD_ARST; +input [13:0] PORT_B_ADDR; +input [PORT_B_WR_BE_WIDTH-1:0] PORT_B_WR_BE; +input [PORT_B_WIDTH-1:0] PORT_B_WR_DATA; +output [PORT_B_WIDTH-1:0] PORT_B_RD_DATA; + +function [319:0] init_slice; + input integer idx; + integer i, j; + init_slice = 0; + for (i = 0; i < 16; i = i + 1) begin + init_slice[i*20+:18] = INIT[(idx * 16 + i) * 18+:18]; + end +endfunction + +wire [17:0] DOA; +wire [17:0] DOB; +wire [17:0] DIA = PORT_A_WR_DATA; +wire [17:0] DIB = PORT_B_WR_DATA; + +assign PORT_A_RD_DATA = DOA; +assign PORT_B_RD_DATA = DOB; + +DP16KD #( + .INITVAL_00(init_slice('h00)), + .INITVAL_01(init_slice('h01)), + .INITVAL_02(init_slice('h02)), + .INITVAL_03(init_slice('h03)), + .INITVAL_04(init_slice('h04)), + .INITVAL_05(init_slice('h05)), + .INITVAL_06(init_slice('h06)), + .INITVAL_07(init_slice('h07)), + .INITVAL_08(init_slice('h08)), + .INITVAL_09(init_slice('h09)), + .INITVAL_0A(init_slice('h0a)), + .INITVAL_0B(init_slice('h0b)), + .INITVAL_0C(init_slice('h0c)), + .INITVAL_0D(init_slice('h0d)), + .INITVAL_0E(init_slice('h0e)), + .INITVAL_0F(init_slice('h0f)), + .INITVAL_10(init_slice('h10)), + .INITVAL_11(init_slice('h11)), + .INITVAL_12(init_slice('h12)), + .INITVAL_13(init_slice('h13)), + .INITVAL_14(init_slice('h14)), + .INITVAL_15(init_slice('h15)), + .INITVAL_16(init_slice('h16)), + .INITVAL_17(init_slice('h17)), + .INITVAL_18(init_slice('h18)), + .INITVAL_19(init_slice('h19)), + .INITVAL_1A(init_slice('h1a)), + .INITVAL_1B(init_slice('h1b)), + .INITVAL_1C(init_slice('h1c)), + .INITVAL_1D(init_slice('h1d)), + .INITVAL_1E(init_slice('h1e)), + .INITVAL_1F(init_slice('h1f)), + .INITVAL_20(init_slice('h20)), + .INITVAL_21(init_slice('h21)), + .INITVAL_22(init_slice('h22)), + .INITVAL_23(init_slice('h23)), + .INITVAL_24(init_slice('h24)), + .INITVAL_25(init_slice('h25)), + .INITVAL_26(init_slice('h26)), + .INITVAL_27(init_slice('h27)), + .INITVAL_28(init_slice('h28)), + .INITVAL_29(init_slice('h29)), + .INITVAL_2A(init_slice('h2a)), + .INITVAL_2B(init_slice('h2b)), + .INITVAL_2C(init_slice('h2c)), + .INITVAL_2D(init_slice('h2d)), + .INITVAL_2E(init_slice('h2e)), + .INITVAL_2F(init_slice('h2f)), + .INITVAL_30(init_slice('h30)), + .INITVAL_31(init_slice('h31)), + .INITVAL_32(init_slice('h32)), + .INITVAL_33(init_slice('h33)), + .INITVAL_34(init_slice('h34)), + .INITVAL_35(init_slice('h35)), + .INITVAL_36(init_slice('h36)), + .INITVAL_37(init_slice('h37)), + .INITVAL_38(init_slice('h38)), + .INITVAL_39(init_slice('h39)), + .INITVAL_3A(init_slice('h3a)), + .INITVAL_3B(init_slice('h3b)), + .INITVAL_3C(init_slice('h3c)), + .INITVAL_3D(init_slice('h3d)), + .INITVAL_3E(init_slice('h3e)), + .INITVAL_3F(init_slice('h3f)), + .DATA_WIDTH_A(PORT_A_WIDTH), + .DATA_WIDTH_B(PORT_B_WIDTH), + .REGMODE_A("NOREG"), + .REGMODE_B("NOREG"), + .RESETMODE(OPTION_RESETMODE), + .ASYNC_RESET_RELEASE(OPTION_RESETMODE), + .CSDECODE_A("0b000"), + .CSDECODE_B("0b000"), + .CLKAMUX(PORT_A_CLK_POL ? "CLKA" : "INV"), + .CLKBMUX(PORT_B_CLK_POL ? "CLKB" : "INV"), + .WRITEMODE_A(PORT_A_OPTION_WRITEMODE), + .WRITEMODE_B(PORT_B_OPTION_WRITEMODE), + .GSR("AUTO") +) _TECHMAP_REPLACE_ ( + .CLKA(PORT_A_CLK), + .WEA(PORT_A_WIDTH == 18 ? PORT_A_WR_EN : (PORT_A_WR_EN | PORT_A_WR_BE[0])), + .CEA(PORT_A_CLK_EN), + .OCEA(1'b1), + .RSTA(OPTION_RESETMODE == "SYNC" ? PORT_A_RD_SRST : PORT_A_RD_ARST), + .CSA0(1'b0), + .CSA1(1'b0), + .CSA2(1'b0), + .ADA0(PORT_A_WIDTH == 18 ? PORT_A_WR_BE[0] : PORT_A_ADDR[0]), + .ADA1(PORT_A_WIDTH == 18 ? PORT_A_WR_BE[1] : PORT_A_ADDR[1]), + .ADA2(PORT_A_ADDR[2]), + .ADA3(PORT_A_ADDR[3]), + .ADA4(PORT_A_ADDR[4]), + .ADA5(PORT_A_ADDR[5]), + .ADA6(PORT_A_ADDR[6]), + .ADA7(PORT_A_ADDR[7]), + .ADA8(PORT_A_ADDR[8]), + .ADA9(PORT_A_ADDR[9]), + .ADA10(PORT_A_ADDR[10]), + .ADA11(PORT_A_ADDR[11]), + .ADA12(PORT_A_ADDR[12]), + .ADA13(PORT_A_ADDR[13]), + .DIA0(DIA[0]), + .DIA1(DIA[1]), + .DIA2(DIA[2]), + .DIA3(DIA[3]), + .DIA4(DIA[4]), + .DIA5(DIA[5]), + .DIA6(DIA[6]), + .DIA7(DIA[7]), + .DIA8(DIA[8]), + .DIA9(DIA[9]), + .DIA10(DIA[10]), + .DIA11(DIA[11]), + .DIA12(DIA[12]), + .DIA13(DIA[13]), + .DIA14(DIA[14]), + .DIA15(DIA[15]), + .DIA16(DIA[16]), + .DIA17(DIA[17]), + .DOA0(DOA[0]), + .DOA1(DOA[1]), + .DOA2(DOA[2]), + .DOA3(DOA[3]), + .DOA4(DOA[4]), + .DOA5(DOA[5]), + .DOA6(DOA[6]), + .DOA7(DOA[7]), + .DOA8(DOA[8]), + .DOA9(DOA[9]), + .DOA10(DOA[10]), + .DOA11(DOA[11]), + .DOA12(DOA[12]), + .DOA13(DOA[13]), + .DOA14(DOA[14]), + .DOA15(DOA[15]), + .DOA16(DOA[16]), + .DOA17(DOA[17]), + + .CLKB(PORT_B_CLK), + .WEB(PORT_B_WIDTH == 18 ? PORT_B_WR_EN : (PORT_B_WR_EN | PORT_B_WR_BE[0])), + .CEB(PORT_B_CLK_EN), + .OCEB(1'b1), + .RSTB(OPTION_RESETMODE == "SYNC" ? PORT_B_RD_SRST : PORT_B_RD_ARST), + .CSB0(1'b0), + .CSB1(1'b0), + .CSB2(1'b0), + .ADB0(PORT_B_WIDTH == 18 ? PORT_B_WR_BE[0] : PORT_B_ADDR[0]), + .ADB1(PORT_B_WIDTH == 18 ? PORT_B_WR_BE[1] : PORT_B_ADDR[1]), + .ADB2(PORT_B_ADDR[2]), + .ADB3(PORT_B_ADDR[3]), + .ADB4(PORT_B_ADDR[4]), + .ADB5(PORT_B_ADDR[5]), + .ADB6(PORT_B_ADDR[6]), + .ADB7(PORT_B_ADDR[7]), + .ADB8(PORT_B_ADDR[8]), + .ADB9(PORT_B_ADDR[9]), + .ADB10(PORT_B_ADDR[10]), + .ADB11(PORT_B_ADDR[11]), + .ADB12(PORT_B_ADDR[12]), + .ADB13(PORT_B_ADDR[13]), + .DIB0(DIB[0]), + .DIB1(DIB[1]), + .DIB2(DIB[2]), + .DIB3(DIB[3]), + .DIB4(DIB[4]), + .DIB5(DIB[5]), + .DIB6(DIB[6]), + .DIB7(DIB[7]), + .DIB8(DIB[8]), + .DIB9(DIB[9]), + .DIB10(DIB[10]), + .DIB11(DIB[11]), + .DIB12(DIB[12]), + .DIB13(DIB[13]), + .DIB14(DIB[14]), + .DIB15(DIB[15]), + .DIB16(DIB[16]), + .DIB17(DIB[17]), + .DOB0(DOB[0]), + .DOB1(DOB[1]), + .DOB2(DOB[2]), + .DOB3(DOB[3]), + .DOB4(DOB[4]), + .DOB5(DOB[5]), + .DOB6(DOB[6]), + .DOB7(DOB[7]), + .DOB8(DOB[8]), + .DOB9(DOB[9]), + .DOB10(DOB[10]), + .DOB11(DOB[11]), + .DOB12(DOB[12]), + .DOB13(DOB[13]), + .DOB14(DOB[14]), + .DOB15(DOB[15]), + .DOB16(DOB[16]), + .DOB17(DOB[17]), +); + endmodule -module \$__ECP5_PDPW16KD (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN); - parameter CFG_ABITS = 9; - parameter CFG_DBITS = 36; - parameter CFG_ENABLE_A = 4; - - parameter CLKPOL2 = 1; - parameter CLKPOL3 = 1; - parameter [18431:0] INIT = 18432'bx; - - input CLK2; - input CLK3; - - input [CFG_ABITS-1:0] A1ADDR; - input [CFG_DBITS-1:0] A1DATA; - input [CFG_ENABLE_A-1:0] A1EN; - - input [CFG_ABITS-1:0] B1ADDR; - output [CFG_DBITS-1:0] B1DATA; - input B1EN; - - localparam CLKWMUX = CLKPOL2 ? "CLKA" : "INV"; - localparam CLKRMUX = CLKPOL3 ? "CLKB" : "INV"; - - PDPW16KD #( - `include "bram_init_9_18_36.vh" - .DATA_WIDTH_W(36), - .DATA_WIDTH_R(36), - .CLKWMUX(CLKWMUX), - .CLKRMUX(CLKRMUX), - .GSR("AUTO") - ) _TECHMAP_REPLACE_ ( - `include "bram_conn_36.vh" - .CLKW(CLK2), .CLKR(CLK3), - .CEW(1'b1), - .CER(B1EN), .OCER(1'b1), - .RST(1'b0) - ); + +module $__ECP5_PDPW16KD_ (...); + +parameter INIT = 0; +parameter OPTION_RESETMODE = "SYNC"; + +parameter PORT_R_WIDTH = 36; +parameter PORT_R_CLK_POL = 1; + +input PORT_R_CLK; +input PORT_R_CLK_EN; +input PORT_R_RD_SRST; +input PORT_R_RD_ARST; +input [13:0] PORT_R_ADDR; +output [PORT_R_WIDTH-1:0] PORT_R_RD_DATA; + +parameter PORT_W_WIDTH = 36; +parameter PORT_W_WR_EN_WIDTH = 4; +parameter PORT_W_CLK_POL = 1; + +input PORT_W_CLK; +input PORT_W_CLK_EN; +input [13:0] PORT_W_ADDR; +input [PORT_W_WR_EN_WIDTH-1:0] PORT_W_WR_EN; +input [PORT_W_WIDTH-1:0] PORT_W_WR_DATA; + +function [319:0] init_slice; + input integer idx; + integer i, j; + init_slice = 0; + for (i = 0; i < 16; i = i + 1) begin + init_slice[i*20+:18] = INIT[(idx * 16 + i) * 18+:18]; + end +endfunction + +wire [35:0] DI = PORT_W_WR_DATA; +wire [35:0] DO; + +assign PORT_R_RD_DATA = PORT_R_WIDTH == 36 ? DO : DO[35:18]; + +DP16KD #( + .INITVAL_00(init_slice('h00)), + .INITVAL_01(init_slice('h01)), + .INITVAL_02(init_slice('h02)), + .INITVAL_03(init_slice('h03)), + .INITVAL_04(init_slice('h04)), + .INITVAL_05(init_slice('h05)), + .INITVAL_06(init_slice('h06)), + .INITVAL_07(init_slice('h07)), + .INITVAL_08(init_slice('h08)), + .INITVAL_09(init_slice('h09)), + .INITVAL_0A(init_slice('h0a)), + .INITVAL_0B(init_slice('h0b)), + .INITVAL_0C(init_slice('h0c)), + .INITVAL_0D(init_slice('h0d)), + .INITVAL_0E(init_slice('h0e)), + .INITVAL_0F(init_slice('h0f)), + .INITVAL_10(init_slice('h10)), + .INITVAL_11(init_slice('h11)), + .INITVAL_12(init_slice('h12)), + .INITVAL_13(init_slice('h13)), + .INITVAL_14(init_slice('h14)), + .INITVAL_15(init_slice('h15)), + .INITVAL_16(init_slice('h16)), + .INITVAL_17(init_slice('h17)), + .INITVAL_18(init_slice('h18)), + .INITVAL_19(init_slice('h19)), + .INITVAL_1A(init_slice('h1a)), + .INITVAL_1B(init_slice('h1b)), + .INITVAL_1C(init_slice('h1c)), + .INITVAL_1D(init_slice('h1d)), + .INITVAL_1E(init_slice('h1e)), + .INITVAL_1F(init_slice('h1f)), + .INITVAL_20(init_slice('h20)), + .INITVAL_21(init_slice('h21)), + .INITVAL_22(init_slice('h22)), + .INITVAL_23(init_slice('h23)), + .INITVAL_24(init_slice('h24)), + .INITVAL_25(init_slice('h25)), + .INITVAL_26(init_slice('h26)), + .INITVAL_27(init_slice('h27)), + .INITVAL_28(init_slice('h28)), + .INITVAL_29(init_slice('h29)), + .INITVAL_2A(init_slice('h2a)), + .INITVAL_2B(init_slice('h2b)), + .INITVAL_2C(init_slice('h2c)), + .INITVAL_2D(init_slice('h2d)), + .INITVAL_2E(init_slice('h2e)), + .INITVAL_2F(init_slice('h2f)), + .INITVAL_30(init_slice('h30)), + .INITVAL_31(init_slice('h31)), + .INITVAL_32(init_slice('h32)), + .INITVAL_33(init_slice('h33)), + .INITVAL_34(init_slice('h34)), + .INITVAL_35(init_slice('h35)), + .INITVAL_36(init_slice('h36)), + .INITVAL_37(init_slice('h37)), + .INITVAL_38(init_slice('h38)), + .INITVAL_39(init_slice('h39)), + .INITVAL_3A(init_slice('h3a)), + .INITVAL_3B(init_slice('h3b)), + .INITVAL_3C(init_slice('h3c)), + .INITVAL_3D(init_slice('h3d)), + .INITVAL_3E(init_slice('h3e)), + .INITVAL_3F(init_slice('h3f)), + .DATA_WIDTH_A(PORT_W_WIDTH), + .DATA_WIDTH_B(PORT_R_WIDTH), + .REGMODE_A("NOREG"), + .REGMODE_B("NOREG"), + .RESETMODE(OPTION_RESETMODE), + .ASYNC_RESET_RELEASE(OPTION_RESETMODE), + .CSDECODE_A("0b000"), + .CSDECODE_B("0b000"), + .CLKAMUX(PORT_W_CLK_POL ? "CLKA" : "INV"), + .CLKBMUX(PORT_R_CLK_POL ? "CLKB" : "INV"), + .GSR("AUTO") +) _TECHMAP_REPLACE_ ( + .CLKA(PORT_W_CLK), + .WEA(PORT_W_WIDTH >= 18 ? 1'b1 : PORT_W_WR_EN[0]), + .CEA(PORT_W_CLK_EN), + .OCEA(1'b0), + .RSTA(1'b0), + .CSA0(1'b0), + .CSA1(1'b0), + .CSA2(1'b0), + .ADA0(PORT_W_WIDTH >= 18 ? PORT_W_WR_EN[0] : PORT_W_ADDR[0]), + .ADA1(PORT_W_WIDTH >= 18 ? PORT_W_WR_EN[1] : PORT_W_ADDR[1]), + .ADA2(PORT_W_WIDTH >= 36 ? PORT_W_WR_EN[2] : PORT_W_ADDR[2]), + .ADA3(PORT_W_WIDTH >= 36 ? PORT_W_WR_EN[3] : PORT_W_ADDR[3]), + .ADA4(PORT_W_ADDR[4]), + .ADA5(PORT_W_ADDR[5]), + .ADA6(PORT_W_ADDR[6]), + .ADA7(PORT_W_ADDR[7]), + .ADA8(PORT_W_ADDR[8]), + .ADA9(PORT_W_ADDR[9]), + .ADA10(PORT_W_ADDR[10]), + .ADA11(PORT_W_ADDR[11]), + .ADA12(PORT_W_ADDR[12]), + .ADA13(PORT_W_ADDR[13]), + .DIA0(DI[0]), + .DIA1(DI[1]), + .DIA2(DI[2]), + .DIA3(DI[3]), + .DIA4(DI[4]), + .DIA5(DI[5]), + .DIA6(DI[6]), + .DIA7(DI[7]), + .DIA8(DI[8]), + .DIA9(DI[9]), + .DIA10(DI[10]), + .DIA11(DI[11]), + .DIA12(DI[12]), + .DIA13(DI[13]), + .DIA14(DI[14]), + .DIA15(DI[15]), + .DIA16(DI[16]), + .DIA17(DI[17]), + .DIB0(DI[18]), + .DIB1(DI[19]), + .DIB2(DI[20]), + .DIB3(DI[21]), + .DIB4(DI[22]), + .DIB5(DI[23]), + .DIB6(DI[24]), + .DIB7(DI[25]), + .DIB8(DI[26]), + .DIB9(DI[27]), + .DIB10(DI[28]), + .DIB11(DI[29]), + .DIB12(DI[30]), + .DIB13(DI[31]), + .DIB14(DI[32]), + .DIB15(DI[33]), + .DIB16(DI[34]), + .DIB17(DI[35]), + + .CLKB(PORT_R_CLK), + .WEB(1'b0), + .CEB(PORT_R_CLK_EN), + .OCEB(1'b1), + .RSTB(OPTION_RESETMODE == "SYNC" ? PORT_R_RD_SRST : PORT_R_RD_ARST), + .CSB0(1'b0), + .CSB1(1'b0), + .CSB2(1'b0), + .ADB0(PORT_R_ADDR[0]), + .ADB1(PORT_R_ADDR[1]), + .ADB2(PORT_R_ADDR[2]), + .ADB3(PORT_R_ADDR[3]), + .ADB4(PORT_R_ADDR[4]), + .ADB5(PORT_R_ADDR[5]), + .ADB6(PORT_R_ADDR[6]), + .ADB7(PORT_R_ADDR[7]), + .ADB8(PORT_R_ADDR[8]), + .ADB9(PORT_R_ADDR[9]), + .ADB10(PORT_R_ADDR[10]), + .ADB11(PORT_R_ADDR[11]), + .ADB12(PORT_R_ADDR[12]), + .ADB13(PORT_R_ADDR[13]), + .DOA0(DO[0]), + .DOA1(DO[1]), + .DOA2(DO[2]), + .DOA3(DO[3]), + .DOA4(DO[4]), + .DOA5(DO[5]), + .DOA6(DO[6]), + .DOA7(DO[7]), + .DOA8(DO[8]), + .DOA9(DO[9]), + .DOA10(DO[10]), + .DOA11(DO[11]), + .DOA12(DO[12]), + .DOA13(DO[13]), + .DOA14(DO[14]), + .DOA15(DO[15]), + .DOA16(DO[16]), + .DOA17(DO[17]), + .DOB0(DO[18]), + .DOB1(DO[19]), + .DOB2(DO[20]), + .DOB3(DO[21]), + .DOB4(DO[22]), + .DOB5(DO[23]), + .DOB6(DO[24]), + .DOB7(DO[25]), + .DOB8(DO[26]), + .DOB9(DO[27]), + .DOB10(DO[28]), + .DOB11(DO[29]), + .DOB12(DO[30]), + .DOB13(DO[31]), + .DOB14(DO[32]), + .DOB15(DO[33]), + .DOB16(DO[34]), + .DOB17(DO[35]), +); endmodule diff --git a/techlibs/ecp5/cells_bb.v b/techlibs/ecp5/cells_bb.v index e616d24d6..fc352a52c 100644 --- a/techlibs/ecp5/cells_bb.v +++ b/techlibs/ecp5/cells_bb.v @@ -223,7 +223,7 @@ endmodule (* blackbox *) module IDDRX2F( - input D, SCLK, ECLK, RST, + input D, SCLK, ECLK, RST, ALIGNWD, output Q0, Q1, Q2, Q3 ); parameter GSR = "ENABLED"; diff --git a/techlibs/ecp5/cells_map.v b/techlibs/ecp5/cells_map.v index dc83d96dc..4944ece45 100644 --- a/techlibs/ecp5/cells_map.v +++ b/techlibs/ecp5/cells_map.v @@ -88,14 +88,13 @@ module \$_SDFFE_NP1N_ (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), module \$_SDFFE_PP0N_ (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("INV"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule module \$_SDFFE_PP1N_ (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("INV"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule -`ifdef ASYNC_PRLD -module \$_DLATCH_N_ (input E, input D, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .LSRMODE("PRLD"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.LSR(!E), .DI(1'b0), .M(D), .Q(Q)); endmodule -module \$_DLATCH_P_ (input E, input D, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .LSRMODE("PRLD"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.LSR(E), .DI(1'b0), .M(D), .Q(Q)); endmodule +module \$_ALDFF_NP_ (input C, L, AD, D, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("INV"), .LSRMODE("PRLD"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(L), .DI(D), .M(AD), .Q(Q)); endmodule +module \$_ALDFF_PP_ (input C, L, AD, D, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMODE("PRLD"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(L), .DI(D), .M(AD), .Q(Q)); endmodule -module \$_DFFSR_NPP_ (input C, S, R, D, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("INV"), .LSRMODE("PRLD"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(S || R), .DI(D), .M(!R), .Q(Q)); endmodule - -module \$_DFFSR_PPP_ (input C, S, R, D, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMODE("PRLD"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(S || R), .DI(D), .M(!R), .Q(Q)); endmodule -`endif +module \$_ALDFFE_NPN_ (input C, E, L, AD, D, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("INV"), .CLKMUX("INV"), .LSRMODE("PRLD"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(L), .DI(D), .M(AD), .Q(Q)); endmodule +module \$_ALDFFE_NPP_ (input C, E, L, AD, D, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMODE("PRLD"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(L), .DI(D), .M(AD), .Q(Q)); endmodule +module \$_ALDFFE_PPN_ (input C, E, L, AD, D, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("INV"), .CLKMUX("CLK"), .LSRMODE("PRLD"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(L), .DI(D), .M(AD), .Q(Q)); endmodule +module \$_ALDFFE_PPP_ (input C, E, L, AD, D, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMODE("PRLD"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(L), .DI(D), .M(AD), .Q(Q)); endmodule `include "cells_ff.vh" `include "cells_io.vh" diff --git a/techlibs/ecp5/cells_sim.v b/techlibs/ecp5/cells_sim.v index 357fd9173..f9d503deb 100644 --- a/techlibs/ecp5/cells_sim.v +++ b/techlibs/ecp5/cells_sim.v @@ -204,7 +204,7 @@ module TRELLIS_DPR16X4 ( integer i; initial begin for (i = 0; i < 16; i = i + 1) - mem[i] <= {INITVAL[i+3], INITVAL[i+2], INITVAL[i+1], INITVAL[i]}; + mem[i] <= INITVAL[4*i +: 4]; end wire muxwck = (WCKMUX == "INV") ? ~WCK : WCK; @@ -355,37 +355,24 @@ module TRELLIS_FF(input CLK, LSR, CE, DI, M, output reg Q); end endgenerate - generate - // TODO - if (CLKMUX == "INV") - specify - $setup(DI, negedge CLK, 0); - $setup(CE, negedge CLK, 0); - $setup(LSR, negedge CLK, 0); -`ifndef YOSYS - if (SRMODE == "ASYNC" && muxlsr) (negedge CLK => (Q : srval)) = 0; -`else - if (SRMODE == "ASYNC" && muxlsr) (LSR => Q) = 0; // Technically, this should be an edge sensitive path - // but for facilitating a bypass box, let's pretend it's - // a simple path -`endif - if (!muxlsr && muxce) (negedge CLK => (Q : DI)) = 0; - endspecify - else - specify - $setup(DI, posedge CLK, 0); - $setup(CE, posedge CLK, 0); - $setup(LSR, posedge CLK, 0); + specify + $setup(DI, negedge CLK &&& CLKMUX == "INV", 0); + $setup(CE, negedge CLK &&& CLKMUX == "INV", 0); + $setup(LSR, negedge CLK &&& CLKMUX == "INV", 0); + $setup(DI, posedge CLK &&& CLKMUX != "INV", 0); + $setup(CE, posedge CLK &&& CLKMUX != "INV", 0); + $setup(LSR, posedge CLK &&& CLKMUX != "INV", 0); `ifndef YOSYS - if (SRMODE == "ASYNC" && muxlsr) (posedge CLK => (Q : srval)) = 0; + if (SRMODE == "ASYNC" && muxlsr && CLKMUX == "INV") (negedge CLK => (Q : srval)) = 0; + if (SRMODE == "ASYNC" && muxlsr && CLKMUX != "INV") (posedge CLK => (Q : srval)) = 0; `else - if (SRMODE == "ASYNC" && muxlsr) (LSR => Q) = 0; // Technically, this should be an edge sensitive path - // but for facilitating a bypass box, let's pretend it's - // a simple path + if (SRMODE == "ASYNC" && muxlsr) (LSR => Q) = 0; // Technically, this should be an edge sensitive path + // but for facilitating a bypass box, let's pretend it's + // a simple path `endif - if (!muxlsr && muxce) (posedge CLK => (Q : DI)) = 0; - endspecify - endgenerate + if (!muxlsr && muxce && CLKMUX == "INV") (negedge CLK => (Q : DI)) = 0; + if (!muxlsr && muxce && CLKMUX != "INV") (posedge CLK => (Q : DI)) = 0; + endspecify endmodule // --------------------------------------- @@ -812,6 +799,7 @@ module DP16KD( parameter INITVAL_3D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; parameter INITVAL_3E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; parameter INITVAL_3F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_DATA = "STATIC"; endmodule `ifndef NO_INCLUDES diff --git a/techlibs/ecp5/lutrams.txt b/techlibs/ecp5/lutrams.txt index 5370a1ddb..ea42d4fcb 100644 --- a/techlibs/ecp5/lutrams.txt +++ b/techlibs/ecp5/lutrams.txt @@ -1,26 +1,12 @@ -bram $__TRELLIS_DPR16X4 - init 1 - abits 4 - dbits 4 - groups 2 - ports 1 1 - wrmode 0 1 - enable 0 1 - transp 0 0 - clocks 0 1 - clkpol 0 2 -endbram - -# The syn_* attributes are described in: -# https://www.latticesemi.com/view_document?document_id=51556 -attr_icase 1 - -match $__TRELLIS_DPR16X4 - attribute !syn_ramstyle syn_ramstyle=auto syn_ramstyle=distributed - attribute !syn_romstyle syn_romstyle=auto - attribute !ram_block - attribute !rom_block - attribute !logic_block - make_outreg - min wports 1 -endmatch +ram distributed $__TRELLIS_DPR16X4_ { + abits 4; + width 4; + cost 4; + init any; + prune_rom; + port sw "W" { + clock anyedge; + } + port ar "R" { + } +} diff --git a/techlibs/ecp5/lutrams_map.v b/techlibs/ecp5/lutrams_map.v index 3b3de831f..3cb325f04 100644 --- a/techlibs/ecp5/lutrams_map.v +++ b/techlibs/ecp5/lutrams_map.v @@ -1,28 +1,30 @@ -module \$__TRELLIS_DPR16X4 (CLK1, A1ADDR, A1DATA, B1ADDR, B1DATA, B1EN); - parameter [63:0] INIT = 64'bx; - parameter CLKPOL2 = 1; - input CLK1; +module $__TRELLIS_DPR16X4_(...); - input [3:0] A1ADDR; - output [3:0] A1DATA; +parameter INIT = 64'bx; +parameter PORT_W_CLK_POL = 1; - input [3:0] B1ADDR; - input [3:0] B1DATA; - input B1EN; +input PORT_W_CLK; +input [3:0] PORT_W_ADDR; +input [3:0] PORT_W_WR_DATA; +input PORT_W_WR_EN; - localparam WCKMUX = CLKPOL2 ? "WCK" : "INV"; +input [3:0] PORT_R_ADDR; +output [3:0] PORT_R_RD_DATA; - TRELLIS_DPR16X4 #( - .INITVAL(INIT), - .WCKMUX(WCKMUX), - .WREMUX("WRE") - ) _TECHMAP_REPLACE_ ( - .RAD(A1ADDR), - .DO(A1DATA), +localparam WCKMUX = PORT_W_CLK_POL ? "WCK" : "INV"; + +TRELLIS_DPR16X4 #( + .INITVAL(INIT), + .WCKMUX(WCKMUX), + .WREMUX("WRE") +) _TECHMAP_REPLACE_ ( + .RAD(PORT_R_ADDR), + .DO(PORT_R_RD_DATA), + + .WAD(PORT_W_ADDR), + .DI(PORT_W_WR_DATA), + .WCK(PORT_W_CLK), + .WRE(PORT_W_WR_EN) +); - .WAD(B1ADDR), - .DI(B1DATA), - .WCK(CLK1), - .WRE(B1EN) - ); endmodule diff --git a/techlibs/ecp5/synth_ecp5.cc b/techlibs/ecp5/synth_ecp5.cc index dc67fc71b..8c7ea5b39 100644 --- a/techlibs/ecp5/synth_ecp5.cc +++ b/techlibs/ecp5/synth_ecp5.cc @@ -88,7 +88,7 @@ struct SynthEcp5Pass : public ScriptPass log(" do not use PFU muxes to implement LUTs larger than LUT4s\n"); log("\n"); log(" -asyncprld\n"); - log(" use async PRLD mode to implement DLATCH and DFFSR (EXPERIMENTAL)\n"); + log(" use async PRLD mode to implement ALDFF (EXPERIMENTAL)\n"); log("\n"); log(" -abc2\n"); log(" run two passes of 'abc' for slightly improved logic density\n"); @@ -277,24 +277,23 @@ struct SynthEcp5Pass : public ScriptPass run("opt_clean"); } - if (!nobram && check_label("map_bram", "(skip if -nobram)")) + if (check_label("map_ram")) { - run("memory_bram -rules +/ecp5/brams.txt"); - run("techmap -map +/ecp5/brams_map.v"); - } - - if (!nolutram && check_label("map_lutram", "(skip if -nolutram)")) - { - run("memory_bram -rules +/ecp5/lutrams.txt"); - run("techmap -map +/ecp5/lutrams_map.v"); + std::string args = ""; + if (nobram) + args += " -no-auto-block"; + if (nolutram) + args += " -no-auto-distributed"; + if (help_mode) + args += " [-no-auto-block] [-no-auto-distributed]"; + run("memory_libmap -lib +/ecp5/lutrams.txt -lib +/ecp5/brams.txt" + args, "(-no-auto-block if -nobram, -no-auto-distributed if -nolutram)"); + run("techmap -map +/ecp5/lutrams_map.v -map +/ecp5/brams_map.v"); } if (check_label("map_ffram")) { run("opt -fast -mux_undef -undriven -fine"); - run("memory_map -iattr -attr !ram_block -attr !rom_block -attr logic_block " - "-attr syn_ramstyle=auto -attr syn_ramstyle=registers " - "-attr syn_romstyle=auto -attr syn_romstyle=logic"); + run("memory_map"); run("opt -undriven -fine"); } @@ -318,16 +317,17 @@ struct SynthEcp5Pass : public ScriptPass } else if (!nodffe) { dfflegalize_args += " -cell $_DFFE_??_ 01 -cell $_DFFE_?P??_ r -cell $_SDFFE_?P??_ r"; } - dfflegalize_args += " -cell $_DLATCH_?_ x"; if (help_mode) { - dfflegalize_args += " [-cell $_DFFSR_?PP_ x]"; + dfflegalize_args += " [-cell $_ALDFF_?P_ x -cell $_ALDFFE_?P?_ x] [-cell $_DLATCH_?_ x]"; } else if (asyncprld) { - dfflegalize_args += " -cell $_DFFSR_?PP_ x"; + dfflegalize_args += " -cell $_ALDFF_?P_ x -cell $_ALDFFE_?P?_ x"; + } else { + dfflegalize_args += " -cell $_DLATCH_?_ x"; } - run("dfflegalize" + dfflegalize_args, "($_DFFSR_*_ only if -asyncprld, $_*DFFE_* only if not -nodffe)"); + run("dfflegalize" + dfflegalize_args, "($_ALDFF_*_ only if -asyncprld, $_DLATCH_* only if not -asyncprld, $_*DFFE_* only if not -nodffe)"); if ((abc9 && dff) || help_mode) run("zinit -all w:* t:$_DFF_?_ t:$_DFFE_??_ t:$_SDFF*", "(only if -abc9 and -dff)"); - run(stringf("techmap -D NO_LUT %s -map +/ecp5/cells_map.v", help_mode ? "[-D ASYNC_PRLD]" : (asyncprld ? "-D ASYNC_PRLD" : ""))); + run("techmap -D NO_LUT -map +/ecp5/cells_map.v"); run("opt_expr -undriven -mux_undef"); run("simplemap"); run("ecp5_gsr"); diff --git a/techlibs/efinix/brams.txt b/techlibs/efinix/brams.txt index 0b3fd9308..271fc4fc4 100644 --- a/techlibs/efinix/brams.txt +++ b/techlibs/efinix/brams.txt @@ -1,32 +1,19 @@ -bram $__EFINIX_5K - init 1 - - abits 8 @a8d16 - dbits 16 @a8d16 - abits 9 @a9d8 - dbits 8 @a9d8 - abits 10 @a10d4 - dbits 4 @a10d4 - abits 11 @a11d2 - dbits 2 @a11d2 - abits 12 @a12d1 - dbits 1 @a12d1 - abits 8 @a8d20 - dbits 20 @a8d20 - abits 9 @a9d10 - dbits 10 @a9d10 - - groups 2 - ports 1 1 - wrmode 1 0 - enable 1 1 - transp 0 2 - clocks 2 3 - clkpol 2 3 -endbram - -match $__EFINIX_5K - min bits 256 - min efficiency 5 - shuffle_enable B -endmatch +ram block $__EFINIX_5K_ { + abits 12; + widths 1 2 5 10 20 per_port; + cost 32; + init no_undef; + port sr "R" { + clock anyedge; + rden; + } + port sw "W" { + clock anyedge; + option "WRITE_MODE" "READ_FIRST" { + wrtrans "R" old; + } + option "WRITE_MODE" "WRITE_FIRST" { + wrtrans "R" new; + } + } +} diff --git a/techlibs/efinix/brams_map.v b/techlibs/efinix/brams_map.v index 6786ae769..752010f45 100644 --- a/techlibs/efinix/brams_map.v +++ b/techlibs/efinix/brams_map.v @@ -1,65 +1,149 @@ -module \$__EFINIX_5K (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN); - parameter CFG_ABITS = 8; - parameter CFG_DBITS = 20; - parameter CFG_ENABLE_A = 1; +module $__EFINIX_5K_ (...); + parameter INIT = 0; + parameter OPTION_WRITE_MODE = "READ_FIRST"; - parameter CLKPOL2 = 1; - parameter CLKPOL3 = 1; - parameter [5119:0] INIT = 5119'bx; - parameter TRANSP2 = 0; + parameter PORT_R_WIDTH = 20; + parameter PORT_R_CLK_POL = 1; + parameter PORT_W_WIDTH = 20; + parameter PORT_W_CLK_POL = 1; - input CLK2; - input CLK3; + input PORT_R_CLK; + input PORT_R_RD_EN; + input [11:0] PORT_R_ADDR; + output [PORT_R_WIDTH-1:0] PORT_R_RD_DATA; - input [CFG_ABITS-1:0] A1ADDR; - input [CFG_DBITS-1:0] A1DATA; - input [CFG_ENABLE_A-1:0] A1EN; + input PORT_W_CLK; + input PORT_W_WR_EN; + input [11:0] PORT_W_ADDR; + input [PORT_W_WIDTH-1:0] PORT_W_WR_DATA; - input [CFG_ABITS-1:0] B1ADDR; - output [CFG_DBITS-1:0] B1DATA; - input B1EN; + localparam IS_5BIT = PORT_R_WIDTH >= 5 && PORT_W_WIDTH >= 5; - localparam WRITEMODE_A = TRANSP2 ? "WRITE_FIRST" : "READ_FIRST"; + localparam RADDR_WIDTH = + PORT_R_WIDTH == 1 ? 12 : + PORT_R_WIDTH == 2 ? 11 : + PORT_R_WIDTH == 5 ? 10 : + PORT_R_WIDTH == 10 ? 9 : + 8; + + localparam WADDR_WIDTH = + PORT_W_WIDTH == 1 ? 12 : + PORT_W_WIDTH == 2 ? 11 : + PORT_W_WIDTH == 5 ? 10 : + PORT_W_WIDTH == 10 ? 9 : + 8; + + localparam READ_WIDTH = + PORT_R_WIDTH == 1 ? 1 : + PORT_R_WIDTH == 2 ? 2 : + PORT_R_WIDTH == 5 ? (IS_5BIT ? 5 : 4) : + PORT_R_WIDTH == 10 ? (IS_5BIT ? 10 : 8) : + (IS_5BIT ? 20 : 16); + + localparam WRITE_WIDTH = + PORT_W_WIDTH == 1 ? 1 : + PORT_W_WIDTH == 2 ? 2 : + PORT_W_WIDTH == 5 ? (IS_5BIT ? 5 : 4) : + PORT_W_WIDTH == 10 ? (IS_5BIT ? 10 : 8) : + (IS_5BIT ? 20 : 16); + + wire [RADDR_WIDTH-1:0] RADDR = PORT_R_ADDR[11:12-RADDR_WIDTH]; + wire [WADDR_WIDTH-1:0] WADDR = PORT_W_ADDR[11:12-WADDR_WIDTH]; + + wire [WRITE_WIDTH-1:0] WDATA; + wire [READ_WIDTH-1:0] RDATA; + + generate + case (WRITE_WIDTH) + 1: assign WDATA = PORT_W_WR_DATA; + 2: assign WDATA = PORT_W_WR_DATA; + 4: assign WDATA = PORT_W_WR_DATA[3:0]; + 5: assign WDATA = PORT_W_WR_DATA; + 8: assign WDATA = { + PORT_W_WR_DATA[8:5], + PORT_W_WR_DATA[3:0] + }; + 10: assign WDATA = PORT_W_WR_DATA; + 16: assign WDATA = { + PORT_W_WR_DATA[18:15], + PORT_W_WR_DATA[13:10], + PORT_W_WR_DATA[8:5], + PORT_W_WR_DATA[3:0] + }; + 20: assign WDATA = PORT_W_WR_DATA; + endcase + case (READ_WIDTH) + 1: assign PORT_R_RD_DATA = RDATA; + 2: assign PORT_R_RD_DATA = RDATA; + 4: assign PORT_R_RD_DATA[3:0] = RDATA; + 5: assign PORT_R_RD_DATA = RDATA; + 8: assign { + PORT_R_RD_DATA[8:5], + PORT_R_RD_DATA[3:0] + } = RDATA; + 10: assign PORT_R_RD_DATA = RDATA; + 16: assign { + PORT_R_RD_DATA[18:15], + PORT_R_RD_DATA[13:10], + PORT_R_RD_DATA[8:5], + PORT_R_RD_DATA[3:0] + } = RDATA; + 20: assign PORT_R_RD_DATA = RDATA; + endcase + endgenerate + + function [255:0] init_slice; + input integer idx; + integer i; + if (IS_5BIT) + init_slice = INIT[idx * 256 +: 256]; + else if (idx > 16) + init_slice = 0; + else + for (i = 0; i < 64; i = i + 1) + init_slice[i*4+:4] = INIT[(idx * 64 + i) * 5+:4]; + endfunction EFX_RAM_5K #( - .READ_WIDTH(CFG_DBITS), - .WRITE_WIDTH(CFG_DBITS), - .OUTPUT_REG(1'b0), - .RCLK_POLARITY(1'b1), - .RE_POLARITY(1'b1), - .WCLK_POLARITY(1'b1), - .WE_POLARITY(1'b1), - .WCLKE_POLARITY(1'b1), - .WRITE_MODE(WRITEMODE_A), - .INIT_0(INIT[ 0*256 +: 256]), - .INIT_1(INIT[ 1*256 +: 256]), - .INIT_2(INIT[ 2*256 +: 256]), - .INIT_3(INIT[ 3*256 +: 256]), - .INIT_4(INIT[ 4*256 +: 256]), - .INIT_5(INIT[ 5*256 +: 256]), - .INIT_6(INIT[ 6*256 +: 256]), - .INIT_7(INIT[ 7*256 +: 256]), - .INIT_8(INIT[ 8*256 +: 256]), - .INIT_9(INIT[ 9*256 +: 256]), - .INIT_A(INIT[10*256 +: 256]), - .INIT_B(INIT[11*256 +: 256]), - .INIT_C(INIT[12*256 +: 256]), - .INIT_D(INIT[13*256 +: 256]), - .INIT_E(INIT[14*256 +: 256]), - .INIT_F(INIT[15*256 +: 256]), - .INIT_10(INIT[16*256 +: 256]), - .INIT_11(INIT[17*256 +: 256]), - .INIT_12(INIT[18*256 +: 256]), - .INIT_13(INIT[19*256 +: 256]) + .READ_WIDTH(READ_WIDTH), + .WRITE_WIDTH(WRITE_WIDTH), + .OUTPUT_REG(1'b0), + .RCLK_POLARITY(PORT_R_CLK_POL), + .RE_POLARITY(1'b1), + .WCLK_POLARITY(PORT_W_CLK_POL), + .WE_POLARITY(1'b1), + .WCLKE_POLARITY(1'b1), + .WRITE_MODE(OPTION_WRITE_MODE), + .INIT_0(init_slice('h00)), + .INIT_1(init_slice('h01)), + .INIT_2(init_slice('h02)), + .INIT_3(init_slice('h03)), + .INIT_4(init_slice('h04)), + .INIT_5(init_slice('h05)), + .INIT_6(init_slice('h06)), + .INIT_7(init_slice('h07)), + .INIT_8(init_slice('h08)), + .INIT_9(init_slice('h09)), + .INIT_A(init_slice('h0a)), + .INIT_B(init_slice('h0b)), + .INIT_C(init_slice('h0c)), + .INIT_D(init_slice('h0d)), + .INIT_E(init_slice('h0e)), + .INIT_F(init_slice('h0f)), + .INIT_10(init_slice('h10)), + .INIT_11(init_slice('h11)), + .INIT_12(init_slice('h12)), + .INIT_13(init_slice('h13)), ) _TECHMAP_REPLACE_ ( - .WDATA(A1DATA), - .WADDR(A1ADDR), - .WE(A1EN), - .WCLK(CLK2), - .WCLKE(1'b1), - .RDATA(B1DATA), - .RADDR(B1ADDR), - .RE(B1EN), - .RCLK(CLK3) + .WDATA(WDATA), + .WADDR(WADDR), + .WE(PORT_W_WR_EN), + .WCLK(PORT_W_CLK), + .WCLKE(1'b1), + .RDATA(RDATA), + .RADDR(RADDR), + .RE(PORT_R_RD_EN), + .RCLK(PORT_R_CLK) ); + endmodule diff --git a/techlibs/efinix/synth_efinix.cc b/techlibs/efinix/synth_efinix.cc index ace56bee9..bbc389444 100644 --- a/techlibs/efinix/synth_efinix.cc +++ b/techlibs/efinix/synth_efinix.cc @@ -158,11 +158,13 @@ struct SynthEfinixPass : public ScriptPass run("synth -run coarse"); } - if (!nobram || check_label("map_bram", "(skip if -nobram)")) + if (check_label("map_ram")) { - run("memory_bram -rules +/efinix/brams.txt"); + std::string args = ""; + if (nobram) + args += " -no-auto-block"; + run("memory_libmap -lib +/efinix/brams.txt" + args); run("techmap -map +/efinix/brams_map.v"); - run("setundef -zero -params t:EFX_RAM_5K"); } if (check_label("map_ffram")) diff --git a/techlibs/gatemate/Makefile.inc b/techlibs/gatemate/Makefile.inc new file mode 100644 index 000000000..d1341d7bb --- /dev/null +++ b/techlibs/gatemate/Makefile.inc @@ -0,0 +1,14 @@ +
+OBJS += techlibs/gatemate/synth_gatemate.o
+
+$(eval $(call add_share_file,share/gatemate,techlibs/gatemate/reg_map.v))
+$(eval $(call add_share_file,share/gatemate,techlibs/gatemate/mux_map.v))
+$(eval $(call add_share_file,share/gatemate,techlibs/gatemate/lut_map.v))
+$(eval $(call add_share_file,share/gatemate,techlibs/gatemate/mul_map.v))
+$(eval $(call add_share_file,share/gatemate,techlibs/gatemate/arith_map.v))
+$(eval $(call add_share_file,share/gatemate,techlibs/gatemate/cells_sim.v))
+$(eval $(call add_share_file,share/gatemate,techlibs/gatemate/cells_bb.v))
+$(eval $(call add_share_file,share/gatemate,techlibs/gatemate/brams_map.v))
+$(eval $(call add_share_file,share/gatemate,techlibs/gatemate/brams.txt))
+$(eval $(call add_share_file,share/gatemate,techlibs/gatemate/brams_init_20.vh))
+$(eval $(call add_share_file,share/gatemate,techlibs/gatemate/brams_init_40.vh))
diff --git a/techlibs/gatemate/arith_map.v b/techlibs/gatemate/arith_map.v new file mode 100644 index 000000000..a3ab9c186 --- /dev/null +++ b/techlibs/gatemate/arith_map.v @@ -0,0 +1,69 @@ +/*
+ * yosys -- Yosys Open SYnthesis Suite
+ *
+ * Copyright (C) 2021 Cologne Chip AG <support@colognechip.com>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+
+(* techmap_celltype = "$alu" *)
+module _80_gatemate_alu(A, B, CI, BI, X, Y, CO);
+ parameter A_SIGNED = 0;
+ parameter B_SIGNED = 0;
+ parameter A_WIDTH = 1;
+ parameter B_WIDTH = 1;
+ parameter Y_WIDTH = 1;
+
+ (* force_downto *)
+ input [A_WIDTH-1:0] A;
+ (* force_downto *)
+ input [B_WIDTH-1:0] B;
+ (* force_downto *)
+ output [Y_WIDTH-1:0] X, Y;
+
+ input CI, BI;
+ (* force_downto *)
+ output [Y_WIDTH-1:0] CO;
+
+ wire _TECHMAP_FAIL_ = Y_WIDTH <= 2;
+
+ (* force_downto *)
+ wire [Y_WIDTH-1:0] A_buf, B_buf;
+ \$pos #(.A_SIGNED(A_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(Y_WIDTH)) A_conv (.A(A), .Y(A_buf));
+ \$pos #(.A_SIGNED(B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(Y_WIDTH)) B_conv (.A(B), .Y(B_buf));
+
+ (* force_downto *)
+ wire [Y_WIDTH-1:0] AA = A_buf;
+ (* force_downto *)
+ wire [Y_WIDTH-1:0] BB = BI ? ~B_buf : B_buf;
+ (* force_downto *)
+ wire [Y_WIDTH-1:0] C = {CO, CI};
+
+ genvar i;
+ generate
+ for (i = 0; i < Y_WIDTH; i = i + 1)
+ begin: slice
+ CC_ADDF addf_i (
+ .A(AA[i]),
+ .B(BB[i]),
+ .CI(C[i]),
+ .CO(CO[i]),
+ .S(Y[i])
+ );
+ end
+ endgenerate
+
+ assign X = AA ^ BB;
+
+endmodule
diff --git a/techlibs/gatemate/brams.txt b/techlibs/gatemate/brams.txt new file mode 100644 index 000000000..a0b500060 --- /dev/null +++ b/techlibs/gatemate/brams.txt @@ -0,0 +1,76 @@ +ram block $__CC_BRAM_TDP_ { + option "MODE" "20K" { + abits 14; + widths 1 2 5 10 20 per_port; + cost 129; + } + option "MODE" "40K" { + abits 15; + widths 1 2 5 10 20 40 per_port; + cost 257; + } + option "MODE" "CASCADE" { + abits 16; + # hack to enforce same INIT layout as in the other modes + widths 1 2 5 per_port; + cost 513; + } + byte 1; + init no_undef; + port srsw "A" "B" { + clock anyedge; + clken; + option "MODE" "20K" { + width mix; + } + option "MODE" "40K" { + width mix; + } + option "MODE" "CASCADE" { + width mix 1; + } + portoption "WR_MODE" "NO_CHANGE" { + rdwr no_change; + } + portoption "WR_MODE" "WRITE_THROUGH" { + rdwr new; + } + wrbe_separate; + } +} + +ram block $__CC_BRAM_SDP_ { + option "MODE" "20K" { + abits 14; + widths 1 2 5 10 20 40 per_port; + cost 129; + } + option "MODE" "40K" { + abits 15; + widths 1 2 5 10 20 40 80 per_port; + cost 257; + } + byte 1; + init no_undef; + port sr "R" { + option "MODE" "20K" { + width 40; + } + option "MODE" "40K" { + width 80; + } + clock anyedge; + clken; + } + port sw "W" { + option "MODE" "20K" { + width 40; + } + option "MODE" "40K" { + width 80; + } + clock anyedge; + clken; + wrbe_separate; + } +} diff --git a/techlibs/gatemate/brams_init_20.vh b/techlibs/gatemate/brams_init_20.vh new file mode 100644 index 000000000..d0764ed2a --- /dev/null +++ b/techlibs/gatemate/brams_init_20.vh @@ -0,0 +1,64 @@ +.INIT_00(permute_init(INIT[ 0*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_01(permute_init(INIT[ 1*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_02(permute_init(INIT[ 2*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_03(permute_init(INIT[ 3*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_04(permute_init(INIT[ 4*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_05(permute_init(INIT[ 5*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_06(permute_init(INIT[ 6*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_07(permute_init(INIT[ 7*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_08(permute_init(INIT[ 8*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_09(permute_init(INIT[ 9*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_0A(permute_init(INIT[ 10*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_0B(permute_init(INIT[ 11*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_0C(permute_init(INIT[ 12*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_0D(permute_init(INIT[ 13*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_0E(permute_init(INIT[ 14*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_0F(permute_init(INIT[ 15*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_10(permute_init(INIT[ 16*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_11(permute_init(INIT[ 17*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_12(permute_init(INIT[ 18*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_13(permute_init(INIT[ 19*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_14(permute_init(INIT[ 20*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_15(permute_init(INIT[ 21*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_16(permute_init(INIT[ 22*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_17(permute_init(INIT[ 23*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_18(permute_init(INIT[ 24*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_19(permute_init(INIT[ 25*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_1A(permute_init(INIT[ 26*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_1B(permute_init(INIT[ 27*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_1C(permute_init(INIT[ 28*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_1D(permute_init(INIT[ 29*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_1E(permute_init(INIT[ 30*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_1F(permute_init(INIT[ 31*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_20(permute_init(INIT[ 32*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_21(permute_init(INIT[ 33*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_22(permute_init(INIT[ 34*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_23(permute_init(INIT[ 35*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_24(permute_init(INIT[ 36*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_25(permute_init(INIT[ 37*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_26(permute_init(INIT[ 38*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_27(permute_init(INIT[ 39*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_28(permute_init(INIT[ 40*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_29(permute_init(INIT[ 41*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_2A(permute_init(INIT[ 42*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_2B(permute_init(INIT[ 43*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_2C(permute_init(INIT[ 44*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_2D(permute_init(INIT[ 45*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_2E(permute_init(INIT[ 46*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_2F(permute_init(INIT[ 47*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_30(permute_init(INIT[ 48*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_31(permute_init(INIT[ 49*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_32(permute_init(INIT[ 50*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_33(permute_init(INIT[ 51*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_34(permute_init(INIT[ 52*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_35(permute_init(INIT[ 53*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_36(permute_init(INIT[ 54*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_37(permute_init(INIT[ 55*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_38(permute_init(INIT[ 56*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_39(permute_init(INIT[ 57*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_3A(permute_init(INIT[ 58*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_3B(permute_init(INIT[ 59*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_3C(permute_init(INIT[ 60*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_3D(permute_init(INIT[ 61*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_3E(permute_init(INIT[ 62*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_3F(permute_init(INIT[ 63*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), diff --git a/techlibs/gatemate/brams_init_40.vh b/techlibs/gatemate/brams_init_40.vh new file mode 100644 index 000000000..649342560 --- /dev/null +++ b/techlibs/gatemate/brams_init_40.vh @@ -0,0 +1,260 @@ +`ifdef INIT_LOWER +.INIT_00(permute_init(INIT[ 0*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_01(permute_init(INIT[ 1*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_02(permute_init(INIT[ 2*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_03(permute_init(INIT[ 3*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_04(permute_init(INIT[ 4*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_05(permute_init(INIT[ 5*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_06(permute_init(INIT[ 6*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_07(permute_init(INIT[ 7*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_08(permute_init(INIT[ 8*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_09(permute_init(INIT[ 9*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_0A(permute_init(INIT[ 10*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_0B(permute_init(INIT[ 11*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_0C(permute_init(INIT[ 12*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_0D(permute_init(INIT[ 13*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_0E(permute_init(INIT[ 14*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_0F(permute_init(INIT[ 15*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_10(permute_init(INIT[ 16*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_11(permute_init(INIT[ 17*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_12(permute_init(INIT[ 18*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_13(permute_init(INIT[ 19*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_14(permute_init(INIT[ 20*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_15(permute_init(INIT[ 21*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_16(permute_init(INIT[ 22*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_17(permute_init(INIT[ 23*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_18(permute_init(INIT[ 24*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_19(permute_init(INIT[ 25*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_1A(permute_init(INIT[ 26*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_1B(permute_init(INIT[ 27*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_1C(permute_init(INIT[ 28*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_1D(permute_init(INIT[ 29*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_1E(permute_init(INIT[ 30*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_1F(permute_init(INIT[ 31*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_20(permute_init(INIT[ 32*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_21(permute_init(INIT[ 33*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_22(permute_init(INIT[ 34*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_23(permute_init(INIT[ 35*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_24(permute_init(INIT[ 36*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_25(permute_init(INIT[ 37*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_26(permute_init(INIT[ 38*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_27(permute_init(INIT[ 39*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_28(permute_init(INIT[ 40*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_29(permute_init(INIT[ 41*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_2A(permute_init(INIT[ 42*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_2B(permute_init(INIT[ 43*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_2C(permute_init(INIT[ 44*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_2D(permute_init(INIT[ 45*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_2E(permute_init(INIT[ 46*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_2F(permute_init(INIT[ 47*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_30(permute_init(INIT[ 48*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_31(permute_init(INIT[ 49*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_32(permute_init(INIT[ 50*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_33(permute_init(INIT[ 51*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_34(permute_init(INIT[ 52*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_35(permute_init(INIT[ 53*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_36(permute_init(INIT[ 54*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_37(permute_init(INIT[ 55*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_38(permute_init(INIT[ 56*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_39(permute_init(INIT[ 57*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_3A(permute_init(INIT[ 58*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_3B(permute_init(INIT[ 59*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_3C(permute_init(INIT[ 60*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_3D(permute_init(INIT[ 61*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_3E(permute_init(INIT[ 62*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_3F(permute_init(INIT[ 63*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_40(permute_init(INIT[ 64*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_41(permute_init(INIT[ 65*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_42(permute_init(INIT[ 66*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_43(permute_init(INIT[ 67*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_44(permute_init(INIT[ 68*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_45(permute_init(INIT[ 69*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_46(permute_init(INIT[ 70*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_47(permute_init(INIT[ 71*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_48(permute_init(INIT[ 72*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_49(permute_init(INIT[ 73*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_4A(permute_init(INIT[ 74*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_4B(permute_init(INIT[ 75*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_4C(permute_init(INIT[ 76*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_4D(permute_init(INIT[ 77*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_4E(permute_init(INIT[ 78*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_4F(permute_init(INIT[ 79*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_50(permute_init(INIT[ 80*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_51(permute_init(INIT[ 81*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_52(permute_init(INIT[ 82*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_53(permute_init(INIT[ 83*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_54(permute_init(INIT[ 84*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_55(permute_init(INIT[ 85*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_56(permute_init(INIT[ 86*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_57(permute_init(INIT[ 87*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_58(permute_init(INIT[ 88*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_59(permute_init(INIT[ 89*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_5A(permute_init(INIT[ 90*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_5B(permute_init(INIT[ 91*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_5C(permute_init(INIT[ 92*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_5D(permute_init(INIT[ 93*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_5E(permute_init(INIT[ 94*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_5F(permute_init(INIT[ 95*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_60(permute_init(INIT[ 96*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_61(permute_init(INIT[ 97*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_62(permute_init(INIT[ 98*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_63(permute_init(INIT[ 99*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_64(permute_init(INIT[100*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_65(permute_init(INIT[101*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_66(permute_init(INIT[102*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_67(permute_init(INIT[103*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_68(permute_init(INIT[104*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_69(permute_init(INIT[105*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_6A(permute_init(INIT[106*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_6B(permute_init(INIT[107*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_6C(permute_init(INIT[108*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_6D(permute_init(INIT[109*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_6E(permute_init(INIT[110*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_6F(permute_init(INIT[111*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_70(permute_init(INIT[112*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_71(permute_init(INIT[113*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_72(permute_init(INIT[114*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_73(permute_init(INIT[115*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_74(permute_init(INIT[116*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_75(permute_init(INIT[117*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_76(permute_init(INIT[118*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_77(permute_init(INIT[119*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_78(permute_init(INIT[120*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_79(permute_init(INIT[121*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_7A(permute_init(INIT[122*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_7B(permute_init(INIT[123*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_7C(permute_init(INIT[124*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_7D(permute_init(INIT[125*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_7E(permute_init(INIT[126*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_7F(permute_init(INIT[127*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +`endif +`ifdef INIT_UPPER +.INIT_00(permute_init(INIT[128*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_01(permute_init(INIT[129*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_02(permute_init(INIT[130*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_03(permute_init(INIT[131*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_04(permute_init(INIT[132*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_05(permute_init(INIT[133*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_06(permute_init(INIT[134*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_07(permute_init(INIT[135*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_08(permute_init(INIT[136*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_09(permute_init(INIT[137*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_0A(permute_init(INIT[138*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_0B(permute_init(INIT[139*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_0C(permute_init(INIT[140*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_0D(permute_init(INIT[141*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_0E(permute_init(INIT[142*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_0F(permute_init(INIT[143*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_10(permute_init(INIT[144*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_11(permute_init(INIT[145*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_12(permute_init(INIT[146*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_13(permute_init(INIT[147*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_14(permute_init(INIT[148*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_15(permute_init(INIT[149*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_16(permute_init(INIT[150*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_17(permute_init(INIT[151*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_18(permute_init(INIT[152*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_19(permute_init(INIT[153*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_1A(permute_init(INIT[154*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_1B(permute_init(INIT[155*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_1C(permute_init(INIT[156*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_1D(permute_init(INIT[157*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_1E(permute_init(INIT[158*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_1F(permute_init(INIT[159*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_20(permute_init(INIT[160*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_21(permute_init(INIT[161*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_22(permute_init(INIT[162*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_23(permute_init(INIT[163*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_24(permute_init(INIT[164*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_25(permute_init(INIT[165*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_26(permute_init(INIT[166*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_27(permute_init(INIT[167*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_28(permute_init(INIT[168*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_29(permute_init(INIT[169*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_2A(permute_init(INIT[170*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_2B(permute_init(INIT[171*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_2C(permute_init(INIT[172*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_2D(permute_init(INIT[173*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_2E(permute_init(INIT[174*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_2F(permute_init(INIT[175*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_30(permute_init(INIT[176*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_31(permute_init(INIT[177*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_32(permute_init(INIT[178*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_33(permute_init(INIT[179*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_34(permute_init(INIT[180*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_35(permute_init(INIT[181*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_36(permute_init(INIT[182*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_37(permute_init(INIT[183*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_38(permute_init(INIT[184*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_39(permute_init(INIT[185*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_3A(permute_init(INIT[186*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_3B(permute_init(INIT[187*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_3C(permute_init(INIT[188*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_3D(permute_init(INIT[189*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_3E(permute_init(INIT[190*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_3F(permute_init(INIT[191*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_40(permute_init(INIT[192*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_41(permute_init(INIT[193*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_42(permute_init(INIT[194*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_43(permute_init(INIT[195*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_44(permute_init(INIT[196*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_45(permute_init(INIT[197*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_46(permute_init(INIT[198*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_47(permute_init(INIT[199*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_48(permute_init(INIT[200*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_49(permute_init(INIT[201*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_4A(permute_init(INIT[202*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_4B(permute_init(INIT[203*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_4C(permute_init(INIT[204*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_4D(permute_init(INIT[205*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_4E(permute_init(INIT[206*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_4F(permute_init(INIT[207*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_50(permute_init(INIT[208*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_51(permute_init(INIT[209*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_52(permute_init(INIT[210*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_53(permute_init(INIT[211*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_54(permute_init(INIT[212*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_55(permute_init(INIT[213*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_56(permute_init(INIT[214*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_57(permute_init(INIT[215*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_58(permute_init(INIT[216*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_59(permute_init(INIT[217*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_5A(permute_init(INIT[218*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_5B(permute_init(INIT[219*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_5C(permute_init(INIT[220*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_5D(permute_init(INIT[221*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_5E(permute_init(INIT[222*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_5F(permute_init(INIT[223*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_60(permute_init(INIT[224*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_61(permute_init(INIT[225*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_62(permute_init(INIT[226*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_63(permute_init(INIT[227*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_64(permute_init(INIT[228*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_65(permute_init(INIT[229*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_66(permute_init(INIT[230*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_67(permute_init(INIT[231*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_68(permute_init(INIT[232*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_69(permute_init(INIT[233*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_6A(permute_init(INIT[234*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_6B(permute_init(INIT[235*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_6C(permute_init(INIT[236*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_6D(permute_init(INIT[237*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_6E(permute_init(INIT[238*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_6F(permute_init(INIT[239*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_70(permute_init(INIT[240*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_71(permute_init(INIT[241*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_72(permute_init(INIT[242*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_73(permute_init(INIT[243*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_74(permute_init(INIT[244*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_75(permute_init(INIT[245*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_76(permute_init(INIT[246*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_77(permute_init(INIT[247*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_78(permute_init(INIT[248*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_79(permute_init(INIT[249*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_7A(permute_init(INIT[250*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_7B(permute_init(INIT[251*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_7C(permute_init(INIT[252*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_7D(permute_init(INIT[253*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_7E(permute_init(INIT[254*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_7F(permute_init(INIT[255*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +`endif diff --git a/techlibs/gatemate/brams_map.v b/techlibs/gatemate/brams_map.v new file mode 100644 index 000000000..7023f5ef2 --- /dev/null +++ b/techlibs/gatemate/brams_map.v @@ -0,0 +1,875 @@ +module $__CC_BRAM_TDP_(...);
+
+parameter INIT = 0;
+parameter OPTION_MODE = "20K";
+
+parameter PORT_A_CLK_POL = 1;
+parameter PORT_A_RD_WIDTH = 1;
+parameter PORT_A_WR_WIDTH = 1;
+parameter PORT_A_WR_BE_WIDTH = 1;
+parameter PORT_A_OPTION_WR_MODE = "NO_CHANGE";
+
+parameter PORT_B_CLK_POL = 1;
+parameter PORT_B_RD_WIDTH = 1;
+parameter PORT_B_WR_WIDTH = 1;
+parameter PORT_B_WR_BE_WIDTH = 1;
+parameter PORT_B_OPTION_WR_MODE = "NO_CHANGE";
+
+input PORT_A_CLK;
+input PORT_A_CLK_EN;
+input PORT_A_WR_EN;
+input [15:0] PORT_A_ADDR;
+input [PORT_A_WR_BE_WIDTH-1:0] PORT_A_WR_BE;
+input [PORT_A_WR_WIDTH-1:0] PORT_A_WR_DATA;
+output [PORT_A_RD_WIDTH-1:0] PORT_A_RD_DATA;
+
+input PORT_B_CLK;
+input PORT_B_CLK_EN;
+input PORT_B_WR_EN;
+input [15:0] PORT_B_ADDR;
+input [PORT_B_WR_BE_WIDTH-1:0] PORT_B_WR_BE;
+input [PORT_B_WR_WIDTH-1:0] PORT_B_WR_DATA;
+output [PORT_B_RD_WIDTH-1:0] PORT_B_RD_DATA;
+
+generate
+ if (OPTION_MODE == "20K") begin
+ CC_BRAM_20K #(
+ .INIT_00(INIT['h00*320+:320]),
+ .INIT_01(INIT['h01*320+:320]),
+ .INIT_02(INIT['h02*320+:320]),
+ .INIT_03(INIT['h03*320+:320]),
+ .INIT_04(INIT['h04*320+:320]),
+ .INIT_05(INIT['h05*320+:320]),
+ .INIT_06(INIT['h06*320+:320]),
+ .INIT_07(INIT['h07*320+:320]),
+ .INIT_08(INIT['h08*320+:320]),
+ .INIT_09(INIT['h09*320+:320]),
+ .INIT_0A(INIT['h0a*320+:320]),
+ .INIT_0B(INIT['h0b*320+:320]),
+ .INIT_0C(INIT['h0c*320+:320]),
+ .INIT_0D(INIT['h0d*320+:320]),
+ .INIT_0E(INIT['h0e*320+:320]),
+ .INIT_0F(INIT['h0f*320+:320]),
+ .INIT_10(INIT['h10*320+:320]),
+ .INIT_11(INIT['h11*320+:320]),
+ .INIT_12(INIT['h12*320+:320]),
+ .INIT_13(INIT['h13*320+:320]),
+ .INIT_14(INIT['h14*320+:320]),
+ .INIT_15(INIT['h15*320+:320]),
+ .INIT_16(INIT['h16*320+:320]),
+ .INIT_17(INIT['h17*320+:320]),
+ .INIT_18(INIT['h18*320+:320]),
+ .INIT_19(INIT['h19*320+:320]),
+ .INIT_1A(INIT['h1a*320+:320]),
+ .INIT_1B(INIT['h1b*320+:320]),
+ .INIT_1C(INIT['h1c*320+:320]),
+ .INIT_1D(INIT['h1d*320+:320]),
+ .INIT_1E(INIT['h1e*320+:320]),
+ .INIT_1F(INIT['h1f*320+:320]),
+ .INIT_20(INIT['h20*320+:320]),
+ .INIT_21(INIT['h21*320+:320]),
+ .INIT_22(INIT['h22*320+:320]),
+ .INIT_23(INIT['h23*320+:320]),
+ .INIT_24(INIT['h24*320+:320]),
+ .INIT_25(INIT['h25*320+:320]),
+ .INIT_26(INIT['h26*320+:320]),
+ .INIT_27(INIT['h27*320+:320]),
+ .INIT_28(INIT['h28*320+:320]),
+ .INIT_29(INIT['h29*320+:320]),
+ .INIT_2A(INIT['h2a*320+:320]),
+ .INIT_2B(INIT['h2b*320+:320]),
+ .INIT_2C(INIT['h2c*320+:320]),
+ .INIT_2D(INIT['h2d*320+:320]),
+ .INIT_2E(INIT['h2e*320+:320]),
+ .INIT_2F(INIT['h2f*320+:320]),
+ .INIT_30(INIT['h30*320+:320]),
+ .INIT_31(INIT['h31*320+:320]),
+ .INIT_32(INIT['h32*320+:320]),
+ .INIT_33(INIT['h33*320+:320]),
+ .INIT_34(INIT['h34*320+:320]),
+ .INIT_35(INIT['h35*320+:320]),
+ .INIT_36(INIT['h36*320+:320]),
+ .INIT_37(INIT['h37*320+:320]),
+ .INIT_38(INIT['h38*320+:320]),
+ .INIT_39(INIT['h39*320+:320]),
+ .INIT_3A(INIT['h3a*320+:320]),
+ .INIT_3B(INIT['h3b*320+:320]),
+ .INIT_3C(INIT['h3c*320+:320]),
+ .INIT_3D(INIT['h3d*320+:320]),
+ .INIT_3E(INIT['h3e*320+:320]),
+ .INIT_3F(INIT['h3f*320+:320]),
+ .A_RD_WIDTH(PORT_A_RD_WIDTH),
+ .A_WR_WIDTH(PORT_A_WR_WIDTH),
+ .B_RD_WIDTH(PORT_B_RD_WIDTH),
+ .B_WR_WIDTH(PORT_B_WR_WIDTH),
+ .RAM_MODE("TDP"),
+ .A_WR_MODE(PORT_A_OPTION_WR_MODE),
+ .B_WR_MODE(PORT_B_OPTION_WR_MODE),
+ .A_CLK_INV(!PORT_A_CLK_POL),
+ .B_CLK_INV(!PORT_B_CLK_POL),
+ ) _TECHMAP_REPLACE_ (
+ .A_CLK(PORT_A_CLK),
+ .A_EN(PORT_A_CLK_EN),
+ .A_WE(PORT_A_WR_EN),
+ .A_BM(PORT_A_WR_BE),
+ .A_DI(PORT_A_WR_DATA),
+ .A_ADDR({PORT_A_ADDR[13:5], 1'b0, PORT_A_ADDR[4:0], 1'b0}),
+ .A_DO(PORT_A_RD_DATA),
+ .B_CLK(PORT_B_CLK),
+ .B_EN(PORT_B_CLK_EN),
+ .B_WE(PORT_B_WR_EN),
+ .B_BM(PORT_B_WR_BE),
+ .B_DI(PORT_A_WR_DATA),
+ .B_ADDR({PORT_B_ADDR[13:5], 1'b0, PORT_B_ADDR[4:0], 1'b0}),
+ .B_DO(PORT_B_RD_DATA),
+ );
+ end else if (OPTION_MODE == "40K") begin
+ CC_BRAM_40K #(
+ .INIT_00(INIT['h00*320+:320]),
+ .INIT_01(INIT['h01*320+:320]),
+ .INIT_02(INIT['h02*320+:320]),
+ .INIT_03(INIT['h03*320+:320]),
+ .INIT_04(INIT['h04*320+:320]),
+ .INIT_05(INIT['h05*320+:320]),
+ .INIT_06(INIT['h06*320+:320]),
+ .INIT_07(INIT['h07*320+:320]),
+ .INIT_08(INIT['h08*320+:320]),
+ .INIT_09(INIT['h09*320+:320]),
+ .INIT_0A(INIT['h0a*320+:320]),
+ .INIT_0B(INIT['h0b*320+:320]),
+ .INIT_0C(INIT['h0c*320+:320]),
+ .INIT_0D(INIT['h0d*320+:320]),
+ .INIT_0E(INIT['h0e*320+:320]),
+ .INIT_0F(INIT['h0f*320+:320]),
+ .INIT_10(INIT['h10*320+:320]),
+ .INIT_11(INIT['h11*320+:320]),
+ .INIT_12(INIT['h12*320+:320]),
+ .INIT_13(INIT['h13*320+:320]),
+ .INIT_14(INIT['h14*320+:320]),
+ .INIT_15(INIT['h15*320+:320]),
+ .INIT_16(INIT['h16*320+:320]),
+ .INIT_17(INIT['h17*320+:320]),
+ .INIT_18(INIT['h18*320+:320]),
+ .INIT_19(INIT['h19*320+:320]),
+ .INIT_1A(INIT['h1a*320+:320]),
+ .INIT_1B(INIT['h1b*320+:320]),
+ .INIT_1C(INIT['h1c*320+:320]),
+ .INIT_1D(INIT['h1d*320+:320]),
+ .INIT_1E(INIT['h1e*320+:320]),
+ .INIT_1F(INIT['h1f*320+:320]),
+ .INIT_20(INIT['h20*320+:320]),
+ .INIT_21(INIT['h21*320+:320]),
+ .INIT_22(INIT['h22*320+:320]),
+ .INIT_23(INIT['h23*320+:320]),
+ .INIT_24(INIT['h24*320+:320]),
+ .INIT_25(INIT['h25*320+:320]),
+ .INIT_26(INIT['h26*320+:320]),
+ .INIT_27(INIT['h27*320+:320]),
+ .INIT_28(INIT['h28*320+:320]),
+ .INIT_29(INIT['h29*320+:320]),
+ .INIT_2A(INIT['h2a*320+:320]),
+ .INIT_2B(INIT['h2b*320+:320]),
+ .INIT_2C(INIT['h2c*320+:320]),
+ .INIT_2D(INIT['h2d*320+:320]),
+ .INIT_2E(INIT['h2e*320+:320]),
+ .INIT_2F(INIT['h2f*320+:320]),
+ .INIT_30(INIT['h30*320+:320]),
+ .INIT_31(INIT['h31*320+:320]),
+ .INIT_32(INIT['h32*320+:320]),
+ .INIT_33(INIT['h33*320+:320]),
+ .INIT_34(INIT['h34*320+:320]),
+ .INIT_35(INIT['h35*320+:320]),
+ .INIT_36(INIT['h36*320+:320]),
+ .INIT_37(INIT['h37*320+:320]),
+ .INIT_38(INIT['h38*320+:320]),
+ .INIT_39(INIT['h39*320+:320]),
+ .INIT_3A(INIT['h3a*320+:320]),
+ .INIT_3B(INIT['h3b*320+:320]),
+ .INIT_3C(INIT['h3c*320+:320]),
+ .INIT_3D(INIT['h3d*320+:320]),
+ .INIT_3E(INIT['h3e*320+:320]),
+ .INIT_3F(INIT['h3f*320+:320]),
+ .INIT_40(INIT['h40*320+:320]),
+ .INIT_41(INIT['h41*320+:320]),
+ .INIT_42(INIT['h42*320+:320]),
+ .INIT_43(INIT['h43*320+:320]),
+ .INIT_44(INIT['h44*320+:320]),
+ .INIT_45(INIT['h45*320+:320]),
+ .INIT_46(INIT['h46*320+:320]),
+ .INIT_47(INIT['h47*320+:320]),
+ .INIT_48(INIT['h48*320+:320]),
+ .INIT_49(INIT['h49*320+:320]),
+ .INIT_4A(INIT['h4a*320+:320]),
+ .INIT_4B(INIT['h4b*320+:320]),
+ .INIT_4C(INIT['h4c*320+:320]),
+ .INIT_4D(INIT['h4d*320+:320]),
+ .INIT_4E(INIT['h4e*320+:320]),
+ .INIT_4F(INIT['h4f*320+:320]),
+ .INIT_50(INIT['h50*320+:320]),
+ .INIT_51(INIT['h51*320+:320]),
+ .INIT_52(INIT['h52*320+:320]),
+ .INIT_53(INIT['h53*320+:320]),
+ .INIT_54(INIT['h54*320+:320]),
+ .INIT_55(INIT['h55*320+:320]),
+ .INIT_56(INIT['h56*320+:320]),
+ .INIT_57(INIT['h57*320+:320]),
+ .INIT_58(INIT['h58*320+:320]),
+ .INIT_59(INIT['h59*320+:320]),
+ .INIT_5A(INIT['h5a*320+:320]),
+ .INIT_5B(INIT['h5b*320+:320]),
+ .INIT_5C(INIT['h5c*320+:320]),
+ .INIT_5D(INIT['h5d*320+:320]),
+ .INIT_5E(INIT['h5e*320+:320]),
+ .INIT_5F(INIT['h5f*320+:320]),
+ .INIT_60(INIT['h60*320+:320]),
+ .INIT_61(INIT['h61*320+:320]),
+ .INIT_62(INIT['h62*320+:320]),
+ .INIT_63(INIT['h63*320+:320]),
+ .INIT_64(INIT['h64*320+:320]),
+ .INIT_65(INIT['h65*320+:320]),
+ .INIT_66(INIT['h66*320+:320]),
+ .INIT_67(INIT['h67*320+:320]),
+ .INIT_68(INIT['h68*320+:320]),
+ .INIT_69(INIT['h69*320+:320]),
+ .INIT_6A(INIT['h6a*320+:320]),
+ .INIT_6B(INIT['h6b*320+:320]),
+ .INIT_6C(INIT['h6c*320+:320]),
+ .INIT_6D(INIT['h6d*320+:320]),
+ .INIT_6E(INIT['h6e*320+:320]),
+ .INIT_6F(INIT['h6f*320+:320]),
+ .INIT_70(INIT['h70*320+:320]),
+ .INIT_71(INIT['h71*320+:320]),
+ .INIT_72(INIT['h72*320+:320]),
+ .INIT_73(INIT['h73*320+:320]),
+ .INIT_74(INIT['h74*320+:320]),
+ .INIT_75(INIT['h75*320+:320]),
+ .INIT_76(INIT['h76*320+:320]),
+ .INIT_77(INIT['h77*320+:320]),
+ .INIT_78(INIT['h78*320+:320]),
+ .INIT_79(INIT['h79*320+:320]),
+ .INIT_7A(INIT['h7a*320+:320]),
+ .INIT_7B(INIT['h7b*320+:320]),
+ .INIT_7C(INIT['h7c*320+:320]),
+ .INIT_7D(INIT['h7d*320+:320]),
+ .INIT_7E(INIT['h7e*320+:320]),
+ .INIT_7F(INIT['h7f*320+:320]),
+ .A_RD_WIDTH(PORT_A_RD_WIDTH),
+ .A_WR_WIDTH(PORT_A_WR_WIDTH),
+ .B_RD_WIDTH(PORT_B_RD_WIDTH),
+ .B_WR_WIDTH(PORT_B_WR_WIDTH),
+ .RAM_MODE("TDP"),
+ .A_WR_MODE(PORT_A_OPTION_WR_MODE),
+ .B_WR_MODE(PORT_B_OPTION_WR_MODE),
+ .A_CLK_INV(!PORT_A_CLK_POL),
+ .B_CLK_INV(!PORT_B_CLK_POL),
+ ) _TECHMAP_REPLACE_ (
+ .A_CLK(PORT_A_CLK),
+ .A_EN(PORT_A_CLK_EN),
+ .A_WE(PORT_A_WR_EN),
+ .A_BM(PORT_A_WR_BE),
+ .A_DI(PORT_A_WR_DATA),
+ .A_ADDR({PORT_A_ADDR[14:0], 1'b0}),
+ .A_DO(PORT_A_RD_DATA),
+ .B_CLK(PORT_B_CLK),
+ .B_EN(PORT_B_CLK_EN),
+ .B_WE(PORT_B_WR_EN),
+ .B_BM(PORT_B_WR_BE),
+ .B_DI(PORT_A_WR_DATA),
+ .B_ADDR({PORT_B_ADDR[14:0], 1'b0}),
+ .B_DO(PORT_B_RD_DATA),
+ );
+ end else begin
+ wire CAS_A, CAS_B;
+ CC_BRAM_40K #(
+ .INIT_00(INIT['h00*320+:320]),
+ .INIT_01(INIT['h01*320+:320]),
+ .INIT_02(INIT['h02*320+:320]),
+ .INIT_03(INIT['h03*320+:320]),
+ .INIT_04(INIT['h04*320+:320]),
+ .INIT_05(INIT['h05*320+:320]),
+ .INIT_06(INIT['h06*320+:320]),
+ .INIT_07(INIT['h07*320+:320]),
+ .INIT_08(INIT['h08*320+:320]),
+ .INIT_09(INIT['h09*320+:320]),
+ .INIT_0A(INIT['h0a*320+:320]),
+ .INIT_0B(INIT['h0b*320+:320]),
+ .INIT_0C(INIT['h0c*320+:320]),
+ .INIT_0D(INIT['h0d*320+:320]),
+ .INIT_0E(INIT['h0e*320+:320]),
+ .INIT_0F(INIT['h0f*320+:320]),
+ .INIT_10(INIT['h10*320+:320]),
+ .INIT_11(INIT['h11*320+:320]),
+ .INIT_12(INIT['h12*320+:320]),
+ .INIT_13(INIT['h13*320+:320]),
+ .INIT_14(INIT['h14*320+:320]),
+ .INIT_15(INIT['h15*320+:320]),
+ .INIT_16(INIT['h16*320+:320]),
+ .INIT_17(INIT['h17*320+:320]),
+ .INIT_18(INIT['h18*320+:320]),
+ .INIT_19(INIT['h19*320+:320]),
+ .INIT_1A(INIT['h1a*320+:320]),
+ .INIT_1B(INIT['h1b*320+:320]),
+ .INIT_1C(INIT['h1c*320+:320]),
+ .INIT_1D(INIT['h1d*320+:320]),
+ .INIT_1E(INIT['h1e*320+:320]),
+ .INIT_1F(INIT['h1f*320+:320]),
+ .INIT_20(INIT['h20*320+:320]),
+ .INIT_21(INIT['h21*320+:320]),
+ .INIT_22(INIT['h22*320+:320]),
+ .INIT_23(INIT['h23*320+:320]),
+ .INIT_24(INIT['h24*320+:320]),
+ .INIT_25(INIT['h25*320+:320]),
+ .INIT_26(INIT['h26*320+:320]),
+ .INIT_27(INIT['h27*320+:320]),
+ .INIT_28(INIT['h28*320+:320]),
+ .INIT_29(INIT['h29*320+:320]),
+ .INIT_2A(INIT['h2a*320+:320]),
+ .INIT_2B(INIT['h2b*320+:320]),
+ .INIT_2C(INIT['h2c*320+:320]),
+ .INIT_2D(INIT['h2d*320+:320]),
+ .INIT_2E(INIT['h2e*320+:320]),
+ .INIT_2F(INIT['h2f*320+:320]),
+ .INIT_30(INIT['h30*320+:320]),
+ .INIT_31(INIT['h31*320+:320]),
+ .INIT_32(INIT['h32*320+:320]),
+ .INIT_33(INIT['h33*320+:320]),
+ .INIT_34(INIT['h34*320+:320]),
+ .INIT_35(INIT['h35*320+:320]),
+ .INIT_36(INIT['h36*320+:320]),
+ .INIT_37(INIT['h37*320+:320]),
+ .INIT_38(INIT['h38*320+:320]),
+ .INIT_39(INIT['h39*320+:320]),
+ .INIT_3A(INIT['h3a*320+:320]),
+ .INIT_3B(INIT['h3b*320+:320]),
+ .INIT_3C(INIT['h3c*320+:320]),
+ .INIT_3D(INIT['h3d*320+:320]),
+ .INIT_3E(INIT['h3e*320+:320]),
+ .INIT_3F(INIT['h3f*320+:320]),
+ .INIT_40(INIT['h40*320+:320]),
+ .INIT_41(INIT['h41*320+:320]),
+ .INIT_42(INIT['h42*320+:320]),
+ .INIT_43(INIT['h43*320+:320]),
+ .INIT_44(INIT['h44*320+:320]),
+ .INIT_45(INIT['h45*320+:320]),
+ .INIT_46(INIT['h46*320+:320]),
+ .INIT_47(INIT['h47*320+:320]),
+ .INIT_48(INIT['h48*320+:320]),
+ .INIT_49(INIT['h49*320+:320]),
+ .INIT_4A(INIT['h4a*320+:320]),
+ .INIT_4B(INIT['h4b*320+:320]),
+ .INIT_4C(INIT['h4c*320+:320]),
+ .INIT_4D(INIT['h4d*320+:320]),
+ .INIT_4E(INIT['h4e*320+:320]),
+ .INIT_4F(INIT['h4f*320+:320]),
+ .INIT_50(INIT['h50*320+:320]),
+ .INIT_51(INIT['h51*320+:320]),
+ .INIT_52(INIT['h52*320+:320]),
+ .INIT_53(INIT['h53*320+:320]),
+ .INIT_54(INIT['h54*320+:320]),
+ .INIT_55(INIT['h55*320+:320]),
+ .INIT_56(INIT['h56*320+:320]),
+ .INIT_57(INIT['h57*320+:320]),
+ .INIT_58(INIT['h58*320+:320]),
+ .INIT_59(INIT['h59*320+:320]),
+ .INIT_5A(INIT['h5a*320+:320]),
+ .INIT_5B(INIT['h5b*320+:320]),
+ .INIT_5C(INIT['h5c*320+:320]),
+ .INIT_5D(INIT['h5d*320+:320]),
+ .INIT_5E(INIT['h5e*320+:320]),
+ .INIT_5F(INIT['h5f*320+:320]),
+ .INIT_60(INIT['h60*320+:320]),
+ .INIT_61(INIT['h61*320+:320]),
+ .INIT_62(INIT['h62*320+:320]),
+ .INIT_63(INIT['h63*320+:320]),
+ .INIT_64(INIT['h64*320+:320]),
+ .INIT_65(INIT['h65*320+:320]),
+ .INIT_66(INIT['h66*320+:320]),
+ .INIT_67(INIT['h67*320+:320]),
+ .INIT_68(INIT['h68*320+:320]),
+ .INIT_69(INIT['h69*320+:320]),
+ .INIT_6A(INIT['h6a*320+:320]),
+ .INIT_6B(INIT['h6b*320+:320]),
+ .INIT_6C(INIT['h6c*320+:320]),
+ .INIT_6D(INIT['h6d*320+:320]),
+ .INIT_6E(INIT['h6e*320+:320]),
+ .INIT_6F(INIT['h6f*320+:320]),
+ .INIT_70(INIT['h70*320+:320]),
+ .INIT_71(INIT['h71*320+:320]),
+ .INIT_72(INIT['h72*320+:320]),
+ .INIT_73(INIT['h73*320+:320]),
+ .INIT_74(INIT['h74*320+:320]),
+ .INIT_75(INIT['h75*320+:320]),
+ .INIT_76(INIT['h76*320+:320]),
+ .INIT_77(INIT['h77*320+:320]),
+ .INIT_78(INIT['h78*320+:320]),
+ .INIT_79(INIT['h79*320+:320]),
+ .INIT_7A(INIT['h7a*320+:320]),
+ .INIT_7B(INIT['h7b*320+:320]),
+ .INIT_7C(INIT['h7c*320+:320]),
+ .INIT_7D(INIT['h7d*320+:320]),
+ .INIT_7E(INIT['h7e*320+:320]),
+ .INIT_7F(INIT['h7f*320+:320]),
+ .A_RD_WIDTH(PORT_A_RD_WIDTH),
+ .A_WR_WIDTH(PORT_A_WR_WIDTH),
+ .B_RD_WIDTH(PORT_B_RD_WIDTH),
+ .B_WR_WIDTH(PORT_B_WR_WIDTH),
+ .RAM_MODE("TDP"),
+ .A_WR_MODE(PORT_A_OPTION_WR_MODE),
+ .B_WR_MODE(PORT_B_OPTION_WR_MODE),
+ .A_CLK_INV(!PORT_A_CLK_POL),
+ .B_CLK_INV(!PORT_B_CLK_POL),
+ .CAS("LOWER"),
+ ) lower (
+ .A_CO(CAS_A),
+ .B_CO(CAS_B),
+ .A_CLK(PORT_A_CLK),
+ .A_EN(PORT_A_CLK_EN),
+ .A_WE(PORT_A_WR_EN),
+ .A_BM(PORT_A_WR_BE),
+ .A_DI(PORT_A_WR_DATA),
+ .A_ADDR({PORT_A_ADDR[14:0], PORT_A_ADDR[15]}),
+ .B_CLK(PORT_B_CLK),
+ .B_EN(PORT_B_CLK_EN),
+ .B_WE(PORT_B_WR_EN),
+ .B_BM(PORT_B_WR_BE),
+ .B_DI(PORT_A_WR_DATA),
+ .B_ADDR({PORT_B_ADDR[14:0], PORT_B_ADDR[15]}),
+ );
+ CC_BRAM_40K #(
+ .INIT_00(INIT['h80*320+:320]),
+ .INIT_01(INIT['h81*320+:320]),
+ .INIT_02(INIT['h82*320+:320]),
+ .INIT_03(INIT['h83*320+:320]),
+ .INIT_04(INIT['h84*320+:320]),
+ .INIT_05(INIT['h85*320+:320]),
+ .INIT_06(INIT['h86*320+:320]),
+ .INIT_07(INIT['h87*320+:320]),
+ .INIT_08(INIT['h88*320+:320]),
+ .INIT_09(INIT['h89*320+:320]),
+ .INIT_0A(INIT['h8a*320+:320]),
+ .INIT_0B(INIT['h8b*320+:320]),
+ .INIT_0C(INIT['h8c*320+:320]),
+ .INIT_0D(INIT['h8d*320+:320]),
+ .INIT_0E(INIT['h8e*320+:320]),
+ .INIT_0F(INIT['h8f*320+:320]),
+ .INIT_10(INIT['h90*320+:320]),
+ .INIT_11(INIT['h91*320+:320]),
+ .INIT_12(INIT['h92*320+:320]),
+ .INIT_13(INIT['h93*320+:320]),
+ .INIT_14(INIT['h94*320+:320]),
+ .INIT_15(INIT['h95*320+:320]),
+ .INIT_16(INIT['h96*320+:320]),
+ .INIT_17(INIT['h97*320+:320]),
+ .INIT_18(INIT['h98*320+:320]),
+ .INIT_19(INIT['h99*320+:320]),
+ .INIT_1A(INIT['h9a*320+:320]),
+ .INIT_1B(INIT['h9b*320+:320]),
+ .INIT_1C(INIT['h9c*320+:320]),
+ .INIT_1D(INIT['h9d*320+:320]),
+ .INIT_1E(INIT['h9e*320+:320]),
+ .INIT_1F(INIT['h9f*320+:320]),
+ .INIT_20(INIT['ha0*320+:320]),
+ .INIT_21(INIT['ha1*320+:320]),
+ .INIT_22(INIT['ha2*320+:320]),
+ .INIT_23(INIT['ha3*320+:320]),
+ .INIT_24(INIT['ha4*320+:320]),
+ .INIT_25(INIT['ha5*320+:320]),
+ .INIT_26(INIT['ha6*320+:320]),
+ .INIT_27(INIT['ha7*320+:320]),
+ .INIT_28(INIT['ha8*320+:320]),
+ .INIT_29(INIT['ha9*320+:320]),
+ .INIT_2A(INIT['haa*320+:320]),
+ .INIT_2B(INIT['hab*320+:320]),
+ .INIT_2C(INIT['hac*320+:320]),
+ .INIT_2D(INIT['had*320+:320]),
+ .INIT_2E(INIT['hae*320+:320]),
+ .INIT_2F(INIT['haf*320+:320]),
+ .INIT_30(INIT['hb0*320+:320]),
+ .INIT_31(INIT['hb1*320+:320]),
+ .INIT_32(INIT['hb2*320+:320]),
+ .INIT_33(INIT['hb3*320+:320]),
+ .INIT_34(INIT['hb4*320+:320]),
+ .INIT_35(INIT['hb5*320+:320]),
+ .INIT_36(INIT['hb6*320+:320]),
+ .INIT_37(INIT['hb7*320+:320]),
+ .INIT_38(INIT['hb8*320+:320]),
+ .INIT_39(INIT['hb9*320+:320]),
+ .INIT_3A(INIT['hba*320+:320]),
+ .INIT_3B(INIT['hbb*320+:320]),
+ .INIT_3C(INIT['hbc*320+:320]),
+ .INIT_3D(INIT['hbd*320+:320]),
+ .INIT_3E(INIT['hbe*320+:320]),
+ .INIT_3F(INIT['hbf*320+:320]),
+ .INIT_40(INIT['hc0*320+:320]),
+ .INIT_41(INIT['hc1*320+:320]),
+ .INIT_42(INIT['hc2*320+:320]),
+ .INIT_43(INIT['hc3*320+:320]),
+ .INIT_44(INIT['hc4*320+:320]),
+ .INIT_45(INIT['hc5*320+:320]),
+ .INIT_46(INIT['hc6*320+:320]),
+ .INIT_47(INIT['hc7*320+:320]),
+ .INIT_48(INIT['hc8*320+:320]),
+ .INIT_49(INIT['hc9*320+:320]),
+ .INIT_4A(INIT['hca*320+:320]),
+ .INIT_4B(INIT['hcb*320+:320]),
+ .INIT_4C(INIT['hcc*320+:320]),
+ .INIT_4D(INIT['hcd*320+:320]),
+ .INIT_4E(INIT['hce*320+:320]),
+ .INIT_4F(INIT['hcf*320+:320]),
+ .INIT_50(INIT['hd0*320+:320]),
+ .INIT_51(INIT['hd1*320+:320]),
+ .INIT_52(INIT['hd2*320+:320]),
+ .INIT_53(INIT['hd3*320+:320]),
+ .INIT_54(INIT['hd4*320+:320]),
+ .INIT_55(INIT['hd5*320+:320]),
+ .INIT_56(INIT['hd6*320+:320]),
+ .INIT_57(INIT['hd7*320+:320]),
+ .INIT_58(INIT['hd8*320+:320]),
+ .INIT_59(INIT['hd9*320+:320]),
+ .INIT_5A(INIT['hda*320+:320]),
+ .INIT_5B(INIT['hdb*320+:320]),
+ .INIT_5C(INIT['hdc*320+:320]),
+ .INIT_5D(INIT['hdd*320+:320]),
+ .INIT_5E(INIT['hde*320+:320]),
+ .INIT_5F(INIT['hdf*320+:320]),
+ .INIT_60(INIT['he0*320+:320]),
+ .INIT_61(INIT['he1*320+:320]),
+ .INIT_62(INIT['he2*320+:320]),
+ .INIT_63(INIT['he3*320+:320]),
+ .INIT_64(INIT['he4*320+:320]),
+ .INIT_65(INIT['he5*320+:320]),
+ .INIT_66(INIT['he6*320+:320]),
+ .INIT_67(INIT['he7*320+:320]),
+ .INIT_68(INIT['he8*320+:320]),
+ .INIT_69(INIT['he9*320+:320]),
+ .INIT_6A(INIT['hea*320+:320]),
+ .INIT_6B(INIT['heb*320+:320]),
+ .INIT_6C(INIT['hec*320+:320]),
+ .INIT_6D(INIT['hed*320+:320]),
+ .INIT_6E(INIT['hee*320+:320]),
+ .INIT_6F(INIT['hef*320+:320]),
+ .INIT_70(INIT['hf0*320+:320]),
+ .INIT_71(INIT['hf1*320+:320]),
+ .INIT_72(INIT['hf2*320+:320]),
+ .INIT_73(INIT['hf3*320+:320]),
+ .INIT_74(INIT['hf4*320+:320]),
+ .INIT_75(INIT['hf5*320+:320]),
+ .INIT_76(INIT['hf6*320+:320]),
+ .INIT_77(INIT['hf7*320+:320]),
+ .INIT_78(INIT['hf8*320+:320]),
+ .INIT_79(INIT['hf9*320+:320]),
+ .INIT_7A(INIT['hfa*320+:320]),
+ .INIT_7B(INIT['hfb*320+:320]),
+ .INIT_7C(INIT['hfc*320+:320]),
+ .INIT_7D(INIT['hfd*320+:320]),
+ .INIT_7E(INIT['hfe*320+:320]),
+ .INIT_7F(INIT['hff*320+:320]),
+ .A_RD_WIDTH(PORT_A_RD_WIDTH),
+ .A_WR_WIDTH(PORT_A_WR_WIDTH),
+ .B_RD_WIDTH(PORT_B_RD_WIDTH),
+ .B_WR_WIDTH(PORT_B_WR_WIDTH),
+ .RAM_MODE("TDP"),
+ .A_WR_MODE(PORT_A_OPTION_WR_MODE),
+ .B_WR_MODE(PORT_B_OPTION_WR_MODE),
+ .A_CLK_INV(!PORT_A_CLK_POL),
+ .B_CLK_INV(!PORT_B_CLK_POL),
+ .CAS("UPPER"),
+ ) upper (
+ .A_CI(CAS_A),
+ .B_CI(CAS_B),
+ .A_CLK(PORT_A_CLK),
+ .A_EN(PORT_A_CLK_EN),
+ .A_WE(PORT_A_WR_EN),
+ .A_BM(PORT_A_WR_BE),
+ .A_DI(PORT_A_WR_DATA),
+ .A_DO(PORT_A_RD_DATA),
+ .A_ADDR({PORT_A_ADDR[14:0], PORT_A_ADDR[15]}),
+ .B_CLK(PORT_B_CLK),
+ .B_EN(PORT_B_CLK_EN),
+ .B_WE(PORT_B_WR_EN),
+ .B_BM(PORT_B_WR_BE),
+ .B_DI(PORT_A_WR_DATA),
+ .B_DO(PORT_B_RD_DATA),
+ .B_ADDR({PORT_B_ADDR[14:0], PORT_B_ADDR[15]}),
+ );
+ end
+endgenerate
+
+endmodule
+
+
+module $__CC_BRAM_SDP_(...);
+
+parameter INIT = 0;
+parameter OPTION_MODE = "20K";
+
+parameter PORT_W_CLK_POL = 1;
+parameter PORT_W_WIDTH = 40;
+parameter PORT_W_WR_BE_WIDTH = 40;
+
+parameter PORT_R_CLK_POL = 1;
+parameter PORT_R_WIDTH = 40;
+
+input PORT_W_CLK;
+input PORT_W_CLK_EN;
+input PORT_W_WR_EN;
+input [15:0] PORT_W_ADDR;
+input [PORT_W_WR_BE_WIDTH-1:0] PORT_W_WR_BE;
+input [PORT_W_WIDTH-1:0] PORT_W_WR_DATA;
+
+input PORT_R_CLK;
+input PORT_R_CLK_EN;
+input [15:0] PORT_R_ADDR;
+output [PORT_R_WIDTH-1:0] PORT_R_RD_DATA;
+
+generate
+ if (OPTION_MODE == "20K") begin
+ CC_BRAM_20K #(
+ .INIT_00(INIT['h00*320+:320]),
+ .INIT_01(INIT['h01*320+:320]),
+ .INIT_02(INIT['h02*320+:320]),
+ .INIT_03(INIT['h03*320+:320]),
+ .INIT_04(INIT['h04*320+:320]),
+ .INIT_05(INIT['h05*320+:320]),
+ .INIT_06(INIT['h06*320+:320]),
+ .INIT_07(INIT['h07*320+:320]),
+ .INIT_08(INIT['h08*320+:320]),
+ .INIT_09(INIT['h09*320+:320]),
+ .INIT_0A(INIT['h0a*320+:320]),
+ .INIT_0B(INIT['h0b*320+:320]),
+ .INIT_0C(INIT['h0c*320+:320]),
+ .INIT_0D(INIT['h0d*320+:320]),
+ .INIT_0E(INIT['h0e*320+:320]),
+ .INIT_0F(INIT['h0f*320+:320]),
+ .INIT_10(INIT['h10*320+:320]),
+ .INIT_11(INIT['h11*320+:320]),
+ .INIT_12(INIT['h12*320+:320]),
+ .INIT_13(INIT['h13*320+:320]),
+ .INIT_14(INIT['h14*320+:320]),
+ .INIT_15(INIT['h15*320+:320]),
+ .INIT_16(INIT['h16*320+:320]),
+ .INIT_17(INIT['h17*320+:320]),
+ .INIT_18(INIT['h18*320+:320]),
+ .INIT_19(INIT['h19*320+:320]),
+ .INIT_1A(INIT['h1a*320+:320]),
+ .INIT_1B(INIT['h1b*320+:320]),
+ .INIT_1C(INIT['h1c*320+:320]),
+ .INIT_1D(INIT['h1d*320+:320]),
+ .INIT_1E(INIT['h1e*320+:320]),
+ .INIT_1F(INIT['h1f*320+:320]),
+ .INIT_20(INIT['h20*320+:320]),
+ .INIT_21(INIT['h21*320+:320]),
+ .INIT_22(INIT['h22*320+:320]),
+ .INIT_23(INIT['h23*320+:320]),
+ .INIT_24(INIT['h24*320+:320]),
+ .INIT_25(INIT['h25*320+:320]),
+ .INIT_26(INIT['h26*320+:320]),
+ .INIT_27(INIT['h27*320+:320]),
+ .INIT_28(INIT['h28*320+:320]),
+ .INIT_29(INIT['h29*320+:320]),
+ .INIT_2A(INIT['h2a*320+:320]),
+ .INIT_2B(INIT['h2b*320+:320]),
+ .INIT_2C(INIT['h2c*320+:320]),
+ .INIT_2D(INIT['h2d*320+:320]),
+ .INIT_2E(INIT['h2e*320+:320]),
+ .INIT_2F(INIT['h2f*320+:320]),
+ .INIT_30(INIT['h30*320+:320]),
+ .INIT_31(INIT['h31*320+:320]),
+ .INIT_32(INIT['h32*320+:320]),
+ .INIT_33(INIT['h33*320+:320]),
+ .INIT_34(INIT['h34*320+:320]),
+ .INIT_35(INIT['h35*320+:320]),
+ .INIT_36(INIT['h36*320+:320]),
+ .INIT_37(INIT['h37*320+:320]),
+ .INIT_38(INIT['h38*320+:320]),
+ .INIT_39(INIT['h39*320+:320]),
+ .INIT_3A(INIT['h3a*320+:320]),
+ .INIT_3B(INIT['h3b*320+:320]),
+ .INIT_3C(INIT['h3c*320+:320]),
+ .INIT_3D(INIT['h3d*320+:320]),
+ .INIT_3E(INIT['h3e*320+:320]),
+ .INIT_3F(INIT['h3f*320+:320]),
+ .A_RD_WIDTH(0),
+ .A_WR_WIDTH(PORT_W_WIDTH),
+ .B_RD_WIDTH(PORT_R_WIDTH),
+ .B_WR_WIDTH(0),
+ .RAM_MODE("SDP"),
+ .A_WR_MODE("NO_CHANGE"),
+ .B_WR_MODE("NO_CHANGE"),
+ .A_CLK_INV(!PORT_W_CLK_POL),
+ .B_CLK_INV(!PORT_R_CLK_POL),
+ ) _TECHMAP_REPLACE_ (
+ .A_CLK(PORT_W_CLK),
+ .A_EN(PORT_W_CLK_EN),
+ .A_WE(PORT_W_WR_EN),
+ .A_BM(PORT_W_WR_BE[19:0]),
+ .B_BM(PORT_W_WR_BE[39:20]),
+ .A_DI(PORT_W_WR_DATA[19:0]),
+ .B_DI(PORT_W_WR_DATA[39:20]),
+ .A_ADDR({PORT_W_ADDR[13:5], 1'b0, PORT_W_ADDR[4:0], 1'b0}),
+ .B_CLK(PORT_R_CLK),
+ .B_EN(PORT_R_CLK_EN),
+ .B_WE(1'b0),
+ .B_ADDR({PORT_R_ADDR[13:5], 1'b0, PORT_R_ADDR[4:0], 1'b0}),
+ .A_DO(PORT_R_RD_DATA[19:0]),
+ .B_DO(PORT_R_RD_DATA[39:20]),
+ );
+ end else if (OPTION_MODE == "40K") begin
+ CC_BRAM_40K #(
+ .INIT_00(INIT['h00*320+:320]),
+ .INIT_01(INIT['h01*320+:320]),
+ .INIT_02(INIT['h02*320+:320]),
+ .INIT_03(INIT['h03*320+:320]),
+ .INIT_04(INIT['h04*320+:320]),
+ .INIT_05(INIT['h05*320+:320]),
+ .INIT_06(INIT['h06*320+:320]),
+ .INIT_07(INIT['h07*320+:320]),
+ .INIT_08(INIT['h08*320+:320]),
+ .INIT_09(INIT['h09*320+:320]),
+ .INIT_0A(INIT['h0a*320+:320]),
+ .INIT_0B(INIT['h0b*320+:320]),
+ .INIT_0C(INIT['h0c*320+:320]),
+ .INIT_0D(INIT['h0d*320+:320]),
+ .INIT_0E(INIT['h0e*320+:320]),
+ .INIT_0F(INIT['h0f*320+:320]),
+ .INIT_10(INIT['h10*320+:320]),
+ .INIT_11(INIT['h11*320+:320]),
+ .INIT_12(INIT['h12*320+:320]),
+ .INIT_13(INIT['h13*320+:320]),
+ .INIT_14(INIT['h14*320+:320]),
+ .INIT_15(INIT['h15*320+:320]),
+ .INIT_16(INIT['h16*320+:320]),
+ .INIT_17(INIT['h17*320+:320]),
+ .INIT_18(INIT['h18*320+:320]),
+ .INIT_19(INIT['h19*320+:320]),
+ .INIT_1A(INIT['h1a*320+:320]),
+ .INIT_1B(INIT['h1b*320+:320]),
+ .INIT_1C(INIT['h1c*320+:320]),
+ .INIT_1D(INIT['h1d*320+:320]),
+ .INIT_1E(INIT['h1e*320+:320]),
+ .INIT_1F(INIT['h1f*320+:320]),
+ .INIT_20(INIT['h20*320+:320]),
+ .INIT_21(INIT['h21*320+:320]),
+ .INIT_22(INIT['h22*320+:320]),
+ .INIT_23(INIT['h23*320+:320]),
+ .INIT_24(INIT['h24*320+:320]),
+ .INIT_25(INIT['h25*320+:320]),
+ .INIT_26(INIT['h26*320+:320]),
+ .INIT_27(INIT['h27*320+:320]),
+ .INIT_28(INIT['h28*320+:320]),
+ .INIT_29(INIT['h29*320+:320]),
+ .INIT_2A(INIT['h2a*320+:320]),
+ .INIT_2B(INIT['h2b*320+:320]),
+ .INIT_2C(INIT['h2c*320+:320]),
+ .INIT_2D(INIT['h2d*320+:320]),
+ .INIT_2E(INIT['h2e*320+:320]),
+ .INIT_2F(INIT['h2f*320+:320]),
+ .INIT_30(INIT['h30*320+:320]),
+ .INIT_31(INIT['h31*320+:320]),
+ .INIT_32(INIT['h32*320+:320]),
+ .INIT_33(INIT['h33*320+:320]),
+ .INIT_34(INIT['h34*320+:320]),
+ .INIT_35(INIT['h35*320+:320]),
+ .INIT_36(INIT['h36*320+:320]),
+ .INIT_37(INIT['h37*320+:320]),
+ .INIT_38(INIT['h38*320+:320]),
+ .INIT_39(INIT['h39*320+:320]),
+ .INIT_3A(INIT['h3a*320+:320]),
+ .INIT_3B(INIT['h3b*320+:320]),
+ .INIT_3C(INIT['h3c*320+:320]),
+ .INIT_3D(INIT['h3d*320+:320]),
+ .INIT_3E(INIT['h3e*320+:320]),
+ .INIT_3F(INIT['h3f*320+:320]),
+ .INIT_40(INIT['h40*320+:320]),
+ .INIT_41(INIT['h41*320+:320]),
+ .INIT_42(INIT['h42*320+:320]),
+ .INIT_43(INIT['h43*320+:320]),
+ .INIT_44(INIT['h44*320+:320]),
+ .INIT_45(INIT['h45*320+:320]),
+ .INIT_46(INIT['h46*320+:320]),
+ .INIT_47(INIT['h47*320+:320]),
+ .INIT_48(INIT['h48*320+:320]),
+ .INIT_49(INIT['h49*320+:320]),
+ .INIT_4A(INIT['h4a*320+:320]),
+ .INIT_4B(INIT['h4b*320+:320]),
+ .INIT_4C(INIT['h4c*320+:320]),
+ .INIT_4D(INIT['h4d*320+:320]),
+ .INIT_4E(INIT['h4e*320+:320]),
+ .INIT_4F(INIT['h4f*320+:320]),
+ .INIT_50(INIT['h50*320+:320]),
+ .INIT_51(INIT['h51*320+:320]),
+ .INIT_52(INIT['h52*320+:320]),
+ .INIT_53(INIT['h53*320+:320]),
+ .INIT_54(INIT['h54*320+:320]),
+ .INIT_55(INIT['h55*320+:320]),
+ .INIT_56(INIT['h56*320+:320]),
+ .INIT_57(INIT['h57*320+:320]),
+ .INIT_58(INIT['h58*320+:320]),
+ .INIT_59(INIT['h59*320+:320]),
+ .INIT_5A(INIT['h5a*320+:320]),
+ .INIT_5B(INIT['h5b*320+:320]),
+ .INIT_5C(INIT['h5c*320+:320]),
+ .INIT_5D(INIT['h5d*320+:320]),
+ .INIT_5E(INIT['h5e*320+:320]),
+ .INIT_5F(INIT['h5f*320+:320]),
+ .INIT_60(INIT['h60*320+:320]),
+ .INIT_61(INIT['h61*320+:320]),
+ .INIT_62(INIT['h62*320+:320]),
+ .INIT_63(INIT['h63*320+:320]),
+ .INIT_64(INIT['h64*320+:320]),
+ .INIT_65(INIT['h65*320+:320]),
+ .INIT_66(INIT['h66*320+:320]),
+ .INIT_67(INIT['h67*320+:320]),
+ .INIT_68(INIT['h68*320+:320]),
+ .INIT_69(INIT['h69*320+:320]),
+ .INIT_6A(INIT['h6a*320+:320]),
+ .INIT_6B(INIT['h6b*320+:320]),
+ .INIT_6C(INIT['h6c*320+:320]),
+ .INIT_6D(INIT['h6d*320+:320]),
+ .INIT_6E(INIT['h6e*320+:320]),
+ .INIT_6F(INIT['h6f*320+:320]),
+ .INIT_70(INIT['h70*320+:320]),
+ .INIT_71(INIT['h71*320+:320]),
+ .INIT_72(INIT['h72*320+:320]),
+ .INIT_73(INIT['h73*320+:320]),
+ .INIT_74(INIT['h74*320+:320]),
+ .INIT_75(INIT['h75*320+:320]),
+ .INIT_76(INIT['h76*320+:320]),
+ .INIT_77(INIT['h77*320+:320]),
+ .INIT_78(INIT['h78*320+:320]),
+ .INIT_79(INIT['h79*320+:320]),
+ .INIT_7A(INIT['h7a*320+:320]),
+ .INIT_7B(INIT['h7b*320+:320]),
+ .INIT_7C(INIT['h7c*320+:320]),
+ .INIT_7D(INIT['h7d*320+:320]),
+ .INIT_7E(INIT['h7e*320+:320]),
+ .INIT_7F(INIT['h7f*320+:320]),
+ .A_RD_WIDTH(0),
+ .A_WR_WIDTH(PORT_W_WIDTH),
+ .B_RD_WIDTH(PORT_R_WIDTH),
+ .B_WR_WIDTH(0),
+ .RAM_MODE("SDP"),
+ .A_WR_MODE("NO_CHANGE"),
+ .B_WR_MODE("NO_CHANGE"),
+ .A_CLK_INV(!PORT_W_CLK_POL),
+ .B_CLK_INV(!PORT_R_CLK_POL),
+ ) _TECHMAP_REPLACE_ (
+ .A_CLK(PORT_W_CLK),
+ .A_EN(PORT_W_CLK_EN),
+ .A_WE(PORT_W_WR_EN),
+ .A_BM(PORT_W_WR_BE[39:0]),
+ .B_BM(PORT_W_WR_BE[79:40]),
+ .A_DI(PORT_W_WR_DATA[39:0]),
+ .B_DI(PORT_W_WR_DATA[79:40]),
+ .A_ADDR({PORT_W_ADDR[14:0], 1'b0}),
+ .B_CLK(PORT_R_CLK),
+ .B_EN(PORT_R_CLK_EN),
+ .B_WE(1'b0),
+ .B_ADDR({PORT_R_ADDR[14:0], 1'b0}),
+ .A_DO(PORT_R_RD_DATA[39:0]),
+ .B_DO(PORT_R_RD_DATA[79:40]),
+ );
+ end
+endgenerate
+
+endmodule
diff --git a/techlibs/gatemate/cells_bb.v b/techlibs/gatemate/cells_bb.v new file mode 100644 index 000000000..f6fe6a3e1 --- /dev/null +++ b/techlibs/gatemate/cells_bb.v @@ -0,0 +1,191 @@ +/*
+ * yosys -- Yosys Open SYnthesis Suite
+ *
+ * Copyright (C) 2021 Cologne Chip AG <support@colognechip.com>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+
+(* blackbox *)
+module CC_PLL #(
+ parameter REF_CLK = "", // e.g. "10.0"
+ parameter OUT_CLK = "", // e.g. "50.0"
+ parameter PERF_MD = "", // LOWPOWER, ECONOMY, SPEED
+ parameter LOW_JITTER = 1,
+ parameter CI_FILTER_CONST = 2,
+ parameter CP_FILTER_CONST = 4
+)(
+ input CLK_REF, CLK_FEEDBACK, USR_CLK_REF,
+ input USR_LOCKED_STDY_RST,
+ output USR_PLL_LOCKED_STDY, USR_PLL_LOCKED,
+ output CLK270, CLK180, CLK90, CLK0, CLK_REF_OUT
+);
+endmodule
+
+(* blackbox *)
+module CC_PLL_ADV #(
+ parameter [95:0] PLL_CFG_A = 96'bx,
+ parameter [95:0] PLL_CFG_B = 96'bx
+)(
+ input CLK_REF, CLK_FEEDBACK, USR_CLK_REF,
+ input USR_LOCKED_STDY_RST, USR_SEL_A_B,
+ output USR_PLL_LOCKED_STDY, USR_PLL_LOCKED,
+ output CLK270, CLK180, CLK90, CLK0, CLK_REF_OUT
+);
+endmodule
+
+(* blackbox *) (* keep *)
+module CC_SERDES #(
+ parameter SERDES_CFG = ""
+)(
+ input [63:0] TX_DATA_I,
+ input TX_RESET_I,
+ input TX_PCS_RESET_I,
+ input TX_PMA_RESET_I,
+ input PLL_RESET_I,
+ input TX_POWERDOWN_N_I,
+ input TX_POLARITY_I,
+ input [2:0] TX_PRBS_SEL_I,
+ input TX_PRBS_FORCE_ERR_I,
+ input TX_8B10B_EN_I,
+ input [7:0] TX_8B10B_BYPASS_I,
+ input [7:0] TX_CHAR_IS_K_I,
+ input [7:0] TX_CHAR_DISPMODE_I,
+ input [7:0] TX_CHAR_DISPVAL_I,
+ input TX_ELEC_IDLE_I,
+ input TX_DETECT_RX_I,
+ input [2:0] LOOPBACK_I,
+ input CLK_CORE_TX_I,
+ input CLK_CORE_RX_I,
+ input RX_RESET_I,
+ input RX_PMA_RESET_I,
+ input RX_EQA_RESET_I,
+ input RX_CDR_RESET_I,
+ input RX_PCS_RESET_I,
+ input RX_BUF_RESET_I,
+ input RX_POWERDOWN_N_I,
+ input RX_POLARITY_I,
+ input [2:0] RX_PRBS_SEL_I,
+ input RX_PRBS_CNT_RESET_I,
+ input RX_8B10B_EN_I,
+ input [7:0] RX_8B10B_BYPASS_I,
+ input RX_EN_EI_DETECTOR_I,
+ input RX_COMMA_DETECT_EN_I,
+ input RX_SLIDE_I,
+ input RX_MCOMMA_ALIGN_I,
+ input RX_PCOMMA_ALIGN_I,
+ input CLK_REG_I,
+ input REGFILE_WE_I,
+ input REGFILE_EN_I,
+ input [7:0] REGFILE_ADDR_I,
+ input [15:0] REGFILE_DI_I,
+ input [15:0] REGFILE_MASK_I,
+ output [63:0] RX_DATA_O,
+ output [7:0] RX_NOT_IN_TABLE_O,
+ output [7:0] RX_CHAR_IS_COMMA_O,
+ output [7:0] RX_CHAR_IS_K_O,
+ output [7:0] RX_DISP_ERR_O,
+ output RX_DETECT_DONE_O,
+ output RX_PRESENT_O,
+ output TX_BUF_ERR_O,
+ output TX_RESETDONE_O,
+ output RX_PRBS_ERR_O,
+ output RX_BUF_ERR_O,
+ output RX_BYTE_IS_ALIGNED_O,
+ output RX_BYTE_REALIGN_O,
+ output RX_RESETDONE_O,
+ output RX_EI_EN_O,
+ output CLK_CORE_RX_O,
+ output CLK_CORE_PLL_O,
+ output [15:0] REGFILE_DO_O,
+ output REGFILE_RDY_O
+);
+endmodule
+
+(* blackbox *) (* keep *)
+module CC_CFG_CTRL(
+ input [7:0] DATA,
+ input CLK,
+ input EN,
+ input RECFG,
+ input VALID
+);
+endmodule
+
+(* blackbox *)
+module CC_FIFO_40K (
+ output A_ECC_1B_ERR,
+ output B_ECC_1B_ERR,
+ output A_ECC_2B_ERR,
+ output B_ECC_2B_ERR,
+ // FIFO pop port
+ output [39:0] A_DO,
+ output [39:0] B_DO,
+ (* clkbuf_sink *)
+ input A_CLK,
+ input A_EN,
+ // FIFO push port
+ input [39:0] A_DI,
+ input [39:0] B_DI,
+ input [39:0] A_BM,
+ input [39:0] B_BM,
+ (* clkbuf_sink *)
+ input B_CLK,
+ input B_EN,
+ input B_WE,
+ // FIFO control
+ input F_RST_N,
+ input [12:0] F_ALMOST_FULL_OFFSET,
+ input [12:0] F_ALMOST_EMPTY_OFFSET,
+ // FIFO status signals
+ output F_FULL,
+ output F_EMPTY,
+ output F_ALMOST_FULL,
+ output F_ALMOST_EMPTY,
+ output F_RD_ERROR,
+ output F_WR_ERROR,
+ output [15:0] F_RD_PTR,
+ output [15:0] F_WR_PTR
+);
+ // Location format: D(0..N-1)X(0..3)Y(0..7) or UNPLACED
+ parameter LOC = "UNPLACED";
+
+ // Offset configuration
+ parameter [12:0] ALMOST_FULL_OFFSET = 12'b0;
+ parameter [12:0] ALMOST_EMPTY_OFFSET = 12'b0;
+
+ // Port Widths
+ parameter A_WIDTH = 0;
+ parameter B_WIDTH = 0;
+
+ // RAM and Write Modes
+ parameter RAM_MODE = "SDP"; // "TPD" or "SDP"
+ parameter FIFO_MODE = "SYNC"; // "ASYNC" or "SYNC"
+
+ // Inverting Control Pins
+ parameter A_CLK_INV = 1'b0;
+ parameter B_CLK_INV = 1'b0;
+ parameter A_EN_INV = 1'b0;
+ parameter B_EN_INV = 1'b0;
+ parameter A_WE_INV = 1'b0;
+ parameter B_WE_INV = 1'b0;
+
+ // Output Register
+ parameter A_DO_REG = 1'b0;
+ parameter B_DO_REG = 1'b0;
+
+ // Error Checking and Correction
+ parameter A_ECC_EN = 1'b0;
+ parameter B_ECC_EN = 1'b0;
+endmodule
diff --git a/techlibs/gatemate/cells_sim.v b/techlibs/gatemate/cells_sim.v new file mode 100644 index 000000000..1de3d1c7a --- /dev/null +++ b/techlibs/gatemate/cells_sim.v @@ -0,0 +1,1411 @@ +/*
+ * yosys -- Yosys Open SYnthesis Suite
+ *
+ * Copyright (C) 2021 Cologne Chip AG <support@colognechip.com>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+
+`timescale 1ps/1ps
+
+module CC_IBUF #(
+ parameter PIN_NAME = "UNPLACED",
+ parameter V_IO = "UNDEFINED",
+ parameter [0:0] PULLUP = 1'bx,
+ parameter [0:0] PULLDOWN = 1'bx,
+ parameter [0:0] KEEPER = 1'bx,
+ parameter [0:0] SCHMITT_TRIGGER = 1'bx,
+ // IOSEL
+ parameter [3:0] DELAY_IBF = 1'bx,
+ parameter [0:0] FF_IBF = 1'bx
+)(
+ (* iopad_external_pin *)
+ input I,
+ output Y
+);
+ assign Y = I;
+
+endmodule
+
+
+module CC_OBUF #(
+ parameter PIN_NAME = "UNPLACED",
+ parameter V_IO = "UNDEFINED",
+ parameter DRIVE = "UNDEFINED",
+ parameter SLEW = "UNDEFINED",
+ // IOSEL
+ parameter [3:0] DELAY_OBF = 1'bx,
+ parameter [0:0] FF_OBF = 1'bx
+)(
+ input A,
+ (* iopad_external_pin *)
+ output O
+);
+ assign O = A;
+
+endmodule
+
+
+module CC_TOBUF #(
+ parameter PIN_NAME = "UNPLACED",
+ parameter V_IO = "UNDEFINED",
+ parameter DRIVE = "UNDEFINED",
+ parameter SLEW = "UNDEFINED",
+ parameter [0:0] PULLUP = 1'bx,
+ parameter [0:0] PULLDOWN = 1'bx,
+ parameter [0:0] KEEPER = 1'bx,
+ // IOSEL
+ parameter [3:0] DELAY_OBF = 1'bx,
+ parameter [0:0] FF_OBF = 1'bx
+)(
+ input A, T,
+ (* iopad_external_pin *)
+ output O
+);
+ assign O = T ? 1'bz : A;
+
+endmodule
+
+
+module CC_IOBUF #(
+ parameter PIN_NAME = "UNPLACED",
+ parameter V_IO = "UNDEFINED",
+ parameter DRIVE = "UNDEFINED",
+ parameter SLEW = "UNDEFINED",
+ parameter [0:0] PULLUP = 1'bx,
+ parameter [0:0] PULLDOWN = 1'bx,
+ parameter [0:0] KEEPER = 1'bx,
+ parameter [0:0] SCHMITT_TRIGGER = 1'bx,
+ // IOSEL
+ parameter [3:0] DELAY_IBF = 1'bx,
+ parameter [3:0] DELAY_OBF = 1'bx,
+ parameter [0:0] FF_IBF = 1'bx,
+ parameter [0:0] FF_OBF = 1'bx
+)(
+ input A, T,
+ output Y,
+ (* iopad_external_pin *)
+ inout IO
+);
+ assign IO = T ? 1'bz : A;
+ assign Y = IO;
+
+endmodule
+
+
+module CC_LVDS_IBUF #(
+ parameter PIN_NAME_P = "UNPLACED",
+ parameter PIN_NAME_N = "UNPLACED",
+ parameter V_IO = "UNDEFINED",
+ parameter [0:0] LVDS_RTERM = 1'bx,
+ // IOSEL
+ parameter [3:0] DELAY_IBF = 1'bx,
+ parameter [0:0] FF_IBF = 1'bx
+)(
+ (* iopad_external_pin *)
+ input IP, IN,
+ output Y
+);
+ assign Y = IP;
+
+endmodule
+
+
+module CC_LVDS_OBUF #(
+ parameter PIN_NAME_P = "UNPLACED",
+ parameter PIN_NAME_N = "UNPLACED",
+ parameter V_IO = "UNDEFINED",
+ parameter [0:0] LVDS_BOOST = 1'bx,
+ // IOSEL
+ parameter [3:0] DELAY_OBF = 1'bx,
+ parameter [0:0] FF_OBF = 1'bx
+)(
+ input A,
+ (* iopad_external_pin *)
+ output OP, ON
+);
+ assign OP = A;
+ assign ON = ~A;
+
+endmodule
+
+
+module CC_LVDS_TOBUF #(
+ parameter PIN_NAME_P = "UNPLACED",
+ parameter PIN_NAME_N = "UNPLACED",
+ parameter V_IO = "UNDEFINED",
+ parameter [0:0] LVDS_BOOST = 1'bx,
+ // IOSEL
+ parameter [3:0] DELAY_OBF = 1'bx,
+ parameter [0:0] FF_OBF = 1'bx
+)(
+ input A, T,
+ (* iopad_external_pin *)
+ output OP, ON
+);
+ assign OP = T ? 1'bz : A;
+ assign ON = T ? 1'bz : ~A;
+
+endmodule
+
+
+module CC_LVDS_IOBUF #(
+ parameter PIN_NAME_P = "UNPLACED",
+ parameter PIN_NAME_N = "UNPLACED",
+ parameter V_IO = "UNDEFINED",
+ parameter [0:0] LVDS_RTERM = 1'bx,
+ parameter [0:0] LVDS_BOOST = 1'bx,
+ // IOSEL
+ parameter [3:0] DELAY_IBF = 1'bx,
+ parameter [3:0] DELAY_OBF = 1'bx,
+ parameter [0:0] FF_IBF = 1'bx,
+ parameter [0:0] FF_OBF = 1'bx
+)(
+ input A, T,
+ (* iopad_external_pin *)
+ inout IOP, ION,
+ output Y
+);
+ assign IOP = T ? 1'bz : A;
+ assign ION = T ? 1'bz : ~A;
+ assign Y = IOP;
+
+endmodule
+
+
+module CC_IDDR #(
+ parameter [0:0] CLK_INV = 1'b0
+)(
+ input D,
+ (* clkbuf_sink *)
+ input CLK,
+ output reg Q0, Q1
+);
+ wire clk;
+ assign clk = (CLK_INV) ? ~CLK : CLK;
+
+ always @(posedge clk)
+ begin
+ Q0 <= D;
+ end
+
+ always @(negedge clk)
+ begin
+ Q1 <= D;
+ end
+
+endmodule
+
+
+module CC_ODDR #(
+ parameter [0:0] CLK_INV = 1'b0
+)(
+ input D0,
+ input D1,
+ (* clkbuf_sink *)
+ input CLK,
+ (* clkbuf_sink *)
+ input DDR,
+ output Q
+);
+ wire clk;
+ assign clk = (CLK_INV) ? ~CLK : CLK;
+
+ reg q0, q1;
+ assign Q = (DDR) ? q0 : q1;
+
+ always @(posedge clk)
+ begin
+ q0 <= D0;
+ end
+
+ always @(negedge clk)
+ begin
+ q1 <= D1;
+ end
+
+endmodule
+
+
+module CC_DFF #(
+ parameter [0:0] CLK_INV = 1'b0,
+ parameter [0:0] EN_INV = 1'b0,
+ parameter [0:0] SR_INV = 1'b0,
+ parameter [0:0] SR_VAL = 1'b0
+)(
+ input D,
+ (* clkbuf_sink *)
+ input CLK,
+ input EN,
+ input SR,
+ output reg Q
+);
+ wire clk, en, sr;
+ assign clk = (CLK_INV) ? ~CLK : CLK;
+ assign en = (EN_INV) ? ~EN : EN;
+ assign sr = (SR_INV) ? ~SR : SR;
+
+ initial Q = 1'bX;
+
+ always @(posedge clk or posedge sr)
+ begin
+ if (sr) begin
+ Q <= SR_VAL;
+ end
+ else if (en) begin
+ Q <= D;
+ end
+ end
+
+endmodule
+
+
+module CC_DLT #(
+ parameter [0:0] G_INV = 1'b0,
+ parameter [0:0] SR_INV = 1'b0,
+ parameter [0:0] SR_VAL = 1'b0
+)(
+ input D,
+ input G,
+ input SR,
+ output reg Q
+);
+ wire en, sr;
+ assign en = (G_INV) ? ~G : G;
+ assign sr = (SR_INV) ? ~SR : SR;
+
+ initial Q = 1'bX;
+
+ always @(*)
+ begin
+ if (sr) begin
+ Q <= SR_VAL;
+ end
+ else if (en) begin
+ Q <= D;
+ end
+ end
+
+endmodule
+
+
+module CC_LUT1 (
+ output O,
+ input I0
+);
+ parameter [1:0] INIT = 0;
+
+ assign O = I0 ? INIT[1] : INIT[0];
+
+endmodule
+
+
+module CC_LUT2 (
+ output O,
+ input I0, I1
+);
+ parameter [3:0] INIT = 0;
+
+ wire [1:0] s1 = I1 ? INIT[3:2] : INIT[1:0];
+ assign O = I0 ? s1[1] : s1[0];
+
+endmodule
+
+
+module CC_LUT3 (
+ output O,
+ input I0, I1, I2
+);
+ parameter [7:0] INIT = 0;
+
+ wire [3:0] s2 = I2 ? INIT[7:4] : INIT[3:0];
+ wire [1:0] s1 = I1 ? s2[3:2] : s2[1:0];
+ assign O = I0 ? s1[1] : s1[0];
+
+endmodule
+
+
+module CC_LUT4 (
+ output O,
+ input I0, I1, I2, I3
+);
+ parameter [15:0] INIT = 0;
+
+ wire [7:0] s3 = I3 ? INIT[15:8] : INIT[7:0];
+ wire [3:0] s2 = I2 ? s3[7:4] : s3[3:0];
+ wire [1:0] s1 = I1 ? s2[3:2] : s2[1:0];
+ assign O = I0 ? s1[1] : s1[0];
+
+endmodule
+
+
+module CC_MX2 (
+ input D0, D1,
+ input S0,
+ output Y
+);
+ assign Y = S0 ? D1 : D0;
+
+endmodule
+
+
+module CC_MX4 (
+ input D0, D1, D2, D3,
+ input S0, S1,
+ output Y
+);
+ assign Y = S1 ? (S0 ? D3 : D2) :
+ (S0 ? D1 : D0);
+
+endmodule
+
+
+module CC_MX8 (
+ input D0, D1, D2, D3,
+ input D4, D5, D6, D7,
+ input S0, S1, S2,
+ output Y
+);
+ assign Y = S2 ? (S1 ? (S0 ? D7 : D6) :
+ (S0 ? D5 : D4)) :
+ (S1 ? (S0 ? D3 : D2) :
+ (S0 ? D1 : D0));
+
+endmodule
+
+
+module CC_ADDF (
+ input A, B, CI,
+ output CO, S
+);
+ assign {CO, S} = A + B + CI;
+
+endmodule
+
+
+module CC_MULT #(
+ parameter A_WIDTH = 0,
+ parameter B_WIDTH = 0,
+ parameter P_WIDTH = 0
+)(
+ input signed [A_WIDTH-1:0] A,
+ input signed [B_WIDTH-1:0] B,
+ output reg signed [P_WIDTH-1:0] P
+);
+ always @(*)
+ begin
+ P <= A * B;
+ end
+endmodule
+
+
+module CC_BUFG (
+ input I,
+ (* clkbuf_driver *)
+ output O
+);
+ assign O = I;
+
+endmodule
+
+
+module CC_BRAM_20K (
+ output [19:0] A_DO,
+ output [19:0] B_DO,
+ output ECC_1B_ERR,
+ output ECC_2B_ERR,
+ (* clkbuf_sink *)
+ input A_CLK,
+ (* clkbuf_sink *)
+ input B_CLK,
+ input A_EN,
+ input B_EN,
+ input A_WE,
+ input B_WE,
+ input [15:0] A_ADDR,
+ input [15:0] B_ADDR,
+ input [19:0] A_DI,
+ input [19:0] B_DI,
+ input [19:0] A_BM,
+ input [19:0] B_BM
+);
+ // Location format: D(0..N-1)(0..N-1)X(0..3)Y(0..7)Z(0..1) or UNPLACED
+ parameter LOC = "UNPLACED";
+
+ // Port Widths
+ parameter A_RD_WIDTH = 0;
+ parameter B_RD_WIDTH = 0;
+ parameter A_WR_WIDTH = 0;
+ parameter B_WR_WIDTH = 0;
+
+ // RAM and Write Modes
+ parameter RAM_MODE = "SDP";
+ parameter A_WR_MODE = "NO_CHANGE";
+ parameter B_WR_MODE = "NO_CHANGE";
+
+ // Inverting Control Pins
+ parameter A_CLK_INV = 1'b0;
+ parameter B_CLK_INV = 1'b0;
+ parameter A_EN_INV = 1'b0;
+ parameter B_EN_INV = 1'b0;
+ parameter A_WE_INV = 1'b0;
+ parameter B_WE_INV = 1'b0;
+
+ // Output Register
+ parameter A_DO_REG = 1'b0;
+ parameter B_DO_REG = 1'b0;
+
+ // Error Checking and Correction
+ parameter ECC_EN = 1'b0;
+
+ // RAM Contents
+ parameter INIT_00 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_01 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_02 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_03 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_04 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_05 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_06 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_07 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_08 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_09 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_10 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_11 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_12 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_13 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_14 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_15 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_16 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_17 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_18 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_19 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_1A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_1B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_1C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_1D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_1E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_1F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_20 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_21 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_22 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_23 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_24 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_25 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_26 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_27 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_28 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_29 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_2A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_2B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_2C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_2D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_2E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_2F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_30 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_31 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_32 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_33 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_34 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_35 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_36 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_37 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_38 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_39 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_3A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_3B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_3C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_3D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_3E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_3F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+
+ localparam WIDTH_MODE_A = (A_RD_WIDTH > A_WR_WIDTH) ? A_RD_WIDTH : A_WR_WIDTH;
+ localparam WIDTH_MODE_B = (B_RD_WIDTH > B_WR_WIDTH) ? B_RD_WIDTH : B_WR_WIDTH;
+
+ integer i, k;
+
+ // 512 x 40 bit
+ reg [20479:0] memory = 20480'b0;
+
+ initial begin
+ // Check parameters
+ if ((RAM_MODE != "SDP") && (RAM_MODE != "TDP")) begin
+ $display("ERROR: Illegal RAM MODE %d.", RAM_MODE);
+ $finish();
+ end
+ if ((A_WR_MODE != "WRITE_THROUGH") && (A_WR_MODE != "NO_CHANGE")) begin
+ $display("ERROR: Illegal RAM MODE %d.", RAM_MODE);
+ $finish();
+ end
+ if ((RAM_MODE == "SDP") && (A_WR_MODE == "WRITE_THROUGH")) begin
+ $display("ERROR: %s is not supported in %s mode.", A_WR_MODE, RAM_MODE);
+ $finish();
+ end
+ if (ECC_EN != 1'b0) begin
+ $display("WARNING: ECC feature not supported in simulation.");
+ end
+ if ((ECC_EN == 1'b1) && (RAM_MODE != "SDP") && (WIDTH_MODE_A != 40)) begin
+ $display("ERROR: Illegal ECC Port configuration. Must be SDP 40 bit, but is %s %d.", RAM_MODE, WIDTH_MODE_A);
+ $finish();
+ end
+ if ((WIDTH_MODE_A == 40) && (RAM_MODE == "TDP")) begin
+ $display("ERROR: Port A width of 40 bits is only supported in SDP mode.");
+ $finish();
+ end
+ if ((WIDTH_MODE_B == 40) && (RAM_MODE == "TDP")) begin
+ $display("ERROR: Port B width of 40 bits is only supported in SDP mode.");
+ $finish();
+ end
+ if ((WIDTH_MODE_A != 40) && (WIDTH_MODE_A != 20) && (WIDTH_MODE_A != 10) &&
+ (WIDTH_MODE_A != 5) && (WIDTH_MODE_A != 2) && (WIDTH_MODE_A != 1) && (WIDTH_MODE_A != 0)) begin
+ $display("ERROR: Illegal %s Port A width configuration %d.", RAM_MODE, WIDTH_MODE_A);
+ $finish();
+ end
+ if ((WIDTH_MODE_B != 40) && (WIDTH_MODE_B != 20) && (WIDTH_MODE_B != 10) &&
+ (WIDTH_MODE_B != 5) && (WIDTH_MODE_B != 2) && (WIDTH_MODE_B != 1) && (WIDTH_MODE_B != 0)) begin
+ $display("ERROR: Illegal %s Port B width configuration %d.", RAM_MODE, WIDTH_MODE_B);
+ $finish();
+ end
+ // RAM initialization
+ memory[320*0+319:320*0] = INIT_00;
+ memory[320*1+319:320*1] = INIT_01;
+ memory[320*2+319:320*2] = INIT_02;
+ memory[320*3+319:320*3] = INIT_03;
+ memory[320*4+319:320*4] = INIT_04;
+ memory[320*5+319:320*5] = INIT_05;
+ memory[320*6+319:320*6] = INIT_06;
+ memory[320*7+319:320*7] = INIT_07;
+ memory[320*8+319:320*8] = INIT_08;
+ memory[320*9+319:320*9] = INIT_09;
+ memory[320*10+319:320*10] = INIT_0A;
+ memory[320*11+319:320*11] = INIT_0B;
+ memory[320*12+319:320*12] = INIT_0C;
+ memory[320*13+319:320*13] = INIT_0D;
+ memory[320*14+319:320*14] = INIT_0E;
+ memory[320*15+319:320*15] = INIT_0F;
+ memory[320*16+319:320*16] = INIT_10;
+ memory[320*17+319:320*17] = INIT_11;
+ memory[320*18+319:320*18] = INIT_12;
+ memory[320*19+319:320*19] = INIT_13;
+ memory[320*20+319:320*20] = INIT_14;
+ memory[320*21+319:320*21] = INIT_15;
+ memory[320*22+319:320*22] = INIT_16;
+ memory[320*23+319:320*23] = INIT_17;
+ memory[320*24+319:320*24] = INIT_18;
+ memory[320*25+319:320*25] = INIT_19;
+ memory[320*26+319:320*26] = INIT_1A;
+ memory[320*27+319:320*27] = INIT_1B;
+ memory[320*28+319:320*28] = INIT_1C;
+ memory[320*29+319:320*29] = INIT_1D;
+ memory[320*30+319:320*30] = INIT_1E;
+ memory[320*31+319:320*31] = INIT_1F;
+ memory[320*32+319:320*32] = INIT_20;
+ memory[320*33+319:320*33] = INIT_21;
+ memory[320*34+319:320*34] = INIT_22;
+ memory[320*35+319:320*35] = INIT_23;
+ memory[320*36+319:320*36] = INIT_24;
+ memory[320*37+319:320*37] = INIT_25;
+ memory[320*38+319:320*38] = INIT_26;
+ memory[320*39+319:320*39] = INIT_27;
+ memory[320*40+319:320*40] = INIT_28;
+ memory[320*41+319:320*41] = INIT_29;
+ memory[320*42+319:320*42] = INIT_2A;
+ memory[320*43+319:320*43] = INIT_2B;
+ memory[320*44+319:320*44] = INIT_2C;
+ memory[320*45+319:320*45] = INIT_2D;
+ memory[320*46+319:320*46] = INIT_2E;
+ memory[320*47+319:320*47] = INIT_2F;
+ memory[320*48+319:320*48] = INIT_30;
+ memory[320*49+319:320*49] = INIT_31;
+ memory[320*50+319:320*50] = INIT_32;
+ memory[320*51+319:320*51] = INIT_33;
+ memory[320*52+319:320*52] = INIT_34;
+ memory[320*53+319:320*53] = INIT_35;
+ memory[320*54+319:320*54] = INIT_36;
+ memory[320*55+319:320*55] = INIT_37;
+ memory[320*56+319:320*56] = INIT_38;
+ memory[320*57+319:320*57] = INIT_39;
+ memory[320*58+319:320*58] = INIT_3A;
+ memory[320*59+319:320*59] = INIT_3B;
+ memory[320*60+319:320*60] = INIT_3C;
+ memory[320*61+319:320*61] = INIT_3D;
+ memory[320*62+319:320*62] = INIT_3E;
+ memory[320*63+319:320*63] = INIT_3F;
+ end
+
+ // Signal inversion
+ wire clka = A_CLK_INV ^ A_CLK;
+ wire clkb = B_CLK_INV ^ B_CLK;
+ wire ena = A_EN_INV ^ A_EN;
+ wire enb = B_EN_INV ^ B_EN;
+ wire wea = A_WE_INV ^ A_WE;
+ wire web = B_WE_INV ^ B_WE;
+
+ // Internal signals
+ wire [15:0] addra;
+ wire [15:0] addrb;
+ reg [19:0] A_DO_out = 0, A_DO_reg = 0;
+ reg [19:0] B_DO_out = 0, B_DO_reg = 0;
+
+ generate
+ if (RAM_MODE == "SDP") begin
+ // Port A (write)
+ if (A_WR_WIDTH == 40) begin
+ assign addra = A_ADDR[15:7]*40;
+ end
+ // Port B (read)
+ if (B_RD_WIDTH == 40) begin
+ assign addrb = B_ADDR[15:7]*40;
+ end
+ end
+ else if (RAM_MODE == "TDP") begin
+ // Port A
+ if (WIDTH_MODE_A <= 1) begin
+ wire [15:0] tmpa = {2'b0, A_ADDR[15:7], A_ADDR[5:1]};
+ assign addra = tmpa + (tmpa/4);
+ end
+ else if (WIDTH_MODE_A <= 2) begin
+ wire [15:0] tmpa = {3'b0, A_ADDR[15:7], A_ADDR[5:2]};
+ assign addra = tmpa*2 + (tmpa/2);
+ end
+ else if (WIDTH_MODE_A <= 5) begin
+ assign addra = {4'b0, A_ADDR[15:7], A_ADDR[5:3]}*5;
+ end
+ else if (WIDTH_MODE_A <= 10) begin
+ assign addra = {5'b0, A_ADDR[15:7], A_ADDR[5:4]}*10;
+ end
+ else if (WIDTH_MODE_A <= 20) begin
+ assign addra = {6'b0, A_ADDR[15:7], A_ADDR[5]}*20;
+ end
+ // Port B
+ if (WIDTH_MODE_B <= 1) begin
+ wire [15:0] tmpb = {2'b0, B_ADDR[15:7], B_ADDR[5:1]};
+ assign addrb = tmpb + (tmpb/4);
+ end
+ else if (WIDTH_MODE_B <= 2) begin
+ wire [15:0] tmpb = {3'b0, B_ADDR[15:7], B_ADDR[5:2]};
+ assign addrb = tmpb*2 + (tmpb/2);
+ end
+ else if (WIDTH_MODE_B <= 5) begin
+ assign addrb = {4'b0, B_ADDR[15:7], B_ADDR[5:3]}*5;
+ end
+ else if (WIDTH_MODE_B <= 10) begin
+ assign addrb = {5'b0, B_ADDR[15:7], B_ADDR[5:4]}*10;
+ end
+ else if (WIDTH_MODE_B <= 20) begin
+ assign addrb = {6'b0, B_ADDR[15:7], B_ADDR[5]}*20;
+ end
+ end
+ endgenerate
+
+ generate
+ if (RAM_MODE == "SDP") begin
+ // SDP write port
+ always @(posedge clka)
+ begin
+ for (k=0; k < A_WR_WIDTH; k=k+1) begin
+ if (k < 20) begin
+ if (ena && wea && A_BM[k]) memory[addra+k] <= A_DI[k];
+ end
+ else begin // use both ports
+ if (ena && wea && B_BM[k-20]) memory[addra+k] <= B_DI[k-20];
+ end
+ end
+ end
+ // SDP read port
+ always @(posedge clkb)
+ begin
+ // "NO_CHANGE" only
+ for (k=0; k < B_RD_WIDTH; k=k+1) begin
+ if (k < 20) begin
+ if (enb && !wea) A_DO_out[k] <= memory[addrb+k];
+ end
+ else begin // use both ports
+ if (enb && !wea) B_DO_out[k-20] <= memory[addrb+k];
+ end
+ end
+ end
+ end
+ else if (RAM_MODE == "TDP") begin
+ // TDP port A
+ always @(posedge clka)
+ begin
+ for (i=0; i < WIDTH_MODE_A; i=i+1) begin
+ if (ena && wea && A_BM[i]) memory[addra+i] <= A_DI[i];
+
+ if (A_WR_MODE == "NO_CHANGE") begin
+ if (ena && !wea) A_DO_out[i] <= memory[addra+i];
+ end
+ else if (A_WR_MODE == "WRITE_THROUGH") begin
+ if (ena) begin
+ if (wea && A_BM[i]) begin
+ A_DO_out[i] <= A_DI[i];
+ end
+ else begin
+ A_DO_out[i] <= memory[addra+i];
+ end
+ end
+ end
+ end
+ end
+ // TDP port B
+ always @(posedge clkb)
+ begin
+ for (i=0; i < WIDTH_MODE_B; i=i+1) begin
+ if (enb && web && B_BM[i]) memory[addrb+i] <= B_DI[i];
+
+ if (B_WR_MODE == "NO_CHANGE") begin
+ if (enb && !web) B_DO_out[i] <= memory[addrb+i];
+ end
+ else if (B_WR_MODE == "WRITE_THROUGH") begin
+ if (enb) begin
+ if (web && B_BM[i]) begin
+ B_DO_out[i] <= B_DI[i];
+ end
+ else begin
+ B_DO_out[i] <= memory[addrb+i];
+ end
+ end
+ end
+ end
+ end
+ end
+ endgenerate
+
+ // Optional output register
+ generate
+ if (A_DO_REG) begin
+ always @(posedge clka) begin
+ A_DO_reg <= A_DO_out;
+ end
+ assign A_DO = A_DO_reg;
+ end
+ else begin
+ assign A_DO = A_DO_out;
+ end
+ if (B_DO_REG) begin
+ always @(posedge clkb) begin
+ B_DO_reg <= B_DO_out;
+ end
+ assign B_DO = B_DO_reg;
+ end
+ else begin
+ assign B_DO = B_DO_out;
+ end
+ endgenerate
+endmodule
+
+
+module CC_BRAM_40K (
+ output [39:0] A_DO,
+ output [39:0] B_DO,
+ output A_ECC_1B_ERR,
+ output B_ECC_1B_ERR,
+ output A_ECC_2B_ERR,
+ output B_ECC_2B_ERR,
+ output reg A_CO = 0,
+ output reg B_CO = 0,
+ (* clkbuf_sink *)
+ input A_CLK,
+ (* clkbuf_sink *)
+ input B_CLK,
+ input A_EN,
+ input B_EN,
+ input A_WE,
+ input B_WE,
+ input [15:0] A_ADDR,
+ input [15:0] B_ADDR,
+ input [39:0] A_DI,
+ input [39:0] B_DI,
+ input [39:0] A_BM,
+ input [39:0] B_BM,
+ input A_CI,
+ input B_CI
+);
+ // Location format: D(0..N-1)X(0..3)Y(0..7) or UNPLACED
+ parameter LOC = "UNPLACED";
+ parameter CAS = "NONE"; // NONE, UPPER, LOWER
+
+ // Port Widths
+ parameter A_RD_WIDTH = 0;
+ parameter B_RD_WIDTH = 0;
+ parameter A_WR_WIDTH = 0;
+ parameter B_WR_WIDTH = 0;
+
+ // RAM and Write Modes
+ parameter RAM_MODE = "SDP";
+ parameter A_WR_MODE = "NO_CHANGE";
+ parameter B_WR_MODE = "NO_CHANGE";
+
+ // Inverting Control Pins
+ parameter A_CLK_INV = 1'b0;
+ parameter B_CLK_INV = 1'b0;
+ parameter A_EN_INV = 1'b0;
+ parameter B_EN_INV = 1'b0;
+ parameter A_WE_INV = 1'b0;
+ parameter B_WE_INV = 1'b0;
+
+ // Output Register
+ parameter A_DO_REG = 1'b0;
+ parameter B_DO_REG = 1'b0;
+
+ // Error Checking and Correction
+ parameter A_ECC_EN = 1'b0;
+ parameter B_ECC_EN = 1'b0;
+
+ parameter INIT_00 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_01 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_02 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_03 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_04 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_05 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_06 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_07 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_08 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_09 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_10 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_11 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_12 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_13 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_14 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_15 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_16 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_17 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_18 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_19 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_1A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_1B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_1C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_1D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_1E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_1F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_20 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_21 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_22 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_23 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_24 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_25 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_26 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_27 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_28 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_29 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_2A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_2B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_2C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_2D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_2E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_2F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_30 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_31 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_32 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_33 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_34 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_35 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_36 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_37 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_38 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_39 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_3A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_3B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_3C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_3D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_3E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_3F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_40 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_41 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_42 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_43 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_44 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_45 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_46 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_47 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_48 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_49 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_4A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_4B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_4C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_4D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_4E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_4F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_50 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_51 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_52 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_53 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_54 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_55 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_56 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_57 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_58 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_59 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_5A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_5B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_5C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_5D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_5E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_5F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_60 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_61 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_62 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_63 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_64 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_65 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_66 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_67 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_68 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_69 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_6A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_6B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_6C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_6D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_6E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_6F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_70 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_71 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_72 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_73 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_74 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_75 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_76 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_77 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_78 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_79 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_7A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_7B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_7C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_7D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_7E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_7F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+
+ localparam WIDTH_MODE_A = (A_RD_WIDTH > A_WR_WIDTH) ? A_RD_WIDTH : A_WR_WIDTH;
+ localparam WIDTH_MODE_B = (B_RD_WIDTH > B_WR_WIDTH) ? B_RD_WIDTH : B_WR_WIDTH;
+
+ integer i, k;
+
+ // 512 x 80 bit
+ reg [40959:0] memory = 40960'b0;
+
+ initial begin
+ // Check parameters
+ if ((RAM_MODE != "SDP") && (RAM_MODE != "TDP")) begin
+ $display("ERROR: Illegal RAM MODE %d.", RAM_MODE);
+ $finish();
+ end
+ if ((A_WR_MODE != "WRITE_THROUGH") && (A_WR_MODE != "NO_CHANGE")) begin
+ $display("ERROR: Illegal RAM MODE %d.", RAM_MODE);
+ $finish();
+ end
+ if ((RAM_MODE == "SDP") && (A_WR_MODE == "WRITE_THROUGH")) begin
+ $display("ERROR: %s is not supported in %s mode.", A_WR_MODE, RAM_MODE);
+ $finish();
+ end
+ if ((A_ECC_EN != 1'b0) || (B_ECC_EN != 1'b0)) begin
+ $display("WARNING: ECC feature not supported in simulation.");
+ end
+ if ((A_ECC_EN == 1'b1) && (RAM_MODE != "SDP") && (WIDTH_MODE_A != 40)) begin
+ $display("ERROR: Illegal ECC Port A configuration. Must be SDP 40 bit, but is %s %d.", RAM_MODE, WIDTH_MODE_A);
+ $finish();
+ end
+ if ((WIDTH_MODE_A == 80) && (RAM_MODE == "TDP")) begin
+ $display("ERROR: Port A width of 80 bits is only supported in SDP mode.");
+ $finish();
+ end
+ if ((WIDTH_MODE_B == 80) && (RAM_MODE == "TDP")) begin
+ $display("ERROR: Port B width of 80 bits is only supported in SDP mode.");
+ $finish();
+ end
+ if ((WIDTH_MODE_A != 80) && (WIDTH_MODE_A != 40) && (WIDTH_MODE_A != 20) && (WIDTH_MODE_A != 10) &&
+ (WIDTH_MODE_A != 5) && (WIDTH_MODE_A != 2) && (WIDTH_MODE_A != 1) && (WIDTH_MODE_A != 0)) begin
+ $display("ERROR: Illegal %s Port A width configuration %d.", RAM_MODE, WIDTH_MODE_A);
+ $finish();
+ end
+ if ((WIDTH_MODE_B != 80) && (WIDTH_MODE_B != 40) && (WIDTH_MODE_B != 20) && (WIDTH_MODE_B != 10) &&
+ (WIDTH_MODE_B != 5) && (WIDTH_MODE_B != 2) && (WIDTH_MODE_B != 1) && (WIDTH_MODE_B != 0)) begin
+ $display("ERROR: Illegal %s Port B width configuration %d.", RAM_MODE, WIDTH_MODE_B);
+ $finish();
+ end
+ if ((CAS != "NONE") && ((WIDTH_MODE_A > 1) || (WIDTH_MODE_B > 1))) begin
+ $display("ERROR: Cascade feature only supported in 1 bit data width mode.");
+ $finish();
+ end
+ if ((CAS != "NONE") && (RAM_MODE != "TDP")) begin
+ $display("ERROR: Cascade feature only supported in TDP mode.");
+ $finish();
+ end
+ // RAM initialization
+ memory[320*0+319:320*0] = INIT_00;
+ memory[320*1+319:320*1] = INIT_01;
+ memory[320*2+319:320*2] = INIT_02;
+ memory[320*3+319:320*3] = INIT_03;
+ memory[320*4+319:320*4] = INIT_04;
+ memory[320*5+319:320*5] = INIT_05;
+ memory[320*6+319:320*6] = INIT_06;
+ memory[320*7+319:320*7] = INIT_07;
+ memory[320*8+319:320*8] = INIT_08;
+ memory[320*9+319:320*9] = INIT_09;
+ memory[320*10+319:320*10] = INIT_0A;
+ memory[320*11+319:320*11] = INIT_0B;
+ memory[320*12+319:320*12] = INIT_0C;
+ memory[320*13+319:320*13] = INIT_0D;
+ memory[320*14+319:320*14] = INIT_0E;
+ memory[320*15+319:320*15] = INIT_0F;
+ memory[320*16+319:320*16] = INIT_10;
+ memory[320*17+319:320*17] = INIT_11;
+ memory[320*18+319:320*18] = INIT_12;
+ memory[320*19+319:320*19] = INIT_13;
+ memory[320*20+319:320*20] = INIT_14;
+ memory[320*21+319:320*21] = INIT_15;
+ memory[320*22+319:320*22] = INIT_16;
+ memory[320*23+319:320*23] = INIT_17;
+ memory[320*24+319:320*24] = INIT_18;
+ memory[320*25+319:320*25] = INIT_19;
+ memory[320*26+319:320*26] = INIT_1A;
+ memory[320*27+319:320*27] = INIT_1B;
+ memory[320*28+319:320*28] = INIT_1C;
+ memory[320*29+319:320*29] = INIT_1D;
+ memory[320*30+319:320*30] = INIT_1E;
+ memory[320*31+319:320*31] = INIT_1F;
+ memory[320*32+319:320*32] = INIT_20;
+ memory[320*33+319:320*33] = INIT_21;
+ memory[320*34+319:320*34] = INIT_22;
+ memory[320*35+319:320*35] = INIT_23;
+ memory[320*36+319:320*36] = INIT_24;
+ memory[320*37+319:320*37] = INIT_25;
+ memory[320*38+319:320*38] = INIT_26;
+ memory[320*39+319:320*39] = INIT_27;
+ memory[320*40+319:320*40] = INIT_28;
+ memory[320*41+319:320*41] = INIT_29;
+ memory[320*42+319:320*42] = INIT_2A;
+ memory[320*43+319:320*43] = INIT_2B;
+ memory[320*44+319:320*44] = INIT_2C;
+ memory[320*45+319:320*45] = INIT_2D;
+ memory[320*46+319:320*46] = INIT_2E;
+ memory[320*47+319:320*47] = INIT_2F;
+ memory[320*48+319:320*48] = INIT_30;
+ memory[320*49+319:320*49] = INIT_31;
+ memory[320*50+319:320*50] = INIT_32;
+ memory[320*51+319:320*51] = INIT_33;
+ memory[320*52+319:320*52] = INIT_34;
+ memory[320*53+319:320*53] = INIT_35;
+ memory[320*54+319:320*54] = INIT_36;
+ memory[320*55+319:320*55] = INIT_37;
+ memory[320*56+319:320*56] = INIT_38;
+ memory[320*57+319:320*57] = INIT_39;
+ memory[320*58+319:320*58] = INIT_3A;
+ memory[320*59+319:320*59] = INIT_3B;
+ memory[320*60+319:320*60] = INIT_3C;
+ memory[320*61+319:320*61] = INIT_3D;
+ memory[320*62+319:320*62] = INIT_3E;
+ memory[320*63+319:320*63] = INIT_3F;
+ memory[320*64+319:320*64] = INIT_40;
+ memory[320*65+319:320*65] = INIT_41;
+ memory[320*66+319:320*66] = INIT_42;
+ memory[320*67+319:320*67] = INIT_43;
+ memory[320*68+319:320*68] = INIT_44;
+ memory[320*69+319:320*69] = INIT_45;
+ memory[320*70+319:320*70] = INIT_46;
+ memory[320*71+319:320*71] = INIT_47;
+ memory[320*72+319:320*72] = INIT_48;
+ memory[320*73+319:320*73] = INIT_49;
+ memory[320*74+319:320*74] = INIT_4A;
+ memory[320*75+319:320*75] = INIT_4B;
+ memory[320*76+319:320*76] = INIT_4C;
+ memory[320*77+319:320*77] = INIT_4D;
+ memory[320*78+319:320*78] = INIT_4E;
+ memory[320*79+319:320*79] = INIT_4F;
+ memory[320*80+319:320*80] = INIT_50;
+ memory[320*81+319:320*81] = INIT_51;
+ memory[320*82+319:320*82] = INIT_52;
+ memory[320*83+319:320*83] = INIT_53;
+ memory[320*84+319:320*84] = INIT_54;
+ memory[320*85+319:320*85] = INIT_55;
+ memory[320*86+319:320*86] = INIT_56;
+ memory[320*87+319:320*87] = INIT_57;
+ memory[320*88+319:320*88] = INIT_58;
+ memory[320*89+319:320*89] = INIT_59;
+ memory[320*90+319:320*90] = INIT_5A;
+ memory[320*91+319:320*91] = INIT_5B;
+ memory[320*92+319:320*92] = INIT_5C;
+ memory[320*93+319:320*93] = INIT_5D;
+ memory[320*94+319:320*94] = INIT_5E;
+ memory[320*95+319:320*95] = INIT_5F;
+ memory[320*96+319:320*96] = INIT_60;
+ memory[320*97+319:320*97] = INIT_61;
+ memory[320*98+319:320*98] = INIT_62;
+ memory[320*99+319:320*99] = INIT_63;
+ memory[320*100+319:320*100] = INIT_64;
+ memory[320*101+319:320*101] = INIT_65;
+ memory[320*102+319:320*102] = INIT_66;
+ memory[320*103+319:320*103] = INIT_67;
+ memory[320*104+319:320*104] = INIT_68;
+ memory[320*105+319:320*105] = INIT_69;
+ memory[320*106+319:320*106] = INIT_6A;
+ memory[320*107+319:320*107] = INIT_6B;
+ memory[320*108+319:320*108] = INIT_6C;
+ memory[320*109+319:320*109] = INIT_6D;
+ memory[320*110+319:320*110] = INIT_6E;
+ memory[320*111+319:320*111] = INIT_6F;
+ memory[320*112+319:320*112] = INIT_70;
+ memory[320*113+319:320*113] = INIT_71;
+ memory[320*114+319:320*114] = INIT_72;
+ memory[320*115+319:320*115] = INIT_73;
+ memory[320*116+319:320*116] = INIT_74;
+ memory[320*117+319:320*117] = INIT_75;
+ memory[320*118+319:320*118] = INIT_76;
+ memory[320*119+319:320*119] = INIT_77;
+ memory[320*120+319:320*120] = INIT_78;
+ memory[320*121+319:320*121] = INIT_79;
+ memory[320*122+319:320*122] = INIT_7A;
+ memory[320*123+319:320*123] = INIT_7B;
+ memory[320*124+319:320*124] = INIT_7C;
+ memory[320*125+319:320*125] = INIT_7D;
+ memory[320*126+319:320*126] = INIT_7E;
+ memory[320*127+319:320*127] = INIT_7F;
+ end
+
+ // Signal inversion
+ wire clka = A_CLK_INV ^ A_CLK;
+ wire clkb = B_CLK_INV ^ B_CLK;
+ wire ena = A_EN_INV ^ A_EN;
+ wire enb = B_EN_INV ^ B_EN;
+ wire wea = A_WE_INV ^ A_WE;
+ wire web = B_WE_INV ^ B_WE;
+
+ // Internal signals
+ wire [15:0] addra;
+ wire [15:0] addrb;
+ reg [39:0] A_DO_out = 0, A_DO_reg = 0;
+ reg [39:0] B_DO_out = 0, B_DO_reg = 0;
+
+ generate
+ if (RAM_MODE == "SDP") begin
+ // Port A (write)
+ if (A_WR_WIDTH == 80) begin
+ assign addra = A_ADDR[15:7]*80;
+ end
+ // Port B (read)
+ if (B_RD_WIDTH == 80) begin
+ assign addrb = B_ADDR[15:7]*80;
+ end
+ end
+ else if (RAM_MODE == "TDP") begin
+ // Port A
+ if (WIDTH_MODE_A <= 1) begin
+ wire [15:0] tmpa = {1'b0, A_ADDR[15:1]};
+ assign addra = tmpa + (tmpa/4);
+ end
+ else if (WIDTH_MODE_A <= 2) begin
+ wire [15:0] tmpa = {2'b0, A_ADDR[15:2]};
+ assign addra = tmpa*2 + (tmpa/2);
+ end
+ else if (WIDTH_MODE_A <= 5) begin
+ assign addra = {3'b0, A_ADDR[15:3]}*5;
+ end
+ else if (WIDTH_MODE_A <= 10) begin
+ assign addra = {4'b0, A_ADDR[15:4]}*10;
+ end
+ else if (WIDTH_MODE_A <= 20) begin
+ assign addra = {5'b0, A_ADDR[15:5]}*20;
+ end
+ else if (WIDTH_MODE_A <= 40) begin
+ assign addra = {6'b0, A_ADDR[15:6]}*40;
+ end
+ // Port B
+ if (WIDTH_MODE_B <= 1) begin
+ wire [15:0] tmpb = {1'b0, B_ADDR[15:1]};
+ assign addrb = tmpb + (tmpb/4);
+ end
+ else if (WIDTH_MODE_B <= 2) begin
+ wire [15:0] tmpb = {2'b0, B_ADDR[15:2]};
+ assign addrb = tmpb*2 + (tmpb/2);
+ end
+ else if (WIDTH_MODE_B <= 5) begin
+ assign addrb = {3'b0, B_ADDR[15:3]}*5;
+ end
+ else if (WIDTH_MODE_B <= 10) begin
+ assign addrb = {4'b0, B_ADDR[15:4]}*10;
+ end
+ else if (WIDTH_MODE_B <= 20) begin
+ assign addrb = {5'b0, B_ADDR[15:5]}*20;
+ end
+ else if (WIDTH_MODE_B <= 40) begin
+ assign addrb = {6'b0, B_ADDR[15:6]}*40;
+ end
+ end
+ endgenerate
+
+ generate
+ if (RAM_MODE == "SDP") begin
+ // SDP write port
+ always @(posedge clka)
+ begin
+ for (k=0; k < A_WR_WIDTH; k=k+1) begin
+ if (k < 40) begin
+ if (ena && wea && A_BM[k]) memory[addra+k] <= A_DI[k];
+ end
+ else begin // use both ports
+ if (ena && wea && B_BM[k-40]) memory[addra+k] <= B_DI[k-40];
+ end
+ end
+ end
+ // SDP read port
+ always @(posedge clkb)
+ begin
+ // "NO_CHANGE" only
+ for (k=0; k < B_RD_WIDTH; k=k+1) begin
+ if (k < 40) begin
+ if (enb && !wea) A_DO_out[k] <= memory[addrb+k];
+ end
+ else begin // use both ports
+ if (enb && !wea) B_DO_out[k-40] <= memory[addrb+k];
+ end
+ end
+ end
+ end
+ else if (RAM_MODE == "TDP") begin
+ // {A,B}_ADDR[0]=0 selects lower, {A,B}_ADDR[0]=1 selects upper cascade memory
+ wire upper_sel_a = ((CAS == "UPPER") && (A_ADDR[0] == 1));
+ wire lower_sel_a = ((CAS == "LOWER") && (A_ADDR[0] == 0));
+ wire upper_sel_b = ((CAS == "UPPER") && (B_ADDR[0] == 1));
+ wire lower_sel_b = ((CAS == "LOWER") && (B_ADDR[0] == 0));
+
+ reg dumm;
+
+ // Cascade output port A
+ always @(*)
+ begin
+ if ((A_WR_MODE == "NO_CHANGE") && lower_sel_a) begin
+ A_CO = memory[addra];
+ end
+ else if ((A_WR_MODE == "WRITE_THROUGH") && lower_sel_a) begin
+ A_CO = ((wea && A_BM[0]) ? (A_DI[0]) : (memory[addra]));
+ end
+ end
+
+ // Cascade output port B
+ always @(*)
+ begin
+ if ((B_WR_MODE == "NO_CHANGE") && lower_sel_b) begin
+ B_CO = memory[addrb];
+ end
+ else if ((B_WR_MODE == "WRITE_THROUGH") && lower_sel_b) begin
+ B_CO = ((web && B_BM[0]) ? (B_DI[0]) : (memory[addrb]));
+ end
+ end
+
+ // TDP port A
+ always @(posedge clka)
+ begin
+ for (i=0; i < WIDTH_MODE_A; i=i+1) begin
+ if (upper_sel_a || lower_sel_a || (CAS == "NONE")) begin
+ if (ena && wea && A_BM[i])
+ memory[addra+i] <= A_DI[i];
+ end
+
+ if (A_WR_MODE == "NO_CHANGE") begin
+ if (ena && !wea) begin
+ if (CAS == "UPPER") begin
+ A_DO_out[i] <= ((A_ADDR[0] == 1) ? (memory[addra+i]) : (A_CI));
+ end
+ else if (CAS == "NONE") begin
+ A_DO_out[i] <= memory[addra+i];
+ end
+ end
+ end
+ else if (A_WR_MODE == "WRITE_THROUGH") begin
+ if (ena) begin
+ if (CAS == "UPPER") begin
+ if (A_ADDR[0] == 1) begin
+ A_DO_out[i] <= ((wea && A_BM[i]) ? (A_DI[i]) : (memory[addra+i]));
+ end else begin
+ A_DO_out[i] <= A_CI;
+ end
+ end
+ else if (CAS == "NONE") begin
+ A_DO_out[i] <= ((wea && A_BM[i]) ? (A_DI[i]) : (memory[addra+i]));
+ end
+ end
+ end
+ end
+ end
+ // TDP port B
+ always @(posedge clkb)
+ begin
+ for (i=0; i < WIDTH_MODE_B; i=i+1) begin
+ if (upper_sel_b || lower_sel_b || (CAS == "NONE")) begin
+ if (enb && web && B_BM[i])
+ memory[addrb+i] <= B_DI[i];
+ end
+
+ if (B_WR_MODE == "NO_CHANGE") begin
+ if (enb && !web) begin
+ if (CAS == "UPPER") begin
+ B_DO_out[i] <= ((B_ADDR[0] == 1) ? (memory[addrb+i]) : (B_CI));
+ end
+ else if (CAS == "NONE") begin
+ B_DO_out[i] <= memory[addrb+i];
+ end
+ end
+ end
+ else if (B_WR_MODE == "WRITE_THROUGH") begin
+ if (enb) begin
+ if (CAS == "UPPER") begin
+ if (B_ADDR[0] == 1) begin
+ B_DO_out[i] <= ((web && B_BM[i]) ? (B_DI[i]) : (memory[addrb+i]));
+ end else begin
+ B_DO_out[i] <= B_CI;
+ end
+ end
+ else if (CAS == "NONE") begin
+ B_DO_out[i] <= ((web && B_BM[i]) ? (B_DI[i]) : (memory[addrb+i]));
+ end
+ end
+ end
+ end
+ end
+ end
+ endgenerate
+
+ // Optional output register
+ generate
+ if (A_DO_REG) begin
+ always @(posedge clka) begin
+ A_DO_reg <= A_DO_out;
+ end
+ assign A_DO = A_DO_reg;
+ end
+ else begin
+ assign A_DO = A_DO_out;
+ end
+ if (B_DO_REG) begin
+ always @(posedge clkb) begin
+ B_DO_reg <= B_DO_out;
+ end
+ assign B_DO = B_DO_reg;
+ end
+ else begin
+ assign B_DO = B_DO_out;
+ end
+ endgenerate
+endmodule
diff --git a/techlibs/gatemate/lut_map.v b/techlibs/gatemate/lut_map.v new file mode 100644 index 000000000..1e5d49725 --- /dev/null +++ b/techlibs/gatemate/lut_map.v @@ -0,0 +1,45 @@ +/*
+ * yosys -- Yosys Open SYnthesis Suite
+ *
+ * Copyright (C) 2021 Cologne Chip AG <support@colognechip.com>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+
+module \$lut (A, Y);
+ parameter WIDTH = 0;
+ parameter LUT = 0;
+
+ (* force_downto *)
+ input [WIDTH-1:0] A;
+ output Y;
+
+ generate
+ if (WIDTH == 1) begin
+ CC_LUT1 #(.INIT(LUT)) _TECHMAP_REPLACE_ (.O(Y), .I0(A[0]));
+ end
+ else if (WIDTH == 2) begin
+ CC_LUT2 #(.INIT(LUT)) _TECHMAP_REPLACE_ (.O(Y), .I0(A[0]), .I1(A[1]));
+ end
+ else if (WIDTH == 3) begin
+ CC_LUT3 #(.INIT(LUT)) _TECHMAP_REPLACE_ (.O(Y), .I0(A[0]), .I1(A[1]), .I2(A[2]));
+ end
+ else if (WIDTH == 4) begin
+ CC_LUT4 #(.INIT(LUT)) _TECHMAP_REPLACE_ (.O(Y), .I0(A[0]), .I1(A[1]), .I2(A[2]), .I3(A[3]));
+ end
+ else begin
+ wire _TECHMAP_FAIL_ = 1;
+ end
+ endgenerate
+endmodule
diff --git a/techlibs/gatemate/mul_map.v b/techlibs/gatemate/mul_map.v new file mode 100644 index 000000000..c2dd0a9b4 --- /dev/null +++ b/techlibs/gatemate/mul_map.v @@ -0,0 +1,77 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2021 Cologne Chip AG <support@colognechip.com> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + */ + +(* techmap_celltype = "$mul $__mul" *) +module \$__MULMXN (A, B, Y); + + parameter A_SIGNED = 0; + parameter B_SIGNED = 0; + parameter A_WIDTH = 1; + parameter B_WIDTH = 1; + parameter Y_WIDTH = 1; + + (* force_downto *) + input [A_WIDTH-1:0] A; + (* force_downto *) + input [B_WIDTH-1:0] B; + (* force_downto *) + output [Y_WIDTH-1:0] Y; + + localparam A_ADJWIDTH = A_WIDTH + (A_SIGNED ? 0 : 1); + localparam B_ADJWIDTH = B_WIDTH + (B_SIGNED ? 0 : 1); + + generate + if (A_SIGNED) begin: blkA + wire signed [A_ADJWIDTH-1:0] Aext = $signed(A); + end + else begin: blkA + wire [A_ADJWIDTH-1:0] Aext = A; + end + if (B_SIGNED) begin: blkB + wire signed [B_ADJWIDTH-1:0] Bext = $signed(B); + end + else begin: blkB + wire [B_ADJWIDTH-1:0] Bext = B; + end + + if (A_WIDTH >= B_WIDTH) begin + CC_MULT #( + .A_WIDTH(A_ADJWIDTH), + .B_WIDTH(B_ADJWIDTH), + .P_WIDTH(Y_WIDTH), + ) _TECHMAP_REPLACE_ ( + .A(blkA.Aext), + .B(blkB.Bext), + .P(Y) + ); + end + else begin // swap A,B + CC_MULT #( + .A_WIDTH(B_ADJWIDTH), + .B_WIDTH(A_ADJWIDTH), + .P_WIDTH(Y_WIDTH), + ) _TECHMAP_REPLACE_ ( + .A(blkB.Bext), + .B(blkA.Aext), + .P(Y) + ); + end + endgenerate + +endmodule diff --git a/techlibs/gatemate/mux_map.v b/techlibs/gatemate/mux_map.v new file mode 100644 index 000000000..13c1972e3 --- /dev/null +++ b/techlibs/gatemate/mux_map.v @@ -0,0 +1,56 @@ +/*
+ * yosys -- Yosys Open SYnthesis Suite
+ *
+ * Copyright (C) 2021 Cologne Chip AG <support@colognechip.com>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+
+module \$_MUX8_ (A, B, C, D, E, F, G, H, S, T, U, Y);
+ input A, B, C, D, E, F, G, H, S, T, U;
+ output Y;
+
+ CC_MX8 _TECHMAP_REPLACE_ (
+ .D0(A), .D1(B), .D2(C), .D3(D),
+ .D4(E), .D5(F), .D6(G), .D7(H),
+ .S0(S), .S1(T), .S2(U),
+ .Y(Y)
+ );
+
+endmodule
+
+module \$_MUX4_ (A, B, C, D, S, T, Y);
+ input A, B, C, D, S, T;
+ output Y;
+
+ CC_MX4 _TECHMAP_REPLACE_ (
+ .D0(A), .D1(B), .D2(C), .D3(D),
+ .S0(S), .S1(T),
+ .Y(Y)
+ );
+
+endmodule
+
+/*
+module \$_MUX_ (A, B, S, Y);
+ input A, B, S;
+ output Y;
+
+ CC_MX2 _TECHMAP_REPLACE_ (
+ .D0(A), .D1(B), .S0(S),
+ .Y(Y)
+ );
+
+endmodule
+*/
diff --git a/techlibs/gatemate/reg_map.v b/techlibs/gatemate/reg_map.v new file mode 100644 index 000000000..6a2c7fb91 --- /dev/null +++ b/techlibs/gatemate/reg_map.v @@ -0,0 +1,45 @@ +/*
+ * yosys -- Yosys Open SYnthesis Suite
+ *
+ * Copyright (C) 2021 Cologne Chip AG <support@colognechip.com>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+
+(* techmap_celltype = "$_DFFE_[NP][NP][01][NP]_" *)
+module \$_DFFE_xxxx_ (input D, C, R, E, output Q);
+
+ parameter _TECHMAP_CELLTYPE_ = "";
+
+ CC_DFF #(
+ .CLK_INV(_TECHMAP_CELLTYPE_[39:32] == "N"),
+ .EN_INV(_TECHMAP_CELLTYPE_[15:8] == "N"),
+ .SR_INV(_TECHMAP_CELLTYPE_[31:24] == "N"),
+ .SR_VAL(_TECHMAP_CELLTYPE_[23:16] == "1")
+ ) _TECHMAP_REPLACE_ (.D(D), .EN(E), .CLK(C), .SR(R), .Q(Q));
+
+endmodule
+
+(* techmap_celltype = "$_DLATCH_[NP][NP][01]_" *)
+module \$_DLATCH_xxx_ (input E, R, D, output Q);
+
+ parameter _TECHMAP_CELLTYPE_ = "";
+
+ CC_DLT #(
+ .G_INV(_TECHMAP_CELLTYPE_[31:24] == "N"),
+ .SR_INV(_TECHMAP_CELLTYPE_[23:16] == "N"),
+ .SR_VAL(_TECHMAP_CELLTYPE_[15:8] == "1")
+ ) _TECHMAP_REPLACE_ (.D(D), .G(E), .SR(R), .Q(Q));
+
+endmodule
diff --git a/techlibs/gatemate/synth_gatemate.cc b/techlibs/gatemate/synth_gatemate.cc new file mode 100644 index 000000000..93b16b2e0 --- /dev/null +++ b/techlibs/gatemate/synth_gatemate.cc @@ -0,0 +1,346 @@ +/*
+ * yosys -- Yosys Open SYnthesis Suite
+ *
+ * Copyright (C) 2021 Cologne Chip AG <support@colognechip.com>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+
+#include "kernel/register.h"
+#include "kernel/celltypes.h"
+#include "kernel/rtlil.h"
+#include "kernel/log.h"
+
+USING_YOSYS_NAMESPACE
+PRIVATE_NAMESPACE_BEGIN
+
+struct SynthGateMatePass : public ScriptPass
+{
+ SynthGateMatePass() : ScriptPass("synth_gatemate", "synthesis for Cologne Chip GateMate FPGAs") { }
+
+ void help() override
+ {
+ // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
+ log("\n");
+ log(" synth_gatemate [options]\n");
+ log("\n");
+ log("This command runs synthesis for Cologne Chip AG GateMate FPGAs.\n");
+ log("\n");
+ log(" -top <module>\n");
+ log(" use the specified module as top module.\n");
+ log("\n");
+ log(" -vlog <file>\n");
+ log(" write the design to the specified verilog file. Writing of an output\n");
+ log(" file is omitted if this parameter is not specified.\n");
+ log("\n");
+ log(" -json <file>\n");
+ log(" write the design to the specified JSON file. Writing of an output file\n");
+ log(" is omitted if this parameter is not specified.\n");
+ log("\n");
+ log(" -run <from_label>:<to_label>\n");
+ log(" only run the commands between the labels (see below). An empty\n");
+ log(" from label is synonymous to 'begin', and empty to label is\n");
+ log(" synonymous to the end of the command list.\n");
+ log("\n");
+ log(" -noflatten\n");
+ log(" do not flatten design before synthesis.\n");
+ log("\n");
+ log(" -nobram\n");
+ log(" do not use CC_BRAM_20K or CC_BRAM_40K cells in output netlist.\n");
+ log("\n");
+ log(" -noaddf\n");
+ log(" do not use CC_ADDF full adder cells in output netlist.\n");
+ log("\n");
+ log(" -nomult\n");
+ log(" do not use CC_MULT multiplier cells in output netlist.\n");
+ log("\n");
+ log(" -nomx8, -nomx4\n");
+ log(" do not use CC_MX{8,4} multiplexer cells in output netlist.\n");
+ log("\n");;
+ log(" -dff\n");
+ log(" run 'abc' with -dff option\n");
+ log("\n");
+ log(" -retime\n");
+ log(" run 'abc' with '-dff -D 1' options\n");
+ log("\n");
+ log(" -noiopad\n");
+ log(" disable I/O buffer insertion (useful for hierarchical or \n");
+ log(" out-of-context flows).\n");
+ log("\n");
+ log(" -noclkbuf\n");
+ log(" disable automatic clock buffer insertion.\n");
+ log("\n");
+ log("The following commands are executed by this synthesis command:\n");
+ help_script();
+ log("\n");
+ }
+
+ string top_opt, vlog_file, json_file;
+ bool noflatten, nobram, noaddf, nomult, nomx4, nomx8, dff, retime, noiopad, noclkbuf;
+
+ void clear_flags() override
+ {
+ top_opt = "-auto-top";
+ vlog_file = "";
+ json_file = "";
+ noflatten = false;
+ nobram = false;
+ noaddf = false;
+ nomult = false;
+ nomx4 = false;
+ nomx8 = false;
+ dff = false;
+ retime = false;
+ noiopad = false;
+ noclkbuf = false;
+ }
+
+ void execute(std::vector<std::string> args, RTLIL::Design *design) override
+ {
+ string run_from, run_to;
+ clear_flags();
+
+ size_t argidx;
+ for (argidx = 1; argidx < args.size(); argidx++)
+ {
+ if (args[argidx] == "-top" && argidx+1 < args.size()) {
+ top_opt = "-top " + args[++argidx];
+ continue;
+ }
+ if (args[argidx] == "-vlog" && argidx+1 < args.size()) {
+ vlog_file = args[++argidx];
+ continue;
+ }
+ if (args[argidx] == "-json" && argidx+1 < args.size()) {
+ json_file = args[++argidx];
+ continue;
+ }
+ if (args[argidx] == "-run" && argidx+1 < args.size()) {
+ size_t pos = args[argidx+1].find(':');
+ if (pos == std::string::npos)
+ break;
+ run_from = args[++argidx].substr(0, pos);
+ run_to = args[argidx].substr(pos+1);
+ continue;
+ }
+ if (args[argidx] == "-noflatten") {
+ noflatten = true;
+ continue;
+ }
+ if (args[argidx] == "-nobram") {
+ nobram = true;
+ continue;
+ }
+ if (args[argidx] == "-noaddf") {
+ noaddf = true;
+ continue;
+ }
+ if (args[argidx] == "-nomult") {
+ nomult = true;
+ continue;
+ }
+ if (args[argidx] == "-nomx4") {
+ nomx4 = true;
+ continue;
+ }
+ if (args[argidx] == "-nomx8") {
+ nomx8 = true;
+ continue;
+ }
+ if (args[argidx] == "-dff") {
+ dff = true;
+ continue;
+ }
+ if (args[argidx] == "-retime") {
+ retime = true;
+ continue;
+ }
+ if (args[argidx] == "-noiopad") {
+ noiopad = true;
+ continue;
+ }
+ if (args[argidx] == "-noclkbuf") {
+ noclkbuf = true;
+ continue;
+ }
+ break;
+ }
+ extra_args(args, argidx, design);
+
+ if (!design->full_selection()) {
+ log_cmd_error("This command only operates on fully selected designs!\n");
+ }
+
+ log_header(design, "Executing SYNTH_GATEMATE pass.\n");
+ log_push();
+
+ run_script(design, run_from, run_to);
+
+ log_pop();
+ }
+
+ void script() override
+ {
+ if (check_label("begin"))
+ {
+ run("read_verilog -lib -specify +/gatemate/cells_sim.v +/gatemate/cells_bb.v");
+ run(stringf("hierarchy -check %s", help_mode ? "-top <top>" : top_opt.c_str()));
+ }
+
+ if (check_label("prepare"))
+ {
+ run("proc");
+ if (!noflatten) {
+ run("flatten");
+ }
+ run("tribuf -logic");
+ run("deminout");
+ run("opt_expr");
+ run("opt_clean");
+ run("check");
+ run("opt -nodffe -nosdff");
+ run("fsm");
+ run("opt");
+ run("wreduce");
+ run("peepopt");
+ run("opt_clean");
+ run("muxpack");
+ run("share");
+ run("techmap -map +/cmp2lut.v -D LUT_WIDTH=4");
+ run("opt_expr");
+ run("opt_clean");
+ }
+
+ if (check_label("map_mult", "(skip if '-nomult')") && !nomult)
+ {
+ run("techmap -map +/gatemate/mul_map.v");
+ }
+
+ if (check_label("coarse"))
+ {
+ run("alumacc");
+ run("opt");
+ run("memory -nomap");
+ run("opt_clean");
+ }
+
+ if (check_label("map_bram", "(skip if '-nobram')") && !nobram)
+ {
+ run("memory_libmap -lib +/gatemate/brams.txt");
+ run("techmap -map +/gatemate/brams_map.v");
+ }
+
+ if (check_label("map_ffram"))
+ {
+ run("opt -fast -mux_undef -undriven -fine");
+ run("memory_map");
+ run("opt -undriven -fine");
+ }
+
+ if (check_label("map_gates"))
+ {
+ std::string techmap_args = "";
+ if (!noaddf) {
+ techmap_args += " -map +/gatemate/arith_map.v";
+ }
+ run("techmap -map +/techmap.v " + techmap_args);
+ run("opt -fast");
+ if (retime) {
+ run("abc -dff -D 1", "(only if -retime)");
+ }
+ }
+
+ if (check_label("map_io", "(skip if '-noiopad')") && !noiopad)
+ {
+ run("iopadmap -bits "
+ "-inpad CC_IBUF Y:I "
+ "-outpad CC_OBUF A:O "
+ "-toutpad CC_TOBUF ~T:A:O "
+ "-tinoutpad CC_IOBUF ~T:Y:A:IO"
+ );
+ run("clean");
+ }
+
+ if (check_label("map_regs"))
+ {
+ run("opt_clean");
+ run("dfflegalize -cell $_DFFE_????_ x -cell $_DLATCH_???_ x");
+ run("techmap -map +/gatemate/reg_map.v");
+ run("opt_expr -mux_undef");
+ run("simplemap");
+ run("opt_clean");
+ }
+
+ if (check_label("map_muxs"))
+ {
+ std::string muxcover_args;
+ if (!nomx4) {
+ muxcover_args += stringf(" -mux4");
+ }
+ if (!nomx8) {
+ muxcover_args += stringf(" -mux8");
+ }
+ run("muxcover " + muxcover_args);
+ run("opt -full");
+ run("techmap -map +/gatemate/mux_map.v");
+ }
+
+ if (check_label("map_luts"))
+ {
+ std::string abc_args = " -dress -lut 4";
+ if (dff) {
+ abc_args += " -dff";
+ }
+ run("abc " + abc_args);
+ run("clean");
+ }
+
+ if (check_label("map_cells"))
+ {
+ run("techmap -map +/gatemate/lut_map.v");
+ run("clean");
+ }
+
+ if (check_label("map_bufg", "(skip if '-noclkbuf')") && !noclkbuf)
+ {
+ run("clkbufmap -buf CC_BUFG O:I");
+ run("clean");
+ }
+
+ if (check_label("check"))
+ {
+ run("hierarchy -check");
+ run("stat -width");
+ run("check -noinit");
+ run("blackbox =A:whitebox");
+ }
+
+ if (check_label("vlog"))
+ {
+ run("opt_clean -purge");
+ if (!vlog_file.empty() || help_mode) {
+ run(stringf("write_verilog -noattr %s", help_mode ? "<file-name>" : vlog_file.c_str()));
+ }
+ }
+
+ if (check_label("json"))
+ {
+ if (!json_file.empty() || help_mode) {
+ run(stringf("write_json %s", help_mode ? "<file-name>" : json_file.c_str()));
+ }
+ }
+ }
+} SynthGateMatePass;
+
+PRIVATE_NAMESPACE_END
diff --git a/techlibs/gowin/.gitignore b/techlibs/gowin/.gitignore deleted file mode 100644 index d6c48e90d..000000000 --- a/techlibs/gowin/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -brams_init.mk -bram_init_*.vh diff --git a/techlibs/gowin/Makefile.inc b/techlibs/gowin/Makefile.inc index e6a6be970..4f3a33f36 100644 --- a/techlibs/gowin/Makefile.inc +++ b/techlibs/gowin/Makefile.inc @@ -1,8 +1,6 @@ OBJS += techlibs/gowin/synth_gowin.o -GENFILES += techlibs/gowin/bram_init_16.vh - $(eval $(call add_share_file,share/gowin,techlibs/gowin/cells_map.v)) $(eval $(call add_share_file,share/gowin,techlibs/gowin/cells_sim.v)) $(eval $(call add_share_file,share/gowin,techlibs/gowin/arith_map.v)) @@ -10,16 +8,3 @@ $(eval $(call add_share_file,share/gowin,techlibs/gowin/brams_map.v)) $(eval $(call add_share_file,share/gowin,techlibs/gowin/brams.txt)) $(eval $(call add_share_file,share/gowin,techlibs/gowin/lutrams_map.v)) $(eval $(call add_share_file,share/gowin,techlibs/gowin/lutrams.txt)) - -$(eval $(call add_share_file,share/gowin,techlibs/gowin/brams_init3.vh)) - -EXTRA_OBJS += techlibs/gowin/brams_init.mk -.SECONDARY: techlibs/gowin/brams_init.mk - -techlibs/gowin/brams_init.mk: techlibs/gowin/brams_init.py - $(Q) mkdir -p techlibs/gowin - $(P) python3 $< - $(Q) touch $@ - -techlibs/gowin/bram_init_16.vh: techlibs/gowin/brams_init.mk -$(eval $(call add_gen_share_file,share/gowin,techlibs/gowin/bram_init_16.vh)) diff --git a/techlibs/gowin/brams.txt b/techlibs/gowin/brams.txt index e406f9c51..0c0d8fa3e 100644 --- a/techlibs/gowin/brams.txt +++ b/techlibs/gowin/brams.txt @@ -1,31 +1,81 @@ -bram $__GW1NR_SDP - init 1 - abits 9 @a9d36 - dbits 32 @a9d36 - abits 10 @a10d18 - dbits 16 @a10d18 - abits 11 @a11d9 - dbits 8 @a11d9 - abits 12 @a12d4 - dbits 4 @a12d4 - abits 13 @a13d2 - dbits 2 @a13d2 - abits 14 @a14d1 - dbits 1 @a14d1 - groups 2 - ports 1 1 - wrmode 1 0 - enable 4 1 @a9d36 - enable 2 1 @a10d18 - enable 1 1 @a11d9 @a12d4 @a13d2 @a14d1 - transp 0 0 - clocks 2 3 - clkpol 2 3 -endbram +ram block $__GOWIN_SP_ { + abits 14; + widths 1 2 4 9 18 36 per_port; + byte 9; + cost 128; + init no_undef; + port srsw "A" { + clock posedge; + clken; + wrbe_separate; + option "RESET_MODE" "SYNC" { + rdsrst zero ungated; + } + option "RESET_MODE" "ASYNC" { + rdarst zero; + } + rdinit zero; + portoption "WRITE_MODE" 0 { + rdwr no_change; + } + portoption "WRITE_MODE" 1 { + rdwr new; + } + portoption "WRITE_MODE" 2 { + rdwr old; + } + } +} -match $__GW1NR_SDP - min bits 2048 - min efficiency 5 - shuffle_enable A - make_transp -endmatch +ram block $__GOWIN_DP_ { + abits 14; + widths 1 2 4 9 18 per_port; + byte 9; + cost 128; + init no_undef; + port srsw "A" "B" { + clock posedge; + clken; + wrbe_separate; + option "RESET_MODE" "SYNC" { + rdsrst zero ungated; + } + option "RESET_MODE" "ASYNC" { + rdarst zero; + } + rdinit zero; + portoption "WRITE_MODE" 0 { + rdwr no_change; + } + portoption "WRITE_MODE" 1 { + rdwr new; + } + portoption "WRITE_MODE" 2 { + rdwr old; + } + } +} + +ram block $__GOWIN_SDP_ { + abits 14; + widths 1 2 4 9 18 36 per_port; + byte 9; + cost 128; + init no_undef; + port sr "R" { + clock posedge; + clken; + option "RESET_MODE" "SYNC" { + rdsrst zero ungated; + } + option "RESET_MODE" "ASYNC" { + rdarst zero; + } + rdinit zero; + } + port sw "W" { + clock posedge; + clken; + wrbe_separate; + } +} diff --git a/techlibs/gowin/brams_init.py b/techlibs/gowin/brams_init.py deleted file mode 100755 index b78eb8da5..000000000 --- a/techlibs/gowin/brams_init.py +++ /dev/null @@ -1,8 +0,0 @@ -#!/usr/bin/env python3 - -with open("techlibs/gowin/bram_init_16.vh", "w") as f: - for i in range(0, 0x40): - low = i << 8 - hi = ((i+1) << 8)-1 - snippet = "INIT[%d:%d]" % (hi, low) - print(".INIT_RAM_%02X({%s})," % (i, snippet), file=f) diff --git a/techlibs/gowin/brams_init3.vh b/techlibs/gowin/brams_init3.vh deleted file mode 100644 index 84397fa24..000000000 --- a/techlibs/gowin/brams_init3.vh +++ /dev/null @@ -1,12 +0,0 @@ -localparam [15:0] INIT_0 = { - INIT[ 60], INIT[ 56], INIT[ 52], INIT[ 48], INIT[ 44], INIT[ 40], INIT[ 36], INIT[ 32], INIT[ 28], INIT[ 24], INIT[ 20], INIT[ 16], INIT[ 12], INIT[ 8], INIT[ 4], INIT[ 0] -}; -localparam [15:0] INIT_1 = { - INIT[ 61], INIT[ 57], INIT[ 53], INIT[ 49], INIT[ 45], INIT[ 41], INIT[ 37], INIT[ 33], INIT[ 29], INIT[ 25], INIT[ 21], INIT[ 17], INIT[ 13], INIT[ 9], INIT[ 5], INIT[ 1] -}; -localparam [15:0] INIT_2 = { - INIT[ 62], INIT[ 58], INIT[ 54], INIT[ 50], INIT[ 46], INIT[ 42], INIT[ 38], INIT[ 34], INIT[ 30], INIT[ 26], INIT[ 22], INIT[ 18], INIT[ 14], INIT[ 10], INIT[ 6], INIT[ 2] -}; -localparam [15:0] INIT_3 = { - INIT[ 63], INIT[ 59], INIT[ 55], INIT[ 51], INIT[ 47], INIT[ 43], INIT[ 39], INIT[ 35], INIT[ 31], INIT[ 27], INIT[ 23], INIT[ 19], INIT[ 15], INIT[ 11], INIT[ 7], INIT[ 3] -}; diff --git a/techlibs/gowin/brams_map.v b/techlibs/gowin/brams_map.v index fbebc4af8..7ffc91bac 100644 --- a/techlibs/gowin/brams_map.v +++ b/techlibs/gowin/brams_map.v @@ -1,142 +1,410 @@ -/* Semi Dual Port (SDP) memory have the following configurations: - * Memory Config RAM(BIT) Port Mode Memory Depth Data Depth - * ----------------|---------| ----------|--------------|------------| - * B-SRAM_16K_SD1 16K 16Kx1 16,384 1 - * B-SRAM_8K_SD2 16K 8Kx2 8,192 2 - * B-SRAM_4K_SD4 16K 4Kx2 4,096 4 - */ -module \$__GW1NR_SDP (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN); - parameter CFG_ABITS = 10; - parameter CFG_DBITS = 16; - parameter CFG_ENABLE_A = 1; - parameter [16383:0] INIT = 16384'hx; - parameter CLKPOL2 = 1; - parameter CLKPOL3 = 1; - - input CLK2; - input CLK3; - - input [CFG_ABITS-1:0] A1ADDR; - input [CFG_DBITS-1:0] A1DATA; - input [CFG_ENABLE_A-1:0] A1EN; - - input [CFG_ABITS-1:0] B1ADDR; - output [CFG_DBITS-1:0] B1DATA; - input B1EN; - - wire [31-CFG_DBITS:0] open; - - - generate if (CFG_DBITS == 1) begin - SDP #( - `include "bram_init_16.vh" - .READ_MODE(0), - .BIT_WIDTH_0(1), - .BIT_WIDTH_1(1), - .BLK_SEL(3'b000), - .RESET_MODE("SYNC") - ) _TECHMAP_REPLACE_ ( - .CLKA(CLK2), .CLKB(CLK3), - .WREA(A1EN), .OCE(1'b0), .CEA(1'b1), - .WREB(1'b0), .CEB(B1EN), - .RESETA(1'b0), .RESETB(1'b0), .BLKSEL(3'b000), - .DI({{(32-CFG_DBITS){1'b0}}, A1DATA}), - .DO({open, B1DATA}), - .ADA({A1ADDR, {(14-CFG_ABITS){1'b0}}}), - .ADB({B1ADDR, {(14-CFG_ABITS){1'b0}}}) - ); - end else if (CFG_DBITS == 2) begin - SDP #( - `include "bram_init_16.vh" - .READ_MODE(0), - .BIT_WIDTH_0(2), - .BIT_WIDTH_1(2), - .BLK_SEL(3'b000), - .RESET_MODE("SYNC") - ) _TECHMAP_REPLACE_ ( - .CLKA(CLK2), .CLKB(CLK3), - .WREA(A1EN), .OCE(1'b0), .CEA(1'b1), - .WREB(1'b0), .CEB(B1EN), - .RESETA(1'b0), .RESETB(1'b0), .BLKSEL(3'b000), - .DI({{(32-CFG_DBITS){1'b0}}, A1DATA}), - .DO({open, B1DATA}), - .ADA({A1ADDR, {(14-CFG_ABITS){1'b0}}}), - .ADB({B1ADDR, {(14-CFG_ABITS){1'b0}}}) - ); - end else if (CFG_DBITS <= 4) begin - SDP #( - `include "bram_init_16.vh" - .READ_MODE(0), - .BIT_WIDTH_0(4), - .BIT_WIDTH_1(4), - .BLK_SEL(3'b000), - .RESET_MODE("SYNC") - ) _TECHMAP_REPLACE_ ( - .CLKA(CLK2), .CLKB(CLK3), - .WREA(A1EN), .OCE(1'b0), - .WREB(1'b0), .CEB(B1EN), .CEA(1'b1), - .RESETA(1'b0), .RESETB(1'b0), .BLKSEL(3'b000), - .DI({{(32-CFG_DBITS){1'b0}}, A1DATA}), - .DO({open, B1DATA}), - .ADA({A1ADDR, {(14-CFG_ABITS){1'b0}}}), - .ADB({B1ADDR, {(14-CFG_ABITS){1'b0}}}) - ); - end else if (CFG_DBITS <= 8) begin - SDP #( - `include "bram_init_16.vh" - .READ_MODE(0), - .BIT_WIDTH_0(8), - .BIT_WIDTH_1(8), - .BLK_SEL(3'b000), - .RESET_MODE("SYNC") - ) _TECHMAP_REPLACE_ ( - .CLKA(CLK2), .CLKB(CLK3), - .WREA(A1EN), .OCE(1'b0), .CEA(1'b1), - .WREB(1'b0), .CEB(B1EN), - .RESETA(1'b0), .RESETB(1'b0), .BLKSEL(3'b000), - .DI({{(32-CFG_DBITS){1'b0}}, A1DATA}), - .DO({open, B1DATA}), - .ADA({A1ADDR, {(14-CFG_ABITS){1'b0}}}), - .ADB({B1ADDR, {(14-CFG_ABITS){1'b0}}}) - ); - end else if (CFG_DBITS <= 16) begin - SDP #( - `include "bram_init_16.vh" - .READ_MODE(0), - .BIT_WIDTH_0(16), - .BIT_WIDTH_1(16), - .BLK_SEL(3'b000), - .RESET_MODE("SYNC") - ) _TECHMAP_REPLACE_ ( - .CLKA(CLK2), .CLKB(CLK3), - .WREA(|A1EN), .OCE(1'b0), - .WREB(1'b0), .CEB(B1EN), .CEA(1'b1), - .RESETA(1'b0), .RESETB(1'b0), .BLKSEL(3'b000), - .DI({{(32-CFG_DBITS){1'b0}}, A1DATA}), - .DO({open, B1DATA}), - .ADA({A1ADDR, {(12-CFG_ABITS){1'b0}}, A1EN}), - .ADB({B1ADDR, {(14-CFG_ABITS){1'b0}}}) - ); - end else if (CFG_DBITS <= 32) begin - SDP #( - `include "bram_init_16.vh" - .READ_MODE(0), - .BIT_WIDTH_0(32), - .BIT_WIDTH_1(32), - .BLK_SEL(3'b000), - .RESET_MODE("SYNC") - ) _TECHMAP_REPLACE_ ( - .CLKA(CLK2), .CLKB(CLK3), - .WREA(|A1EN), .OCE(1'b0), - .WREB(1'b0), .CEB(B1EN), .CEA(1'b1), - .RESETA(1'b0), .RESETB(1'b0), .BLKSEL(3'b000), - .DI(A1DATA), - .DO(B1DATA), - .ADA({A1ADDR, {(10-CFG_ABITS){1'b0}}, A1EN}), - .ADB({B1ADDR, {(14-CFG_ABITS){1'b0}}}) - ); - end else begin - wire TECHMAP_FAIL = 1'b1; - end endgenerate - +`define DEF_FUNCS \ + function [255:0] init_slice_x8; \ + input integer idx; \ + integer i; \ + for (i = 0; i < 32; i = i + 1) begin \ + init_slice_x8[i*8+:8] = INIT[(idx * 32 + i) * 9+:8]; \ + end \ + endfunction \ + function [287:0] init_slice_x9; \ + input integer idx; \ + init_slice_x9 = INIT[idx * 288+:288]; \ + endfunction \ + +`define x8_width(width) (width / 9 * 8 + width % 9) +`define x8_rd_data(data) {1'bx, data[31:24], 1'bx, data[23:16], 1'bx, data[15:8], 1'bx, data[7:0]} +`define x8_wr_data(data) {data[34:27], data[25:18], data[16:9], data[7:0]} +`define wre(width, wr_en, wr_be) (width < 18 ? wr_en | wr_be[0] : wr_en) +`define addrbe(width, addr, wr_be) (width < 18 ? addr : {addr[13:4], wr_be}) + + +`define INIT(func) \ + .INIT_RAM_00(func('h00)), \ + .INIT_RAM_01(func('h01)), \ + .INIT_RAM_02(func('h02)), \ + .INIT_RAM_03(func('h03)), \ + .INIT_RAM_04(func('h04)), \ + .INIT_RAM_05(func('h05)), \ + .INIT_RAM_06(func('h06)), \ + .INIT_RAM_07(func('h07)), \ + .INIT_RAM_08(func('h08)), \ + .INIT_RAM_09(func('h09)), \ + .INIT_RAM_0A(func('h0a)), \ + .INIT_RAM_0B(func('h0b)), \ + .INIT_RAM_0C(func('h0c)), \ + .INIT_RAM_0D(func('h0d)), \ + .INIT_RAM_0E(func('h0e)), \ + .INIT_RAM_0F(func('h0f)), \ + .INIT_RAM_10(func('h10)), \ + .INIT_RAM_11(func('h11)), \ + .INIT_RAM_12(func('h12)), \ + .INIT_RAM_13(func('h13)), \ + .INIT_RAM_14(func('h14)), \ + .INIT_RAM_15(func('h15)), \ + .INIT_RAM_16(func('h16)), \ + .INIT_RAM_17(func('h17)), \ + .INIT_RAM_18(func('h18)), \ + .INIT_RAM_19(func('h19)), \ + .INIT_RAM_1A(func('h1a)), \ + .INIT_RAM_1B(func('h1b)), \ + .INIT_RAM_1C(func('h1c)), \ + .INIT_RAM_1D(func('h1d)), \ + .INIT_RAM_1E(func('h1e)), \ + .INIT_RAM_1F(func('h1f)), \ + .INIT_RAM_20(func('h20)), \ + .INIT_RAM_21(func('h21)), \ + .INIT_RAM_22(func('h22)), \ + .INIT_RAM_23(func('h23)), \ + .INIT_RAM_24(func('h24)), \ + .INIT_RAM_25(func('h25)), \ + .INIT_RAM_26(func('h26)), \ + .INIT_RAM_27(func('h27)), \ + .INIT_RAM_28(func('h28)), \ + .INIT_RAM_29(func('h29)), \ + .INIT_RAM_2A(func('h2a)), \ + .INIT_RAM_2B(func('h2b)), \ + .INIT_RAM_2C(func('h2c)), \ + .INIT_RAM_2D(func('h2d)), \ + .INIT_RAM_2E(func('h2e)), \ + .INIT_RAM_2F(func('h2f)), \ + .INIT_RAM_30(func('h30)), \ + .INIT_RAM_31(func('h31)), \ + .INIT_RAM_32(func('h32)), \ + .INIT_RAM_33(func('h33)), \ + .INIT_RAM_34(func('h34)), \ + .INIT_RAM_35(func('h35)), \ + .INIT_RAM_36(func('h36)), \ + .INIT_RAM_37(func('h37)), \ + .INIT_RAM_38(func('h38)), \ + .INIT_RAM_39(func('h39)), \ + .INIT_RAM_3A(func('h3a)), \ + .INIT_RAM_3B(func('h3b)), \ + .INIT_RAM_3C(func('h3c)), \ + .INIT_RAM_3D(func('h3d)), \ + .INIT_RAM_3E(func('h3e)), \ + .INIT_RAM_3F(func('h3f)), + +module $__GOWIN_SP_ (...); + +parameter INIT = 0; +parameter OPTION_RESET_MODE = "SYNC"; + +parameter PORT_A_WIDTH = 36; +parameter PORT_A_WR_BE_WIDTH = 4; +parameter PORT_A_OPTION_WRITE_MODE = 0; + +input PORT_A_CLK; +input PORT_A_CLK_EN; +input PORT_A_WR_EN; +input PORT_A_RD_SRST; +input PORT_A_RD_ARST; +input [13:0] PORT_A_ADDR; +input [PORT_A_WR_BE_WIDTH-1:0] PORT_A_WR_BE; +input [PORT_A_WIDTH-1:0] PORT_A_WR_DATA; +output [PORT_A_WIDTH-1:0] PORT_A_RD_DATA; + +`DEF_FUNCS + +wire RST = OPTION_RESET_MODE == "SYNC" ? PORT_A_RD_SRST : PORT_A_RD_ARST; +wire WRE = `wre(PORT_A_WIDTH, PORT_A_WR_EN, PORT_A_WR_BE); +wire [13:0] AD = `addrbe(PORT_A_WIDTH, PORT_A_ADDR, PORT_A_WR_BE); + +generate + +if (PORT_A_WIDTH < 9) begin + + wire [31:0] DI = `x8_wr_data(PORT_A_WR_DATA); + wire [31:0] DO; + + assign PORT_A_RD_DATA = `x8_rd_data(DO); + + SP #( + `INIT(init_slice_x8) + .READ_MODE(1'b0), + .WRITE_MODE(PORT_A_OPTION_WRITE_MODE), + .BIT_WIDTH(`x8_width(PORT_A_WIDTH)), + .BLK_SEL(3'b000), + .RESET_MODE(OPTION_RESET_MODE), + ) _TECHMAP_REPLACE_ ( + .BLKSEL(3'b000), + .CLK(PORT_A_CLK), + .CE(PORT_A_CLK_EN), + .WRE(WRE), + .RESET(RST), + .OCE(1'b0), + .AD(AD), + .DI(DI), + .DO(DO), + ); + +end else begin + + wire [35:0] DI = PORT_A_WR_DATA; + wire [35:0] DO; + + assign PORT_A_RD_DATA = DO; + + SPX9 #( + `INIT(init_slice_x9) + .READ_MODE(1'b0), + .WRITE_MODE(PORT_A_OPTION_WRITE_MODE), + .BIT_WIDTH(PORT_A_WIDTH), + .BLK_SEL(3'b000), + .RESET_MODE(OPTION_RESET_MODE), + ) _TECHMAP_REPLACE_ ( + .BLKSEL(3'b000), + .CLK(PORT_A_CLK), + .CE(PORT_A_CLK_EN), + .WRE(WRE), + .RESET(RST), + .OCE(1'b0), + .AD(AD), + .DI(DI), + .DO(DO), + ); + +end + +endgenerate + +endmodule + + +module $__GOWIN_DP_ (...); + +parameter INIT = 0; +parameter OPTION_RESET_MODE = "SYNC"; + +parameter PORT_A_WIDTH = 18; +parameter PORT_A_WR_BE_WIDTH = 2; +parameter PORT_A_OPTION_WRITE_MODE = 0; + +parameter PORT_B_WIDTH = 18; +parameter PORT_B_WR_BE_WIDTH = 2; +parameter PORT_B_OPTION_WRITE_MODE = 0; + +input PORT_A_CLK; +input PORT_A_CLK_EN; +input PORT_A_WR_EN; +input PORT_A_RD_SRST; +input PORT_A_RD_ARST; +input [13:0] PORT_A_ADDR; +input [PORT_A_WR_BE_WIDTH-1:0] PORT_A_WR_BE; +input [PORT_A_WIDTH-1:0] PORT_A_WR_DATA; +output [PORT_A_WIDTH-1:0] PORT_A_RD_DATA; + +input PORT_B_CLK; +input PORT_B_CLK_EN; +input PORT_B_WR_EN; +input PORT_B_RD_SRST; +input PORT_B_RD_ARST; +input [13:0] PORT_B_ADDR; +input [PORT_A_WR_BE_WIDTH-1:0] PORT_B_WR_BE; +input [PORT_A_WIDTH-1:0] PORT_B_WR_DATA; +output [PORT_A_WIDTH-1:0] PORT_B_RD_DATA; + +`DEF_FUNCS + +wire RSTA = OPTION_RESET_MODE == "SYNC" ? PORT_A_RD_SRST : PORT_A_RD_ARST; +wire RSTB = OPTION_RESET_MODE == "SYNC" ? PORT_B_RD_SRST : PORT_B_RD_ARST; +wire WREA = `wre(PORT_A_WIDTH, PORT_A_WR_EN, PORT_A_WR_BE); +wire WREB = `wre(PORT_B_WIDTH, PORT_B_WR_EN, PORT_B_WR_BE); +wire [13:0] ADA = `addrbe(PORT_A_WIDTH, PORT_A_ADDR, PORT_A_WR_BE); +wire [13:0] ADB = `addrbe(PORT_B_WIDTH, PORT_B_ADDR, PORT_B_WR_BE); + +generate + +if (PORT_A_WIDTH < 9 || PORT_B_WIDTH < 9) begin + + wire [15:0] DIA = `x8_wr_data(PORT_A_WR_DATA); + wire [15:0] DIB = `x8_wr_data(PORT_B_WR_DATA); + wire [15:0] DOA; + wire [15:0] DOB; + + assign PORT_A_RD_DATA = `x8_rd_data(DOA); + assign PORT_B_RD_DATA = `x8_rd_data(DOB); + + DP #( + `INIT(init_slice_x8) + .READ_MODE0(1'b0), + .READ_MODE1(1'b0), + .WRITE_MODE0(PORT_A_OPTION_WRITE_MODE), + .WRITE_MODE1(PORT_B_OPTION_WRITE_MODE), + .BIT_WIDTH_0(`x8_width(PORT_A_WIDTH)), + .BIT_WIDTH_1(`x8_width(PORT_B_WIDTH)), + .BLK_SEL(3'b000), + .RESET_MODE(OPTION_RESET_MODE), + ) _TECHMAP_REPLACE_ ( + .BLKSEL(3'b000), + + .CLKA(PORT_A_CLK), + .CEA(PORT_A_CLK_EN), + .WREA(WREA), + .RESETA(RSTA), + .OCEA(1'b0), + .ADA(ADA), + .DIA(DIA), + .DOA(DOA), + + .CLKB(PORT_B_CLK), + .CEB(PORT_B_CLK_EN), + .WREB(WREB), + .RESETB(RSTB), + .OCEB(1'b0), + .ADB(ADB), + .DIB(DIB), + .DOB(DOB), + ); + +end else begin + + wire [17:0] DIA = PORT_A_WR_DATA; + wire [17:0] DIB = PORT_B_WR_DATA; + wire [17:0] DOA; + wire [17:0] DOB; + + assign PORT_A_RD_DATA = DOA; + assign PORT_B_RD_DATA = DOB; + + DPX9 #( + `INIT(init_slice_x9) + .READ_MODE0(1'b0), + .READ_MODE1(1'b0), + .WRITE_MODE0(PORT_A_OPTION_WRITE_MODE), + .WRITE_MODE1(PORT_B_OPTION_WRITE_MODE), + .BIT_WIDTH_0(PORT_A_WIDTH), + .BIT_WIDTH_1(PORT_B_WIDTH), + .BLK_SEL(3'b000), + .RESET_MODE(OPTION_RESET_MODE), + ) _TECHMAP_REPLACE_ ( + .BLKSEL(3'b000), + + .CLKA(PORT_A_CLK), + .CEA(PORT_A_CLK_EN), + .WREA(WREA), + .RESETA(RSTA), + .OCEA(1'b0), + .ADA(ADA), + .DIA(DIA), + .DOA(DOA), + + .CLKB(PORT_B_CLK), + .CEB(PORT_B_CLK_EN), + .WREB(WREB), + .RESETB(RSTB), + .OCEB(1'b0), + .ADB(ADB), + .DIB(DIB), + .DOB(DOB), + ); + +end + +endgenerate + +endmodule + + +module $__GOWIN_SDP_ (...); + +parameter INIT = 0; +parameter OPTION_RESET_MODE = "SYNC"; + +parameter PORT_R_WIDTH = 18; + +parameter PORT_W_WIDTH = 18; +parameter PORT_W_WR_BE_WIDTH = 2; + +input PORT_R_CLK; +input PORT_R_CLK_EN; +input PORT_R_RD_SRST; +input PORT_R_RD_ARST; +input [13:0] PORT_R_ADDR; +output [PORT_R_WIDTH-1:0] PORT_R_RD_DATA; + +input PORT_W_CLK; +input PORT_W_CLK_EN; +input PORT_W_WR_EN; +input [13:0] PORT_W_ADDR; +input [PORT_W_WR_BE_WIDTH-1:0] PORT_W_WR_BE; +input [PORT_W_WIDTH-1:0] PORT_W_WR_DATA; + +`DEF_FUNCS + +wire RST = OPTION_RESET_MODE == "SYNC" ? PORT_R_RD_SRST : PORT_R_RD_ARST; +wire WRE = `wre(PORT_W_WIDTH, PORT_W_WR_EN, PORT_W_WR_BE); +wire [13:0] ADW = `addrbe(PORT_W_WIDTH, PORT_W_ADDR, PORT_W_WR_BE); + +generate + +if (PORT_W_WIDTH < 9 || PORT_R_WIDTH < 9) begin + + wire [31:0] DI = `x8_wr_data(PORT_W_WR_DATA); + wire [31:0] DO; + + assign PORT_R_RD_DATA = `x8_rd_data(DO); + + SDP #( + `INIT(init_slice_x8) + .READ_MODE(1'b0), + .BIT_WIDTH_0(`x8_width(PORT_W_WIDTH)), + .BIT_WIDTH_1(`x8_width(PORT_R_WIDTH)), + .BLK_SEL(3'b000), + .RESET_MODE(OPTION_RESET_MODE), + ) _TECHMAP_REPLACE_ ( + .BLKSEL(3'b000), + + .CLKA(PORT_W_CLK), + .CEA(PORT_W_CLK_EN), + .WREA(WRE), + .RESETA(1'b0), + .ADA(ADW), + .DI(DI), + + .CLKB(PORT_R_CLK), + .CEB(PORT_R_CLK_EN), + .WREB(1'b0), + .RESETB(RST), + .OCE(1'b0), + .ADB(PORT_R_ADDR), + .DO(DO), + ); + +end else begin + + wire [35:0] DI = PORT_W_WR_DATA; + wire [35:0] DO; + + assign PORT_R_RD_DATA = DO; + + SDPX9 #( + `INIT(init_slice_x9) + .READ_MODE(1'b0), + .BIT_WIDTH_0(PORT_W_WIDTH), + .BIT_WIDTH_1(PORT_R_WIDTH), + .BLK_SEL(3'b000), + .RESET_MODE(OPTION_RESET_MODE), + ) _TECHMAP_REPLACE_ ( + .BLKSEL(3'b000), + + .CLKA(PORT_W_CLK), + .CEA(PORT_W_CLK_EN), + .WREA(WRE), + .RESETA(1'b0), + .ADA(ADW), + .DI(DI), + + .CLKB(PORT_R_CLK), + .CEB(PORT_R_CLK_EN), + .WREB(1'b0), + .RESETB(RST), + .OCE(1'b0), + .ADB(PORT_R_ADDR), + .DO(DO), + ); + +end + +endgenerate + endmodule diff --git a/techlibs/gowin/cells_map.v b/techlibs/gowin/cells_map.v index 90eb9b5a4..5978a00d0 100644 --- a/techlibs/gowin/cells_map.v +++ b/techlibs/gowin/cells_map.v @@ -122,14 +122,6 @@ module \$_DFFE_NP0P_ (input D, C, R, E, output Q); wire _TECHMAP_REMOVEINIT_Q_ = 1; endmodule -module \$__GW_IOBUF (input I, OE, output O, inout IO); - IOBUF _TECHMAP_REPLACE_ (.I(I), .O(O), .OEN(~OE), .IO(IO)); -endmodule - -module \$__GW_TBUF (input I, OE, output O); - TBUF _TECHMAP_REPLACE_ (.I(I), .OEN(~OE), .O(O)); -endmodule - module \$lut (A, Y); parameter WIDTH = 0; parameter LUT = 0; diff --git a/techlibs/gowin/cells_sim.v b/techlibs/gowin/cells_sim.v index 41398409d..736aa0707 100644 --- a/techlibs/gowin/cells_sim.v +++ b/techlibs/gowin/cells_sim.v @@ -550,7 +550,6 @@ module GND(output G); assign G = 0; endmodule -(* abc9_box *) module IBUF(output O, input I); specify @@ -560,7 +559,6 @@ module IBUF(output O, input I); assign O = I; endmodule -(* abc9_box *) module OBUF(output O, input I); specify @@ -584,6 +582,39 @@ module IOBUF (O, IO, I, OEN); assign I = IO; endmodule +module TLVDS_OBUF (I, O, OB); + input I; + output O; + output OB; + assign O = I; + assign OB = ~I; +endmodule + +(* blackbox *) +module ODDR(D0, D1, TX, CLK, Q0, Q1); + input D0; + input D1; + input TX; + input CLK; + output Q0; + output Q1; + parameter TXCLK_POL = 0; + parameter INIT = 0; +endmodule + +(* blackbox *) +module ODDRC(D0, D1, CLEAR, TX, CLK, Q0, Q1); + input D0; + input D1; + input CLEAR; + input TX; + input CLK; + output Q0; + output Q1; + parameter TXCLK_POL = 0; + parameter INIT = 0; +endmodule + module GSR (input GSRI); wire GSRO = GSRI; endmodule @@ -674,134 +705,610 @@ end endmodule + +module RAM16S1 (DO, DI, AD, WRE, CLK); + +parameter INIT_0 = 16'h0000; + +input [3:0] AD; +input DI; +output DO; +input CLK; +input WRE; + +specify + (AD *> DO) = (270, 405); + $setup(DI, posedge CLK, 62); + $setup(WRE, posedge CLK, 62); + $setup(AD, posedge CLK, 62); + (posedge CLK => (DO : 1'bx)) = (474, 565); +endspecify + +reg [15:0] mem; + +initial begin + mem = INIT_0; +end + +assign DO = mem[AD]; + +always @(posedge CLK) begin + if (WRE) begin + mem[AD] <= DI; + end +end + +endmodule + + +module RAM16S2 (DO, DI, AD, WRE, CLK); + +parameter INIT_0 = 16'h0000; +parameter INIT_1 = 16'h0000; + +input [3:0] AD; +input [1:0] DI; +output [1:0] DO; +input CLK; +input WRE; + +specify + (AD *> DO) = (270, 405); + $setup(DI, posedge CLK, 62); + $setup(WRE, posedge CLK, 62); + $setup(AD, posedge CLK, 62); + (posedge CLK => (DO : 2'bx)) = (474, 565); +endspecify + +reg [15:0] mem0, mem1; + +initial begin + mem0 = INIT_0; + mem1 = INIT_1; +end + +assign DO[0] = mem0[AD]; +assign DO[1] = mem1[AD]; + +always @(posedge CLK) begin + if (WRE) begin + mem0[AD] <= DI[0]; + mem1[AD] <= DI[1]; + end +end + +endmodule + + module RAM16S4 (DO, DI, AD, WRE, CLK); - parameter WIDTH = 4; - parameter INIT_0 = 16'h0000; - parameter INIT_1 = 16'h0000; - parameter INIT_2 = 16'h0000; - parameter INIT_3 = 16'h0000; - - input [WIDTH-1:0] AD; - input [WIDTH-1:0] DI; - output [WIDTH-1:0] DO; - input CLK; - input WRE; - specify - (AD => DO) = (270, 405); +parameter INIT_0 = 16'h0000; +parameter INIT_1 = 16'h0000; +parameter INIT_2 = 16'h0000; +parameter INIT_3 = 16'h0000; + +input [3:0] AD; +input [3:0] DI; +output [3:0] DO; +input CLK; +input WRE; + +specify + (AD *> DO) = (270, 405); $setup(DI, posedge CLK, 62); $setup(WRE, posedge CLK, 62); $setup(AD, posedge CLK, 62); - (posedge CLK => (DO : {WIDTH{1'bx}})) = (474, 565); - endspecify + (posedge CLK => (DO : 4'bx)) = (474, 565); +endspecify + +reg [15:0] mem0, mem1, mem2, mem3; + +initial begin + mem0 = INIT_0; + mem1 = INIT_1; + mem2 = INIT_2; + mem3 = INIT_3; +end + +assign DO[0] = mem0[AD]; +assign DO[1] = mem1[AD]; +assign DO[2] = mem2[AD]; +assign DO[3] = mem3[AD]; + +always @(posedge CLK) begin + if (WRE) begin + mem0[AD] <= DI[0]; + mem1[AD] <= DI[1]; + mem2[AD] <= DI[2]; + mem3[AD] <= DI[3]; + end +end + +endmodule + + +module RAM16SDP1 (DO, DI, WAD, RAD, WRE, CLK); + +parameter INIT_0 = 16'h0000; + +input [3:0] WAD; +input [3:0] RAD; +input DI; +output DO; +input CLK; +input WRE; + +specify + (RAD *> DO) = (270, 405); + $setup(DI, posedge CLK, 62); + $setup(WRE, posedge CLK, 62); + $setup(WAD, posedge CLK, 62); + (posedge CLK => (DO : 1'bx)) = (474, 565); +endspecify + +reg [15:0] mem; + +initial begin + mem = INIT_0; +end + +assign DO = mem[RAD]; + +always @(posedge CLK) begin + if (WRE) begin + mem[WAD] <= DI; + end +end + +endmodule + + +module RAM16SDP2 (DO, DI, WAD, RAD, WRE, CLK); + +parameter INIT_0 = 16'h0000; +parameter INIT_1 = 16'h0000; + +input [3:0] WAD; +input [3:0] RAD; +input [1:0] DI; +output [1:0] DO; +input CLK; +input WRE; + +specify + (RAD *> DO) = (270, 405); + $setup(DI, posedge CLK, 62); + $setup(WRE, posedge CLK, 62); + $setup(WAD, posedge CLK, 62); + (posedge CLK => (DO : 2'bx)) = (474, 565); +endspecify + +reg [15:0] mem0, mem1; + +initial begin + mem0 = INIT_0; + mem1 = INIT_1; +end + +assign DO[0] = mem0[RAD]; +assign DO[1] = mem1[RAD]; + +always @(posedge CLK) begin + if (WRE) begin + mem0[WAD] <= DI[0]; + mem1[WAD] <= DI[1]; + end +end + +endmodule + + +module RAM16SDP4 (DO, DI, WAD, RAD, WRE, CLK); + +parameter INIT_0 = 16'h0000; +parameter INIT_1 = 16'h0000; +parameter INIT_2 = 16'h0000; +parameter INIT_3 = 16'h0000; + +input [3:0] WAD; +input [3:0] RAD; +input [3:0] DI; +output [3:0] DO; +input CLK; +input WRE; + +specify + (RAD *> DO) = (270, 405); + $setup(DI, posedge CLK, 62); + $setup(WRE, posedge CLK, 62); + $setup(WAD, posedge CLK, 62); + (posedge CLK => (DO : 4'bx)) = (474, 565); +endspecify + +reg [15:0] mem0, mem1, mem2, mem3; + +initial begin + mem0 = INIT_0; + mem1 = INIT_1; + mem2 = INIT_2; + mem3 = INIT_3; +end + +assign DO[0] = mem0[RAD]; +assign DO[1] = mem1[RAD]; +assign DO[2] = mem2[RAD]; +assign DO[3] = mem3[RAD]; + +always @(posedge CLK) begin + if (WRE) begin + mem0[WAD] <= DI[0]; + mem1[WAD] <= DI[1]; + mem2[WAD] <= DI[2]; + mem3[WAD] <= DI[3]; + end +end + +endmodule + + +(* blackbox *) +module SP (DO, DI, BLKSEL, AD, WRE, CLK, CE, OCE, RESET); + +// 1 Enables output pipeline registers. +parameter READ_MODE = 1'b0; +// 0: no read on write, 1: transparent, 2: read-before-write +parameter WRITE_MODE = 2'b00; +parameter BIT_WIDTH = 32; // 1, 2, 4, 8, 16, 32 +parameter BLK_SEL = 3'b000; +parameter RESET_MODE = "SYNC"; +parameter INIT_RAM_00 = 256'h0; +parameter INIT_RAM_01 = 256'h0; +parameter INIT_RAM_02 = 256'h0; +parameter INIT_RAM_03 = 256'h0; +parameter INIT_RAM_04 = 256'h0; +parameter INIT_RAM_05 = 256'h0; +parameter INIT_RAM_06 = 256'h0; +parameter INIT_RAM_07 = 256'h0; +parameter INIT_RAM_08 = 256'h0; +parameter INIT_RAM_09 = 256'h0; +parameter INIT_RAM_0A = 256'h0; +parameter INIT_RAM_0B = 256'h0; +parameter INIT_RAM_0C = 256'h0; +parameter INIT_RAM_0D = 256'h0; +parameter INIT_RAM_0E = 256'h0; +parameter INIT_RAM_0F = 256'h0; +parameter INIT_RAM_10 = 256'h0; +parameter INIT_RAM_11 = 256'h0; +parameter INIT_RAM_12 = 256'h0; +parameter INIT_RAM_13 = 256'h0; +parameter INIT_RAM_14 = 256'h0; +parameter INIT_RAM_15 = 256'h0; +parameter INIT_RAM_16 = 256'h0; +parameter INIT_RAM_17 = 256'h0; +parameter INIT_RAM_18 = 256'h0; +parameter INIT_RAM_19 = 256'h0; +parameter INIT_RAM_1A = 256'h0; +parameter INIT_RAM_1B = 256'h0; +parameter INIT_RAM_1C = 256'h0; +parameter INIT_RAM_1D = 256'h0; +parameter INIT_RAM_1E = 256'h0; +parameter INIT_RAM_1F = 256'h0; +parameter INIT_RAM_20 = 256'h0; +parameter INIT_RAM_21 = 256'h0; +parameter INIT_RAM_22 = 256'h0; +parameter INIT_RAM_23 = 256'h0; +parameter INIT_RAM_24 = 256'h0; +parameter INIT_RAM_25 = 256'h0; +parameter INIT_RAM_26 = 256'h0; +parameter INIT_RAM_27 = 256'h0; +parameter INIT_RAM_28 = 256'h0; +parameter INIT_RAM_29 = 256'h0; +parameter INIT_RAM_2A = 256'h0; +parameter INIT_RAM_2B = 256'h0; +parameter INIT_RAM_2C = 256'h0; +parameter INIT_RAM_2D = 256'h0; +parameter INIT_RAM_2E = 256'h0; +parameter INIT_RAM_2F = 256'h0; +parameter INIT_RAM_30 = 256'h0; +parameter INIT_RAM_31 = 256'h0; +parameter INIT_RAM_32 = 256'h0; +parameter INIT_RAM_33 = 256'h0; +parameter INIT_RAM_34 = 256'h0; +parameter INIT_RAM_35 = 256'h0; +parameter INIT_RAM_36 = 256'h0; +parameter INIT_RAM_37 = 256'h0; +parameter INIT_RAM_38 = 256'h0; +parameter INIT_RAM_39 = 256'h0; +parameter INIT_RAM_3A = 256'h0; +parameter INIT_RAM_3B = 256'h0; +parameter INIT_RAM_3C = 256'h0; +parameter INIT_RAM_3D = 256'h0; +parameter INIT_RAM_3E = 256'h0; +parameter INIT_RAM_3F = 256'h0; + +output [31:0] DO; +input [31:0] DI; +input [2:0] BLKSEL; +input [13:0] AD; +input WRE; +input CLK; +input CE; +input OCE; +input RESET; + +endmodule + +(* blackbox *) +module SPX9 (DO, DI, BLKSEL, AD, WRE, CLK, CE, OCE, RESET); - reg [15:0] mem0, mem1, mem2, mem3; - - initial begin - mem0 = INIT_0; - mem1 = INIT_1; - mem2 = INIT_2; - mem3 = INIT_3; - end - - assign DO[0] = mem0[AD]; - assign DO[1] = mem1[AD]; - assign DO[2] = mem2[AD]; - assign DO[3] = mem3[AD]; - - always @(posedge CLK) begin - if (WRE) begin - mem0[AD] <= DI[0]; - mem1[AD] <= DI[1]; - mem2[AD] <= DI[2]; - mem3[AD] <= DI[3]; - end - end - -endmodule // RAM16S4 +// 1 Enables output pipeline registers. +parameter READ_MODE = 1'b0; +// 0: no read on write, 1: transparent, 2: read-before-write +parameter WRITE_MODE = 2'b00; +parameter BIT_WIDTH = 36; // 9, 18, 36 +parameter BLK_SEL = 3'b000; +parameter RESET_MODE = "SYNC"; +parameter INIT_RAM_00 = 288'h0; +parameter INIT_RAM_01 = 288'h0; +parameter INIT_RAM_02 = 288'h0; +parameter INIT_RAM_03 = 288'h0; +parameter INIT_RAM_04 = 288'h0; +parameter INIT_RAM_05 = 288'h0; +parameter INIT_RAM_06 = 288'h0; +parameter INIT_RAM_07 = 288'h0; +parameter INIT_RAM_08 = 288'h0; +parameter INIT_RAM_09 = 288'h0; +parameter INIT_RAM_0A = 288'h0; +parameter INIT_RAM_0B = 288'h0; +parameter INIT_RAM_0C = 288'h0; +parameter INIT_RAM_0D = 288'h0; +parameter INIT_RAM_0E = 288'h0; +parameter INIT_RAM_0F = 288'h0; +parameter INIT_RAM_10 = 288'h0; +parameter INIT_RAM_11 = 288'h0; +parameter INIT_RAM_12 = 288'h0; +parameter INIT_RAM_13 = 288'h0; +parameter INIT_RAM_14 = 288'h0; +parameter INIT_RAM_15 = 288'h0; +parameter INIT_RAM_16 = 288'h0; +parameter INIT_RAM_17 = 288'h0; +parameter INIT_RAM_18 = 288'h0; +parameter INIT_RAM_19 = 288'h0; +parameter INIT_RAM_1A = 288'h0; +parameter INIT_RAM_1B = 288'h0; +parameter INIT_RAM_1C = 288'h0; +parameter INIT_RAM_1D = 288'h0; +parameter INIT_RAM_1E = 288'h0; +parameter INIT_RAM_1F = 288'h0; +parameter INIT_RAM_20 = 288'h0; +parameter INIT_RAM_21 = 288'h0; +parameter INIT_RAM_22 = 288'h0; +parameter INIT_RAM_23 = 288'h0; +parameter INIT_RAM_24 = 288'h0; +parameter INIT_RAM_25 = 288'h0; +parameter INIT_RAM_26 = 288'h0; +parameter INIT_RAM_27 = 288'h0; +parameter INIT_RAM_28 = 288'h0; +parameter INIT_RAM_29 = 288'h0; +parameter INIT_RAM_2A = 288'h0; +parameter INIT_RAM_2B = 288'h0; +parameter INIT_RAM_2C = 288'h0; +parameter INIT_RAM_2D = 288'h0; +parameter INIT_RAM_2E = 288'h0; +parameter INIT_RAM_2F = 288'h0; +parameter INIT_RAM_30 = 288'h0; +parameter INIT_RAM_31 = 288'h0; +parameter INIT_RAM_32 = 288'h0; +parameter INIT_RAM_33 = 288'h0; +parameter INIT_RAM_34 = 288'h0; +parameter INIT_RAM_35 = 288'h0; +parameter INIT_RAM_36 = 288'h0; +parameter INIT_RAM_37 = 288'h0; +parameter INIT_RAM_38 = 288'h0; +parameter INIT_RAM_39 = 288'h0; +parameter INIT_RAM_3A = 288'h0; +parameter INIT_RAM_3B = 288'h0; +parameter INIT_RAM_3C = 288'h0; +parameter INIT_RAM_3D = 288'h0; +parameter INIT_RAM_3E = 288'h0; +parameter INIT_RAM_3F = 288'h0; + +output [35:0] DO; +input [35:0] DI; +input [2:0] BLKSEL; +input [13:0] AD; +input WRE; +input CLK; +input CE; +input OCE; +input RESET; + +endmodule (* blackbox *) module SDP (DO, DI, BLKSEL, ADA, ADB, WREA, WREB, CLKA, CLKB, CEA, CEB, OCE, RESETA, RESETB); -//1'b0: Bypass mode; 1'b1 Pipeline mode + parameter READ_MODE = 1'b0; parameter BIT_WIDTH_0 = 32; // 1, 2, 4, 8, 16, 32 parameter BIT_WIDTH_1 = 32; // 1, 2, 4, 8, 16, 32 parameter BLK_SEL = 3'b000; parameter RESET_MODE = "SYNC"; -parameter INIT_RAM_00 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_01 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_02 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_03 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_04 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_05 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_06 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_07 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_08 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_09 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_0A = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_0B = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_0C = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_0D = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_0E = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_0F = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_10 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_11 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_12 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_13 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_14 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_15 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_16 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_17 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_18 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_19 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_1A = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_1B = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_1C = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_1D = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_1E = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_1F = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_20 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_21 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_22 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_23 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_24 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_25 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_26 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_27 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_28 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_29 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_2A = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_2B = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_2C = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_2D = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_2E = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_2F = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_30 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_31 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_32 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_33 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_34 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_35 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_36 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_37 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_38 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_39 = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_3A = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_3B = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_3C = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_3D = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_3E = 256'h0000000000000000000000000000000000000000000000000000000000000000; -parameter INIT_RAM_3F = 256'h0000000000000000000000000000000000000000000000000000000000000000; - -input CLKA, CEA, CLKB, CEB; -input OCE; // clock enable of memory output register -input RESETA, RESETB; // resets output registers, not memory contents -input WREA, WREB; // 1'b0: read enabled; 1'b1: write enabled -input [13:0] ADA, ADB; +parameter INIT_RAM_00 = 256'h0; +parameter INIT_RAM_01 = 256'h0; +parameter INIT_RAM_02 = 256'h0; +parameter INIT_RAM_03 = 256'h0; +parameter INIT_RAM_04 = 256'h0; +parameter INIT_RAM_05 = 256'h0; +parameter INIT_RAM_06 = 256'h0; +parameter INIT_RAM_07 = 256'h0; +parameter INIT_RAM_08 = 256'h0; +parameter INIT_RAM_09 = 256'h0; +parameter INIT_RAM_0A = 256'h0; +parameter INIT_RAM_0B = 256'h0; +parameter INIT_RAM_0C = 256'h0; +parameter INIT_RAM_0D = 256'h0; +parameter INIT_RAM_0E = 256'h0; +parameter INIT_RAM_0F = 256'h0; +parameter INIT_RAM_10 = 256'h0; +parameter INIT_RAM_11 = 256'h0; +parameter INIT_RAM_12 = 256'h0; +parameter INIT_RAM_13 = 256'h0; +parameter INIT_RAM_14 = 256'h0; +parameter INIT_RAM_15 = 256'h0; +parameter INIT_RAM_16 = 256'h0; +parameter INIT_RAM_17 = 256'h0; +parameter INIT_RAM_18 = 256'h0; +parameter INIT_RAM_19 = 256'h0; +parameter INIT_RAM_1A = 256'h0; +parameter INIT_RAM_1B = 256'h0; +parameter INIT_RAM_1C = 256'h0; +parameter INIT_RAM_1D = 256'h0; +parameter INIT_RAM_1E = 256'h0; +parameter INIT_RAM_1F = 256'h0; +parameter INIT_RAM_20 = 256'h0; +parameter INIT_RAM_21 = 256'h0; +parameter INIT_RAM_22 = 256'h0; +parameter INIT_RAM_23 = 256'h0; +parameter INIT_RAM_24 = 256'h0; +parameter INIT_RAM_25 = 256'h0; +parameter INIT_RAM_26 = 256'h0; +parameter INIT_RAM_27 = 256'h0; +parameter INIT_RAM_28 = 256'h0; +parameter INIT_RAM_29 = 256'h0; +parameter INIT_RAM_2A = 256'h0; +parameter INIT_RAM_2B = 256'h0; +parameter INIT_RAM_2C = 256'h0; +parameter INIT_RAM_2D = 256'h0; +parameter INIT_RAM_2E = 256'h0; +parameter INIT_RAM_2F = 256'h0; +parameter INIT_RAM_30 = 256'h0; +parameter INIT_RAM_31 = 256'h0; +parameter INIT_RAM_32 = 256'h0; +parameter INIT_RAM_33 = 256'h0; +parameter INIT_RAM_34 = 256'h0; +parameter INIT_RAM_35 = 256'h0; +parameter INIT_RAM_36 = 256'h0; +parameter INIT_RAM_37 = 256'h0; +parameter INIT_RAM_38 = 256'h0; +parameter INIT_RAM_39 = 256'h0; +parameter INIT_RAM_3A = 256'h0; +parameter INIT_RAM_3B = 256'h0; +parameter INIT_RAM_3C = 256'h0; +parameter INIT_RAM_3D = 256'h0; +parameter INIT_RAM_3E = 256'h0; +parameter INIT_RAM_3F = 256'h0; + +output [31:0] DO; input [31:0] DI; input [2:0] BLKSEL; -output [31:0] DO; +input [13:0] ADA, ADB; +input WREA, WREB; +input CLKA, CLKB; +input CEA, CEB; +input OCE; +input RESETA, RESETB; + +specify + (posedge CLKB => (DO : DI)) = (419, 493); + $setup(RESETA, posedge CLKA, 62); + $setup(RESETB, posedge CLKB, 62); + $setup(OCE, posedge CLKB, 62); + $setup(CEA, posedge CLKA, 62); + $setup(CEB, posedge CLKB, 62); + $setup(OCE, posedge CLKB, 62); + $setup(WREA, posedge CLKA, 62); + $setup(WREB, posedge CLKB, 62); + $setup(DI, posedge CLKA, 62); + $setup(ADA, posedge CLKA, 62); + $setup(ADB, posedge CLKB, 62); + $setup(BLKSEL, posedge CLKA, 62); +endspecify + +endmodule + +(* blackbox *) +module SDPX9 (DO, DI, BLKSEL, ADA, ADB, WREA, WREB, CLKA, CLKB, CEA, CEB, OCE, RESETA, RESETB); + +parameter READ_MODE = 1'b0; +parameter BIT_WIDTH_0 = 36; // 9, 18, 36 +parameter BIT_WIDTH_1 = 36; // 9, 18, 36 +parameter BLK_SEL = 3'b000; +parameter RESET_MODE = "SYNC"; +parameter INIT_RAM_00 = 288'h0; +parameter INIT_RAM_01 = 288'h0; +parameter INIT_RAM_02 = 288'h0; +parameter INIT_RAM_03 = 288'h0; +parameter INIT_RAM_04 = 288'h0; +parameter INIT_RAM_05 = 288'h0; +parameter INIT_RAM_06 = 288'h0; +parameter INIT_RAM_07 = 288'h0; +parameter INIT_RAM_08 = 288'h0; +parameter INIT_RAM_09 = 288'h0; +parameter INIT_RAM_0A = 288'h0; +parameter INIT_RAM_0B = 288'h0; +parameter INIT_RAM_0C = 288'h0; +parameter INIT_RAM_0D = 288'h0; +parameter INIT_RAM_0E = 288'h0; +parameter INIT_RAM_0F = 288'h0; +parameter INIT_RAM_10 = 288'h0; +parameter INIT_RAM_11 = 288'h0; +parameter INIT_RAM_12 = 288'h0; +parameter INIT_RAM_13 = 288'h0; +parameter INIT_RAM_14 = 288'h0; +parameter INIT_RAM_15 = 288'h0; +parameter INIT_RAM_16 = 288'h0; +parameter INIT_RAM_17 = 288'h0; +parameter INIT_RAM_18 = 288'h0; +parameter INIT_RAM_19 = 288'h0; +parameter INIT_RAM_1A = 288'h0; +parameter INIT_RAM_1B = 288'h0; +parameter INIT_RAM_1C = 288'h0; +parameter INIT_RAM_1D = 288'h0; +parameter INIT_RAM_1E = 288'h0; +parameter INIT_RAM_1F = 288'h0; +parameter INIT_RAM_20 = 288'h0; +parameter INIT_RAM_21 = 288'h0; +parameter INIT_RAM_22 = 288'h0; +parameter INIT_RAM_23 = 288'h0; +parameter INIT_RAM_24 = 288'h0; +parameter INIT_RAM_25 = 288'h0; +parameter INIT_RAM_26 = 288'h0; +parameter INIT_RAM_27 = 288'h0; +parameter INIT_RAM_28 = 288'h0; +parameter INIT_RAM_29 = 288'h0; +parameter INIT_RAM_2A = 288'h0; +parameter INIT_RAM_2B = 288'h0; +parameter INIT_RAM_2C = 288'h0; +parameter INIT_RAM_2D = 288'h0; +parameter INIT_RAM_2E = 288'h0; +parameter INIT_RAM_2F = 288'h0; +parameter INIT_RAM_30 = 288'h0; +parameter INIT_RAM_31 = 288'h0; +parameter INIT_RAM_32 = 288'h0; +parameter INIT_RAM_33 = 288'h0; +parameter INIT_RAM_34 = 288'h0; +parameter INIT_RAM_35 = 288'h0; +parameter INIT_RAM_36 = 288'h0; +parameter INIT_RAM_37 = 288'h0; +parameter INIT_RAM_38 = 288'h0; +parameter INIT_RAM_39 = 288'h0; +parameter INIT_RAM_3A = 288'h0; +parameter INIT_RAM_3B = 288'h0; +parameter INIT_RAM_3C = 288'h0; +parameter INIT_RAM_3D = 288'h0; +parameter INIT_RAM_3E = 288'h0; +parameter INIT_RAM_3F = 288'h0; + +output [35:0] DO; +input [35:0] DI; +input [2:0] BLKSEL; +input [13:0] ADA, ADB; +input WREA, WREB; +input CLKA, CLKB; +input CEA, CEB; +input OCE; +input RESETA, RESETB; specify (posedge CLKB => (DO : DI)) = (419, 493); @@ -821,6 +1328,184 @@ endspecify endmodule + +(* blackbox *) +module DP (DOA, DOB, DIA, DIB, BLKSEL, ADA, ADB, WREA, WREB, CLKA, CLKB, CEA, CEB, OCEA, OCEB, RESETA, RESETB); + +parameter READ_MODE0 = 1'b0; +parameter READ_MODE1 = 1'b0; +parameter WRITE_MODE0 = 2'b00; +parameter WRITE_MODE1 = 2'b00; +parameter BIT_WIDTH_0 = 16; // 1, 2, 4, 8, 16 +parameter BIT_WIDTH_1 = 16; // 1, 2, 4, 8, 16 +parameter BLK_SEL = 3'b000; +parameter RESET_MODE = "SYNC"; +parameter INIT_RAM_00 = 256'h0; +parameter INIT_RAM_01 = 256'h0; +parameter INIT_RAM_02 = 256'h0; +parameter INIT_RAM_03 = 256'h0; +parameter INIT_RAM_04 = 256'h0; +parameter INIT_RAM_05 = 256'h0; +parameter INIT_RAM_06 = 256'h0; +parameter INIT_RAM_07 = 256'h0; +parameter INIT_RAM_08 = 256'h0; +parameter INIT_RAM_09 = 256'h0; +parameter INIT_RAM_0A = 256'h0; +parameter INIT_RAM_0B = 256'h0; +parameter INIT_RAM_0C = 256'h0; +parameter INIT_RAM_0D = 256'h0; +parameter INIT_RAM_0E = 256'h0; +parameter INIT_RAM_0F = 256'h0; +parameter INIT_RAM_10 = 256'h0; +parameter INIT_RAM_11 = 256'h0; +parameter INIT_RAM_12 = 256'h0; +parameter INIT_RAM_13 = 256'h0; +parameter INIT_RAM_14 = 256'h0; +parameter INIT_RAM_15 = 256'h0; +parameter INIT_RAM_16 = 256'h0; +parameter INIT_RAM_17 = 256'h0; +parameter INIT_RAM_18 = 256'h0; +parameter INIT_RAM_19 = 256'h0; +parameter INIT_RAM_1A = 256'h0; +parameter INIT_RAM_1B = 256'h0; +parameter INIT_RAM_1C = 256'h0; +parameter INIT_RAM_1D = 256'h0; +parameter INIT_RAM_1E = 256'h0; +parameter INIT_RAM_1F = 256'h0; +parameter INIT_RAM_20 = 256'h0; +parameter INIT_RAM_21 = 256'h0; +parameter INIT_RAM_22 = 256'h0; +parameter INIT_RAM_23 = 256'h0; +parameter INIT_RAM_24 = 256'h0; +parameter INIT_RAM_25 = 256'h0; +parameter INIT_RAM_26 = 256'h0; +parameter INIT_RAM_27 = 256'h0; +parameter INIT_RAM_28 = 256'h0; +parameter INIT_RAM_29 = 256'h0; +parameter INIT_RAM_2A = 256'h0; +parameter INIT_RAM_2B = 256'h0; +parameter INIT_RAM_2C = 256'h0; +parameter INIT_RAM_2D = 256'h0; +parameter INIT_RAM_2E = 256'h0; +parameter INIT_RAM_2F = 256'h0; +parameter INIT_RAM_30 = 256'h0; +parameter INIT_RAM_31 = 256'h0; +parameter INIT_RAM_32 = 256'h0; +parameter INIT_RAM_33 = 256'h0; +parameter INIT_RAM_34 = 256'h0; +parameter INIT_RAM_35 = 256'h0; +parameter INIT_RAM_36 = 256'h0; +parameter INIT_RAM_37 = 256'h0; +parameter INIT_RAM_38 = 256'h0; +parameter INIT_RAM_39 = 256'h0; +parameter INIT_RAM_3A = 256'h0; +parameter INIT_RAM_3B = 256'h0; +parameter INIT_RAM_3C = 256'h0; +parameter INIT_RAM_3D = 256'h0; +parameter INIT_RAM_3E = 256'h0; +parameter INIT_RAM_3F = 256'h0; + +output [15:0] DOA, DOB; +input [15:0] DIA, DIB; +input [2:0] BLKSEL; +input [13:0] ADA, ADB; +input WREA, WREB; +input CLKA, CLKB; +input CEA, CEB; +input OCEA, OCEB; +input RESETA, RESETB; + +endmodule + +(* blackbox *) +module DPX9 (DOA, DOB, DIA, DIB, BLKSEL, ADA, ADB, WREA, WREB, CLKA, CLKB, CEA, CEB, OCEA, OCEB, RESETA, RESETB); + +parameter READ_MODE0 = 1'b0; +parameter READ_MODE1 = 1'b0; +parameter WRITE_MODE0 = 2'b00; +parameter WRITE_MODE1 = 2'b00; +parameter BIT_WIDTH_0 = 18; // 9, 18 +parameter BIT_WIDTH_1 = 18; // 9, 18 +parameter BLK_SEL = 3'b000; +parameter RESET_MODE = "SYNC"; +parameter INIT_RAM_00 = 288'h0; +parameter INIT_RAM_01 = 288'h0; +parameter INIT_RAM_02 = 288'h0; +parameter INIT_RAM_03 = 288'h0; +parameter INIT_RAM_04 = 288'h0; +parameter INIT_RAM_05 = 288'h0; +parameter INIT_RAM_06 = 288'h0; +parameter INIT_RAM_07 = 288'h0; +parameter INIT_RAM_08 = 288'h0; +parameter INIT_RAM_09 = 288'h0; +parameter INIT_RAM_0A = 288'h0; +parameter INIT_RAM_0B = 288'h0; +parameter INIT_RAM_0C = 288'h0; +parameter INIT_RAM_0D = 288'h0; +parameter INIT_RAM_0E = 288'h0; +parameter INIT_RAM_0F = 288'h0; +parameter INIT_RAM_10 = 288'h0; +parameter INIT_RAM_11 = 288'h0; +parameter INIT_RAM_12 = 288'h0; +parameter INIT_RAM_13 = 288'h0; +parameter INIT_RAM_14 = 288'h0; +parameter INIT_RAM_15 = 288'h0; +parameter INIT_RAM_16 = 288'h0; +parameter INIT_RAM_17 = 288'h0; +parameter INIT_RAM_18 = 288'h0; +parameter INIT_RAM_19 = 288'h0; +parameter INIT_RAM_1A = 288'h0; +parameter INIT_RAM_1B = 288'h0; +parameter INIT_RAM_1C = 288'h0; +parameter INIT_RAM_1D = 288'h0; +parameter INIT_RAM_1E = 288'h0; +parameter INIT_RAM_1F = 288'h0; +parameter INIT_RAM_20 = 288'h0; +parameter INIT_RAM_21 = 288'h0; +parameter INIT_RAM_22 = 288'h0; +parameter INIT_RAM_23 = 288'h0; +parameter INIT_RAM_24 = 288'h0; +parameter INIT_RAM_25 = 288'h0; +parameter INIT_RAM_26 = 288'h0; +parameter INIT_RAM_27 = 288'h0; +parameter INIT_RAM_28 = 288'h0; +parameter INIT_RAM_29 = 288'h0; +parameter INIT_RAM_2A = 288'h0; +parameter INIT_RAM_2B = 288'h0; +parameter INIT_RAM_2C = 288'h0; +parameter INIT_RAM_2D = 288'h0; +parameter INIT_RAM_2E = 288'h0; +parameter INIT_RAM_2F = 288'h0; +parameter INIT_RAM_30 = 288'h0; +parameter INIT_RAM_31 = 288'h0; +parameter INIT_RAM_32 = 288'h0; +parameter INIT_RAM_33 = 288'h0; +parameter INIT_RAM_34 = 288'h0; +parameter INIT_RAM_35 = 288'h0; +parameter INIT_RAM_36 = 288'h0; +parameter INIT_RAM_37 = 288'h0; +parameter INIT_RAM_38 = 288'h0; +parameter INIT_RAM_39 = 288'h0; +parameter INIT_RAM_3A = 288'h0; +parameter INIT_RAM_3B = 288'h0; +parameter INIT_RAM_3C = 288'h0; +parameter INIT_RAM_3D = 288'h0; +parameter INIT_RAM_3E = 288'h0; +parameter INIT_RAM_3F = 288'h0; + +output [17:0] DOA, DOB; +input [17:0] DIA, DIB; +input [2:0] BLKSEL; +input [13:0] ADA, ADB; +input WREA, WREB; +input CLKA, CLKB; +input CEA, CEB; +input OCEA, OCEB; +input RESETA, RESETB; + +endmodule + + (* blackbox *) module rPLL (CLKOUT, CLKOUTP, CLKOUTD, CLKOUTD3, LOCK, CLKIN, CLKFB, FBDSEL, IDSEL, ODSEL, DUTYDA, PSDA, FDLY, RESET, RESET_P); input CLKIN; @@ -866,3 +1551,37 @@ parameter CLKOUTD3_SRC = "CLKOUT"; // CLKOUT, CLKOUTP parameter DEVICE = "GW1N-1"; // "GW1N-1", "GW1N-4", "GW1N-9", "GW1NR-4", "GW1NR-9", "GW1N-4B", "GW1NR-4B", "GW1NS-2", "GW1NS-2C", "GW1NZ-1", "GW1NSR-2", "GW1NSR-2C", "GW1N-1S", "GW1NSE-2C", "GW1NRF-4B", "GW1N-9C", "GW1NR-9C", "GW1N-4C", "GW1NR-4C" endmodule + +(* blackbox *) +module OSC(OSCOUT); +output OSCOUT; + +parameter FREQ_DIV = 100; +parameter DEVICE = "GW1N-4"; +endmodule + +(* blackbox *) +module OSCZ(OSCOUT, OSCEN); +input OSCEN; + +output OSCOUT; + +parameter FREQ_DIV = 100; +endmodule + +(* blackbox *) +module OSCF(OSCOUT, OSCOUT30M, OSCEN); +input OSCEN; + +output OSCOUT; +output OSCOUT30M; + +parameter FREQ_DIV = 100; +endmodule + +(* blackbox *) +module OSCH(OSCOUT); +output OSCOUT; + +parameter FREQ_DIV = 96; +endmodule diff --git a/techlibs/gowin/lutrams.txt b/techlibs/gowin/lutrams.txt index 9db530251..76c4cd584 100644 --- a/techlibs/gowin/lutrams.txt +++ b/techlibs/gowin/lutrams.txt @@ -1,17 +1,13 @@ -bram $__GW1NR_RAM16S4 - init 1 - abits 4 - dbits 4 - groups 2 - ports 1 1 - wrmode 0 1 - enable 0 1 - transp 0 1 - clocks 0 1 - clkpol 0 1 -endbram - -match $__GW1NR_RAM16S4 - make_outreg - min wports 1 -endmatch +ram distributed $__GOWIN_LUTRAM_ { + abits 4; + width 4; + cost 4; + widthscale; + init no_undef; + prune_rom; + port sw "W" { + clock posedge; + } + port ar "R" { + } +} diff --git a/techlibs/gowin/lutrams_map.v b/techlibs/gowin/lutrams_map.v index a50ab365a..6396ef7c6 100644 --- a/techlibs/gowin/lutrams_map.v +++ b/techlibs/gowin/lutrams_map.v @@ -1,31 +1,65 @@ -module \$__GW1NR_RAM16S4 (CLK1, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN); - parameter CFG_ABITS = 4; - parameter CFG_DBITS = 4; - - parameter [63:0] INIT = 64'bx; - input CLK1; - - 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 B1EN; - - `include "brams_init3.vh" - - RAM16S4 - #(.INIT_0(INIT_0), - .INIT_1(INIT_1), - .INIT_2(INIT_2), - .INIT_3(INIT_3)) - _TECHMAP_REPLACE_ - (.AD(B1ADDR), - .DI(B1DATA), - .DO(A1DATA), - .CLK(CLK1), - .WRE(B1EN)); - - +module $__GOWIN_LUTRAM_(...); + +parameter INIT = 64'bx; +parameter BITS_USED = 0; + +input PORT_W_CLK; +input [3:0] PORT_W_ADDR; +input PORT_W_WR_EN; +input [3:0] PORT_W_WR_DATA; + +input [3:0] PORT_R_ADDR; +output [3:0] PORT_R_RD_DATA; + +function [15:0] init_slice; +input integer idx; +integer i; +for (i = 0; i < 16; i = i + 1) + init_slice[i] = INIT[4*i+idx]; +endfunction + +generate + +casez(BITS_USED) +4'b000z: +RAM16SDP1 #( + .INIT_0(init_slice(0)), +) _TECHMAP_REPLACE_ ( + .WAD(PORT_W_ADDR), + .RAD(PORT_R_ADDR), + .DI(PORT_W_WR_DATA[0]), + .DO(PORT_R_RD_DATA[0]), + .CLK(PORT_W_CLK), + .WRE(PORT_W_WR_EN) +); +4'b00zz: +RAM16SDP2 #( + .INIT_0(init_slice(0)), + .INIT_1(init_slice(1)), +) _TECHMAP_REPLACE_ ( + .WAD(PORT_W_ADDR), + .RAD(PORT_R_ADDR), + .DI(PORT_W_WR_DATA[1:0]), + .DO(PORT_R_RD_DATA[1:0]), + .CLK(PORT_W_CLK), + .WRE(PORT_W_WR_EN) +); +default: +RAM16SDP4 #( + .INIT_0(init_slice(0)), + .INIT_1(init_slice(1)), + .INIT_2(init_slice(2)), + .INIT_3(init_slice(3)), +) _TECHMAP_REPLACE_ ( + .WAD(PORT_W_ADDR), + .RAD(PORT_R_ADDR), + .DI(PORT_W_WR_DATA), + .DO(PORT_R_RD_DATA), + .CLK(PORT_W_CLK), + .WRE(PORT_W_WR_EN) +); +endcase + +endgenerate + endmodule diff --git a/techlibs/gowin/synth_gowin.cc b/techlibs/gowin/synth_gowin.cc index 087f6b8cf..d900bd255 100644 --- a/techlibs/gowin/synth_gowin.cc +++ b/techlibs/gowin/synth_gowin.cc @@ -126,8 +126,6 @@ struct SynthGowinPass : public ScriptPass json_file = args[++argidx]; nobram = true; nolutram = true; - nowidelut = true; - noalu = true; continue; } if (args[argidx] == "-run" && argidx+1 < args.size()) { @@ -210,17 +208,17 @@ struct SynthGowinPass : public ScriptPass run("synth -run coarse"); } - if (!nobram && check_label("map_bram", "(skip if -nobram)")) - { - run("memory_bram -rules +/gowin/brams.txt"); - run("techmap -map +/gowin/brams_map.v"); - } - - if (!nolutram && check_label("map_lutram", "(skip if -nolutram)")) + if (check_label("map_ram")) { - run("memory_bram -rules +/gowin/lutrams.txt"); - run("techmap -map +/gowin/lutrams_map.v"); - run("setundef -params -zero t:RAM16S4"); + std::string args = ""; + if (nobram) + args += " -no-auto-block"; + if (nolutram) + args += " -no-auto-distributed"; + if (help_mode) + args += " [-no-auto-block] [-no-auto-distributed]"; + run("memory_libmap -lib +/gowin/lutrams.txt -lib +/gowin/brams.txt" + args, "(-no-auto-block if -nobram, -no-auto-distributed if -nolutram)"); + run("techmap -map +/gowin/lutrams_map.v -map +/gowin/brams_map.v"); } if (check_label("map_ffram")) @@ -240,10 +238,9 @@ struct SynthGowinPass : public ScriptPass run("opt -fast"); if (retime || help_mode) run("abc -dff -D 1", "(only if -retime)"); - run("splitnets"); if (!noiopads || help_mode) run("iopadmap -bits -inpad IBUF O:I -outpad OBUF I:O " - "-toutpad $__GW_TBUF OE:I:O -tinoutpad $__GW_IOBUF OE:O:I:IO", "(unless -noiopads)"); + "-toutpad TBUF ~OEN:I:O -tinoutpad IOBUF ~OEN:O:I:IO", "(unless -noiopads)"); } if (check_label("map_ffs")) @@ -280,6 +277,8 @@ struct SynthGowinPass : public ScriptPass run("opt_lut_ins -tech gowin"); run("setundef -undriven -params -zero"); run("hilomap -singleton -hicell VCC V -locell GND G"); + if (!vout_file.empty() || help_mode) // vendor output requires 1-bit wires + run("splitnets -ports", "(only if -vout used)"); run("clean"); run("autoname"); } @@ -295,7 +294,7 @@ struct SynthGowinPass : public ScriptPass if (check_label("vout")) { if (!vout_file.empty() || help_mode) - run(stringf("write_verilog -decimal -attr2comment -defparam -renameprefix gen %s", + run(stringf("write_verilog -simple-lhs -decimal -attr2comment -defparam -renameprefix gen %s", help_mode ? "<file-name>" : vout_file.c_str())); if (!json_file.empty() || help_mode) run(stringf("write_json %s", diff --git a/techlibs/ice40/.gitignore b/techlibs/ice40/.gitignore deleted file mode 100644 index 6bf3b6717..000000000 --- a/techlibs/ice40/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -brams_init.mk -brams_init1.vh -brams_init2.vh -brams_init3.vh diff --git a/techlibs/ice40/Makefile.inc b/techlibs/ice40/Makefile.inc index 8ce3cb024..4bf8e4e86 100644 --- a/techlibs/ice40/Makefile.inc +++ b/techlibs/ice40/Makefile.inc @@ -3,22 +3,6 @@ OBJS += techlibs/ice40/synth_ice40.o OBJS += techlibs/ice40/ice40_braminit.o OBJS += techlibs/ice40/ice40_opt.o -GENFILES += techlibs/ice40/brams_init1.vh -GENFILES += techlibs/ice40/brams_init2.vh -GENFILES += techlibs/ice40/brams_init3.vh - -EXTRA_OBJS += techlibs/ice40/brams_init.mk -.SECONDARY: techlibs/ice40/brams_init.mk - -techlibs/ice40/brams_init.mk: techlibs/ice40/brams_init.py - $(Q) mkdir -p techlibs/ice40 - $(P) $(PYTHON_EXECUTABLE) $< - $(Q) touch techlibs/ice40/brams_init.mk - -techlibs/ice40/brams_init1.vh: techlibs/ice40/brams_init.mk -techlibs/ice40/brams_init2.vh: techlibs/ice40/brams_init.mk -techlibs/ice40/brams_init3.vh: techlibs/ice40/brams_init.mk - $(eval $(call add_share_file,share/ice40,techlibs/ice40/arith_map.v)) $(eval $(call add_share_file,share/ice40,techlibs/ice40/cells_map.v)) $(eval $(call add_share_file,share/ice40,techlibs/ice40/ff_map.v)) @@ -26,10 +10,7 @@ $(eval $(call add_share_file,share/ice40,techlibs/ice40/cells_sim.v)) $(eval $(call add_share_file,share/ice40,techlibs/ice40/latches_map.v)) $(eval $(call add_share_file,share/ice40,techlibs/ice40/brams.txt)) $(eval $(call add_share_file,share/ice40,techlibs/ice40/brams_map.v)) +$(eval $(call add_share_file,share/ice40,techlibs/ice40/spram.txt)) +$(eval $(call add_share_file,share/ice40,techlibs/ice40/spram_map.v)) $(eval $(call add_share_file,share/ice40,techlibs/ice40/dsp_map.v)) $(eval $(call add_share_file,share/ice40,techlibs/ice40/abc9_model.v)) - -$(eval $(call add_gen_share_file,share/ice40,techlibs/ice40/brams_init1.vh)) -$(eval $(call add_gen_share_file,share/ice40,techlibs/ice40/brams_init2.vh)) -$(eval $(call add_gen_share_file,share/ice40,techlibs/ice40/brams_init3.vh)) - diff --git a/techlibs/ice40/brams.txt b/techlibs/ice40/brams.txt index 36dfddab2..518972c2a 100644 --- a/techlibs/ice40/brams.txt +++ b/techlibs/ice40/brams.txt @@ -1,100 +1,23 @@ -bram $__ICE40_RAM4K_M0 - init 1 - abits 8 - dbits 16 - groups 2 - ports 1 1 - wrmode 0 1 - enable 1 16 - transp 0 0 - clocks 2 3 - clkpol 2 3 -endbram - -bram $__ICE40_RAM4K_M123 - init 1 - abits 9 @M1 - dbits 8 @M1 - abits 10 @M2 - dbits 4 @M2 - abits 11 @M3 - dbits 2 @M3 - groups 2 - ports 1 1 - wrmode 0 1 - enable 1 1 - transp 0 0 - clocks 2 3 - clkpol 2 3 -endbram - -# The syn_* attributes are described in: -# https://www.latticesemi.com/-/media/LatticeSemi/Documents/Tutorials/AK/LatticeDiamondTutorial311.ashx -attr_icase 1 - -match $__ICE40_RAM4K_M0 - # implicitly requested RAM or ROM - attribute !syn_ramstyle syn_ramstyle=auto - attribute !syn_romstyle syn_romstyle=auto - attribute !ram_block - attribute !rom_block - attribute !logic_block - min efficiency 2 - make_transp - or_next_if_better -endmatch - -match $__ICE40_RAM4K_M0 - # explicitly requested RAM - attribute syn_ramstyle=block_ram ram_block - attribute !syn_romstyle - attribute !rom_block - attribute !logic_block - min wports 1 - make_transp - or_next_if_better -endmatch - -match $__ICE40_RAM4K_M0 - # explicitly requested ROM - attribute syn_romstyle=ebr rom_block - attribute !syn_ramstyle - attribute !ram_block - attribute !logic_block - max wports 0 - make_transp - or_next_if_better -endmatch - -match $__ICE40_RAM4K_M123 - # implicitly requested RAM or ROM - attribute !syn_ramstyle syn_ramstyle=auto - attribute !syn_romstyle syn_romstyle=auto - attribute !ram_block - attribute !rom_block - attribute !logic_block - min efficiency 2 - make_transp - or_next_if_better -endmatch - -match $__ICE40_RAM4K_M123 - # explicitly requested RAM - attribute syn_ramstyle=block_ram ram_block - attribute !syn_romstyle - attribute !rom_block - attribute !logic_block - min wports 1 - make_transp - or_next_if_better -endmatch - -match $__ICE40_RAM4K_M123 - # explicitly requested ROM - attribute syn_romstyle=ebr rom_block - attribute !syn_ramstyle - attribute !ram_block - attribute !logic_block - max wports 0 - make_transp -endmatch +ram block $__ICE40_RAM4K_ { + abits 11; + widths 2 4 8 16 per_port; + cost 64; + option "HAS_BE" 1 { + byte 1; + } + init any; + port sw "W" { + option "HAS_BE" 0 { + width 2 4 8; + } + option "HAS_BE" 1 { + width 16; + wrbe_separate; + } + clock anyedge; + } + port sr "R" { + clock anyedge; + rden; + } +} diff --git a/techlibs/ice40/brams_init.py b/techlibs/ice40/brams_init.py deleted file mode 100644 index 4a1485110..000000000 --- a/techlibs/ice40/brams_init.py +++ /dev/null @@ -1,14 +0,0 @@ -#!/usr/bin/env python3 - -def write_init_vh(filename, initbits): - with open(filename, "w") as f: - for i in range(16): - print("localparam [255:0] INIT_%X = {" % i, file=f) - for k in range(32): - print(" %s%s" % (", ".join(["INIT[%4d]" % initbits[i*256 + 255 - k*8 - l] for l in range(8)]), "," if k != 31 else ""), file=f) - print("};", file=f); - -write_init_vh("techlibs/ice40/brams_init1.vh", [i//2 + 2048*(i%2) for i in range(4096)]) -write_init_vh("techlibs/ice40/brams_init2.vh", [i//4 + 1024*(i%4) for i in range(4096)]) -write_init_vh("techlibs/ice40/brams_init3.vh", [i//8 + 512*(i%8) for i in range(4096)]) - diff --git a/techlibs/ice40/brams_map.v b/techlibs/ice40/brams_map.v index db9f5d8ce..9d7b793e1 100644 --- a/techlibs/ice40/brams_map.v +++ b/techlibs/ice40/brams_map.v @@ -1,318 +1,218 @@ - -module \$__ICE40_RAM4K ( - output [15:0] RDATA, - input RCLK, RCLKE, RE, - input [10:0] RADDR, - input WCLK, WCLKE, WE, - input [10:0] WADDR, - input [15:0] MASK, WDATA -); - parameter [1:0] READ_MODE = 0; - parameter [1:0] WRITE_MODE = 0; - parameter [0:0] NEGCLK_R = 0; - parameter [0:0] NEGCLK_W = 0; - - parameter [255:0] INIT_0 = 256'h0000000000000000000000000000000000000000000000000000000000000000; - parameter [255:0] INIT_1 = 256'h0000000000000000000000000000000000000000000000000000000000000000; - parameter [255:0] INIT_2 = 256'h0000000000000000000000000000000000000000000000000000000000000000; - parameter [255:0] INIT_3 = 256'h0000000000000000000000000000000000000000000000000000000000000000; - parameter [255:0] INIT_4 = 256'h0000000000000000000000000000000000000000000000000000000000000000; - parameter [255:0] INIT_5 = 256'h0000000000000000000000000000000000000000000000000000000000000000; - parameter [255:0] INIT_6 = 256'h0000000000000000000000000000000000000000000000000000000000000000; - parameter [255:0] INIT_7 = 256'h0000000000000000000000000000000000000000000000000000000000000000; - parameter [255:0] INIT_8 = 256'h0000000000000000000000000000000000000000000000000000000000000000; - parameter [255:0] INIT_9 = 256'h0000000000000000000000000000000000000000000000000000000000000000; - parameter [255:0] INIT_A = 256'h0000000000000000000000000000000000000000000000000000000000000000; - parameter [255:0] INIT_B = 256'h0000000000000000000000000000000000000000000000000000000000000000; - parameter [255:0] INIT_C = 256'h0000000000000000000000000000000000000000000000000000000000000000; - parameter [255:0] INIT_D = 256'h0000000000000000000000000000000000000000000000000000000000000000; - parameter [255:0] INIT_E = 256'h0000000000000000000000000000000000000000000000000000000000000000; - parameter [255:0] INIT_F = 256'h0000000000000000000000000000000000000000000000000000000000000000; - - generate - case ({NEGCLK_R, NEGCLK_W}) - 2'b00: - SB_RAM40_4K #( - .READ_MODE(READ_MODE), - .WRITE_MODE(WRITE_MODE), - .INIT_0(INIT_0), - .INIT_1(INIT_1), - .INIT_2(INIT_2), - .INIT_3(INIT_3), - .INIT_4(INIT_4), - .INIT_5(INIT_5), - .INIT_6(INIT_6), - .INIT_7(INIT_7), - .INIT_8(INIT_8), - .INIT_9(INIT_9), - .INIT_A(INIT_A), - .INIT_B(INIT_B), - .INIT_C(INIT_C), - .INIT_D(INIT_D), - .INIT_E(INIT_E), - .INIT_F(INIT_F) - ) _TECHMAP_REPLACE_ ( - .RDATA(RDATA), - .RCLK (RCLK ), - .RCLKE(RCLKE), - .RE (RE ), - .RADDR(RADDR), - .WCLK (WCLK ), - .WCLKE(WCLKE), - .WE (WE ), - .WADDR(WADDR), - .MASK (MASK ), - .WDATA(WDATA) - ); - 2'b01: - SB_RAM40_4KNW #( - .READ_MODE(READ_MODE), - .WRITE_MODE(WRITE_MODE), - .INIT_0(INIT_0), - .INIT_1(INIT_1), - .INIT_2(INIT_2), - .INIT_3(INIT_3), - .INIT_4(INIT_4), - .INIT_5(INIT_5), - .INIT_6(INIT_6), - .INIT_7(INIT_7), - .INIT_8(INIT_8), - .INIT_9(INIT_9), - .INIT_A(INIT_A), - .INIT_B(INIT_B), - .INIT_C(INIT_C), - .INIT_D(INIT_D), - .INIT_E(INIT_E), - .INIT_F(INIT_F) - ) _TECHMAP_REPLACE_ ( - .RDATA(RDATA), - .RCLK (RCLK ), - .RCLKE(RCLKE), - .RE (RE ), - .RADDR(RADDR), - .WCLKN(WCLK ), - .WCLKE(WCLKE), - .WE (WE ), - .WADDR(WADDR), - .MASK (MASK ), - .WDATA(WDATA) - ); - 2'b10: - SB_RAM40_4KNR #( - .READ_MODE(READ_MODE), - .WRITE_MODE(WRITE_MODE), - .INIT_0(INIT_0), - .INIT_1(INIT_1), - .INIT_2(INIT_2), - .INIT_3(INIT_3), - .INIT_4(INIT_4), - .INIT_5(INIT_5), - .INIT_6(INIT_6), - .INIT_7(INIT_7), - .INIT_8(INIT_8), - .INIT_9(INIT_9), - .INIT_A(INIT_A), - .INIT_B(INIT_B), - .INIT_C(INIT_C), - .INIT_D(INIT_D), - .INIT_E(INIT_E), - .INIT_F(INIT_F) - ) _TECHMAP_REPLACE_ ( - .RDATA(RDATA), - .RCLKN(RCLK ), - .RCLKE(RCLKE), - .RE (RE ), - .RADDR(RADDR), - .WCLK (WCLK ), - .WCLKE(WCLKE), - .WE (WE ), - .WADDR(WADDR), - .MASK (MASK ), - .WDATA(WDATA) - ); - 2'b11: - SB_RAM40_4KNRNW #( - .READ_MODE(READ_MODE), - .WRITE_MODE(WRITE_MODE), - .INIT_0(INIT_0), - .INIT_1(INIT_1), - .INIT_2(INIT_2), - .INIT_3(INIT_3), - .INIT_4(INIT_4), - .INIT_5(INIT_5), - .INIT_6(INIT_6), - .INIT_7(INIT_7), - .INIT_8(INIT_8), - .INIT_9(INIT_9), - .INIT_A(INIT_A), - .INIT_B(INIT_B), - .INIT_C(INIT_C), - .INIT_D(INIT_D), - .INIT_E(INIT_E), - .INIT_F(INIT_F) - ) _TECHMAP_REPLACE_ ( - .RDATA(RDATA), - .RCLKN(RCLK ), - .RCLKE(RCLKE), - .RE (RE ), - .RADDR(RADDR), - .WCLKN(WCLK ), - .WCLKE(WCLKE), - .WE (WE ), - .WADDR(WADDR), - .MASK (MASK ), - .WDATA(WDATA) - ); - endcase - endgenerate -endmodule - - -module \$__ICE40_RAM4K_M0 (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN); - parameter [0:0] CLKPOL2 = 1; - parameter [0:0] CLKPOL3 = 1; - - parameter [4095:0] INIT = 4096'bx; - - input CLK2; - input CLK3; - - input [7:0] A1ADDR; - output [15:0] A1DATA; - input A1EN; - - input [7:0] B1ADDR; - input [15:0] B1DATA; - input [15:0] B1EN; - - wire [10:0] A1ADDR_11 = A1ADDR; - wire [10:0] B1ADDR_11 = B1ADDR; - - \$__ICE40_RAM4K #( - .READ_MODE(0), - .WRITE_MODE(0), - .NEGCLK_R(!CLKPOL2), - .NEGCLK_W(!CLKPOL3), - .INIT_0(INIT[ 0*256 +: 256]), - .INIT_1(INIT[ 1*256 +: 256]), - .INIT_2(INIT[ 2*256 +: 256]), - .INIT_3(INIT[ 3*256 +: 256]), - .INIT_4(INIT[ 4*256 +: 256]), - .INIT_5(INIT[ 5*256 +: 256]), - .INIT_6(INIT[ 6*256 +: 256]), - .INIT_7(INIT[ 7*256 +: 256]), - .INIT_8(INIT[ 8*256 +: 256]), - .INIT_9(INIT[ 9*256 +: 256]), - .INIT_A(INIT[10*256 +: 256]), - .INIT_B(INIT[11*256 +: 256]), - .INIT_C(INIT[12*256 +: 256]), - .INIT_D(INIT[13*256 +: 256]), - .INIT_E(INIT[14*256 +: 256]), - .INIT_F(INIT[15*256 +: 256]) - ) _TECHMAP_REPLACE_ ( - .RDATA(A1DATA), - .RADDR(A1ADDR_11), - .RCLK(CLK2), - .RCLKE(A1EN), - .RE(1'b1), - .WDATA(B1DATA), - .WADDR(B1ADDR_11), - .MASK(~B1EN), - .WCLK(CLK3), - .WCLKE(|B1EN), - .WE(1'b1) - ); -endmodule - -module \$__ICE40_RAM4K_M123 (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN); - parameter CFG_ABITS = 9; - parameter CFG_DBITS = 8; - - parameter [0:0] CLKPOL2 = 1; - parameter [0:0] CLKPOL3 = 1; - - parameter [4095:0] INIT = 4096'bx; - - localparam MODE = - CFG_ABITS == 9 ? 1 : - CFG_ABITS == 10 ? 2 : - CFG_ABITS == 11 ? 3 : 'bx; - - 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 B1EN; - - wire [10:0] A1ADDR_11 = A1ADDR; - wire [10:0] B1ADDR_11 = B1ADDR; - - wire [15:0] A1DATA_16, B1DATA_16; - -`define INSTANCE \ - \$__ICE40_RAM4K #( \ - .READ_MODE(MODE), \ - .WRITE_MODE(MODE), \ - .NEGCLK_R(!CLKPOL2), \ - .NEGCLK_W(!CLKPOL3), \ - .INIT_0(INIT_0), \ - .INIT_1(INIT_1), \ - .INIT_2(INIT_2), \ - .INIT_3(INIT_3), \ - .INIT_4(INIT_4), \ - .INIT_5(INIT_5), \ - .INIT_6(INIT_6), \ - .INIT_7(INIT_7), \ - .INIT_8(INIT_8), \ - .INIT_9(INIT_9), \ - .INIT_A(INIT_A), \ - .INIT_B(INIT_B), \ - .INIT_C(INIT_C), \ - .INIT_D(INIT_D), \ - .INIT_E(INIT_E), \ - .INIT_F(INIT_F) \ +module $__ICE40_RAM4K_ (...); + +parameter INIT = 0; +parameter OPTION_HAS_BE = 1; +parameter PORT_R_WIDTH = 16; +parameter PORT_W_WIDTH = 16; +parameter PORT_W_WR_BE_WIDTH = 16; +parameter PORT_R_CLK_POL = 1; +parameter PORT_W_CLK_POL = 1; + +input PORT_R_CLK; +input PORT_R_RD_EN; +input [10:0] PORT_R_ADDR; +output [PORT_R_WIDTH-1:0] PORT_R_RD_DATA; + +input PORT_W_CLK; +input PORT_W_WR_EN; +input [15:0] PORT_W_WR_BE; +input [10:0] PORT_W_ADDR; +input [PORT_W_WIDTH-1:0] PORT_W_WR_DATA; + +wire [15:0] RDATA; +wire [15:0] WDATA; +wire [15:0] MASK; +wire [10:0] RADDR = {PORT_R_ADDR[0], PORT_R_ADDR[1], PORT_R_ADDR[2], PORT_R_ADDR[10:3]}; +wire [10:0] WADDR = {PORT_W_ADDR[0], PORT_W_ADDR[1], PORT_W_ADDR[2], PORT_W_ADDR[10:3]}; + +function [1:0] mode; + input integer width; + case (width) + 16: mode = 0; + 8: mode = 1; + 4: mode = 2; + 2: mode = 3; + endcase +endfunction + +function [255:0] slice_init; + input [3:0] idx; + integer i; + reg [7:0] ri; + reg [11:0] a; + for (i = 0; i < 256; i = i + 1) begin + ri = i; + a = {idx, ri[7:4], ri[0], ri[1], ri[2], ri[3]}; + slice_init[i] = INIT[a]; + end +endfunction + +`define INSTANCE(type, rclk, wclk) \ + type #( \ + .INIT_0(slice_init(0)), \ + .INIT_1(slice_init(1)), \ + .INIT_2(slice_init(2)), \ + .INIT_3(slice_init(3)), \ + .INIT_4(slice_init(4)), \ + .INIT_5(slice_init(5)), \ + .INIT_6(slice_init(6)), \ + .INIT_7(slice_init(7)), \ + .INIT_8(slice_init(8)), \ + .INIT_9(slice_init(9)), \ + .INIT_A(slice_init(10)), \ + .INIT_B(slice_init(11)), \ + .INIT_C(slice_init(12)), \ + .INIT_D(slice_init(13)), \ + .INIT_E(slice_init(14)), \ + .INIT_F(slice_init(15)), \ + .READ_MODE(mode(PORT_R_WIDTH)), \ + .WRITE_MODE(mode(PORT_W_WIDTH)) \ ) _TECHMAP_REPLACE_ ( \ - .RDATA(A1DATA_16), \ - .RADDR(A1ADDR_11), \ - .RCLK(CLK2), \ - .RCLKE(A1EN), \ + .RDATA(RDATA), \ + .rclk(PORT_R_CLK), \ + .RCLKE(PORT_R_RD_EN), \ .RE(1'b1), \ - .WDATA(B1DATA_16), \ - .WADDR(B1ADDR_11), \ - .WCLK(CLK3), \ - .WCLKE(|B1EN), \ - .WE(1'b1) \ + .RADDR(RADDR), \ + .WDATA(WDATA), \ + .wclk(PORT_W_CLK), \ + .WCLKE(PORT_W_WR_EN), \ + .WE(1'b1), \ + .WADDR(WADDR), \ + .MASK(MASK), \ ); - generate - if (MODE == 1) begin - assign A1DATA = {A1DATA_16[14], A1DATA_16[12], A1DATA_16[10], A1DATA_16[ 8], - A1DATA_16[ 6], A1DATA_16[ 4], A1DATA_16[ 2], A1DATA_16[ 0]}; - assign {B1DATA_16[14], B1DATA_16[12], B1DATA_16[10], B1DATA_16[ 8], - B1DATA_16[ 6], B1DATA_16[ 4], B1DATA_16[ 2], B1DATA_16[ 0]} = B1DATA; - `include "brams_init1.vh" - `INSTANCE - end - if (MODE == 2) begin - assign A1DATA = {A1DATA_16[13], A1DATA_16[9], A1DATA_16[5], A1DATA_16[1]}; - assign {B1DATA_16[13], B1DATA_16[9], B1DATA_16[5], B1DATA_16[1]} = B1DATA; - `include "brams_init2.vh" - `INSTANCE - end - if (MODE == 3) begin - assign A1DATA = {A1DATA_16[11], A1DATA_16[3]}; - assign {B1DATA_16[11], B1DATA_16[3]} = B1DATA; - `include "brams_init3.vh" - `INSTANCE - end - endgenerate - -`undef INSTANCE +generate + +case(PORT_R_WIDTH) + 2: begin + assign PORT_R_RD_DATA = { + RDATA[11], + RDATA[3] + }; + end + 4: begin + assign PORT_R_RD_DATA = { + RDATA[13], + RDATA[5], + RDATA[9], + RDATA[1] + }; + end + 8: begin + assign PORT_R_RD_DATA = { + RDATA[14], + RDATA[6], + RDATA[10], + RDATA[2], + RDATA[12], + RDATA[4], + RDATA[8], + RDATA[0] + }; + end + 16: begin + assign PORT_R_RD_DATA = { + RDATA[15], + RDATA[7], + RDATA[11], + RDATA[3], + RDATA[13], + RDATA[5], + RDATA[9], + RDATA[1], + RDATA[14], + RDATA[6], + RDATA[10], + RDATA[2], + RDATA[12], + RDATA[4], + RDATA[8], + RDATA[0] + }; + end +endcase + +case(PORT_W_WIDTH) + 2: begin + assign { + WDATA[11], + WDATA[3] + } = PORT_W_WR_DATA; + end + 4: begin + assign { + WDATA[13], + WDATA[5], + WDATA[9], + WDATA[1] + } = PORT_W_WR_DATA; + end + 8: begin + assign { + WDATA[14], + WDATA[6], + WDATA[10], + WDATA[2], + WDATA[12], + WDATA[4], + WDATA[8], + WDATA[0] + } = PORT_W_WR_DATA; + end + 16: begin + assign WDATA = { + PORT_W_WR_DATA[15], + PORT_W_WR_DATA[7], + PORT_W_WR_DATA[11], + PORT_W_WR_DATA[3], + PORT_W_WR_DATA[13], + PORT_W_WR_DATA[5], + PORT_W_WR_DATA[9], + PORT_W_WR_DATA[1], + PORT_W_WR_DATA[14], + PORT_W_WR_DATA[6], + PORT_W_WR_DATA[10], + PORT_W_WR_DATA[2], + PORT_W_WR_DATA[12], + PORT_W_WR_DATA[4], + PORT_W_WR_DATA[8], + PORT_W_WR_DATA[0] + }; + assign MASK = ~{ + PORT_W_WR_BE[15], + PORT_W_WR_BE[7], + PORT_W_WR_BE[11], + PORT_W_WR_BE[3], + PORT_W_WR_BE[13], + PORT_W_WR_BE[5], + PORT_W_WR_BE[9], + PORT_W_WR_BE[1], + PORT_W_WR_BE[14], + PORT_W_WR_BE[6], + PORT_W_WR_BE[10], + PORT_W_WR_BE[2], + PORT_W_WR_BE[12], + PORT_W_WR_BE[4], + PORT_W_WR_BE[8], + PORT_W_WR_BE[0] + }; + end +endcase + +if (PORT_R_CLK_POL) begin + if (PORT_W_CLK_POL) begin + `INSTANCE(SB_RAM40_4K, RCLK, WCLK) + end else begin + `INSTANCE(SB_RAM40_4KNW, RCLK, WCLKN) + end +end else begin + if (PORT_W_CLK_POL) begin + `INSTANCE(SB_RAM40_4KNR, RCLKN, WCLK) + end else begin + `INSTANCE(SB_RAM40_4KNRNW, RCLKN, WCLKN) + end +end + +endgenerate endmodule - diff --git a/techlibs/ice40/cells_sim.v b/techlibs/ice40/cells_sim.v index f33e92488..2e1c6807a 100644 --- a/techlibs/ice40/cells_sim.v +++ b/techlibs/ice40/cells_sim.v @@ -1,6 +1,6 @@ `timescale 1ps / 1ps -`define SB_DFF_REG reg Q = 0 -// `define SB_DFF_REG reg Q +`define SB_DFF_INIT initial Q = 0; +// `define SB_DFF_INIT `ifndef NO_ICE40_DEFAULT_ASSIGNMENTS `define ICE40_DEFAULT_ASSIGNMENT_V(v) = v @@ -263,9 +263,11 @@ endmodule (* abc9_flop, lib_whitebox *) module SB_DFF ( - output `SB_DFF_REG, + output reg Q, input C, D ); + `SB_DFF_INIT + always @(posedge C) Q <= D; `ifdef ICE40_HX @@ -299,9 +301,11 @@ endmodule (* abc9_flop, lib_whitebox *) module SB_DFFE ( - output `SB_DFF_REG, + output reg Q, input C, E `ICE40_DEFAULT_ASSIGNMENT_1, D ); + `SB_DFF_INIT + always @(posedge C) if (E) Q <= D; @@ -342,9 +346,11 @@ endmodule (* abc9_flop, lib_whitebox *) module SB_DFFSR ( - output `SB_DFF_REG, + output reg Q, input C, R, D ); + `SB_DFF_INIT + always @(posedge C) if (R) Q <= 0; @@ -390,9 +396,11 @@ endmodule (* abc9_box, lib_whitebox *) module SB_DFFR ( - output `SB_DFF_REG, + output reg Q, input C, R, D ); + `SB_DFF_INIT + always @(posedge C, posedge R) if (R) Q <= 0; @@ -459,9 +467,11 @@ endmodule (* abc9_flop, lib_whitebox *) module SB_DFFSS ( - output `SB_DFF_REG, + output reg Q, input C, S, D ); + `SB_DFF_INIT + always @(posedge C) if (S) Q <= 1; @@ -507,9 +517,11 @@ endmodule (* abc9_box, lib_whitebox *) module SB_DFFS ( - output `SB_DFF_REG, + output reg Q, input C, S, D ); + `SB_DFF_INIT + always @(posedge C, posedge S) if (S) Q <= 1; @@ -576,9 +588,11 @@ endmodule (* abc9_flop, lib_whitebox *) module SB_DFFESR ( - output `SB_DFF_REG, + output reg Q, input C, E `ICE40_DEFAULT_ASSIGNMENT_1, R, D ); + `SB_DFF_INIT + always @(posedge C) if (E) begin if (R) @@ -632,9 +646,11 @@ endmodule (* abc9_box, lib_whitebox *) module SB_DFFER ( - output `SB_DFF_REG, + output reg Q, input C, E `ICE40_DEFAULT_ASSIGNMENT_1, R, D ); + `SB_DFF_INIT + always @(posedge C, posedge R) if (R) Q <= 0; @@ -707,9 +723,11 @@ endmodule (* abc9_flop, lib_whitebox *) module SB_DFFESS ( - output `SB_DFF_REG, + output reg Q, input C, E `ICE40_DEFAULT_ASSIGNMENT_1, S, D ); + `SB_DFF_INIT + always @(posedge C) if (E) begin if (S) @@ -763,9 +781,11 @@ endmodule (* abc9_box, lib_whitebox *) module SB_DFFES ( - output `SB_DFF_REG, + output reg Q, input C, E `ICE40_DEFAULT_ASSIGNMENT_1, S, D ); + `SB_DFF_INIT + always @(posedge C, posedge S) if (S) Q <= 1; @@ -840,9 +860,11 @@ endmodule (* abc9_flop, lib_whitebox *) module SB_DFFN ( - output `SB_DFF_REG, + output reg Q, input C, D ); + `SB_DFF_INIT + always @(negedge C) Q <= D; `ifdef ICE40_HX @@ -876,9 +898,11 @@ endmodule (* abc9_flop, lib_whitebox *) module SB_DFFNE ( - output `SB_DFF_REG, + output reg Q, input C, E `ICE40_DEFAULT_ASSIGNMENT_1, D ); + `SB_DFF_INIT + always @(negedge C) if (E) Q <= D; @@ -919,9 +943,11 @@ endmodule (* abc9_flop, lib_whitebox *) module SB_DFFNSR ( - output `SB_DFF_REG, + output reg Q, input C, R, D ); + `SB_DFF_INIT + always @(negedge C) if (R) Q <= 0; @@ -967,9 +993,11 @@ endmodule (* abc9_flop, lib_whitebox *) module SB_DFFNR ( - output `SB_DFF_REG, + output reg Q, input C, R, D ); + `SB_DFF_INIT + always @(negedge C, posedge R) if (R) Q <= 0; @@ -1036,9 +1064,11 @@ endmodule (* abc9_flop, lib_whitebox *) module SB_DFFNSS ( - output `SB_DFF_REG, + output reg Q, input C, S, D ); + `SB_DFF_INIT + always @(negedge C) if (S) Q <= 1; @@ -1084,9 +1114,11 @@ endmodule (* abc9_box, lib_whitebox *) module SB_DFFNS ( - output `SB_DFF_REG, + output reg Q, input C, S, D ); + `SB_DFF_INIT + always @(negedge C, posedge S) if (S) Q <= 1; @@ -1153,9 +1185,11 @@ endmodule (* abc9_flop, lib_whitebox *) module SB_DFFNESR ( - output `SB_DFF_REG, + output reg Q, input C, E `ICE40_DEFAULT_ASSIGNMENT_1, R, D ); + `SB_DFF_INIT + always @(negedge C) if (E) begin if (R) @@ -1209,9 +1243,11 @@ endmodule (* abc9_box, lib_whitebox *) module SB_DFFNER ( - output `SB_DFF_REG, + output reg Q, input C, E `ICE40_DEFAULT_ASSIGNMENT_1, R, D ); + `SB_DFF_INIT + always @(negedge C, posedge R) if (R) Q <= 0; @@ -1284,9 +1320,11 @@ endmodule (* abc9_flop, lib_whitebox *) module SB_DFFNESS ( - output `SB_DFF_REG, + output reg Q, input C, E `ICE40_DEFAULT_ASSIGNMENT_1, S, D ); + `SB_DFF_INIT + always @(negedge C) if (E) begin if (S) @@ -1340,9 +1378,11 @@ endmodule (* abc9_box, lib_whitebox *) module SB_DFFNES ( - output `SB_DFF_REG, + output reg Q, input C, E `ICE40_DEFAULT_ASSIGNMENT_1, S, D ); + `SB_DFF_INIT + always @(negedge C, posedge S) if (S) Q <= 1; diff --git a/techlibs/ice40/spram.txt b/techlibs/ice40/spram.txt new file mode 100644 index 000000000..ed0699f7d --- /dev/null +++ b/techlibs/ice40/spram.txt @@ -0,0 +1,12 @@ +ram huge $__ICE40_SPRAM_ { + abits 14; + width 16; + cost 2048; + byte 4; + port srsw "A" { + clock posedge; + clken; + wrbe_separate; + rdwr no_change; + } +} diff --git a/techlibs/ice40/spram_map.v b/techlibs/ice40/spram_map.v new file mode 100644 index 000000000..ae8919505 --- /dev/null +++ b/techlibs/ice40/spram_map.v @@ -0,0 +1,24 @@ +module $__ICE40_SPRAM_ (...); + +input PORT_A_CLK; +input PORT_A_CLK_EN; +input PORT_A_WR_EN; +input [3:0] PORT_A_WR_BE; +input [13:0] PORT_A_ADDR; +input [15:0] PORT_A_WR_DATA; +output [15:0] PORT_A_RD_DATA; + +SB_SPRAM256KA _TECHMAP_REPLACE_ ( + .ADDRESS(PORT_A_ADDR), + .DATAIN(PORT_A_WR_DATA), + .MASKWREN(PORT_A_WR_BE), + .WREN(PORT_A_WR_EN), + .CHIPSELECT(PORT_A_CLK_EN), + .CLOCK(PORT_A_CLK), + .STANDBY(1'b0), + .SLEEP(1'b0), + .POWEROFF(1'b1), + .DATAOUT(PORT_A_RD_DATA), +); + +endmodule diff --git a/techlibs/ice40/synth_ice40.cc b/techlibs/ice40/synth_ice40.cc index 421ec3b4e..c10b7003e 100644 --- a/techlibs/ice40/synth_ice40.cc +++ b/techlibs/ice40/synth_ice40.cc @@ -90,6 +90,9 @@ struct SynthIce40Pass : public ScriptPass log(" -nobram\n"); log(" do not use SB_RAM40_4K* cells in output netlist\n"); log("\n"); + log(" -spram\n"); + log(" enable automatic inference of SB_SPRAM256KA\n"); + log("\n"); log(" -dsp\n"); log(" use iCE40 UltraPlus DSP cells for large arithmetic\n"); log("\n"); @@ -116,7 +119,7 @@ struct SynthIce40Pass : public ScriptPass } string top_opt, blif_file, edif_file, json_file, device_opt; - bool nocarry, nodffe, nobram, dsp, flatten, retime, noabc, abc2, vpr, abc9, dff, flowmap; + bool nocarry, nodffe, nobram, spram, dsp, flatten, retime, noabc, abc2, vpr, abc9, dff, flowmap; int min_ce_use; void clear_flags() override @@ -129,6 +132,7 @@ struct SynthIce40Pass : public ScriptPass nodffe = false; min_ce_use = -1; nobram = false; + spram = false; dsp = false; flatten = true; retime = false; @@ -204,6 +208,10 @@ struct SynthIce40Pass : public ScriptPass nobram = true; continue; } + if (args[argidx] == "-spram") { + spram = true; + continue; + } if (args[argidx] == "-dsp") { dsp = true; continue; @@ -322,19 +330,24 @@ struct SynthIce40Pass : public ScriptPass run("opt_clean"); } - if (!nobram && check_label("map_bram", "(skip if -nobram)")) + if (check_label("map_ram")) { - run("memory_bram -rules +/ice40/brams.txt"); - run("techmap -map +/ice40/brams_map.v"); + std::string args = ""; + if (!spram) + args += " -no-auto-huge"; + if (nobram) + args += " -no-auto-block"; + if (help_mode) + args += " [-no-auto-huge] [-no-auto-block]"; + run("memory_libmap -lib +/ice40/brams.txt -lib +/ice40/spram.txt" + args, "(-no-auto-huge unless -spram, -no-auto-block if -nobram)"); + run("techmap -map +/ice40/brams_map.v -map +/ice40/spram_map.v"); run("ice40_braminit"); } if (check_label("map_ffram")) { run("opt -fast -mux_undef -undriven -fine"); - run("memory_map -iattr -attr !ram_block -attr !rom_block -attr logic_block " - "-attr syn_ramstyle=auto -attr syn_ramstyle=registers " - "-attr syn_romstyle=auto -attr syn_romstyle=logic"); + run("memory_map"); run("opt -undriven -fine"); } diff --git a/techlibs/intel_alm/Makefile.inc b/techlibs/intel_alm/Makefile.inc index 614d5802c..b5f279a92 100644 --- a/techlibs/intel_alm/Makefile.inc +++ b/techlibs/intel_alm/Makefile.inc @@ -19,6 +19,7 @@ $(eval $(call add_share_file,share/intel_alm/cyclonev,techlibs/intel_alm/cyclone # RAM $(eval $(call add_share_file,share/intel_alm/common,techlibs/intel_alm/common/bram_m10k.txt)) +$(eval $(call add_share_file,share/intel_alm/common,techlibs/intel_alm/common/bram_m10k_map.v)) $(eval $(call add_share_file,share/intel_alm/common,techlibs/intel_alm/common/bram_m20k.txt)) $(eval $(call add_share_file,share/intel_alm/common,techlibs/intel_alm/common/bram_m20k_map.v)) $(eval $(call add_share_file,share/intel_alm/common,techlibs/intel_alm/common/lutram_mlab.txt)) diff --git a/techlibs/intel_alm/common/alm_sim.v b/techlibs/intel_alm/common/alm_sim.v index 6e70be865..242f1003f 100644 --- a/techlibs/intel_alm/common/alm_sim.v +++ b/techlibs/intel_alm/common/alm_sim.v @@ -77,6 +77,14 @@ // SUMOUT 368 1342 1323 887 927 - 785 - // CARRYOUT 71 1082 1062 866 813 - 1198 - +// Arria V LUT output timings (picoseconds): +// +// CARRY A B C D E F G +// COMBOUT - 387 375 316 317 - 76 319 (LUT6) +// COMBOUT - 387 375 316 317 218 76 319 (LUT7) +// SUMOUT 249 744 732 562 576 - 511 - +// CARRYOUT 19 629 623 530 514 - 696 - + (* abc9_lut=2, lib_whitebox *) module MISTRAL_ALUT6(input A, B, C, D, E, F, output Q); @@ -92,6 +100,16 @@ specify (F => Q) = 97; endspecify `endif +`ifdef arriav +specify + (A => Q) = 387; + (B => Q) = 375; + (C => Q) = 316; + (D => Q) = 317; + (E => Q) = 319; + (F => Q) = 76; +endspecify +`endif `ifdef cyclone10gx specify (A => Q) = 275; @@ -122,6 +140,15 @@ specify (E => Q) = 97; endspecify `endif +`ifdef arriav +specify + (A => Q) = 375; + (B => Q) = 316; + (C => Q) = 317; + (D => Q) = 319; + (E => Q) = 76; +endspecify +`endif `ifdef cyclone10gx specify (A => Q) = 272; @@ -150,6 +177,14 @@ specify (D => Q) = 97; endspecify `endif +`ifdef arriav +specify + (A => Q) = 316; + (B => Q) = 317; + (C => Q) = 319; + (D => Q) = 76; +endspecify +`endif `ifdef cyclone10gx specify (A => Q) = 175; @@ -176,6 +211,13 @@ specify (C => Q) = 97; endspecify `endif +`ifdef arriav +specify + (A => Q) = 316; + (B => Q) = 317; + (C => Q) = 76; +endspecify +`endif `ifdef cyclone10gx specify (A => Q) = 165; @@ -200,6 +242,12 @@ specify (B => Q) = 97; endspecify `endif +`ifdef arriav +specify + (A => Q) = 316; + (B => Q) = 76; +endspecify +`endif `ifdef cyclone10gx specify (A => Q) = 162; @@ -220,6 +268,11 @@ specify (A => Q) = 97; endspecify `endif +`ifdef arriav +specify + (A => Q) = 76; +endspecify +`endif `ifdef cyclone10gx specify (A => Q) = 53; @@ -255,6 +308,23 @@ specify (CI => CO) = 36; // Divided by 2 to account for there being two ALUT_ARITHs in an ALM) endspecify `endif +`ifdef arriav +specify + (A => SO) = 744; + (B => SO) = 732; + (C => SO) = 562; + (D0 => SO) = 576; + (D1 => SO) = 511; + (CI => SO) = 249; + + (A => CO) = 629; + (B => CO) = 623; + (C => CO) = 530; + (D0 => CO) = 514; + (D1 => CO) = 696; + (CI => CO) = 10; // Divided by 2 to account for there being two ALUT_ARITHs in an ALM) +endspecify +`endif `ifdef cyclone10gx specify (A => SO) = 644; diff --git a/techlibs/intel_alm/common/bram_m10k.txt b/techlibs/intel_alm/common/bram_m10k.txt index e9355fe2c..560711b65 100644 --- a/techlibs/intel_alm/common/bram_m10k.txt +++ b/techlibs/intel_alm/common/bram_m10k.txt @@ -1,21 +1,15 @@ -bram MISTRAL_M10K +bram $__MISTRAL_M10K init 0 # TODO: Re-enable when I figure out how BRAM init works abits 13 @D8192x1 dbits 1 @D8192x1 abits 12 @D4096x2 dbits 2 @D4096x2 - abits 11 @D2048x4 @D2048x5 - dbits 4 @D2048x4 + abits 11 @D2048x5 dbits 5 @D2048x5 - abits 10 @D1024x8 @D1024x10 - dbits 8 @D1024x8 + abits 10 @D1024x10 dbits 10 @D1024x10 - abits 9 @D512x16 @D512x20 - dbits 16 @D512x16 + abits 9 @D512x20 dbits 20 @D512x20 - abits 8 @D256x32 @D256x40 - dbits 32 @D256x32 - dbits 40 @D256x40 groups 2 ports 1 1 wrmode 1 0 @@ -27,7 +21,7 @@ bram MISTRAL_M10K endbram -match MISTRAL_M10K +match $__MISTRAL_M10K min efficiency 5 make_transp endmatch diff --git a/techlibs/intel_alm/common/bram_m10k_map.v b/techlibs/intel_alm/common/bram_m10k_map.v new file mode 100644 index 000000000..8f9d4a3b3 --- /dev/null +++ b/techlibs/intel_alm/common/bram_m10k_map.v @@ -0,0 +1,16 @@ +// Stub to invert M10K write-enable. + +module \$__MISTRAL_M10K (CLK1, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN); + +parameter CFG_ABITS = 10; +parameter CFG_DBITS = 10; + +input CLK1; +input [CFG_ABITS-1:0] A1ADDR, B1ADDR; +input [CFG_DBITS-1:0] A1DATA; +input A1EN, B1EN; +output reg [CFG_DBITS-1:0] B1DATA; + +MISTRAL_M10K #(.CFG_ABITS(CFG_ABITS), .CFG_DBITS(CFG_DBITS)) _TECHMAP_REPLACE_ (.CLK1(CLK1), .A1ADDR(A1ADDR), .A1DATA(A1DATA), .A1EN(!A1EN), .B1ADDR(B1ADDR), .B1DATA(B1DATA), .B1EN(B1EN)); + +endmodule
\ No newline at end of file diff --git a/techlibs/intel_alm/common/dff_sim.v b/techlibs/intel_alm/common/dff_sim.v index 6bee994be..8d58bf614 100644 --- a/techlibs/intel_alm/common/dff_sim.v +++ b/techlibs/intel_alm/common/dff_sim.v @@ -77,6 +77,21 @@ specify if (ACLR === 1'b0) (ACLR => Q) = 282; endspecify `endif +`ifdef arriav +specify + if (ENA && ACLR !== 1'b0 && !SCLR && !SLOAD) (posedge CLK => (Q : DATAIN)) = 470; + if (ENA && SCLR) (posedge CLK => (Q : 1'b0)) = 633; + if (ENA && !SCLR && SLOAD) (posedge CLK => (Q : SDATA)) = 439; + + $setup(DATAIN, posedge CLK, /* -170 */ 0); + $setup(ENA, posedge CLK, /* -170 */ 0); + $setup(SCLR, posedge CLK, /* -170 */ 0); + $setup(SLOAD, posedge CLK, /* -170 */ 0); + $setup(SDATA, posedge CLK, /* -170 */ 0); + + if (ACLR === 1'b0) (ACLR => Q) = 215; +endspecify +`endif `ifdef cyclone10gx specify // TODO (long-term): investigate these numbers. diff --git a/techlibs/intel_alm/common/dsp_sim.v b/techlibs/intel_alm/common/dsp_sim.v index bdb6d18d5..3d4b5590b 100644 --- a/techlibs/intel_alm/common/dsp_sim.v +++ b/techlibs/intel_alm/common/dsp_sim.v @@ -1,14 +1,31 @@ +`default_nettype none + (* abc9_box *) module MISTRAL_MUL27X27(input [26:0] A, input [26:0] B, output [53:0] Y); parameter A_SIGNED = 1; parameter B_SIGNED = 1; +`ifdef cyclonev +specify + (A *> Y) = 3732; + (B *> Y) = 3928; +endspecify +`endif +`ifdef arriav +// NOTE: Arria V appears to have only one set of timings for all DSP modes... +specify + (A *> Y) = 1895; + (B *> Y) = 2053; +endspecify +`endif +`ifdef cyclone10gx // TODO: Cyclone 10 GX timings; the below are for Cyclone V specify (A *> Y) = 3732; (B *> Y) = 3928; endspecify +`endif wire [53:0] A_, B_; @@ -32,11 +49,26 @@ module MISTRAL_MUL18X18(input [17:0] A, input [17:0] B, output [35:0] Y); parameter A_SIGNED = 1; parameter B_SIGNED = 1; +`ifdef cyclonev +specify + (A *> Y) = 3180; + (B *> Y) = 3982; +endspecify +`endif +`ifdef arriav +// NOTE: Arria V appears to have only one set of timings for all DSP modes... +specify + (A *> Y) = 1895; + (B *> Y) = 2053; +endspecify +`endif +`ifdef cyclone10gx // TODO: Cyclone 10 GX timings; the below are for Cyclone V specify (A *> Y) = 3180; (B *> Y) = 3982; endspecify +`endif wire [35:0] A_, B_; @@ -60,11 +92,26 @@ module MISTRAL_MUL9X9(input [8:0] A, input [8:0] B, output [17:0] Y); parameter A_SIGNED = 1; parameter B_SIGNED = 1; +`ifdef cyclonev +specify + (A *> Y) = 2818; + (B *> Y) = 3051; +endspecify +`endif +`ifdef arriav +// NOTE: Arria V appears to have only one set of timings for all DSP modes... +specify + (A *> Y) = 1895; + (B *> Y) = 2053; +endspecify +`endif +`ifdef cyclone10gx // TODO: Cyclone 10 GX timings; the below are for Cyclone V specify (A *> Y) = 2818; (B *> Y) = 3051; endspecify +`endif wire [17:0] A_, B_; diff --git a/techlibs/intel_alm/common/megafunction_bb.v b/techlibs/intel_alm/common/megafunction_bb.v index 414d1c941..d4ed95173 100644 --- a/techlibs/intel_alm/common/megafunction_bb.v +++ b/techlibs/intel_alm/common/megafunction_bb.v @@ -697,3 +697,21 @@ output outclk; endmodule +// Internal interfaces +(* keep *) +module cyclonev_oscillator(oscena, clkout, clkout1); + +input oscena; +output clkout; +output clkout1; + +endmodule + +// HPS interfaces +(* keep *) +module cyclonev_hps_interface_mpu_general_purpose(gp_in, gp_out); + +input [31:0] gp_in; +output [31:0] gp_out; + +endmodule diff --git a/techlibs/intel_alm/common/mem_sim.v b/techlibs/intel_alm/common/mem_sim.v index dbdf69839..c9ba8c7f1 100644 --- a/techlibs/intel_alm/common/mem_sim.v +++ b/techlibs/intel_alm/common/mem_sim.v @@ -56,6 +56,33 @@ module MISTRAL_MLAB(input [4:0] A1ADDR, input A1DATA, A1EN, reg [31:0] mem = 32'b0; +`ifdef cyclonev +specify + $setup(A1ADDR, posedge CLK1, 86); + $setup(A1DATA, posedge CLK1, 86); + $setup(A1EN, posedge CLK1, 86); + + (B1ADDR[0] => B1DATA) = 487; + (B1ADDR[1] => B1DATA) = 475; + (B1ADDR[2] => B1DATA) = 382; + (B1ADDR[3] => B1DATA) = 284; + (B1ADDR[4] => B1DATA) = 96; +endspecify +`endif +`ifdef arriav +specify + $setup(A1ADDR, posedge CLK1, 62); + $setup(A1DATA, posedge CLK1, 62); + $setup(A1EN, posedge CLK1, 62); + + (B1ADDR[0] => B1DATA) = 370; + (B1ADDR[1] => B1DATA) = 292; + (B1ADDR[2] => B1DATA) = 218; + (B1ADDR[3] => B1DATA) = 74; + (B1ADDR[4] => B1DATA) = 177; +endspecify +`endif +`ifdef cyclone10gx // TODO: Cyclone 10 GX timings; the below timings are for Cyclone V specify $setup(A1ADDR, posedge CLK1, 86); @@ -68,6 +95,7 @@ specify (B1ADDR[3] => B1DATA) = 284; (B1ADDR[4] => B1DATA) = 96; endspecify +`endif always @(posedge CLK1) if (A1EN) mem[A1ADDR] <= A1DATA; @@ -93,15 +121,31 @@ output reg [CFG_DBITS-1:0] B1DATA; reg [2**CFG_ABITS * CFG_DBITS - 1 : 0] mem = 0; +`ifdef cyclonev +specify + $setup(A1ADDR, posedge CLK1, 125); + $setup(A1DATA, posedge CLK1, 97); + $setup(A1EN, posedge CLK1, 140); + $setup(B1ADDR, posedge CLK1, 125); + $setup(B1EN, posedge CLK1, 161); + + if (B1EN) (posedge CLK1 => (B1DATA : A1DATA)) = 1004; +endspecify +`endif +`ifdef arriav specify - $setup(A1ADDR, posedge CLK1, 0); - $setup(A1DATA, posedge CLK1, 0); + $setup(A1ADDR, posedge CLK1, 97); + $setup(A1DATA, posedge CLK1, 74); + $setup(A1EN, posedge CLK1, 109); + $setup(B1ADDR, posedge CLK1, 97); + $setup(B1EN, posedge CLK1, 126); - if (B1EN) (posedge CLK1 => (B1DATA : A1DATA)) = 0; + if (B1EN) (posedge CLK1 => (B1DATA : A1DATA)) = 787; endspecify +`endif always @(posedge CLK1) begin - if (A1EN) + if (!A1EN) mem[(A1ADDR + 1) * CFG_DBITS - 1 : A1ADDR * CFG_DBITS] <= A1DATA; if (B1EN) diff --git a/techlibs/intel_alm/common/quartus_rename.v b/techlibs/intel_alm/common/quartus_rename.v index 57321de77..217dc5de9 100644 --- a/techlibs/intel_alm/common/quartus_rename.v +++ b/techlibs/intel_alm/common/quartus_rename.v @@ -2,14 +2,25 @@ `define LCELL cyclonev_lcell_comb `define MAC cyclonev_mac `define MLAB cyclonev_mlab_cell +`define RAM_BLOCK cyclonev_ram_block `define IBUF cyclonev_io_ibuf `define OBUF cyclonev_io_obuf `define CLKENA cyclonev_clkena `endif +`ifdef arriav +`define LCELL arriav_lcell_comb +`define MAC arriav_mac +`define MLAB arriav_mlab_cell +`define RAM_BLOCK arriav_ram_block +`define IBUF arriav_io_ibuf +`define OBUF arriav_io_obuf +`define CLKENA arriav_clkena +`endif `ifdef cyclone10gx `define LCELL cyclone10gx_lcell_comb `define MAC cyclone10gx_mac `define MLAB cyclone10gx_mlab_cell +`define RAM_BLOCK cyclone10gx_ram_block `define IBUF cyclone10gx_io_ibuf `define OBUF cyclone10gx_io_obuf `define CLKENA cyclone10gx_clkena @@ -146,7 +157,12 @@ output [CFG_DBITS-1:0] B1DATA; // Much like the MLAB, the M10K has mem_init[01234] parameters which would let // you initialise the RAM cell via hex literals. If they were implemented. -cyclonev_ram_block #( +// Since the MISTRAL_M10K block has an inverted write-enable (like the real hardware) +// but the Quartus primitive expects a normal write-enable, we add an inverter. +wire A1EN_N; +NOT wren_inv (.IN(A1EN), .OUT(A1EN_N)); + +`RAM_BLOCK #( .operation_mode("dual_port"), .logical_ram_name(_TECHMAP_CELLNAME_), .port_a_address_width(CFG_ABITS), @@ -165,10 +181,10 @@ cyclonev_ram_block #( .port_b_first_bit_number(0), .port_b_address_clock("clock0"), .port_b_read_enable_clock("clock0") -) _TECHMAP_REPLACE_ ( +) ram_block ( .portaaddr(A1ADDR), .portadatain(A1DATA), - .portawe(A1EN), + .portawe(A1EN_N), .portbaddr(B1ADDR), .portbdataout(B1DATA), .portbre(B1EN), diff --git a/techlibs/intel_alm/synth_intel_alm.cc b/techlibs/intel_alm/synth_intel_alm.cc index 385fc26b6..43d3592d5 100644 --- a/techlibs/intel_alm/synth_intel_alm.cc +++ b/techlibs/intel_alm/synth_intel_alm.cc @@ -43,6 +43,7 @@ struct SynthIntelALMPass : public ScriptPass { log(" -family <family>\n"); log(" target one of:\n"); log(" \"cyclonev\" - Cyclone V (default)\n"); + log(" \"arriav\" - Arria V (non-GZ)"); log(" \"cyclone10gx\" - Cyclone 10GX\n"); log("\n"); log(" -vqm <file>\n"); @@ -169,10 +170,14 @@ struct SynthIntelALMPass : public ScriptPass { if (!design->full_selection()) log_cmd_error("This command only operates on fully selected designs!\n"); - if (family_opt == "cyclonev") { + if (family_opt == "cyclonev" || family_opt == "arriav") { bram_type = "m10k"; } else if (family_opt == "cyclone10gx") { bram_type = "m20k"; + } else if (family_opt == "arriva") { + // I have typoed "arriav" as "arriva" (a local bus company) + // so many times I thought it would be funny to have an easter egg. + log_cmd_error("synth_intel_alm cannot synthesize for bus companies. (did you mean '-family arriav'?)\n"); } else { log_cmd_error("Invalid family specified: '%s'\n", family_opt.c_str()); } @@ -229,12 +234,12 @@ struct SynthIntelALMPass : public ScriptPass { if (help_mode) { run("techmap -map +/mul2dsp.v [...]", "(unless -nodsp)"); } else if (!nodsp) { - // Cyclone V supports 9x9 multiplication, Cyclone 10 GX does not. + // Cyclone V/Arria V supports 9x9 multiplication, Cyclone 10 GX does not. run("techmap -map +/mul2dsp.v -D DSP_A_MAXWIDTH=27 -D DSP_B_MAXWIDTH=27 -D DSP_A_MINWIDTH=19 -D DSP_B_MINWIDTH=4 -D DSP_NAME=__MUL27X27"); run("chtype -set $mul t:$__soft_mul"); run("techmap -map +/mul2dsp.v -D DSP_A_MAXWIDTH=27 -D DSP_B_MAXWIDTH=27 -D DSP_A_MINWIDTH=4 -D DSP_B_MINWIDTH=19 -D DSP_NAME=__MUL27X27"); run("chtype -set $mul t:$__soft_mul"); - if (family_opt == "cyclonev") { + if (family_opt == "cyclonev" || family_opt == "arriav") { run("techmap -map +/mul2dsp.v -D DSP_A_MAXWIDTH=18 -D DSP_B_MAXWIDTH=18 -D DSP_A_MINWIDTH=10 -D DSP_B_MINWIDTH=4 -D DSP_NAME=__MUL18X18"); run("chtype -set $mul t:$__soft_mul"); run("techmap -map +/mul2dsp.v -D DSP_A_MAXWIDTH=18 -D DSP_B_MAXWIDTH=18 -D DSP_A_MINWIDTH=4 -D DSP_B_MINWIDTH=10 -D DSP_NAME=__MUL18X18"); @@ -257,8 +262,7 @@ struct SynthIntelALMPass : public ScriptPass { if (!nobram && check_label("map_bram", "(skip if -nobram)")) { run(stringf("memory_bram -rules +/intel_alm/common/bram_%s.txt", bram_type.c_str())); - if (help_mode || bram_type != "m10k") - run(stringf("techmap -map +/intel_alm/common/bram_%s_map.v", bram_type.c_str())); + run(stringf("techmap -map +/intel_alm/common/bram_%s_map.v", bram_type.c_str())); } if (!nolutram && check_label("map_lutram", "(skip if -nolutram)")) { diff --git a/techlibs/machxo2/Makefile.inc b/techlibs/machxo2/Makefile.inc index 6f6f6ce94..f6aafbd2b 100644 --- a/techlibs/machxo2/Makefile.inc +++ b/techlibs/machxo2/Makefile.inc @@ -3,3 +3,8 @@ OBJS += techlibs/machxo2/synth_machxo2.o $(eval $(call add_share_file,share/machxo2,techlibs/machxo2/cells_map.v)) $(eval $(call add_share_file,share/machxo2,techlibs/machxo2/cells_sim.v)) + +$(eval $(call add_share_file,share/machxo2,techlibs/machxo2/lutrams.txt)) +$(eval $(call add_share_file,share/machxo2,techlibs/machxo2/lutrams_map.v)) +$(eval $(call add_share_file,share/machxo2,techlibs/machxo2/brams.txt)) +$(eval $(call add_share_file,share/machxo2,techlibs/machxo2/brams_map.v)) diff --git a/techlibs/machxo2/brams.txt b/techlibs/machxo2/brams.txt new file mode 100644 index 000000000..3afbeda07 --- /dev/null +++ b/techlibs/machxo2/brams.txt @@ -0,0 +1,50 @@ +ram block $__DP8KC_ { + abits 13; + widths 1 2 4 9 per_port; + cost 64; + init no_undef; + port srsw "A" "B" { + clock posedge; + clken; + portoption "WRITEMODE" "NORMAL" { + rdwr no_change; + } + portoption "WRITEMODE" "WRITETHROUGH" { + rdwr new; + } + portoption "WRITEMODE" "READBEFOREWRITE" { + rdwr old; + } + option "RESETMODE" "SYNC" { + rdsrst zero ungated block_wr; + } + option "RESETMODE" "ASYNC" { + rdarst zero; + } + rdinit zero; + } +} + +ram block $__PDPW8KC_ { + abits 13; + widths 1 2 4 9 18 per_port; + byte 9; + cost 64; + init no_undef; + port sr "R" { + clock posedge; + clken; + option "RESETMODE" "SYNC" { + rdsrst zero ungated; + } + option "RESETMODE" "ASYNC" { + rdarst zero; + } + rdinit zero; + } + port sw "W" { + width 18; + clock posedge; + clken; + } +} diff --git a/techlibs/machxo2/brams_map.v b/techlibs/machxo2/brams_map.v new file mode 100644 index 000000000..05a8e8a9b --- /dev/null +++ b/techlibs/machxo2/brams_map.v @@ -0,0 +1,337 @@ +module $__DP8KC_ (...); + +parameter INIT = 0; +parameter OPTION_RESETMODE = "SYNC"; + +parameter PORT_A_WIDTH = 18; +parameter PORT_A_OPTION_WRITEMODE = "NORMAL"; + +input PORT_A_CLK; +input PORT_A_CLK_EN; +input PORT_A_WR_EN; +input PORT_A_RD_SRST; +input PORT_A_RD_ARST; +input [12:0] PORT_A_ADDR; +input [PORT_A_WIDTH-1:0] PORT_A_WR_DATA; +output [PORT_A_WIDTH-1:0] PORT_A_RD_DATA; + +parameter PORT_B_WIDTH = 18; +parameter PORT_B_OPTION_WRITEMODE = "NORMAL"; + +input PORT_B_CLK; +input PORT_B_CLK_EN; +input PORT_B_WR_EN; +input PORT_B_RD_SRST; +input PORT_B_RD_ARST; +input [12:0] PORT_B_ADDR; +input [PORT_B_WIDTH-1:0] PORT_B_WR_DATA; +output [PORT_B_WIDTH-1:0] PORT_B_RD_DATA; + +function [319:0] init_slice; + input integer idx; + integer i, j; + init_slice = 0; + for (i = 0; i < 16; i = i + 1) begin + init_slice[i*20+:18] = INIT[(idx * 16 + i) * 18+:18]; + end +endfunction + +wire [8:0] DOA; +wire [8:0] DOB; +wire [8:0] DIA = PORT_A_WR_DATA; +wire [8:0] DIB = PORT_B_WR_DATA; + +assign PORT_A_RD_DATA = DOA; +assign PORT_B_RD_DATA = DOB; + +DP8KC #( + .INITVAL_00($sformatf("0x%080x", init_slice('h00))), + .INITVAL_01($sformatf("0x%080x", init_slice('h01))), + .INITVAL_02($sformatf("0x%080x", init_slice('h02))), + .INITVAL_03($sformatf("0x%080x", init_slice('h03))), + .INITVAL_04($sformatf("0x%080x", init_slice('h04))), + .INITVAL_05($sformatf("0x%080x", init_slice('h05))), + .INITVAL_06($sformatf("0x%080x", init_slice('h06))), + .INITVAL_07($sformatf("0x%080x", init_slice('h07))), + .INITVAL_08($sformatf("0x%080x", init_slice('h08))), + .INITVAL_09($sformatf("0x%080x", init_slice('h09))), + .INITVAL_0A($sformatf("0x%080x", init_slice('h0a))), + .INITVAL_0B($sformatf("0x%080x", init_slice('h0b))), + .INITVAL_0C($sformatf("0x%080x", init_slice('h0c))), + .INITVAL_0D($sformatf("0x%080x", init_slice('h0d))), + .INITVAL_0E($sformatf("0x%080x", init_slice('h0e))), + .INITVAL_0F($sformatf("0x%080x", init_slice('h0f))), + .INITVAL_10($sformatf("0x%080x", init_slice('h10))), + .INITVAL_11($sformatf("0x%080x", init_slice('h11))), + .INITVAL_12($sformatf("0x%080x", init_slice('h12))), + .INITVAL_13($sformatf("0x%080x", init_slice('h13))), + .INITVAL_14($sformatf("0x%080x", init_slice('h14))), + .INITVAL_15($sformatf("0x%080x", init_slice('h15))), + .INITVAL_16($sformatf("0x%080x", init_slice('h16))), + .INITVAL_17($sformatf("0x%080x", init_slice('h17))), + .INITVAL_18($sformatf("0x%080x", init_slice('h18))), + .INITVAL_19($sformatf("0x%080x", init_slice('h19))), + .INITVAL_1A($sformatf("0x%080x", init_slice('h1a))), + .INITVAL_1B($sformatf("0x%080x", init_slice('h1b))), + .INITVAL_1C($sformatf("0x%080x", init_slice('h1c))), + .INITVAL_1D($sformatf("0x%080x", init_slice('h1d))), + .INITVAL_1E($sformatf("0x%080x", init_slice('h1e))), + .INITVAL_1F($sformatf("0x%080x", init_slice('h1f))), + .DATA_WIDTH_A(PORT_A_WIDTH), + .DATA_WIDTH_B(PORT_B_WIDTH), + .REGMODE_A("NOREG"), + .REGMODE_B("NOREG"), + .RESETMODE(OPTION_RESETMODE), + .ASYNC_RESET_RELEASE(OPTION_RESETMODE), + .CSDECODE_A("0b000"), + .CSDECODE_B("0b000"), + .WRITEMODE_A(PORT_A_OPTION_WRITEMODE), + .WRITEMODE_B(PORT_B_OPTION_WRITEMODE), + .GSR("AUTO") +) _TECHMAP_REPLACE_ ( + .CLKA(PORT_A_CLK), + .WEA(PORT_A_WR_EN), + .CEA(PORT_A_CLK_EN), + .OCEA(1'b1), + .RSTA(OPTION_RESETMODE == "SYNC" ? PORT_A_RD_SRST : PORT_A_RD_ARST), + .CSA0(1'b0), + .CSA1(1'b0), + .CSA2(1'b0), + .ADA0(PORT_A_WIDTH == 9 ? 1'b1 : PORT_A_ADDR[0]), + .ADA1(PORT_A_ADDR[1]), + .ADA2(PORT_A_ADDR[2]), + .ADA3(PORT_A_ADDR[3]), + .ADA4(PORT_A_ADDR[4]), + .ADA5(PORT_A_ADDR[5]), + .ADA6(PORT_A_ADDR[6]), + .ADA7(PORT_A_ADDR[7]), + .ADA8(PORT_A_ADDR[8]), + .ADA9(PORT_A_ADDR[9]), + .ADA10(PORT_A_ADDR[10]), + .ADA11(PORT_A_ADDR[11]), + .ADA12(PORT_A_ADDR[12]), + .DIA0(DIA[0]), + .DIA1(DIA[1]), + .DIA2(DIA[2]), + .DIA3(DIA[3]), + .DIA4(DIA[4]), + .DIA5(DIA[5]), + .DIA6(DIA[6]), + .DIA7(DIA[7]), + .DIA8(DIA[8]), + .DOA0(DOA[0]), + .DOA1(DOA[1]), + .DOA2(DOA[2]), + .DOA3(DOA[3]), + .DOA4(DOA[4]), + .DOA5(DOA[5]), + .DOA6(DOA[6]), + .DOA7(DOA[7]), + .DOA8(DOA[8]), + + .CLKB(PORT_B_CLK), + .WEB(PORT_B_WR_EN), + .CEB(PORT_B_CLK_EN), + .OCEB(1'b1), + .RSTB(OPTION_RESETMODE == "SYNC" ? PORT_B_RD_SRST : PORT_B_RD_ARST), + .CSB0(1'b0), + .CSB1(1'b0), + .CSB2(1'b0), + .ADB0(PORT_B_WIDTH == 9 ? 1'b1 : PORT_B_ADDR[0]), + .ADB1(PORT_B_ADDR[1]), + .ADB2(PORT_B_ADDR[2]), + .ADB3(PORT_B_ADDR[3]), + .ADB4(PORT_B_ADDR[4]), + .ADB5(PORT_B_ADDR[5]), + .ADB6(PORT_B_ADDR[6]), + .ADB7(PORT_B_ADDR[7]), + .ADB8(PORT_B_ADDR[8]), + .ADB9(PORT_B_ADDR[9]), + .ADB10(PORT_B_ADDR[10]), + .ADB11(PORT_B_ADDR[11]), + .ADB12(PORT_B_ADDR[12]), + .DIB0(DIB[0]), + .DIB1(DIB[1]), + .DIB2(DIB[2]), + .DIB3(DIB[3]), + .DIB4(DIB[4]), + .DIB5(DIB[5]), + .DIB6(DIB[6]), + .DIB7(DIB[7]), + .DIB8(DIB[8]), + .DOB0(DOB[0]), + .DOB1(DOB[1]), + .DOB2(DOB[2]), + .DOB3(DOB[3]), + .DOB4(DOB[4]), + .DOB5(DOB[5]), + .DOB6(DOB[6]), + .DOB7(DOB[7]), + .DOB8(DOB[8]), +); + +endmodule + + +module $__PDPW8KC_ (...); + +parameter INIT = 0; +parameter OPTION_RESETMODE = "SYNC"; + +parameter PORT_R_WIDTH = 18; + +input PORT_R_CLK; +input PORT_R_CLK_EN; +input PORT_R_RD_SRST; +input PORT_R_RD_ARST; +input [12:0] PORT_R_ADDR; +output [PORT_R_WIDTH-1:0] PORT_R_RD_DATA; + +parameter PORT_W_WIDTH = 18; +parameter PORT_W_WR_EN_WIDTH = 2; + +input PORT_W_CLK; +input PORT_W_CLK_EN; +input [12:0] PORT_W_ADDR; +input [PORT_W_WR_EN_WIDTH-1:0] PORT_W_WR_EN; +input [PORT_W_WIDTH-1:0] PORT_W_WR_DATA; + +function [319:0] init_slice; + input integer idx; + integer i, j; + init_slice = 0; + for (i = 0; i < 16; i = i + 1) begin + init_slice[i*20+:18] = INIT[(idx * 16 + i) * 18+:18]; + end +endfunction + +wire [17:0] DI = PORT_W_WR_DATA; +wire [17:0] DO; + +assign PORT_R_RD_DATA = PORT_R_WIDTH == 18 ? DO : DO[17:9]; + +DP8KC #( + .INITVAL_00($sformatf("0x%080x", init_slice('h00))), + .INITVAL_01($sformatf("0x%080x", init_slice('h01))), + .INITVAL_02($sformatf("0x%080x", init_slice('h02))), + .INITVAL_03($sformatf("0x%080x", init_slice('h03))), + .INITVAL_04($sformatf("0x%080x", init_slice('h04))), + .INITVAL_05($sformatf("0x%080x", init_slice('h05))), + .INITVAL_06($sformatf("0x%080x", init_slice('h06))), + .INITVAL_07($sformatf("0x%080x", init_slice('h07))), + .INITVAL_08($sformatf("0x%080x", init_slice('h08))), + .INITVAL_09($sformatf("0x%080x", init_slice('h09))), + .INITVAL_0A($sformatf("0x%080x", init_slice('h0a))), + .INITVAL_0B($sformatf("0x%080x", init_slice('h0b))), + .INITVAL_0C($sformatf("0x%080x", init_slice('h0c))), + .INITVAL_0D($sformatf("0x%080x", init_slice('h0d))), + .INITVAL_0E($sformatf("0x%080x", init_slice('h0e))), + .INITVAL_0F($sformatf("0x%080x", init_slice('h0f))), + .INITVAL_10($sformatf("0x%080x", init_slice('h10))), + .INITVAL_11($sformatf("0x%080x", init_slice('h11))), + .INITVAL_12($sformatf("0x%080x", init_slice('h12))), + .INITVAL_13($sformatf("0x%080x", init_slice('h13))), + .INITVAL_14($sformatf("0x%080x", init_slice('h14))), + .INITVAL_15($sformatf("0x%080x", init_slice('h15))), + .INITVAL_16($sformatf("0x%080x", init_slice('h16))), + .INITVAL_17($sformatf("0x%080x", init_slice('h17))), + .INITVAL_18($sformatf("0x%080x", init_slice('h18))), + .INITVAL_19($sformatf("0x%080x", init_slice('h19))), + .INITVAL_1A($sformatf("0x%080x", init_slice('h1a))), + .INITVAL_1B($sformatf("0x%080x", init_slice('h1b))), + .INITVAL_1C($sformatf("0x%080x", init_slice('h1c))), + .INITVAL_1D($sformatf("0x%080x", init_slice('h1d))), + .INITVAL_1E($sformatf("0x%080x", init_slice('h1e))), + .INITVAL_1F($sformatf("0x%080x", init_slice('h1f))), + .DATA_WIDTH_A(PORT_W_WIDTH), + .DATA_WIDTH_B(PORT_R_WIDTH), + .REGMODE_A("NOREG"), + .REGMODE_B("NOREG"), + .RESETMODE(OPTION_RESETMODE), + .ASYNC_RESET_RELEASE(OPTION_RESETMODE), + .CSDECODE_A("0b000"), + .CSDECODE_B("0b000"), + .GSR("AUTO") +) _TECHMAP_REPLACE_ ( + .CLKA(PORT_W_CLK), + .WEA(PORT_W_WIDTH >= 9 ? 1'b1 : PORT_W_WR_EN[0]), + .CEA(PORT_W_CLK_EN), + .OCEA(1'b0), + .RSTA(1'b0), + .CSA0(1'b0), + .CSA1(1'b0), + .CSA2(1'b0), + .ADA0(PORT_W_WIDTH >= 9 ? PORT_W_WR_EN[0] : PORT_W_ADDR[0]), + .ADA1(PORT_W_WIDTH >= 18 ? PORT_W_WR_EN[1] : PORT_W_ADDR[1]), + .ADA2(PORT_W_ADDR[2]), + .ADA3(PORT_W_ADDR[3]), + .ADA4(PORT_W_ADDR[4]), + .ADA5(PORT_W_ADDR[5]), + .ADA6(PORT_W_ADDR[6]), + .ADA7(PORT_W_ADDR[7]), + .ADA8(PORT_W_ADDR[8]), + .ADA9(PORT_W_ADDR[9]), + .ADA10(PORT_W_ADDR[10]), + .ADA11(PORT_W_ADDR[11]), + .ADA12(PORT_W_ADDR[12]), + .DIA0(DI[0]), + .DIA1(DI[1]), + .DIA2(DI[2]), + .DIA3(DI[3]), + .DIA4(DI[4]), + .DIA5(DI[5]), + .DIA6(DI[6]), + .DIA7(DI[7]), + .DIA8(DI[8]), + .DIB0(DI[9]), + .DIB1(DI[10]), + .DIB2(DI[11]), + .DIB3(DI[12]), + .DIB4(DI[13]), + .DIB5(DI[14]), + .DIB6(DI[15]), + .DIB7(DI[16]), + .DIB8(DI[17]), + + .CLKB(PORT_R_CLK), + .WEB(1'b0), + .CEB(PORT_R_CLK_EN), + .OCEB(1'b1), + .RSTB(OPTION_RESETMODE == "SYNC" ? PORT_R_RD_SRST : PORT_R_RD_ARST), + .CSB0(1'b0), + .CSB1(1'b0), + .CSB2(1'b0), + .ADB0(PORT_R_ADDR[0]), + .ADB1(PORT_R_ADDR[1]), + .ADB2(PORT_R_ADDR[2]), + .ADB3(PORT_R_ADDR[3]), + .ADB4(PORT_R_ADDR[4]), + .ADB5(PORT_R_ADDR[5]), + .ADB6(PORT_R_ADDR[6]), + .ADB7(PORT_R_ADDR[7]), + .ADB8(PORT_R_ADDR[8]), + .ADB9(PORT_R_ADDR[9]), + .ADB10(PORT_R_ADDR[10]), + .ADB11(PORT_R_ADDR[11]), + .ADB12(PORT_R_ADDR[12]), + .DOA0(DO[0]), + .DOA1(DO[1]), + .DOA2(DO[2]), + .DOA3(DO[3]), + .DOA4(DO[4]), + .DOA5(DO[5]), + .DOA6(DO[6]), + .DOA7(DO[7]), + .DOA8(DO[8]), + .DOB0(DO[9]), + .DOB1(DO[10]), + .DOB2(DO[11]), + .DOB3(DO[12]), + .DOB4(DO[13]), + .DOB5(DO[14]), + .DOB6(DO[15]), + .DOB7(DO[16]), + .DOB8(DO[17]), +); + +endmodule diff --git a/techlibs/machxo2/cells_map.v b/techlibs/machxo2/cells_map.v index 82eb10d95..9c370f246 100644 --- a/techlibs/machxo2/cells_map.v +++ b/techlibs/machxo2/cells_map.v @@ -30,5 +30,5 @@ module \$_DFF_P_ (input D, C, output Q); FACADE_FF #(.CEMUX("1"), .CLKMUX("CLK" // IO- "$__" cells for the iopadmap pass. module \$__FACADE_OUTPAD (input I, output O); FACADE_IO #(.DIR("OUTPUT")) _TECHMAP_REPLACE_ (.PAD(O), .I(I), .T(1'b0)); endmodule module \$__FACADE_INPAD (input I, output O); FACADE_IO #(.DIR("INPUT")) _TECHMAP_REPLACE_ (.PAD(I), .O(O)); endmodule -module \$__FACADE_TOUTPAD (input I, OE, output O); FACADE_IO #(.DIR("OUTPUT")) _TECHMAP_REPLACE_ (.PAD(O), .I(I), .T(~OE)); endmodule -module \$__FACADE_TINOUTPAD (input I, OE, output O, inout B); FACADE_IO #(.DIR("BIDIR")) _TECHMAP_REPLACE_ (.PAD(B), .I(I), .O(O), .T(~OE)); endmodule +module \$__FACADE_TOUTPAD (input I, T, output O); FACADE_IO #(.DIR("OUTPUT")) _TECHMAP_REPLACE_ (.PAD(O), .I(I), .T(T)); endmodule +module \$__FACADE_TINOUTPAD (input I, T, output O, inout B); FACADE_IO #(.DIR("BIDIR")) _TECHMAP_REPLACE_ (.PAD(B), .I(I), .O(O), .T(T)); endmodule diff --git a/techlibs/machxo2/cells_sim.v b/techlibs/machxo2/cells_sim.v index 161ddfe2e..82c9d8c4b 100644 --- a/techlibs/machxo2/cells_sim.v +++ b/techlibs/machxo2/cells_sim.v @@ -199,6 +199,127 @@ module DCMA ( ); endmodule +(* abc9_box, lib_whitebox *) +module DPR16X4C ( + input [3:0] DI, + input WCK, WRE, + input [3:0] RAD, + input [3:0] WAD, + output [3:0] DO +); + parameter INITVAL = "0x0000000000000000"; + + function [63:0] convert_initval; + input [143:0] hex_initval; + reg done; + reg [63:0] temp; + reg [7:0] char; + integer i; + begin + done = 1'b0; + temp = 0; + for (i = 0; i < 16; i = i + 1) begin + if (!done) begin + char = hex_initval[8*i +: 8]; + if (char == "x") begin + done = 1'b1; + end else begin + if (char >= "0" && char <= "9") + temp[4*i +: 4] = char - "0"; + else if (char >= "A" && char <= "F") + temp[4*i +: 4] = 10 + char - "A"; + else if (char >= "a" && char <= "f") + temp[4*i +: 4] = 10 + char - "a"; + end + end + end + convert_initval = temp; + end + endfunction + + localparam conv_initval = convert_initval(INITVAL); + + reg [3:0] ram[0:15]; + integer i; + initial begin + for (i = 0; i < 15; i = i + 1) begin + ram[i] <= conv_initval[4*i +: 4]; + end + end + + always @(posedge WCK) + if (WRE) + ram[WAD] <= DI; + + assign DO = ram[RAD]; +endmodule + +(* blackbox *) +module DP8KC( + input DIA8, DIA7, DIA6, DIA5, DIA4, DIA3, DIA2, DIA1, DIA0, + input ADA12, ADA11, ADA10, ADA9, ADA8, ADA7, ADA6, ADA5, ADA4, ADA3, ADA2, ADA1, ADA0, + input CEA, OCEA, CLKA, WEA, RSTA, + input CSA2, CSA1, CSA0, + output DOA8, DOA7, DOA6, DOA5, DOA4, DOA3, DOA2, DOA1, DOA0, + + input DIB8, DIB7, DIB6, DIB5, DIB4, DIB3, DIB2, DIB1, DIB0, + input ADB12, ADB11, ADB10, ADB9, ADB8, ADB7, ADB6, ADB5, ADB4, ADB3, ADB2, ADB1, ADB0, + input CEB, OCEB, CLKB, WEB, RSTB, + input CSB2, CSB1, CSB0, + output DOB8, DOB7, DOB6, DOB5, DOB4, DOB3, DOB2, DOB1, DOB0 +); + parameter DATA_WIDTH_A = 9; + parameter DATA_WIDTH_B = 9; + + parameter REGMODE_A = "NOREG"; + parameter REGMODE_B = "NOREG"; + + parameter RESETMODE = "SYNC"; + parameter ASYNC_RESET_RELEASE = "SYNC"; + + parameter CSDECODE_A = "0b000"; + parameter CSDECODE_B = "0b000"; + + parameter WRITEMODE_A = "NORMAL"; + parameter WRITEMODE_B = "NORMAL"; + + parameter GSR = "ENABLED"; + parameter INIT_DATA = "STATIC"; + + parameter INITVAL_00 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_01 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_02 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_03 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_04 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_05 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_06 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_07 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_08 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_09 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_0A = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_0B = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_0C = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_0D = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_0E = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_0F = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_10 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_11 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_12 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_13 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_14 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_15 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_16 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_17 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_18 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_19 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_1A = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_1B = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_1C = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_1D = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_1E = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_1F = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; +endmodule + // IO- "$__" cells for the iopadmap pass. These are temporary cells not meant // to be instantiated by the end user. They are required in this file for // attrmvcp to work. @@ -207,6 +328,6 @@ module \$__FACADE_OUTPAD (input I, output O); endmodule (* blackbox *) module \$__FACADE_INPAD (input I, output O); endmodule (* blackbox *) -module \$__FACADE_TOUTPAD (input I, OE, output O); endmodule +module \$__FACADE_TOUTPAD (input I, T, output O); endmodule (* blackbox *) -module \$__FACADE_TINOUTPAD (input I, OE, output O, inout B); endmodule +module \$__FACADE_TINOUTPAD (input I, T, output O, inout B); endmodule diff --git a/techlibs/machxo2/lutrams.txt b/techlibs/machxo2/lutrams.txt new file mode 100644 index 000000000..c6b0b6c45 --- /dev/null +++ b/techlibs/machxo2/lutrams.txt @@ -0,0 +1,12 @@ +ram distributed $__DPR16X4C_ { + abits 4; + width 4; + cost 4; + init no_undef; + prune_rom; + port sw "W" { + clock posedge; + } + port ar "R" { + } +} diff --git a/techlibs/machxo2/lutrams_map.v b/techlibs/machxo2/lutrams_map.v new file mode 100644 index 000000000..b55253fb8 --- /dev/null +++ b/techlibs/machxo2/lutrams_map.v @@ -0,0 +1,23 @@ +module $__DPR16X4C_ (...); + parameter INIT = 64'b0; + + input PORT_W_CLK; + input [3:0] PORT_W_ADDR; + input [3:0] PORT_W_WR_DATA; + input PORT_W_WR_EN; + + input [3:0] PORT_R_ADDR; + output [3:0] PORT_R_RD_DATA; + + DPR16X4C #( + .INITVAL($sformatf("0x%08x", INIT)) + ) _TECHMAP_REPLACE_ ( + .RAD(PORT_R_ADDR), + .DO(PORT_R_RD_DATA), + + .WAD(PORT_W_ADDR), + .DI(PORT_W_WR_DATA), + .WCK(PORT_W_CLK), + .WRE(PORT_W_WR_EN) + ); +endmodule diff --git a/techlibs/machxo2/synth_machxo2.cc b/techlibs/machxo2/synth_machxo2.cc index bba8f4830..dbd01bbfd 100644 --- a/techlibs/machxo2/synth_machxo2.cc +++ b/techlibs/machxo2/synth_machxo2.cc @@ -57,6 +57,12 @@ struct SynthMachXO2Pass : public ScriptPass log(" from label is synonymous to 'begin', and empty to label is\n"); log(" synonymous to the end of the command list.\n"); log("\n"); + log(" -nobram\n"); + log(" do not use block RAM cells in output netlist\n"); + log("\n"); + log(" -nolutram\n"); + log(" do not use LUT RAM cells in output netlist\n"); + log("\n"); log(" -noflatten\n"); log(" do not flatten design before synthesis\n"); log("\n"); @@ -74,7 +80,7 @@ struct SynthMachXO2Pass : public ScriptPass } string top_opt, blif_file, edif_file, json_file; - bool flatten, vpr, noiopad; + bool nobram, nolutram, flatten, vpr, noiopad; void clear_flags() override { @@ -82,6 +88,8 @@ struct SynthMachXO2Pass : public ScriptPass blif_file = ""; edif_file = ""; json_file = ""; + nobram = false; + nolutram = false; flatten = true; vpr = false; noiopad = false; @@ -127,6 +135,14 @@ struct SynthMachXO2Pass : public ScriptPass flatten = false; continue; } + if (args[argidx] == "-nobram") { + nobram = true; + continue; + } + if (args[argidx] == "-nolutram") { + nolutram = true; + continue; + } if (args[argidx] == "-noiopad") { noiopad = true; continue; @@ -173,6 +189,19 @@ struct SynthMachXO2Pass : public ScriptPass run("synth -run coarse"); } + if (check_label("map_ram")) + { + std::string args = ""; + if (nobram) + args += " -no-auto-block"; + if (nolutram) + args += " -no-auto-distributed"; + if (help_mode) + args += " [-no-auto-block] [-no-auto-distributed]"; + run("memory_libmap -lib +/machxo2/lutrams.txt -lib +/machxo2/brams.txt" + args, "(-no-auto-block if -nobram, -no-auto-distributed if -nolutram)"); + run("techmap -map +/machxo2/lutrams_map.v -map +/machxo2/brams_map.v"); + } + if (check_label("fine")) { run("memory_map"); @@ -185,7 +214,7 @@ struct SynthMachXO2Pass : public ScriptPass { if (!noiopad || help_mode) { - run("iopadmap -bits -outpad $__FACADE_OUTPAD I:O -inpad $__FACADE_INPAD O:I -toutpad $__FACADE_TOUTPAD OE:I:O -tinoutpad $__FACADE_TINOUTPAD OE:O:I:B A:top"); + run("iopadmap -bits -outpad $__FACADE_OUTPAD I:O -inpad $__FACADE_INPAD O:I -toutpad $__FACADE_TOUTPAD ~T:I:O -tinoutpad $__FACADE_TINOUTPAD ~T:O:I:B A:top"); run("attrmvcp -attr src -attr LOC t:$__FACADE_OUTPAD %x:+[O] t:$__FACADE_TOUTPAD %x:+[O] t:$__FACADE_TINOUTPAD %x:+[B]"); run("attrmvcp -attr src -attr LOC -driven t:$__FACADE_INPAD %x:+[I]"); } diff --git a/techlibs/nexus/Makefile.inc b/techlibs/nexus/Makefile.inc index 9828d32c1..8121d1d8a 100644 --- a/techlibs/nexus/Makefile.inc +++ b/techlibs/nexus/Makefile.inc @@ -6,10 +6,8 @@ $(eval $(call add_share_file,share/nexus,techlibs/nexus/parse_init.vh)) $(eval $(call add_share_file,share/nexus,techlibs/nexus/cells_xtra.v)) $(eval $(call add_share_file,share/nexus,techlibs/nexus/lutrams_map.v)) $(eval $(call add_share_file,share/nexus,techlibs/nexus/lutrams.txt)) -$(eval $(call add_share_file,share/nexus,techlibs/nexus/brams_init.vh)) $(eval $(call add_share_file,share/nexus,techlibs/nexus/brams_map.v)) $(eval $(call add_share_file,share/nexus,techlibs/nexus/brams.txt)) -$(eval $(call add_share_file,share/nexus,techlibs/nexus/lrams_init.vh)) $(eval $(call add_share_file,share/nexus,techlibs/nexus/lrams_map.v)) $(eval $(call add_share_file,share/nexus,techlibs/nexus/lrams.txt)) $(eval $(call add_share_file,share/nexus,techlibs/nexus/arith_map.v)) diff --git a/techlibs/nexus/arith_map.v b/techlibs/nexus/arith_map.v index 9a1fedfc8..81ab7ba54 100644 --- a/techlibs/nexus/arith_map.v +++ b/techlibs/nexus/arith_map.v @@ -90,7 +90,7 @@ module _80_nexus_alu (A, B, CI, BI, X, Y, CO); assign CO[i] = (AA[i] && BB[i]) || ((Y[i] ^ AA[i] ^ BB[i]) && (AA[i] || BB[i])); if (i+1 < Y_WIDTH) begin - assign CO[i + 1] = (AA[i] && BB[i]) || ((Y[i] ^ AA[i] ^ BB[i]) && (AA[i] || BB[i])); + assign CO[i + 1] = (AA[i + 1] && BB[i + 1]) || ((Y[i + 1] ^ AA[i + 1] ^ BB[i + 1]) && (AA[i + 1] || BB[i + 1])); assign Y[i+1] = Y1[i]; end end endgenerate diff --git a/techlibs/nexus/brams.txt b/techlibs/nexus/brams.txt index 086afe8bf..975a8d227 100644 --- a/techlibs/nexus/brams.txt +++ b/techlibs/nexus/brams.txt @@ -1,63 +1,47 @@ -bram $__NX_PDP16K - init 1 +ram block $__NX_DP16K_ { + abits 14; + widths 1 2 4 9 18 per_port; + byte 9; + cost 129; + init no_undef; + port srsw "A" "B" { + clock posedge; + clken; + wrbe_separate; + rdwr no_change; + portoption "RESETMODE" "SYNC" { + rdsrst zero gated_clken; + } + portoption "RESETMODE" "ASYNC" { + rdarst zero; + } + rdinit zero; + } +} - abits 9 @a9d36 - dbits 36 @a9d36 - abits 10 @a10d18 - dbits 18 @a10d18 - abits 11 @a11d9 - dbits 9 @a11d9 - abits 12 @a12d4 - dbits 4 @a12d4 - abits 13 @a13d2 - dbits 2 @a13d2 - abits 14 @a14d1 - dbits 1 @a14d1 - - groups 2 - ports 1 1 - wrmode 1 0 - enable 4 1 @a9d36 - enable 2 1 @a10d18 - enable 1 1 @a11d9 @a12d4 @a13d2 @a14d1 - transp 0 0 - clocks 2 3 - clkpol 2 3 -endbram - -match $__NX_PDP16K - # implicitly requested RAM or ROM - attribute !syn_ramstyle syn_ramstyle=auto - attribute !syn_romstyle syn_romstyle=auto - attribute !ram_block - attribute !rom_block - attribute !logic_block - min bits 2048 - min efficiency 5 - shuffle_enable A - make_transp - or_next_if_better -endmatch - -match $__NX_PDP16K - # explicitly requested RAM - attribute syn_ramstyle=block_ram ram_block - attribute !syn_romstyle - attribute !rom_block - attribute !logic_block - min wports 1 - shuffle_enable A - make_transp - or_next_if_better -endmatch - -match $__NX_PDP16K - # explicitly requested ROM - attribute syn_romstyle=ebr rom_block - attribute !syn_ramstyle - attribute !ram_block - attribute !logic_block - max wports 0 - make_transp - shuffle_enable A -endmatch +ram block $__NX_PDP16K_ { + abits 14; + widths 1 2 4 9 18 36 per_port; + byte 9; + option "SAME_CLOCK" 1 cost 128; + option "SAME_CLOCK" 0 cost 129; + init no_undef; + port sr "R" { + option "SAME_CLOCK" 1 clock posedge "C"; + option "SAME_CLOCK" 0 clock posedge; + clken; + portoption "RESETMODE" "SYNC" { + rdsrst zero gated_clken; + } + portoption "RESETMODE" "ASYNC" { + rdarst zero; + } + rdinit zero; + } + port sw "W" { + option "SAME_CLOCK" 1 clock posedge "C"; + option "SAME_CLOCK" 0 clock posedge; + clken; + option "SAME_CLOCK" 1 wrtrans all old; + } +} diff --git a/techlibs/nexus/brams_init.vh b/techlibs/nexus/brams_init.vh deleted file mode 100644 index 5b1d0188a..000000000 --- a/techlibs/nexus/brams_init.vh +++ /dev/null @@ -1,64 +0,0 @@ -.INITVAL_00($sformatf("0x%080x", permute_init(INIT[0 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_01($sformatf("0x%080x", permute_init(INIT[1 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_02($sformatf("0x%080x", permute_init(INIT[2 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_03($sformatf("0x%080x", permute_init(INIT[3 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_04($sformatf("0x%080x", permute_init(INIT[4 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_05($sformatf("0x%080x", permute_init(INIT[5 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_06($sformatf("0x%080x", permute_init(INIT[6 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_07($sformatf("0x%080x", permute_init(INIT[7 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_08($sformatf("0x%080x", permute_init(INIT[8 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_09($sformatf("0x%080x", permute_init(INIT[9 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_0A($sformatf("0x%080x", permute_init(INIT[10 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_0B($sformatf("0x%080x", permute_init(INIT[11 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_0C($sformatf("0x%080x", permute_init(INIT[12 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_0D($sformatf("0x%080x", permute_init(INIT[13 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_0E($sformatf("0x%080x", permute_init(INIT[14 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_0F($sformatf("0x%080x", permute_init(INIT[15 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_10($sformatf("0x%080x", permute_init(INIT[16 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_11($sformatf("0x%080x", permute_init(INIT[17 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_12($sformatf("0x%080x", permute_init(INIT[18 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_13($sformatf("0x%080x", permute_init(INIT[19 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_14($sformatf("0x%080x", permute_init(INIT[20 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_15($sformatf("0x%080x", permute_init(INIT[21 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_16($sformatf("0x%080x", permute_init(INIT[22 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_17($sformatf("0x%080x", permute_init(INIT[23 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_18($sformatf("0x%080x", permute_init(INIT[24 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_19($sformatf("0x%080x", permute_init(INIT[25 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_1A($sformatf("0x%080x", permute_init(INIT[26 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_1B($sformatf("0x%080x", permute_init(INIT[27 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_1C($sformatf("0x%080x", permute_init(INIT[28 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_1D($sformatf("0x%080x", permute_init(INIT[29 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_1E($sformatf("0x%080x", permute_init(INIT[30 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_1F($sformatf("0x%080x", permute_init(INIT[31 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_20($sformatf("0x%080x", permute_init(INIT[32 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_21($sformatf("0x%080x", permute_init(INIT[33 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_22($sformatf("0x%080x", permute_init(INIT[34 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_23($sformatf("0x%080x", permute_init(INIT[35 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_24($sformatf("0x%080x", permute_init(INIT[36 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_25($sformatf("0x%080x", permute_init(INIT[37 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_26($sformatf("0x%080x", permute_init(INIT[38 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_27($sformatf("0x%080x", permute_init(INIT[39 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_28($sformatf("0x%080x", permute_init(INIT[40 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_29($sformatf("0x%080x", permute_init(INIT[41 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_2A($sformatf("0x%080x", permute_init(INIT[42 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_2B($sformatf("0x%080x", permute_init(INIT[43 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_2C($sformatf("0x%080x", permute_init(INIT[44 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_2D($sformatf("0x%080x", permute_init(INIT[45 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_2E($sformatf("0x%080x", permute_init(INIT[46 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_2F($sformatf("0x%080x", permute_init(INIT[47 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_30($sformatf("0x%080x", permute_init(INIT[48 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_31($sformatf("0x%080x", permute_init(INIT[49 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_32($sformatf("0x%080x", permute_init(INIT[50 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_33($sformatf("0x%080x", permute_init(INIT[51 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_34($sformatf("0x%080x", permute_init(INIT[52 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_35($sformatf("0x%080x", permute_init(INIT[53 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_36($sformatf("0x%080x", permute_init(INIT[54 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_37($sformatf("0x%080x", permute_init(INIT[55 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_38($sformatf("0x%080x", permute_init(INIT[56 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_39($sformatf("0x%080x", permute_init(INIT[57 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_3A($sformatf("0x%080x", permute_init(INIT[58 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_3B($sformatf("0x%080x", permute_init(INIT[59 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_3C($sformatf("0x%080x", permute_init(INIT[60 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_3D($sformatf("0x%080x", permute_init(INIT[61 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_3E($sformatf("0x%080x", permute_init(INIT[62 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_3F($sformatf("0x%080x", permute_init(INIT[63 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))) diff --git a/techlibs/nexus/brams_map.v b/techlibs/nexus/brams_map.v index 214da4326..3cada2414 100644 --- a/techlibs/nexus/brams_map.v +++ b/techlibs/nexus/brams_map.v @@ -1,115 +1,382 @@ -module \$__NX_PDP16K (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN); - parameter CFG_ABITS = 9; - parameter CFG_DBITS = 36; - parameter CFG_ENABLE_A = 4; - - parameter CLKPOL2 = 1; - parameter CLKPOL3 = 1; - parameter [18431:0] INIT = 18432'b0; - - parameter _TECHMAP_BITS_CONNMAP_ = 8; - parameter [_TECHMAP_BITS_CONNMAP_-1:0] _TECHMAP_CONNMAP_CLK2_ = 0; - parameter [_TECHMAP_BITS_CONNMAP_-1:0] _TECHMAP_CONNMAP_CLK3_ = 0; - - input CLK2; - input CLK3; - - input [CFG_ABITS-1:0] A1ADDR; - input [CFG_DBITS-1:0] A1DATA; - input [CFG_ENABLE_A-1:0] A1EN; - - input [CFG_ABITS-1:0] B1ADDR; - output [CFG_DBITS-1:0] B1DATA; - input B1EN; - - // Address is left justified, in x18 and above lower bits are byte enables - localparam A_SHIFT = - (CFG_DBITS == 36) ? 5 : - (CFG_DBITS == 18) ? 4 : - (CFG_DBITS == 9) ? 3 : - (CFG_DBITS == 4) ? 2 : - (CFG_DBITS == 2) ? 1 : - 0; - - // Different primitives needed for single vs dual clock case - localparam SINGLE_CLOCK = (_TECHMAP_CONNMAP_CLK2_ == _TECHMAP_CONNMAP_CLK3_); - - localparam WIDTH = $sformatf("X%d", CFG_DBITS); - - wire [13:0] ra, wa; - wire [35:0] rd, wd; - - assign ra = {B1ADDR, {A_SHIFT{1'b1}}}; - - generate - if (CFG_ENABLE_A > 1) - assign wa = {A1ADDR, {(A_SHIFT-CFG_ENABLE_A){1'b1}}, A1EN}; - else - assign wa = {A1ADDR, {A_SHIFT{1'b1}}}; - endgenerate - - assign wd = A1DATA; - assign B1DATA = rd[CFG_DBITS-1:0]; - - wire wck, rck; - - generate - if (CLKPOL2) - assign wck = CLK2; - else - INV wck_inv_i (.A(CLK2), .Z(wck)); - if (CLKPOL3) - assign rck = CLK3; - else - INV wck_inv_i (.A(CLK3), .Z(rck)); - endgenerate - - wire we = |A1EN; - - localparam INIT_CHUNK_SIZE = (CFG_DBITS <= 4) ? 256 : 288; - - function [319:0] permute_init; - input [INIT_CHUNK_SIZE-1:0] chunk; - integer i; - begin - if (CFG_DBITS <= 4) begin - for (i = 0; i < 32; i = i + 1'b1) - permute_init[i * 10 +: 10] = {2'b00, chunk[i * 8 +: 8]}; - end else begin - for (i = 0; i < 32; i = i + 1'b1) - permute_init[i * 10 +: 10] = {1'b0, chunk[i * 9 +: 9]}; - end - end - endfunction - - generate - if (SINGLE_CLOCK) begin - PDPSC16K #( - .DATA_WIDTH_W(WIDTH), - .DATA_WIDTH_R(WIDTH), - .OUTREG("BYPASSED"), - .ECC("DISABLED"), - .GSR("DISABLED"), -`include "brams_init.vh" - ) _TECHMAP_REPLACE_ ( - .CLK(wck), .RST(1'b0), - .DI(wd), .ADW(wa), .CEW(we), .CSW(3'b111), - .ADR(ra), .DO(rd), .CER(B1EN), .CSR(3'b111) - ); - end else begin - PDP16K #( - .DATA_WIDTH_W(WIDTH), - .DATA_WIDTH_R(WIDTH), - .OUTREG("BYPASSED"), - .ECC("DISABLED"), - .GSR("DISABLED"), -`include "brams_init.vh" - ) _TECHMAP_REPLACE_ ( - .CLKW(wck), .CLKR(rck), .RST(1'b0), - .DI(wd), .ADW(wa), .CEW(we), .CSW(3'b111), - .ADR(ra), .DO(rd), .CER(B1EN), .CSR(3'b111) - ); - end - endgenerate +module $__NX_DP16K_ (...); + +parameter INIT = 0; + +parameter PORT_A_OPTION_RESETMODE = "SYNC"; +parameter PORT_A_WIDTH = 18; +parameter PORT_A_WR_BE_WIDTH = 2; + +input PORT_A_CLK; +input PORT_A_CLK_EN; +input PORT_A_WR_EN; +input PORT_A_RD_SRST; +input PORT_A_RD_ARST; +input [13:0] PORT_A_ADDR; +input [PORT_A_WR_BE_WIDTH-1:0] PORT_A_WR_BE; +input [PORT_A_WIDTH-1:0] PORT_A_WR_DATA; +output [PORT_A_WIDTH-1:0] PORT_A_RD_DATA; + +parameter PORT_B_OPTION_RESETMODE = "SYNC"; +parameter PORT_B_WIDTH = 18; +parameter PORT_B_WR_BE_WIDTH = 2; + +input PORT_B_CLK; +input PORT_B_CLK_EN; +input PORT_B_WR_EN; +input PORT_B_RD_SRST; +input PORT_B_RD_ARST; +input [13:0] PORT_B_ADDR; +input [PORT_B_WR_BE_WIDTH-1:0] PORT_B_WR_BE; +input [PORT_B_WIDTH-1:0] PORT_B_WR_DATA; +output [PORT_B_WIDTH-1:0] PORT_B_RD_DATA; + +function [319:0] init_slice; + input integer idx; + integer i, j; + init_slice = 0; + for (i = 0; i < 16; i = i + 1) begin + init_slice[i*20+:18] = INIT[(idx * 16 + i) * 18+:18]; + end +endfunction + +wire [17:0] DOA; +wire [17:0] DOB; +wire [17:0] DIA = PORT_A_WR_DATA; +wire [17:0] DIB = PORT_B_WR_DATA; +wire [13:0] ADA = PORT_A_WIDTH == 18 ? {PORT_A_ADDR[13:2], PORT_A_WR_BE} : PORT_A_ADDR; +wire [13:0] ADB = PORT_B_WIDTH == 18 ? {PORT_B_ADDR[13:2], PORT_B_WR_BE} : PORT_B_ADDR; + +assign PORT_A_RD_DATA = DOA; +assign PORT_B_RD_DATA = DOB; + +DP16K #( + .INITVAL_00($sformatf("0x%080x", init_slice('h00))), + .INITVAL_01($sformatf("0x%080x", init_slice('h01))), + .INITVAL_02($sformatf("0x%080x", init_slice('h02))), + .INITVAL_03($sformatf("0x%080x", init_slice('h03))), + .INITVAL_04($sformatf("0x%080x", init_slice('h04))), + .INITVAL_05($sformatf("0x%080x", init_slice('h05))), + .INITVAL_06($sformatf("0x%080x", init_slice('h06))), + .INITVAL_07($sformatf("0x%080x", init_slice('h07))), + .INITVAL_08($sformatf("0x%080x", init_slice('h08))), + .INITVAL_09($sformatf("0x%080x", init_slice('h09))), + .INITVAL_0A($sformatf("0x%080x", init_slice('h0a))), + .INITVAL_0B($sformatf("0x%080x", init_slice('h0b))), + .INITVAL_0C($sformatf("0x%080x", init_slice('h0c))), + .INITVAL_0D($sformatf("0x%080x", init_slice('h0d))), + .INITVAL_0E($sformatf("0x%080x", init_slice('h0e))), + .INITVAL_0F($sformatf("0x%080x", init_slice('h0f))), + .INITVAL_10($sformatf("0x%080x", init_slice('h10))), + .INITVAL_11($sformatf("0x%080x", init_slice('h11))), + .INITVAL_12($sformatf("0x%080x", init_slice('h12))), + .INITVAL_13($sformatf("0x%080x", init_slice('h13))), + .INITVAL_14($sformatf("0x%080x", init_slice('h14))), + .INITVAL_15($sformatf("0x%080x", init_slice('h15))), + .INITVAL_16($sformatf("0x%080x", init_slice('h16))), + .INITVAL_17($sformatf("0x%080x", init_slice('h17))), + .INITVAL_18($sformatf("0x%080x", init_slice('h18))), + .INITVAL_19($sformatf("0x%080x", init_slice('h19))), + .INITVAL_1A($sformatf("0x%080x", init_slice('h1a))), + .INITVAL_1B($sformatf("0x%080x", init_slice('h1b))), + .INITVAL_1C($sformatf("0x%080x", init_slice('h1c))), + .INITVAL_1D($sformatf("0x%080x", init_slice('h1d))), + .INITVAL_1E($sformatf("0x%080x", init_slice('h1e))), + .INITVAL_1F($sformatf("0x%080x", init_slice('h1f))), + .INITVAL_20($sformatf("0x%080x", init_slice('h20))), + .INITVAL_21($sformatf("0x%080x", init_slice('h21))), + .INITVAL_22($sformatf("0x%080x", init_slice('h22))), + .INITVAL_23($sformatf("0x%080x", init_slice('h23))), + .INITVAL_24($sformatf("0x%080x", init_slice('h24))), + .INITVAL_25($sformatf("0x%080x", init_slice('h25))), + .INITVAL_26($sformatf("0x%080x", init_slice('h26))), + .INITVAL_27($sformatf("0x%080x", init_slice('h27))), + .INITVAL_28($sformatf("0x%080x", init_slice('h28))), + .INITVAL_29($sformatf("0x%080x", init_slice('h29))), + .INITVAL_2A($sformatf("0x%080x", init_slice('h2a))), + .INITVAL_2B($sformatf("0x%080x", init_slice('h2b))), + .INITVAL_2C($sformatf("0x%080x", init_slice('h2c))), + .INITVAL_2D($sformatf("0x%080x", init_slice('h2d))), + .INITVAL_2E($sformatf("0x%080x", init_slice('h2e))), + .INITVAL_2F($sformatf("0x%080x", init_slice('h2f))), + .INITVAL_30($sformatf("0x%080x", init_slice('h30))), + .INITVAL_31($sformatf("0x%080x", init_slice('h31))), + .INITVAL_32($sformatf("0x%080x", init_slice('h32))), + .INITVAL_33($sformatf("0x%080x", init_slice('h33))), + .INITVAL_34($sformatf("0x%080x", init_slice('h34))), + .INITVAL_35($sformatf("0x%080x", init_slice('h35))), + .INITVAL_36($sformatf("0x%080x", init_slice('h36))), + .INITVAL_37($sformatf("0x%080x", init_slice('h37))), + .INITVAL_38($sformatf("0x%080x", init_slice('h38))), + .INITVAL_39($sformatf("0x%080x", init_slice('h39))), + .INITVAL_3A($sformatf("0x%080x", init_slice('h3a))), + .INITVAL_3B($sformatf("0x%080x", init_slice('h3b))), + .INITVAL_3C($sformatf("0x%080x", init_slice('h3c))), + .INITVAL_3D($sformatf("0x%080x", init_slice('h3d))), + .INITVAL_3E($sformatf("0x%080x", init_slice('h3e))), + .INITVAL_3F($sformatf("0x%080x", init_slice('h3f))), + .DATA_WIDTH_A($sformatf("X%d", PORT_A_WIDTH)), + .DATA_WIDTH_B($sformatf("X%d", PORT_B_WIDTH)), + .OUTREG_A("BYPASSED"), + .OUTREG_B("BYPASSED"), + .RESETMODE_A(PORT_A_OPTION_RESETMODE), + .RESETMODE_B(PORT_B_OPTION_RESETMODE), + .ASYNC_RST_RELEASE_A(PORT_A_OPTION_RESETMODE), + .ASYNC_RST_RELEASE_B(PORT_B_OPTION_RESETMODE), + .CSDECODE_A("000"), + .CSDECODE_B("000"), + .GSR("DISABLED"), +) _TECHMAP_REPLACE_ ( + .CLKA(PORT_A_CLK), + .WEA(PORT_A_WIDTH == 18 ? PORT_A_WR_EN : (PORT_A_WR_EN | PORT_A_WR_BE[0])), + .CEA(PORT_A_CLK_EN), + .RSTA(PORT_A_OPTION_RESETMODE == "SYNC" ? PORT_A_RD_SRST : PORT_A_RD_ARST), + .CSA(3'b111), + .DIA(DIA), + .DOA(DOA), + .ADA(ADA), + + .CLKB(PORT_B_CLK), + .WEB(PORT_B_WIDTH == 18 ? PORT_B_WR_EN : (PORT_B_WR_EN | PORT_B_WR_BE[0])), + .CEB(PORT_B_CLK_EN), + .RSTB(PORT_B_OPTION_RESETMODE == "SYNC" ? PORT_B_RD_SRST : PORT_B_RD_ARST), + .CSB(3'b111), + .ADB(ADB), + .DIB(DIB), + .DOB(DOB), +); + +endmodule + + +module $__NX_PDP16K_ (...); + +parameter INIT = 0; +parameter OPTION_SAME_CLOCK = 1; + +parameter PORT_R_WIDTH = 36; +parameter PORT_R_OPTION_RESETMODE = "SYNC"; + +input CLK_C; + +input PORT_R_CLK; +input PORT_R_CLK_EN; +input PORT_R_RD_SRST; +input PORT_R_RD_ARST; +input [13:0] PORT_R_ADDR; +output [PORT_R_WIDTH-1:0] PORT_R_RD_DATA; + +parameter PORT_W_WIDTH = 36; +parameter PORT_W_WR_EN_WIDTH = 4; + +input PORT_W_CLK; +input PORT_W_CLK_EN; +input [13:0] PORT_W_ADDR; +input [PORT_W_WR_EN_WIDTH-1:0] PORT_W_WR_EN; +input [PORT_W_WIDTH-1:0] PORT_W_WR_DATA; + +function [319:0] init_slice; + input integer idx; + integer i, j; + init_slice = 0; + for (i = 0; i < 16; i = i + 1) begin + init_slice[i*20+:18] = INIT[(idx * 16 + i) * 18+:18]; + end +endfunction + +wire [35:0] DI = PORT_W_WR_DATA; +wire [35:0] DO; + +assign PORT_R_RD_DATA = DO; + +wire [13:0] ADW = PORT_W_WIDTH == 36 ? {PORT_W_ADDR[13:4], PORT_W_WR_EN} : + (PORT_W_WIDTH == 18 ? {PORT_W_ADDR[13:2], PORT_W_WR_EN} : PORT_W_ADDR); + +generate + +if (OPTION_SAME_CLOCK) begin + +PDPSC16K #( + .INITVAL_00($sformatf("0x%080x", init_slice('h00))), + .INITVAL_01($sformatf("0x%080x", init_slice('h01))), + .INITVAL_02($sformatf("0x%080x", init_slice('h02))), + .INITVAL_03($sformatf("0x%080x", init_slice('h03))), + .INITVAL_04($sformatf("0x%080x", init_slice('h04))), + .INITVAL_05($sformatf("0x%080x", init_slice('h05))), + .INITVAL_06($sformatf("0x%080x", init_slice('h06))), + .INITVAL_07($sformatf("0x%080x", init_slice('h07))), + .INITVAL_08($sformatf("0x%080x", init_slice('h08))), + .INITVAL_09($sformatf("0x%080x", init_slice('h09))), + .INITVAL_0A($sformatf("0x%080x", init_slice('h0a))), + .INITVAL_0B($sformatf("0x%080x", init_slice('h0b))), + .INITVAL_0C($sformatf("0x%080x", init_slice('h0c))), + .INITVAL_0D($sformatf("0x%080x", init_slice('h0d))), + .INITVAL_0E($sformatf("0x%080x", init_slice('h0e))), + .INITVAL_0F($sformatf("0x%080x", init_slice('h0f))), + .INITVAL_10($sformatf("0x%080x", init_slice('h10))), + .INITVAL_11($sformatf("0x%080x", init_slice('h11))), + .INITVAL_12($sformatf("0x%080x", init_slice('h12))), + .INITVAL_13($sformatf("0x%080x", init_slice('h13))), + .INITVAL_14($sformatf("0x%080x", init_slice('h14))), + .INITVAL_15($sformatf("0x%080x", init_slice('h15))), + .INITVAL_16($sformatf("0x%080x", init_slice('h16))), + .INITVAL_17($sformatf("0x%080x", init_slice('h17))), + .INITVAL_18($sformatf("0x%080x", init_slice('h18))), + .INITVAL_19($sformatf("0x%080x", init_slice('h19))), + .INITVAL_1A($sformatf("0x%080x", init_slice('h1a))), + .INITVAL_1B($sformatf("0x%080x", init_slice('h1b))), + .INITVAL_1C($sformatf("0x%080x", init_slice('h1c))), + .INITVAL_1D($sformatf("0x%080x", init_slice('h1d))), + .INITVAL_1E($sformatf("0x%080x", init_slice('h1e))), + .INITVAL_1F($sformatf("0x%080x", init_slice('h1f))), + .INITVAL_20($sformatf("0x%080x", init_slice('h20))), + .INITVAL_21($sformatf("0x%080x", init_slice('h21))), + .INITVAL_22($sformatf("0x%080x", init_slice('h22))), + .INITVAL_23($sformatf("0x%080x", init_slice('h23))), + .INITVAL_24($sformatf("0x%080x", init_slice('h24))), + .INITVAL_25($sformatf("0x%080x", init_slice('h25))), + .INITVAL_26($sformatf("0x%080x", init_slice('h26))), + .INITVAL_27($sformatf("0x%080x", init_slice('h27))), + .INITVAL_28($sformatf("0x%080x", init_slice('h28))), + .INITVAL_29($sformatf("0x%080x", init_slice('h29))), + .INITVAL_2A($sformatf("0x%080x", init_slice('h2a))), + .INITVAL_2B($sformatf("0x%080x", init_slice('h2b))), + .INITVAL_2C($sformatf("0x%080x", init_slice('h2c))), + .INITVAL_2D($sformatf("0x%080x", init_slice('h2d))), + .INITVAL_2E($sformatf("0x%080x", init_slice('h2e))), + .INITVAL_2F($sformatf("0x%080x", init_slice('h2f))), + .INITVAL_30($sformatf("0x%080x", init_slice('h30))), + .INITVAL_31($sformatf("0x%080x", init_slice('h31))), + .INITVAL_32($sformatf("0x%080x", init_slice('h32))), + .INITVAL_33($sformatf("0x%080x", init_slice('h33))), + .INITVAL_34($sformatf("0x%080x", init_slice('h34))), + .INITVAL_35($sformatf("0x%080x", init_slice('h35))), + .INITVAL_36($sformatf("0x%080x", init_slice('h36))), + .INITVAL_37($sformatf("0x%080x", init_slice('h37))), + .INITVAL_38($sformatf("0x%080x", init_slice('h38))), + .INITVAL_39($sformatf("0x%080x", init_slice('h39))), + .INITVAL_3A($sformatf("0x%080x", init_slice('h3a))), + .INITVAL_3B($sformatf("0x%080x", init_slice('h3b))), + .INITVAL_3C($sformatf("0x%080x", init_slice('h3c))), + .INITVAL_3D($sformatf("0x%080x", init_slice('h3d))), + .INITVAL_3E($sformatf("0x%080x", init_slice('h3e))), + .INITVAL_3F($sformatf("0x%080x", init_slice('h3f))), + .DATA_WIDTH_W($sformatf("X%d", PORT_W_WIDTH)), + .DATA_WIDTH_R($sformatf("X%d", PORT_R_WIDTH)), + .OUTREG("BYPASSED"), + .RESETMODE(PORT_R_OPTION_RESETMODE), + .ASYNC_RST_RELEASE(PORT_R_OPTION_RESETMODE), + .CSDECODE_W("000"), + .CSDECODE_R("000"), + .ECC("DISABLED"), + .GSR("DISABLED"), +) _TECHMAP_REPLACE_ ( + .CLK(CLK_C), + + .CEW(PORT_W_CLK_EN), + .CSW(3'b111), + .ADW(ADW), + .DI(DI), + + .CER(PORT_R_CLK_EN), + .RST(PORT_R_OPTION_RESETMODE == "SYNC" ? PORT_R_RD_SRST : PORT_R_RD_ARST), + .CSR(3'b111), + .ADR(PORT_R_ADDR), + .DO(DO), +); + +end else begin + +PDP16K #( + .INITVAL_00($sformatf("0x%080x", init_slice('h00))), + .INITVAL_01($sformatf("0x%080x", init_slice('h01))), + .INITVAL_02($sformatf("0x%080x", init_slice('h02))), + .INITVAL_03($sformatf("0x%080x", init_slice('h03))), + .INITVAL_04($sformatf("0x%080x", init_slice('h04))), + .INITVAL_05($sformatf("0x%080x", init_slice('h05))), + .INITVAL_06($sformatf("0x%080x", init_slice('h06))), + .INITVAL_07($sformatf("0x%080x", init_slice('h07))), + .INITVAL_08($sformatf("0x%080x", init_slice('h08))), + .INITVAL_09($sformatf("0x%080x", init_slice('h09))), + .INITVAL_0A($sformatf("0x%080x", init_slice('h0a))), + .INITVAL_0B($sformatf("0x%080x", init_slice('h0b))), + .INITVAL_0C($sformatf("0x%080x", init_slice('h0c))), + .INITVAL_0D($sformatf("0x%080x", init_slice('h0d))), + .INITVAL_0E($sformatf("0x%080x", init_slice('h0e))), + .INITVAL_0F($sformatf("0x%080x", init_slice('h0f))), + .INITVAL_10($sformatf("0x%080x", init_slice('h10))), + .INITVAL_11($sformatf("0x%080x", init_slice('h11))), + .INITVAL_12($sformatf("0x%080x", init_slice('h12))), + .INITVAL_13($sformatf("0x%080x", init_slice('h13))), + .INITVAL_14($sformatf("0x%080x", init_slice('h14))), + .INITVAL_15($sformatf("0x%080x", init_slice('h15))), + .INITVAL_16($sformatf("0x%080x", init_slice('h16))), + .INITVAL_17($sformatf("0x%080x", init_slice('h17))), + .INITVAL_18($sformatf("0x%080x", init_slice('h18))), + .INITVAL_19($sformatf("0x%080x", init_slice('h19))), + .INITVAL_1A($sformatf("0x%080x", init_slice('h1a))), + .INITVAL_1B($sformatf("0x%080x", init_slice('h1b))), + .INITVAL_1C($sformatf("0x%080x", init_slice('h1c))), + .INITVAL_1D($sformatf("0x%080x", init_slice('h1d))), + .INITVAL_1E($sformatf("0x%080x", init_slice('h1e))), + .INITVAL_1F($sformatf("0x%080x", init_slice('h1f))), + .INITVAL_20($sformatf("0x%080x", init_slice('h20))), + .INITVAL_21($sformatf("0x%080x", init_slice('h21))), + .INITVAL_22($sformatf("0x%080x", init_slice('h22))), + .INITVAL_23($sformatf("0x%080x", init_slice('h23))), + .INITVAL_24($sformatf("0x%080x", init_slice('h24))), + .INITVAL_25($sformatf("0x%080x", init_slice('h25))), + .INITVAL_26($sformatf("0x%080x", init_slice('h26))), + .INITVAL_27($sformatf("0x%080x", init_slice('h27))), + .INITVAL_28($sformatf("0x%080x", init_slice('h28))), + .INITVAL_29($sformatf("0x%080x", init_slice('h29))), + .INITVAL_2A($sformatf("0x%080x", init_slice('h2a))), + .INITVAL_2B($sformatf("0x%080x", init_slice('h2b))), + .INITVAL_2C($sformatf("0x%080x", init_slice('h2c))), + .INITVAL_2D($sformatf("0x%080x", init_slice('h2d))), + .INITVAL_2E($sformatf("0x%080x", init_slice('h2e))), + .INITVAL_2F($sformatf("0x%080x", init_slice('h2f))), + .INITVAL_30($sformatf("0x%080x", init_slice('h30))), + .INITVAL_31($sformatf("0x%080x", init_slice('h31))), + .INITVAL_32($sformatf("0x%080x", init_slice('h32))), + .INITVAL_33($sformatf("0x%080x", init_slice('h33))), + .INITVAL_34($sformatf("0x%080x", init_slice('h34))), + .INITVAL_35($sformatf("0x%080x", init_slice('h35))), + .INITVAL_36($sformatf("0x%080x", init_slice('h36))), + .INITVAL_37($sformatf("0x%080x", init_slice('h37))), + .INITVAL_38($sformatf("0x%080x", init_slice('h38))), + .INITVAL_39($sformatf("0x%080x", init_slice('h39))), + .INITVAL_3A($sformatf("0x%080x", init_slice('h3a))), + .INITVAL_3B($sformatf("0x%080x", init_slice('h3b))), + .INITVAL_3C($sformatf("0x%080x", init_slice('h3c))), + .INITVAL_3D($sformatf("0x%080x", init_slice('h3d))), + .INITVAL_3E($sformatf("0x%080x", init_slice('h3e))), + .INITVAL_3F($sformatf("0x%080x", init_slice('h3f))), + .DATA_WIDTH_W($sformatf("X%d", PORT_W_WIDTH)), + .DATA_WIDTH_R($sformatf("X%d", PORT_R_WIDTH)), + .OUTREG("BYPASSED"), + .RESETMODE(PORT_R_OPTION_RESETMODE), + .ASYNC_RST_RELEASE(PORT_R_OPTION_RESETMODE), + .CSDECODE_W("000"), + .CSDECODE_R("000"), + .ECC("DISABLED"), + .GSR("DISABLED"), +) _TECHMAP_REPLACE_ ( + .CLKW(PORT_W_CLK), + .CEW(PORT_W_CLK_EN), + .CSW(3'b111), + .ADW(ADW), + .DI(DI), + + .CLKR(PORT_R_CLK), + .CER(PORT_R_CLK_EN), + .RST(PORT_R_OPTION_RESETMODE == "SYNC" ? PORT_R_RD_SRST : PORT_R_RD_ARST), + .CSR(3'b111), + .ADR(PORT_R_ADDR), + .DO(DO), +); + +end + +endgenerate endmodule diff --git a/techlibs/nexus/cells_map.v b/techlibs/nexus/cells_map.v index 1e53e4026..b70edbcf4 100644 --- a/techlibs/nexus/cells_map.v +++ b/techlibs/nexus/cells_map.v @@ -53,14 +53,6 @@ module \$_DFFE_PP1P_ (input D, C, E, R, output Q); \$__FF_ASYNCLSR #(1) _TECHM module \$_SDFFE_PP0P_ (input D, C, E, R, output Q); \$__FF_SYNCLSR #(0) _TECHMAP_REPLACE_ (.D(D), .C(C), .R(R), .E(E), .Q(Q)); endmodule module \$_SDFFE_PP1P_ (input D, C, E, R, output Q); \$__FF_SYNCLSR #(1) _TECHMAP_REPLACE_ (.D(D), .C(C), .R(R), .E(E), .Q(Q)); endmodule -module \$__NX_TINOUTPAD (input I, OE, output O, inout B); - BB _TECHMAP_REPLACE_ (.I(I), .O(O), .T(~OE), .B(B)); -endmodule - -module \$__NX_TOUTPAD (input I, OE, output O); - OBZ _TECHMAP_REPLACE_ (.I(I), .T(~OE), .O(O)); -endmodule - `ifndef NO_LUT module \$lut (A, Y); parameter WIDTH = 0; diff --git a/techlibs/nexus/cells_sim.v b/techlibs/nexus/cells_sim.v index 1e876a210..d1c8bf0d7 100644 --- a/techlibs/nexus/cells_sim.v +++ b/techlibs/nexus/cells_sim.v @@ -54,8 +54,8 @@ endmodule // Bidirectional IO buffer module BB(input T, I, output O, (* iopad_external_pin *) inout B); - assign B = T ? 1'bz : O; - assign I = B; + assign B = T ? 1'bz : I; + assign O = B; endmodule // Input buffer diff --git a/techlibs/nexus/lrams.txt b/techlibs/nexus/lrams.txt index 481629b98..ad2845783 100644 --- a/techlibs/nexus/lrams.txt +++ b/techlibs/nexus/lrams.txt @@ -1,22 +1,21 @@ -bram $__NX_PDPSC512K - init 1 - - abits 14 - dbits 32 - - groups 2 - ports 1 1 - wrmode 1 0 - enable 4 1 - transp 0 0 - clocks 2 2 - clkpol 2 2 -endbram - -match $__NX_PDPSC512K - # explicitly requested LRAM only, due to limited availability and - # slower Fmax - attribute lram - shuffle_enable A - make_transp -endmatch +ram huge $__NX_DPSC512K_ { + abits 14; + width 32; + byte 8; + cost 2048; + init no_undef; + port srsw "A" "B" { + clock posedge "C"; + clken; + wrbe_separate; + rdwr no_change; + option "RESETMODE" "SYNC" { + rdsrst zero gated_clken; + } + option "RESETMODE" "ASYNC" { + rdarst zero; + } + rdinit zero; + wrtrans all old; + } +} diff --git a/techlibs/nexus/lrams_init.vh b/techlibs/nexus/lrams_init.vh deleted file mode 100644 index 31a7ba4a8..000000000 --- a/techlibs/nexus/lrams_init.vh +++ /dev/null @@ -1,128 +0,0 @@ -.INITVAL_00($sformatf("0x%05120x", permute_init(INIT[0 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_01($sformatf("0x%05120x", permute_init(INIT[1 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_02($sformatf("0x%05120x", permute_init(INIT[2 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_03($sformatf("0x%05120x", permute_init(INIT[3 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_04($sformatf("0x%05120x", permute_init(INIT[4 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_05($sformatf("0x%05120x", permute_init(INIT[5 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_06($sformatf("0x%05120x", permute_init(INIT[6 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_07($sformatf("0x%05120x", permute_init(INIT[7 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_08($sformatf("0x%05120x", permute_init(INIT[8 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_09($sformatf("0x%05120x", permute_init(INIT[9 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_0A($sformatf("0x%05120x", permute_init(INIT[10 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_0B($sformatf("0x%05120x", permute_init(INIT[11 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_0C($sformatf("0x%05120x", permute_init(INIT[12 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_0D($sformatf("0x%05120x", permute_init(INIT[13 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_0E($sformatf("0x%05120x", permute_init(INIT[14 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_0F($sformatf("0x%05120x", permute_init(INIT[15 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_10($sformatf("0x%05120x", permute_init(INIT[16 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_11($sformatf("0x%05120x", permute_init(INIT[17 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_12($sformatf("0x%05120x", permute_init(INIT[18 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_13($sformatf("0x%05120x", permute_init(INIT[19 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_14($sformatf("0x%05120x", permute_init(INIT[20 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_15($sformatf("0x%05120x", permute_init(INIT[21 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_16($sformatf("0x%05120x", permute_init(INIT[22 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_17($sformatf("0x%05120x", permute_init(INIT[23 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_18($sformatf("0x%05120x", permute_init(INIT[24 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_19($sformatf("0x%05120x", permute_init(INIT[25 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_1A($sformatf("0x%05120x", permute_init(INIT[26 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_1B($sformatf("0x%05120x", permute_init(INIT[27 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_1C($sformatf("0x%05120x", permute_init(INIT[28 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_1D($sformatf("0x%05120x", permute_init(INIT[29 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_1E($sformatf("0x%05120x", permute_init(INIT[30 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_1F($sformatf("0x%05120x", permute_init(INIT[31 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_20($sformatf("0x%05120x", permute_init(INIT[32 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_21($sformatf("0x%05120x", permute_init(INIT[33 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_22($sformatf("0x%05120x", permute_init(INIT[34 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_23($sformatf("0x%05120x", permute_init(INIT[35 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_24($sformatf("0x%05120x", permute_init(INIT[36 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_25($sformatf("0x%05120x", permute_init(INIT[37 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_26($sformatf("0x%05120x", permute_init(INIT[38 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_27($sformatf("0x%05120x", permute_init(INIT[39 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_28($sformatf("0x%05120x", permute_init(INIT[40 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_29($sformatf("0x%05120x", permute_init(INIT[41 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_2A($sformatf("0x%05120x", permute_init(INIT[42 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_2B($sformatf("0x%05120x", permute_init(INIT[43 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_2C($sformatf("0x%05120x", permute_init(INIT[44 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_2D($sformatf("0x%05120x", permute_init(INIT[45 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_2E($sformatf("0x%05120x", permute_init(INIT[46 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_2F($sformatf("0x%05120x", permute_init(INIT[47 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_30($sformatf("0x%05120x", permute_init(INIT[48 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_31($sformatf("0x%05120x", permute_init(INIT[49 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_32($sformatf("0x%05120x", permute_init(INIT[50 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_33($sformatf("0x%05120x", permute_init(INIT[51 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_34($sformatf("0x%05120x", permute_init(INIT[52 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_35($sformatf("0x%05120x", permute_init(INIT[53 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_36($sformatf("0x%05120x", permute_init(INIT[54 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_37($sformatf("0x%05120x", permute_init(INIT[55 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_38($sformatf("0x%05120x", permute_init(INIT[56 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_39($sformatf("0x%05120x", permute_init(INIT[57 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_3A($sformatf("0x%05120x", permute_init(INIT[58 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_3B($sformatf("0x%05120x", permute_init(INIT[59 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_3C($sformatf("0x%05120x", permute_init(INIT[60 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_3D($sformatf("0x%05120x", permute_init(INIT[61 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_3E($sformatf("0x%05120x", permute_init(INIT[62 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_3F($sformatf("0x%05120x", permute_init(INIT[63 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_40($sformatf("0x%05120x", permute_init(INIT[64 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_41($sformatf("0x%05120x", permute_init(INIT[65 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_42($sformatf("0x%05120x", permute_init(INIT[66 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_43($sformatf("0x%05120x", permute_init(INIT[67 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_44($sformatf("0x%05120x", permute_init(INIT[68 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_45($sformatf("0x%05120x", permute_init(INIT[69 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_46($sformatf("0x%05120x", permute_init(INIT[70 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_47($sformatf("0x%05120x", permute_init(INIT[71 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_48($sformatf("0x%05120x", permute_init(INIT[72 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_49($sformatf("0x%05120x", permute_init(INIT[73 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_4A($sformatf("0x%05120x", permute_init(INIT[74 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_4B($sformatf("0x%05120x", permute_init(INIT[75 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_4C($sformatf("0x%05120x", permute_init(INIT[76 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_4D($sformatf("0x%05120x", permute_init(INIT[77 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_4E($sformatf("0x%05120x", permute_init(INIT[78 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_4F($sformatf("0x%05120x", permute_init(INIT[79 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_50($sformatf("0x%05120x", permute_init(INIT[80 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_51($sformatf("0x%05120x", permute_init(INIT[81 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_52($sformatf("0x%05120x", permute_init(INIT[82 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_53($sformatf("0x%05120x", permute_init(INIT[83 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_54($sformatf("0x%05120x", permute_init(INIT[84 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_55($sformatf("0x%05120x", permute_init(INIT[85 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_56($sformatf("0x%05120x", permute_init(INIT[86 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_57($sformatf("0x%05120x", permute_init(INIT[87 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_58($sformatf("0x%05120x", permute_init(INIT[88 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_59($sformatf("0x%05120x", permute_init(INIT[89 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_5A($sformatf("0x%05120x", permute_init(INIT[90 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_5B($sformatf("0x%05120x", permute_init(INIT[91 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_5C($sformatf("0x%05120x", permute_init(INIT[92 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_5D($sformatf("0x%05120x", permute_init(INIT[93 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_5E($sformatf("0x%05120x", permute_init(INIT[94 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_5F($sformatf("0x%05120x", permute_init(INIT[95 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_60($sformatf("0x%05120x", permute_init(INIT[96 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_61($sformatf("0x%05120x", permute_init(INIT[97 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_62($sformatf("0x%05120x", permute_init(INIT[98 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_63($sformatf("0x%05120x", permute_init(INIT[99 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_64($sformatf("0x%05120x", permute_init(INIT[100 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_65($sformatf("0x%05120x", permute_init(INIT[101 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_66($sformatf("0x%05120x", permute_init(INIT[102 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_67($sformatf("0x%05120x", permute_init(INIT[103 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_68($sformatf("0x%05120x", permute_init(INIT[104 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_69($sformatf("0x%05120x", permute_init(INIT[105 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_6A($sformatf("0x%05120x", permute_init(INIT[106 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_6B($sformatf("0x%05120x", permute_init(INIT[107 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_6C($sformatf("0x%05120x", permute_init(INIT[108 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_6D($sformatf("0x%05120x", permute_init(INIT[109 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_6E($sformatf("0x%05120x", permute_init(INIT[110 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_6F($sformatf("0x%05120x", permute_init(INIT[111 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_70($sformatf("0x%05120x", permute_init(INIT[112 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_71($sformatf("0x%05120x", permute_init(INIT[113 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_72($sformatf("0x%05120x", permute_init(INIT[114 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_73($sformatf("0x%05120x", permute_init(INIT[115 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_74($sformatf("0x%05120x", permute_init(INIT[116 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_75($sformatf("0x%05120x", permute_init(INIT[117 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_76($sformatf("0x%05120x", permute_init(INIT[118 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_77($sformatf("0x%05120x", permute_init(INIT[119 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_78($sformatf("0x%05120x", permute_init(INIT[120 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_79($sformatf("0x%05120x", permute_init(INIT[121 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_7A($sformatf("0x%05120x", permute_init(INIT[122 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_7B($sformatf("0x%05120x", permute_init(INIT[123 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_7C($sformatf("0x%05120x", permute_init(INIT[124 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_7D($sformatf("0x%05120x", permute_init(INIT[125 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_7E($sformatf("0x%05120x", permute_init(INIT[126 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), -.INITVAL_7F($sformatf("0x%05120x", permute_init(INIT[127 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), diff --git a/techlibs/nexus/lrams_map.v b/techlibs/nexus/lrams_map.v index 938a0e843..5db5ae8bf 100644 --- a/techlibs/nexus/lrams_map.v +++ b/techlibs/nexus/lrams_map.v @@ -1,56 +1,194 @@ -module \$__NX_PDPSC512K (CLK2, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN); - parameter CFG_ABITS = 14; - parameter CFG_DBITS = 32; - parameter CFG_ENABLE_A = 4; - - parameter CLKPOL2 = 1; - parameter [524287:0] INIT = 524287'b0; - - input CLK2; - - input [CFG_ABITS-1:0] A1ADDR; - input [CFG_DBITS-1:0] A1DATA; - input [CFG_ENABLE_A-1:0] A1EN; - - input [CFG_ABITS-1:0] B1ADDR; - output [CFG_DBITS-1:0] B1DATA; - input B1EN; - - wire clk; - wire [31:0] rd; - assign B1DATA = rd[CFG_DBITS-1:0]; - - generate - if (CLKPOL2) - assign clk = CLK2; - else - INV clk_inv_i (.A(CLK2), .Z(clk)); - endgenerate - - wire we = |A1EN; - - localparam INIT_CHUNK_SIZE = 4096; - - function [5119:0] permute_init; - input [INIT_CHUNK_SIZE-1:0] chunk; - integer i; - begin - for (i = 0; i < 128; i = i + 1'b1) - permute_init[i * 40 +: 40] = {8'b0, chunk[i * 32 +: 32]}; - end - endfunction - - generate - PDPSC512K #( - .OUTREG("NO_REG"), - .ECC_BYTE_SEL("BYTE_EN"), -`include "lrams_init.vh" - .GSR("DISABLED") - ) _TECHMAP_REPLACE_ ( - .CLK(clk), .RSTR(1'b0), - .DI(A1DATA), .ADW(A1ADDR), .CEW(we), .WE(we), .CSW(1'b1), - .ADR(B1ADDR), .DO(rd), .CER(B1EN), .CSR(1'b1), - ); - endgenerate +module $__NX_DPSC512K_ (...); + +parameter INIT = 0; +parameter OPTION_RESETMODE = "SYNC"; + +input CLK_C; + +input PORT_A_CLK; +input PORT_A_CLK_EN; +input PORT_A_WR_EN; +input PORT_A_RD_SRST; +input PORT_A_RD_ARST; +input [13:0] PORT_A_ADDR; +input [3:0] PORT_A_WR_BE; +input [31:0] PORT_A_WR_DATA; +output [31:0] PORT_A_RD_DATA; + +input PORT_B_CLK; +input PORT_B_CLK_EN; +input PORT_B_WR_EN; +input PORT_B_RD_SRST; +input PORT_B_RD_ARST; +input [13:0] PORT_B_ADDR; +input [3:0] PORT_B_WR_BE; +input [31:0] PORT_B_WR_DATA; +output [31:0] PORT_B_RD_DATA; + +function [5119:0] init_slice; + input integer idx; + integer i, j; + init_slice = 0; + for (i = 0; i < 128; i = i + 1) begin + init_slice[i*40+:32] = INIT[(idx * 128 + i) * 32+:32]; + end +endfunction + +DPSC512K #( + .INITVAL_00($sformatf("0x%01280x", init_slice('h00))), + .INITVAL_01($sformatf("0x%01280x", init_slice('h01))), + .INITVAL_02($sformatf("0x%01280x", init_slice('h02))), + .INITVAL_03($sformatf("0x%01280x", init_slice('h03))), + .INITVAL_04($sformatf("0x%01280x", init_slice('h04))), + .INITVAL_05($sformatf("0x%01280x", init_slice('h05))), + .INITVAL_06($sformatf("0x%01280x", init_slice('h06))), + .INITVAL_07($sformatf("0x%01280x", init_slice('h07))), + .INITVAL_08($sformatf("0x%01280x", init_slice('h08))), + .INITVAL_09($sformatf("0x%01280x", init_slice('h09))), + .INITVAL_0A($sformatf("0x%01280x", init_slice('h0a))), + .INITVAL_0B($sformatf("0x%01280x", init_slice('h0b))), + .INITVAL_0C($sformatf("0x%01280x", init_slice('h0c))), + .INITVAL_0D($sformatf("0x%01280x", init_slice('h0d))), + .INITVAL_0E($sformatf("0x%01280x", init_slice('h0e))), + .INITVAL_0F($sformatf("0x%01280x", init_slice('h0f))), + .INITVAL_10($sformatf("0x%01280x", init_slice('h10))), + .INITVAL_11($sformatf("0x%01280x", init_slice('h11))), + .INITVAL_12($sformatf("0x%01280x", init_slice('h12))), + .INITVAL_13($sformatf("0x%01280x", init_slice('h13))), + .INITVAL_14($sformatf("0x%01280x", init_slice('h14))), + .INITVAL_15($sformatf("0x%01280x", init_slice('h15))), + .INITVAL_16($sformatf("0x%01280x", init_slice('h16))), + .INITVAL_17($sformatf("0x%01280x", init_slice('h17))), + .INITVAL_18($sformatf("0x%01280x", init_slice('h18))), + .INITVAL_19($sformatf("0x%01280x", init_slice('h19))), + .INITVAL_1A($sformatf("0x%01280x", init_slice('h1a))), + .INITVAL_1B($sformatf("0x%01280x", init_slice('h1b))), + .INITVAL_1C($sformatf("0x%01280x", init_slice('h1c))), + .INITVAL_1D($sformatf("0x%01280x", init_slice('h1d))), + .INITVAL_1E($sformatf("0x%01280x", init_slice('h1e))), + .INITVAL_1F($sformatf("0x%01280x", init_slice('h1f))), + .INITVAL_20($sformatf("0x%01280x", init_slice('h20))), + .INITVAL_21($sformatf("0x%01280x", init_slice('h21))), + .INITVAL_22($sformatf("0x%01280x", init_slice('h22))), + .INITVAL_23($sformatf("0x%01280x", init_slice('h23))), + .INITVAL_24($sformatf("0x%01280x", init_slice('h24))), + .INITVAL_25($sformatf("0x%01280x", init_slice('h25))), + .INITVAL_26($sformatf("0x%01280x", init_slice('h26))), + .INITVAL_27($sformatf("0x%01280x", init_slice('h27))), + .INITVAL_28($sformatf("0x%01280x", init_slice('h28))), + .INITVAL_29($sformatf("0x%01280x", init_slice('h29))), + .INITVAL_2A($sformatf("0x%01280x", init_slice('h2a))), + .INITVAL_2B($sformatf("0x%01280x", init_slice('h2b))), + .INITVAL_2C($sformatf("0x%01280x", init_slice('h2c))), + .INITVAL_2D($sformatf("0x%01280x", init_slice('h2d))), + .INITVAL_2E($sformatf("0x%01280x", init_slice('h2e))), + .INITVAL_2F($sformatf("0x%01280x", init_slice('h2f))), + .INITVAL_30($sformatf("0x%01280x", init_slice('h30))), + .INITVAL_31($sformatf("0x%01280x", init_slice('h31))), + .INITVAL_32($sformatf("0x%01280x", init_slice('h32))), + .INITVAL_33($sformatf("0x%01280x", init_slice('h33))), + .INITVAL_34($sformatf("0x%01280x", init_slice('h34))), + .INITVAL_35($sformatf("0x%01280x", init_slice('h35))), + .INITVAL_36($sformatf("0x%01280x", init_slice('h36))), + .INITVAL_37($sformatf("0x%01280x", init_slice('h37))), + .INITVAL_38($sformatf("0x%01280x", init_slice('h38))), + .INITVAL_39($sformatf("0x%01280x", init_slice('h39))), + .INITVAL_3A($sformatf("0x%01280x", init_slice('h3a))), + .INITVAL_3B($sformatf("0x%01280x", init_slice('h3b))), + .INITVAL_3C($sformatf("0x%01280x", init_slice('h3c))), + .INITVAL_3D($sformatf("0x%01280x", init_slice('h3d))), + .INITVAL_3E($sformatf("0x%01280x", init_slice('h3e))), + .INITVAL_3F($sformatf("0x%01280x", init_slice('h3f))), + .INITVAL_40($sformatf("0x%01280x", init_slice('h40))), + .INITVAL_41($sformatf("0x%01280x", init_slice('h41))), + .INITVAL_42($sformatf("0x%01280x", init_slice('h42))), + .INITVAL_43($sformatf("0x%01280x", init_slice('h43))), + .INITVAL_44($sformatf("0x%01280x", init_slice('h44))), + .INITVAL_45($sformatf("0x%01280x", init_slice('h45))), + .INITVAL_46($sformatf("0x%01280x", init_slice('h46))), + .INITVAL_47($sformatf("0x%01280x", init_slice('h47))), + .INITVAL_48($sformatf("0x%01280x", init_slice('h48))), + .INITVAL_49($sformatf("0x%01280x", init_slice('h49))), + .INITVAL_4A($sformatf("0x%01280x", init_slice('h4a))), + .INITVAL_4B($sformatf("0x%01280x", init_slice('h4b))), + .INITVAL_4C($sformatf("0x%01280x", init_slice('h4c))), + .INITVAL_4D($sformatf("0x%01280x", init_slice('h4d))), + .INITVAL_4E($sformatf("0x%01280x", init_slice('h4e))), + .INITVAL_4F($sformatf("0x%01280x", init_slice('h4f))), + .INITVAL_50($sformatf("0x%01280x", init_slice('h50))), + .INITVAL_51($sformatf("0x%01280x", init_slice('h51))), + .INITVAL_52($sformatf("0x%01280x", init_slice('h52))), + .INITVAL_53($sformatf("0x%01280x", init_slice('h53))), + .INITVAL_54($sformatf("0x%01280x", init_slice('h54))), + .INITVAL_55($sformatf("0x%01280x", init_slice('h55))), + .INITVAL_56($sformatf("0x%01280x", init_slice('h56))), + .INITVAL_57($sformatf("0x%01280x", init_slice('h57))), + .INITVAL_58($sformatf("0x%01280x", init_slice('h58))), + .INITVAL_59($sformatf("0x%01280x", init_slice('h59))), + .INITVAL_5A($sformatf("0x%01280x", init_slice('h5a))), + .INITVAL_5B($sformatf("0x%01280x", init_slice('h5b))), + .INITVAL_5C($sformatf("0x%01280x", init_slice('h5c))), + .INITVAL_5D($sformatf("0x%01280x", init_slice('h5d))), + .INITVAL_5E($sformatf("0x%01280x", init_slice('h5e))), + .INITVAL_5F($sformatf("0x%01280x", init_slice('h5f))), + .INITVAL_60($sformatf("0x%01280x", init_slice('h60))), + .INITVAL_61($sformatf("0x%01280x", init_slice('h61))), + .INITVAL_62($sformatf("0x%01280x", init_slice('h62))), + .INITVAL_63($sformatf("0x%01280x", init_slice('h63))), + .INITVAL_64($sformatf("0x%01280x", init_slice('h64))), + .INITVAL_65($sformatf("0x%01280x", init_slice('h65))), + .INITVAL_66($sformatf("0x%01280x", init_slice('h66))), + .INITVAL_67($sformatf("0x%01280x", init_slice('h67))), + .INITVAL_68($sformatf("0x%01280x", init_slice('h68))), + .INITVAL_69($sformatf("0x%01280x", init_slice('h69))), + .INITVAL_6A($sformatf("0x%01280x", init_slice('h6a))), + .INITVAL_6B($sformatf("0x%01280x", init_slice('h6b))), + .INITVAL_6C($sformatf("0x%01280x", init_slice('h6c))), + .INITVAL_6D($sformatf("0x%01280x", init_slice('h6d))), + .INITVAL_6E($sformatf("0x%01280x", init_slice('h6e))), + .INITVAL_6F($sformatf("0x%01280x", init_slice('h6f))), + .INITVAL_70($sformatf("0x%01280x", init_slice('h70))), + .INITVAL_71($sformatf("0x%01280x", init_slice('h71))), + .INITVAL_72($sformatf("0x%01280x", init_slice('h72))), + .INITVAL_73($sformatf("0x%01280x", init_slice('h73))), + .INITVAL_74($sformatf("0x%01280x", init_slice('h74))), + .INITVAL_75($sformatf("0x%01280x", init_slice('h75))), + .INITVAL_76($sformatf("0x%01280x", init_slice('h76))), + .INITVAL_77($sformatf("0x%01280x", init_slice('h77))), + .INITVAL_78($sformatf("0x%01280x", init_slice('h78))), + .INITVAL_79($sformatf("0x%01280x", init_slice('h79))), + .INITVAL_7A($sformatf("0x%01280x", init_slice('h7a))), + .INITVAL_7B($sformatf("0x%01280x", init_slice('h7b))), + .INITVAL_7C($sformatf("0x%01280x", init_slice('h7c))), + .INITVAL_7D($sformatf("0x%01280x", init_slice('h7d))), + .INITVAL_7E($sformatf("0x%01280x", init_slice('h7e))), + .INITVAL_7F($sformatf("0x%01280x", init_slice('h7f))), + .OUTREG_A("NO_REG"), + .OUTREG_B("NO_REG"), + .ECC_BYTE_SEL("BYTE_EN"), + .GSR("DISABLED"), + .RESETMODE(OPTION_RESETMODE), + .ASYNC_RESET_RELEASE(OPTION_RESETMODE), +) _TECHMAP_REPLACE_ ( + .CLK(CLK_C), + + .WEA(PORT_A_WR_EN), + .CEA(PORT_A_CLK_EN), + .RSTA(OPTION_RESETMODE == "SYNC" ? PORT_A_RD_SRST : PORT_A_RD_ARST), + .CSA(1'b1), + .ADA(PORT_A_ADDR), + .BENA_N(~PORT_A_WR_BE), + .DIA(PORT_A_WR_DATA), + .DOA(PORT_A_RD_DATA), + + .WEB(PORT_B_WR_EN), + .CEB(PORT_B_CLK_EN), + .RSTB(OPTION_RESETMODE == "SYNC" ? PORT_B_RD_SRST : PORT_B_RD_ARST), + .CSB(1'b1), + .BENB_N(~PORT_B_WR_BE), + .ADB(PORT_B_ADDR), + .DIB(PORT_B_WR_DATA), + .DOB(PORT_B_RD_DATA), +); endmodule diff --git a/techlibs/nexus/lutrams.txt b/techlibs/nexus/lutrams.txt index 2568b9998..90e1e7bfd 100644 --- a/techlibs/nexus/lutrams.txt +++ b/techlibs/nexus/lutrams.txt @@ -1,26 +1,12 @@ -bram $__NEXUS_DPR16X4 - init 1 - abits 4 - dbits 4 - groups 2 - ports 1 1 - wrmode 0 1 - enable 0 1 - transp 0 0 - clocks 0 1 - clkpol 0 2 -endbram - -# The syn_* attributes are described in: -# https://www.latticesemi.com/-/media/LatticeSemi/Documents/Tutorials/AK/LatticeDiamondTutorial311.ashx -attr_icase 1 - -match $__NEXUS_DPR16X4 - attribute !syn_ramstyle syn_ramstyle=auto syn_ramstyle=distributed - attribute !syn_romstyle syn_romstyle=auto - attribute !ram_block - attribute !rom_block - attribute !logic_block - make_outreg - min wports 1 -endmatch +ram distributed $__NEXUS_DPR16X4_ { + abits 4; + width 4; + cost 4; + init no_undef; + prune_rom; + port sw "W" { + clock posedge; + } + port ar "R" { + } +} diff --git a/techlibs/nexus/lutrams_map.v b/techlibs/nexus/lutrams_map.v index 0910664ce..d12b49060 100644 --- a/techlibs/nexus/lutrams_map.v +++ b/techlibs/nexus/lutrams_map.v @@ -1,34 +1,23 @@ -module \$__NEXUS_DPR16X4 (CLK1, A1ADDR, A1DATA, B1ADDR, B1DATA, B1EN); - parameter [63:0] INIT = 64'b0; - parameter CLKPOL2 = 1; - input CLK1; +module $__NEXUS_DPR16X4_ (...); + parameter INIT = 64'b0; - input [3:0] A1ADDR; - output [3:0] A1DATA; + input PORT_W_CLK; + input [3:0] PORT_W_ADDR; + input [3:0] PORT_W_WR_DATA; + input PORT_W_WR_EN; - input [3:0] B1ADDR; - input [3:0] B1DATA; - input B1EN; - - - wire wck; - - generate - if (CLKPOL2) - assign wck = CLK1; - else - INV wck_inv_i (.A(CLK1), .Z(wck)); - endgenerate + input [3:0] PORT_R_ADDR; + output [3:0] PORT_R_RD_DATA; DPR16X4 #( .INITVAL($sformatf("0x%08x", INIT)) ) _TECHMAP_REPLACE_ ( - .RAD(A1ADDR), - .DO(A1DATA), + .RAD(PORT_R_ADDR), + .DO(PORT_R_RD_DATA), - .WAD(B1ADDR), - .DI(B1DATA), - .WCK(CLK1), - .WRE(B1EN) + .WAD(PORT_W_ADDR), + .DI(PORT_W_WR_DATA), + .WCK(PORT_W_CLK), + .WRE(PORT_W_WR_EN) ); endmodule diff --git a/techlibs/nexus/synth_nexus.cc b/techlibs/nexus/synth_nexus.cc index d725546cc..6fd15ba55 100644 --- a/techlibs/nexus/synth_nexus.cc +++ b/techlibs/nexus/synth_nexus.cc @@ -296,33 +296,24 @@ struct SynthNexusPass : public ScriptPass run("opt_clean"); } - if (!nolram && check_label("map_lram", "(skip if -nolram)")) + if (check_label("map_ram")) { - run("memory_bram -rules +/nexus/lrams.txt"); - run("setundef -zero -params t:$__NX_PDPSC512K"); - run("techmap -map +/nexus/lrams_map.v"); - } - - if (!nobram && check_label("map_bram", "(skip if -nobram)")) - { - run("memory_bram -rules +/nexus/brams.txt"); - run("setundef -zero -params t:$__NX_PDP16K"); - run("techmap -map +/nexus/brams_map.v"); - } - - if (!nolutram && check_label("map_lutram", "(skip if -nolutram)")) - { - run("memory_bram -rules +/nexus/lutrams.txt"); - run("setundef -zero -params t:$__NEXUS_DPR16X4"); - run("techmap -map +/nexus/lutrams_map.v"); + std::string args = ""; + args += " -no-auto-huge"; + if (nobram) + args += " -no-auto-block"; + if (nolutram) + args += " -no-auto-distributed"; + if (help_mode) + args += " [-no-auto-block] [-no-auto-distributed]"; + run("memory_libmap -lib +/nexus/lutrams.txt -lib +/nexus/brams.txt -lib +/nexus/lrams.txt" + args, "(-no-auto-block if -nobram, -no-auto-distributed if -nolutram)"); + run("techmap -map +/nexus/lutrams_map.v -map +/nexus/brams_map.v -map +/nexus/lrams_map.v"); } if (check_label("map_ffram")) { run("opt -fast -mux_undef -undriven -fine"); - run("memory_map -iattr -attr !ram_block -attr !rom_block -attr logic_block " - "-attr syn_ramstyle=auto -attr syn_ramstyle=registers " - "-attr syn_romstyle=auto -attr syn_romstyle=logic"); + run("memory_map"); run("opt -undriven -fine"); } @@ -333,7 +324,7 @@ struct SynthNexusPass : public ScriptPass else run("techmap -map +/techmap.v -map +/nexus/arith_map.v"); if (help_mode || !noiopad) - run("iopadmap -bits -outpad OB I:O -inpad IB O:I -toutpad $__NX_TOUTPAD OE:I:O -tinoutpad $__NX_TINOUTPAD OE:O:I:B A:top", "(skip if '-noiopad')"); + run("iopadmap -bits -outpad OB I:O -inpad IB O:I -toutpad OBZ ~T:I:O -tinoutpad BB ~T:O:I:B A:top", "(skip if '-noiopad')"); run("opt -fast"); if (retime || help_mode) run("abc -dff -D 1", "(only if -retime)"); diff --git a/techlibs/quicklogic/synth_quicklogic.cc b/techlibs/quicklogic/synth_quicklogic.cc index a67b167b8..754de2de6 100644 --- a/techlibs/quicklogic/synth_quicklogic.cc +++ b/techlibs/quicklogic/synth_quicklogic.cc @@ -225,8 +225,8 @@ struct SynthQuickLogicPass : public ScriptPass { } if (check_label("verilog")) { - if (!verilog_file.empty()) { - run("write_verilog -noattr -nohex " + verilog_file); + if (!verilog_file.empty() || help_mode) { + run(stringf("write_verilog -noattr -nohex %s", help_mode ? "<file-name>" : verilog_file.c_str())); } } } diff --git a/techlibs/xilinx/.gitignore b/techlibs/xilinx/.gitignore deleted file mode 100644 index d127107db..000000000 --- a/techlibs/xilinx/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -brams_init.mk -brams_init_*.vh diff --git a/techlibs/xilinx/Makefile.inc b/techlibs/xilinx/Makefile.inc index ba87278de..2d3d0f63c 100644 --- a/techlibs/xilinx/Makefile.inc +++ b/techlibs/xilinx/Makefile.inc @@ -2,45 +2,37 @@ OBJS += techlibs/xilinx/synth_xilinx.o OBJS += techlibs/xilinx/xilinx_dffopt.o -GENFILES += techlibs/xilinx/brams_init_36.vh -GENFILES += techlibs/xilinx/brams_init_32.vh -GENFILES += techlibs/xilinx/brams_init_18.vh -GENFILES += techlibs/xilinx/brams_init_16.vh -GENFILES += techlibs/xilinx/brams_init_9.vh -GENFILES += techlibs/xilinx/brams_init_8.vh +$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/cells_map.v)) +$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/cells_sim.v)) +$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/cells_xtra.v)) -EXTRA_OBJS += techlibs/xilinx/brams_init.mk -.SECONDARY: techlibs/xilinx/brams_init.mk +$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/lutrams_xcv.txt)) +$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/lutrams_xcv_map.v)) -techlibs/xilinx/brams_init.mk: techlibs/xilinx/brams_init.py - $(Q) mkdir -p techlibs/xilinx - $(P) $(PYTHON_EXECUTABLE) $< - $(Q) touch $@ +$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/lutrams_xc5v.txt)) +$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/lutrams_xcu.txt)) +$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/lutrams_xc5v_map.v)) -techlibs/xilinx/brams_init_36.vh: techlibs/xilinx/brams_init.mk -techlibs/xilinx/brams_init_32.vh: techlibs/xilinx/brams_init.mk -techlibs/xilinx/brams_init_18.vh: techlibs/xilinx/brams_init.mk -techlibs/xilinx/brams_init_16.vh: techlibs/xilinx/brams_init.mk -techlibs/xilinx/brams_init_9.vh: techlibs/xilinx/brams_init.mk -techlibs/xilinx/brams_init_8.vh: techlibs/xilinx/brams_init.mk +$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/brams_xcv.txt)) +$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/brams_xcv_map.v)) + +$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/brams_defs.vh)) + +$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/brams_xc2v.txt)) +$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/brams_xc2v_map.v)) + +$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/brams_xc3sda.txt)) +$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/brams_xc3sda_map.v)) + +$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/brams_xc4v.txt)) +$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/brams_xc4v_map.v)) +$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/brams_xc5v_map.v)) +$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/brams_xc6v_map.v)) +$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/brams_xcu_map.v)) + +$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/urams.txt)) +$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/urams_map.v)) -$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/cells_map.v)) -$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/cells_sim.v)) -$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/cells_xtra.v)) -$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xc2v_brams.txt)) -$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xc2v_brams_map.v)) -$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xc3sa_brams.txt)) -$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xc3sda_brams.txt)) -$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xc6s_brams.txt)) -$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xc6s_brams_map.v)) -$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xc7_xcu_brams.txt)) -$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xc7_brams_map.v)) -$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xcu_brams_map.v)) -$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xcup_urams.txt)) -$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xcup_urams_map.v)) -$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/lut4_lutrams.txt)) -$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/lut6_lutrams.txt)) -$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/lutrams_map.v)) $(eval $(call add_share_file,share/xilinx,techlibs/xilinx/arith_map.v)) $(eval $(call add_share_file,share/xilinx,techlibs/xilinx/ff_map.v)) $(eval $(call add_share_file,share/xilinx,techlibs/xilinx/lut_map.v)) @@ -54,11 +46,3 @@ $(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xc7_dsp_map.v)) $(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xcu_dsp_map.v)) $(eval $(call add_share_file,share/xilinx,techlibs/xilinx/abc9_model.v)) - -$(eval $(call add_gen_share_file,share/xilinx,techlibs/xilinx/brams_init_36.vh)) -$(eval $(call add_gen_share_file,share/xilinx,techlibs/xilinx/brams_init_32.vh)) -$(eval $(call add_gen_share_file,share/xilinx,techlibs/xilinx/brams_init_18.vh)) -$(eval $(call add_gen_share_file,share/xilinx,techlibs/xilinx/brams_init_16.vh)) -$(eval $(call add_gen_share_file,share/xilinx,techlibs/xilinx/brams_init_9.vh)) -$(eval $(call add_gen_share_file,share/xilinx,techlibs/xilinx/brams_init_8.vh)) - diff --git a/techlibs/xilinx/brams_defs.vh b/techlibs/xilinx/brams_defs.vh new file mode 100644 index 000000000..69fe5d716 --- /dev/null +++ b/techlibs/xilinx/brams_defs.vh @@ -0,0 +1,561 @@ +`define PARAMS_INIT_9 \ + .INIT_00(slice_init('h00)), \ + .INIT_01(slice_init('h01)), \ + .INIT_02(slice_init('h02)), \ + .INIT_03(slice_init('h03)), \ + .INIT_04(slice_init('h04)), \ + .INIT_05(slice_init('h05)), \ + .INIT_06(slice_init('h06)), \ + .INIT_07(slice_init('h07)), \ + .INIT_08(slice_init('h08)), \ + .INIT_09(slice_init('h09)), \ + .INIT_0A(slice_init('h0a)), \ + .INIT_0B(slice_init('h0b)), \ + .INIT_0C(slice_init('h0c)), \ + .INIT_0D(slice_init('h0d)), \ + .INIT_0E(slice_init('h0e)), \ + .INIT_0F(slice_init('h0f)), \ + .INIT_10(slice_init('h10)), \ + .INIT_11(slice_init('h11)), \ + .INIT_12(slice_init('h12)), \ + .INIT_13(slice_init('h13)), \ + .INIT_14(slice_init('h14)), \ + .INIT_15(slice_init('h15)), \ + .INIT_16(slice_init('h16)), \ + .INIT_17(slice_init('h17)), \ + .INIT_18(slice_init('h18)), \ + .INIT_19(slice_init('h19)), \ + .INIT_1A(slice_init('h1a)), \ + .INIT_1B(slice_init('h1b)), \ + .INIT_1C(slice_init('h1c)), \ + .INIT_1D(slice_init('h1d)), \ + .INIT_1E(slice_init('h1e)), \ + .INIT_1F(slice_init('h1f)), + +`define PARAMS_INITP_9 \ + .INITP_00(slice_initp('h00)), \ + .INITP_01(slice_initp('h01)), \ + .INITP_02(slice_initp('h02)), \ + .INITP_03(slice_initp('h03)), + +`define PARAMS_INIT_18 \ + .INIT_00(slice_init('h00)), \ + .INIT_01(slice_init('h01)), \ + .INIT_02(slice_init('h02)), \ + .INIT_03(slice_init('h03)), \ + .INIT_04(slice_init('h04)), \ + .INIT_05(slice_init('h05)), \ + .INIT_06(slice_init('h06)), \ + .INIT_07(slice_init('h07)), \ + .INIT_08(slice_init('h08)), \ + .INIT_09(slice_init('h09)), \ + .INIT_0A(slice_init('h0a)), \ + .INIT_0B(slice_init('h0b)), \ + .INIT_0C(slice_init('h0c)), \ + .INIT_0D(slice_init('h0d)), \ + .INIT_0E(slice_init('h0e)), \ + .INIT_0F(slice_init('h0f)), \ + .INIT_10(slice_init('h10)), \ + .INIT_11(slice_init('h11)), \ + .INIT_12(slice_init('h12)), \ + .INIT_13(slice_init('h13)), \ + .INIT_14(slice_init('h14)), \ + .INIT_15(slice_init('h15)), \ + .INIT_16(slice_init('h16)), \ + .INIT_17(slice_init('h17)), \ + .INIT_18(slice_init('h18)), \ + .INIT_19(slice_init('h19)), \ + .INIT_1A(slice_init('h1a)), \ + .INIT_1B(slice_init('h1b)), \ + .INIT_1C(slice_init('h1c)), \ + .INIT_1D(slice_init('h1d)), \ + .INIT_1E(slice_init('h1e)), \ + .INIT_1F(slice_init('h1f)), \ + .INIT_20(slice_init('h20)), \ + .INIT_21(slice_init('h21)), \ + .INIT_22(slice_init('h22)), \ + .INIT_23(slice_init('h23)), \ + .INIT_24(slice_init('h24)), \ + .INIT_25(slice_init('h25)), \ + .INIT_26(slice_init('h26)), \ + .INIT_27(slice_init('h27)), \ + .INIT_28(slice_init('h28)), \ + .INIT_29(slice_init('h29)), \ + .INIT_2A(slice_init('h2a)), \ + .INIT_2B(slice_init('h2b)), \ + .INIT_2C(slice_init('h2c)), \ + .INIT_2D(slice_init('h2d)), \ + .INIT_2E(slice_init('h2e)), \ + .INIT_2F(slice_init('h2f)), \ + .INIT_30(slice_init('h30)), \ + .INIT_31(slice_init('h31)), \ + .INIT_32(slice_init('h32)), \ + .INIT_33(slice_init('h33)), \ + .INIT_34(slice_init('h34)), \ + .INIT_35(slice_init('h35)), \ + .INIT_36(slice_init('h36)), \ + .INIT_37(slice_init('h37)), \ + .INIT_38(slice_init('h38)), \ + .INIT_39(slice_init('h39)), \ + .INIT_3A(slice_init('h3a)), \ + .INIT_3B(slice_init('h3b)), \ + .INIT_3C(slice_init('h3c)), \ + .INIT_3D(slice_init('h3d)), \ + .INIT_3E(slice_init('h3e)), \ + .INIT_3F(slice_init('h3f)), + +`define PARAMS_INIT_18_U \ + .INIT_00(slice_init('h40)), \ + .INIT_01(slice_init('h41)), \ + .INIT_02(slice_init('h42)), \ + .INIT_03(slice_init('h43)), \ + .INIT_04(slice_init('h44)), \ + .INIT_05(slice_init('h45)), \ + .INIT_06(slice_init('h46)), \ + .INIT_07(slice_init('h47)), \ + .INIT_08(slice_init('h48)), \ + .INIT_09(slice_init('h49)), \ + .INIT_0A(slice_init('h4a)), \ + .INIT_0B(slice_init('h4b)), \ + .INIT_0C(slice_init('h4c)), \ + .INIT_0D(slice_init('h4d)), \ + .INIT_0E(slice_init('h4e)), \ + .INIT_0F(slice_init('h4f)), \ + .INIT_10(slice_init('h50)), \ + .INIT_11(slice_init('h51)), \ + .INIT_12(slice_init('h52)), \ + .INIT_13(slice_init('h53)), \ + .INIT_14(slice_init('h54)), \ + .INIT_15(slice_init('h55)), \ + .INIT_16(slice_init('h56)), \ + .INIT_17(slice_init('h57)), \ + .INIT_18(slice_init('h58)), \ + .INIT_19(slice_init('h59)), \ + .INIT_1A(slice_init('h5a)), \ + .INIT_1B(slice_init('h5b)), \ + .INIT_1C(slice_init('h5c)), \ + .INIT_1D(slice_init('h5d)), \ + .INIT_1E(slice_init('h5e)), \ + .INIT_1F(slice_init('h5f)), \ + .INIT_20(slice_init('h60)), \ + .INIT_21(slice_init('h61)), \ + .INIT_22(slice_init('h62)), \ + .INIT_23(slice_init('h63)), \ + .INIT_24(slice_init('h64)), \ + .INIT_25(slice_init('h65)), \ + .INIT_26(slice_init('h66)), \ + .INIT_27(slice_init('h67)), \ + .INIT_28(slice_init('h68)), \ + .INIT_29(slice_init('h69)), \ + .INIT_2A(slice_init('h6a)), \ + .INIT_2B(slice_init('h6b)), \ + .INIT_2C(slice_init('h6c)), \ + .INIT_2D(slice_init('h6d)), \ + .INIT_2E(slice_init('h6e)), \ + .INIT_2F(slice_init('h6f)), \ + .INIT_30(slice_init('h70)), \ + .INIT_31(slice_init('h71)), \ + .INIT_32(slice_init('h72)), \ + .INIT_33(slice_init('h73)), \ + .INIT_34(slice_init('h74)), \ + .INIT_35(slice_init('h75)), \ + .INIT_36(slice_init('h76)), \ + .INIT_37(slice_init('h77)), \ + .INIT_38(slice_init('h78)), \ + .INIT_39(slice_init('h79)), \ + .INIT_3A(slice_init('h7a)), \ + .INIT_3B(slice_init('h7b)), \ + .INIT_3C(slice_init('h7c)), \ + .INIT_3D(slice_init('h7d)), \ + .INIT_3E(slice_init('h7e)), \ + .INIT_3F(slice_init('h7f)), + +`define PARAMS_INITP_18 \ + .INITP_00(slice_initp('h00)), \ + .INITP_01(slice_initp('h01)), \ + .INITP_02(slice_initp('h02)), \ + .INITP_03(slice_initp('h03)), \ + .INITP_04(slice_initp('h04)), \ + .INITP_05(slice_initp('h05)), \ + .INITP_06(slice_initp('h06)), \ + .INITP_07(slice_initp('h07)), + +`define PARAMS_INIT_36 \ + .INIT_00(slice_init('h00)), \ + .INIT_01(slice_init('h01)), \ + .INIT_02(slice_init('h02)), \ + .INIT_03(slice_init('h03)), \ + .INIT_04(slice_init('h04)), \ + .INIT_05(slice_init('h05)), \ + .INIT_06(slice_init('h06)), \ + .INIT_07(slice_init('h07)), \ + .INIT_08(slice_init('h08)), \ + .INIT_09(slice_init('h09)), \ + .INIT_0A(slice_init('h0a)), \ + .INIT_0B(slice_init('h0b)), \ + .INIT_0C(slice_init('h0c)), \ + .INIT_0D(slice_init('h0d)), \ + .INIT_0E(slice_init('h0e)), \ + .INIT_0F(slice_init('h0f)), \ + .INIT_10(slice_init('h10)), \ + .INIT_11(slice_init('h11)), \ + .INIT_12(slice_init('h12)), \ + .INIT_13(slice_init('h13)), \ + .INIT_14(slice_init('h14)), \ + .INIT_15(slice_init('h15)), \ + .INIT_16(slice_init('h16)), \ + .INIT_17(slice_init('h17)), \ + .INIT_18(slice_init('h18)), \ + .INIT_19(slice_init('h19)), \ + .INIT_1A(slice_init('h1a)), \ + .INIT_1B(slice_init('h1b)), \ + .INIT_1C(slice_init('h1c)), \ + .INIT_1D(slice_init('h1d)), \ + .INIT_1E(slice_init('h1e)), \ + .INIT_1F(slice_init('h1f)), \ + .INIT_20(slice_init('h20)), \ + .INIT_21(slice_init('h21)), \ + .INIT_22(slice_init('h22)), \ + .INIT_23(slice_init('h23)), \ + .INIT_24(slice_init('h24)), \ + .INIT_25(slice_init('h25)), \ + .INIT_26(slice_init('h26)), \ + .INIT_27(slice_init('h27)), \ + .INIT_28(slice_init('h28)), \ + .INIT_29(slice_init('h29)), \ + .INIT_2A(slice_init('h2a)), \ + .INIT_2B(slice_init('h2b)), \ + .INIT_2C(slice_init('h2c)), \ + .INIT_2D(slice_init('h2d)), \ + .INIT_2E(slice_init('h2e)), \ + .INIT_2F(slice_init('h2f)), \ + .INIT_30(slice_init('h30)), \ + .INIT_31(slice_init('h31)), \ + .INIT_32(slice_init('h32)), \ + .INIT_33(slice_init('h33)), \ + .INIT_34(slice_init('h34)), \ + .INIT_35(slice_init('h35)), \ + .INIT_36(slice_init('h36)), \ + .INIT_37(slice_init('h37)), \ + .INIT_38(slice_init('h38)), \ + .INIT_39(slice_init('h39)), \ + .INIT_3A(slice_init('h3a)), \ + .INIT_3B(slice_init('h3b)), \ + .INIT_3C(slice_init('h3c)), \ + .INIT_3D(slice_init('h3d)), \ + .INIT_3E(slice_init('h3e)), \ + .INIT_3F(slice_init('h3f)), \ + .INIT_40(slice_init('h40)), \ + .INIT_41(slice_init('h41)), \ + .INIT_42(slice_init('h42)), \ + .INIT_43(slice_init('h43)), \ + .INIT_44(slice_init('h44)), \ + .INIT_45(slice_init('h45)), \ + .INIT_46(slice_init('h46)), \ + .INIT_47(slice_init('h47)), \ + .INIT_48(slice_init('h48)), \ + .INIT_49(slice_init('h49)), \ + .INIT_4A(slice_init('h4a)), \ + .INIT_4B(slice_init('h4b)), \ + .INIT_4C(slice_init('h4c)), \ + .INIT_4D(slice_init('h4d)), \ + .INIT_4E(slice_init('h4e)), \ + .INIT_4F(slice_init('h4f)), \ + .INIT_50(slice_init('h50)), \ + .INIT_51(slice_init('h51)), \ + .INIT_52(slice_init('h52)), \ + .INIT_53(slice_init('h53)), \ + .INIT_54(slice_init('h54)), \ + .INIT_55(slice_init('h55)), \ + .INIT_56(slice_init('h56)), \ + .INIT_57(slice_init('h57)), \ + .INIT_58(slice_init('h58)), \ + .INIT_59(slice_init('h59)), \ + .INIT_5A(slice_init('h5a)), \ + .INIT_5B(slice_init('h5b)), \ + .INIT_5C(slice_init('h5c)), \ + .INIT_5D(slice_init('h5d)), \ + .INIT_5E(slice_init('h5e)), \ + .INIT_5F(slice_init('h5f)), \ + .INIT_60(slice_init('h60)), \ + .INIT_61(slice_init('h61)), \ + .INIT_62(slice_init('h62)), \ + .INIT_63(slice_init('h63)), \ + .INIT_64(slice_init('h64)), \ + .INIT_65(slice_init('h65)), \ + .INIT_66(slice_init('h66)), \ + .INIT_67(slice_init('h67)), \ + .INIT_68(slice_init('h68)), \ + .INIT_69(slice_init('h69)), \ + .INIT_6A(slice_init('h6a)), \ + .INIT_6B(slice_init('h6b)), \ + .INIT_6C(slice_init('h6c)), \ + .INIT_6D(slice_init('h6d)), \ + .INIT_6E(slice_init('h6e)), \ + .INIT_6F(slice_init('h6f)), \ + .INIT_70(slice_init('h70)), \ + .INIT_71(slice_init('h71)), \ + .INIT_72(slice_init('h72)), \ + .INIT_73(slice_init('h73)), \ + .INIT_74(slice_init('h74)), \ + .INIT_75(slice_init('h75)), \ + .INIT_76(slice_init('h76)), \ + .INIT_77(slice_init('h77)), \ + .INIT_78(slice_init('h78)), \ + .INIT_79(slice_init('h79)), \ + .INIT_7A(slice_init('h7a)), \ + .INIT_7B(slice_init('h7b)), \ + .INIT_7C(slice_init('h7c)), \ + .INIT_7D(slice_init('h7d)), \ + .INIT_7E(slice_init('h7e)), \ + .INIT_7F(slice_init('h7f)), + +`define PARAMS_INIT_36_U \ + .INIT_00(slice_init('h80)), \ + .INIT_01(slice_init('h81)), \ + .INIT_02(slice_init('h82)), \ + .INIT_03(slice_init('h83)), \ + .INIT_04(slice_init('h84)), \ + .INIT_05(slice_init('h85)), \ + .INIT_06(slice_init('h86)), \ + .INIT_07(slice_init('h87)), \ + .INIT_08(slice_init('h88)), \ + .INIT_09(slice_init('h89)), \ + .INIT_0A(slice_init('h8a)), \ + .INIT_0B(slice_init('h8b)), \ + .INIT_0C(slice_init('h8c)), \ + .INIT_0D(slice_init('h8d)), \ + .INIT_0E(slice_init('h8e)), \ + .INIT_0F(slice_init('h8f)), \ + .INIT_10(slice_init('h90)), \ + .INIT_11(slice_init('h91)), \ + .INIT_12(slice_init('h92)), \ + .INIT_13(slice_init('h93)), \ + .INIT_14(slice_init('h94)), \ + .INIT_15(slice_init('h95)), \ + .INIT_16(slice_init('h96)), \ + .INIT_17(slice_init('h97)), \ + .INIT_18(slice_init('h98)), \ + .INIT_19(slice_init('h99)), \ + .INIT_1A(slice_init('h9a)), \ + .INIT_1B(slice_init('h9b)), \ + .INIT_1C(slice_init('h9c)), \ + .INIT_1D(slice_init('h9d)), \ + .INIT_1E(slice_init('h9e)), \ + .INIT_1F(slice_init('h9f)), \ + .INIT_20(slice_init('ha0)), \ + .INIT_21(slice_init('ha1)), \ + .INIT_22(slice_init('ha2)), \ + .INIT_23(slice_init('ha3)), \ + .INIT_24(slice_init('ha4)), \ + .INIT_25(slice_init('ha5)), \ + .INIT_26(slice_init('ha6)), \ + .INIT_27(slice_init('ha7)), \ + .INIT_28(slice_init('ha8)), \ + .INIT_29(slice_init('ha9)), \ + .INIT_2A(slice_init('haa)), \ + .INIT_2B(slice_init('hab)), \ + .INIT_2C(slice_init('hac)), \ + .INIT_2D(slice_init('had)), \ + .INIT_2E(slice_init('hae)), \ + .INIT_2F(slice_init('haf)), \ + .INIT_30(slice_init('hb0)), \ + .INIT_31(slice_init('hb1)), \ + .INIT_32(slice_init('hb2)), \ + .INIT_33(slice_init('hb3)), \ + .INIT_34(slice_init('hb4)), \ + .INIT_35(slice_init('hb5)), \ + .INIT_36(slice_init('hb6)), \ + .INIT_37(slice_init('hb7)), \ + .INIT_38(slice_init('hb8)), \ + .INIT_39(slice_init('hb9)), \ + .INIT_3A(slice_init('hba)), \ + .INIT_3B(slice_init('hbb)), \ + .INIT_3C(slice_init('hbc)), \ + .INIT_3D(slice_init('hbd)), \ + .INIT_3E(slice_init('hbe)), \ + .INIT_3F(slice_init('hbf)), \ + .INIT_40(slice_init('hc0)), \ + .INIT_41(slice_init('hc1)), \ + .INIT_42(slice_init('hc2)), \ + .INIT_43(slice_init('hc3)), \ + .INIT_44(slice_init('hc4)), \ + .INIT_45(slice_init('hc5)), \ + .INIT_46(slice_init('hc6)), \ + .INIT_47(slice_init('hc7)), \ + .INIT_48(slice_init('hc8)), \ + .INIT_49(slice_init('hc9)), \ + .INIT_4A(slice_init('hca)), \ + .INIT_4B(slice_init('hcb)), \ + .INIT_4C(slice_init('hcc)), \ + .INIT_4D(slice_init('hcd)), \ + .INIT_4E(slice_init('hce)), \ + .INIT_4F(slice_init('hcf)), \ + .INIT_50(slice_init('hd0)), \ + .INIT_51(slice_init('hd1)), \ + .INIT_52(slice_init('hd2)), \ + .INIT_53(slice_init('hd3)), \ + .INIT_54(slice_init('hd4)), \ + .INIT_55(slice_init('hd5)), \ + .INIT_56(slice_init('hd6)), \ + .INIT_57(slice_init('hd7)), \ + .INIT_58(slice_init('hd8)), \ + .INIT_59(slice_init('hd9)), \ + .INIT_5A(slice_init('hda)), \ + .INIT_5B(slice_init('hdb)), \ + .INIT_5C(slice_init('hdc)), \ + .INIT_5D(slice_init('hdd)), \ + .INIT_5E(slice_init('hde)), \ + .INIT_5F(slice_init('hdf)), \ + .INIT_60(slice_init('he0)), \ + .INIT_61(slice_init('he1)), \ + .INIT_62(slice_init('he2)), \ + .INIT_63(slice_init('he3)), \ + .INIT_64(slice_init('he4)), \ + .INIT_65(slice_init('he5)), \ + .INIT_66(slice_init('he6)), \ + .INIT_67(slice_init('he7)), \ + .INIT_68(slice_init('he8)), \ + .INIT_69(slice_init('he9)), \ + .INIT_6A(slice_init('hea)), \ + .INIT_6B(slice_init('heb)), \ + .INIT_6C(slice_init('hec)), \ + .INIT_6D(slice_init('hed)), \ + .INIT_6E(slice_init('hee)), \ + .INIT_6F(slice_init('hef)), \ + .INIT_70(slice_init('hf0)), \ + .INIT_71(slice_init('hf1)), \ + .INIT_72(slice_init('hf2)), \ + .INIT_73(slice_init('hf3)), \ + .INIT_74(slice_init('hf4)), \ + .INIT_75(slice_init('hf5)), \ + .INIT_76(slice_init('hf6)), \ + .INIT_77(slice_init('hf7)), \ + .INIT_78(slice_init('hf8)), \ + .INIT_79(slice_init('hf9)), \ + .INIT_7A(slice_init('hfa)), \ + .INIT_7B(slice_init('hfb)), \ + .INIT_7C(slice_init('hfc)), \ + .INIT_7D(slice_init('hfd)), \ + .INIT_7E(slice_init('hfe)), \ + .INIT_7F(slice_init('hff)), + +`define PARAMS_INITP_36 \ + .INITP_00(slice_initp('h00)), \ + .INITP_01(slice_initp('h01)), \ + .INITP_02(slice_initp('h02)), \ + .INITP_03(slice_initp('h03)), \ + .INITP_04(slice_initp('h04)), \ + .INITP_05(slice_initp('h05)), \ + .INITP_06(slice_initp('h06)), \ + .INITP_07(slice_initp('h07)), \ + .INITP_08(slice_initp('h08)), \ + .INITP_09(slice_initp('h09)), \ + .INITP_0A(slice_initp('h0a)), \ + .INITP_0B(slice_initp('h0b)), \ + .INITP_0C(slice_initp('h0c)), \ + .INITP_0D(slice_initp('h0d)), \ + .INITP_0E(slice_initp('h0e)), \ + .INITP_0F(slice_initp('h0f)), + +`define MAKE_DO(do, dop, rdata) \ + wire [63:0] do; \ + wire [7:0] dop; \ + assign rdata = { \ + dop[7], \ + do[63:56], \ + dop[6], \ + do[55:48], \ + dop[5], \ + do[47:40], \ + dop[4], \ + do[39:32], \ + dop[3], \ + do[31:24], \ + dop[2], \ + do[23:16], \ + dop[1], \ + do[15:8], \ + dop[0], \ + do[7:0] \ + }; + +`define MAKE_DI(di, dip, wdata) \ + wire [63:0] di; \ + wire [7:0] dip; \ + assign { \ + dip[7], \ + di[63:56], \ + dip[6], \ + di[55:48], \ + dip[5], \ + di[47:40], \ + dip[4], \ + di[39:32], \ + dip[3], \ + di[31:24], \ + dip[2], \ + di[23:16], \ + dip[1], \ + di[15:8], \ + dip[0], \ + di[7:0] \ + } = wdata; + +function [71:0] ival; + input integer width; + input [71:0] val; + if (width == 72) + ival = { + val[71], + val[62], + val[53], + val[44], + val[35], + val[26], + val[17], + val[8], + val[70:63], + val[61:54], + val[52:45], + val[43:36], + val[34:27], + val[25:18], + val[16:9], + val[7:0] + }; + else if (width == 36) + ival = { + val[35], + val[26], + val[17], + val[8], + val[34:27], + val[25:18], + val[16:9], + val[7:0] + }; + else if (width == 18) + ival = { + val[17], + val[8], + val[16:9], + val[7:0] + }; + else + ival = val; +endfunction + +function [255:0] slice_init; + input integer idx; + integer i; + for (i = 0; i < 32; i = i + 1) + slice_init[i*8+:8] = INIT[(idx * 32 + i)*9+:8]; +endfunction + +function [255:0] slice_initp; + input integer idx; + integer i; + for (i = 0; i < 256; i = i + 1) + slice_initp[i] = INIT[(idx * 256 + i)*9+8]; +endfunction diff --git a/techlibs/xilinx/brams_init.py b/techlibs/xilinx/brams_init.py deleted file mode 100644 index 10057a0cb..000000000 --- a/techlibs/xilinx/brams_init.py +++ /dev/null @@ -1,50 +0,0 @@ -#!/usr/bin/env python3 - -with open("techlibs/xilinx/brams_init_9.vh", "w") as f: - for i in range(4): - init_snippets = [" INIT[%3d*9+8]" % (k+256*i,) for k in range(255, -1, -1)] - for k in range(4, 256, 4): - init_snippets[k] = "\n " + init_snippets[k] - print(".INITP_%02X({%s})," % (i, ",".join(init_snippets)), file=f) - for i in range(32): - init_snippets = [" INIT[%3d*9 +: 8]" % (k+32*i,) for k in range(31, -1, -1)] - for k in range(4, 32, 4): - init_snippets[k] = "\n " + init_snippets[k] - print(".INIT_%02X({%s})," % (i, ",".join(init_snippets)), file=f) - -with open("techlibs/xilinx/brams_init_18.vh", "w") as f: - for i in range(8): - init_snippets = [" INIT[%3d*9+8]" % (k+256*i,) for k in range(255, -1, -1)] - for k in range(4, 256, 4): - init_snippets[k] = "\n " + init_snippets[k] - print(".INITP_%02X({%s})," % (i, ",".join(init_snippets)), file=f) - for i in range(64): - init_snippets = [" INIT[%3d*9 +: 8]" % (k+32*i,) for k in range(31, -1, -1)] - for k in range(4, 32, 4): - init_snippets[k] = "\n " + init_snippets[k] - print(".INIT_%02X({%s})," % (i, ",".join(init_snippets)), file=f) - -with open("techlibs/xilinx/brams_init_36.vh", "w") as f: - for i in range(16): - init_snippets = [" INIT[%3d*9+8]" % (k+256*i,) for k in range(255, -1, -1)] - for k in range(4, 256, 4): - init_snippets[k] = "\n " + init_snippets[k] - print(".INITP_%02X({%s})," % (i, ",".join(init_snippets)), file=f) - for i in range(128): - init_snippets = [" INIT[%3d*9 +: 8]" % (k+32*i,) for k in range(31, -1, -1)] - for k in range(4, 32, 4): - init_snippets[k] = "\n " + init_snippets[k] - print(".INIT_%02X({%s})," % (i, ",".join(init_snippets)), file=f) - -with open("techlibs/xilinx/brams_init_8.vh", "w") as f: - for i in range(32): - print(".INIT_%02X(INIT[%3d*256 +: 256])," % (i, i), file=f) - -with open("techlibs/xilinx/brams_init_16.vh", "w") as f: - for i in range(64): - print(".INIT_%02X(INIT[%3d*256 +: 256])," % (i, i), file=f) - -with open("techlibs/xilinx/brams_init_32.vh", "w") as f: - for i in range(128): - print(".INIT_%02X(INIT[%3d*256 +: 256])," % (i, i), file=f) - diff --git a/techlibs/xilinx/brams_xc2v.txt b/techlibs/xilinx/brams_xc2v.txt new file mode 100644 index 000000000..562148c21 --- /dev/null +++ b/techlibs/xilinx/brams_xc2v.txt @@ -0,0 +1,33 @@ +# Block RAMs for Virtex 2, Spartan 3, Spartan 3E, Spartan 3A(N) +# The corresponding mapping file is brams_xc2v_map.v + +ram block $__XILINX_BLOCKRAM_ { + abits 14; + widths 1 2 4 9 18 36 per_port; + ifdef HAS_BE { + option "USE_BE" 1 byte 9; + } + cost 129; + init any; + port srsw "A" "B" { + option "USE_BE" 0 width tied; + ifdef HAS_BE { + option "USE_BE" 1 width tied 9 18 36; + } + clock posedge; + clken; + rdsrst any gated_clken; + rdinit any; + portoption "WRITE_MODE" "NO_CHANGE" { + rdwr no_change; + } + portoption "WRITE_MODE" "WRITE_FIRST" { + rdwr new_only; + } + portoption "WRITE_MODE" "READ_FIRST" { + rdwr old; + wrtrans all old; + } + optional; + } +} diff --git a/techlibs/xilinx/brams_xc2v_map.v b/techlibs/xilinx/brams_xc2v_map.v new file mode 100644 index 000000000..a82feff60 --- /dev/null +++ b/techlibs/xilinx/brams_xc2v_map.v @@ -0,0 +1,532 @@ +module $__XILINX_BLOCKRAM_ (...); + +parameter INIT = 0; +parameter OPTION_USE_BE = 0; + +parameter PORT_A_WIDTH = 1; +parameter PORT_A_WR_EN_WIDTH = 1; +parameter PORT_A_USED = 1; +parameter PORT_A_OPTION_WRITE_MODE = "NO_CHANGE"; +parameter PORT_A_RD_INIT_VALUE = 0; +parameter PORT_A_RD_SRST_VALUE = 0; + +parameter PORT_B_WIDTH = 1; +parameter PORT_B_WR_EN_WIDTH = 1; +parameter PORT_B_USED = 0; +parameter PORT_B_OPTION_WRITE_MODE = "NO_CHANGE"; +parameter PORT_B_RD_INIT_VALUE = 0; +parameter PORT_B_RD_SRST_VALUE = 0; + +input PORT_A_CLK; +input PORT_A_CLK_EN; +input [13:0] PORT_A_ADDR; +input [PORT_A_WIDTH-1:0] PORT_A_WR_DATA; +input [PORT_A_WR_EN_WIDTH-1:0] PORT_A_WR_EN; +output [PORT_A_WIDTH-1:0] PORT_A_RD_DATA; +input PORT_A_RD_SRST; + +input PORT_B_CLK; +input PORT_B_CLK_EN; +input [13:0] PORT_B_ADDR; +input [PORT_B_WIDTH-1:0] PORT_B_WR_DATA; +input [PORT_B_WR_EN_WIDTH-1:0] PORT_B_WR_EN; +output [PORT_B_WIDTH-1:0] PORT_B_RD_DATA; +input PORT_B_RD_SRST; + +`include "brams_defs.vh" + +`define PARAMS_DP \ + `PARAMS_INIT_18 \ + .WRITE_MODE_A(PORT_A_OPTION_WRITE_MODE), \ + .WRITE_MODE_B(PORT_B_OPTION_WRITE_MODE), \ + .SRVAL_A(SRVAL_A), \ + .SRVAL_B(SRVAL_B), \ + .INIT_A(INIT_A), \ + .INIT_B(INIT_B), + +`define PARAMS_DP_SWAP \ + `PARAMS_INIT_18 \ + .WRITE_MODE_A(PORT_B_OPTION_WRITE_MODE), \ + .WRITE_MODE_B(PORT_A_OPTION_WRITE_MODE), \ + .SRVAL_A(SRVAL_B), \ + .SRVAL_B(SRVAL_A), \ + .INIT_A(INIT_B), \ + .INIT_B(INIT_A), + +`define PARAMS_SP \ + `PARAMS_INIT_18 \ + .WRITE_MODE(PORT_A_OPTION_WRITE_MODE), \ + .SRVAL(SRVAL_A), \ + .INIT(INIT_A), + +`define PORTS_DP(addr_slice_a, addr_slice_b) \ + .CLKA(PORT_A_CLK), \ + .ENA(PORT_A_CLK_EN), \ + .WEA(PORT_A_WR_EN), \ + .SSRA(PORT_A_RD_SRST), \ + .ADDRA(PORT_A_ADDR addr_slice_a), \ + .DOA(DO_A), \ + .DIA(DI_A), \ + .CLKB(PORT_B_CLK), \ + .ENB(PORT_B_CLK_EN), \ + .WEB(PORT_B_WR_EN), \ + .SSRB(PORT_B_RD_SRST), \ + .ADDRB(PORT_B_ADDR addr_slice_b), \ + .DOB(DO_B), \ + .DIB(DI_B), + +`define PORTS_DP_SWAP(addr_slice_a, addr_slice_b) \ + .CLKB(PORT_A_CLK), \ + .ENB(PORT_A_CLK_EN), \ + .WEB(PORT_A_WR_EN), \ + .SSRB(PORT_A_RD_SRST), \ + .ADDRB(PORT_A_ADDR addr_slice_a), \ + .DOB(DO_A), \ + .DIB(DI_A), \ + .CLKA(PORT_B_CLK), \ + .ENA(PORT_B_CLK_EN), \ + .WEA(PORT_B_WR_EN), \ + .SSRA(PORT_B_RD_SRST), \ + .ADDRA(PORT_B_ADDR addr_slice_b), \ + .DOA(DO_B), \ + .DIA(DI_B), + +`define PORTS_SP(addr_slice) \ + .CLK(PORT_A_CLK), \ + .EN(PORT_A_CLK_EN), \ + .WE(PORT_A_WR_EN), \ + .SSR(PORT_A_RD_SRST), \ + .ADDR(PORT_A_ADDR addr_slice), \ + .DO(DO_A), \ + .DI(DI_A), + +localparam [PORT_A_WIDTH-1:0] SRVAL_A = ival(PORT_A_WIDTH, PORT_A_RD_SRST_VALUE); +localparam [PORT_B_WIDTH-1:0] SRVAL_B = ival(PORT_B_WIDTH, PORT_B_RD_SRST_VALUE); +localparam [PORT_A_WIDTH-1:0] INIT_A = ival(PORT_A_WIDTH, PORT_A_RD_INIT_VALUE); +localparam [PORT_B_WIDTH-1:0] INIT_B = ival(PORT_B_WIDTH, PORT_B_RD_INIT_VALUE); + +`MAKE_DI(DI_A, DIP_A, PORT_A_WR_DATA) +`MAKE_DI(DI_B, DIP_B, PORT_B_WR_DATA) +`MAKE_DO(DO_A, DOP_A, PORT_A_RD_DATA) +`MAKE_DO(DO_B, DOP_B, PORT_B_RD_DATA) + +generate + +if (OPTION_USE_BE) begin + if (!PORT_B_USED) begin + case (PORT_A_WIDTH) + 9: RAMB16_S9 #( + `PARAMS_SP + `PARAMS_INITP_18 + ) _TECHMAP_REPLACE_ ( + `PORTS_SP([13:3]) + .DIP(DIP_A), + .DOP(DOP_A), + ); + 18: RAMB16BWE_S18 #( + `PARAMS_SP + `PARAMS_INITP_18 + ) _TECHMAP_REPLACE_ ( + `PORTS_SP([13:4]) + .DIP(DIP_A), + .DOP(DOP_A), + ); + 36: RAMB16BWE_S36 #( + `PARAMS_SP + `PARAMS_INITP_18 + ) _TECHMAP_REPLACE_ ( + `PORTS_SP([13:5]) + .DIP(DIP_A), + .DOP(DOP_A), + ); + endcase + end else begin + case (PORT_A_WIDTH) + 9: case(PORT_B_WIDTH) + 9: RAMB16_S9_S9 #( + `PARAMS_DP + `PARAMS_INITP_18 + ) _TECHMAP_REPLACE_ ( + `PORTS_DP([13:3], [13:3]) + .DIPA(DIP_A), .DOPA(DOP_A), + .DIPB(DIP_B), .DOPB(DOP_B), + ); + 18: RAMB16BWE_S9_S18 #( + `PARAMS_DP + `PARAMS_INITP_18 + ) _TECHMAP_REPLACE_ ( + `PORTS_DP([13:3], [13:4]) + .DIPA(DIP_A), .DOPA(DOP_A), + .DIPB(DIP_B), .DOPB(DOP_B), + ); + 36: RAMB16BWE_S9_S36 #( + `PARAMS_DP + `PARAMS_INITP_18 + ) _TECHMAP_REPLACE_ ( + `PORTS_DP([13:3], [13:5]) + .DIPA(DIP_A), .DOPA(DOP_A), + .DIPB(DIP_B), .DOPB(DOP_B), + ); + endcase + 18: case(PORT_B_WIDTH) + 9: RAMB16BWE_S9_S18 #( + `PARAMS_DP_SWAP + `PARAMS_INITP_18 + ) _TECHMAP_REPLACE_ ( + `PORTS_DP_SWAP([13:4], [13:3]) + .DIPA(DIP_B), .DOPA(DOP_B), + .DIPB(DIP_A), .DOPB(DOP_A), + ); + 18: RAMB16BWE_S18_S18 #( + `PARAMS_DP + `PARAMS_INITP_18 + ) _TECHMAP_REPLACE_ ( + `PORTS_DP([13:4], [13:4]) + .DIPA(DIP_A), .DOPA(DOP_A), + .DIPB(DIP_B), .DOPB(DOP_B), + ); + 36: RAMB16BWE_S18_S36 #( + `PARAMS_DP + `PARAMS_INITP_18 + ) _TECHMAP_REPLACE_ ( + `PORTS_DP([13:4], [13:5]) + .DIPA(DIP_A), .DOPA(DOP_A), + .DIPB(DIP_B), .DOPB(DOP_B), + ); + endcase + 36: case(PORT_B_WIDTH) + 9: RAMB16BWE_S9_S36 #( + `PARAMS_DP_SWAP + `PARAMS_INITP_18 + ) _TECHMAP_REPLACE_ ( + `PORTS_DP_SWAP([13:5], [13:3]) + .DIPA(DIP_B), .DOPA(DOP_B), + .DIPB(DIP_A), .DOPB(DOP_A), + ); + 18: RAMB16BWE_S18_S36 #( + `PARAMS_DP_SWAP + `PARAMS_INITP_18 + ) _TECHMAP_REPLACE_ ( + `PORTS_DP_SWAP([13:5], [13:4]) + .DIPA(DIP_B), .DOPA(DOP_B), + .DIPB(DIP_A), .DOPB(DOP_A), + ); + 36: RAMB16BWE_S36_S36 #( + `PARAMS_DP + `PARAMS_INITP_18 + ) _TECHMAP_REPLACE_ ( + `PORTS_DP([13:5], [13:5]) + .DIPA(DIP_A), .DOPA(DOP_A), + .DIPB(DIP_B), .DOPB(DOP_B), + ); + endcase + endcase + end +end else begin + if (!PORT_B_USED) begin + case (PORT_A_WIDTH) + 1: RAMB16_S1 #( + `PARAMS_SP + ) _TECHMAP_REPLACE_ ( + `PORTS_SP([13:0]) + ); + 2: RAMB16_S2 #( + `PARAMS_SP + ) _TECHMAP_REPLACE_ ( + `PORTS_SP([13:1]) + ); + 4: RAMB16_S4 #( + `PARAMS_SP + ) _TECHMAP_REPLACE_ ( + `PORTS_SP([13:2]) + ); + 9: RAMB16_S9 #( + `PARAMS_SP + `PARAMS_INITP_18 + ) _TECHMAP_REPLACE_ ( + `PORTS_SP([13:3]) + .DIP(DIP_A), + .DOP(DOP_A), + ); + 18: RAMB16_S18 #( + `PARAMS_SP + `PARAMS_INITP_18 + ) _TECHMAP_REPLACE_ ( + `PORTS_SP([13:4]) + .DIP(DIP_A), + .DOP(DOP_A), + ); + 36: RAMB16_S36 #( + `PARAMS_SP + `PARAMS_INITP_18 + ) _TECHMAP_REPLACE_ ( + `PORTS_SP([13:5]) + .DIP(DIP_A), + .DOP(DOP_A), + ); + endcase + end else begin + case (PORT_A_WIDTH) + 1: case(PORT_B_WIDTH) + 1: RAMB16_S1_S1 #( + `PARAMS_DP + ) _TECHMAP_REPLACE_ ( + `PORTS_DP([13:0], [13:0]) + ); + 2: RAMB16_S1_S2 #( + `PARAMS_DP + ) _TECHMAP_REPLACE_ ( + `PORTS_DP([13:0], [13:1]) + ); + 4: RAMB16_S1_S4 #( + `PARAMS_DP + ) _TECHMAP_REPLACE_ ( + `PORTS_DP([13:0], [13:2]) + ); + 9: RAMB16_S1_S9 #( + `PARAMS_DP + `PARAMS_INITP_18 + ) _TECHMAP_REPLACE_ ( + `PORTS_DP([13:0], [13:3]) + .DIPB(DIP_B), .DOPB(DOP_B), + ); + 18: RAMB16_S1_S18 #( + `PARAMS_DP + `PARAMS_INITP_18 + ) _TECHMAP_REPLACE_ ( + `PORTS_DP([13:0], [13:4]) + .DIPB(DIP_B), .DOPB(DOP_B), + ); + 36: RAMB16_S1_S36 #( + `PARAMS_DP + `PARAMS_INITP_18 + ) _TECHMAP_REPLACE_ ( + `PORTS_DP([13:0], [13:5]) + .DIPB(DIP_B), .DOPB(DOP_B), + ); + endcase + 2: case(PORT_B_WIDTH) + 1: RAMB16_S1_S2 #( + `PARAMS_DP_SWAP + ) _TECHMAP_REPLACE_ ( + `PORTS_DP_SWAP([13:1], [13:0]) + ); + 2: RAMB16_S2_S2 #( + `PARAMS_DP + ) _TECHMAP_REPLACE_ ( + `PORTS_DP([13:1], [13:1]) + ); + 4: RAMB16_S2_S4 #( + `PARAMS_DP + ) _TECHMAP_REPLACE_ ( + `PORTS_DP([13:1], [13:2]) + ); + 9: RAMB16_S2_S9 #( + `PARAMS_DP + `PARAMS_INITP_18 + ) _TECHMAP_REPLACE_ ( + `PORTS_DP([13:1], [13:3]) + .DIPB(DIP_B), .DOPB(DOP_B), + ); + 18: RAMB16_S2_S18 #( + `PARAMS_DP + `PARAMS_INITP_18 + ) _TECHMAP_REPLACE_ ( + `PORTS_DP([13:1], [13:4]) + .DIPB(DIP_B), .DOPB(DOP_B), + ); + 36: RAMB16_S2_S36 #( + `PARAMS_DP + `PARAMS_INITP_18 + ) _TECHMAP_REPLACE_ ( + `PORTS_DP([13:1], [13:5]) + .DIPB(DIP_B), .DOPB(DOP_B), + ); + endcase + 4: case(PORT_B_WIDTH) + 1: RAMB16_S1_S4 #( + `PARAMS_DP_SWAP + ) _TECHMAP_REPLACE_ ( + `PORTS_DP_SWAP([13:2], [13:0]) + ); + 2: RAMB16_S2_S4 #( + `PARAMS_DP_SWAP + ) _TECHMAP_REPLACE_ ( + `PORTS_DP_SWAP([13:2], [13:1]) + ); + 4: RAMB16_S4_S4 #( + `PARAMS_DP + ) _TECHMAP_REPLACE_ ( + `PORTS_DP([13:2], [13:2]) + ); + 9: RAMB16_S4_S9 #( + `PARAMS_DP + `PARAMS_INITP_18 + ) _TECHMAP_REPLACE_ ( + `PORTS_DP([13:2], [13:3]) + .DIPB(DIP_B), .DOPB(DOP_B), + ); + 18: RAMB16_S4_S18 #( + `PARAMS_DP + `PARAMS_INITP_18 + ) _TECHMAP_REPLACE_ ( + `PORTS_DP([13:2], [13:4]) + .DIPB(DIP_B), .DOPB(DOP_B), + ); + 36: RAMB16_S4_S36 #( + `PARAMS_DP + `PARAMS_INITP_18 + ) _TECHMAP_REPLACE_ ( + `PORTS_DP([13:2], [13:5]) + .DIPB(DIP_B), .DOPB(DOP_B), + ); + endcase + 9: case(PORT_B_WIDTH) + 1: RAMB16_S1_S9 #( + `PARAMS_DP_SWAP + `PARAMS_INITP_18 + ) _TECHMAP_REPLACE_ ( + `PORTS_DP_SWAP([13:3], [13:0]) + .DIPB(DIP_A), .DOPB(DOP_A), + ); + 2: RAMB16_S2_S9 #( + `PARAMS_DP_SWAP + `PARAMS_INITP_18 + ) _TECHMAP_REPLACE_ ( + `PORTS_DP_SWAP([13:3], [13:1]) + .DIPB(DIP_A), .DOPB(DOP_A), + ); + 4: RAMB16_S4_S9 #( + `PARAMS_DP_SWAP + `PARAMS_INITP_18 + ) _TECHMAP_REPLACE_ ( + `PORTS_DP_SWAP([13:3], [13:2]) + .DIPB(DIP_A), .DOPB(DOP_A), + ); + 9: RAMB16_S9_S9 #( + `PARAMS_DP + `PARAMS_INITP_18 + ) _TECHMAP_REPLACE_ ( + `PORTS_DP([13:3], [13:3]) + .DIPA(DIP_A), .DOPA(DOP_A), + .DIPB(DIP_B), .DOPB(DOP_B), + ); + 18: RAMB16_S9_S18 #( + `PARAMS_DP + `PARAMS_INITP_18 + ) _TECHMAP_REPLACE_ ( + `PORTS_DP([13:3], [13:4]) + .DIPA(DIP_A), .DOPA(DOP_A), + .DIPB(DIP_B), .DOPB(DOP_B), + ); + 36: RAMB16_S9_S36 #( + `PARAMS_DP + `PARAMS_INITP_18 + ) _TECHMAP_REPLACE_ ( + `PORTS_DP([13:3], [13:5]) + .DIPA(DIP_A), .DOPA(DOP_A), + .DIPB(DIP_B), .DOPB(DOP_B), + ); + endcase + 18: case(PORT_B_WIDTH) + 1: RAMB16_S1_S18 #( + `PARAMS_DP_SWAP + `PARAMS_INITP_18 + ) _TECHMAP_REPLACE_ ( + `PORTS_DP_SWAP([13:4], [13:0]) + .DIPB(DIP_A), .DOPB(DOP_A), + ); + 2: RAMB16_S2_S18 #( + `PARAMS_DP_SWAP + `PARAMS_INITP_18 + ) _TECHMAP_REPLACE_ ( + `PORTS_DP_SWAP([13:4], [13:1]) + .DIPB(DIP_A), .DOPB(DOP_A), + ); + 4: RAMB16_S4_S18 #( + `PARAMS_DP_SWAP + `PARAMS_INITP_18 + ) _TECHMAP_REPLACE_ ( + `PORTS_DP_SWAP([13:4], [13:2]) + .DIPB(DIP_A), .DOPB(DOP_A), + ); + 9: RAMB16_S9_S18 #( + `PARAMS_DP_SWAP + `PARAMS_INITP_18 + ) _TECHMAP_REPLACE_ ( + `PORTS_DP_SWAP([13:4], [13:3]) + .DIPA(DIP_B), .DOPA(DOP_B), + .DIPB(DIP_A), .DOPB(DOP_A), + ); + 18: RAMB16_S18_S18 #( + `PARAMS_DP + `PARAMS_INITP_18 + ) _TECHMAP_REPLACE_ ( + `PORTS_DP([13:4], [13:4]) + .DIPA(DIP_A), .DOPA(DOP_A), + .DIPB(DIP_B), .DOPB(DOP_B), + ); + 36: RAMB16_S18_S36 #( + `PARAMS_DP + `PARAMS_INITP_18 + ) _TECHMAP_REPLACE_ ( + `PORTS_DP([13:4], [13:5]) + .DIPA(DIP_A), .DOPA(DOP_A), + .DIPB(DIP_B), .DOPB(DOP_B), + ); + endcase + 36: case(PORT_B_WIDTH) + 1: RAMB16_S1_S36 #( + `PARAMS_DP_SWAP + `PARAMS_INITP_18 + ) _TECHMAP_REPLACE_ ( + `PORTS_DP_SWAP([13:5], [13:0]) + .DIPB(DIP_A), .DOPB(DOP_A), + ); + 2: RAMB16_S2_S36 #( + `PARAMS_DP_SWAP + `PARAMS_INITP_18 + ) _TECHMAP_REPLACE_ ( + `PORTS_DP_SWAP([13:5], [13:1]) + .DIPB(DIP_A), .DOPB(DOP_A), + ); + 4: RAMB16_S4_S36 #( + `PARAMS_DP_SWAP + `PARAMS_INITP_18 + ) _TECHMAP_REPLACE_ ( + `PORTS_DP_SWAP([13:5], [13:2]) + .DIPB(DIP_A), .DOPB(DOP_A), + ); + 9: RAMB16_S9_S36 #( + `PARAMS_DP_SWAP + `PARAMS_INITP_18 + ) _TECHMAP_REPLACE_ ( + `PORTS_DP_SWAP([13:5], [13:3]) + .DIPA(DIP_B), .DOPA(DOP_B), + .DIPB(DIP_A), .DOPB(DOP_A), + ); + 18: RAMB16_S18_S36 #( + `PARAMS_DP_SWAP + `PARAMS_INITP_18 + ) _TECHMAP_REPLACE_ ( + `PORTS_DP_SWAP([13:5], [13:4]) + .DIPA(DIP_B), .DOPA(DOP_B), + .DIPB(DIP_A), .DOPB(DOP_A), + ); + 36: RAMB16_S36_S36 #( + `PARAMS_DP + `PARAMS_INITP_18 + ) _TECHMAP_REPLACE_ ( + `PORTS_DP([13:5], [13:5]) + .DIPA(DIP_A), .DOPA(DOP_A), + .DIPB(DIP_B), .DOPB(DOP_B), + ); + endcase + endcase + end +end + +endgenerate + + +endmodule diff --git a/techlibs/xilinx/brams_xc3sda.txt b/techlibs/xilinx/brams_xc3sda.txt new file mode 100644 index 000000000..451999150 --- /dev/null +++ b/techlibs/xilinx/brams_xc3sda.txt @@ -0,0 +1,120 @@ +# Block RAMs for Spartan 3A DSP and Spartan 6. +# The corresponding mapping file is brams_xc3sda_map.v + +ram block $__XILINX_BLOCKRAM_TDP_ { + byte 9; + ifdef IS_SPARTAN6 { + option "MODE" "HALF" { + abits 13; + widths 1 2 4 9 18 per_port; + cost 65; + } + } + option "MODE" "FULL" { + abits 14; + widths 1 2 4 9 18 36 per_port; + cost 129; + } + init any; + port srsw "A" "B" { + # Spartan 6 and Virtex 6 have a bug where READ_FIRST is not usable with asynchronous clocks. + ifdef IS_SPARTAN6 { + option "HAS_RDFIRST" 1 { + clock posedge "C"; + } + option "HAS_RDFIRST" 0 { + clock posedge; + } + } else { + clock posedge; + } + clken; + option "RSTTYPE" "SYNC" { + portoption "RST_PRIORITY" "CE" { + rdsrst any gated_clken; + } + ifdef IS_SPARTAN6 { + portoption "RST_PRIORITY" "SR" { + rdsrst any ungated; + } + } + } + ifdef IS_SPARTAN6 { + option "RSTTYPE" "ASYNC" { + portoption "RST_PRIORITY" "SR" { + rdarst any; + } + } + } + rdinit any; + portoption "WRITE_MODE" "NO_CHANGE" { + rdwr no_change; + } + portoption "WRITE_MODE" "WRITE_FIRST" { + rdwr new; + } + ifdef IS_SPARTAN6 { + option "HAS_RDFIRST" 1 { + portoption "WRITE_MODE" "READ_FIRST" { + rdwr old; + wrtrans all old; + } + } + } else { + portoption "WRITE_MODE" "READ_FIRST" { + rdwr old; + wrtrans all old; + } + } + optional; + } +} + +ifdef IS_SPARTAN6 { + ram block $__XILINX_BLOCKRAM_SDP_ { + byte 9; + abits 13; + widths 1 2 4 9 18 36 per_port; + cost 65; + init any; + port sw "W" { + width 36; + # Spartan 6 and Virtex 6 have a bug where READ_FIRST is not usable with asynchronous clocks. + option "WRITE_MODE" "READ_FIRST" { + clock posedge "C"; + wrtrans all old; + } + option "WRITE_MODE" "WRITE_FIRST" { + clock posedge; + } + clken; + optional; + } + port sr "R" { + width 36; + # Spartan 6 and Virtex 6 have a bug where READ_FIRST is not usable with asynchronous clocks. + option "WRITE_MODE" "READ_FIRST" { + clock posedge "C"; + } + option "WRITE_MODE" "WRITE_FIRST" { + clock posedge; + } + clken; + option "RSTTYPE" "SYNC" { + portoption "RST_PRIORITY" "CE" { + rdsrst any gated_clken; + } + portoption "RST_PRIORITY" "SR" { + rdsrst any ungated; + } + } + option "RSTTYPE" "ASYNC" { + portoption "RST_PRIORITY" "SR" { + rdarst any; + } + } + rdinit any; + optional; + } + } +} diff --git a/techlibs/xilinx/brams_xc3sda_map.v b/techlibs/xilinx/brams_xc3sda_map.v new file mode 100644 index 000000000..f5f0e5aa1 --- /dev/null +++ b/techlibs/xilinx/brams_xc3sda_map.v @@ -0,0 +1,224 @@ +module $__XILINX_BLOCKRAM_TDP_ (...); + +parameter INIT = 0; +parameter OPTION_MODE = "FULL"; +parameter OPTION_RSTTYPE = "SYNC"; +parameter OPTION_HAS_RDFIRST = 0; + +parameter PORT_A_WIDTH = 1; +parameter PORT_A_WR_EN_WIDTH = 1; +parameter PORT_A_USED = 1; +parameter PORT_A_OPTION_WRITE_MODE = "NO_CHANGE"; +parameter PORT_A_RD_INIT_VALUE = 0; +parameter PORT_A_RD_SRST_VALUE = 0; +parameter PORT_A_RD_ARST_VALUE = 0; +parameter PORT_A_OPTION_RST_PRIORITY = "CE"; + +parameter PORT_B_WIDTH = 1; +parameter PORT_B_WR_EN_WIDTH = 1; +parameter PORT_B_USED = 0; +parameter PORT_B_OPTION_WRITE_MODE = "NO_CHANGE"; +parameter PORT_B_RD_INIT_VALUE = 0; +parameter PORT_B_RD_SRST_VALUE = 0; +parameter PORT_B_RD_ARST_VALUE = 0; +parameter PORT_B_OPTION_RST_PRIORITY = "CE"; + +input CLK_C; + +input PORT_A_CLK; +input PORT_A_CLK_EN; +input [13:0] PORT_A_ADDR; +input [PORT_A_WIDTH-1:0] PORT_A_WR_DATA; +input [PORT_A_WR_EN_WIDTH-1:0] PORT_A_WR_EN; +output [PORT_A_WIDTH-1:0] PORT_A_RD_DATA; +input PORT_A_RD_SRST; +input PORT_A_RD_ARST; + +input PORT_B_CLK; +input PORT_B_CLK_EN; +input [13:0] PORT_B_ADDR; +input [PORT_B_WIDTH-1:0] PORT_B_WR_DATA; +input [PORT_B_WR_EN_WIDTH-1:0] PORT_B_WR_EN; +output [PORT_B_WIDTH-1:0] PORT_B_RD_DATA; +input PORT_B_RD_SRST; +input PORT_B_RD_ARST; + +`include "brams_defs.vh" + +`define PARAMS_COMMON \ + .WRITE_MODE_A(PORT_A_OPTION_WRITE_MODE), \ + .WRITE_MODE_B(PORT_B_OPTION_WRITE_MODE), \ + .DATA_WIDTH_A(PORT_A_USED ? PORT_A_WIDTH : 0), \ + .DATA_WIDTH_B(PORT_B_USED ? PORT_B_WIDTH : 0), \ + .EN_RSTRAM_A("TRUE"), \ + .EN_RSTRAM_B("TRUE"), \ + .DOA_REG(0), \ + .DOB_REG(0), \ + .RST_PRIORITY_A(PORT_A_OPTION_RST_PRIORITY), \ + .RST_PRIORITY_B(PORT_B_OPTION_RST_PRIORITY), \ + .RSTTYPE(OPTION_RSTTYPE), \ + .INIT_A(ival(PORT_A_WIDTH, PORT_A_RD_INIT_VALUE)), \ + .INIT_B(ival(PORT_B_WIDTH, PORT_B_RD_INIT_VALUE)), \ + .SRVAL_A(ival(PORT_A_WIDTH, OPTION_RSTTYPE == "SYNC" ? PORT_A_RD_SRST_VALUE : PORT_A_RD_ARST_VALUE)), \ + .SRVAL_B(ival(PORT_B_WIDTH, OPTION_RSTTYPE == "SYNC" ? PORT_B_RD_SRST_VALUE : PORT_B_RD_ARST_VALUE)), + +wire RST_A = OPTION_RSTTYPE == "SYNC" ? PORT_A_RD_SRST : PORT_A_RD_ARST; +wire RST_B = OPTION_RSTTYPE == "SYNC" ? PORT_B_RD_SRST : PORT_B_RD_ARST; + +`MAKE_DI(DI_A, DIP_A, PORT_A_WR_DATA) +`MAKE_DI(DI_B, DIP_B, PORT_B_WR_DATA) +`MAKE_DO(DO_A, DOP_A, PORT_A_RD_DATA) +`MAKE_DO(DO_B, DOP_B, PORT_B_RD_DATA) + +generate + +if (OPTION_MODE == "FULL") begin + wire [3:0] WE_A = {4{PORT_A_WR_EN}}; + wire [3:0] WE_B = {4{PORT_B_WR_EN}}; + RAMB16BWER #( + `PARAMS_INIT_18 + `PARAMS_INITP_18 + `PARAMS_COMMON + ) _TECHMAP_REPLACE_ ( + .DOA(DO_A), + .DOPA(DOP_A), + .DIA(DI_A), + .DIPA(DIP_A), + .DOB(DO_B), + .DOPB(DOP_B), + .DIB(DI_B), + .DIPB(DIP_B), + .ADDRA(PORT_A_ADDR), + .ADDRB(PORT_B_ADDR), + .CLKA(PORT_A_CLK), + .CLKB(PORT_B_CLK), + .ENA(PORT_A_CLK_EN), + .ENB(PORT_B_CLK_EN), + .REGCEA(1'b0), + .REGCEB(1'b0), + .RSTA(RST_A), + .RSTB(RST_B), + .WEA(WE_A), + .WEB(WE_B), + ); +end else begin + wire [1:0] WE_A = {2{PORT_A_WR_EN}}; + wire [1:0] WE_B = {2{PORT_B_WR_EN}}; + RAMB8BWER #( + `PARAMS_INIT_9 + `PARAMS_INITP_9 + `PARAMS_COMMON + .RAM_MODE("TDP"), + ) _TECHMAP_REPLACE_ ( + .DOADO(DO_A), + .DOPADOP(DOP_A), + .DIADI(DI_A), + .DIPADIP(DIP_A), + .DOBDO(DO_B), + .DOPBDOP(DOP_B), + .DIBDI(DI_B), + .DIPBDIP(DIP_B), + .ADDRAWRADDR(PORT_A_ADDR), + .ADDRBRDADDR(PORT_B_ADDR), + .CLKAWRCLK(PORT_A_CLK), + .CLKBRDCLK(PORT_B_CLK), + .ENAWREN(PORT_A_CLK_EN), + .ENBRDEN(PORT_B_CLK_EN), + .REGCEA(1'b0), + .REGCEBREGCE(1'b0), + .RSTA(RST_A), + .RSTBRST(RST_B), + .WEAWEL(WE_A), + .WEBWEU(WE_B), + ); +end + +endgenerate + +endmodule + + +module $__XILINX_BLOCKRAM_SDP_ (...); + +parameter INIT = 0; +parameter OPTION_RSTTYPE = "SYNC"; +parameter OPTION_WRITE_MODE = "READ_FIRST"; + +parameter PORT_W_WIDTH = 1; +parameter PORT_W_WR_EN_WIDTH = 1; +parameter PORT_W_USED = 1; + +parameter PORT_R_WIDTH = 1; +parameter PORT_R_USED = 0; +parameter PORT_R_RD_INIT_VALUE = 0; +parameter PORT_R_RD_SRST_VALUE = 0; +parameter PORT_R_RD_ARST_VALUE = 0; +parameter PORT_R_OPTION_RST_PRIORITY = "CE"; + +input CLK_C; + +input PORT_W_CLK; +input PORT_W_CLK_EN; +input [13:0] PORT_W_ADDR; +input [PORT_W_WIDTH-1:0] PORT_W_WR_DATA; +input [PORT_W_WR_EN_WIDTH-1:0] PORT_W_WR_EN; + +input PORT_R_CLK; +input PORT_R_CLK_EN; +input [13:0] PORT_R_ADDR; +output [PORT_R_WIDTH-1:0] PORT_R_RD_DATA; +input PORT_R_RD_SRST; +input PORT_R_RD_ARST; + +`include "brams_defs.vh" + +wire RST = OPTION_RSTTYPE == "SYNC" ? PORT_R_RD_SRST : PORT_R_RD_ARST; + +`MAKE_DI(DI, DIP, PORT_W_WR_DATA) +`MAKE_DO(DO, DOP, PORT_R_RD_DATA) + +localparam [35:0] RST_VALUE = OPTION_RSTTYPE == "SYNC" ? PORT_R_RD_SRST_VALUE : PORT_R_RD_ARST_VALUE; + +RAMB8BWER #( + `PARAMS_INIT_9 + `PARAMS_INITP_9 + .WRITE_MODE_A(OPTION_WRITE_MODE), + .WRITE_MODE_B(OPTION_WRITE_MODE), + .DATA_WIDTH_A(PORT_W_USED ? PORT_W_WIDTH : 0), + .DATA_WIDTH_B(PORT_R_USED ? PORT_R_WIDTH : 0), + .EN_RSTRAM_A("TRUE"), + .EN_RSTRAM_B("TRUE"), + .DOA_REG(0), + .DOB_REG(0), + .RST_PRIORITY_A("CE"), + .RST_PRIORITY_B(PORT_R_OPTION_RST_PRIORITY), + .RSTTYPE(OPTION_RSTTYPE), + .INIT_A(ival(18, PORT_R_RD_INIT_VALUE[17:0])), + .INIT_B(ival(18, PORT_R_RD_INIT_VALUE[35:18])), + .SRVAL_A(ival(18, RST_VALUE[17:0])), + .SRVAL_B(ival(18, RST_VALUE[35:18])), + .RAM_MODE("SDP"), +) _TECHMAP_REPLACE_ ( + .DOADO(DO[15:0]), + .DOPADOP(DOP[1:0]), + .DIADI(DI[15:0]), + .DIPADIP(DIP[1:0]), + .DOBDO(DO[31:16]), + .DOPBDOP(DOP[3:2]), + .DIBDI(DI[31:16]), + .DIPBDIP(DIP[3:2]), + .ADDRAWRADDR(PORT_W_ADDR), + .ADDRBRDADDR(PORT_R_ADDR), + .CLKAWRCLK(PORT_W_CLK), + .CLKBRDCLK(PORT_R_CLK), + .ENAWREN(PORT_W_CLK_EN), + .ENBRDEN(PORT_R_CLK_EN), + .REGCEA(1'b0), + .REGCEBREGCE(1'b0), + .RSTA(1'b0), + .RSTBRST(RST), + .WEAWEL(PORT_W_WR_EN[1:0]), + .WEBWEU(PORT_W_WR_EN[3:2]), +); + +endmodule diff --git a/techlibs/xilinx/brams_xc4v.txt b/techlibs/xilinx/brams_xc4v.txt new file mode 100644 index 000000000..2301835ea --- /dev/null +++ b/techlibs/xilinx/brams_xc4v.txt @@ -0,0 +1,169 @@ +# Block RAMs for Virtex 4+. +# The corresponding mapping files are: +# - brams_xc3sda_map.v: Spartan 3A DSP, Spartan 6 +# - brams_xc4v_map.v: Virtex 4 +# - brams_xc5v_map.v: Virtex 5 +# - brams_xc6v_map.v: Virtex 6, Series 7 +# - brams_xcu_map.v: Ultrascale + +ram block $__XILINX_BLOCKRAM_TDP_ { + byte 9; + ifdef HAS_SIZE_36 { + option "MODE" "HALF" { + abits 14; + widths 1 2 4 9 18 per_port; + cost 129; + } + option "MODE" "FULL" { + abits 15; + widths 1 2 4 9 18 36 per_port; + cost 257; + } + ifdef HAS_CASCADE { + option "MODE" "CASCADE" { + abits 16; + # hack to enforce same INIT layout as in the other modes + widths 1 2 4 9 per_port; + cost 513; + } + } + } else { + option "MODE" "FULL" { + abits 14; + widths 1 2 4 9 18 36 per_port; + cost 129; + } + ifdef HAS_CASCADE { + option "MODE" "CASCADE" { + abits 15; + widths 1 2 4 9 per_port; + cost 257; + } + } + } + init any; + port srsw "A" "B" { + option "MODE" "HALF" { + width mix; + } + option "MODE" "FULL" { + width mix; + } + option "MODE" "CASCADE" { + width mix 1; + } + ifdef HAS_ADDRCE { + # TODO + # addrce; + } + # Spartan 6 and Virtex 6 have a bug where READ_FIRST is not usable with asynchronous clocks. + ifdef HAS_CONFLICT_BUG { + option "HAS_RDFIRST" 1 { + clock posedge "C"; + } + option "HAS_RDFIRST" 0 { + clock posedge; + } + } else { + clock posedge; + } + clken; + rdsrst any gated_clken; + rdinit any; + portoption "WRITE_MODE" "NO_CHANGE" { + rdwr no_change; + option "MODE" "CASCADE" { + forbid; + } + } + portoption "WRITE_MODE" "WRITE_FIRST" { + ifdef HAS_SIZE_36 { + rdwr new; + } else { + rdwr new_only; + } + } + ifdef HAS_CONFLICT_BUG { + option "HAS_RDFIRST" 1 { + portoption "WRITE_MODE" "READ_FIRST" { + rdwr old; + wrtrans all old; + } + } + } else { + portoption "WRITE_MODE" "READ_FIRST" { + rdwr old; + wrtrans all old; + } + } + optional_rw; + } +} + +ifdef HAS_SIZE_36 { + ram block $__XILINX_BLOCKRAM_SDP_ { + byte 9; + option "MODE" "HALF" { + abits 14; + widths 1 2 4 9 18 36 per_port; + cost 129; + } + option "MODE" "FULL" { + abits 15; + widths 1 2 4 9 18 36 72 per_port; + cost 257; + } + init any; + port sw "W" { + ifndef HAS_MIXWIDTH_SDP { + option "MODE" "HALF" width 36; + option "MODE" "FULL" width 72; + } + ifdef HAS_ADDRCE { + # TODO + # addrce; + } + # Spartan 6 and Virtex 6 have a bug where READ_FIRST is not usable with asynchronous clocks. + ifdef HAS_CONFLICT_BUG { + option "WRITE_MODE" "READ_FIRST" { + clock posedge "C"; + } + option "WRITE_MODE" "WRITE_FIRST" { + clock posedge; + } + } else { + clock posedge; + } + clken; + option "WRITE_MODE" "READ_FIRST" { + wrtrans all old; + } + optional; + } + port sr "R" { + ifndef HAS_MIXWIDTH_SDP { + option "MODE" "HALF" width 36; + option "MODE" "FULL" width 72; + } + ifdef HAS_ADDRCE { + # TODO + # addrce; + } + # Spartan 6 and Virtex 6 have a bug where READ_FIRST is not usable with asynchronous clocks. + ifdef HAS_CONFLICT_BUG { + option "WRITE_MODE" "READ_FIRST" { + clock posedge "C"; + } + option "WRITE_MODE" "WRITE_FIRST" { + clock posedge; + } + } else { + clock posedge; + } + clken; + rdsrst any gated_clken; + rdinit any; + optional; + } + } +} diff --git a/techlibs/xilinx/brams_xc4v_map.v b/techlibs/xilinx/brams_xc4v_map.v new file mode 100644 index 000000000..a1747d40a --- /dev/null +++ b/techlibs/xilinx/brams_xc4v_map.v @@ -0,0 +1,149 @@ +module $__XILINX_BLOCKRAM_TDP_ (...); + +parameter INIT = 0; +parameter OPTION_MODE = "FULL"; + +parameter PORT_A_RD_WIDTH = 1; +parameter PORT_A_WR_WIDTH = 1; +parameter PORT_A_WR_EN_WIDTH = 1; +parameter PORT_A_RD_USED = 1; +parameter PORT_A_WR_USED = 1; +parameter PORT_A_OPTION_WRITE_MODE = "NO_CHANGE"; +parameter PORT_A_RD_INIT_VALUE = 0; +parameter PORT_A_RD_SRST_VALUE = 0; + +parameter PORT_B_RD_WIDTH = 1; +parameter PORT_B_WR_WIDTH = 1; +parameter PORT_B_WR_EN_WIDTH = 1; +parameter PORT_B_RD_USED = 0; +parameter PORT_B_WR_USED = 0; +parameter PORT_B_OPTION_WRITE_MODE = "NO_CHANGE"; +parameter PORT_B_RD_INIT_VALUE = 0; +parameter PORT_B_RD_SRST_VALUE = 0; + +input PORT_A_CLK; +input PORT_A_CLK_EN; +input [14:0] PORT_A_ADDR; +input [PORT_A_WR_WIDTH-1:0] PORT_A_WR_DATA; +input [PORT_A_WR_EN_WIDTH-1:0] PORT_A_WR_EN; +output [PORT_A_RD_WIDTH-1:0] PORT_A_RD_DATA; +input PORT_A_RD_SRST; + +input PORT_B_CLK; +input PORT_B_CLK_EN; +input [14:0] PORT_B_ADDR; +input [PORT_B_WR_WIDTH-1:0] PORT_B_WR_DATA; +input [PORT_B_WR_EN_WIDTH-1:0] PORT_B_WR_EN; +output [PORT_B_RD_WIDTH-1:0] PORT_B_RD_DATA; +input PORT_B_RD_SRST; + +`include "brams_defs.vh" + +`define PARAMS_COMMON \ + .WRITE_MODE_A(PORT_A_OPTION_WRITE_MODE), \ + .WRITE_MODE_B(PORT_B_OPTION_WRITE_MODE), \ + .READ_WIDTH_A(PORT_A_RD_USED ? PORT_A_RD_WIDTH : 0), \ + .READ_WIDTH_B(PORT_B_RD_USED ? PORT_B_RD_WIDTH : 0), \ + .WRITE_WIDTH_A(PORT_A_WR_USED ? PORT_A_WR_WIDTH : 0), \ + .WRITE_WIDTH_B(PORT_B_WR_USED ? PORT_B_WR_WIDTH : 0), \ + .DOA_REG(0), \ + .DOB_REG(0), \ + .INIT_A(ival(PORT_A_RD_WIDTH, PORT_A_RD_INIT_VALUE)), \ + .INIT_B(ival(PORT_B_RD_WIDTH, PORT_B_RD_INIT_VALUE)), \ + .SRVAL_A(ival(PORT_A_RD_WIDTH, PORT_A_RD_SRST_VALUE)), \ + .SRVAL_B(ival(PORT_B_RD_WIDTH, PORT_B_RD_SRST_VALUE)), + +`MAKE_DI(DI_A, DIP_A, PORT_A_WR_DATA) +`MAKE_DI(DI_B, DIP_B, PORT_B_WR_DATA) +`MAKE_DO(DO_A, DOP_A, PORT_A_RD_DATA) +`MAKE_DO(DO_B, DOP_B, PORT_B_RD_DATA) + +wire [3:0] WE_A = {4{PORT_A_WR_EN}}; +wire [3:0] WE_B = {4{PORT_B_WR_EN}}; + +generate + +if (OPTION_MODE == "FULL") begin + RAMB16 #( + `PARAMS_INIT_18 + `PARAMS_INITP_18 + `PARAMS_COMMON + .RAM_EXTENSION_A("NONE"), + .RAM_EXTENSION_B("NONE"), + ) _TECHMAP_REPLACE_ ( + .DOA(DO_A), + .DOPA(DOP_A), + .DIA(DI_A), + .DIPA(DIP_A), + .DOB(DO_B), + .DOPB(DOP_B), + .DIB(DI_B), + .DIPB(DIP_B), + .ADDRA({1'b1, PORT_A_ADDR[13:0]}), + .ADDRB({1'b1, PORT_B_ADDR[13:0]}), + .CLKA(PORT_A_CLK), + .CLKB(PORT_B_CLK), + .ENA(PORT_A_CLK_EN), + .ENB(PORT_B_CLK_EN), + .REGCEA(1'b0), + .REGCEB(1'b0), + .SSRA(PORT_A_RD_SRST), + .SSRB(PORT_B_RD_SRST), + .WEA(WE_A), + .WEB(WE_B), + ); +end else begin + wire CAS_A, CAS_B; + RAMB16 #( + `PARAMS_INIT_18 + `PARAMS_COMMON + .RAM_EXTENSION_A("LOWER"), + .RAM_EXTENSION_B("LOWER"), + ) lower ( + .DIA(DI_A), + .DIB(DI_B), + .ADDRA(PORT_A_ADDR), + .ADDRB(PORT_B_ADDR), + .CLKA(PORT_A_CLK), + .CLKB(PORT_B_CLK), + .ENA(PORT_A_CLK_EN), + .ENB(PORT_B_CLK_EN), + .REGCEA(1'b0), + .REGCEB(1'b0), + .SSRA(PORT_A_RD_SRST), + .SSRB(PORT_B_RD_SRST), + .WEA(WE_A), + .WEB(WE_B), + .CASCADEOUTA(CAS_A), + .CASCADEOUTB(CAS_B), + ); + RAMB16 #( + `PARAMS_INIT_18_U + `PARAMS_COMMON + .RAM_EXTENSION_A("UPPER"), + .RAM_EXTENSION_B("UPPER"), + ) upper ( + .DOA(DO_A), + .DIA(DI_A), + .DOB(DO_B), + .DIB(DI_B), + .ADDRA(PORT_A_ADDR), + .ADDRB(PORT_B_ADDR), + .CLKA(PORT_A_CLK), + .CLKB(PORT_B_CLK), + .ENA(PORT_A_CLK_EN), + .ENB(PORT_B_CLK_EN), + .REGCEA(1'b0), + .REGCEB(1'b0), + .SSRA(PORT_A_RD_SRST), + .SSRB(PORT_B_RD_SRST), + .WEA(WE_A), + .WEB(WE_B), + .CASCADEINA(CAS_A), + .CASCADEINB(CAS_B), + ); +end + +endgenerate + +endmodule diff --git a/techlibs/xilinx/brams_xc5v_map.v b/techlibs/xilinx/brams_xc5v_map.v new file mode 100644 index 000000000..6349af359 --- /dev/null +++ b/techlibs/xilinx/brams_xc5v_map.v @@ -0,0 +1,255 @@ +module $__XILINX_BLOCKRAM_TDP_ (...); + +parameter INIT = 0; +parameter OPTION_MODE = "FULL"; + +parameter PORT_A_RD_WIDTH = 1; +parameter PORT_A_WR_WIDTH = 1; +parameter PORT_A_WR_EN_WIDTH = 1; +parameter PORT_A_RD_USED = 1; +parameter PORT_A_WR_USED = 1; +parameter PORT_A_OPTION_WRITE_MODE = "NO_CHANGE"; +parameter PORT_A_RD_INIT_VALUE = 0; +parameter PORT_A_RD_SRST_VALUE = 0; + +parameter PORT_B_RD_WIDTH = 1; +parameter PORT_B_WR_WIDTH = 1; +parameter PORT_B_WR_EN_WIDTH = 1; +parameter PORT_B_RD_USED = 0; +parameter PORT_B_WR_USED = 0; +parameter PORT_B_OPTION_WRITE_MODE = "NO_CHANGE"; +parameter PORT_B_RD_INIT_VALUE = 0; +parameter PORT_B_RD_SRST_VALUE = 0; + +input PORT_A_CLK; +input PORT_A_CLK_EN; +input [15:0] PORT_A_ADDR; +input [PORT_A_WR_WIDTH-1:0] PORT_A_WR_DATA; +input [PORT_A_WR_EN_WIDTH-1:0] PORT_A_WR_EN; +output [PORT_A_RD_WIDTH-1:0] PORT_A_RD_DATA; +input PORT_A_RD_SRST; + +input PORT_B_CLK; +input PORT_B_CLK_EN; +input [15:0] PORT_B_ADDR; +input [PORT_B_WR_WIDTH-1:0] PORT_B_WR_DATA; +input [PORT_B_WR_EN_WIDTH-1:0] PORT_B_WR_EN; +output [PORT_B_RD_WIDTH-1:0] PORT_B_RD_DATA; +input PORT_B_RD_SRST; + +`include "brams_defs.vh" + +`define PARAMS_COMMON \ + .WRITE_MODE_A(PORT_A_OPTION_WRITE_MODE), \ + .WRITE_MODE_B(PORT_B_OPTION_WRITE_MODE), \ + .READ_WIDTH_A(PORT_A_RD_USED ? PORT_A_RD_WIDTH : 0), \ + .READ_WIDTH_B(PORT_B_RD_USED ? PORT_B_RD_WIDTH : 0), \ + .WRITE_WIDTH_A(PORT_A_WR_USED ? PORT_A_WR_WIDTH : 0), \ + .WRITE_WIDTH_B(PORT_B_WR_USED ? PORT_B_WR_WIDTH : 0), \ + .DOA_REG(0), \ + .DOB_REG(0), \ + .INIT_A(ival(PORT_A_RD_WIDTH, PORT_A_RD_INIT_VALUE)), \ + .INIT_B(ival(PORT_B_RD_WIDTH, PORT_B_RD_INIT_VALUE)), \ + .SRVAL_A(ival(PORT_A_RD_WIDTH, PORT_A_RD_SRST_VALUE)), \ + .SRVAL_B(ival(PORT_B_RD_WIDTH, PORT_B_RD_SRST_VALUE)), + +`MAKE_DI(DI_A, DIP_A, PORT_A_WR_DATA) +`MAKE_DI(DI_B, DIP_B, PORT_B_WR_DATA) +`MAKE_DO(DO_A, DOP_A, PORT_A_RD_DATA) +`MAKE_DO(DO_B, DOP_B, PORT_B_RD_DATA) + +wire [3:0] WE_A = {4{PORT_A_WR_EN}}; +wire [3:0] WE_B = {4{PORT_B_WR_EN}}; + +generate + +if (OPTION_MODE == "HALF") begin + RAMB18 #( + `PARAMS_INIT_18 + `PARAMS_INITP_18 + `PARAMS_COMMON + ) _TECHMAP_REPLACE_ ( + .DOA(DO_A), + .DOPA(DOP_A), + .DIA(DI_A), + .DIPA(DIP_A), + .DOB(DO_B), + .DOPB(DOP_B), + .DIB(DI_B), + .DIPB(DIP_B), + .ADDRA(PORT_A_ADDR[13:0]), + .ADDRB(PORT_B_ADDR[13:0]), + .CLKA(PORT_A_CLK), + .CLKB(PORT_B_CLK), + .ENA(PORT_A_CLK_EN), + .ENB(PORT_B_CLK_EN), + .REGCEA(1'b0), + .REGCEB(1'b0), + .SSRA(PORT_A_RD_SRST), + .SSRB(PORT_B_RD_SRST), + .WEA(WE_A), + .WEB(WE_B), + ); +end else if (OPTION_MODE == "FULL") begin + RAMB36 #( + `PARAMS_INIT_36 + `PARAMS_INITP_36 + `PARAMS_COMMON + .RAM_EXTENSION_A("NONE"), + .RAM_EXTENSION_B("NONE"), + ) _TECHMAP_REPLACE_ ( + .DOA(DO_A), + .DOPA(DOP_A), + .DIA(DI_A), + .DIPA(DIP_A), + .DOB(DO_B), + .DOPB(DOP_B), + .DIB(DI_B), + .DIPB(DIP_B), + .ADDRA({1'b1, PORT_A_ADDR[14:0]}), + .ADDRB({1'b1, PORT_B_ADDR[14:0]}), + .CLKA(PORT_A_CLK), + .CLKB(PORT_B_CLK), + .ENA(PORT_A_CLK_EN), + .ENB(PORT_B_CLK_EN), + .REGCEA(1'b0), + .REGCEB(1'b0), + .SSRA(PORT_A_RD_SRST), + .SSRB(PORT_B_RD_SRST), + .WEA(WE_A), + .WEB(WE_B), + ); +end else begin + wire CAS_A, CAS_B; + RAMB36 #( + `PARAMS_INIT_36 + `PARAMS_COMMON + .RAM_EXTENSION_A("LOWER"), + .RAM_EXTENSION_B("LOWER"), + ) lower ( + .DIA(DI_A), + .DIB(DI_B), + .ADDRA(PORT_A_ADDR), + .ADDRB(PORT_B_ADDR), + .CLKA(PORT_A_CLK), + .CLKB(PORT_B_CLK), + .ENA(PORT_A_CLK_EN), + .ENB(PORT_B_CLK_EN), + .REGCEA(1'b0), + .REGCEB(1'b0), + .SSRA(PORT_A_RD_SRST), + .SSRB(PORT_B_RD_SRST), + .WEA(WE_A), + .WEB(WE_B), + .CASCADEOUTLATA(CAS_A), + .CASCADEOUTLATB(CAS_B), + ); + RAMB36 #( + `PARAMS_INIT_36_U + `PARAMS_COMMON + .RAM_EXTENSION_A("UPPER"), + .RAM_EXTENSION_B("UPPER"), + ) upper ( + .DOA(DO_A), + .DIA(DI_A), + .DOB(DO_B), + .DIB(DI_B), + .ADDRA(PORT_A_ADDR), + .ADDRB(PORT_B_ADDR), + .CLKA(PORT_A_CLK), + .CLKB(PORT_B_CLK), + .ENA(PORT_A_CLK_EN), + .ENB(PORT_B_CLK_EN), + .REGCEA(1'b0), + .REGCEB(1'b0), + .SSRA(PORT_A_RD_SRST), + .SSRB(PORT_B_RD_SRST), + .WEA(WE_A), + .WEB(WE_B), + .CASCADEINLATA(CAS_A), + .CASCADEINLATB(CAS_B), + ); +end + +endgenerate + +endmodule + + +module $__XILINX_BLOCKRAM_SDP_ (...); + +parameter INIT = 0; +parameter OPTION_MODE = "FULL"; +parameter OPTION_WRITE_MODE = "READ_FIRST"; + +parameter PORT_W_WIDTH = 1; +parameter PORT_W_WR_EN_WIDTH = 1; +parameter PORT_W_USED = 1; + +parameter PORT_R_WIDTH = 1; +parameter PORT_R_USED = 0; +parameter PORT_R_RD_INIT_VALUE = 0; +parameter PORT_R_RD_SRST_VALUE = 0; + +input PORT_W_CLK; +input PORT_W_CLK_EN; +input [15:0] PORT_W_ADDR; +input [PORT_W_WIDTH-1:0] PORT_W_WR_DATA; +input [PORT_W_WR_EN_WIDTH-1:0] PORT_W_WR_EN; + +input PORT_R_CLK; +input PORT_R_CLK_EN; +input [15:0] PORT_R_ADDR; +output [PORT_R_WIDTH-1:0] PORT_R_RD_DATA; +input PORT_R_RD_SRST; + +`include "brams_defs.vh" + +`define PARAMS_COMMON \ + .DO_REG(0), \ + .INIT(ival(PORT_R_WIDTH, PORT_R_RD_INIT_VALUE)), \ + .SRVAL(ival(PORT_R_WIDTH, PORT_R_RD_SRST_VALUE)), + +`define PORTS_COMMON \ + .DO(DO), \ + .DOP(DOP), \ + .DI(DI), \ + .DIP(DIP), \ + .WRCLK(PORT_W_CLK), \ + .RDCLK(PORT_R_CLK), \ + .WREN(PORT_W_CLK_EN), \ + .RDEN(PORT_R_CLK_EN), \ + .REGCE(1'b0), \ + .SSR(PORT_R_RD_SRST), \ + .WE(PORT_W_WR_EN), + +`MAKE_DI(DI, DIP, PORT_W_WR_DATA) +`MAKE_DO(DO, DOP, PORT_R_RD_DATA) + +generate + +if (OPTION_MODE == "HALF") begin + RAMB18SDP #( + `PARAMS_INIT_18 + `PARAMS_INITP_18 + `PARAMS_COMMON + ) _TECHMAP_REPLACE_ ( + `PORTS_COMMON + .WRADDR(PORT_W_ADDR[13:5]), + .RDADDR(PORT_R_ADDR[13:5]), + ); +end else if (OPTION_MODE == "FULL") begin + RAMB36SDP #( + `PARAMS_INIT_36 + `PARAMS_INITP_36 + `PARAMS_COMMON + ) _TECHMAP_REPLACE_ ( + `PORTS_COMMON + .WRADDR(PORT_W_ADDR[14:6]), + .RDADDR(PORT_R_ADDR[14:6]), + ); +end + +endgenerate + +endmodule diff --git a/techlibs/xilinx/brams_xc6v_map.v b/techlibs/xilinx/brams_xc6v_map.v new file mode 100644 index 000000000..b2698a3aa --- /dev/null +++ b/techlibs/xilinx/brams_xc6v_map.v @@ -0,0 +1,284 @@ +module $__XILINX_BLOCKRAM_TDP_ (...); + +parameter INIT = 0; +parameter OPTION_MODE = "FULL"; +parameter OPTION_HAS_RDFIRST = 0; + +parameter PORT_A_RD_WIDTH = 1; +parameter PORT_A_WR_WIDTH = 1; +parameter PORT_A_WR_EN_WIDTH = 1; +parameter PORT_A_RD_USED = 1; +parameter PORT_A_WR_USED = 1; +parameter PORT_A_OPTION_WRITE_MODE = "NO_CHANGE"; +parameter PORT_A_RD_INIT_VALUE = 0; +parameter PORT_A_RD_SRST_VALUE = 1; + +parameter PORT_B_RD_WIDTH = 1; +parameter PORT_B_WR_WIDTH = 1; +parameter PORT_B_WR_EN_WIDTH = 1; +parameter PORT_B_RD_USED = 0; +parameter PORT_B_WR_USED = 0; +parameter PORT_B_OPTION_WRITE_MODE = "NO_CHANGE"; +parameter PORT_B_RD_INIT_VALUE = 0; +parameter PORT_B_RD_SRST_VALUE = 0; + +input CLK_C; + +input PORT_A_CLK; +input PORT_A_CLK_EN; +input [15:0] PORT_A_ADDR; +input [PORT_A_WR_WIDTH-1:0] PORT_A_WR_DATA; +input [PORT_A_WR_EN_WIDTH-1:0] PORT_A_WR_EN; +output [PORT_A_RD_WIDTH-1:0] PORT_A_RD_DATA; +input PORT_A_RD_SRST; + +input PORT_B_CLK; +input PORT_B_CLK_EN; +input [15:0] PORT_B_ADDR; +input [PORT_B_WR_WIDTH-1:0] PORT_B_WR_DATA; +input [PORT_B_WR_EN_WIDTH-1:0] PORT_B_WR_EN; +output [PORT_B_RD_WIDTH-1:0] PORT_B_RD_DATA; +input PORT_B_RD_SRST; + +`include "brams_defs.vh" + +`define PARAMS_COMMON \ + .WRITE_MODE_A(PORT_A_OPTION_WRITE_MODE), \ + .WRITE_MODE_B(PORT_B_OPTION_WRITE_MODE), \ + .READ_WIDTH_A(PORT_A_RD_USED ? PORT_A_RD_WIDTH : 0), \ + .READ_WIDTH_B(PORT_B_RD_USED ? PORT_B_RD_WIDTH : 0), \ + .WRITE_WIDTH_A(PORT_A_WR_USED ? PORT_A_WR_WIDTH : 0), \ + .WRITE_WIDTH_B(PORT_B_WR_USED ? PORT_B_WR_WIDTH : 0), \ + .DOA_REG(0), \ + .DOB_REG(0), \ + .INIT_A(ival(PORT_A_RD_WIDTH, PORT_A_RD_INIT_VALUE)), \ + .INIT_B(ival(PORT_B_RD_WIDTH, PORT_B_RD_INIT_VALUE)), \ + .SRVAL_A(ival(PORT_A_RD_WIDTH, PORT_A_RD_SRST_VALUE)), \ + .SRVAL_B(ival(PORT_B_RD_WIDTH, PORT_B_RD_SRST_VALUE)), \ + .RAM_MODE("TDP"), + +`define PORTS_COMMON \ + .DOADO(DO_A), \ + .DOPADOP(DOP_A), \ + .DIADI(DI_A), \ + .DIPADIP(DIP_A), \ + .DOBDO(DO_B), \ + .DOPBDOP(DOP_B), \ + .DIBDI(DI_B), \ + .DIPBDIP(DIP_B), \ + .CLKARDCLK(PORT_A_CLK), \ + .CLKBWRCLK(PORT_B_CLK), \ + .ENARDEN(PORT_A_CLK_EN), \ + .ENBWREN(PORT_B_CLK_EN), \ + .REGCEAREGCE(1'b0), \ + .REGCEB(1'b0), \ + .RSTRAMARSTRAM(PORT_A_RD_SRST), \ + .RSTRAMB(PORT_B_RD_SRST), \ + .RSTREGARSTREG(1'b0), \ + .RSTREGB(1'b0), \ + .WEA(WE_A), \ + .WEBWE(WE_B), + +`MAKE_DI(DI_A, DIP_A, PORT_A_WR_DATA) +`MAKE_DI(DI_B, DIP_B, PORT_B_WR_DATA) +`MAKE_DO(DO_A, DOP_A, PORT_A_RD_DATA) +`MAKE_DO(DO_B, DOP_B, PORT_B_RD_DATA) + +wire [3:0] WE_A = {4{PORT_A_WR_EN}}; +wire [3:0] WE_B = {4{PORT_B_WR_EN}}; + +generate + +if (OPTION_MODE == "HALF") begin + RAMB18E1 #( + `PARAMS_INIT_18 + `PARAMS_INITP_18 + `PARAMS_COMMON + ) _TECHMAP_REPLACE_ ( + `PORTS_COMMON + .ADDRARDADDR(PORT_A_ADDR[13:0]), + .ADDRBWRADDR(PORT_B_ADDR[13:0]), + ); +end else if (OPTION_MODE == "FULL") begin + RAMB36E1 #( + `PARAMS_INIT_36 + `PARAMS_INITP_36 + `PARAMS_COMMON + .RAM_EXTENSION_A("NONE"), + .RAM_EXTENSION_B("NONE"), + ) _TECHMAP_REPLACE_ ( + `PORTS_COMMON + .ADDRARDADDR({1'b1, PORT_A_ADDR[14:0]}), + .ADDRBWRADDR({1'b1, PORT_B_ADDR[14:0]}), + ); +end else begin + wire CAS_A, CAS_B; + RAMB36E1 #( + `PARAMS_INIT_36 + `PARAMS_COMMON + .RAM_EXTENSION_A("LOWER"), + .RAM_EXTENSION_B("LOWER"), + ) lower ( + .DIADI(DI_A), + .DIBDI(DI_B), + .CLKARDCLK(PORT_A_CLK), + .CLKBWRCLK(PORT_B_CLK), + .ENARDEN(PORT_A_CLK_EN), + .ENBWREN(PORT_B_CLK_EN), + .REGCEAREGCE(1'b0), + .REGCEB(1'b0), + .RSTRAMARSTRAM(PORT_A_RD_SRST), + .RSTRAMB(PORT_B_RD_SRST), + .RSTREGARSTREG(1'b0), + .RSTREGB(1'b0), + .WEA(WE_A), + .WEBWE(WE_B), + .ADDRARDADDR(PORT_A_ADDR), + .ADDRBWRADDR(PORT_B_ADDR), + .CASCADEOUTA(CAS_A), + .CASCADEOUTB(CAS_B), + ); + RAMB36E1 #( + `PARAMS_INIT_36_U + `PARAMS_COMMON + .RAM_EXTENSION_A("UPPER"), + .RAM_EXTENSION_B("UPPER"), + ) upper ( + .DOADO(DO_A), + .DIADI(DI_A), + .DOBDO(DO_B), + .DIBDI(DI_B), + .CLKARDCLK(PORT_A_CLK), + .CLKBWRCLK(PORT_B_CLK), + .ENARDEN(PORT_A_CLK_EN), + .ENBWREN(PORT_B_CLK_EN), + .REGCEAREGCE(1'b0), + .REGCEB(1'b0), + .RSTRAMARSTRAM(PORT_A_RD_SRST), + .RSTRAMB(PORT_B_RD_SRST), + .RSTREGARSTREG(1'b0), + .RSTREGB(1'b0), + .WEA(WE_A), + .WEBWE(WE_B), + .ADDRARDADDR(PORT_A_ADDR), + .ADDRBWRADDR(PORT_B_ADDR), + .CASCADEINA(CAS_A), + .CASCADEINB(CAS_B), + ); +end + +endgenerate + +endmodule + + +module $__XILINX_BLOCKRAM_SDP_ (...); + +parameter INIT = 0; +parameter OPTION_MODE = "FULL"; +parameter OPTION_WRITE_MODE = "READ_FIRST"; + +parameter PORT_W_WIDTH = 1; +parameter PORT_W_WR_EN_WIDTH = 1; +parameter PORT_W_USED = 1; + +parameter PORT_R_WIDTH = 1; +parameter PORT_R_USED = 0; +parameter PORT_R_RD_INIT_VALUE = 0; +parameter PORT_R_RD_SRST_VALUE = 0; + +input CLK_C; + +input PORT_W_CLK; +input PORT_W_CLK_EN; +input [15:0] PORT_W_ADDR; +input [PORT_W_WIDTH-1:0] PORT_W_WR_DATA; +input [PORT_W_WR_EN_WIDTH-1:0] PORT_W_WR_EN; + +input PORT_R_CLK; +input PORT_R_CLK_EN; +input [15:0] PORT_R_ADDR; +output [PORT_R_WIDTH-1:0] PORT_R_RD_DATA; +input PORT_R_RD_SRST; + +`include "brams_defs.vh" + +`define PARAMS_COMMON \ + .WRITE_MODE_A(OPTION_WRITE_MODE), \ + .WRITE_MODE_B(OPTION_WRITE_MODE), \ + .READ_WIDTH_A(PORT_R_USED ? PORT_R_WIDTH : 0), \ + .READ_WIDTH_B(0), \ + .WRITE_WIDTH_A(0), \ + .WRITE_WIDTH_B(PORT_W_USED ? PORT_W_WIDTH : 0), \ + .DOA_REG(0), \ + .DOB_REG(0), \ + .RAM_MODE("SDP"), + +`define PORTS_COMMON \ + .CLKBWRCLK(PORT_W_CLK), \ + .CLKARDCLK(PORT_R_CLK), \ + .ENBWREN(PORT_W_CLK_EN), \ + .ENARDEN(PORT_R_CLK_EN), \ + .REGCEAREGCE(1'b0), \ + .REGCEB(1'b0), \ + .RSTRAMARSTRAM(PORT_R_RD_SRST), \ + .RSTRAMB(1'b0), \ + .RSTREGARSTREG(1'b0), \ + .RSTREGB(1'b0), \ + .WEA(0), \ + .WEBWE(PORT_W_WR_EN), + +`MAKE_DI(DI, DIP, PORT_W_WR_DATA) +`MAKE_DO(DO, DOP, PORT_R_RD_DATA) + +generate + +if (OPTION_MODE == "HALF") begin + RAMB18E1 #( + `PARAMS_INIT_18 + `PARAMS_INITP_18 + `PARAMS_COMMON + .INIT_A(PORT_R_WIDTH == 36 ? ival(18, PORT_R_RD_INIT_VALUE[17:0]) : ival(PORT_R_WIDTH, PORT_R_RD_INIT_VALUE)), + .INIT_B(PORT_R_WIDTH == 36 ? ival(18, PORT_R_RD_INIT_VALUE[35:18]) : 0), + .SRVAL_A(PORT_R_WIDTH == 36 ? ival(18, PORT_R_RD_SRST_VALUE[17:0]) : ival(PORT_R_WIDTH, PORT_R_RD_SRST_VALUE)), + .SRVAL_B(PORT_R_WIDTH == 36 ? ival(18, PORT_R_RD_SRST_VALUE[35:18]) : 0), + ) _TECHMAP_REPLACE_ ( + `PORTS_COMMON + .ADDRARDADDR(PORT_R_ADDR[13:0]), + .ADDRBWRADDR(PORT_W_ADDR[13:0]), + .DOADO(DO[15:0]), + .DOBDO(DO[31:16]), + .DOPADOP(DOP[1:0]), + .DOPBDOP(DOP[3:2]), + .DIADI(DI[15:0]), + .DIBDI(PORT_W_WIDTH == 36 ? DI[31:16] : DI[15:0]), + .DIPADIP(DIP[1:0]), + .DIPBDIP(PORT_W_WIDTH == 36 ? DIP[3:2] : DIP[1:0]), + ); +end else if (OPTION_MODE == "FULL") begin + RAMB36E1 #( + `PARAMS_INIT_36 + `PARAMS_INITP_36 + `PARAMS_COMMON + .INIT_A(PORT_R_WIDTH == 72 ? ival(36, PORT_R_RD_INIT_VALUE[35:0]) : ival(PORT_R_WIDTH, PORT_R_RD_INIT_VALUE)), + .INIT_B(PORT_R_WIDTH == 72 ? ival(36, PORT_R_RD_INIT_VALUE[71:36]) : 0), + .SRVAL_A(PORT_R_WIDTH == 72 ? ival(36, PORT_R_RD_SRST_VALUE[35:0]) : ival(PORT_R_WIDTH, PORT_R_RD_SRST_VALUE)), + .SRVAL_B(PORT_R_WIDTH == 72 ? ival(36, PORT_R_RD_SRST_VALUE[71:36]) : 0), + ) _TECHMAP_REPLACE_ ( + `PORTS_COMMON + .ADDRARDADDR({1'b1, PORT_R_ADDR}), + .ADDRBWRADDR({1'b1, PORT_W_ADDR}), + .DOADO(DO[31:0]), + .DOBDO(DO[63:32]), + .DOPADOP(DOP[3:0]), + .DOPBDOP(DOP[7:4]), + .DIADI(DI[31:0]), + .DIBDI(PORT_W_WIDTH == 72 ? DI[63:32] : DI[31:0]), + .DIPADIP(DIP[3:0]), + .DIPBDIP(PORT_W_WIDTH == 71 ? DIP[7:4] : DIP[3:0]), + ); +end + +endgenerate + +endmodule diff --git a/techlibs/xilinx/brams_xcu_map.v b/techlibs/xilinx/brams_xcu_map.v new file mode 100644 index 000000000..d48c21a59 --- /dev/null +++ b/techlibs/xilinx/brams_xcu_map.v @@ -0,0 +1,225 @@ +module $__XILINX_BLOCKRAM_TDP_ (...); + +parameter INIT = 0; +parameter OPTION_MODE = "FULL"; +parameter OPTION_HAS_RDFIRST = 0; + +parameter PORT_A_RD_WIDTH = 1; +parameter PORT_A_WR_WIDTH = 1; +parameter PORT_A_WR_EN_WIDTH = 1; +parameter PORT_A_RD_USED = 1; +parameter PORT_A_WR_USED = 1; +parameter PORT_A_OPTION_WRITE_MODE = "NO_CHANGE"; +parameter PORT_A_RD_INIT_VALUE = 0; +parameter PORT_A_RD_SRST_VALUE = 1; + +parameter PORT_B_RD_WIDTH = 1; +parameter PORT_B_WR_WIDTH = 1; +parameter PORT_B_WR_EN_WIDTH = 1; +parameter PORT_B_RD_USED = 0; +parameter PORT_B_WR_USED = 0; +parameter PORT_B_OPTION_WRITE_MODE = "NO_CHANGE"; +parameter PORT_B_RD_INIT_VALUE = 0; +parameter PORT_B_RD_SRST_VALUE = 0; + +input PORT_A_CLK; +input PORT_A_CLK_EN; +input [15:0] PORT_A_ADDR; +input [PORT_A_WR_WIDTH-1:0] PORT_A_WR_DATA; +input [PORT_A_WR_EN_WIDTH-1:0] PORT_A_WR_EN; +output [PORT_A_RD_WIDTH-1:0] PORT_A_RD_DATA; +input PORT_A_RD_SRST; + +input PORT_B_CLK; +input PORT_B_CLK_EN; +input [15:0] PORT_B_ADDR; +input [PORT_B_WR_WIDTH-1:0] PORT_B_WR_DATA; +input [PORT_B_WR_EN_WIDTH-1:0] PORT_B_WR_EN; +output [PORT_B_RD_WIDTH-1:0] PORT_B_RD_DATA; +input PORT_B_RD_SRST; + +`include "brams_defs.vh" + +`define PARAMS_COMMON \ + .WRITE_MODE_A(PORT_A_OPTION_WRITE_MODE), \ + .WRITE_MODE_B(PORT_B_OPTION_WRITE_MODE), \ + .READ_WIDTH_A(PORT_A_RD_USED ? PORT_A_RD_WIDTH : 0), \ + .READ_WIDTH_B(PORT_B_RD_USED ? PORT_B_RD_WIDTH : 0), \ + .WRITE_WIDTH_A(PORT_A_WR_USED ? PORT_A_WR_WIDTH : 0), \ + .WRITE_WIDTH_B(PORT_B_WR_USED ? PORT_B_WR_WIDTH : 0), \ + .DOA_REG(0), \ + .DOB_REG(0), \ + .INIT_A(ival(PORT_A_RD_WIDTH, PORT_A_RD_INIT_VALUE)), \ + .INIT_B(ival(PORT_B_RD_WIDTH, PORT_B_RD_INIT_VALUE)), \ + .SRVAL_A(ival(PORT_A_RD_WIDTH, PORT_A_RD_SRST_VALUE)), \ + .SRVAL_B(ival(PORT_B_RD_WIDTH, PORT_B_RD_SRST_VALUE)), + +`define PORTS_COMMON \ + .DOUTADOUT(DO_A), \ + .DOUTPADOUTP(DOP_A), \ + .DINADIN(DI_A), \ + .DINPADINP(DIP_A), \ + .DOUTBDOUT(DO_B), \ + .DOUTPBDOUTP(DOP_B), \ + .DINBDIN(DI_B), \ + .DINPBDINP(DIP_B), \ + .CLKARDCLK(PORT_A_CLK), \ + .CLKBWRCLK(PORT_B_CLK), \ + .ENARDEN(PORT_A_CLK_EN), \ + .ENBWREN(PORT_B_CLK_EN), \ + .REGCEAREGCE(1'b0), \ + .REGCEB(1'b0), \ + .ADDRENA(1'b1), \ + .ADDRENB(1'b1), \ + .RSTRAMARSTRAM(PORT_A_RD_SRST), \ + .RSTRAMB(PORT_B_RD_SRST), \ + .RSTREGARSTREG(1'b0), \ + .RSTREGB(1'b0), \ + .WEA(WE_A), \ + .WEBWE(WE_B), \ + .ADDRARDADDR(PORT_A_ADDR), \ + .ADDRBWRADDR(PORT_B_ADDR), \ + .SLEEP(1'b0), + +`MAKE_DI(DI_A, DIP_A, PORT_A_WR_DATA) +`MAKE_DI(DI_B, DIP_B, PORT_B_WR_DATA) +`MAKE_DO(DO_A, DOP_A, PORT_A_RD_DATA) +`MAKE_DO(DO_B, DOP_B, PORT_B_RD_DATA) + +wire [3:0] WE_A = {4{PORT_A_WR_EN}}; +wire [3:0] WE_B = {4{PORT_B_WR_EN}}; + +generate + +if (OPTION_MODE == "HALF") begin + RAMB18E2 #( + `PARAMS_INIT_18 + `PARAMS_INITP_18 + `PARAMS_COMMON + ) _TECHMAP_REPLACE_ ( + `PORTS_COMMON + ); +end else if (OPTION_MODE == "FULL") begin + RAMB36E2 #( + `PARAMS_INIT_36 + `PARAMS_INITP_36 + `PARAMS_COMMON + ) _TECHMAP_REPLACE_ ( + `PORTS_COMMON + ); +end + +endgenerate + +endmodule + + +module $__XILINX_BLOCKRAM_SDP_ (...); + +parameter INIT = 0; +parameter OPTION_MODE = "FULL"; +parameter OPTION_WRITE_MODE = "READ_FIRST"; + +parameter PORT_W_WIDTH = 1; +parameter PORT_W_WR_EN_WIDTH = 1; +parameter PORT_W_USED = 1; + +parameter PORT_R_WIDTH = 1; +parameter PORT_R_USED = 0; +parameter PORT_R_RD_INIT_VALUE = 0; +parameter PORT_R_RD_SRST_VALUE = 0; + +input PORT_W_CLK; +input PORT_W_CLK_EN; +input [15:0] PORT_W_ADDR; +input [PORT_W_WIDTH-1:0] PORT_W_WR_DATA; +input [PORT_W_WR_EN_WIDTH-1:0] PORT_W_WR_EN; + +input PORT_R_CLK; +input PORT_R_CLK_EN; +input [15:0] PORT_R_ADDR; +output [PORT_R_WIDTH-1:0] PORT_R_RD_DATA; +input PORT_R_RD_SRST; + +`include "brams_defs.vh" + +`define PARAMS_COMMON \ + .WRITE_MODE_A(OPTION_WRITE_MODE), \ + .WRITE_MODE_B(OPTION_WRITE_MODE), \ + .READ_WIDTH_A(PORT_R_USED ? PORT_R_WIDTH : 0), \ + .READ_WIDTH_B(0), \ + .WRITE_WIDTH_A(0), \ + .WRITE_WIDTH_B(PORT_W_USED ? PORT_W_WIDTH : 0), \ + .DOA_REG(0), \ + .DOB_REG(0), + +`define PORTS_COMMON \ + .CLKBWRCLK(PORT_W_CLK), \ + .CLKARDCLK(PORT_R_CLK), \ + .ENBWREN(PORT_W_CLK_EN), \ + .ENARDEN(PORT_R_CLK_EN), \ + .REGCEAREGCE(1'b0), \ + .REGCEB(1'b0), \ + .ADDRENA(1'b1), \ + .ADDRENB(1'b1), \ + .RSTRAMARSTRAM(PORT_R_RD_SRST), \ + .RSTRAMB(1'b0), \ + .RSTREGARSTREG(1'b0), \ + .RSTREGB(1'b0), \ + .WEA(0), \ + .WEBWE(PORT_W_WR_EN), \ + .ADDRARDADDR(PORT_R_ADDR), \ + .ADDRBWRADDR(PORT_W_ADDR), \ + .SLEEP(1'b0), + +`MAKE_DI(DI, DIP, PORT_W_WR_DATA) +`MAKE_DO(DO, DOP, PORT_R_RD_DATA) + +generate + +if (OPTION_MODE == "HALF") begin + RAMB18E2 #( + `PARAMS_INIT_18 + `PARAMS_INITP_18 + `PARAMS_COMMON + .INIT_A(PORT_R_WIDTH == 36 ? ival(18, PORT_R_RD_INIT_VALUE[17:0]) : ival(PORT_R_WIDTH, PORT_R_RD_INIT_VALUE)), + .INIT_B(PORT_R_WIDTH == 36 ? ival(18, PORT_R_RD_INIT_VALUE[35:18]) : 0), + .SRVAL_A(PORT_R_WIDTH == 36 ? ival(18, PORT_R_RD_SRST_VALUE[17:0]) : ival(PORT_R_WIDTH, PORT_R_RD_SRST_VALUE)), + .SRVAL_B(PORT_R_WIDTH == 36 ? ival(18, PORT_R_RD_SRST_VALUE[35:18]) : 0), + ) _TECHMAP_REPLACE_ ( + `PORTS_COMMON + .DOUTADOUT(DO[15:0]), + .DOUTBDOUT(DO[31:16]), + .DOUTPADOUTP(DOP[1:0]), + .DOUTPBDOUTP(DOP[3:2]), + .DINADIN(DI[15:0]), + .DINBDIN(PORT_W_WIDTH == 36 ? DI[31:16] : DI[15:0]), + .DINPADINP(DIP[1:0]), + .DINPBDINP(PORT_W_WIDTH == 36 ? DIP[3:2] : DIP[1:0]), + ); +end else if (OPTION_MODE == "FULL") begin + RAMB36E2 #( + `PARAMS_INIT_36 + `PARAMS_INITP_36 + `PARAMS_COMMON + .INIT_A(PORT_R_WIDTH == 72 ? ival(36, PORT_R_RD_INIT_VALUE[35:0]) : ival(PORT_R_WIDTH, PORT_R_RD_INIT_VALUE)), + .INIT_B(PORT_R_WIDTH == 72 ? ival(36, PORT_R_RD_INIT_VALUE[71:36]) : 0), + .SRVAL_A(PORT_R_WIDTH == 72 ? ival(36, PORT_R_RD_SRST_VALUE[35:0]) : ival(PORT_R_WIDTH, PORT_R_RD_SRST_VALUE)), + .SRVAL_B(PORT_R_WIDTH == 72 ? ival(36, PORT_R_RD_SRST_VALUE[71:36]) : 0), + ) _TECHMAP_REPLACE_ ( + `PORTS_COMMON + .DOUTADOUT(DO[31:0]), + .DOUTBDOUT(DO[63:32]), + .DOUTPADOUTP(DOP[3:0]), + .DOUTPBDOUTP(DOP[7:4]), + .DINADIN(DI[31:0]), + .DINBDIN(PORT_W_WIDTH == 72 ? DI[63:32] : DI[31:0]), + .DINPADINP(DIP[3:0]), + .DINPBDINP(PORT_W_WIDTH == 71 ? DIP[7:4] : DIP[3:0]), + ); +end + +endgenerate + +endmodule + diff --git a/techlibs/xilinx/brams_xcv.txt b/techlibs/xilinx/brams_xcv.txt new file mode 100644 index 000000000..294e9036b --- /dev/null +++ b/techlibs/xilinx/brams_xcv.txt @@ -0,0 +1,17 @@ +# Block RAMs for the original Virtex. +# The corresponding mapping file is brams_xcv_map.v + +ram block $__XILINX_BLOCKRAM_ { + abits 12; + widths 1 2 4 8 16 per_port; + cost 32; + init any; + port srsw "A" "B" { + clock posedge; + clken; + rdwr new; + rdinit zero; + rdsrst zero gated_clken; + optional; + } +} diff --git a/techlibs/xilinx/brams_xcv_map.v b/techlibs/xilinx/brams_xcv_map.v new file mode 100644 index 000000000..408cc6795 --- /dev/null +++ b/techlibs/xilinx/brams_xcv_map.v @@ -0,0 +1,257 @@ +module $__XILINX_BLOCKRAM_ (...); + +parameter INIT = 0; + +parameter PORT_A_WIDTH = 1; +parameter PORT_B_WIDTH = 1; +parameter PORT_A_USED = 1; +parameter PORT_B_USED = 0; + +input PORT_A_CLK; +input PORT_A_CLK_EN; +input [11:0] PORT_A_ADDR; +input [PORT_A_WIDTH-1:0] PORT_A_WR_DATA; +input PORT_A_WR_EN; +output [PORT_A_WIDTH-1:0] PORT_A_RD_DATA; +input PORT_A_RD_SRST; + +input PORT_B_CLK; +input PORT_B_CLK_EN; +input [11:0] PORT_B_ADDR; +input [PORT_B_WIDTH-1:0] PORT_B_WR_DATA; +input PORT_B_WR_EN; +output [PORT_B_WIDTH-1:0] PORT_B_RD_DATA; +input PORT_B_RD_SRST; + +`define PARAMS_INIT \ + .INIT_00(INIT[0*256+:256]), \ + .INIT_01(INIT[1*256+:256]), \ + .INIT_02(INIT[2*256+:256]), \ + .INIT_03(INIT[3*256+:256]), \ + .INIT_04(INIT[4*256+:256]), \ + .INIT_05(INIT[5*256+:256]), \ + .INIT_06(INIT[6*256+:256]), \ + .INIT_07(INIT[7*256+:256]), \ + .INIT_08(INIT[8*256+:256]), \ + .INIT_09(INIT[9*256+:256]), \ + .INIT_0A(INIT[10*256+:256]), \ + .INIT_0B(INIT[11*256+:256]), \ + .INIT_0C(INIT[12*256+:256]), \ + .INIT_0D(INIT[13*256+:256]), \ + .INIT_0E(INIT[14*256+:256]), \ + .INIT_0F(INIT[15*256+:256]), + +`define PORTS_DP(addr_slice_a, addr_slice_b) \ + .CLKA(PORT_A_CLK), \ + .ENA(PORT_A_CLK_EN), \ + .WEA(PORT_A_WR_EN), \ + .RSTA(PORT_A_RD_SRST), \ + .ADDRA(PORT_A_ADDR addr_slice_a), \ + .DOA(PORT_A_RD_DATA), \ + .DIA(PORT_A_WR_DATA), \ + .CLKB(PORT_B_CLK), \ + .ENB(PORT_B_CLK_EN), \ + .WEB(PORT_B_WR_EN), \ + .RSTB(PORT_B_RD_SRST), \ + .ADDRB(PORT_B_ADDR addr_slice_b), \ + .DOB(PORT_B_RD_DATA), \ + .DIB(PORT_B_WR_DATA), + +`define PORTS_DP_SWAP(addr_slice_a, addr_slice_b) \ + .CLKB(PORT_A_CLK), \ + .ENB(PORT_A_CLK_EN), \ + .WEB(PORT_A_WR_EN), \ + .RSTB(PORT_A_RD_SRST), \ + .ADDRB(PORT_A_ADDR addr_slice_a), \ + .DOB(PORT_A_RD_DATA), \ + .DIB(PORT_A_WR_DATA), \ + .CLKA(PORT_B_CLK), \ + .ENA(PORT_B_CLK_EN), \ + .WEA(PORT_B_WR_EN), \ + .RSTA(PORT_B_RD_SRST), \ + .ADDRA(PORT_B_ADDR addr_slice_b), \ + .DOA(PORT_B_RD_DATA), \ + .DIA(PORT_B_WR_DATA), + +`define PORTS_SP(addr_slice) \ + .CLK(PORT_A_CLK), \ + .EN(PORT_A_CLK_EN), \ + .WE(PORT_A_WR_EN), \ + .RST(PORT_A_RD_SRST), \ + .ADDR(PORT_A_ADDR addr_slice), \ + .DO(PORT_A_RD_DATA), \ + .DI(PORT_A_WR_DATA), + +generate + +if (!PORT_B_USED) begin + case (PORT_A_WIDTH) + 1: RAMB4_S1 #( + `PARAMS_INIT + ) _TECHMAP_REPLACE_ ( + `PORTS_SP([11:0]) + ); + 2: RAMB4_S2 #( + `PARAMS_INIT + ) _TECHMAP_REPLACE_ ( + `PORTS_SP([11:1]) + ); + 4: RAMB4_S4 #( + `PARAMS_INIT + ) _TECHMAP_REPLACE_ ( + `PORTS_SP([11:2]) + ); + 8: RAMB4_S8 #( + `PARAMS_INIT + ) _TECHMAP_REPLACE_ ( + `PORTS_SP([11:3]) + ); + 16: RAMB4_S16 #( + `PARAMS_INIT + ) _TECHMAP_REPLACE_ ( + `PORTS_SP([11:4]) + ); + endcase +end else begin + case (PORT_A_WIDTH) + 1: case(PORT_B_WIDTH) + 1: RAMB4_S1_S1 #( + `PARAMS_INIT + ) _TECHMAP_REPLACE_ ( + `PORTS_DP([11:0], [11:0]) + ); + 2: RAMB4_S1_S2 #( + `PARAMS_INIT + ) _TECHMAP_REPLACE_ ( + `PORTS_DP([11:0], [11:1]) + ); + 4: RAMB4_S1_S4 #( + `PARAMS_INIT + ) _TECHMAP_REPLACE_ ( + `PORTS_DP([11:0], [11:2]) + ); + 8: RAMB4_S1_S8 #( + `PARAMS_INIT + ) _TECHMAP_REPLACE_ ( + `PORTS_DP([11:0], [11:3]) + ); + 16: RAMB4_S1_S16 #( + `PARAMS_INIT + ) _TECHMAP_REPLACE_ ( + `PORTS_DP([11:0], [11:4]) + ); + endcase + 2: case(PORT_B_WIDTH) + 1: RAMB4_S1_S2 #( + `PARAMS_INIT + ) _TECHMAP_REPLACE_ ( + `PORTS_DP_SWAP([11:1], [11:0]) + ); + 2: RAMB4_S2_S2 #( + `PARAMS_INIT + ) _TECHMAP_REPLACE_ ( + `PORTS_DP([11:1], [11:1]) + ); + 4: RAMB4_S2_S4 #( + `PARAMS_INIT + ) _TECHMAP_REPLACE_ ( + `PORTS_DP([11:1], [11:2]) + ); + 8: RAMB4_S2_S8 #( + `PARAMS_INIT + ) _TECHMAP_REPLACE_ ( + `PORTS_DP([11:1], [11:3]) + ); + 16: RAMB4_S2_S16 #( + `PARAMS_INIT + ) _TECHMAP_REPLACE_ ( + `PORTS_DP([11:1], [11:4]) + ); + endcase + 4: case(PORT_B_WIDTH) + 1: RAMB4_S1_S4 #( + `PARAMS_INIT + ) _TECHMAP_REPLACE_ ( + `PORTS_DP_SWAP([11:2], [11:0]) + ); + 2: RAMB4_S2_S4 #( + `PARAMS_INIT + ) _TECHMAP_REPLACE_ ( + `PORTS_DP_SWAP([11:2], [11:1]) + ); + 4: RAMB4_S4_S4 #( + `PARAMS_INIT + ) _TECHMAP_REPLACE_ ( + `PORTS_DP([11:2], [11:2]) + ); + 8: RAMB4_S4_S8 #( + `PARAMS_INIT + ) _TECHMAP_REPLACE_ ( + `PORTS_DP([11:2], [11:3]) + ); + 16: RAMB4_S4_S16 #( + `PARAMS_INIT + ) _TECHMAP_REPLACE_ ( + `PORTS_DP([11:2], [11:4]) + ); + endcase + 8: case(PORT_B_WIDTH) + 1: RAMB4_S1_S8 #( + `PARAMS_INIT + ) _TECHMAP_REPLACE_ ( + `PORTS_DP_SWAP([11:3], [11:0]) + ); + 2: RAMB4_S2_S8 #( + `PARAMS_INIT + ) _TECHMAP_REPLACE_ ( + `PORTS_DP_SWAP([11:3], [11:1]) + ); + 4: RAMB4_S4_S8 #( + `PARAMS_INIT + ) _TECHMAP_REPLACE_ ( + `PORTS_DP_SWAP([11:3], [11:2]) + ); + 8: RAMB4_S8_S8 #( + `PARAMS_INIT + ) _TECHMAP_REPLACE_ ( + `PORTS_DP([11:3], [11:3]) + ); + 16: RAMB4_S8_S16 #( + `PARAMS_INIT + ) _TECHMAP_REPLACE_ ( + `PORTS_DP([11:3], [11:4]) + ); + endcase + 16: case(PORT_B_WIDTH) + 1: RAMB4_S1_S16 #( + `PARAMS_INIT + ) _TECHMAP_REPLACE_ ( + `PORTS_DP_SWAP([11:4], [11:0]) + ); + 2: RAMB4_S2_S16 #( + `PARAMS_INIT + ) _TECHMAP_REPLACE_ ( + `PORTS_DP_SWAP([11:4], [11:1]) + ); + 4: RAMB4_S4_S16 #( + `PARAMS_INIT + ) _TECHMAP_REPLACE_ ( + `PORTS_DP_SWAP([11:4], [11:2]) + ); + 8: RAMB4_S8_S16 #( + `PARAMS_INIT + ) _TECHMAP_REPLACE_ ( + `PORTS_DP_SWAP([11:4], [11:3]) + ); + 16: RAMB4_S16_S16 #( + `PARAMS_INIT + ) _TECHMAP_REPLACE_ ( + `PORTS_DP([11:4], [11:4]) + ); + endcase + endcase +end + +endgenerate + +endmodule diff --git a/techlibs/xilinx/cells_map.v b/techlibs/xilinx/cells_map.v index e8386e2e0..2b8eade2f 100644 --- a/techlibs/xilinx/cells_map.v +++ b/techlibs/xilinx/cells_map.v @@ -359,11 +359,3 @@ module \$__XILINX_MUXF78 (O, I0, I1, I2, I3, S0, S1); else MUXF8 mux8 (.I0(T0), .I1(T1), .S(S1), .O(O)); endmodule - -module \$__XILINX_TINOUTPAD (input I, OE, output O, inout IO); - IOBUF _TECHMAP_REPLACE_ (.I(I), .O(O), .T(~OE), .IO(IO)); -endmodule - -module \$__XILINX_TOUTPAD (input I, OE, output O); - OBUFT _TECHMAP_REPLACE_ (.I(I), .O(O), .T(~OE)); -endmodule diff --git a/techlibs/xilinx/cells_xtra.py b/techlibs/xilinx/cells_xtra.py index cb23b9787..2630c7a0f 100644 --- a/techlibs/xilinx/cells_xtra.py +++ b/techlibs/xilinx/cells_xtra.py @@ -108,7 +108,26 @@ CELLS = [ # Block RAM. # Virtex. - # TODO: RAMB4_* + Cell('RAMB4_S1', port_attrs={'CLK': ['clkbuf_sink']}), + Cell('RAMB4_S2', port_attrs={'CLK': ['clkbuf_sink']}), + Cell('RAMB4_S4', port_attrs={'CLK': ['clkbuf_sink']}), + Cell('RAMB4_S8', port_attrs={'CLK': ['clkbuf_sink']}), + Cell('RAMB4_S16', port_attrs={'CLK': ['clkbuf_sink']}), + Cell('RAMB4_S1_S1', port_attrs={'CLKA': ['clkbuf_sink'], 'CLKB': ['clkbuf_sink']}), + Cell('RAMB4_S1_S2', port_attrs={'CLKA': ['clkbuf_sink'], 'CLKB': ['clkbuf_sink']}), + Cell('RAMB4_S1_S4', port_attrs={'CLKA': ['clkbuf_sink'], 'CLKB': ['clkbuf_sink']}), + Cell('RAMB4_S1_S8', port_attrs={'CLKA': ['clkbuf_sink'], 'CLKB': ['clkbuf_sink']}), + Cell('RAMB4_S1_S16', port_attrs={'CLKA': ['clkbuf_sink'], 'CLKB': ['clkbuf_sink']}), + Cell('RAMB4_S2_S2', port_attrs={'CLKA': ['clkbuf_sink'], 'CLKB': ['clkbuf_sink']}), + Cell('RAMB4_S2_S4', port_attrs={'CLKA': ['clkbuf_sink'], 'CLKB': ['clkbuf_sink']}), + Cell('RAMB4_S2_S8', port_attrs={'CLKA': ['clkbuf_sink'], 'CLKB': ['clkbuf_sink']}), + Cell('RAMB4_S2_S16', port_attrs={'CLKA': ['clkbuf_sink'], 'CLKB': ['clkbuf_sink']}), + Cell('RAMB4_S4_S4', port_attrs={'CLKA': ['clkbuf_sink'], 'CLKB': ['clkbuf_sink']}), + Cell('RAMB4_S4_S8', port_attrs={'CLKA': ['clkbuf_sink'], 'CLKB': ['clkbuf_sink']}), + Cell('RAMB4_S4_S16', port_attrs={'CLKA': ['clkbuf_sink'], 'CLKB': ['clkbuf_sink']}), + Cell('RAMB4_S8_S8', port_attrs={'CLKA': ['clkbuf_sink'], 'CLKB': ['clkbuf_sink']}), + Cell('RAMB4_S8_S16', port_attrs={'CLKA': ['clkbuf_sink'], 'CLKB': ['clkbuf_sink']}), + Cell('RAMB4_S16_S16', port_attrs={'CLKA': ['clkbuf_sink'], 'CLKB': ['clkbuf_sink']}), # Virtex 2, Spartan 3. Cell('RAMB16_S1', port_attrs={'CLK': ['clkbuf_sink']}), Cell('RAMB16_S2', port_attrs={'CLK': ['clkbuf_sink']}), diff --git a/techlibs/xilinx/cells_xtra.v b/techlibs/xilinx/cells_xtra.v index 1187101fd..aae0d3ee5 100644 --- a/techlibs/xilinx/cells_xtra.v +++ b/techlibs/xilinx/cells_xtra.v @@ -1,5 +1,680 @@ // Created by cells_xtra.py from Xilinx models +module RAMB4_S1 (...); + parameter INIT_00 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_01 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_02 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_03 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_04 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_05 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_06 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_07 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_08 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_09 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0A = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0B = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0C = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0D = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0E = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0F = 256'h0000000000000000000000000000000000000000000000000000000000000000; + output [0:0] DO; + input [11:0] ADDR; + input [0:0] DI; + input EN; + (* clkbuf_sink *) + input CLK; + input WE; + input RST; +endmodule + +module RAMB4_S2 (...); + parameter INIT_00 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_01 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_02 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_03 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_04 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_05 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_06 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_07 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_08 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_09 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0A = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0B = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0C = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0D = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0E = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0F = 256'h0000000000000000000000000000000000000000000000000000000000000000; + output [1:0] DO; + input [10:0] ADDR; + input [1:0] DI; + input EN; + (* clkbuf_sink *) + input CLK; + input WE; + input RST; +endmodule + +module RAMB4_S4 (...); + parameter INIT_00 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_01 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_02 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_03 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_04 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_05 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_06 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_07 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_08 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_09 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0A = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0B = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0C = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0D = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0E = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0F = 256'h0000000000000000000000000000000000000000000000000000000000000000; + output [3:0] DO; + input [9:0] ADDR; + input [3:0] DI; + input EN; + (* clkbuf_sink *) + input CLK; + input WE; + input RST; +endmodule + +module RAMB4_S8 (...); + parameter INIT_00 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_01 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_02 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_03 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_04 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_05 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_06 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_07 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_08 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_09 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0A = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0B = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0C = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0D = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0E = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0F = 256'h0000000000000000000000000000000000000000000000000000000000000000; + output [7:0] DO; + input [8:0] ADDR; + input [7:0] DI; + input EN; + (* clkbuf_sink *) + input CLK; + input WE; + input RST; +endmodule + +module RAMB4_S16 (...); + parameter INIT_00 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_01 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_02 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_03 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_04 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_05 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_06 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_07 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_08 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_09 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0A = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0B = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0C = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0D = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0E = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0F = 256'h0000000000000000000000000000000000000000000000000000000000000000; + output [15:0] DO; + input [7:0] ADDR; + input [15:0] DI; + input EN; + (* clkbuf_sink *) + input CLK; + input WE; + input RST; +endmodule + +module RAMB4_S1_S1 (...); + parameter SIM_COLLISION_CHECK = "ALL"; + parameter INIT_00 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_01 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_02 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_03 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_04 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_05 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_06 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_07 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_08 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_09 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0A = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0B = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0C = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0D = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0E = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0F = 256'h0000000000000000000000000000000000000000000000000000000000000000; + output [0:0] DOA; + input [11:0] ADDRA; + input [0:0] DIA; + input ENA; + (* clkbuf_sink *) + input CLKA; + input WEA; + input RSTA; + output [0:0] DOB; + input [11:0] ADDRB; + input [0:0] DIB; + input ENB; + (* clkbuf_sink *) + input CLKB; + input WEB; + input RSTB; +endmodule + +module RAMB4_S1_S2 (...); + parameter SIM_COLLISION_CHECK = "ALL"; + parameter INIT_00 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_01 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_02 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_03 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_04 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_05 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_06 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_07 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_08 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_09 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0A = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0B = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0C = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0D = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0E = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0F = 256'h0000000000000000000000000000000000000000000000000000000000000000; + output [0:0] DOA; + input [11:0] ADDRA; + input [0:0] DIA; + input ENA; + (* clkbuf_sink *) + input CLKA; + input WEA; + input RSTA; + output [1:0] DOB; + input [10:0] ADDRB; + input [1:0] DIB; + input ENB; + (* clkbuf_sink *) + input CLKB; + input WEB; + input RSTB; +endmodule + +module RAMB4_S1_S4 (...); + parameter SIM_COLLISION_CHECK = "ALL"; + parameter INIT_00 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_01 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_02 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_03 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_04 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_05 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_06 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_07 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_08 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_09 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0A = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0B = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0C = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0D = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0E = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0F = 256'h0000000000000000000000000000000000000000000000000000000000000000; + output [0:0] DOA; + input [11:0] ADDRA; + input [0:0] DIA; + input ENA; + (* clkbuf_sink *) + input CLKA; + input WEA; + input RSTA; + output [3:0] DOB; + input [9:0] ADDRB; + input [3:0] DIB; + input ENB; + (* clkbuf_sink *) + input CLKB; + input WEB; + input RSTB; +endmodule + +module RAMB4_S1_S8 (...); + parameter SIM_COLLISION_CHECK = "ALL"; + parameter INIT_00 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_01 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_02 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_03 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_04 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_05 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_06 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_07 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_08 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_09 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0A = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0B = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0C = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0D = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0E = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0F = 256'h0000000000000000000000000000000000000000000000000000000000000000; + output [0:0] DOA; + input [11:0] ADDRA; + input [0:0] DIA; + input ENA; + (* clkbuf_sink *) + input CLKA; + input WEA; + input RSTA; + output [7:0] DOB; + input [8:0] ADDRB; + input [7:0] DIB; + input ENB; + (* clkbuf_sink *) + input CLKB; + input WEB; + input RSTB; +endmodule + +module RAMB4_S1_S16 (...); + parameter SIM_COLLISION_CHECK = "ALL"; + parameter INIT_00 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_01 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_02 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_03 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_04 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_05 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_06 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_07 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_08 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_09 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0A = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0B = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0C = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0D = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0E = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0F = 256'h0000000000000000000000000000000000000000000000000000000000000000; + output [0:0] DOA; + input [11:0] ADDRA; + input [0:0] DIA; + input ENA; + (* clkbuf_sink *) + input CLKA; + input WEA; + input RSTA; + output [15:0] DOB; + input [7:0] ADDRB; + input [15:0] DIB; + input ENB; + (* clkbuf_sink *) + input CLKB; + input WEB; + input RSTB; +endmodule + +module RAMB4_S2_S2 (...); + parameter SIM_COLLISION_CHECK = "ALL"; + parameter INIT_00 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_01 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_02 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_03 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_04 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_05 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_06 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_07 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_08 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_09 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0A = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0B = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0C = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0D = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0E = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0F = 256'h0000000000000000000000000000000000000000000000000000000000000000; + output [1:0] DOA; + input [10:0] ADDRA; + input [1:0] DIA; + input ENA; + (* clkbuf_sink *) + input CLKA; + input WEA; + input RSTA; + output [1:0] DOB; + input [10:0] ADDRB; + input [1:0] DIB; + input ENB; + (* clkbuf_sink *) + input CLKB; + input WEB; + input RSTB; +endmodule + +module RAMB4_S2_S4 (...); + parameter SIM_COLLISION_CHECK = "ALL"; + parameter INIT_00 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_01 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_02 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_03 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_04 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_05 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_06 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_07 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_08 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_09 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0A = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0B = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0C = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0D = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0E = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0F = 256'h0000000000000000000000000000000000000000000000000000000000000000; + output [1:0] DOA; + input [10:0] ADDRA; + input [1:0] DIA; + input ENA; + (* clkbuf_sink *) + input CLKA; + input WEA; + input RSTA; + output [3:0] DOB; + input [9:0] ADDRB; + input [3:0] DIB; + input ENB; + (* clkbuf_sink *) + input CLKB; + input WEB; + input RSTB; +endmodule + +module RAMB4_S2_S8 (...); + parameter SIM_COLLISION_CHECK = "ALL"; + parameter INIT_00 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_01 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_02 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_03 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_04 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_05 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_06 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_07 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_08 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_09 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0A = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0B = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0C = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0D = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0E = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0F = 256'h0000000000000000000000000000000000000000000000000000000000000000; + output [1:0] DOA; + input [10:0] ADDRA; + input [1:0] DIA; + input ENA; + (* clkbuf_sink *) + input CLKA; + input WEA; + input RSTA; + output [7:0] DOB; + input [8:0] ADDRB; + input [7:0] DIB; + input ENB; + (* clkbuf_sink *) + input CLKB; + input WEB; + input RSTB; +endmodule + +module RAMB4_S2_S16 (...); + parameter SIM_COLLISION_CHECK = "ALL"; + parameter INIT_00 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_01 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_02 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_03 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_04 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_05 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_06 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_07 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_08 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_09 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0A = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0B = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0C = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0D = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0E = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0F = 256'h0000000000000000000000000000000000000000000000000000000000000000; + output [1:0] DOA; + input [10:0] ADDRA; + input [1:0] DIA; + input ENA; + (* clkbuf_sink *) + input CLKA; + input WEA; + input RSTA; + output [15:0] DOB; + input [7:0] ADDRB; + input [15:0] DIB; + input ENB; + (* clkbuf_sink *) + input CLKB; + input WEB; + input RSTB; +endmodule + +module RAMB4_S4_S4 (...); + parameter SIM_COLLISION_CHECK = "ALL"; + parameter INIT_00 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_01 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_02 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_03 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_04 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_05 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_06 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_07 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_08 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_09 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0A = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0B = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0C = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0D = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0E = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0F = 256'h0000000000000000000000000000000000000000000000000000000000000000; + output [3:0] DOA; + input [9:0] ADDRA; + input [3:0] DIA; + input ENA; + (* clkbuf_sink *) + input CLKA; + input WEA; + input RSTA; + output [3:0] DOB; + input [9:0] ADDRB; + input [3:0] DIB; + input ENB; + (* clkbuf_sink *) + input CLKB; + input WEB; + input RSTB; +endmodule + +module RAMB4_S4_S8 (...); + parameter SIM_COLLISION_CHECK = "ALL"; + parameter INIT_00 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_01 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_02 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_03 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_04 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_05 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_06 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_07 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_08 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_09 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0A = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0B = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0C = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0D = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0E = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0F = 256'h0000000000000000000000000000000000000000000000000000000000000000; + output [3:0] DOA; + input [9:0] ADDRA; + input [3:0] DIA; + input ENA; + (* clkbuf_sink *) + input CLKA; + input WEA; + input RSTA; + output [7:0] DOB; + input [8:0] ADDRB; + input [7:0] DIB; + input ENB; + (* clkbuf_sink *) + input CLKB; + input WEB; + input RSTB; +endmodule + +module RAMB4_S4_S16 (...); + parameter SIM_COLLISION_CHECK = "ALL"; + parameter INIT_00 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_01 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_02 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_03 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_04 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_05 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_06 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_07 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_08 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_09 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0A = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0B = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0C = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0D = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0E = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0F = 256'h0000000000000000000000000000000000000000000000000000000000000000; + output [3:0] DOA; + input [9:0] ADDRA; + input [3:0] DIA; + input ENA; + (* clkbuf_sink *) + input CLKA; + input WEA; + input RSTA; + output [15:0] DOB; + input [7:0] ADDRB; + input [15:0] DIB; + input ENB; + (* clkbuf_sink *) + input CLKB; + input WEB; + input RSTB; +endmodule + +module RAMB4_S8_S8 (...); + parameter SIM_COLLISION_CHECK = "ALL"; + parameter INIT_00 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_01 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_02 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_03 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_04 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_05 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_06 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_07 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_08 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_09 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0A = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0B = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0C = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0D = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0E = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0F = 256'h0000000000000000000000000000000000000000000000000000000000000000; + output [7:0] DOA; + input [8:0] ADDRA; + input [7:0] DIA; + input ENA; + (* clkbuf_sink *) + input CLKA; + input WEA; + input RSTA; + output [7:0] DOB; + input [8:0] ADDRB; + input [7:0] DIB; + input ENB; + (* clkbuf_sink *) + input CLKB; + input WEB; + input RSTB; +endmodule + +module RAMB4_S8_S16 (...); + parameter SIM_COLLISION_CHECK = "ALL"; + parameter INIT_00 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_01 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_02 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_03 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_04 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_05 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_06 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_07 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_08 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_09 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0A = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0B = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0C = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0D = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0E = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0F = 256'h0000000000000000000000000000000000000000000000000000000000000000; + output [7:0] DOA; + input [8:0] ADDRA; + input [7:0] DIA; + input ENA; + (* clkbuf_sink *) + input CLKA; + input WEA; + input RSTA; + output [15:0] DOB; + input [7:0] ADDRB; + input [15:0] DIB; + input ENB; + (* clkbuf_sink *) + input CLKB; + input WEB; + input RSTB; +endmodule + +module RAMB4_S16_S16 (...); + parameter SIM_COLLISION_CHECK = "ALL"; + parameter INIT_00 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_01 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_02 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_03 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_04 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_05 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_06 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_07 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_08 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_09 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0A = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0B = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0C = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0D = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0E = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0F = 256'h0000000000000000000000000000000000000000000000000000000000000000; + output [15:0] DOA; + input [7:0] ADDRA; + input [15:0] DIA; + input ENA; + (* clkbuf_sink *) + input CLKA; + input WEA; + input RSTA; + output [15:0] DOB; + input [7:0] ADDRB; + input [15:0] DIB; + input ENB; + (* clkbuf_sink *) + input CLKB; + input WEB; + input RSTB; +endmodule + module RAMB16_S1 (...); parameter [0:0] INIT = 1'h0; parameter [0:0] SRVAL = 1'h0; diff --git a/techlibs/xilinx/lut4_lutrams.txt b/techlibs/xilinx/lut4_lutrams.txt deleted file mode 100644 index 2b344a9ee..000000000 --- a/techlibs/xilinx/lut4_lutrams.txt +++ /dev/null @@ -1,19 +0,0 @@ -bram $__XILINX_RAM16X1D - init 1 - abits 4 - dbits 1 - groups 2 - ports 1 1 - wrmode 0 1 - enable 0 1 - transp 0 0 - clocks 0 1 - clkpol 0 2 -endbram - - -match $__XILINX_RAM16X1D - min bits 2 - min wports 1 - make_outreg -endmatch diff --git a/techlibs/xilinx/lut6_lutrams.txt b/techlibs/xilinx/lut6_lutrams.txt deleted file mode 100644 index 3b3cb81e1..000000000 --- a/techlibs/xilinx/lut6_lutrams.txt +++ /dev/null @@ -1,143 +0,0 @@ -bram $__XILINX_RAM32X1D - init 1 - abits 5 - dbits 1 - groups 2 - ports 1 1 - wrmode 0 1 - enable 0 1 - transp 0 0 - clocks 0 1 - clkpol 0 2 -endbram - -bram $__XILINX_RAM64X1D - init 1 - abits 6 - dbits 1 - groups 2 - ports 1 1 - wrmode 0 1 - enable 0 1 - transp 0 0 - clocks 0 1 - clkpol 0 2 -endbram - -bram $__XILINX_RAM128X1D - init 1 - abits 7 - dbits 1 - groups 2 - ports 1 1 - wrmode 0 1 - enable 0 1 - transp 0 0 - clocks 0 1 - clkpol 0 2 -endbram - - -bram $__XILINX_RAM32X6SDP - init 1 - abits 5 - dbits 6 - groups 2 - ports 1 1 - wrmode 0 1 - enable 0 1 - transp 0 0 - clocks 0 1 - clkpol 0 2 -endbram - -bram $__XILINX_RAM64X3SDP - init 1 - abits 6 - dbits 3 - groups 2 - ports 1 1 - wrmode 0 1 - enable 0 1 - transp 0 0 - clocks 0 1 - clkpol 0 2 -endbram - -bram $__XILINX_RAM32X2Q - init 1 - abits 5 - dbits 2 - groups 2 - ports 3 1 - wrmode 0 1 - enable 0 1 - transp 0 0 - clocks 0 1 - clkpol 0 2 -endbram - -bram $__XILINX_RAM64X1Q - init 1 - abits 6 - dbits 1 - groups 2 - ports 3 1 - wrmode 0 1 - enable 0 1 - transp 0 0 - clocks 0 1 - clkpol 0 2 -endbram - - -match $__XILINX_RAM32X1D - min bits 3 - min wports 1 - make_outreg - or_next_if_better -endmatch - -match $__XILINX_RAM64X1D - min bits 5 - min wports 1 - make_outreg - or_next_if_better -endmatch - -match $__XILINX_RAM128X1D - min bits 9 - min wports 1 - make_outreg - or_next_if_better -endmatch - - -match $__XILINX_RAM32X6SDP - min bits 5 - min wports 1 - make_outreg - or_next_if_better -endmatch - -match $__XILINX_RAM64X3SDP - min bits 6 - min wports 1 - make_outreg - or_next_if_better -endmatch - -match $__XILINX_RAM32X2Q - min bits 5 - min rports 2 - min wports 1 - make_outreg - or_next_if_better -endmatch - -match $__XILINX_RAM64X1Q - min bits 5 - min rports 2 - min wports 1 - make_outreg -endmatch diff --git a/techlibs/xilinx/lutrams_map.v b/techlibs/xilinx/lutrams_map.v deleted file mode 100644 index 3ac1143bb..000000000 --- a/techlibs/xilinx/lutrams_map.v +++ /dev/null @@ -1,279 +0,0 @@ - -module \$__XILINX_RAM16X1D (CLK1, A1ADDR, A1DATA, B1ADDR, B1DATA, B1EN); - parameter [15:0] INIT = 16'bx; - parameter CLKPOL2 = 1; - input CLK1; - - input [3:0] A1ADDR; - output A1DATA; - - input [3:0] B1ADDR; - input B1DATA; - input B1EN; - - RAM16X1D #( - .INIT(INIT), - .IS_WCLK_INVERTED(!CLKPOL2) - ) _TECHMAP_REPLACE_ ( - .DPRA0(A1ADDR[0]), - .DPRA1(A1ADDR[1]), - .DPRA2(A1ADDR[2]), - .DPRA3(A1ADDR[3]), - .DPO(A1DATA), - - .A0(B1ADDR[0]), - .A1(B1ADDR[1]), - .A2(B1ADDR[2]), - .A3(B1ADDR[3]), - .D(B1DATA), - .WCLK(CLK1), - .WE(B1EN) - ); -endmodule - -module \$__XILINX_RAM32X1D (CLK1, A1ADDR, A1DATA, B1ADDR, B1DATA, B1EN); - parameter [31:0] INIT = 32'bx; - parameter CLKPOL2 = 1; - input CLK1; - - input [4:0] A1ADDR; - output A1DATA; - - input [4:0] B1ADDR; - input B1DATA; - input B1EN; - - RAM32X1D #( - .INIT(INIT), - .IS_WCLK_INVERTED(!CLKPOL2) - ) _TECHMAP_REPLACE_ ( - .DPRA0(A1ADDR[0]), - .DPRA1(A1ADDR[1]), - .DPRA2(A1ADDR[2]), - .DPRA3(A1ADDR[3]), - .DPRA4(A1ADDR[4]), - .DPO(A1DATA), - - .A0(B1ADDR[0]), - .A1(B1ADDR[1]), - .A2(B1ADDR[2]), - .A3(B1ADDR[3]), - .A4(B1ADDR[4]), - .D(B1DATA), - .WCLK(CLK1), - .WE(B1EN) - ); -endmodule - -module \$__XILINX_RAM64X1D (CLK1, A1ADDR, A1DATA, B1ADDR, B1DATA, B1EN); - parameter [63:0] INIT = 64'bx; - parameter CLKPOL2 = 1; - input CLK1; - - input [5:0] A1ADDR; - output A1DATA; - - input [5:0] B1ADDR; - input B1DATA; - input B1EN; - - RAM64X1D #( - .INIT(INIT), - .IS_WCLK_INVERTED(!CLKPOL2) - ) _TECHMAP_REPLACE_ ( - .DPRA0(A1ADDR[0]), - .DPRA1(A1ADDR[1]), - .DPRA2(A1ADDR[2]), - .DPRA3(A1ADDR[3]), - .DPRA4(A1ADDR[4]), - .DPRA5(A1ADDR[5]), - .DPO(A1DATA), - - .A0(B1ADDR[0]), - .A1(B1ADDR[1]), - .A2(B1ADDR[2]), - .A3(B1ADDR[3]), - .A4(B1ADDR[4]), - .A5(B1ADDR[5]), - .D(B1DATA), - .WCLK(CLK1), - .WE(B1EN) - ); -endmodule - -module \$__XILINX_RAM128X1D (CLK1, A1ADDR, A1DATA, B1ADDR, B1DATA, B1EN); - parameter [127:0] INIT = 128'bx; - parameter CLKPOL2 = 1; - input CLK1; - - input [6:0] A1ADDR; - output A1DATA; - - input [6:0] B1ADDR; - input B1DATA; - input B1EN; - - RAM128X1D #( - .INIT(INIT), - .IS_WCLK_INVERTED(!CLKPOL2) - ) _TECHMAP_REPLACE_ ( - .DPRA(A1ADDR), - .DPO(A1DATA), - - .A(B1ADDR), - .D(B1DATA), - .WCLK(CLK1), - .WE(B1EN) - ); -endmodule - - -module \$__XILINX_RAM32X6SDP (CLK1, A1ADDR, A1DATA, B1ADDR, B1DATA, B1EN); - parameter [32*6-1:0] INIT = {32*6{1'bx}}; - parameter CLKPOL2 = 1; - input CLK1; - - input [4:0] A1ADDR; - output [5:0] A1DATA; - - input [4:0] B1ADDR; - input [5:0] B1DATA; - input B1EN; - - wire [1:0] DOD_unused; - - RAM32M #( - .INIT_A({INIT[187:186], INIT[181:180], INIT[175:174], INIT[169:168], INIT[163:162], INIT[157:156], INIT[151:150], INIT[145:144], INIT[139:138], INIT[133:132], INIT[127:126], INIT[121:120], INIT[115:114], INIT[109:108], INIT[103:102], INIT[ 97: 96], INIT[ 91: 90], INIT[ 85: 84], INIT[ 79: 78], INIT[ 73: 72], INIT[ 67: 66], INIT[ 61: 60], INIT[ 55: 54], INIT[ 49: 48], INIT[ 43: 42], INIT[ 37: 36], INIT[ 31: 30], INIT[ 25: 24], INIT[ 19: 18], INIT[ 13: 12], INIT[ 7: 6], INIT[ 1: 0]}), - .INIT_B({INIT[189:188], INIT[183:182], INIT[177:176], INIT[171:170], INIT[165:164], INIT[159:158], INIT[153:152], INIT[147:146], INIT[141:140], INIT[135:134], INIT[129:128], INIT[123:122], INIT[117:116], INIT[111:110], INIT[105:104], INIT[ 99: 98], INIT[ 93: 92], INIT[ 87: 86], INIT[ 81: 80], INIT[ 75: 74], INIT[ 69: 68], INIT[ 63: 62], INIT[ 57: 56], INIT[ 51: 50], INIT[ 45: 44], INIT[ 39: 38], INIT[ 33: 32], INIT[ 27: 26], INIT[ 21: 20], INIT[ 15: 14], INIT[ 9: 8], INIT[ 3: 2]}), - .INIT_C({INIT[191:190], INIT[185:184], INIT[179:178], INIT[173:172], INIT[167:166], INIT[161:160], INIT[155:154], INIT[149:148], INIT[143:142], INIT[137:136], INIT[131:130], INIT[125:124], INIT[119:118], INIT[113:112], INIT[107:106], INIT[101:100], INIT[ 95: 94], INIT[ 89: 88], INIT[ 83: 82], INIT[ 77: 76], INIT[ 71: 70], INIT[ 65: 64], INIT[ 59: 58], INIT[ 53: 52], INIT[ 47: 46], INIT[ 41: 40], INIT[ 35: 34], INIT[ 29: 28], INIT[ 23: 22], INIT[ 17: 16], INIT[ 11: 10], INIT[ 5: 4]}), - .INIT_D(64'bx), - .IS_WCLK_INVERTED(!CLKPOL2) - ) _TECHMAP_REPLACE_ ( - .ADDRA(A1ADDR), - .ADDRB(A1ADDR), - .ADDRC(A1ADDR), - .DOA(A1DATA[1:0]), - .DOB(A1DATA[3:2]), - .DOC(A1DATA[5:4]), - .DOD(DOD_unused), - - .ADDRD(B1ADDR), - .DIA(B1DATA[1:0]), - .DIB(B1DATA[3:2]), - .DIC(B1DATA[5:4]), - .DID(2'b00), - .WCLK(CLK1), - .WE(B1EN) - ); -endmodule - -module \$__XILINX_RAM64X3SDP (CLK1, A1ADDR, A1DATA, B1ADDR, B1DATA, B1EN); - parameter [64*3-1:0] INIT = {64*3{1'bx}}; - parameter CLKPOL2 = 1; - input CLK1; - - input [5:0] A1ADDR; - output [2:0] A1DATA; - - input [5:0] B1ADDR; - input [2:0] B1DATA; - input B1EN; - - wire DOD_unused; - - RAM64M #( - .INIT_A({INIT[189], INIT[186], INIT[183], INIT[180], INIT[177], INIT[174], INIT[171], INIT[168], INIT[165], INIT[162], INIT[159], INIT[156], INIT[153], INIT[150], INIT[147], INIT[144], INIT[141], INIT[138], INIT[135], INIT[132], INIT[129], INIT[126], INIT[123], INIT[120], INIT[117], INIT[114], INIT[111], INIT[108], INIT[105], INIT[102], INIT[ 99], INIT[ 96], INIT[ 93], INIT[ 90], INIT[ 87], INIT[ 84], INIT[ 81], INIT[ 78], INIT[ 75], INIT[ 72], INIT[ 69], INIT[ 66], INIT[ 63], INIT[ 60], INIT[ 57], INIT[ 54], INIT[ 51], INIT[ 48], INIT[ 45], INIT[ 42], INIT[ 39], INIT[ 36], INIT[ 33], INIT[ 30], INIT[ 27], INIT[ 24], INIT[ 21], INIT[ 18], INIT[ 15], INIT[ 12], INIT[ 9], INIT[ 6], INIT[ 3], INIT[ 0]}), - .INIT_B({INIT[190], INIT[187], INIT[184], INIT[181], INIT[178], INIT[175], INIT[172], INIT[169], INIT[166], INIT[163], INIT[160], INIT[157], INIT[154], INIT[151], INIT[148], INIT[145], INIT[142], INIT[139], INIT[136], INIT[133], INIT[130], INIT[127], INIT[124], INIT[121], INIT[118], INIT[115], INIT[112], INIT[109], INIT[106], INIT[103], INIT[100], INIT[ 97], INIT[ 94], INIT[ 91], INIT[ 88], INIT[ 85], INIT[ 82], INIT[ 79], INIT[ 76], INIT[ 73], INIT[ 70], INIT[ 67], INIT[ 64], INIT[ 61], INIT[ 58], INIT[ 55], INIT[ 52], INIT[ 49], INIT[ 46], INIT[ 43], INIT[ 40], INIT[ 37], INIT[ 34], INIT[ 31], INIT[ 28], INIT[ 25], INIT[ 22], INIT[ 19], INIT[ 16], INIT[ 13], INIT[ 10], INIT[ 7], INIT[ 4], INIT[ 1]}), - .INIT_C({INIT[191], INIT[188], INIT[185], INIT[182], INIT[179], INIT[176], INIT[173], INIT[170], INIT[167], INIT[164], INIT[161], INIT[158], INIT[155], INIT[152], INIT[149], INIT[146], INIT[143], INIT[140], INIT[137], INIT[134], INIT[131], INIT[128], INIT[125], INIT[122], INIT[119], INIT[116], INIT[113], INIT[110], INIT[107], INIT[104], INIT[101], INIT[ 98], INIT[ 95], INIT[ 92], INIT[ 89], INIT[ 86], INIT[ 83], INIT[ 80], INIT[ 77], INIT[ 74], INIT[ 71], INIT[ 68], INIT[ 65], INIT[ 62], INIT[ 59], INIT[ 56], INIT[ 53], INIT[ 50], INIT[ 47], INIT[ 44], INIT[ 41], INIT[ 38], INIT[ 35], INIT[ 32], INIT[ 29], INIT[ 26], INIT[ 23], INIT[ 20], INIT[ 17], INIT[ 14], INIT[ 11], INIT[ 8], INIT[ 5], INIT[ 2]}), - .INIT_D(64'bx), - .IS_WCLK_INVERTED(!CLKPOL2) - ) _TECHMAP_REPLACE_ ( - .ADDRA(A1ADDR), - .ADDRB(A1ADDR), - .ADDRC(A1ADDR), - .DOA(A1DATA[0]), - .DOB(A1DATA[1]), - .DOC(A1DATA[2]), - .DOD(DOD_unused), - - .ADDRD(B1ADDR), - .DIA(B1DATA[0]), - .DIB(B1DATA[1]), - .DIC(B1DATA[2]), - .DID(1'b0), - .WCLK(CLK1), - .WE(B1EN) - ); -endmodule - -module \$__XILINX_RAM32X2Q (CLK1, A1ADDR, A1DATA, A2ADDR, A2DATA, A3ADDR, A3DATA, B1ADDR, B1DATA, B1EN); - parameter [63:0] INIT = 64'bx; - parameter CLKPOL2 = 1; - input CLK1; - - input [4:0] A1ADDR, A2ADDR, A3ADDR; - output [1:0] A1DATA, A2DATA, A3DATA; - - input [4:0] B1ADDR; - input [1:0] B1DATA; - input B1EN; - - RAM32M #( - .INIT_A(INIT), - .INIT_B(INIT), - .INIT_C(INIT), - .INIT_D(INIT), - .IS_WCLK_INVERTED(!CLKPOL2) - ) _TECHMAP_REPLACE_ ( - .ADDRA(A1ADDR), - .ADDRB(A2ADDR), - .ADDRC(A3ADDR), - .DOA(A1DATA), - .DOB(A2DATA), - .DOC(A3DATA), - - .ADDRD(B1ADDR), - .DIA(B1DATA), - .DIB(B1DATA), - .DIC(B1DATA), - .DID(B1DATA), - .WCLK(CLK1), - .WE(B1EN) - ); -endmodule - -module \$__XILINX_RAM64X1Q (CLK1, A1ADDR, A1DATA, A2ADDR, A2DATA, A3ADDR, A3DATA, B1ADDR, B1DATA, B1EN); - parameter [63:0] INIT = 64'bx; - parameter CLKPOL2 = 1; - input CLK1; - - input [5:0] A1ADDR, A2ADDR, A3ADDR; - output A1DATA, A2DATA, A3DATA; - - input [5:0] B1ADDR; - input B1DATA; - input B1EN; - - RAM64M #( - .INIT_A(INIT), - .INIT_B(INIT), - .INIT_C(INIT), - .INIT_D(INIT), - .IS_WCLK_INVERTED(!CLKPOL2) - ) _TECHMAP_REPLACE_ ( - .ADDRA(A1ADDR), - .ADDRB(A2ADDR), - .ADDRC(A3ADDR), - .DOA(A1DATA), - .DOB(A2DATA), - .DOC(A3DATA), - - .ADDRD(B1ADDR), - .DIA(B1DATA), - .DIB(B1DATA), - .DIC(B1DATA), - .DID(B1DATA), - .WCLK(CLK1), - .WE(B1EN) - ); -endmodule diff --git a/techlibs/xilinx/lutrams_xc5v.txt b/techlibs/xilinx/lutrams_xc5v.txt new file mode 100644 index 000000000..8ab8076b4 --- /dev/null +++ b/techlibs/xilinx/lutrams_xc5v.txt @@ -0,0 +1,100 @@ +# LUT RAMs for Virtex 5, Virtex 6, Spartan 6, Series 7. +# The corresponding mapping file is lutrams_xc5v_map.v + +# Single-port RAMs. + +ram distributed $__XILINX_LUTRAM_SP_ { + cost 8; + widthscale; + option "ABITS" 5 { + abits 5; + widths 8 global; + } + option "ABITS" 6 { + abits 6; + widths 4 global; + } + option "ABITS" 7 { + abits 7; + widths 2 global; + } + option "ABITS" 8 { + abits 8; + widths 1 global; + } + init no_undef; + prune_rom; + port arsw "RW" { + clock posedge; + } +} + +# Dual-port RAMs. + +ram distributed $__XILINX_LUTRAM_DP_ { + cost 8; + widthscale; + option "ABITS" 5 { + abits 5; + widths 4 global; + } + option "ABITS" 6 { + abits 6; + widths 2 global; + } + option "ABITS" 7 { + abits 7; + widths 1 global; + } + init no_undef; + prune_rom; + port arsw "RW" { + clock posedge; + } + port ar "R" { + } +} + +# Quad-port RAMs. + +ram distributed $__XILINX_LUTRAM_QP_ { + cost 7; + widthscale; + option "ABITS" 5 { + abits 5; + widths 2 global; + } + option "ABITS" 6 { + abits 6; + widths 1 global; + } + init no_undef; + prune_rom; + port arsw "RW" { + clock posedge; + } + port ar "R0" "R1" "R2" { + } +} + +# Simple dual port RAMs. + +ram distributed $__XILINX_LUTRAM_SDP_ { + cost 8; + widthscale 7; + option "ABITS" 5 { + abits 5; + widths 6 global; + } + option "ABITS" 6 { + abits 6; + widths 3 global; + } + init no_undef; + prune_rom; + port sw "W" { + clock posedge; + } + port ar "R" { + } +} diff --git a/techlibs/xilinx/lutrams_xc5v_map.v b/techlibs/xilinx/lutrams_xc5v_map.v new file mode 100644 index 000000000..18ce3a575 --- /dev/null +++ b/techlibs/xilinx/lutrams_xc5v_map.v @@ -0,0 +1,901 @@ +// LUT RAMs for Virtex 5, Virtex 6, Spartan 6, Series 7, Ultrascale. +// The definitions are in lutrams_xc5v.txt (everything but Ultrascale) +// and lutrams_xcu.txt (Ultrascale). + + +module $__XILINX_LUTRAM_SP_ (...); + +parameter INIT = 0; +parameter OPTION_ABITS = 5; +parameter WIDTH = 8; +parameter BITS_USED = 0; + +output [WIDTH-1:0] PORT_RW_RD_DATA; +input [WIDTH-1:0] PORT_RW_WR_DATA; +input [OPTION_ABITS-1:0] PORT_RW_ADDR; +input PORT_RW_WR_EN; +input PORT_RW_CLK; + +function [(1 << OPTION_ABITS)-1:0] init_slice; + input integer idx; + integer i; + for (i = 0; i < (1 << OPTION_ABITS); i = i + 1) + init_slice[i] = INIT[i * WIDTH + idx]; +endfunction + +function [(2 << OPTION_ABITS)-1:0] init_slice2; + input integer idx; + integer i; + for (i = 0; i < (1 << OPTION_ABITS); i = i + 1) + init_slice2[2 * i +: 2] = INIT[i * WIDTH + idx * 2 +: 2]; +endfunction + +generate +case(OPTION_ABITS) +5: if (WIDTH == 8) + RAM32M + #( + .INIT_D(init_slice2(0)), + .INIT_C(init_slice2(1)), + .INIT_B(init_slice2(2)), + .INIT_A(init_slice2(3)), + ) + _TECHMAP_REPLACE_ + ( + .DOA(PORT_RW_RD_DATA[7:6]), + .DOB(PORT_RW_RD_DATA[5:4]), + .DOC(PORT_RW_RD_DATA[3:2]), + .DOD(PORT_RW_RD_DATA[1:0]), + .DIA(PORT_RW_WR_DATA[7:6]), + .DIB(PORT_RW_WR_DATA[5:4]), + .DIC(PORT_RW_WR_DATA[3:2]), + .DID(PORT_RW_WR_DATA[1:0]), + .ADDRA(PORT_RW_ADDR), + .ADDRB(PORT_RW_ADDR), + .ADDRC(PORT_RW_ADDR), + .ADDRD(PORT_RW_ADDR), + .WE(PORT_RW_WR_EN), + .WCLK(PORT_RW_CLK), + ); +else + RAM32M16 + #( + .INIT_H(init_slice2(0)), + .INIT_G(init_slice2(1)), + .INIT_F(init_slice2(2)), + .INIT_E(init_slice2(3)), + .INIT_D(init_slice2(4)), + .INIT_C(init_slice2(5)), + .INIT_B(init_slice2(6)), + .INIT_A(init_slice2(7)), + ) + _TECHMAP_REPLACE_ + ( + .DOA(PORT_RW_RD_DATA[15:14]), + .DOB(PORT_RW_RD_DATA[13:12]), + .DOC(PORT_RW_RD_DATA[11:10]), + .DOD(PORT_RW_RD_DATA[9:8]), + .DOE(PORT_RW_RD_DATA[7:6]), + .DOF(PORT_RW_RD_DATA[5:4]), + .DOG(PORT_RW_RD_DATA[3:2]), + .DOH(PORT_RW_RD_DATA[1:0]), + .DIA(PORT_RW_WR_DATA[15:14]), + .DIB(PORT_RW_WR_DATA[13:12]), + .DIC(PORT_RW_WR_DATA[11:10]), + .DID(PORT_RW_WR_DATA[9:8]), + .DIE(PORT_RW_WR_DATA[7:6]), + .DIF(PORT_RW_WR_DATA[5:4]), + .DIG(PORT_RW_WR_DATA[3:2]), + .DIH(PORT_RW_WR_DATA[1:0]), + .ADDRA(PORT_RW_ADDR), + .ADDRB(PORT_RW_ADDR), + .ADDRC(PORT_RW_ADDR), + .ADDRD(PORT_RW_ADDR), + .ADDRE(PORT_RW_ADDR), + .ADDRF(PORT_RW_ADDR), + .ADDRG(PORT_RW_ADDR), + .ADDRH(PORT_RW_ADDR), + .WE(PORT_RW_WR_EN), + .WCLK(PORT_RW_CLK), + ); +6: begin + genvar i; + for (i = 0; i < WIDTH; i = i + 1) + if (BITS_USED[i]) + RAM64X1S + #( + .INIT(init_slice(i)), + ) + slice + ( + .A0(PORT_RW_ADDR[0]), + .A1(PORT_RW_ADDR[1]), + .A2(PORT_RW_ADDR[2]), + .A3(PORT_RW_ADDR[3]), + .A4(PORT_RW_ADDR[4]), + .A5(PORT_RW_ADDR[5]), + .D(PORT_RW_WR_DATA[i]), + .O(PORT_RW_RD_DATA[i]), + .WE(PORT_RW_WR_EN), + .WCLK(PORT_RW_CLK), + ); +end +7: begin + genvar i; + for (i = 0; i < WIDTH; i = i + 1) + if (BITS_USED[i]) + RAM128X1S + #( + .INIT(init_slice(i)), + ) + slice + ( + .A0(PORT_RW_ADDR[0]), + .A1(PORT_RW_ADDR[1]), + .A2(PORT_RW_ADDR[2]), + .A3(PORT_RW_ADDR[3]), + .A4(PORT_RW_ADDR[4]), + .A5(PORT_RW_ADDR[5]), + .A6(PORT_RW_ADDR[6]), + .D(PORT_RW_WR_DATA[i]), + .O(PORT_RW_RD_DATA[i]), + .WE(PORT_RW_WR_EN), + .WCLK(PORT_RW_CLK), + ); +end +8: begin + genvar i; + for (i = 0; i < WIDTH; i = i + 1) + if (BITS_USED[i]) + RAM256X1S + #( + .INIT(init_slice(i)), + ) + slice + ( + .A(PORT_RW_ADDR), + .D(PORT_RW_WR_DATA[i]), + .O(PORT_RW_RD_DATA[i]), + .WE(PORT_RW_WR_EN), + .WCLK(PORT_RW_CLK), + ); +end +9: begin + genvar i; + for (i = 0; i < WIDTH; i = i + 1) + if (BITS_USED[i]) + RAM512X1S + #( + .INIT(init_slice(i)), + ) + slice + ( + .A(PORT_RW_ADDR), + .D(PORT_RW_WR_DATA[i]), + .O(PORT_RW_RD_DATA[i]), + .WE(PORT_RW_WR_EN), + .WCLK(PORT_RW_CLK), + ); +end +default: + $error("invalid OPTION_ABITS/WIDTH combination"); +endcase +endgenerate + +endmodule + + +module $__XILINX_LUTRAM_DP_ (...); + +parameter INIT = 0; +parameter OPTION_ABITS = 5; +parameter WIDTH = 4; +parameter BITS_USED = 0; + +output [WIDTH-1:0] PORT_RW_RD_DATA; +input [WIDTH-1:0] PORT_RW_WR_DATA; +input [OPTION_ABITS-1:0] PORT_RW_ADDR; +input PORT_RW_WR_EN; +input PORT_RW_CLK; + +output [WIDTH-1:0] PORT_R_RD_DATA; +input [OPTION_ABITS-1:0] PORT_R_ADDR; + +function [(1 << OPTION_ABITS)-1:0] init_slice; + input integer idx; + integer i; + for (i = 0; i < (1 << OPTION_ABITS); i = i + 1) + init_slice[i] = INIT[i * WIDTH + idx]; +endfunction + +function [(2 << OPTION_ABITS)-1:0] init_slice2; + input integer idx; + integer i; + for (i = 0; i < (1 << OPTION_ABITS); i = i + 1) + init_slice2[2 * i +: 2] = INIT[i * WIDTH + idx * 2 +: 2]; +endfunction + +generate +case (OPTION_ABITS) +5: if (WIDTH == 4) + RAM32M + #( + .INIT_D(init_slice2(0)), + .INIT_C(init_slice2(0)), + .INIT_B(init_slice2(1)), + .INIT_A(init_slice2(1)), + ) + _TECHMAP_REPLACE_ + ( + .DOA(PORT_R_RD_DATA[3:2]), + .DOB(PORT_RW_RD_DATA[3:2]), + .DOC(PORT_R_RD_DATA[1:0]), + .DOD(PORT_RW_RD_DATA[1:0]), + .DIA(PORT_RW_WR_DATA[3:2]), + .DIB(PORT_RW_WR_DATA[3:2]), + .DIC(PORT_RW_WR_DATA[1:0]), + .DID(PORT_RW_WR_DATA[1:0]), + .ADDRA(PORT_R_ADDR), + .ADDRB(PORT_RW_ADDR), + .ADDRC(PORT_R_ADDR), + .ADDRD(PORT_RW_ADDR), + .WE(PORT_RW_WR_EN), + .WCLK(PORT_RW_CLK), + ); +else + RAM32M16 + #( + .INIT_H(init_slice2(0)), + .INIT_G(init_slice2(0)), + .INIT_F(init_slice2(1)), + .INIT_E(init_slice2(1)), + .INIT_D(init_slice2(2)), + .INIT_C(init_slice2(2)), + .INIT_B(init_slice2(3)), + .INIT_A(init_slice2(3)), + ) + _TECHMAP_REPLACE_ + ( + .DOA(PORT_R_RD_DATA[7:6]), + .DOB(PORT_RW_RD_DATA[7:6]), + .DOC(PORT_R_RD_DATA[5:4]), + .DOD(PORT_RW_RD_DATA[5:4]), + .DOE(PORT_R_RD_DATA[3:2]), + .DOF(PORT_RW_RD_DATA[3:2]), + .DOG(PORT_R_RD_DATA[1:0]), + .DOH(PORT_RW_RD_DATA[1:0]), + .DIA(PORT_RW_WR_DATA[7:6]), + .DIB(PORT_RW_WR_DATA[7:6]), + .DIC(PORT_RW_WR_DATA[5:4]), + .DID(PORT_RW_WR_DATA[5:4]), + .DIE(PORT_RW_WR_DATA[3:2]), + .DIF(PORT_RW_WR_DATA[3:2]), + .DIG(PORT_RW_WR_DATA[1:0]), + .DIH(PORT_RW_WR_DATA[1:0]), + .ADDRA(PORT_R_ADDR), + .ADDRB(PORT_RW_ADDR), + .ADDRC(PORT_R_ADDR), + .ADDRD(PORT_RW_ADDR), + .ADDRE(PORT_R_ADDR), + .ADDRF(PORT_RW_ADDR), + .ADDRG(PORT_R_ADDR), + .ADDRH(PORT_RW_ADDR), + .WE(PORT_RW_WR_EN), + .WCLK(PORT_RW_CLK), + ); +6: begin + genvar i; + for (i = 0; i < WIDTH; i = i + 1) + if (BITS_USED[i]) + RAM64X1D + #( + .INIT(init_slice(i)), + ) + slice + ( + .A0(PORT_RW_ADDR[0]), + .A1(PORT_RW_ADDR[1]), + .A2(PORT_RW_ADDR[2]), + .A3(PORT_RW_ADDR[3]), + .A4(PORT_RW_ADDR[4]), + .A5(PORT_RW_ADDR[5]), + .D(PORT_RW_WR_DATA[i]), + .SPO(PORT_RW_RD_DATA[i]), + .WE(PORT_RW_WR_EN), + .WCLK(PORT_RW_CLK), + .DPRA0(PORT_R_ADDR[0]), + .DPRA1(PORT_R_ADDR[1]), + .DPRA2(PORT_R_ADDR[2]), + .DPRA3(PORT_R_ADDR[3]), + .DPRA4(PORT_R_ADDR[4]), + .DPRA5(PORT_R_ADDR[5]), + .DPO(PORT_R_RD_DATA[i]), + ); +end +7: begin + genvar i; + for (i = 0; i < WIDTH; i = i + 1) + if (BITS_USED[i]) + RAM128X1D + #( + .INIT(init_slice(i)), + ) + slice + ( + .A(PORT_RW_ADDR), + .D(PORT_RW_WR_DATA[i]), + .SPO(PORT_RW_RD_DATA[i]), + .WE(PORT_RW_WR_EN), + .WCLK(PORT_RW_CLK), + .DPRA(PORT_R_ADDR), + .DPO(PORT_R_RD_DATA[i]), + ); +end +8: begin + genvar i; + for (i = 0; i < WIDTH; i = i + 1) + if (BITS_USED[i]) + RAM256X1D + #( + .INIT(init_slice(i)), + ) + slice + ( + .A(PORT_RW_ADDR), + .D(PORT_RW_WR_DATA[i]), + .SPO(PORT_RW_RD_DATA[i]), + .WE(PORT_RW_WR_EN), + .WCLK(PORT_RW_CLK), + .DPRA(PORT_R_ADDR), + .DPO(PORT_R_RD_DATA[i]), + ); +end +default: + $error("invalid OPTION_ABITS/WIDTH combination"); +endcase +endgenerate + +endmodule + + +module $__XILINX_LUTRAM_QP_ (...); + +parameter INIT = 0; +parameter OPTION_ABITS = 5; +parameter WIDTH = 2; +parameter BITS_USED = 0; + +output [WIDTH-1:0] PORT_RW_RD_DATA; +input [WIDTH-1:0] PORT_RW_WR_DATA; +input [OPTION_ABITS-1:0] PORT_RW_ADDR; +input PORT_RW_WR_EN; +input PORT_RW_CLK; + +output [WIDTH-1:0] PORT_R0_RD_DATA; +input [OPTION_ABITS-1:0] PORT_R0_ADDR; +output [WIDTH-1:0] PORT_R1_RD_DATA; +input [OPTION_ABITS-1:0] PORT_R1_ADDR; +output [WIDTH-1:0] PORT_R2_RD_DATA; +input [OPTION_ABITS-1:0] PORT_R2_ADDR; + +function [(1 << OPTION_ABITS)-1:0] init_slice; + input integer idx; + integer i; + for (i = 0; i < (1 << OPTION_ABITS); i = i + 1) + init_slice[i] = INIT[i * WIDTH + idx]; +endfunction + +function [(2 << OPTION_ABITS)-1:0] init_slice2; + input integer idx; + integer i; + for (i = 0; i < (1 << OPTION_ABITS); i = i + 1) + init_slice2[2 * i +: 2] = INIT[i * WIDTH + idx * 2 +: 2]; +endfunction + +generate +case (OPTION_ABITS) +5: if (WIDTH == 2) + RAM32M + #( + .INIT_D(init_slice2(0)), + .INIT_C(init_slice2(0)), + .INIT_B(init_slice2(0)), + .INIT_A(init_slice2(0)), + ) + _TECHMAP_REPLACE_ + ( + .DOA(PORT_R2_RD_DATA[1:0]), + .DOB(PORT_R1_RD_DATA[1:0]), + .DOC(PORT_R0_RD_DATA[1:0]), + .DOD(PORT_RW_RD_DATA[1:0]), + .DIA(PORT_RW_WR_DATA[1:0]), + .DIB(PORT_RW_WR_DATA[1:0]), + .DIC(PORT_RW_WR_DATA[1:0]), + .DID(PORT_RW_WR_DATA[1:0]), + .ADDRA(PORT_R2_ADDR), + .ADDRB(PORT_R1_ADDR), + .ADDRC(PORT_R0_ADDR), + .ADDRD(PORT_RW_ADDR), + .WE(PORT_RW_WR_EN), + .WCLK(PORT_RW_CLK), + ); +else + RAM32M16 + #( + .INIT_H(init_slice2(0)), + .INIT_G(init_slice2(0)), + .INIT_F(init_slice2(0)), + .INIT_E(init_slice2(0)), + .INIT_D(init_slice2(1)), + .INIT_C(init_slice2(1)), + .INIT_B(init_slice2(1)), + .INIT_A(init_slice2(1)), + ) + _TECHMAP_REPLACE_ + ( + .DOA(PORT_R2_RD_DATA[3:2]), + .DOB(PORT_R1_RD_DATA[3:2]), + .DOC(PORT_R0_RD_DATA[3:2]), + .DOD(PORT_RW_RD_DATA[3:2]), + .DOE(PORT_R2_RD_DATA[1:0]), + .DOF(PORT_R1_RD_DATA[1:0]), + .DOG(PORT_R0_RD_DATA[1:0]), + .DOH(PORT_RW_RD_DATA[1:0]), + .DIA(PORT_RW_WR_DATA[3:2]), + .DIB(PORT_RW_WR_DATA[3:2]), + .DIC(PORT_RW_WR_DATA[3:2]), + .DID(PORT_RW_WR_DATA[3:2]), + .DIE(PORT_RW_WR_DATA[1:0]), + .DIF(PORT_RW_WR_DATA[1:0]), + .DIG(PORT_RW_WR_DATA[1:0]), + .DIH(PORT_RW_WR_DATA[1:0]), + .ADDRA(PORT_R2_ADDR), + .ADDRB(PORT_R1_ADDR), + .ADDRC(PORT_R0_ADDR), + .ADDRD(PORT_RW_ADDR), + .ADDRE(PORT_R2_ADDR), + .ADDRF(PORT_R1_ADDR), + .ADDRG(PORT_R0_ADDR), + .ADDRH(PORT_RW_ADDR), + .WE(PORT_RW_WR_EN), + .WCLK(PORT_RW_CLK), + ); +6: if (WIDTH == 1) + RAM64M + #( + .INIT_D(init_slice(0)), + .INIT_C(init_slice(0)), + .INIT_B(init_slice(0)), + .INIT_A(init_slice(0)), + ) + _TECHMAP_REPLACE_ + ( + .DOA(PORT_R2_RD_DATA[0]), + .DOB(PORT_R1_RD_DATA[0]), + .DOC(PORT_R0_RD_DATA[0]), + .DOD(PORT_RW_RD_DATA[0]), + .DIA(PORT_RW_WR_DATA[0]), + .DIB(PORT_RW_WR_DATA[0]), + .DIC(PORT_RW_WR_DATA[0]), + .DID(PORT_RW_WR_DATA[0]), + .ADDRA(PORT_R2_ADDR), + .ADDRB(PORT_R1_ADDR), + .ADDRC(PORT_R0_ADDR), + .ADDRD(PORT_RW_ADDR), + .WE(PORT_RW_WR_EN), + .WCLK(PORT_RW_CLK), + ); +else + RAM64M8 + #( + .INIT_H(init_slice(0)), + .INIT_G(init_slice(0)), + .INIT_F(init_slice(0)), + .INIT_E(init_slice(0)), + .INIT_D(init_slice(1)), + .INIT_C(init_slice(1)), + .INIT_B(init_slice(1)), + .INIT_A(init_slice(1)), + ) + _TECHMAP_REPLACE_ + ( + .DOA(PORT_R2_RD_DATA[1]), + .DOB(PORT_R1_RD_DATA[1]), + .DOC(PORT_R0_RD_DATA[1]), + .DOD(PORT_RW_RD_DATA[1]), + .DOE(PORT_R2_RD_DATA[0]), + .DOF(PORT_R1_RD_DATA[0]), + .DOG(PORT_R0_RD_DATA[0]), + .DOH(PORT_RW_RD_DATA[0]), + .DIA(PORT_RW_WR_DATA[1]), + .DIB(PORT_RW_WR_DATA[1]), + .DIC(PORT_RW_WR_DATA[1]), + .DID(PORT_RW_WR_DATA[1]), + .DIE(PORT_RW_WR_DATA[0]), + .DIF(PORT_RW_WR_DATA[0]), + .DIG(PORT_RW_WR_DATA[0]), + .DIH(PORT_RW_WR_DATA[0]), + .ADDRA(PORT_R2_ADDR), + .ADDRB(PORT_R1_ADDR), + .ADDRC(PORT_R0_ADDR), + .ADDRD(PORT_RW_ADDR), + .ADDRE(PORT_R2_ADDR), + .ADDRF(PORT_R1_ADDR), + .ADDRG(PORT_R0_ADDR), + .ADDRH(PORT_RW_ADDR), + .WE(PORT_RW_WR_EN), + .WCLK(PORT_RW_CLK), + ); +default: + $error("invalid OPTION_ABITS/WIDTH combination"); +endcase +endgenerate + +endmodule + + +module $__XILINX_LUTRAM_OP_ (...); + +parameter INIT = 0; +parameter OPTION_ABITS = 5; +parameter WIDTH = 2; +parameter BITS_USED = 0; + +output [WIDTH-1:0] PORT_RW_RD_DATA; +input [WIDTH-1:0] PORT_RW_WR_DATA; +input [OPTION_ABITS-1:0] PORT_RW_ADDR; +input PORT_RW_WR_EN; +input PORT_RW_CLK; + +output [WIDTH-1:0] PORT_R0_RD_DATA; +input [OPTION_ABITS-1:0] PORT_R0_ADDR; +output [WIDTH-1:0] PORT_R1_RD_DATA; +input [OPTION_ABITS-1:0] PORT_R1_ADDR; +output [WIDTH-1:0] PORT_R2_RD_DATA; +input [OPTION_ABITS-1:0] PORT_R2_ADDR; +output [WIDTH-1:0] PORT_R3_RD_DATA; +input [OPTION_ABITS-1:0] PORT_R3_ADDR; +output [WIDTH-1:0] PORT_R4_RD_DATA; +input [OPTION_ABITS-1:0] PORT_R4_ADDR; +output [WIDTH-1:0] PORT_R5_RD_DATA; +input [OPTION_ABITS-1:0] PORT_R5_ADDR; +output [WIDTH-1:0] PORT_R6_RD_DATA; +input [OPTION_ABITS-1:0] PORT_R6_ADDR; + +generate +case (OPTION_ABITS) +5: RAM32M16 + #( + .INIT_H(INIT), + .INIT_G(INIT), + .INIT_F(INIT), + .INIT_E(INIT), + .INIT_D(INIT), + .INIT_C(INIT), + .INIT_B(INIT), + .INIT_A(INIT), + ) + _TECHMAP_REPLACE_ + ( + .DOA(PORT_R6_RD_DATA), + .DOB(PORT_R5_RD_DATA), + .DOC(PORT_R4_RD_DATA), + .DOD(PORT_R3_RD_DATA), + .DOE(PORT_R2_RD_DATA), + .DOF(PORT_R1_RD_DATA), + .DOG(PORT_R0_RD_DATA), + .DOH(PORT_RW_RD_DATA), + .DIA(PORT_RW_WR_DATA), + .DIB(PORT_RW_WR_DATA), + .DIC(PORT_RW_WR_DATA), + .DID(PORT_RW_WR_DATA), + .DIE(PORT_RW_WR_DATA), + .DIF(PORT_RW_WR_DATA), + .DIG(PORT_RW_WR_DATA), + .DIH(PORT_RW_WR_DATA), + .ADDRA(PORT_R6_ADDR), + .ADDRB(PORT_R5_ADDR), + .ADDRC(PORT_R4_ADDR), + .ADDRD(PORT_R3_ADDR), + .ADDRE(PORT_R2_ADDR), + .ADDRF(PORT_R1_ADDR), + .ADDRG(PORT_R0_ADDR), + .ADDRH(PORT_RW_ADDR), + .WE(PORT_RW_WR_EN), + .WCLK(PORT_RW_CLK), + ); +6: RAM64M8 + #( + .INIT_H(INIT), + .INIT_G(INIT), + .INIT_F(INIT), + .INIT_E(INIT), + .INIT_D(INIT), + .INIT_C(INIT), + .INIT_B(INIT), + .INIT_A(INIT), + ) + _TECHMAP_REPLACE_ + ( + .DOA(PORT_R6_RD_DATA), + .DOB(PORT_R5_RD_DATA), + .DOC(PORT_R4_RD_DATA), + .DOD(PORT_R3_RD_DATA), + .DOE(PORT_R2_RD_DATA), + .DOF(PORT_R1_RD_DATA), + .DOG(PORT_R0_RD_DATA), + .DOH(PORT_RW_RD_DATA), + .DIA(PORT_RW_WR_DATA), + .DIB(PORT_RW_WR_DATA), + .DIC(PORT_RW_WR_DATA), + .DID(PORT_RW_WR_DATA), + .DIE(PORT_RW_WR_DATA), + .DIF(PORT_RW_WR_DATA), + .DIG(PORT_RW_WR_DATA), + .DIH(PORT_RW_WR_DATA), + .ADDRA(PORT_R6_ADDR), + .ADDRB(PORT_R5_ADDR), + .ADDRC(PORT_R4_ADDR), + .ADDRD(PORT_R3_ADDR), + .ADDRE(PORT_R2_ADDR), + .ADDRF(PORT_R1_ADDR), + .ADDRG(PORT_R0_ADDR), + .ADDRH(PORT_RW_ADDR), + .WE(PORT_RW_WR_EN), + .WCLK(PORT_RW_CLK), + ); +default: + $error("invalid OPTION_ABITS/WIDTH combination"); +endcase +endgenerate + +endmodule + + +module $__XILINX_LUTRAM_SDP_ (...); + +parameter INIT = 0; +parameter OPTION_ABITS = 5; +parameter WIDTH = 6; +parameter BITS_USED = 0; + +input [WIDTH-1:0] PORT_W_WR_DATA; +input [OPTION_ABITS-1:0] PORT_W_ADDR; +input PORT_W_WR_EN; +input PORT_W_CLK; + +output [WIDTH-1:0] PORT_R_RD_DATA; +input [OPTION_ABITS-1:0] PORT_R_ADDR; + +function [(1 << OPTION_ABITS)-1:0] init_slice; + input integer idx; + integer i; + for (i = 0; i < (1 << OPTION_ABITS); i = i + 1) + init_slice[i] = INIT[i * WIDTH + idx]; +endfunction + +function [(2 << OPTION_ABITS)-1:0] init_slice2; + input integer idx; + integer i; + for (i = 0; i < (1 << OPTION_ABITS); i = i + 1) + init_slice2[2 * i +: 2] = INIT[i * WIDTH + idx * 2 +: 2]; +endfunction + +generate +case (OPTION_ABITS) +5: if (WIDTH == 6) + RAM32M + #( + .INIT_C(init_slice2(0)), + .INIT_B(init_slice2(1)), + .INIT_A(init_slice2(2)), + ) + _TECHMAP_REPLACE_ + ( + .DOA(PORT_R_RD_DATA[5:4]), + .DOB(PORT_R_RD_DATA[3:2]), + .DOC(PORT_R_RD_DATA[1:0]), + .DIA(PORT_W_WR_DATA[5:4]), + .DIB(PORT_W_WR_DATA[3:2]), + .DIC(PORT_W_WR_DATA[1:0]), + .ADDRA(PORT_R_ADDR), + .ADDRB(PORT_R_ADDR), + .ADDRC(PORT_R_ADDR), + .ADDRD(PORT_W_ADDR), + .WE(PORT_W_WR_EN), + .WCLK(PORT_W_CLK), + ); +else + RAM32M16 + #( + .INIT_G(init_slice2(0)), + .INIT_F(init_slice2(1)), + .INIT_E(init_slice2(2)), + .INIT_D(init_slice2(3)), + .INIT_C(init_slice2(4)), + .INIT_B(init_slice2(5)), + .INIT_A(init_slice2(6)), + ) + _TECHMAP_REPLACE_ + ( + .DOA(PORT_R_RD_DATA[13:12]), + .DOB(PORT_R_RD_DATA[11:10]), + .DOC(PORT_R_RD_DATA[9:8]), + .DOD(PORT_R_RD_DATA[7:6]), + .DOE(PORT_R_RD_DATA[5:4]), + .DOF(PORT_R_RD_DATA[3:2]), + .DOG(PORT_R_RD_DATA[1:0]), + .DIA(PORT_W_WR_DATA[13:12]), + .DIB(PORT_W_WR_DATA[11:10]), + .DIC(PORT_W_WR_DATA[9:8]), + .DID(PORT_W_WR_DATA[7:6]), + .DIE(PORT_W_WR_DATA[5:4]), + .DIF(PORT_W_WR_DATA[3:2]), + .DIG(PORT_W_WR_DATA[1:0]), + .ADDRA(PORT_R_ADDR), + .ADDRB(PORT_R_ADDR), + .ADDRC(PORT_R_ADDR), + .ADDRD(PORT_R_ADDR), + .ADDRE(PORT_R_ADDR), + .ADDRF(PORT_R_ADDR), + .ADDRG(PORT_R_ADDR), + .ADDRH(PORT_W_ADDR), + .WE(PORT_W_WR_EN), + .WCLK(PORT_W_CLK), + ); +6: if (WIDTH == 3) + RAM64M + #( + .INIT_C(init_slice(0)), + .INIT_B(init_slice(1)), + .INIT_A(init_slice(2)), + ) + _TECHMAP_REPLACE_ + ( + .DOA(PORT_R_RD_DATA[2]), + .DOB(PORT_R_RD_DATA[1]), + .DOC(PORT_R_RD_DATA[0]), + .DIA(PORT_W_WR_DATA[2]), + .DIB(PORT_W_WR_DATA[1]), + .DIC(PORT_W_WR_DATA[0]), + .ADDRA(PORT_R_ADDR), + .ADDRB(PORT_R_ADDR), + .ADDRC(PORT_R_ADDR), + .ADDRD(PORT_W_ADDR), + .WE(PORT_W_WR_EN), + .WCLK(PORT_W_CLK), + ); +else + RAM64M8 + #( + .INIT_G(init_slice(0)), + .INIT_F(init_slice(1)), + .INIT_E(init_slice(2)), + .INIT_D(init_slice(3)), + .INIT_C(init_slice(4)), + .INIT_B(init_slice(5)), + .INIT_A(init_slice(6)), + ) + _TECHMAP_REPLACE_ + ( + .DOA(PORT_R_RD_DATA[6]), + .DOB(PORT_R_RD_DATA[5]), + .DOC(PORT_R_RD_DATA[4]), + .DOD(PORT_R_RD_DATA[3]), + .DOE(PORT_R_RD_DATA[2]), + .DOF(PORT_R_RD_DATA[1]), + .DOG(PORT_R_RD_DATA[0]), + .DIA(PORT_W_WR_DATA[6]), + .DIB(PORT_W_WR_DATA[5]), + .DIC(PORT_W_WR_DATA[4]), + .DID(PORT_W_WR_DATA[3]), + .DIE(PORT_W_WR_DATA[2]), + .DIF(PORT_W_WR_DATA[1]), + .DIG(PORT_W_WR_DATA[0]), + .ADDRA(PORT_R_ADDR), + .ADDRB(PORT_R_ADDR), + .ADDRC(PORT_R_ADDR), + .ADDRD(PORT_R_ADDR), + .ADDRE(PORT_R_ADDR), + .ADDRF(PORT_R_ADDR), + .ADDRG(PORT_R_ADDR), + .ADDRH(PORT_W_ADDR), + .WE(PORT_W_WR_EN), + .WCLK(PORT_W_CLK), + ); +default: + $error("invalid OPTION_ABITS/WIDTH combination"); +endcase +endgenerate + +endmodule + + +module $__XILINX_LUTRAM_64X8SW_ (...); + +parameter INIT = 0; +parameter OPTION_ABITS = 9; +parameter PORT_RW_WR_WIDTH = 1; +parameter PORT_RW_RD_WIDTH = 8; + +output [PORT_RW_RD_WIDTH-1:0] PORT_RW_RD_DATA; +input [PORT_RW_WR_WIDTH-1:0] PORT_RW_WR_DATA; +input [OPTION_ABITS-1:0] PORT_RW_ADDR; +input PORT_RW_WR_EN; +input PORT_RW_CLK; + +function [63:0] init_slice; + input integer idx; + integer i; + for (i = 0; i < 64; i = i + 1) + init_slice[i] = INIT[i * 8 + idx]; +endfunction + +RAM64X8SW +#( + .INIT_A(init_slice(7)), + .INIT_B(init_slice(6)), + .INIT_C(init_slice(5)), + .INIT_D(init_slice(4)), + .INIT_E(init_slice(3)), + .INIT_F(init_slice(2)), + .INIT_G(init_slice(1)), + .INIT_H(init_slice(0)), +) +_TECHMAP_REPLACE_ +( + .A(PORT_RW_ADDR[8:3]), + .WSEL(PORT_RW_ADDR[2:0]), + .D(PORT_RW_WR_DATA), + .O(PORT_RW_RD_DATA), + .WE(PORT_RW_WR_EN), + .WCLK(PORT_RW_CLK), +); + +endmodule + + +module $__XILINX_LUTRAM_32X16DR8_ (...); + +parameter OPTION_ABITS = 6; +parameter BITS_USED = 0; +parameter PORT_W_WIDTH = 14; +parameter PORT_R_WIDTH = 7; + +input [PORT_W_WIDTH-1:0] PORT_W_WR_DATA; +input [OPTION_ABITS-1:0] PORT_W_ADDR; +input PORT_W_WR_EN; +input PORT_W_CLK; + +output [PORT_R_WIDTH-1:0] PORT_R_RD_DATA; +input [OPTION_ABITS-1:0] PORT_R_ADDR; + +RAM32X16DR8 _TECHMAP_REPLACE_ +( + .DOA(PORT_R_RD_DATA[6]), + .DOB(PORT_R_RD_DATA[5]), + .DOC(PORT_R_RD_DATA[4]), + .DOD(PORT_R_RD_DATA[3]), + .DOE(PORT_R_RD_DATA[2]), + .DOF(PORT_R_RD_DATA[1]), + .DOG(PORT_R_RD_DATA[0]), + .DIA({PORT_W_WR_DATA[13], PORT_W_WR_DATA[6]}), + .DIB({PORT_W_WR_DATA[12], PORT_W_WR_DATA[5]}), + .DIC({PORT_W_WR_DATA[11], PORT_W_WR_DATA[4]}), + .DID({PORT_W_WR_DATA[10], PORT_W_WR_DATA[3]}), + .DIE({PORT_W_WR_DATA[9], PORT_W_WR_DATA[2]}), + .DIF({PORT_W_WR_DATA[8], PORT_W_WR_DATA[1]}), + .DIG({PORT_W_WR_DATA[7], PORT_W_WR_DATA[0]}), + .ADDRA(PORT_R_ADDR), + .ADDRB(PORT_R_ADDR), + .ADDRC(PORT_R_ADDR), + .ADDRD(PORT_R_ADDR), + .ADDRE(PORT_R_ADDR), + .ADDRF(PORT_R_ADDR), + .ADDRG(PORT_R_ADDR), + .ADDRH(PORT_W_ADDR[5:1]), + .WE(PORT_W_WR_EN), + .WCLK(PORT_W_CLK), +); + +endmodule diff --git a/techlibs/xilinx/lutrams_xcu.txt b/techlibs/xilinx/lutrams_xcu.txt new file mode 100644 index 000000000..8062250bf --- /dev/null +++ b/techlibs/xilinx/lutrams_xcu.txt @@ -0,0 +1,162 @@ +# LUT RAMs for Ultrascale. +# The corresponding mapping file is lutrams_xc5v_map.v + +# Single-port RAMs. + +ram distributed $__XILINX_LUTRAM_SP_ { + cost 16; + widthscale; + option "ABITS" 5 { + abits 5; + widths 16 global; + } + option "ABITS" 6 { + abits 6; + widths 8 global; + } + option "ABITS" 7 { + abits 7; + widths 4 global; + } + option "ABITS" 8 { + abits 8; + widths 2 global; + } + option "ABITS" 16 { + abits 16; + widths 1 global; + } + init any; + prune_rom; + port arsw "RW" { + clock posedge; + } +} + +# Dual-port RAMs. + +ram distributed $__XILINX_LUTRAM_DP_ { + cost 16; + widthscale; + option "ABITS" 5 { + abits 5; + widths 8 global; + } + option "ABITS" 6 { + abits 6; + widths 4 global; + } + option "ABITS" 7 { + abits 7; + widths 2 global; + } + option "ABITS" 8 { + abits 8; + widths 1 global; + } + init any; + prune_rom; + port arsw "RW" { + clock posedge; + } + port ar "R" { + } +} + +# Quad-port RAMs. + +ram distributed $__XILINX_LUTRAM_QP_ { + cost 16; + widthscale; + option "ABITS" 5 { + abits 5; + widths 4 global; + } + option "ABITS" 6 { + abits 6; + widths 2 global; + } + init any; + prune_rom; + port arsw "RW" { + clock posedge; + } + port ar "R0" "R1" "R2" { + } +} + +# Octal-port RAMs. + +ram distributed $__XILINX_LUTRAM_OP_ { + cost 16; + widthscale; + option "ABITS" 5 { + abits 5; + widths 2 global; + } + option "ABITS" 6 { + abits 6; + widths 1 global; + } + init any; + prune_rom; + port arsw "RW" { + clock posedge; + } + port ar "R0" "R1" "R2" "R3" "R4" "R5" "R6" { + } +} + +# Simple dual port RAMs. + +ram distributed $__XILINX_LUTRAM_SDP_ { + cost 16; + widthscale; + option "ABITS" 5 { + abits 5; + widths 14 global; + } + option "ABITS" 6 { + abits 6; + widths 7 global; + } + init any; + prune_rom; + port sw "W" { + clock posedge; + } + port ar "R" { + } +} + +# Wide-read RAM. + +ram distributed $__XILINX_LUTRAM_64X8SW_ { + cost 16; + abits 9; + widths 1 2 4 8 per_port; + init any; + prune_rom; + port arsw "RW" { + width rd 8 wr 1; + clock posedge; + } +} + +# Wide-write RAM. + +ram distributed $__XILINX_LUTRAM_32X16DR8_ { + cost 16; + widthscale; + abits 6; + widths 7 14 per_port; + # Yes, no initialization capability. + prune_rom; + port sw "W" { + width 14; + clock posedge; + } + port ar "R" { + width 7; + } +} diff --git a/techlibs/xilinx/lutrams_xcv.txt b/techlibs/xilinx/lutrams_xcv.txt new file mode 100644 index 000000000..0bf17ae35 --- /dev/null +++ b/techlibs/xilinx/lutrams_xcv.txt @@ -0,0 +1,59 @@ +# LUT RAMs for Virtex, Virtex 2, Spartan 3, Virtex 4. +# The corresponding mapping file is lutrams_xcv_map.v + +ram distributed $__XILINX_LUTRAM_SP_ { + width 1; + option "ABITS" 4 { + abits 4; + cost 3; + } + option "ABITS" 5 { + abits 5; + cost 5; + } + ifndef IS_VIRTEX { + option "ABITS" 6 { + abits 6; + cost 9; + } + } + ifdef IS_VIRTEX2 { + # RAM128X1S + option "ABITS" 7 { + abits 7; + cost 17; + } + } + init no_undef; + prune_rom; + port arsw "RW" { + clock posedge; + } +} + +ram distributed $__XILINX_LUTRAM_DP_ { + width 1; + option "ABITS" 4 { + abits 4; + cost 5; + } + ifdef IS_VIRTEX2 { + # RAM32X1D + option "ABITS" 5 { + abits 5; + cost 9; + } + # RAM64X1D + option "ABITS" 6 { + abits 6; + cost 17; + } + } + init no_undef; + prune_rom; + port arsw "RW" { + clock posedge; + } + port ar "R" { + } +} diff --git a/techlibs/xilinx/lutrams_xcv_map.v b/techlibs/xilinx/lutrams_xcv_map.v new file mode 100644 index 000000000..91a96942a --- /dev/null +++ b/techlibs/xilinx/lutrams_xcv_map.v @@ -0,0 +1,177 @@ +// LUT RAMs for Virtex, Virtex 2, Spartan 3, Virtex 4. +// The corresponding definition file is lutrams_xcv.txt + +module $__XILINX_LUTRAM_SP_ (...); + +parameter INIT = 0; +parameter OPTION_ABITS = 4; + +output PORT_RW_RD_DATA; +input PORT_RW_WR_DATA; +input [OPTION_ABITS-1:0] PORT_RW_ADDR; +input PORT_RW_WR_EN; +input PORT_RW_CLK; + +generate +case(OPTION_ABITS) +4: RAM16X1S + #( + .INIT(INIT), + ) + _TECHMAP_REPLACE_ + ( + .A0(PORT_RW_ADDR[0]), + .A1(PORT_RW_ADDR[1]), + .A2(PORT_RW_ADDR[2]), + .A3(PORT_RW_ADDR[3]), + .D(PORT_RW_WR_DATA), + .O(PORT_RW_RD_DATA), + .WE(PORT_RW_WR_EN), + .WCLK(PORT_RW_CLK), + ); +5: RAM32X1S + #( + .INIT(INIT), + ) + _TECHMAP_REPLACE_ + ( + .A0(PORT_RW_ADDR[0]), + .A1(PORT_RW_ADDR[1]), + .A2(PORT_RW_ADDR[2]), + .A3(PORT_RW_ADDR[3]), + .A4(PORT_RW_ADDR[4]), + .D(PORT_RW_WR_DATA), + .O(PORT_RW_RD_DATA), + .WE(PORT_RW_WR_EN), + .WCLK(PORT_RW_CLK), + ); +6: RAM64X1S + #( + .INIT(INIT), + ) + _TECHMAP_REPLACE_ + ( + .A0(PORT_RW_ADDR[0]), + .A1(PORT_RW_ADDR[1]), + .A2(PORT_RW_ADDR[2]), + .A3(PORT_RW_ADDR[3]), + .A4(PORT_RW_ADDR[4]), + .A5(PORT_RW_ADDR[5]), + .D(PORT_RW_WR_DATA), + .O(PORT_RW_RD_DATA), + .WE(PORT_RW_WR_EN), + .WCLK(PORT_RW_CLK), + ); +7: RAM128X1S + #( + .INIT(INIT), + ) + _TECHMAP_REPLACE_ + ( + .A0(PORT_RW_ADDR[0]), + .A1(PORT_RW_ADDR[1]), + .A2(PORT_RW_ADDR[2]), + .A3(PORT_RW_ADDR[3]), + .A4(PORT_RW_ADDR[4]), + .A5(PORT_RW_ADDR[5]), + .A6(PORT_RW_ADDR[6]), + .D(PORT_RW_WR_DATA), + .O(PORT_RW_RD_DATA), + .WE(PORT_RW_WR_EN), + .WCLK(PORT_RW_CLK), + ); +default: + $error("invalid OPTION_ABITS"); +endcase +endgenerate + +endmodule + +module $__XILINX_LUTRAM_DP_ (...); + +parameter INIT = 0; +parameter OPTION_ABITS = 4; + +output PORT_RW_RD_DATA; +input PORT_RW_WR_DATA; +input [OPTION_ABITS-1:0] PORT_RW_ADDR; +input PORT_RW_WR_EN; +input PORT_RW_CLK; + +output PORT_R_RD_DATA; +input [OPTION_ABITS-1:0] PORT_R_ADDR; + +generate +case (OPTION_ABITS) +4: RAM16X1D + #( + .INIT(INIT), + ) + _TECHMAP_REPLACE_ + ( + .A0(PORT_RW_ADDR[0]), + .A1(PORT_RW_ADDR[1]), + .A2(PORT_RW_ADDR[2]), + .A3(PORT_RW_ADDR[3]), + .D(PORT_RW_WR_DATA), + .SPO(PORT_RW_RD_DATA), + .WE(PORT_RW_WR_EN), + .WCLK(PORT_RW_CLK), + .DPRA0(PORT_R_ADDR[0]), + .DPRA1(PORT_R_ADDR[1]), + .DPRA2(PORT_R_ADDR[2]), + .DPRA3(PORT_R_ADDR[3]), + .DPO(PORT_R_RD_DATA), + ); +5: RAM32X1D + #( + .INIT(INIT), + ) + _TECHMAP_REPLACE_ + ( + .A0(PORT_RW_ADDR[0]), + .A1(PORT_RW_ADDR[1]), + .A2(PORT_RW_ADDR[2]), + .A3(PORT_RW_ADDR[3]), + .A4(PORT_RW_ADDR[4]), + .D(PORT_RW_WR_DATA), + .SPO(PORT_RW_RD_DATA), + .WE(PORT_RW_WR_EN), + .WCLK(PORT_RW_CLK), + .DPRA0(PORT_R_ADDR[0]), + .DPRA1(PORT_R_ADDR[1]), + .DPRA2(PORT_R_ADDR[2]), + .DPRA3(PORT_R_ADDR[3]), + .DPRA4(PORT_R_ADDR[4]), + .DPO(PORT_R_RD_DATA), + ); +6: RAM64X1D + #( + .INIT(INIT), + ) + _TECHMAP_REPLACE_ + ( + .A0(PORT_RW_ADDR[0]), + .A1(PORT_RW_ADDR[1]), + .A2(PORT_RW_ADDR[2]), + .A3(PORT_RW_ADDR[3]), + .A4(PORT_RW_ADDR[4]), + .A5(PORT_RW_ADDR[5]), + .D(PORT_RW_WR_DATA), + .SPO(PORT_RW_RD_DATA), + .WE(PORT_RW_WR_EN), + .WCLK(PORT_RW_CLK), + .DPRA0(PORT_R_ADDR[0]), + .DPRA1(PORT_R_ADDR[1]), + .DPRA2(PORT_R_ADDR[2]), + .DPRA3(PORT_R_ADDR[3]), + .DPRA4(PORT_R_ADDR[4]), + .DPRA5(PORT_R_ADDR[5]), + .DPO(PORT_R_RD_DATA), + ); +default: + $error("invalid OPTION_ABITS"); +endcase +endgenerate + +endmodule diff --git a/techlibs/xilinx/synth_xilinx.cc b/techlibs/xilinx/synth_xilinx.cc index 28672fb2e..6214e1411 100644 --- a/techlibs/xilinx/synth_xilinx.cc +++ b/techlibs/xilinx/synth_xilinx.cc @@ -450,56 +450,97 @@ struct SynthXilinxPass : public ScriptPass run("opt_clean"); } - if (check_label("map_uram", "(only if '-uram')")) { + if (check_label("map_memory")) { + std::string params = ""; + std::string lutrams_map = "+/xilinx/lutrams_<family>_map.v"; + std::string brams_map = "+/xilinx/brams_<family>_map.v"; if (help_mode) { - run("memory_bram -rules +/xilinx/{family}_urams.txt"); - run("techmap -map +/xilinx/{family}_urams_map.v"); - } else if (uram) { - if (family == "xcup") { - run("memory_bram -rules +/xilinx/xcup_urams.txt"); - run("techmap -map +/xilinx/xcup_urams_map.v"); - } else { - log_warning("UltraRAM inference not supported for family %s.\n", family.c_str()); - } - } - } - - if (check_label("map_bram", "(skip if '-nobram')")) { - if (help_mode) { - run("memory_bram -rules +/xilinx/{family}_brams.txt"); - run("techmap -map +/xilinx/{family}_brams_map.v"); - } else if (!nobram) { - if (family == "xc2v" || family == "xc2vp" || family == "xc3s" || family == "xc3se") { - run("memory_bram -rules +/xilinx/xc2v_brams.txt"); - run("techmap -map +/xilinx/xc2v_brams_map.v"); + params = " [...]"; + } else { + if (family == "xcv" || family == "xcve") { + params += " -lib +/xilinx/lutrams_xcv.txt"; + params += " -D IS_VIRTEX"; + lutrams_map = "+/xilinx/lutrams_xcv_map.v"; + params += " -lib +/xilinx/brams_xcv.txt"; + brams_map = "+/xilinx/brams_xcv_map.v"; + } else if (family == "xc2v" || family == "xc2vp") { + params += " -lib +/xilinx/lutrams_xcv.txt"; + params += " -D IS_VIRTEX2"; + lutrams_map = "+/xilinx/lutrams_xcv_map.v"; + params += " -lib +/xilinx/brams_xc2v.txt"; + brams_map = "+/xilinx/brams_xc2v_map.v"; + } else if (family == "xc3s" || family == "xc3se") { + params += " -lib +/xilinx/lutrams_xcv.txt"; + lutrams_map = "+/xilinx/lutrams_xcv_map.v"; + params += " -lib +/xilinx/brams_xc2v.txt"; + brams_map = "+/xilinx/brams_xc2v_map.v"; } else if (family == "xc3sa") { - // Superset of Virtex 2 primitives — uses common map file. - run("memory_bram -rules +/xilinx/xc3sa_brams.txt"); - run("techmap -map +/xilinx/xc2v_brams_map.v"); + params += " -lib +/xilinx/lutrams_xcv.txt"; + lutrams_map = "+/xilinx/lutrams_xcv_map.v"; + params += " -lib +/xilinx/brams_xc2v.txt"; + params += " -D HAS_BE"; + brams_map = "+/xilinx/brams_xc2v_map.v"; } else if (family == "xc3sda") { - // Supported block RAMs for Spartan 3A DSP are - // a subset of Spartan 6's ones. - run("memory_bram -rules +/xilinx/xc3sda_brams.txt"); - run("techmap -map +/xilinx/xc6s_brams_map.v"); + params += " -lib +/xilinx/lutrams_xcv.txt"; + lutrams_map = "+/xilinx/lutrams_xcv_map.v"; + params += " -lib +/xilinx/brams_xc3sda.txt"; + brams_map = "+/xilinx/brams_xc3sda_map.v"; } else if (family == "xc6s") { - run("memory_bram -rules +/xilinx/xc6s_brams.txt"); - run("techmap -map +/xilinx/xc6s_brams_map.v"); + params += " -logic-cost-rom 0.015625"; + params += " -lib +/xilinx/lutrams_xc5v.txt"; + lutrams_map = "+/xilinx/lutrams_xc5v_map.v"; + params += " -lib +/xilinx/brams_xc3sda.txt"; + params += " -D IS_SPARTAN6"; + brams_map = "+/xilinx/brams_xc3sda_map.v"; + } else if (family == "xc4v") { + params += " -lib +/xilinx/lutrams_xcv.txt"; + lutrams_map = "+/xilinx/lutrams_xcv_map.v"; + params += " -lib +/xilinx/brams_xc4v.txt"; + params += " -D HAS_CASCADE"; + brams_map = "+/xilinx/brams_xc4v_map.v"; + } else if (family == "xc5v") { + params += " -logic-cost-rom 0.015625"; + params += " -lib +/xilinx/lutrams_xc5v.txt"; + lutrams_map = "+/xilinx/lutrams_xc5v_map.v"; + params += " -lib +/xilinx/brams_xc4v.txt"; + params += " -D HAS_SIZE_36"; + params += " -D HAS_CASCADE"; + brams_map = "+/xilinx/brams_xc5v_map.v"; } else if (family == "xc6v" || family == "xc7") { - run("memory_bram -rules +/xilinx/xc7_xcu_brams.txt"); - run("techmap -map +/xilinx/xc7_brams_map.v"); + params += " -logic-cost-rom 0.015625"; + params += " -lib +/xilinx/lutrams_xc5v.txt"; + lutrams_map = "+/xilinx/lutrams_xc5v_map.v"; + params += " -lib +/xilinx/brams_xc4v.txt"; + params += " -D HAS_SIZE_36"; + params += " -D HAS_CASCADE"; + params += " -D HAS_CONFLICT_BUG"; + params += " -D HAS_MIXWIDTH_SDP"; + brams_map = "+/xilinx/brams_xc6v_map.v"; } else if (family == "xcu" || family == "xcup") { - run("memory_bram -rules +/xilinx/xc7_xcu_brams.txt"); - run("techmap -map +/xilinx/xcu_brams_map.v"); - } else { - log_warning("Block RAM inference not yet supported for family %s.\n", family.c_str()); + params += " -logic-cost-rom 0.015625"; + params += " -lib +/xilinx/lutrams_xcu.txt"; + lutrams_map = "+/xilinx/lutrams_xc5v_map.v"; + params += " -lib +/xilinx/brams_xc4v.txt"; + params += " -D HAS_SIZE_36"; + params += " -D HAS_MIXWIDTH_SDP"; + params += " -D HAS_ADDRCE"; + brams_map = "+/xilinx/brams_xcu_map.v"; + if (family == "xcup") { + params += " -lib +/xilinx/urams.txt"; + } } - } - } - - if (check_label("map_lutram", "(skip if '-nolutram')")) { - if (!nolutram || help_mode) { - run("memory_bram -rules +/xilinx/lut" + lut_size_s + "_lutrams.txt"); - run("techmap -map +/xilinx/lutrams_map.v"); + if (nolutram) + params += " -no-auto-distributed"; + if (nobram) + params += " -no-auto-block"; + if (!uram) + params += " -no-auto-huge"; + } + run("memory_libmap" + params); + run("techmap -map " + lutrams_map); + run("techmap -map " + brams_map); + if (family == "xcup") { + run("techmap -map +/xilinx/urams_map.v"); } } @@ -558,9 +599,10 @@ struct SynthXilinxPass : public ScriptPass } if (check_label("map_cells")) { - // Needs to be done before logic optimization, so that inverters (OE vs T) are handled. + // Needs to be done before logic optimization, so that inverters (inserted + // here because of negative-polarity output enable) are handled. if (help_mode || !noiopad) - run("iopadmap -bits -outpad OBUF I:O -inpad IBUF O:I -toutpad $__XILINX_TOUTPAD OE:I:O -tinoutpad $__XILINX_TINOUTPAD OE:O:I:IO A:top", "(skip if '-noiopad')"); + run("iopadmap -bits -outpad OBUF I:O -inpad IBUF O:I -toutpad OBUFT ~T:I:O -tinoutpad IOBUF ~T:O:I:IO A:top", "(skip if '-noiopad')"); std::string techmap_args = "-map +/techmap.v -map +/xilinx/cells_map.v"; if (widemux > 0) techmap_args += stringf(" -D MIN_MUX_INPUTS=%d", widemux); diff --git a/techlibs/xilinx/urams.txt b/techlibs/xilinx/urams.txt new file mode 100644 index 000000000..6a5920468 --- /dev/null +++ b/techlibs/xilinx/urams.txt @@ -0,0 +1,37 @@ +ram huge $__XILINX_URAM_ { + abits 12; + width 72; + cost 1024; + option "BYTEWIDTH" 8 byte 8; + option "BYTEWIDTH" 9 byte 9; + init zero; + port srsw "A" { + clock anyedge "C"; + clken; + rdwr no_change; + rdinit zero; + portoption "RST_MODE" "SYNC" { + rdsrst zero ungated; + } + portoption "RST_MODE" "ASYNC" { + rdarst zero; + } + wrtrans all new; + wrbe_separate; + } + port srsw "B" { + clock anyedge "C"; + clken; + rdwr no_change; + rdinit zero; + portoption "RST_MODE" "SYNC" { + rdsrst zero ungated; + } + portoption "RST_MODE" "ASYNC" { + rdarst zero; + } + wrtrans all old; + wrprio "A"; + wrbe_separate; + } +} diff --git a/techlibs/xilinx/urams_map.v b/techlibs/xilinx/urams_map.v new file mode 100644 index 000000000..3ecbe704e --- /dev/null +++ b/techlibs/xilinx/urams_map.v @@ -0,0 +1,152 @@ +module $__XILINX_URAM_ (...); + parameter OPTION_BYTEWIDTH = 8; + localparam WR_BE_WIDTH = 72 / OPTION_BYTEWIDTH; + + parameter CLK_C_POL = 1; + parameter PORT_A_CLK_POL = 1; + parameter PORT_A_OPTION_RST_MODE = "SYNC"; + parameter PORT_B_CLK_POL = 1; + parameter PORT_B_OPTION_RST_MODE = "SYNC"; + + input CLK_C; + + input PORT_A_CLK; + input PORT_A_CLK_EN; + input PORT_A_RD_SRST; + input PORT_A_RD_ARST; + input PORT_A_WR_EN; + input [WR_BE_WIDTH-1:0] PORT_A_WR_BE; + input [11:0] PORT_A_ADDR; + input [71:0] PORT_A_WR_DATA; + output [71:0] PORT_A_RD_DATA; + + input PORT_B_CLK; + input PORT_B_CLK_EN; + input PORT_B_RD_SRST; + input PORT_B_RD_ARST; + input PORT_B_WR_EN; + input [WR_BE_WIDTH-1:0] PORT_B_WR_BE; + input [11:0] PORT_B_ADDR; + input [71:0] PORT_B_WR_DATA; + output [71:0] PORT_B_RD_DATA; + + wire [71:0] DIN_A, DIN_B, DOUT_A, DOUT_B; + + generate + if (OPTION_BYTEWIDTH == 8) begin + assign DIN_A = PORT_A_WR_DATA; + assign DIN_B = PORT_B_WR_DATA; + assign PORT_A_RD_DATA = DOUT_A; + assign PORT_B_RD_DATA = DOUT_B; + end else begin + assign DIN_A = { + PORT_A_WR_DATA[71], + PORT_A_WR_DATA[62], + PORT_A_WR_DATA[53], + PORT_A_WR_DATA[44], + PORT_A_WR_DATA[35], + PORT_A_WR_DATA[26], + PORT_A_WR_DATA[17], + PORT_A_WR_DATA[8], + PORT_A_WR_DATA[70:63], + PORT_A_WR_DATA[61:54], + PORT_A_WR_DATA[52:45], + PORT_A_WR_DATA[43:36], + PORT_A_WR_DATA[34:27], + PORT_A_WR_DATA[25:18], + PORT_A_WR_DATA[16:9], + PORT_A_WR_DATA[7:0] + }; + assign DIN_B = { + PORT_B_WR_DATA[71], + PORT_B_WR_DATA[62], + PORT_B_WR_DATA[53], + PORT_B_WR_DATA[44], + PORT_B_WR_DATA[35], + PORT_B_WR_DATA[26], + PORT_B_WR_DATA[17], + PORT_B_WR_DATA[8], + PORT_B_WR_DATA[70:63], + PORT_B_WR_DATA[61:54], + PORT_B_WR_DATA[52:45], + PORT_B_WR_DATA[43:36], + PORT_B_WR_DATA[34:27], + PORT_B_WR_DATA[25:18], + PORT_B_WR_DATA[16:9], + PORT_B_WR_DATA[7:0] + }; + assign PORT_A_RD_DATA = { + DOUT_A[71], + DOUT_A[63:56], + DOUT_A[70], + DOUT_A[55:48], + DOUT_A[69], + DOUT_A[47:40], + DOUT_A[68], + DOUT_A[39:32], + DOUT_A[67], + DOUT_A[31:24], + DOUT_A[66], + DOUT_A[23:16], + DOUT_A[65], + DOUT_A[15:8], + DOUT_A[64], + DOUT_A[7:0] + }; + assign PORT_B_RD_DATA = { + DOUT_B[71], + DOUT_B[63:56], + DOUT_B[70], + DOUT_B[55:48], + DOUT_B[69], + DOUT_B[47:40], + DOUT_B[68], + DOUT_B[39:32], + DOUT_B[67], + DOUT_B[31:24], + DOUT_B[66], + DOUT_B[23:16], + DOUT_B[65], + DOUT_B[15:8], + DOUT_B[64], + DOUT_B[7:0] + }; + end + endgenerate + + URAM288 #( + .BWE_MODE_A(OPTION_BYTEWIDTH == 8 ? "PARITY_INDEPENDENT" : "PARITY_INTERLEAVED"), + .BWE_MODE_B(OPTION_BYTEWIDTH == 8 ? "PARITY_INDEPENDENT" : "PARITY_INTERLEAVED"), + .EN_AUTO_SLEEP_MODE("FALSE"), + .IREG_PRE_A("FALSE"), + .IREG_PRE_B("FALSE"), + .IS_CLK_INVERTED(!CLK_C_POL), + .OREG_A("FALSE"), + .OREG_B("FALSE"), + .RST_MODE_A(PORT_A_OPTION_RST_MODE), + .RST_MODE_B(PORT_B_OPTION_RST_MODE), + ) _TECHMAP_REPLACE_ ( + .ADDR_A({11'b0, PORT_A_ADDR}), + .BWE_A(PORT_A_WR_BE), + .EN_A(PORT_A_CLK_EN), + .RDB_WR_A(PORT_A_WR_EN), + .INJECT_DBITERR_A(1'b0), + .INJECT_SBITERR_A(1'b0), + .RST_A(PORT_A_OPTION_RST_MODE == "SYNC" ? PORT_A_RD_SRST : PORT_A_RD_ARST), + .DIN_A(DIN_A), + .DOUT_A(DOUT_A), + + .ADDR_B({11'b0, PORT_B_ADDR}), + .BWE_B(PORT_B_WR_BE), + .EN_B(PORT_B_CLK_EN), + .RDB_WR_B(PORT_B_WR_EN), + .INJECT_DBITERR_B(1'b0), + .INJECT_SBITERR_B(1'b0), + .RST_B(PORT_B_OPTION_RST_MODE == "SYNC" ? PORT_B_RD_SRST : PORT_B_RD_ARST), + .DIN_B(DIN_B), + .DOUT_B(DOUT_B), + + .CLK(CLK_C), + .SLEEP(1'b0) + ); +endmodule diff --git a/techlibs/xilinx/xc2v_brams.txt b/techlibs/xilinx/xc2v_brams.txt deleted file mode 100644 index ac8cfb552..000000000 --- a/techlibs/xilinx/xc2v_brams.txt +++ /dev/null @@ -1,31 +0,0 @@ -# Virtex 2, Virtex 2 Pro, Spartan 3, Spartan 3E block RAM rules. - -bram $__XILINX_RAMB16 - init 1 - abits 9 @a9d36 - dbits 36 @a9d36 - abits 10 @a10d18 - dbits 18 @a10d18 - abits 11 @a11d9 - dbits 9 @a11d9 - abits 12 @a12d4 - dbits 4 @a12d4 - abits 13 @a13d2 - dbits 2 @a13d2 - abits 14 @a14d1 - dbits 1 @a14d1 - groups 2 - ports 1 1 - wrmode 0 1 - enable 1 1 - transp 0 0 - clocks 2 3 - clkpol 2 3 -endbram - -match $__XILINX_RAMB16 - min bits 4096 - min efficiency 5 - shuffle_enable B - make_transp -endmatch diff --git a/techlibs/xilinx/xc2v_brams_map.v b/techlibs/xilinx/xc2v_brams_map.v deleted file mode 100644 index dc698f956..000000000 --- a/techlibs/xilinx/xc2v_brams_map.v +++ /dev/null @@ -1,266 +0,0 @@ -// Virtex 2, Virtex 2 Pro, Spartan 3, Spartan 3E, Spartan 3A block RAM -// mapping (Spartan 3A is a superset of the other four). - -// ------------------------------------------------------------------------ - -module \$__XILINX_RAMB16 (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN); - parameter CFG_ABITS = 9; - parameter CFG_DBITS = 36; - parameter CFG_ENABLE_B = 1; - - parameter CLKPOL2 = 1; - parameter CLKPOL3 = 1; - parameter [18431:0] INIT = 18432'bx; - - 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; - - generate if (CFG_DBITS == 1) begin - wire DOB; - RAMB16_S1_S1 #( - `include "brams_init_16.vh" - .WRITE_MODE_A("READ_FIRST"), - .WRITE_MODE_B("READ_FIRST"), - ) _TECHMAP_REPLACE_ ( - .DIA(1'd0), - .DOA(A1DATA), - .ADDRA(A1ADDR), - .CLKA(CLK2 ^ !CLKPOL2), - .ENA(A1EN), - .SSRA(|0), - .WEA(1'b0), - - .DIB(B1DATA), - .DOB(DOB), - .ADDRB(B1ADDR), - .CLKB(CLK3 ^ !CLKPOL3), - .ENB(|1), - .SSRB(|0), - .WEB(B1EN) - ); - end else if (CFG_DBITS == 2) begin - wire [1:0] DOB; - RAMB16_S2_S2 #( - `include "brams_init_16.vh" - .WRITE_MODE_A("READ_FIRST"), - .WRITE_MODE_B("READ_FIRST"), - ) _TECHMAP_REPLACE_ ( - .DIA(2'd0), - .DOA(A1DATA), - .ADDRA(A1ADDR), - .CLKA(CLK2 ^ !CLKPOL2), - .ENA(A1EN), - .SSRA(|0), - .WEA(1'b0), - - .DIB(B1DATA), - .DOB(DOB), - .ADDRB(B1ADDR), - .CLKB(CLK3 ^ !CLKPOL3), - .ENB(|1), - .SSRB(|0), - .WEB(B1EN) - ); - end else if (CFG_DBITS == 4) begin - wire [3:0] DOB; - RAMB16_S4_S4 #( - `include "brams_init_16.vh" - .WRITE_MODE_A("READ_FIRST"), - .WRITE_MODE_B("READ_FIRST"), - ) _TECHMAP_REPLACE_ ( - .DIA(4'd0), - .DOA(A1DATA), - .ADDRA(A1ADDR), - .CLKA(CLK2 ^ !CLKPOL2), - .ENA(A1EN), - .SSRA(|0), - .WEA(1'b0), - - .DIB(B1DATA), - .DOB(DOB), - .ADDRB(B1ADDR), - .CLKB(CLK3 ^ !CLKPOL3), - .ENB(|1), - .SSRB(|0), - .WEB(B1EN) - ); - end else if (CFG_DBITS == 9) begin - wire [7:0] DOB; - wire DOPB; - RAMB16_S9_S9 #( - `include "brams_init_18.vh" - .WRITE_MODE_A("READ_FIRST"), - .WRITE_MODE_B("READ_FIRST"), - ) _TECHMAP_REPLACE_ ( - .DIA(8'd0), - .DIPA(1'd0), - .DOA(A1DATA[7:0]), - .DOPA(A1DATA[8]), - .ADDRA(A1ADDR), - .CLKA(CLK2 ^ !CLKPOL2), - .ENA(A1EN), - .SSRA(|0), - .WEA(1'b0), - - .DIB(B1DATA[7:0]), - .DIPB(B1DATA[8]), - .DOB(DOB), - .DOPB(DOPB), - .ADDRB(B1ADDR), - .CLKB(CLK3 ^ !CLKPOL3), - .ENB(|1), - .SSRB(|0), - .WEB(B1EN) - ); - end else if (CFG_DBITS == 18) begin - wire [15:0] DOB; - wire [1:0] DOPB; - RAMB16_S18_S18 #( - `include "brams_init_18.vh" - .WRITE_MODE_A("READ_FIRST"), - .WRITE_MODE_B("READ_FIRST"), - ) _TECHMAP_REPLACE_ ( - .DIA(16'd0), - .DIPA(2'd0), - .DOA({A1DATA[16:9], A1DATA[7:0]}), - .DOPA({A1DATA[17], A1DATA[8]}), - .ADDRA(A1ADDR), - .CLKA(CLK2 ^ !CLKPOL2), - .ENA(A1EN), - .SSRA(|0), - .WEA(1'b0), - - .DIB({B1DATA[16:9], B1DATA[7:0]}), - .DIPB({B1DATA[17], B1DATA[8]}), - .DOB(DOB), - .DOPB(DOPB), - .ADDRB(B1ADDR), - .CLKB(CLK3 ^ !CLKPOL3), - .ENB(|1), - .SSRB(|0), - .WEB(B1EN) - ); - end else if (CFG_DBITS == 36) begin - wire [31:0] DOB; - wire [3:0] DOPB; - RAMB16_S36_S36 #( - `include "brams_init_18.vh" - .WRITE_MODE_A("READ_FIRST"), - .WRITE_MODE_B("READ_FIRST"), - ) _TECHMAP_REPLACE_ ( - .DIA(32'd0), - .DIPA(4'd0), - .DOA({A1DATA[34:27], A1DATA[25:18], A1DATA[16:9], A1DATA[7:0]}), - .DOPA({A1DATA[35], A1DATA[26], A1DATA[17], A1DATA[8]}), - .ADDRA(A1ADDR), - .CLKA(CLK2 ^ !CLKPOL2), - .ENA(A1EN), - .SSRA(|0), - .WEA(1'b0), - - .DIB({B1DATA[34:27], B1DATA[25:18], B1DATA[16:9], B1DATA[7:0]}), - .DIPB({B1DATA[35], B1DATA[26], B1DATA[17], B1DATA[8]}), - .DOB(DOB), - .DOPB(DOPB), - .ADDRB(B1ADDR), - .CLKB(CLK3 ^ !CLKPOL3), - .ENB(|1), - .SSRB(|0), - .WEB(B1EN) - ); - end else begin - $error("Strange block RAM data width."); - end endgenerate -endmodule - - -// Version with separate byte enables, only available on Spartan 3A. - -module \$__XILINX_RAMB16BWE (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN); - parameter CFG_ABITS = 9; - parameter CFG_DBITS = 36; - parameter CFG_ENABLE_B = 4; - - parameter CLKPOL2 = 1; - parameter CLKPOL3 = 1; - parameter [18431:0] INIT = 18432'bx; - - 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; - - generate if (CFG_DBITS == 18) begin - wire [15:0] DOB; - wire [1:0] DOPB; - RAMB16BWE_S18_S18 #( - `include "brams_init_18.vh" - .WRITE_MODE_A("READ_FIRST"), - .WRITE_MODE_B("READ_FIRST"), - ) _TECHMAP_REPLACE_ ( - .DIA(16'd0), - .DIPA(2'd0), - .DOA({A1DATA[16:9], A1DATA[7:0]}), - .DOPA({A1DATA[17], A1DATA[8]}), - .ADDRA(A1ADDR), - .CLKA(CLK2 ^ !CLKPOL2), - .ENA(A1EN), - .SSRA(|0), - .WEA(2'b00), - - .DIB({B1DATA[16:9], B1DATA[7:0]}), - .DIPB({B1DATA[17], B1DATA[8]}), - .DOB(DOB), - .DOPB(DOPB), - .ADDRB(B1ADDR), - .CLKB(CLK3 ^ !CLKPOL3), - .ENB(|1), - .SSRB(|0), - .WEB(B1EN) - ); - end else if (CFG_DBITS == 36) begin - wire [31:0] DOB; - wire [3:0] DOPB; - RAMB16BWE_S36_S36 #( - `include "brams_init_18.vh" - .WRITE_MODE_A("READ_FIRST"), - .WRITE_MODE_B("READ_FIRST"), - ) _TECHMAP_REPLACE_ ( - .DIA(32'd0), - .DIPA(4'd0), - .DOA({A1DATA[34:27], A1DATA[25:18], A1DATA[16:9], A1DATA[7:0]}), - .DOPA({A1DATA[35], A1DATA[26], A1DATA[17], A1DATA[8]}), - .ADDRA(A1ADDR), - .CLKA(CLK2 ^ !CLKPOL2), - .ENA(A1EN), - .SSRA(|0), - .WEA(4'b0000), - - .DIB({B1DATA[34:27], B1DATA[25:18], B1DATA[16:9], B1DATA[7:0]}), - .DIPB({B1DATA[35], B1DATA[26], B1DATA[17], B1DATA[8]}), - .DOB(DOB), - .DOPB(DOPB), - .ADDRB(B1ADDR), - .CLKB(CLK3 ^ !CLKPOL3), - .ENB(|1), - .SSRB(|0), - .WEB(B1EN) - ); - end else begin - $error("Strange block RAM data width."); - end endgenerate -endmodule diff --git a/techlibs/xilinx/xc3sa_brams.txt b/techlibs/xilinx/xc3sa_brams.txt deleted file mode 100644 index 22a62bd2c..000000000 --- a/techlibs/xilinx/xc3sa_brams.txt +++ /dev/null @@ -1,51 +0,0 @@ -# Spartan 3A block RAM rules. - -bram $__XILINX_RAMB16 - init 1 - abits 11 @a11d9 - dbits 9 @a11d9 - abits 12 @a12d4 - dbits 4 @a12d4 - abits 13 @a13d2 - dbits 2 @a13d2 - abits 14 @a14d1 - dbits 1 @a14d1 - groups 2 - ports 1 1 - wrmode 0 1 - enable 1 1 - transp 0 0 - clocks 2 3 - clkpol 2 3 -endbram - -bram $__XILINX_RAMB16BWE - init 1 - abits 9 @a9d36 - dbits 36 @a9d36 - abits 10 @a10d18 - dbits 18 @a10d18 - groups 2 - ports 1 1 - wrmode 0 1 - enable 1 4 @a9d36 - enable 1 2 @a10d18 - transp 0 0 - clocks 2 3 - clkpol 2 3 -endbram - -match $__XILINX_RAMB16 - min bits 4096 - min efficiency 5 - shuffle_enable B - make_transp - or_next_if_better -endmatch - -match $__XILINX_RAMB16BWE - min bits 4096 - min efficiency 5 - shuffle_enable B - make_transp -endmatch diff --git a/techlibs/xilinx/xc3sda_brams.txt b/techlibs/xilinx/xc3sda_brams.txt deleted file mode 100644 index 12c68ffd5..000000000 --- a/techlibs/xilinx/xc3sda_brams.txt +++ /dev/null @@ -1,33 +0,0 @@ -# Spartan 3A DSP block RAM rules. - -bram $__XILINX_RAMB16BWER_TDP - init 1 - abits 9 @a9d36 - dbits 36 @a9d36 - abits 10 @a10d18 - dbits 18 @a10d18 - abits 11 @a11d9 - dbits 9 @a11d9 - abits 12 @a12d4 - dbits 4 @a12d4 - abits 13 @a13d2 - dbits 2 @a13d2 - abits 14 @a14d1 - dbits 1 @a14d1 - groups 2 - ports 1 1 - wrmode 0 1 - enable 1 4 @a9d36 - enable 1 2 @a10d18 - enable 1 1 @a11d9 @a12d4 @a13d2 @a14d1 - transp 0 0 - clocks 2 3 - clkpol 2 3 -endbram - -match $__XILINX_RAMB16BWER_TDP - min bits 4096 - min efficiency 5 - shuffle_enable B - make_transp -endmatch diff --git a/techlibs/xilinx/xc6s_brams.txt b/techlibs/xilinx/xc6s_brams.txt deleted file mode 100644 index 6457097db..000000000 --- a/techlibs/xilinx/xc6s_brams.txt +++ /dev/null @@ -1,85 +0,0 @@ -# Spartan 6 block RAM rules. - -bram $__XILINX_RAMB8BWER_SDP - init 1 - abits 8 - dbits 36 - groups 2 - ports 1 1 - wrmode 0 1 - enable 1 4 - transp 0 0 - clocks 2 3 - clkpol 2 3 -endbram - -bram $__XILINX_RAMB16BWER_TDP - init 1 - abits 9 @a9d36 - dbits 36 @a9d36 - abits 10 @a10d18 - dbits 18 @a10d18 - abits 11 @a11d9 - dbits 9 @a11d9 - abits 12 @a12d4 - dbits 4 @a12d4 - abits 13 @a13d2 - dbits 2 @a13d2 - abits 14 @a14d1 - dbits 1 @a14d1 - groups 2 - ports 1 1 - wrmode 0 1 - enable 1 4 @a9d36 - enable 1 2 @a10d18 - enable 1 1 @a11d9 @a12d4 @a13d2 @a14d1 - transp 0 0 - clocks 2 3 - clkpol 2 3 -endbram - -bram $__XILINX_RAMB8BWER_TDP - init 1 - abits 9 @a9d18 - dbits 18 @a9d18 - abits 10 @a10d9 - dbits 9 @a10d9 - abits 11 @a11d4 - dbits 4 @a11d4 - abits 12 @a12d2 - dbits 2 @a12d2 - abits 13 @a13d1 - dbits 1 @a13d1 - groups 2 - ports 1 1 - wrmode 0 1 - enable 1 2 @a9d18 - enable 1 1 @a10d9 @a11d4 @a12d2 @a13d1 - transp 0 0 - clocks 2 3 - clkpol 2 3 -endbram - -match $__XILINX_RAMB8BWER_SDP - min bits 4096 - min efficiency 5 - shuffle_enable B - make_transp - or_next_if_better -endmatch - -match $__XILINX_RAMB16BWER_TDP - min bits 4096 - min efficiency 5 - shuffle_enable B - make_transp - or_next_if_better -endmatch - -match $__XILINX_RAMB8BWER_TDP - min bits 4096 - min efficiency 5 - shuffle_enable B - make_transp -endmatch - diff --git a/techlibs/xilinx/xc6s_brams_map.v b/techlibs/xilinx/xc6s_brams_map.v deleted file mode 100644 index 9577eebe4..000000000 --- a/techlibs/xilinx/xc6s_brams_map.v +++ /dev/null @@ -1,258 +0,0 @@ -// Spartan 3A DSP and Spartan 6 block RAM mapping (Spartan 6 is a superset of -// Spartan 3A DSP). - -module \$__XILINX_RAMB8BWER_SDP (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN); - parameter CLKPOL2 = 1; - parameter CLKPOL3 = 1; - parameter [9215:0] INIT = 9216'bx; - - input CLK2; - input CLK3; - - input [7:0] A1ADDR; - output [35:0] A1DATA; - input A1EN; - - input [7:0] B1ADDR; - input [35:0] B1DATA; - input [3:0] B1EN; - - wire [12:0] A1ADDR_13 = {A1ADDR, 5'b0}; - wire [12:0] B1ADDR_13 = {B1ADDR, 5'b0}; - - wire [3:0] DIP, DOP; - wire [31:0] DI, DO; - - assign A1DATA = { DOP[3], DO[31:24], DOP[2], DO[23:16], DOP[1], DO[15: 8], DOP[0], DO[ 7: 0] }; - assign { DIP[3], DI[31:24], DIP[2], DI[23:16], DIP[1], DI[15: 8], DIP[0], DI[ 7: 0] } = B1DATA; - - RAMB8BWER #( - .RAM_MODE("SDP"), - .DATA_WIDTH_A(36), - .DATA_WIDTH_B(36), - .WRITE_MODE_A("READ_FIRST"), - .WRITE_MODE_B("READ_FIRST"), - `include "brams_init_9.vh" - ) _TECHMAP_REPLACE_ ( - .DOBDO(DO[31:16]), - .DOADO(DO[15:0]), - .DOPBDOP(DOP[3:2]), - .DOPADOP(DOP[1:0]), - .DIBDI(DI[31:16]), - .DIADI(DI[15:0]), - .DIPBDIP(DIP[3:2]), - .DIPADIP(DIP[1:0]), - .WEBWEU(B1EN[3:2]), - .WEAWEL(B1EN[1:0]), - - .ADDRAWRADDR(B1ADDR_13), - .CLKAWRCLK(CLK3 ^ !CLKPOL3), - .ENAWREN(|1), - .REGCEA(|0), - .RSTA(|0), - - .ADDRBRDADDR(A1ADDR_13), - .CLKBRDCLK(CLK2 ^ !CLKPOL2), - .ENBRDEN(A1EN), - .REGCEBREGCE(|1), - .RSTBRST(|0) - ); -endmodule - -// ------------------------------------------------------------------------ - -module \$__XILINX_RAMB16BWER_TDP (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN); - parameter CFG_ABITS = 9; - parameter CFG_DBITS = 36; - parameter CFG_ENABLE_B = 4; - - parameter CLKPOL2 = 1; - parameter CLKPOL3 = 1; - parameter [18431:0] INIT = 18432'bx; - - 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 [13:0] A1ADDR_14 = A1ADDR << (14 - CFG_ABITS); - wire [13:0] B1ADDR_14 = B1ADDR << (14 - CFG_ABITS); - wire [3:0] B1EN_4 = {4{B1EN}}; - - wire [3:0] DIP, DOP; - wire [31:0] DI, DO; - - wire [31:0] DOB; - wire [3:0] DOPB; - - assign A1DATA = { DOP[3], DO[31:24], DOP[2], DO[23:16], DOP[1], DO[15: 8], DOP[0], DO[ 7: 0] }; - assign { DIP[3], DI[31:24], DIP[2], DI[23:16], DIP[1], DI[15: 8], DIP[0], DI[ 7: 0] } = B1DATA; - - generate if (CFG_DBITS > 8) begin - RAMB16BWER #( - .DATA_WIDTH_A(CFG_DBITS), - .DATA_WIDTH_B(CFG_DBITS), - .WRITE_MODE_A("READ_FIRST"), - .WRITE_MODE_B("READ_FIRST"), - `include "brams_init_18.vh" - ) _TECHMAP_REPLACE_ ( - .DIA(32'd0), - .DIPA(4'd0), - .DOA(DO[31:0]), - .DOPA(DOP[3:0]), - .ADDRA(A1ADDR_14), - .CLKA(CLK2 ^ !CLKPOL2), - .ENA(A1EN), - .REGCEA(|1), - .RSTA(|0), - .WEA(4'b0), - - .DIB(DI), - .DIPB(DIP), - .DOB(DOB), - .DOPB(DOPB), - .ADDRB(B1ADDR_14), - .CLKB(CLK3 ^ !CLKPOL3), - .ENB(|1), - .REGCEB(|0), - .RSTB(|0), - .WEB(B1EN_4) - ); - end else begin - RAMB16BWER #( - .DATA_WIDTH_A(CFG_DBITS), - .DATA_WIDTH_B(CFG_DBITS), - .WRITE_MODE_A("READ_FIRST"), - .WRITE_MODE_B("READ_FIRST"), - `include "brams_init_16.vh" - ) _TECHMAP_REPLACE_ ( - .DIA(32'd0), - .DIPA(4'd0), - .DOA(DO[31:0]), - .DOPA(DOP[3:0]), - .ADDRA(A1ADDR_14), - .CLKA(CLK2 ^ !CLKPOL2), - .ENA(A1EN), - .REGCEA(|1), - .RSTA(|0), - .WEA(4'b0), - - .DIB(DI), - .DIPB(DIP), - .DOB(DOB), - .DOPB(DOPB), - .ADDRB(B1ADDR_14), - .CLKB(CLK3 ^ !CLKPOL3), - .ENB(|1), - .REGCEB(|0), - .RSTB(|0), - .WEB(B1EN_4) - ); - end endgenerate -endmodule - -// ------------------------------------------------------------------------ - -module \$__XILINX_RAMB8BWER_TDP (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN); - parameter CFG_ABITS = 9; - parameter CFG_DBITS = 18; - parameter CFG_ENABLE_B = 2; - - parameter CLKPOL2 = 1; - parameter CLKPOL3 = 1; - parameter [9215:0] INIT = 9216'bx; - - 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 [12:0] A1ADDR_13 = A1ADDR << (13 - CFG_ABITS); - wire [12:0] B1ADDR_13 = B1ADDR << (13 - CFG_ABITS); - wire [1:0] B1EN_2 = {2{B1EN}}; - - wire [1:0] DIP, DOP; - wire [15:0] DI, DO; - - wire [15:0] DOBDO; - wire [1:0] DOPBDOP; - - assign A1DATA = { DOP[1], DO[15: 8], DOP[0], DO[ 7: 0] }; - assign { DIP[1], DI[15: 8], DIP[0], DI[ 7: 0] } = B1DATA; - - generate if (CFG_DBITS > 8) begin - RAMB8BWER #( - .RAM_MODE("TDP"), - .DATA_WIDTH_A(CFG_DBITS), - .DATA_WIDTH_B(CFG_DBITS), - .WRITE_MODE_A("READ_FIRST"), - .WRITE_MODE_B("READ_FIRST"), - `include "brams_init_9.vh" - ) _TECHMAP_REPLACE_ ( - .DIADI(16'b0), - .DIPADIP(2'b0), - .DOADO(DO), - .DOPADOP(DOP), - .ADDRAWRADDR(A1ADDR_13), - .CLKAWRCLK(CLK2 ^ !CLKPOL2), - .ENAWREN(A1EN), - .REGCEA(|1), - .RSTA(|0), - .WEAWEL(2'b0), - - .DIBDI(DI), - .DIPBDIP(DIP), - .DOBDO(DOBDO), - .DOPBDOP(DOPBDOP), - .ADDRBRDADDR(B1ADDR_13), - .CLKBRDCLK(CLK3 ^ !CLKPOL3), - .ENBRDEN(|1), - .REGCEBREGCE(|0), - .RSTBRST(|0), - .WEBWEU(B1EN_2) - ); - end else begin - RAMB8BWER #( - .RAM_MODE("TDP"), - .DATA_WIDTH_A(CFG_DBITS), - .DATA_WIDTH_B(CFG_DBITS), - .WRITE_MODE_A("READ_FIRST"), - .WRITE_MODE_B("READ_FIRST"), - `include "brams_init_8.vh" - ) _TECHMAP_REPLACE_ ( - .DIADI(16'b0), - .DIPADIP(2'b0), - .DOADO(DO), - .DOPADOP(DOP), - .ADDRAWRADDR(A1ADDR_13), - .CLKAWRCLK(CLK2 ^ !CLKPOL2), - .ENAWREN(A1EN), - .REGCEA(|1), - .RSTA(|0), - .WEAWEL(2'b0), - - .DIBDI(DI), - .DIPBDIP(DIP), - .DOBDO(DOBDO), - .DOPBDOP(DOPBDOP), - .ADDRBRDADDR(B1ADDR_13), - .CLKBRDCLK(CLK3 ^ !CLKPOL3), - .ENBRDEN(|1), - .REGCEBREGCE(|0), - .RSTBRST(|0), - .WEBWEU(B1EN_2) - ); - end endgenerate -endmodule diff --git a/techlibs/xilinx/xc7_brams_map.v b/techlibs/xilinx/xc7_brams_map.v deleted file mode 100644 index 982a5a07e..000000000 --- a/techlibs/xilinx/xc7_brams_map.v +++ /dev/null @@ -1,363 +0,0 @@ -// Virtex 6 and Series 7 block RAM mapping. - -module \$__XILINX_RAMB36_SDP (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN); - parameter CLKPOL2 = 1; - parameter CLKPOL3 = 1; - parameter [36863:0] INIT = 36864'bx; - - input CLK2; - input CLK3; - - input [8:0] A1ADDR; - output [71:0] A1DATA; - input A1EN; - - input [8:0] B1ADDR; - input [71:0] B1DATA; - input [7:0] B1EN; - - // Set highest address bit to 1, as stated in UG473 (v1.14) July 3, 2019 - wire [15:0] A1ADDR_16 = {1'b1, A1ADDR, 6'b0}; - wire [15:0] B1ADDR_16 = {1'b1, B1ADDR, 6'b0}; - - wire [7:0] DIP, DOP; - wire [63:0] DI, DO; - - assign A1DATA = { DOP[7], DO[63:56], DOP[6], DO[55:48], DOP[5], DO[47:40], DOP[4], DO[39:32], - DOP[3], DO[31:24], DOP[2], DO[23:16], DOP[1], DO[15: 8], DOP[0], DO[ 7: 0] }; - - assign { DIP[7], DI[63:56], DIP[6], DI[55:48], DIP[5], DI[47:40], DIP[4], DI[39:32], - DIP[3], DI[31:24], DIP[2], DI[23:16], DIP[1], DI[15: 8], DIP[0], DI[ 7: 0] } = B1DATA; - - RAMB36E1 #( - .RAM_MODE("SDP"), - .READ_WIDTH_A(72), - .WRITE_WIDTH_B(72), - .WRITE_MODE_A("READ_FIRST"), - .WRITE_MODE_B("READ_FIRST"), - .IS_CLKARDCLK_INVERTED(!CLKPOL2), - .IS_CLKBWRCLK_INVERTED(!CLKPOL3), - `include "brams_init_36.vh" - .SIM_DEVICE("7SERIES") - ) _TECHMAP_REPLACE_ ( - .DOBDO(DO[63:32]), - .DOADO(DO[31:0]), - .DOPBDOP(DOP[7:4]), - .DOPADOP(DOP[3:0]), - .DIBDI(DI[63:32]), - .DIADI(DI[31:0]), - .DIPBDIP(DIP[7:4]), - .DIPADIP(DIP[3:0]), - - .ADDRARDADDR(A1ADDR_16), - .CLKARDCLK(CLK2), - .ENARDEN(A1EN), - .REGCEAREGCE(|1), - .RSTRAMARSTRAM(|0), - .RSTREGARSTREG(|0), - .WEA(4'b0), - - .ADDRBWRADDR(B1ADDR_16), - .CLKBWRCLK(CLK3), - .ENBWREN(|1), - .REGCEB(|0), - .RSTRAMB(|0), - .RSTREGB(|0), - .WEBWE(B1EN) - ); -endmodule - -// ------------------------------------------------------------------------ - -module \$__XILINX_RAMB18_SDP (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN); - parameter CLKPOL2 = 1; - parameter CLKPOL3 = 1; - parameter [18431:0] INIT = 18432'bx; - - input CLK2; - input CLK3; - - input [8:0] A1ADDR; - output [35:0] A1DATA; - input A1EN; - - input [8:0] B1ADDR; - input [35:0] B1DATA; - input [3:0] B1EN; - - wire [13:0] A1ADDR_14 = {A1ADDR, 5'b0}; - wire [13:0] B1ADDR_14 = {B1ADDR, 5'b0}; - - wire [3:0] DIP, DOP; - wire [31:0] DI, DO; - - assign A1DATA = { DOP[3], DO[31:24], DOP[2], DO[23:16], DOP[1], DO[15: 8], DOP[0], DO[ 7: 0] }; - assign { DIP[3], DI[31:24], DIP[2], DI[23:16], DIP[1], DI[15: 8], DIP[0], DI[ 7: 0] } = B1DATA; - - RAMB18E1 #( - .RAM_MODE("SDP"), - .READ_WIDTH_A(36), - .WRITE_WIDTH_B(36), - .WRITE_MODE_A("READ_FIRST"), - .WRITE_MODE_B("READ_FIRST"), - .IS_CLKARDCLK_INVERTED(!CLKPOL2), - .IS_CLKBWRCLK_INVERTED(!CLKPOL3), - `include "brams_init_18.vh" - .SIM_DEVICE("7SERIES") - ) _TECHMAP_REPLACE_ ( - .DOBDO(DO[31:16]), - .DOADO(DO[15:0]), - .DOPBDOP(DOP[3:2]), - .DOPADOP(DOP[1:0]), - .DIBDI(DI[31:16]), - .DIADI(DI[15:0]), - .DIPBDIP(DIP[3:2]), - .DIPADIP(DIP[1:0]), - - .ADDRARDADDR(A1ADDR_14), - .CLKARDCLK(CLK2), - .ENARDEN(A1EN), - .REGCEAREGCE(|1), - .RSTRAMARSTRAM(|0), - .RSTREGARSTREG(|0), - .WEA(2'b0), - - .ADDRBWRADDR(B1ADDR_14), - .CLKBWRCLK(CLK3), - .ENBWREN(|1), - .REGCEB(|0), - .RSTRAMB(|0), - .RSTREGB(|0), - .WEBWE(B1EN) - ); -endmodule - -// ------------------------------------------------------------------------ - -module \$__XILINX_RAMB36_TDP (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; - - 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; - - // Set highest address bit to 1, as stated in UG473 (v1.14) July 3, 2019 - wire [15:0] A1ADDR_16 = {1'b1, A1ADDR} << (15 - CFG_ABITS); - wire [15:0] B1ADDR_16 = {1'b1, B1ADDR} << (15 - CFG_ABITS); - wire [7:0] B1EN_8 = B1EN; - - wire [3:0] DIP, DOP; - wire [31:0] DI, DO; - - wire [31:0] DOBDO; - wire [3:0] DOPBDOP; - - assign A1DATA = { DOP[3], DO[31:24], DOP[2], DO[23:16], DOP[1], DO[15: 8], DOP[0], DO[ 7: 0] }; - assign { DIP[3], DI[31:24], DIP[2], DI[23:16], DIP[1], DI[15: 8], DIP[0], DI[ 7: 0] } = B1DATA; - - generate if (CFG_DBITS > 8) begin - RAMB36E1 #( - .RAM_MODE("TDP"), - .READ_WIDTH_A(CFG_DBITS), - .READ_WIDTH_B(CFG_DBITS), - .WRITE_WIDTH_A(CFG_DBITS), - .WRITE_WIDTH_B(CFG_DBITS), - .WRITE_MODE_A("READ_FIRST"), - .WRITE_MODE_B("READ_FIRST"), - .IS_CLKARDCLK_INVERTED(!CLKPOL2), - .IS_CLKBWRCLK_INVERTED(!CLKPOL3), - `include "brams_init_36.vh" - .SIM_DEVICE("7SERIES") - ) _TECHMAP_REPLACE_ ( - .DIADI(32'd0), - .DIPADIP(4'd0), - .DOADO(DO[31:0]), - .DOPADOP(DOP[3:0]), - .ADDRARDADDR(A1ADDR_16), - .CLKARDCLK(CLK2), - .ENARDEN(A1EN), - .REGCEAREGCE(|1), - .RSTRAMARSTRAM(|0), - .RSTREGARSTREG(|0), - .WEA(4'b0), - - .DIBDI(DI), - .DIPBDIP(DIP), - .DOBDO(DOBDO), - .DOPBDOP(DOPBDOP), - .ADDRBWRADDR(B1ADDR_16), - .CLKBWRCLK(CLK3), - .ENBWREN(|1), - .REGCEB(|0), - .RSTRAMB(|0), - .RSTREGB(|0), - .WEBWE(B1EN_8) - ); - end else begin - RAMB36E1 #( - .RAM_MODE("TDP"), - .READ_WIDTH_A(CFG_DBITS), - .READ_WIDTH_B(CFG_DBITS), - .WRITE_WIDTH_A(CFG_DBITS), - .WRITE_WIDTH_B(CFG_DBITS), - .WRITE_MODE_A("READ_FIRST"), - .WRITE_MODE_B("READ_FIRST"), - .IS_CLKARDCLK_INVERTED(!CLKPOL2), - .IS_CLKBWRCLK_INVERTED(!CLKPOL3), - `include "brams_init_32.vh" - .SIM_DEVICE("7SERIES") - ) _TECHMAP_REPLACE_ ( - .DIADI(32'd0), - .DIPADIP(4'd0), - .DOADO(DO[31:0]), - .DOPADOP(DOP[3:0]), - .ADDRARDADDR(A1ADDR_16), - .CLKARDCLK(CLK2), - .ENARDEN(A1EN), - .REGCEAREGCE(|1), - .RSTRAMARSTRAM(|0), - .RSTREGARSTREG(|0), - .WEA(4'b0), - - .DIBDI(DI), - .DIPBDIP(DIP), - .DOBDO(DOBDO), - .DOPBDOP(DOPBDOP), - .ADDRBWRADDR(B1ADDR_16), - .CLKBWRCLK(CLK3), - .ENBWREN(|1), - .REGCEB(|0), - .RSTRAMB(|0), - .RSTREGB(|0), - .WEBWE(B1EN_8) - ); - end endgenerate -endmodule - -// ------------------------------------------------------------------------ - -module \$__XILINX_RAMB18_TDP (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN); - parameter CFG_ABITS = 10; - parameter CFG_DBITS = 18; - parameter CFG_ENABLE_B = 2; - - parameter CLKPOL2 = 1; - parameter CLKPOL3 = 1; - parameter [18431:0] INIT = 18432'bx; - - 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 [13:0] A1ADDR_14 = A1ADDR << (14 - CFG_ABITS); - wire [13:0] B1ADDR_14 = B1ADDR << (14 - CFG_ABITS); - wire [3:0] B1EN_4 = B1EN; - - wire [1:0] DIP, DOP; - wire [15:0] DI, DO; - - wire [15:0] DOBDO; - wire [1:0] DOPBDOP; - - assign A1DATA = { DOP[1], DO[15: 8], DOP[0], DO[ 7: 0] }; - assign { DIP[1], DI[15: 8], DIP[0], DI[ 7: 0] } = B1DATA; - - generate if (CFG_DBITS > 8) begin - RAMB18E1 #( - .RAM_MODE("TDP"), - .READ_WIDTH_A(CFG_DBITS), - .READ_WIDTH_B(CFG_DBITS), - .WRITE_WIDTH_A(CFG_DBITS), - .WRITE_WIDTH_B(CFG_DBITS), - .WRITE_MODE_A("READ_FIRST"), - .WRITE_MODE_B("READ_FIRST"), - .IS_CLKARDCLK_INVERTED(!CLKPOL2), - .IS_CLKBWRCLK_INVERTED(!CLKPOL3), - `include "brams_init_18.vh" - .SIM_DEVICE("7SERIES") - ) _TECHMAP_REPLACE_ ( - .DIADI(16'b0), - .DIPADIP(2'b0), - .DOADO(DO), - .DOPADOP(DOP), - .ADDRARDADDR(A1ADDR_14), - .CLKARDCLK(CLK2), - .ENARDEN(A1EN), - .REGCEAREGCE(|1), - .RSTRAMARSTRAM(|0), - .RSTREGARSTREG(|0), - .WEA(2'b0), - - .DIBDI(DI), - .DIPBDIP(DIP), - .DOBDO(DOBDO), - .DOPBDOP(DOPBDOP), - .ADDRBWRADDR(B1ADDR_14), - .CLKBWRCLK(CLK3), - .ENBWREN(|1), - .REGCEB(|0), - .RSTRAMB(|0), - .RSTREGB(|0), - .WEBWE(B1EN_4) - ); - end else begin - RAMB18E1 #( - .RAM_MODE("TDP"), - .READ_WIDTH_A(CFG_DBITS), - .READ_WIDTH_B(CFG_DBITS), - .WRITE_WIDTH_A(CFG_DBITS), - .WRITE_WIDTH_B(CFG_DBITS), - .WRITE_MODE_A("READ_FIRST"), - .WRITE_MODE_B("READ_FIRST"), - .IS_CLKARDCLK_INVERTED(!CLKPOL2), - .IS_CLKBWRCLK_INVERTED(!CLKPOL3), - `include "brams_init_16.vh" - .SIM_DEVICE("7SERIES") - ) _TECHMAP_REPLACE_ ( - .DIADI(16'b0), - .DIPADIP(2'b0), - .DOADO(DO), - .DOPADOP(DOP), - .ADDRARDADDR(A1ADDR_14), - .CLKARDCLK(CLK2), - .ENARDEN(A1EN), - .REGCEAREGCE(|1), - .RSTRAMARSTRAM(|0), - .RSTREGARSTREG(|0), - .WEA(2'b0), - - .DIBDI(DI), - .DIPBDIP(DIP), - .DOBDO(DOBDO), - .DOPBDOP(DOPBDOP), - .ADDRBWRADDR(B1ADDR_14), - .CLKBWRCLK(CLK3), - .ENBWREN(|1), - .REGCEB(|0), - .RSTRAMB(|0), - .RSTREGB(|0), - .WEBWE(B1EN_4) - ); - end endgenerate -endmodule - diff --git a/techlibs/xilinx/xc7_xcu_brams.txt b/techlibs/xilinx/xc7_xcu_brams.txt deleted file mode 100644 index 650367abf..000000000 --- a/techlibs/xilinx/xc7_xcu_brams.txt +++ /dev/null @@ -1,151 +0,0 @@ -# Virtex 6, Series 7, Ultrascale, Ultrascale Plus block RAM rules. - -bram $__XILINX_RAMB36_SDP - init 1 - abits 9 - dbits 72 - groups 2 - ports 1 1 - wrmode 0 1 - enable 1 8 - transp 0 0 - clocks 2 3 - clkpol 2 3 -endbram - -bram $__XILINX_RAMB18_SDP - init 1 - abits 9 - dbits 36 - groups 2 - ports 1 1 - wrmode 0 1 - enable 1 4 - transp 0 0 - clocks 2 3 - clkpol 2 3 -endbram - -bram $__XILINX_RAMB36_TDP - 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 - -bram $__XILINX_RAMB18_TDP - init 1 - abits 10 @a10d18 - dbits 18 @a10d18 - abits 11 @a11d9 - dbits 9 @a11d9 - abits 12 @a12d4 - dbits 4 @a12d4 - abits 13 @a13d2 - dbits 2 @a13d2 - abits 14 @a14d1 - dbits 1 @a14d1 - groups 2 - ports 1 1 - wrmode 0 1 - enable 1 2 @a10d18 - enable 1 1 @a11d9 @a12d4 @a13d2 @a14d1 - transp 0 0 - clocks 2 3 - clkpol 2 3 -endbram - -# The "min bits" value were taken from: -# [[CITE]] 7 Series FPGAs Memory Resources User Guide (UG473), -# v1.14 ed., p 29-30, July, 2019. -# https://www.xilinx.com/support/documentation/user_guides/ug473_7Series_Memory_Resources.pdf - -match $__XILINX_RAMB36_SDP - attribute !ram_style - attribute !logic_block - min bits 1024 - min efficiency 5 - shuffle_enable B - make_transp - or_next_if_better -endmatch - -match $__XILINX_RAMB36_SDP - attribute ram_style=block ram_block - attribute !logic_block - shuffle_enable B - make_transp - or_next_if_better -endmatch - -match $__XILINX_RAMB18_SDP - attribute !ram_style - attribute !logic_block - min bits 1024 - min efficiency 5 - shuffle_enable B - make_transp - or_next_if_better -endmatch - -match $__XILINX_RAMB18_SDP - attribute ram_style=block ram_block - attribute !logic_block - shuffle_enable B - make_transp - or_next_if_better -endmatch - -match $__XILINX_RAMB36_TDP - attribute !ram_style - attribute !logic_block - min bits 1024 - min efficiency 5 - shuffle_enable B - make_transp - or_next_if_better -endmatch - -match $__XILINX_RAMB36_TDP - attribute ram_style=block ram_block - attribute !logic_block - shuffle_enable B - make_transp - or_next_if_better -endmatch - -match $__XILINX_RAMB18_TDP - attribute !ram_style - attribute !logic_block - min bits 1024 - min efficiency 5 - shuffle_enable B - make_transp - or_next_if_better -endmatch - -match $__XILINX_RAMB18_TDP - attribute ram_style=block ram_block - attribute !logic_block - shuffle_enable B - make_transp -endmatch - diff --git a/techlibs/xilinx/xcu_brams_map.v b/techlibs/xilinx/xcu_brams_map.v deleted file mode 100644 index b6719b2dd..000000000 --- a/techlibs/xilinx/xcu_brams_map.v +++ /dev/null @@ -1,386 +0,0 @@ -// Ultrascale and Ultrascale Plus block RAM mapping. - -module \$__XILINX_RAMB36_SDP (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN); - parameter CLKPOL2 = 1; - parameter CLKPOL3 = 1; - parameter [36863:0] INIT = 36864'bx; - - input CLK2; - input CLK3; - - input [8:0] A1ADDR; - output [71:0] A1DATA; - input A1EN; - - input [8:0] B1ADDR; - input [71:0] B1DATA; - input [7:0] B1EN; - - wire [15:0] A1ADDR_16 = {A1ADDR, 6'b0}; - wire [15:0] B1ADDR_16 = {B1ADDR, 6'b0}; - - wire [7:0] DIP, DOP; - wire [63:0] DI, DO; - - assign A1DATA = { DOP[7], DO[63:56], DOP[6], DO[55:48], DOP[5], DO[47:40], DOP[4], DO[39:32], - DOP[3], DO[31:24], DOP[2], DO[23:16], DOP[1], DO[15: 8], DOP[0], DO[ 7: 0] }; - - assign { DIP[7], DI[63:56], DIP[6], DI[55:48], DIP[5], DI[47:40], DIP[4], DI[39:32], - DIP[3], DI[31:24], DIP[2], DI[23:16], DIP[1], DI[15: 8], DIP[0], DI[ 7: 0] } = B1DATA; - - RAMB36E2 #( - .READ_WIDTH_A(72), - .WRITE_WIDTH_B(72), - .WRITE_MODE_A("READ_FIRST"), - .WRITE_MODE_B("READ_FIRST"), - .DOA_REG(0), - .DOB_REG(0), - .IS_CLKARDCLK_INVERTED(!CLKPOL2), - .IS_CLKBWRCLK_INVERTED(!CLKPOL3), - `include "brams_init_36.vh" - ) _TECHMAP_REPLACE_ ( - .DOUTBDOUT(DO[63:32]), - .DOUTADOUT(DO[31:0]), - .DOUTPBDOUTP(DOP[7:4]), - .DOUTPADOUTP(DOP[3:0]), - .DINBDIN(DI[63:32]), - .DINADIN(DI[31:0]), - .DINPBDINP(DIP[7:4]), - .DINPADINP(DIP[3:0]), - - .ADDRARDADDR(A1ADDR_16), - .CLKARDCLK(CLK2), - .ENARDEN(A1EN), - .ADDRENA(|1), - .REGCEAREGCE(|1), - .RSTRAMARSTRAM(|0), - .RSTREGARSTREG(|0), - .WEA(4'b0), - - .ADDRBWRADDR(B1ADDR_16), - .CLKBWRCLK(CLK3), - .ENBWREN(|1), - .ADDRENB(|1), - .REGCEB(|1), - .RSTRAMB(|0), - .RSTREGB(|0), - .WEBWE(B1EN), - - .SLEEP(|0) - ); -endmodule - -// ------------------------------------------------------------------------ - -module \$__XILINX_RAMB18_SDP (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN); - parameter CLKPOL2 = 1; - parameter CLKPOL3 = 1; - parameter [18431:0] INIT = 18432'bx; - - input CLK2; - input CLK3; - - input [8:0] A1ADDR; - output [35:0] A1DATA; - input A1EN; - - input [8:0] B1ADDR; - input [35:0] B1DATA; - input [3:0] B1EN; - - wire [13:0] A1ADDR_14 = {A1ADDR, 5'b0}; - wire [13:0] B1ADDR_14 = {B1ADDR, 5'b0}; - - wire [3:0] DIP, DOP; - wire [31:0] DI, DO; - - assign A1DATA = { DOP[3], DO[31:24], DOP[2], DO[23:16], DOP[1], DO[15: 8], DOP[0], DO[ 7: 0] }; - assign { DIP[3], DI[31:24], DIP[2], DI[23:16], DIP[1], DI[15: 8], DIP[0], DI[ 7: 0] } = B1DATA; - - RAMB18E2 #( - .READ_WIDTH_A(36), - .WRITE_WIDTH_B(36), - .WRITE_MODE_A("READ_FIRST"), - .WRITE_MODE_B("READ_FIRST"), - .DOA_REG(0), - .DOB_REG(0), - .IS_CLKARDCLK_INVERTED(!CLKPOL2), - .IS_CLKBWRCLK_INVERTED(!CLKPOL3), - `include "brams_init_18.vh" - ) _TECHMAP_REPLACE_ ( - .DOUTBDOUT(DO[31:16]), - .DOUTADOUT(DO[15:0]), - .DOUTPBDOUTP(DOP[3:2]), - .DOUTPADOUTP(DOP[1:0]), - .DINBDIN(DI[31:16]), - .DINADIN(DI[15:0]), - .DINPBDINP(DIP[3:2]), - .DINPADINP(DIP[1:0]), - - .ADDRARDADDR(A1ADDR_14), - .CLKARDCLK(CLK2), - .ENARDEN(A1EN), - .ADDRENA(|1), - .REGCEAREGCE(|1), - .RSTRAMARSTRAM(|0), - .RSTREGARSTREG(|0), - .WEA(2'b0), - - .ADDRBWRADDR(B1ADDR_14), - .CLKBWRCLK(CLK3), - .ENBWREN(|1), - .ADDRENB(|1), - .REGCEB(|1), - .RSTRAMB(|0), - .RSTREGB(|0), - .WEBWE(B1EN), - - .SLEEP(|0) - ); -endmodule - -// ------------------------------------------------------------------------ - -module \$__XILINX_RAMB36_TDP (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; - - 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 [15:0] A1ADDR_16 = A1ADDR << (15 - CFG_ABITS); - wire [15:0] B1ADDR_16 = B1ADDR << (15 - CFG_ABITS); - wire [7:0] B1EN_8 = B1EN; - - wire [3:0] DIP, DOP; - wire [31:0] DI, DO; - - wire [31:0] DOBDO; - wire [3:0] DOPBDOP; - - assign A1DATA = { DOP[3], DO[31:24], DOP[2], DO[23:16], DOP[1], DO[15: 8], DOP[0], DO[ 7: 0] }; - assign { DIP[3], DI[31:24], DIP[2], DI[23:16], DIP[1], DI[15: 8], DIP[0], DI[ 7: 0] } = B1DATA; - - generate if (CFG_DBITS > 8) begin - RAMB36E2 #( - .READ_WIDTH_A(CFG_DBITS), - .READ_WIDTH_B(CFG_DBITS), - .WRITE_WIDTH_A(CFG_DBITS), - .WRITE_WIDTH_B(CFG_DBITS), - .WRITE_MODE_A("READ_FIRST"), - .WRITE_MODE_B("READ_FIRST"), - .DOA_REG(0), - .DOB_REG(0), - .IS_CLKARDCLK_INVERTED(!CLKPOL2), - .IS_CLKBWRCLK_INVERTED(!CLKPOL3), - `include "brams_init_36.vh" - ) _TECHMAP_REPLACE_ ( - .DINADIN(32'hFFFFFFFF), - .DINPADINP(4'hF), - .DOUTADOUT(DO[31:0]), - .DOUTPADOUTP(DOP[3:0]), - .ADDRARDADDR(A1ADDR_16), - .CLKARDCLK(CLK2), - .ENARDEN(A1EN), - .ADDRENA(|1), - .REGCEAREGCE(|1), - .RSTRAMARSTRAM(|0), - .RSTREGARSTREG(|0), - .WEA(4'b0), - - .DINBDIN(DI), - .DINPBDINP(DIP), - .DOUTBDOUT(DOBDO), - .DOUTPBDOUTP(DOPBDOP), - .ADDRBWRADDR(B1ADDR_16), - .CLKBWRCLK(CLK3), - .ENBWREN(|1), - .ADDRENB(|1), - .REGCEB(|0), - .RSTRAMB(|0), - .RSTREGB(|0), - .WEBWE(B1EN_8), - - .SLEEP(|0) - ); - end else begin - RAMB36E2 #( - .READ_WIDTH_A(CFG_DBITS), - .READ_WIDTH_B(CFG_DBITS), - .WRITE_WIDTH_A(CFG_DBITS), - .WRITE_WIDTH_B(CFG_DBITS), - .WRITE_MODE_A("READ_FIRST"), - .WRITE_MODE_B("READ_FIRST"), - .DOA_REG(0), - .DOB_REG(0), - .IS_CLKARDCLK_INVERTED(!CLKPOL2), - .IS_CLKBWRCLK_INVERTED(!CLKPOL3), - `include "brams_init_32.vh" - ) _TECHMAP_REPLACE_ ( - .DINADIN(32'hFFFFFFFF), - .DINPADINP(4'hF), - .DOUTADOUT(DO[31:0]), - .DOUTPADOUTP(DOP[3:0]), - .ADDRARDADDR(A1ADDR_16), - .CLKARDCLK(CLK2), - .ENARDEN(A1EN), - .ADDRENA(|1), - .REGCEAREGCE(|1), - .RSTRAMARSTRAM(|0), - .RSTREGARSTREG(|0), - .WEA(4'b0), - - .DINBDIN(DI), - .DINPBDINP(DIP), - .DOUTBDOUT(DOBDO), - .DOUTPBDOUTP(DOPBDOP), - .ADDRBWRADDR(B1ADDR_16), - .CLKBWRCLK(CLK3), - .ENBWREN(|1), - .ADDRENB(|1), - .REGCEB(|0), - .RSTRAMB(|0), - .RSTREGB(|0), - .WEBWE(B1EN_8), - - .SLEEP(|0) - ); - end endgenerate -endmodule - -// ------------------------------------------------------------------------ - -module \$__XILINX_RAMB18_TDP (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN); - parameter CFG_ABITS = 10; - parameter CFG_DBITS = 18; - parameter CFG_ENABLE_B = 2; - - parameter CLKPOL2 = 1; - parameter CLKPOL3 = 1; - parameter [18431:0] INIT = 18432'bx; - - 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 [13:0] A1ADDR_14 = A1ADDR << (14 - CFG_ABITS); - wire [13:0] B1ADDR_14 = B1ADDR << (14 - CFG_ABITS); - wire [3:0] B1EN_4 = B1EN; - - wire [1:0] DIP, DOP; - wire [15:0] DI, DO; - - wire [15:0] DOBDO; - wire [1:0] DOPBDOP; - - assign A1DATA = { DOP[1], DO[15: 8], DOP[0], DO[ 7: 0] }; - assign { DIP[1], DI[15: 8], DIP[0], DI[ 7: 0] } = B1DATA; - - generate if (CFG_DBITS > 8) begin - RAMB18E2 #( - .READ_WIDTH_A(CFG_DBITS), - .READ_WIDTH_B(CFG_DBITS), - .WRITE_WIDTH_A(CFG_DBITS), - .WRITE_WIDTH_B(CFG_DBITS), - .WRITE_MODE_A("READ_FIRST"), - .WRITE_MODE_B("READ_FIRST"), - .DOA_REG(0), - .DOB_REG(0), - .IS_CLKARDCLK_INVERTED(!CLKPOL2), - .IS_CLKBWRCLK_INVERTED(!CLKPOL3), - `include "brams_init_18.vh" - ) _TECHMAP_REPLACE_ ( - .DINADIN(16'hFFFF), - .DINPADINP(2'b11), - .DOUTADOUT(DO), - .DOUTPADOUTP(DOP), - .ADDRARDADDR(A1ADDR_14), - .CLKARDCLK(CLK2), - .ENARDEN(A1EN), - .ADDRENA(|1), - .REGCEAREGCE(|1), - .RSTRAMARSTRAM(|0), - .RSTREGARSTREG(|0), - .WEA(2'b0), - - .DINBDIN(DI), - .DINPBDINP(DIP), - .DOUTBDOUT(DOBDO), - .DOUTPBDOUTP(DOPBDOP), - .ADDRBWRADDR(B1ADDR_14), - .CLKBWRCLK(CLK3), - .ENBWREN(|1), - .ADDRENB(|1), - .REGCEB(|0), - .RSTRAMB(|0), - .RSTREGB(|0), - .WEBWE(B1EN_4), - - .SLEEP(|0) - ); - end else begin - RAMB18E2 #( - //.RAM_MODE("TDP"), - .READ_WIDTH_A(CFG_DBITS), - .READ_WIDTH_B(CFG_DBITS), - .WRITE_WIDTH_A(CFG_DBITS), - .WRITE_WIDTH_B(CFG_DBITS), - .WRITE_MODE_A("READ_FIRST"), - .WRITE_MODE_B("READ_FIRST"), - .DOA_REG(0), - .DOB_REG(0), - .IS_CLKARDCLK_INVERTED(!CLKPOL2), - .IS_CLKBWRCLK_INVERTED(!CLKPOL3), - `include "brams_init_16.vh" - ) _TECHMAP_REPLACE_ ( - .DINADIN(16'hFFFF), - .DINPADINP(2'b11), - .DOUTADOUT(DO), - .DOUTPADOUTP(DOP), - .ADDRARDADDR(A1ADDR_14), - .CLKARDCLK(CLK2), - .ENARDEN(A1EN), - .ADDRENA(|1), - .REGCEAREGCE(|1), - .RSTRAMARSTRAM(|0), - .RSTREGARSTREG(|0), - .WEA(2'b0), - - .DINBDIN(DI), - .DINPBDINP(DIP), - .DOUTBDOUT(DOBDO), - .DOUTPBDOUTP(DOPBDOP), - .ADDRBWRADDR(B1ADDR_14), - .CLKBWRCLK(CLK3), - .ENBWREN(|1), - .ADDRENB(|1), - .REGCEB(|0), - .RSTRAMB(|0), - .RSTREGB(|0), - .WEBWE(B1EN_4), - - .SLEEP(|0) - ); - end endgenerate -endmodule - diff --git a/techlibs/xilinx/xcup_urams.txt b/techlibs/xilinx/xcup_urams.txt deleted file mode 100644 index 40c474239..000000000 --- a/techlibs/xilinx/xcup_urams.txt +++ /dev/null @@ -1,19 +0,0 @@ -bram $__XILINX_URAM288 - init 0 - abits 12 - dbits 72 - groups 2 - ports 1 1 - wrmode 0 1 - enable 1 9 - transp 0 0 - clocks 2 2 - clkpol 2 2 -endbram - -match $__XILINX_URAM288 - min bits 131072 - min efficiency 15 - shuffle_enable B - make_transp -endmatch diff --git a/techlibs/xilinx/xcup_urams_map.v b/techlibs/xilinx/xcup_urams_map.v deleted file mode 100644 index f15211ba3..000000000 --- a/techlibs/xilinx/xcup_urams_map.v +++ /dev/null @@ -1,47 +0,0 @@ -module \$__XILINX_URAM288 (CLK2, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN); - parameter CLKPOL2 = 1; - - input CLK2; - - input [11:0] A1ADDR; - output [71:0] A1DATA; - input A1EN; - - input [11:0] B1ADDR; - input [71:0] B1DATA; - input [8:0] B1EN; - - - URAM288 #( - .BWE_MODE_A("PARITY_INDEPENDENT"), - .BWE_MODE_B("PARITY_INDEPENDENT"), - .EN_AUTO_SLEEP_MODE("FALSE"), - .IREG_PRE_A("FALSE"), - .IREG_PRE_B("FALSE"), - .IS_CLK_INVERTED(!CLKPOL2), - .OREG_A("FALSE"), - .OREG_B("FALSE") - ) _TECHMAP_REPLACE_ ( - .ADDR_A({11'b0, A1ADDR}), - .BWE_A(9'b0), - .DIN_A(72'b0), - .EN_A(A1EN), - .RDB_WR_A(1'b0), - .INJECT_DBITERR_A(1'b0), - .INJECT_SBITERR_A(1'b0), - .RST_A(1'b0), - .DOUT_A(A1DATA), - - .ADDR_B({11'b0, B1ADDR}), - .BWE_B(B1EN), - .DIN_B(B1DATA), - .EN_B(|B1EN), - .RDB_WR_B(1'b1), - .INJECT_DBITERR_B(1'b0), - .INJECT_SBITERR_B(1'b0), - .RST_B(1'b0), - - .CLK(CLK2), - .SLEEP(1'b0) - ); -endmodule |