From 9d11575856e2345d2a6ae68f6b944d256d1e131a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Sun, 6 Mar 2022 02:21:53 +0100 Subject: [PATCH] efinix: Use `memory_libmap` pass. --- techlibs/efinix/brams.txt | 51 ++++----- techlibs/efinix/brams_map.v | 194 +++++++++++++++++++++++--------- techlibs/efinix/synth_efinix.cc | 8 +- tests/arch/efinix/lutram.ys | 13 +-- 4 files changed, 164 insertions(+), 102 deletions(-) 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/tests/arch/efinix/lutram.ys b/tests/arch/efinix/lutram.ys index dcf647ce0..8412d1389 100644 --- a/tests/arch/efinix/lutram.ys +++ b/tests/arch/efinix/lutram.ys @@ -1,17 +1,6 @@ read_verilog ../common/lutram.v hierarchy -top lutram_1w1r -proc -memory -nomap -equiv_opt -run :prove -map +/efinix/cells_sim.v synth_efinix -memory -opt -full - -miter -equiv -flatten -make_assert -make_outputs gold gate miter -#ERROR: Called with -verify and proof did fail! -#sat -verify -prove-asserts -seq 5 -set-init-zero -show-inputs -show-outputs miter -sat -prove-asserts -seq 5 -set-init-zero -show-inputs -show-outputs miter - -design -load postopt +synth_efinix cd lutram_1w1r select -assert-count 1 t:EFX_GBUFCE select -assert-count 1 t:EFX_RAM_5K