From 2dcb0797f08c3747da5144c2940f71c03a39c9b6 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Sun, 6 Mar 2022 03:43:13 +0100 Subject: [PATCH] machxo2: Use `memory_libmap` pass. --- techlibs/machxo2/Makefile.inc | 5 + techlibs/machxo2/brams.txt | 50 +++++ techlibs/machxo2/brams_map.v | 337 ++++++++++++++++++++++++++++++ techlibs/machxo2/cells_sim.v | 121 +++++++++++ techlibs/machxo2/lutrams.txt | 12 ++ techlibs/machxo2/lutrams_map.v | 23 ++ techlibs/machxo2/synth_machxo2.cc | 31 ++- 7 files changed, 578 insertions(+), 1 deletion(-) create mode 100644 techlibs/machxo2/brams.txt create mode 100644 techlibs/machxo2/brams_map.v create mode 100644 techlibs/machxo2/lutrams.txt create mode 100644 techlibs/machxo2/lutrams_map.v 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_sim.v b/techlibs/machxo2/cells_sim.v index dc68a3127..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. 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 e86ec5aaf..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"); -- 2.30.2