efinix: Use `memory_libmap` pass.
authorMarcelina Kościelnicka <mwk@0x04.net>
Sun, 6 Mar 2022 01:21:53 +0000 (02:21 +0100)
committerMarcelina Kościelnicka <mwk@0x04.net>
Wed, 18 May 2022 15:32:56 +0000 (17:32 +0200)
techlibs/efinix/brams.txt
techlibs/efinix/brams_map.v
techlibs/efinix/synth_efinix.cc
tests/arch/efinix/lutram.ys

index 0b3fd93080dca67f1b4cc4d092bcdaa6ac0110e4..271fc4fc4dd7b269d5eb078084f7455c54ea72bb 100644 (file)
@@ -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;
+               }
+       }
+}
index 6786ae76970bc886db9b68328b0615831f39b16c..752010f45ec1d290294bd0e00c83955f95021399 100644 (file)
-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
index ace56bee928c1d217b7b6bda9c75daf2d7d5db0c..bbc389444882a560c6aff9768b497d510820bab4 100644 (file)
@@ -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"))
index dcf647ce0f9ed54c68bc269422db1e4518edbb87..8412d138958250e749c94a97296600deb60686c7 100644 (file)
@@ -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