2 * yosys -- Yosys Open SYnthesis Suite
4 * Copyright (C) 2012 Clifford Wolf <clifford@clifford.at>
6 * Permission to use, copy, modify, and/or distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
20 #include "kernel/yosys.h"
21 #include "kernel/sigtools.h"
27 PRIVATE_NAMESPACE_BEGIN
29 static void run_ice40_braminit(Module
*module
)
31 for (auto cell
: module
->selected_cells())
35 /* Only consider cells we're interested in */
36 if (cell
->type
!= "\\SB_RAM40_4K" &&
37 cell
->type
!= "\\SB_RAM40_4KNR" &&
38 cell
->type
!= "\\SB_RAM40_4KNW" &&
39 cell
->type
!= "\\SB_RAM40_4KNRNW")
41 if (!cell
->hasParam("\\INIT_FILE"))
43 std::string init_file
= cell
->getParam("\\INIT_FILE").decode_string();
44 cell
->unsetParam("\\INIT_FILE");
49 log("Processing %s : %s\n", RTLIL::id2cstr(cell
->name
), init_file
.c_str());
52 f
.open(init_file
.c_str());
54 log("Can not open file `%s`.\n", init_file
.c_str());
59 memset(mem
, 0x00, sizeof(mem
));
61 /* Process each line */
62 bool in_comment
= false;
67 std::string line
, token
;
68 std::getline(f
, line
);
70 for (int i
= 0; i
< GetSize(line
); i
++)
72 if (in_comment
&& line
.substr(i
, 2) == "*/") {
78 if (!in_comment
&& line
.substr(i
, 2) == "/*")
86 bool set_cursor
= false;
89 token
= next_token(line
, " \t\r\n");
90 if (token
.empty() || token
.substr(0, 2) == "//")
93 if (token
[0] == '@') {
94 token
= token
.substr(1);
98 const char *nptr
= token
.c_str();
100 value
= strtol(nptr
, &endptr
, 16);
101 if (!*nptr
|| *endptr
) {
102 log("Can not parse %s `%s` for %s.\n",
103 set_cursor
? "address" : "value",
111 else if (cursor
>= 0 && cursor
< 256)
112 mem
[cursor
++] = value
;
114 log("Attempt to initialize non existent address %d\n", cursor
);
119 const char *hex
= "0123456789ABCDEF";
120 for (int i
=0; i
<16; i
++) {
121 std::string val
= "";
122 for (int j
=15; j
>=0; j
--)
123 val
+= std::bitset
<16>(mem
[i
*16+j
]).to_string();
124 cell
->setParam("\\INIT_" + std::string(1, hex
[i
]), RTLIL::Const::from_string(val
));
129 struct Ice40BRAMInitPass
: public Pass
{
130 Ice40BRAMInitPass() : Pass("ice40_braminit", "iCE40: perform SB_RAM40_4K initialization from file") { }
131 void help() YS_OVERRIDE
133 // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
135 log(" ice40_braminit\n");
137 log("This command processes all SB_RAM40_4K blocks with a non-empty INIT_FILE\n");
138 log("parameter and converts it into the required INIT_x attributes\n");
141 void execute(std::vector
<std::string
> args
, RTLIL::Design
*design
) YS_OVERRIDE
143 log_header(design
, "Executing ICE40_BRAMINIT pass.\n");
146 for (argidx
= 1; argidx
< args
.size(); argidx
++) {
147 // if (args[argidx] == "-???") {
152 extra_args(args
, argidx
, design
);
154 for (auto module
: design
->selected_modules())
155 run_ice40_braminit(module
);
159 PRIVATE_NAMESPACE_END