From d6f7698f591aa1957e263e13b66d0d808cf5a478 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 24 Apr 2015 00:06:50 +0200 Subject: [PATCH] Added ice40 bram support --- techlibs/ice40/Makefile.inc | 2 + techlibs/ice40/brams.txt | 40 ++++++++++++++ techlibs/ice40/brams_map.v | 99 +++++++++++++++++++++++++++++++++++ techlibs/ice40/synth_ice40.cc | 52 +++++++++++++++++- 4 files changed, 192 insertions(+), 1 deletion(-) create mode 100644 techlibs/ice40/brams.txt create mode 100644 techlibs/ice40/brams_map.v diff --git a/techlibs/ice40/Makefile.inc b/techlibs/ice40/Makefile.inc index cd178d664..14ef4e7dc 100644 --- a/techlibs/ice40/Makefile.inc +++ b/techlibs/ice40/Makefile.inc @@ -5,4 +5,6 @@ OBJS += techlibs/ice40/ice40_ffssr.o $(eval $(call add_share_file,share/ice40,techlibs/ice40/arith_map.v)) $(eval $(call add_share_file,share/ice40,techlibs/ice40/cells_map.v)) $(eval $(call add_share_file,share/ice40,techlibs/ice40/cells_sim.v)) +$(eval $(call add_share_file,share/ice40,techlibs/ice40/brams.txt)) +$(eval $(call add_share_file,share/ice40,techlibs/ice40/brams_map.v)) diff --git a/techlibs/ice40/brams.txt b/techlibs/ice40/brams.txt new file mode 100644 index 000000000..5d23ad16b --- /dev/null +++ b/techlibs/ice40/brams.txt @@ -0,0 +1,40 @@ +bram $__ICE40_RAM4K_M0 + init 0 + abits 8 + dbits 16 + groups 2 + ports 1 1 + wrmode 0 1 + enable 0 16 + transp 0 0 + clocks 2 3 + clkpol 2 3 +endbram + +bram $__ICE40_RAM4K_M123 + init 0 + abits 9 @M1 + dbits 8 @M1 + abits 10 @M2 + dbits 4 @M2 + abits 11 @M3 + dbits 2 @M3 + groups 2 + ports 1 1 + wrmode 0 1 + enable 0 1 + transp 0 0 + clocks 2 3 + clkpol 2 3 +endbram + +match $__ICE40_RAM4K_M0 + min efficiency 10 + make_transp + or_next_if_better +endmatch + +match $__ICE40_RAM4K_M123 + min efficiency 10 + make_transp +endmatch diff --git a/techlibs/ice40/brams_map.v b/techlibs/ice40/brams_map.v new file mode 100644 index 000000000..9dbc81e3e --- /dev/null +++ b/techlibs/ice40/brams_map.v @@ -0,0 +1,99 @@ + +module \$__ICE40_RAM4K_M0 (CLK2, CLK3, A1ADDR, A1DATA, B1ADDR, B1DATA, B1EN); + parameter [0:0] CLKPOL2 = 1; + parameter [0:0] CLKPOL3 = 1; + + input CLK2; + input CLK3; + + input [7:0] A1ADDR; + output [15:0] A1DATA; + + input [7:0] B1ADDR; + input [15:0] B1DATA; + input [15:0] B1EN; + + wire [10:0] A1ADDR_11 = A1ADDR; + wire [10:0] B1ADDR_11 = B1ADDR; + + generate + case ({CLKPOL2, CLKPOL3}) + 2'b00: + SB_RAM40_4KNRNW #(.WRITE_MODE(0), .READ_MODE(0)) _TECHMAP_REPLACE_ ( + .RDATA(A1DATA), .RADDR(A1ADDR_11), .RCLK(CLK2), .RCLKE(1'b1), .RE(1'b1), + .WDATA(B1DATA), .WADDR(B1ADDR_11), .WMASK(B1EN), .WCLK(CLK3), .WCLKE(1'b1), .WE(|B1EN) + ); + 2'b01: + SB_RAM40_4KNR #(.WRITE_MODE(0), .READ_MODE(0)) _TECHMAP_REPLACE_ ( + .RDATA(A1DATA), .RADDR(A1ADDR_11), .RCLK(CLK2), .RCLKE(1'b1), .RE(1'b1), + .WDATA(B1DATA), .WADDR(B1ADDR_11), .WMASK(B1EN), .WCLK(CLK3), .WCLKE(1'b1), .WE(|B1EN) + ); + 2'b10: + SB_RAM40_4KNW #(.WRITE_MODE(0), .READ_MODE(0)) _TECHMAP_REPLACE_ ( + .RDATA(A1DATA), .RADDR(A1ADDR_11), .RCLK(CLK2), .RCLKE(1'b1), .RE(1'b1), + .WDATA(B1DATA), .WADDR(B1ADDR_11), .WMASK(B1EN), .WCLK(CLK3), .WCLKE(1'b1), .WE(|B1EN) + ); + 2'b11: + SB_RAM40_4K #(.WRITE_MODE(0), .READ_MODE(0)) _TECHMAP_REPLACE_ ( + .RDATA(A1DATA), .RADDR(A1ADDR_11), .RCLK(CLK2), .RCLKE(1'b1), .RE(1'b1), + .WDATA(B1DATA), .WADDR(B1ADDR_11), .WMASK(B1EN), .WCLK(CLK3), .WCLKE(1'b1), .WE(|B1EN) + ); + endcase + endgenerate +endmodule + +module \$__ICE40_RAM4K_M123 (CLK2, CLK3, A1ADDR, A1DATA, B1ADDR, B1DATA, B1EN); + parameter CFG_ABITS = 9; + parameter CFG_DBITS = 8; + + parameter [0:0] CLKPOL2 = 1; + parameter [0:0] CLKPOL3 = 1; + + localparam MODE = + CFG_ABITS == 9 ? 1 : + CFG_ABITS == 10 ? 2 : + CFG_ABITS == 11 ? 3 : 'bx; + + input CLK2; + input CLK3; + + input [CFG_ABITS-1:0] A1ADDR; + output [CFG_DBITS-1:0] A1DATA; + + input [CFG_ABITS-1:0] B1ADDR; + input [CFG_DBITS-1:0] B1DATA; + input B1EN; + + wire [10:0] A1ADDR_11 = A1ADDR; + wire [10:0] B1ADDR_11 = B1ADDR; + + wire [15:0] A1DATA_16; + wire [15:0] B1DATA_16 = B1DATA; + assign A1DATA = A1DATA_16; + + generate + case ({CLKPOL2, CLKPOL3}) + 2'b00: + SB_RAM40_4KNRNW #(.WRITE_MODE(MODE), .READ_MODE(MODE)) _TECHMAP_REPLACE_ ( + .RDATA(A1DATA_16), .RADDR(A1ADDR_11), .RCLK(CLK2), .RCLKE(1'b1), .RE(1'b1), + .WDATA(B1DATA_16), .WADDR(B1ADDR_11), .WCLK(CLK3), .WCLKE(1'b1), .WE(B1EN) + ); + 2'b01: + SB_RAM40_4KNR #(.WRITE_MODE(MODE), .READ_MODE(MODE)) _TECHMAP_REPLACE_ ( + .RDATA(A1DATA_16), .RADDR(A1ADDR_11), .RCLK(CLK2), .RCLKE(1'b1), .RE(1'b1), + .WDATA(B1DATA_16), .WADDR(B1ADDR_11), .WCLK(CLK3), .WCLKE(1'b1), .WE(B1EN) + ); + 2'b10: + SB_RAM40_4RNW #(.WRITE_MODE(MODE), .READ_MODE(MODE)) _TECHMAP_REPLACE_ ( + .RDATA(A1DATA_16), .RADDR(A1ADDR_11), .RCLK(CLK2), .RCLKE(1'b1), .RE(1'b1), + .WDATA(B1DATA_16), .WADDR(B1ADDR_11), .WCLK(CLK3), .WCLKE(1'b1), .WE(B1EN) + ); + 2'b11: + SB_RAM40_4K #(.WRITE_MODE(MODE), .READ_MODE(MODE)) _TECHMAP_REPLACE_ ( + .RDATA(A1DATA_16), .RADDR(A1ADDR_11), .RCLK(CLK2), .RCLKE(1'b1), .RE(1'b1), + .WDATA(B1DATA_16), .WADDR(B1ADDR_11), .WCLK(CLK3), .WCLKE(1'b1), .WE(B1EN) + ); + endcase + endgenerate +endmodule + diff --git a/techlibs/ice40/synth_ice40.cc b/techlibs/ice40/synth_ice40.cc index dff12f8a9..bb0e5d4ad 100644 --- a/techlibs/ice40/synth_ice40.cc +++ b/techlibs/ice40/synth_ice40.cc @@ -52,6 +52,18 @@ struct SynthIce40Pass : public Pass { 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(" -flatten\n"); + log(" flatten design before synthesis\n"); + log("\n"); + log(" -retime\n"); + log(" run 'abc' with -dff option\n"); + log("\n"); + log(" -nocarry\n"); + log(" do not use SB_CARRY cells in output netlist\n"); + log("\n"); + log(" -nobram\n"); + log(" do not use SB_RAM40_4K* cells in output netlist\n"); + log("\n"); log("\n"); log("The following commands are executed by this synthesis command:\n"); log("\n"); @@ -59,14 +71,23 @@ struct SynthIce40Pass : public Pass { log(" read_verilog -lib +/ice40/cells_sim.v\n"); log(" hierarchy -check -top \n"); log("\n"); + log(" flatten: (only if -flatten)\n"); + log(" proc\n"); + log(" flatten\n"); + log("\n"); log(" coarse:\n"); log(" synth -run coarse\n"); log("\n"); + log(" bram: (skip if -nobram)\n"); + log(" memory_bram -rules +/ice40/brams.txt\n"); + log(" techmap -map +/ice40/brams_map.v\n"); + log("\n"); log(" fine:\n"); log(" opt -fast -mux_undef -undriven -fine\n"); log(" memory_map\n"); log(" opt -undriven -fine\n"); - log(" techmap -map +/techmap.v -map +/ice40/arith_map.v\n"); + log(" techmap -map +/techmap.v [-map +/ice40/arith_map.v]\n"); + log(" abc -dff (only if -retime)\n"); log(" opt -fast\n"); log("\n"); log(" map_ffs:\n"); @@ -96,6 +117,9 @@ struct SynthIce40Pass : public Pass { std::string top_opt = "-auto-top"; std::string run_from, run_to; bool nocarry = false; + bool nobram = false; + bool flatten = false; + bool retime = false; size_t argidx; for (argidx = 1; argidx < args.size(); argidx++) @@ -112,10 +136,22 @@ struct SynthIce40Pass : public Pass { run_to = args[argidx].substr(pos+1); continue; } + if (args[argidx] == "-flatten") { + flatten = true; + continue; + } + if (args[argidx] == "-retime") { + retime = true; + continue; + } if (args[argidx] == "-nocarry") { nocarry = true; continue; } + if (args[argidx] == "-nobram") { + nobram = true; + continue; + } break; } extra_args(args, argidx, design); @@ -134,11 +170,23 @@ struct SynthIce40Pass : public Pass { Pass::call(design, stringf("hierarchy -check %s", top_opt.c_str())); } + if (flatten && check_label(active, run_from, run_to, "flatten")) + { + Pass::call(design, "proc"); + Pass::call(design, "flatten"); + } + if (check_label(active, run_from, run_to, "coarse")) { Pass::call(design, "synth -run coarse"); } + if (!nobram && check_label(active, run_from, run_to, "bram")) + { + Pass::call(design, "memory_bram -rules +/ice40/brams.txt"); + Pass::call(design, "techmap -map +/ice40/brams_map.v"); + } + if (check_label(active, run_from, run_to, "fine")) { Pass::call(design, "opt -fast -mux_undef -undriven -fine"); @@ -148,6 +196,8 @@ struct SynthIce40Pass : public Pass { Pass::call(design, "techmap"); else Pass::call(design, "techmap -map +/techmap.v -map +/ice40/arith_map.v"); + if (retime) + Pass::call(design, "abc -dff"); Pass::call(design, "opt -fast"); } -- 2.30.2