Added bram support
authorMiodrag Milanovic <mmicko@gmail.com>
Sun, 4 Aug 2019 09:46:36 +0000 (11:46 +0200)
committerMiodrag Milanovic <mmicko@gmail.com>
Sun, 4 Aug 2019 09:46:36 +0000 (11:46 +0200)
techlibs/efinix/Makefile.inc
techlibs/efinix/bram.txt [new file with mode: 0644]
techlibs/efinix/brams_map.v [new file with mode: 0644]
techlibs/efinix/cells_sim.v
techlibs/efinix/efinix_determine_init.cc [new file with mode: 0644]
techlibs/efinix/synth_efinix.cc

index 82dfa3cd8862a82a01d7da3f9a39edbd56f71d06..d0593baec5caa15cacf31c3b8b9637dbd509ba27 100644 (file)
@@ -1,7 +1,10 @@
 
 OBJS += techlibs/efinix/synth_efinix.o
 OBJS += techlibs/efinix/efinix_gbuf.o
+OBJS += techlibs/efinix/efinix_determine_init.o
 
 $(eval $(call add_share_file,share/efinix,techlibs/efinix/cells_map.v))
 $(eval $(call add_share_file,share/efinix,techlibs/efinix/arith_map.v))
 $(eval $(call add_share_file,share/efinix,techlibs/efinix/cells_sim.v))
