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 * A very simple and straightforward frontend for the RTLIL text
21 * representation (as generated by the 'ilang' backend).
27 #include "frontends/ilang/ilang_frontend.h"
29 namespace ILANG_FRONTEND {
31 RTLIL::Design *current_design;
32 RTLIL::Module *current_module;
33 RTLIL::Wire *current_wire;
34 RTLIL::Memory *current_memory;
35 RTLIL::Cell *current_cell;
36 RTLIL::Process *current_process;
37 std::vector<std::vector<RTLIL::SwitchRule*>*> switch_stack;
38 std::vector<RTLIL::CaseRule*> case_stack;
39 dict<RTLIL::IdString, RTLIL::Const> attrbuf;
40 bool flag_nooverwrite, flag_overwrite, flag_lib;
41 bool delete_current_module;
43 using namespace ILANG_FRONTEND;
48 %define api.prefix {rtlil_frontend_ilang_yy}
50 /* The union is defined in the header, so we need to provide all the
51 * includes it requires
56 #include "frontends/ilang/ilang_frontend.h"
62 YOSYS_NAMESPACE_PREFIX RTLIL::Const *data;
63 YOSYS_NAMESPACE_PREFIX RTLIL::SigSpec *sigspec;
64 std::vector<YOSYS_NAMESPACE_PREFIX RTLIL::SigSpec> *rsigspec;
67 %token <string> TOK_ID TOK_VALUE TOK_STRING
68 %token <integer> TOK_INT
69 %token TOK_AUTOIDX TOK_MODULE TOK_WIRE TOK_WIDTH TOK_INPUT TOK_OUTPUT TOK_INOUT
70 %token TOK_CELL TOK_CONNECT TOK_SWITCH TOK_CASE TOK_ASSIGN TOK_SYNC
71 %token TOK_LOW TOK_HIGH TOK_POSEDGE TOK_NEGEDGE TOK_EDGE TOK_ALWAYS TOK_GLOBAL TOK_INIT
72 %token TOK_UPDATE TOK_PROCESS TOK_END TOK_INVALID TOK_EOL TOK_OFFSET
73 %token TOK_PARAMETER TOK_ATTRIBUTE TOK_MEMORY TOK_SIZE TOK_SIGNED TOK_REAL TOK_UPTO
75 %type <rsigspec> sigspec_list_reversed
76 %type <sigspec> sigspec sigspec_list
77 %type <integer> sync_type
89 if (attrbuf.size() != 0)
90 rtlil_frontend_ilang_yyerror("dangling attribute");
97 optional_eol TOK_EOL | /* empty */;
102 design autoidx_stmt |
106 TOK_MODULE TOK_ID EOL {
107 delete_current_module = false;
108 if (current_design->has($2)) {
109 RTLIL::Module *existing_mod = current_design->module($2);
110 if (!flag_overwrite && (flag_lib || (attrbuf.count("\\blackbox") && attrbuf.at("\\blackbox").as_bool()))) {
111 log("Ignoring blackbox re-definition of module %s.\n", $2);
112 delete_current_module = true;
113 } else if (!flag_nooverwrite && !flag_overwrite && !existing_mod->get_bool_attribute("\\blackbox")) {
114 rtlil_frontend_ilang_yyerror(stringf("ilang error: redefinition of module %s.", $2).c_str());
115 } else if (flag_nooverwrite) {
116 log("Ignoring re-definition of module %s.\n", $2);
117 delete_current_module = true;
119 log("Replacing existing%s module %s.\n", existing_mod->get_bool_attribute("\\blackbox") ? " blackbox" : "", $2);
120 current_design->remove(existing_mod);
123 current_module = new RTLIL::Module;
124 current_module->name = $2;
125 current_module->attributes = attrbuf;
126 if (!delete_current_module)
127 current_design->add(current_module);
130 } module_body TOK_END {
131 if (attrbuf.size() != 0)
132 rtlil_frontend_ilang_yyerror("dangling attribute");
133 current_module->fixup_ports();
134 if (delete_current_module)
135 delete current_module;
137 current_module->makeblackbox();
138 current_module = nullptr;
142 module_body module_stmt |
146 param_stmt | attr_stmt | wire_stmt | memory_stmt | cell_stmt | proc_stmt | conn_stmt;
149 TOK_PARAMETER TOK_ID EOL {
150 current_module->avail_parameters.insert($2);
155 TOK_ATTRIBUTE TOK_ID constant EOL {
162 TOK_AUTOIDX TOK_INT EOL {
163 autoidx = max(autoidx, $2);
168 current_wire = current_module->addWire("$__ilang_frontend_tmp__");
169 current_wire->attributes = attrbuf;
171 } wire_options TOK_ID EOL {
172 if (current_module->wires_.count($4) != 0)
173 rtlil_frontend_ilang_yyerror(stringf("ilang error: redefinition of wire %s.", $4).c_str());
174 current_module->rename(current_wire, $4);
179 wire_options TOK_WIDTH TOK_INT {
180 current_wire->width = $3;
182 wire_options TOK_UPTO {
183 current_wire->upto = true;
185 wire_options TOK_OFFSET TOK_INT {
186 current_wire->start_offset = $3;
188 wire_options TOK_INPUT TOK_INT {
189 current_wire->port_id = $3;
190 current_wire->port_input = true;
191 current_wire->port_output = false;
193 wire_options TOK_OUTPUT TOK_INT {
194 current_wire->port_id = $3;
195 current_wire->port_input = false;
196 current_wire->port_output = true;
198 wire_options TOK_INOUT TOK_INT {
199 current_wire->port_id = $3;
200 current_wire->port_input = true;
201 current_wire->port_output = true;
207 current_memory = new RTLIL::Memory;
208 current_memory->attributes = attrbuf;
210 } memory_options TOK_ID EOL {
211 if (current_module->memories.count($4) != 0)
212 rtlil_frontend_ilang_yyerror(stringf("ilang error: redefinition of memory %s.", $4).c_str());
213 current_memory->name = $4;
214 current_module->memories[$4] = current_memory;
219 memory_options TOK_WIDTH TOK_INT {
220 current_memory->width = $3;
222 memory_options TOK_SIZE TOK_INT {
223 current_memory->size = $3;
225 memory_options TOK_OFFSET TOK_INT {
226 current_memory->start_offset = $3;
231 TOK_CELL TOK_ID TOK_ID EOL {
232 if (current_module->cells_.count($3) != 0)
233 rtlil_frontend_ilang_yyerror(stringf("ilang error: redefinition of cell %s.", $3).c_str());
234 current_cell = current_module->addCell($3, $2);
235 current_cell->attributes = attrbuf;
239 } cell_body TOK_END EOL;
242 cell_body TOK_PARAMETER TOK_ID constant EOL {
243 current_cell->parameters[$3] = *$4;
247 cell_body TOK_PARAMETER TOK_SIGNED TOK_ID constant EOL {
248 current_cell->parameters[$4] = *$5;
249 current_cell->parameters[$4].flags |= RTLIL::CONST_FLAG_SIGNED;
253 cell_body TOK_PARAMETER TOK_REAL TOK_ID constant EOL {
254 current_cell->parameters[$4] = *$5;
255 current_cell->parameters[$4].flags |= RTLIL::CONST_FLAG_REAL;
259 cell_body TOK_CONNECT TOK_ID sigspec EOL {
260 if (current_cell->hasPort($3))
261 rtlil_frontend_ilang_yyerror(stringf("ilang error: redefinition of cell port %s.", $3).c_str());
262 current_cell->setPort($3, *$4);
269 TOK_PROCESS TOK_ID EOL {
270 if (current_module->processes.count($2) != 0)
271 rtlil_frontend_ilang_yyerror(stringf("ilang error: redefinition of process %s.", $2).c_str());
272 current_process = new RTLIL::Process;
273 current_process->name = $2;
274 current_process->attributes = attrbuf;
275 current_module->processes[$2] = current_process;
276 switch_stack.clear();
277 switch_stack.push_back(¤t_process->root_case.switches);
279 case_stack.push_back(¤t_process->root_case);
282 } case_body sync_list TOK_END EOL;
285 attr_list TOK_SWITCH sigspec EOL {
286 RTLIL::SwitchRule *rule = new RTLIL::SwitchRule;
288 rule->attributes = attrbuf;
289 switch_stack.back()->push_back(rule);
292 } switch_body TOK_END EOL;
299 switch_body TOK_CASE {
300 RTLIL::CaseRule *rule = new RTLIL::CaseRule;
301 switch_stack.back()->back()->cases.push_back(rule);
302 switch_stack.push_back(&rule->switches);
303 case_stack.push_back(rule);
304 } compare_list EOL case_body {
305 switch_stack.pop_back();
306 case_stack.pop_back();
312 case_stack.back()->compare.push_back(*$1);
315 compare_list ',' sigspec {
316 case_stack.back()->compare.push_back(*$3);
322 case_body switch_stmt |
323 case_body assign_stmt |
327 TOK_ASSIGN sigspec sigspec EOL {
328 case_stack.back()->actions.push_back(RTLIL::SigSig(*$2, *$3));
334 sync_list TOK_SYNC sync_type sigspec EOL {
335 RTLIL::SyncRule *rule = new RTLIL::SyncRule;
336 rule->type = RTLIL::SyncType($3);
338 current_process->syncs.push_back(rule);
341 sync_list TOK_SYNC TOK_ALWAYS EOL {
342 RTLIL::SyncRule *rule = new RTLIL::SyncRule;
343 rule->type = RTLIL::SyncType::STa;
344 rule->signal = RTLIL::SigSpec();
345 current_process->syncs.push_back(rule);
347 sync_list TOK_SYNC TOK_GLOBAL EOL {
348 RTLIL::SyncRule *rule = new RTLIL::SyncRule;
349 rule->type = RTLIL::SyncType::STg;
350 rule->signal = RTLIL::SigSpec();
351 current_process->syncs.push_back(rule);
353 sync_list TOK_SYNC TOK_INIT EOL {
354 RTLIL::SyncRule *rule = new RTLIL::SyncRule;
355 rule->type = RTLIL::SyncType::STi;
356 rule->signal = RTLIL::SigSpec();
357 current_process->syncs.push_back(rule);
362 TOK_LOW { $$ = RTLIL::ST0; } |
363 TOK_HIGH { $$ = RTLIL::ST1; } |
364 TOK_POSEDGE { $$ = RTLIL::STp; } |
365 TOK_NEGEDGE { $$ = RTLIL::STn; } |
366 TOK_EDGE { $$ = RTLIL::STe; };
369 update_list TOK_UPDATE sigspec sigspec EOL {
370 current_process->syncs.back()->actions.push_back(RTLIL::SigSig(*$3, *$4));
379 int width = strtol($1, &ep, 10);
380 std::list<RTLIL::State> bits;
381 while (*(++ep) != 0) {
382 RTLIL::State bit = RTLIL::Sx;
384 case '0': bit = RTLIL::S0; break;
385 case '1': bit = RTLIL::S1; break;
386 case 'x': bit = RTLIL::Sx; break;
387 case 'z': bit = RTLIL::Sz; break;
388 case '-': bit = RTLIL::Sa; break;
389 case 'm': bit = RTLIL::Sm; break;
391 bits.push_front(bit);
393 if (bits.size() == 0)
394 bits.push_back(RTLIL::Sx);
395 while ((int)bits.size() < width) {
396 RTLIL::State bit = bits.back();
397 if (bit == RTLIL::S1)
401 while ((int)bits.size() > width)
403 $$ = new RTLIL::Const;
404 for (auto it = bits.begin(); it != bits.end(); it++)
405 $$->bits.push_back(*it);
409 $$ = new RTLIL::Const($1, 32);
412 $$ = new RTLIL::Const($1);
418 $$ = new RTLIL::SigSpec(*$1);
422 if (current_module->wires_.count($1) == 0)
423 rtlil_frontend_ilang_yyerror(stringf("ilang error: wire %s not found", $1).c_str());
424 $$ = new RTLIL::SigSpec(current_module->wires_[$1]);
427 sigspec '[' TOK_INT ']' {
428 $$ = new RTLIL::SigSpec($1->extract($3));
431 sigspec '[' TOK_INT ':' TOK_INT ']' {
432 $$ = new RTLIL::SigSpec($1->extract($5, $3 - $5 + 1));
435 '{' sigspec_list '}' {
439 sigspec_list_reversed:
440 sigspec_list_reversed sigspec {
445 $$ = new std::vector<RTLIL::SigSpec>;
448 sigspec_list: sigspec_list_reversed {
449 $$ = new RTLIL::SigSpec;
450 for (auto it = $1->rbegin(); it != $1->rend(); it++)
456 TOK_CONNECT sigspec sigspec EOL {
457 if (attrbuf.size() != 0)
458 rtlil_frontend_ilang_yyerror("dangling attribute");
459 current_module->connect(*$2, *$3);