From f4d1426229e0843d55a7ac2a10760acecf9c6710 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Sun, 27 Feb 2022 09:57:10 +0100 Subject: [PATCH] anlogic: Use `memory_libmap` pass. --- techlibs/anlogic/.gitignore | 2 - techlibs/anlogic/Makefile.inc | 21 - techlibs/anlogic/brams.txt | 108 +++-- techlibs/anlogic/brams_init.py | 21 - techlibs/anlogic/brams_map.v | 630 ++++++++++++++++++++------- techlibs/anlogic/lutram_init_16x4.vh | 16 - techlibs/anlogic/lutrams.txt | 28 +- techlibs/anlogic/lutrams_map.v | 40 +- techlibs/anlogic/synth_anlogic.cc | 22 +- 9 files changed, 585 insertions(+), 303 deletions(-) delete mode 100644 techlibs/anlogic/.gitignore delete mode 100644 techlibs/anlogic/brams_init.py delete mode 100644 techlibs/anlogic/lutram_init_16x4.vh diff --git a/techlibs/anlogic/.gitignore b/techlibs/anlogic/.gitignore deleted file mode 100644 index d127107db..000000000 --- a/techlibs/anlogic/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -brams_init.mk -brams_init_*.vh diff --git a/techlibs/anlogic/Makefile.inc b/techlibs/anlogic/Makefile.inc index 79519c645..669e8bea5 100644 --- a/techlibs/anlogic/Makefile.inc +++ b/techlibs/anlogic/Makefile.inc @@ -3,32 +3,11 @@ OBJS += techlibs/anlogic/synth_anlogic.o OBJS += techlibs/anlogic/anlogic_eqn.o OBJS += techlibs/anlogic/anlogic_fixcarry.o -GENFILES += techlibs/anlogic/brams_init_16.vh -GENFILES += techlibs/anlogic/brams_init_9.vh -GENFILES += techlibs/anlogic/brams_init_8.vh - -EXTRA_OBJS += techlibs/anlogic/brams_init.mk -.SECONDARY: techlibs/anlogic/brams_init.mk - -techlibs/anlogic/brams_init.mk: techlibs/anlogic/brams_init.py - $(Q) mkdir -p techlibs/anlogic - $(P) $(PYTHON_EXECUTABLE) $< - $(Q) touch $@ - -techlibs/anlogic/brams_init_16.vh: techlibs/anlogic/brams_init.mk -techlibs/anlogic/brams_init_9.vh: techlibs/anlogic/brams_init.mk -techlibs/anlogic/brams_init_8.vh: techlibs/anlogic/brams_init.mk - $(eval $(call add_share_file,share/anlogic,techlibs/anlogic/cells_map.v)) $(eval $(call add_share_file,share/anlogic,techlibs/anlogic/arith_map.v)) $(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)) - -$(eval $(call add_gen_share_file,share/anlogic,techlibs/anlogic/brams_init_16.vh)) -$(eval $(call add_gen_share_file,share/anlogic,techlibs/anlogic/brams_init_9.vh)) -$(eval $(call add_gen_share_file,share/anlogic,techlibs/anlogic/brams_init_8.vh)) diff --git a/techlibs/anlogic/brams.txt b/techlibs/anlogic/brams.txt index a39701c63..910cdebe1 100644 --- a/techlibs/anlogic/brams.txt +++ b/techlibs/anlogic/brams.txt @@ -1,43 +1,69 @@ -bram $__ANLOGIC_BRAM9K_TDP - init 1 - abits 13 @a13d1 - dbits 1 @a13d1 - abits 12 @a12d2 - dbits 2 @a12d2 - abits 11 @a11d4 - dbits 4 @a11d4 - abits 10 @a10d9 - dbits 9 @a10d9 - groups 2 - ports 1 1 - wrmode 0 1 - enable 1 1 - transp 2 0 - clocks 2 3 - clkpol 2 3 -endbram +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; + } +} -bram $__ANLOGIC_BRAM32K - init 1 - abits 11 - dbits 16 - groups 2 - ports 1 1 - wrmode 0 1 - enable 1 2 - transp 0 0 - clocks 2 3 - clkpol 2 3 -endbram +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; + } +} -match $__ANLOGIC_BRAM32K - min efficiency 30 - shuffle_enable B - make_transp - or_next_if_better -endmatch - -match $__ANLOGIC_BRAM9K_TDP - min efficiency 5 - make_transp -endmatch +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_init.py b/techlibs/anlogic/brams_init.py deleted file mode 100644 index 8dda0d33e..000000000 --- a/techlibs/anlogic/brams_init.py +++ /dev/null @@ -1,21 +0,0 @@ -#!/usr/bin/env python3 - -with open("techlibs/anlogic/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/anlogic/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/anlogic/brams_init_16.vh", "w") as f: - for i in range(128): - print(".INIT_%02X(INIT[%3d*256 +: 256])," % (i, i), file=f) diff --git a/techlibs/anlogic/brams_map.v b/techlibs/anlogic/brams_map.v index ee02b6d7c..7e2642d65 100644 --- a/techlibs/anlogic/brams_map.v +++ b/techlibs/anlogic/brams_map.v @@ -1,162 +1,474 @@ -module \$__ANLOGIC_BRAM9K_TDP (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN); - parameter CFG_ABITS = 10; - parameter CFG_DBITS = 9; - - parameter CLKPOL2 = 1; - parameter CLKPOL3 = 1; - parameter [9215:0] INIT = 9216'bx; - parameter TRANSP2 = 0; - - 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; - - localparam CLKAMUX = CLKPOL2 ? "SIG" : "INV"; - localparam CLKBMUX = CLKPOL3 ? "SIG" : "INV"; - - localparam WRITEMODE_B = TRANSP2 ? "WRITETHROUGH" : "READBEFOREWRITE"; - - localparam DATA_WIDTH = CFG_DBITS == 1 ? "1" : - (CFG_DBITS == 2 ? "2" : - (CFG_DBITS <= 4 ? "4" : "9")); - - localparam APADBITS = $clog2(CFG_DBITS == 9 ? 8 : CFG_DBITS); - - wire [12:0] addra; - wire [12:0] addrb; - - assign addra[12:APADBITS] = A1ADDR; - assign addrb[12:APADBITS] = B1ADDR; - - wire [8:0] doa; - wire [8:0] dib; - - assign A1DATA[CFG_DBITS-1:0] = doa; - assign dib[CFG_DBITS-1:0] = B1DATA; - - generate if (CFG_DBITS == 9) begin - EG_PHY_BRAM #( - .MODE("DP8K"), - .DATA_WIDTH_A(DATA_WIDTH), - .DATA_WIDTH_B(DATA_WIDTH), - .READBACK("OFF"), - .REGMODE_A("NOREG"), - .REGMODE_B("NOREG"), - .WRITEMODE_A("READBEFOREWRITE"), - .WRITEMODE_B(WRITEMODE_B), - .RESETMODE("ASYNC"), - .CEAMUX("SIG"), .CEBMUX("SIG"), - .OCEAMUX("1"), .OCEBMUX("1"), - .RSTAMUX("0"), .RSTBMUX("0"), - .CLKAMUX(CLKAMUX), - .CLKBMUX(CLKBMUX), - .WEAMUX("0"), .WEBMUX("SIG"), - .CSA0("1"), .CSA1("1"), - .CSA2("1"), .CSB0("1"), - .CSB1("1"), .CSB2("1"), - `include "brams_init_9.vh" - ) _TECHMAP_REPLACE_ ( - .doa(doa), .dib(dib), - .addra(addra), .addrb(addrb), - .clka(CLK2), .clkb(CLK3), - .cea(A1EN), .ceb(B1EN), - .ocea(1'b1), .oceb(1'b1), - .rsta(1'b0), .rstb(1'b0), - .wea(1'b0), .web(B1EN), - .csa(3'b111), .csb(3'b111) - ); - end else begin - EG_PHY_BRAM #( - .MODE("DP8K"), - .DATA_WIDTH_A(DATA_WIDTH), - .DATA_WIDTH_B(DATA_WIDTH), - .READBACK("OFF"), - .REGMODE_A("NOREG"), - .REGMODE_B("NOREG"), - .WRITEMODE_A("READBEFOREWRITE"), - .WRITEMODE_B(WRITEMODE_B), - .RESETMODE("ASYNC"), - .CEAMUX("SIG"), .CEBMUX("SIG"), - .OCEAMUX("1"), .OCEBMUX("1"), - .RSTAMUX("0"), .RSTBMUX("0"), - .CLKAMUX(CLKAMUX), - .CLKBMUX(CLKBMUX), - .WEAMUX("0"), .WEBMUX("SIG"), - .CSA0("1"), .CSA1("1"), - .CSA2("1"), .CSB0("1"), - .CSB1("1"), .CSB2("1"), - `include "brams_init_8.vh" - ) _TECHMAP_REPLACE_ ( - .doa(doa), .dib(dib), - .addra(addra), .addrb(addrb), - .clka(CLK2), .clkb(CLK3), - .cea(A1EN), .ceb(B1EN), - .ocea(1'b1), .oceb(1'b1), - .rsta(1'b0), .rstb(1'b0), - .wea(1'b0), .web(B1EN), - .csa(3'b111), .csb(3'b111) - ); - end endgenerate +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 (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN); - parameter CFG_ABITS = 11; - parameter CFG_DBITS = 16; - - parameter CLKPOL2 = 1; - parameter CLKPOL3 = 1; - parameter [32767:0] INIT = 32768'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 [1:0] B1EN; - - localparam CLKAMUX = CLKPOL2 ? "SIG" : "INV"; - localparam CLKBMUX = CLKPOL3 ? "SIG" : "INV"; - - wire byteweb = B1EN[1] ^ B1EN[0]; - wire byteb = B1EN[1]; - - EG_PHY_BRAM32K #( - .MODE("DP16K"), - .DATA_WIDTH_A("16"), - .DATA_WIDTH_B("16"), - .REGMODE_A("NOREG"), - .REGMODE_B("NOREG"), - .WRITEMODE_A("NORMAL"), - .WRITEMODE_B("NORMAL"), - .SRMODE("ASYNC"), - .CSAMUX("SIG"), .CSBMUX("SIG"), - .OCEAMUX("1"), .OCEBMUX("1"), - .RSTAMUX("0"), .RSTBMUX("0"), - .CLKAMUX(CLKAMUX), - .CLKBMUX(CLKBMUX), - .WEAMUX("0"), .WEBMUX("SIG"), - .READBACK("OFF"), - `include "brams_init_16.vh" - ) _TECHMAP_REPLACE_ ( - .doa(A1DATA), .dib(B1DATA), - .addra(A1ADDR), .addrb(B1ADDR), - .bytea(1'b0), .byteb(byteb), - .bytewea(1'b0), .byteweb(byteweb), - .csa(A1EN), .csb(|B1EN), - .wea(1'b0), .web(|B1EN), - .clka(CLK2), .clkb(CLK3), - .rsta(1'b0), .rstb(1'b0), - .ocea(1'b1), .oceb(1'b1) - ); + +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 5da14c26b..a3c1e0434 100644 --- a/techlibs/anlogic/synth_anlogic.cc +++ b/techlibs/anlogic/synth_anlogic.cc @@ -166,19 +166,17 @@ struct SynthAnlogicPass : public ScriptPass run("synth -run coarse"); } - if (!nobram && check_label("map_bram", "(skip if -nobram)")) + if (check_label("map_ram")) { - run("memory_bram -rules +/anlogic/brams.txt"); - run("techmap -map +/anlogic/brams_map.v"); - run("setundef -zero -params t:EG_PHY_BRAM"); - run("setundef -zero -params t:EG_PHY_BRAM32K"); - } - - if (!nolutram && check_label("map_lutram", "(skip if -nolutram)")) - { - 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")) -- 2.30.2