From cd2902ab1fec57503320e32ba5620c6487f9cb85 Mon Sep 17 00:00:00 2001 From: Elms Date: Thu, 28 Feb 2019 16:22:24 -0800 Subject: ice40: use 2 bits for READ/WRITE MODE for SB_RAM map EBLIF output .param will only use necessary 2 bits Signed-off-by: Elms --- techlibs/ice40/brams_map.v | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'techlibs/ice40') diff --git a/techlibs/ice40/brams_map.v b/techlibs/ice40/brams_map.v index 19a61d73b..ad3bccd21 100644 --- a/techlibs/ice40/brams_map.v +++ b/techlibs/ice40/brams_map.v @@ -7,8 +7,8 @@ module \$__ICE40_RAM4K ( input [10:0] WADDR, input [15:0] MASK, WDATA ); - parameter integer READ_MODE = 0; - parameter integer WRITE_MODE = 0; + parameter [1:0] READ_MODE = 0; + parameter [1:0] WRITE_MODE = 0; parameter [0:0] NEGCLK_R = 0; parameter [0:0] NEGCLK_W = 0; -- cgit v1.2.3 From e71055cfe8f3d90e157174b1fd83a06487a0a6a2 Mon Sep 17 00:00:00 2001 From: Sylvain Munaut Date: Thu, 7 Mar 2019 23:48:10 +0100 Subject: ice40: Add ice40_braminit pass to allow initialization of BRAM from file This adds a INIT_FILE attribute to the SB_RAM40_4K blocks that will initialize content from a hex file. Same behavior is imlemented in the simulation model and in a new pass for actual synthesis Signed-off-by: Sylvain Munaut --- techlibs/ice40/Makefile.inc | 1 + techlibs/ice40/cells_sim.v | 88 +++++++++++++--------- techlibs/ice40/ice40_braminit.cc | 159 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 211 insertions(+), 37 deletions(-) create mode 100644 techlibs/ice40/ice40_braminit.cc (limited to 'techlibs/ice40') diff --git a/techlibs/ice40/Makefile.inc b/techlibs/ice40/Makefile.inc index 2750901c8..723b59d6f 100644 --- a/techlibs/ice40/Makefile.inc +++ b/techlibs/ice40/Makefile.inc @@ -1,5 +1,6 @@ OBJS += techlibs/ice40/synth_ice40.o +OBJS += techlibs/ice40/ice40_braminit.o OBJS += techlibs/ice40/ice40_ffssr.o OBJS += techlibs/ice40/ice40_ffinit.o OBJS += techlibs/ice40/ice40_opt.o diff --git a/techlibs/ice40/cells_sim.v b/techlibs/ice40/cells_sim.v index 2041693cc..bc36cdd14 100644 --- a/techlibs/ice40/cells_sim.v +++ b/techlibs/ice40/cells_sim.v @@ -326,6 +326,8 @@ module SB_RAM40_4K ( parameter INIT_E = 256'h0000000000000000000000000000000000000000000000000000000000000000; parameter INIT_F = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_FILE = ""; + `ifndef BLACKBOX wire [15:0] WMASK_I; wire [15:0] RMASK_I; @@ -408,43 +410,46 @@ module SB_RAM40_4K ( reg [15:0] memory [0:255]; initial begin - for (i=0; i<16; i=i+1) begin + if (INIT_FILE != "") + $readmemh(INIT_FILE, memory); + else + for (i=0; i<16; i=i+1) begin `ifdef YOSYS - memory[ 0*16 + i] <= INIT_0[16*i +: 16]; - memory[ 1*16 + i] <= INIT_1[16*i +: 16]; - memory[ 2*16 + i] <= INIT_2[16*i +: 16]; - memory[ 3*16 + i] <= INIT_3[16*i +: 16]; - memory[ 4*16 + i] <= INIT_4[16*i +: 16]; - memory[ 5*16 + i] <= INIT_5[16*i +: 16]; - memory[ 6*16 + i] <= INIT_6[16*i +: 16]; - memory[ 7*16 + i] <= INIT_7[16*i +: 16]; - memory[ 8*16 + i] <= INIT_8[16*i +: 16]; - memory[ 9*16 + i] <= INIT_9[16*i +: 16]; - memory[10*16 + i] <= INIT_A[16*i +: 16]; - memory[11*16 + i] <= INIT_B[16*i +: 16]; - memory[12*16 + i] <= INIT_C[16*i +: 16]; - memory[13*16 + i] <= INIT_D[16*i +: 16]; - memory[14*16 + i] <= INIT_E[16*i +: 16]; - memory[15*16 + i] <= INIT_F[16*i +: 16]; + memory[ 0*16 + i] <= INIT_0[16*i +: 16]; + memory[ 1*16 + i] <= INIT_1[16*i +: 16]; + memory[ 2*16 + i] <= INIT_2[16*i +: 16]; + memory[ 3*16 + i] <= INIT_3[16*i +: 16]; + memory[ 4*16 + i] <= INIT_4[16*i +: 16]; + memory[ 5*16 + i] <= INIT_5[16*i +: 16]; + memory[ 6*16 + i] <= INIT_6[16*i +: 16]; + memory[ 7*16 + i] <= INIT_7[16*i +: 16]; + memory[ 8*16 + i] <= INIT_8[16*i +: 16]; + memory[ 9*16 + i] <= INIT_9[16*i +: 16]; + memory[10*16 + i] <= INIT_A[16*i +: 16]; + memory[11*16 + i] <= INIT_B[16*i +: 16]; + memory[12*16 + i] <= INIT_C[16*i +: 16]; + memory[13*16 + i] <= INIT_D[16*i +: 16]; + memory[14*16 + i] <= INIT_E[16*i +: 16]; + memory[15*16 + i] <= INIT_F[16*i +: 16]; `else - memory[ 0*16 + i] = INIT_0[16*i +: 16]; - memory[ 1*16 + i] = INIT_1[16*i +: 16]; - memory[ 2*16 + i] = INIT_2[16*i +: 16]; - memory[ 3*16 + i] = INIT_3[16*i +: 16]; - memory[ 4*16 + i] = INIT_4[16*i +: 16]; - memory[ 5*16 + i] = INIT_5[16*i +: 16]; - memory[ 6*16 + i] = INIT_6[16*i +: 16]; - memory[ 7*16 + i] = INIT_7[16*i +: 16]; - memory[ 8*16 + i] = INIT_8[16*i +: 16]; - memory[ 9*16 + i] = INIT_9[16*i +: 16]; - memory[10*16 + i] = INIT_A[16*i +: 16]; - memory[11*16 + i] = INIT_B[16*i +: 16]; - memory[12*16 + i] = INIT_C[16*i +: 16]; - memory[13*16 + i] = INIT_D[16*i +: 16]; - memory[14*16 + i] = INIT_E[16*i +: 16]; - memory[15*16 + i] = INIT_F[16*i +: 16]; + memory[ 0*16 + i] = INIT_0[16*i +: 16]; + memory[ 1*16 + i] = INIT_1[16*i +: 16]; + memory[ 2*16 + i] = INIT_2[16*i +: 16]; + memory[ 3*16 + i] = INIT_3[16*i +: 16]; + memory[ 4*16 + i] = INIT_4[16*i +: 16]; + memory[ 5*16 + i] = INIT_5[16*i +: 16]; + memory[ 6*16 + i] = INIT_6[16*i +: 16]; + memory[ 7*16 + i] = INIT_7[16*i +: 16]; + memory[ 8*16 + i] = INIT_8[16*i +: 16]; + memory[ 9*16 + i] = INIT_9[16*i +: 16]; + memory[10*16 + i] = INIT_A[16*i +: 16]; + memory[11*16 + i] = INIT_B[16*i +: 16]; + memory[12*16 + i] = INIT_C[16*i +: 16]; + memory[13*16 + i] = INIT_D[16*i +: 16]; + memory[14*16 + i] = INIT_E[16*i +: 16]; + memory[15*16 + i] = INIT_F[16*i +: 16]; `endif - end + end end always @(posedge WCLK) begin @@ -504,6 +509,8 @@ module SB_RAM40_4KNR ( parameter INIT_E = 256'h0000000000000000000000000000000000000000000000000000000000000000; parameter INIT_F = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_FILE = ""; + SB_RAM40_4K #( .WRITE_MODE(WRITE_MODE), .READ_MODE (READ_MODE ), @@ -522,7 +529,8 @@ module SB_RAM40_4KNR ( .INIT_C (INIT_C ), .INIT_D (INIT_D ), .INIT_E (INIT_E ), - .INIT_F (INIT_F ) + .INIT_F (INIT_F ), + .INIT_FILE (INIT_FILE ) ) RAM ( .RDATA(RDATA), .RCLK (~RCLKN), @@ -566,6 +574,8 @@ module SB_RAM40_4KNW ( parameter INIT_E = 256'h0000000000000000000000000000000000000000000000000000000000000000; parameter INIT_F = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_FILE = ""; + SB_RAM40_4K #( .WRITE_MODE(WRITE_MODE), .READ_MODE (READ_MODE ), @@ -584,7 +594,8 @@ module SB_RAM40_4KNW ( .INIT_C (INIT_C ), .INIT_D (INIT_D ), .INIT_E (INIT_E ), - .INIT_F (INIT_F ) + .INIT_F (INIT_F ), + .INIT_FILE (INIT_FILE ) ) RAM ( .RDATA(RDATA), .RCLK (RCLK ), @@ -628,6 +639,8 @@ module SB_RAM40_4KNRNW ( parameter INIT_E = 256'h0000000000000000000000000000000000000000000000000000000000000000; parameter INIT_F = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_FILE = ""; + SB_RAM40_4K #( .WRITE_MODE(WRITE_MODE), .READ_MODE (READ_MODE ), @@ -646,7 +659,8 @@ module SB_RAM40_4KNRNW ( .INIT_C (INIT_C ), .INIT_D (INIT_D ), .INIT_E (INIT_E ), - .INIT_F (INIT_F ) + .INIT_F (INIT_F ), + .INIT_FILE (INIT_FILE ) ) RAM ( .RDATA(RDATA), .RCLK (~RCLKN), diff --git a/techlibs/ice40/ice40_braminit.cc b/techlibs/ice40/ice40_braminit.cc new file mode 100644 index 000000000..bf12f9148 --- /dev/null +++ b/techlibs/ice40/ice40_braminit.cc @@ -0,0 +1,159 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2012 Clifford Wolf + * + * 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" +#include +#include +#include + +USING_YOSYS_NAMESPACE +PRIVATE_NAMESPACE_BEGIN + +static void run_ice40_braminit(Module *module) +{ + for (auto cell : module->selected_cells()) + { + uint16_t mem[256]; + + /* Only consider cells we're interested in */ + if (cell->type != "\\SB_RAM40_4K" && + cell->type != "\\SB_RAM40_4KNR" && + cell->type != "\\SB_RAM40_4KNW" && + cell->type != "\\SB_RAM40_4KNRNW") + continue; + if (!cell->hasParam("\\INIT_FILE")) + continue; + std::string init_file = cell->getParam("\\INIT_FILE").decode_string(); + cell->unsetParam("\\INIT_FILE"); + if (init_file == "") + continue; + + /* Open file */ + log("Processing %s : %s\n", RTLIL::id2cstr(cell->name), init_file.c_str()); + + std::ifstream f; + f.open(init_file.c_str()); + if (f.fail()) { + log("Can not open file `%s`.\n", init_file.c_str()); + continue; + } + + /* Defaults to 0 */ + memset(mem, 0x00, sizeof(mem)); + + /* Process each line */ + bool in_comment = false; + int cursor = 0; + + while (!f.eof()) + { + std::string line, token; + std::getline(f, line); + + for (int i = 0; i < GetSize(line); i++) + { + if (in_comment && line.substr(i, 2) == "*/") { + line[i] = ' '; + line[i+1] = ' '; + in_comment = false; + continue; + } + if (!in_comment && line.substr(i, 2) == "/*") + in_comment = true; + if (in_comment) + line[i] = ' '; + } + + while (1) + { + bool set_cursor = false; + long value; + + token = next_token(line, " \t\r\n"); + if (token.empty() || token.substr(0, 2) == "//") + break; + + if (token[0] == '@') { + token = token.substr(1); + set_cursor = true; + } + + const char *nptr = token.c_str(); + char *endptr; + value = strtol(nptr, &endptr, 16); + if (!*nptr || *endptr) { + log("Can not parse %s `%s` for %s.\n", + set_cursor ? "address" : "value", + nptr, token.c_str() + ); + continue; + } + + if (set_cursor) + cursor = value; + else if (cursor >= 0 && cursor < 256) + mem[cursor++] = value; + else + log("Attempt to initialize non existent address %d\n", cursor); + } + } + + /* Set attributes */ + const char *hex = "0123456789ABCDEF"; + for (int i=0; i<16; i++) { + std::string val = ""; + for (int j=15; j>=0; j--) + val += std::bitset<16>(mem[i*16+j]).to_string(); + cell->setParam("\\INIT_" + std::string(1, hex[i]), RTLIL::Const::from_string(val)); + } + } +} + +struct Ice40BRAMInitPass : public Pass { + Ice40BRAMInitPass() : Pass("ice40_braminit", "iCE40: perform SB_RAM40_4K initialization from file") { } + void help() YS_OVERRIDE + { + // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| + log("\n"); + log(" ice40_braminit\n"); + log("\n"); + log("This command processes all SB_RAM40_4K blocks with a non-empty INIT_FILE\n"); + log("parameter and converts it inti the required INIT_x attributes\n"); + log("\n"); + } + void execute(std::vector args, RTLIL::Design *design) YS_OVERRIDE + { + log_header(design, "Executing ICE40_BRAMINIT pass.\n"); + + size_t argidx; + for (argidx = 1; argidx < args.size(); argidx++) { + // if (args[argidx] == "-???") { + // continue; + // } + break; + } + extra_args(args, argidx, design); + + for (auto module : design->selected_modules()) + run_ice40_braminit(module); + } +} Ice40BRAMInitPass; + +PRIVATE_NAMESPACE_END -- cgit v1.2.3 From 5b6f59103374413e9c64c4f228853ce06b03ce29 Mon Sep 17 00:00:00 2001 From: Sylvain Munaut Date: Fri, 8 Mar 2019 00:11:17 +0100 Subject: ice40: Run ice40_braminit pass by default Signed-off-by: Sylvain Munaut --- techlibs/ice40/synth_ice40.cc | 1 + 1 file changed, 1 insertion(+) (limited to 'techlibs/ice40') diff --git a/techlibs/ice40/synth_ice40.cc b/techlibs/ice40/synth_ice40.cc index 34501b335..8899bfcc4 100644 --- a/techlibs/ice40/synth_ice40.cc +++ b/techlibs/ice40/synth_ice40.cc @@ -257,6 +257,7 @@ struct SynthIce40Pass : public ScriptPass { run("memory_bram -rules +/ice40/brams.txt"); run("techmap -map +/ice40/brams_map.v"); + run("ice40_braminit"); } if (check_label("map")) -- cgit v1.2.3 From ff4c2a14ae34eeb899c3cf0ca1109f0106b41679 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 9 Mar 2019 13:24:55 -0800 Subject: Fix typo in ice40_braminit help msg Signed-off-by: Clifford Wolf --- techlibs/ice40/ice40_braminit.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'techlibs/ice40') diff --git a/techlibs/ice40/ice40_braminit.cc b/techlibs/ice40/ice40_braminit.cc index bf12f9148..4fa6b0792 100644 --- a/techlibs/ice40/ice40_braminit.cc +++ b/techlibs/ice40/ice40_braminit.cc @@ -135,7 +135,7 @@ struct Ice40BRAMInitPass : public Pass { log(" ice40_braminit\n"); log("\n"); log("This command processes all SB_RAM40_4K blocks with a non-empty INIT_FILE\n"); - log("parameter and converts it inti the required INIT_x attributes\n"); + log("parameter and converts it into the required INIT_x attributes\n"); log("\n"); } void execute(std::vector args, RTLIL::Design *design) YS_OVERRIDE -- cgit v1.2.3 From 9284cf92b8dcb510a2a9511965e587e42944c543 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 12 Mar 2019 20:14:18 +0100 Subject: Remove ice40/cells_sim.v hack to avoid warning for blocking memory writes Signed-off-by: Clifford Wolf --- techlibs/ice40/cells_sim.v | 19 ------------------- 1 file changed, 19 deletions(-) (limited to 'techlibs/ice40') diff --git a/techlibs/ice40/cells_sim.v b/techlibs/ice40/cells_sim.v index bc36cdd14..62a28364b 100644 --- a/techlibs/ice40/cells_sim.v +++ b/techlibs/ice40/cells_sim.v @@ -414,24 +414,6 @@ module SB_RAM40_4K ( $readmemh(INIT_FILE, memory); else for (i=0; i<16; i=i+1) begin -`ifdef YOSYS - memory[ 0*16 + i] <= INIT_0[16*i +: 16]; - memory[ 1*16 + i] <= INIT_1[16*i +: 16]; - memory[ 2*16 + i] <= INIT_2[16*i +: 16]; - memory[ 3*16 + i] <= INIT_3[16*i +: 16]; - memory[ 4*16 + i] <= INIT_4[16*i +: 16]; - memory[ 5*16 + i] <= INIT_5[16*i +: 16]; - memory[ 6*16 + i] <= INIT_6[16*i +: 16]; - memory[ 7*16 + i] <= INIT_7[16*i +: 16]; - memory[ 8*16 + i] <= INIT_8[16*i +: 16]; - memory[ 9*16 + i] <= INIT_9[16*i +: 16]; - memory[10*16 + i] <= INIT_A[16*i +: 16]; - memory[11*16 + i] <= INIT_B[16*i +: 16]; - memory[12*16 + i] <= INIT_C[16*i +: 16]; - memory[13*16 + i] <= INIT_D[16*i +: 16]; - memory[14*16 + i] <= INIT_E[16*i +: 16]; - memory[15*16 + i] <= INIT_F[16*i +: 16]; -`else memory[ 0*16 + i] = INIT_0[16*i +: 16]; memory[ 1*16 + i] = INIT_1[16*i +: 16]; memory[ 2*16 + i] = INIT_2[16*i +: 16]; @@ -448,7 +430,6 @@ module SB_RAM40_4K ( memory[13*16 + i] = INIT_D[16*i +: 16]; memory[14*16 + i] = INIT_E[16*i +: 16]; memory[15*16 + i] = INIT_F[16*i +: 16]; -`endif end end -- cgit v1.2.3