+$(eval $(call add_share_file,share/efinix,techlibs/efinix/brams_map.v))
+$(eval $(call add_share_file,share/efinix,techlibs/efinix/bram.txt))
\ No newline at end of file
diff --git a/techlibs/efinix/bram.txt b/techlibs/efinix/bram.txt
new file mode 100644 (file)
index 0000000..0b3fd93
--- /dev/null
@@ -0,0 +1,32 @@
+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
diff --git a/techlibs/efinix/brams_map.v b/techlibs/efinix/brams_map.v
new file mode 100644 (file)
index 0000000..9ef01d0
--- /dev/null
@@ -0,0 +1,65 @@
+module \$__EFINIX_5K (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN);
+       parameter CFG_ABITS = 8;
+       parameter CFG_DBITS = 20;
+       parameter CFG_ENABLE_A = 2;
+
+       parameter CLKPOL2 = 1;
+       parameter CLKPOL3 = 1;
+       parameter [5119:0] INIT = 5119'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 WRITEMODE_A = TRANSP2 ? "WRITE_FIRST" : "READ_FIRST";
+
+       EFX_RAM_5K #(
+               .READ_WIDTH(20),
+               .WRITE_WIDTH(20),
+               .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])
+       ) _TECHMAP_REPLACE_ (
+               .WDATA(A1DATA),
+               .WADDR(A1ADDR),
+               .WE(A1EN),
+               .WCLK(CLK2),
+               .WCLKE(1'b1),
+               .RDATA(B1DATA),
+               .RADDR(B1ADDR),
+               .RE(B1EN),
+               .RCLK(CLK3)
+       );
+endmodule
index 2cbf8ae4bcc12a916f531dd53ba646e5bac81d16..8c8f6afaa3e91c77cc5c32f14c1c1888a2452682 100644 (file)
@@ -35,10 +35,73 @@ module EFX_FF(
    parameter D_POLARITY = 1;
 endmodule
 
-module EFX_GBUFCE (
+module EFX_GBUFCE(
    input CE,
    input I,
    output O
 );
    parameter CE_POLARITY = 1'b1;
 endmodule
+
+module EFX_RAM_5K(
+   input [WRITE_WIDTH-1:0] WDATA,
+   input [WRITE_ADDR_WIDTH-1:0] WADDR,
+   input WE, 
+   input WCLK,
+   input WCLKE, 
+   output [READ_WIDTH-1:0] RDATA, 
+   input [READ_ADDR_WIDTH-1:0] RADDR,
+   input RE, 
+   input RCLK
+);
+   parameter READ_WIDTH = 20;
+   parameter WRITE_WIDTH = 20;
+   parameter OUTPUT_REG = 1'b0;
+   parameter RCLK_POLARITY  = 1'b1;
+   parameter RE_POLARITY    = 1'b1;
+   parameter WCLK_POLARITY  = 1'b1;
+   parameter WE_POLARITY    = 1'b1;
+   parameter WCLKE_POLARITY = 1'b1;
+   parameter WRITE_MODE = "READ_FIRST";
+   parameter INIT_0 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+   parameter INIT_1 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+   parameter INIT_2 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+   parameter INIT_3 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+   parameter INIT_4 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+   parameter INIT_5 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+   parameter INIT_6 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+   parameter INIT_7 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+   parameter INIT_8 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+   parameter INIT_9 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+   parameter INIT_A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+   parameter INIT_B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+   parameter INIT_C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+   parameter INIT_D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+   parameter INIT_E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+   parameter INIT_F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+   parameter INIT_10 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+   parameter INIT_11 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+   parameter INIT_12 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+   parameter INIT_13 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+
+   localparam READ_ADDR_WIDTH = 
+                           (READ_WIDTH == 16) ? 8 :  // 256x16
+                           (READ_WIDTH == 8)  ? 9 :  // 512x8
+                           (READ_WIDTH == 4)  ? 10 : // 1024x4
+                           (READ_WIDTH == 2)  ? 11 : // 2048x2
+                           (READ_WIDTH == 1)  ? 12 : // 4096x1
+                           (READ_WIDTH == 20) ? 8 :  // 256x20
+                           (READ_WIDTH == 10) ? 9 :  // 512x10
+                           (READ_WIDTH == 5)  ? 10 : -1; // 1024x5
+   
+   localparam WRITE_ADDR_WIDTH = 
+                           (WRITE_WIDTH == 16) ? 8 :  // 256x16
+                           (WRITE_WIDTH == 8)  ? 9 :  // 512x8
+                           (WRITE_WIDTH == 4)  ? 10 : // 1024x4
+                           (WRITE_WIDTH == 2)  ? 11 : // 2048x2
+                           (WRITE_WIDTH == 1)  ? 12 : // 4096x1
+                           (WRITE_WIDTH == 20) ? 8 :  // 256x20
+                           (WRITE_WIDTH == 10) ? 9 :  // 512x10
+                           (WRITE_WIDTH == 5)  ? 10 : -1; // 1024x5
+   
+endmodule
\ No newline at end of file
diff --git a/techlibs/efinix/efinix_determine_init.cc b/techlibs/efinix/efinix_determine_init.cc
new file mode 100644 (file)
index 0000000..54da703
--- /dev/null
@@ -0,0 +1,89 @@
+/*
+ *  yosys -- Yosys Open SYnthesis Suite
+ *
+ *  Copyright (C) 2018 Icenowy Zheng <icenowy@aosc.io>
+ *
+ *  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/yosys.h"
+#include "kernel/sigtools.h"
+
+USING_YOSYS_NAMESPACE
+PRIVATE_NAMESPACE_BEGIN
+
+struct EfinixDetermineInitPass : public Pass {
+       EfinixDetermineInitPass() : Pass("efinix_determine_init", "Efinix: Determine the init value of cells") { }
+       void help() YS_OVERRIDE
+       {
+               log("\n");
+               log("    efinix_determine_init [selection]\n");
+               log("\n");
+               log("Determine the init value of cells that doesn't allow unknown init value.\n");
+               log("\n");
+       }
+
+       Const determine_init(Const init)
+       {
+               for (int i = 0; i < GetSize(init); i++) {
+                       if (init[i] != State::S0 && init[i] != State::S1)
+                               init[i] = State::S0;
+               }
+
+               return init;
+       }
+
+       void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
+       {
+               log_header(design, "Executing EFINIX_DETERMINE_INIT pass (determine init value for cells).\n");
+
+               extra_args(args, args.size(), design);
+
+               int cnt = 0;
+               for (auto module : design->selected_modules())
+               {
+                       for (auto cell : module->selected_cells())
+                       {
+                               if (cell->type == "\\EFX_RAM_5K")
+                               {
+                                       cell->setParam("\\INIT_0", determine_init(cell->getParam("\\INIT_0")));                                 
+                                       cell->setParam("\\INIT_1", determine_init(cell->getParam("\\INIT_1")));
+                                       cell->setParam("\\INIT_2", determine_init(cell->getParam("\\INIT_2")));
+                                       cell->setParam("\\INIT_3", determine_init(cell->getParam("\\INIT_3")));
+                                       cell->setParam("\\INIT_4", determine_init(cell->getParam("\\INIT_4")));
+                                       cell->setParam("\\INIT_5", determine_init(cell->getParam("\\INIT_5")));
+                                       cell->setParam("\\INIT_6", determine_init(cell->getParam("\\INIT_6")));
+                                       cell->setParam("\\INIT_7", determine_init(cell->getParam("\\INIT_7")));
+                                       cell->setParam("\\INIT_8", determine_init(cell->getParam("\\INIT_8")));
+                                       cell->setParam("\\INIT_9", determine_init(cell->getParam("\\INIT_9")));
+                                       cell->setParam("\\INIT_A", determine_init(cell->getParam("\\INIT_A")));
+                                       cell->setParam("\\INIT_B", determine_init(cell->getParam("\\INIT_B")));
+                                       cell->setParam("\\INIT_C", determine_init(cell->getParam("\\INIT_C")));
+                                       cell->setParam("\\INIT_D", determine_init(cell->getParam("\\INIT_D")));
+                                       cell->setParam("\\INIT_E", determine_init(cell->getParam("\\INIT_E")));
+                                       cell->setParam("\\INIT_F", determine_init(cell->getParam("\\INIT_F")));
+                                       cell->setParam("\\INIT_10", determine_init(cell->getParam("\\INIT_10")));
+                                       cell->setParam("\\INIT_11", determine_init(cell->getParam("\\INIT_11")));
+                                       cell->setParam("\\INIT_12", determine_init(cell->getParam("\\INIT_12")));
+                                       cell->setParam("\\INIT_13", determine_init(cell->getParam("\\INIT_13")));
+
+                                       cnt++;
+                               }
+                       }
+               }
+               log_header(design, "Updated %d cells with determined init value.\n", cnt);
+       }
+} EfinixDetermineInitPass;
+
+PRIVATE_NAMESPACE_END
index 3f17bafa3a6056840396fe911a06d3f3d3d86209..000a1731013b81c54308baf1558cb949f2f66af8 100644 (file)
@@ -150,6 +150,13 @@ struct SynthEfinixPass : public ScriptPass
                        run("synth -run coarse");
                }
 
+               if (check_label("map_bram", "(skip if -nobram)"))
+               {
+                       run("memory_bram -rules +/efinix/bram.txt");
+                       run("techmap -map +/efinix/brams_map.v");
+                       run("efinix_determine_init");
+               }
+
                if (check_label("fine"))
                {
                        run("opt -fast -mux_undef -undriven -fine");