2 * yosys -- Yosys Open SYnthesis Suite
4 * Copyright (C) 2017 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"
22 #include "kernel/modtools.h"
25 PRIVATE_NAMESPACE_BEGIN
27 //get the list of cells hooked up to at least one bit of a given net
28 pool
<Cell
*> get_other_cells(const RTLIL::SigSpec
& port
, ModIndex
& index
, Cell
* src
)
33 pool
<ModIndex::PortInfo
> ports
= index
.query_ports(b
);
44 //return true if there is a full-width bus connection from cell a port ap to cell b port bp
45 //if other_conns_allowed is false, then we require a strict point to point connection (no other links)
47 const RTLIL::SigSpec
& sig
,
53 bool other_conns_allowed
= false)
57 pool
<ModIndex::PortInfo
> ports
= index
.query_ports(s
);
62 if( (x
.cell
== a
) && (x
.port
== ap
) )
64 else if( (x
.cell
== b
) && (x
.port
== bp
) )
66 else if(!other_conns_allowed
)
70 if( (!found_a
) || (!found_b
) )
77 //return true if the signal connects to one port only (nothing on the other end)
78 bool is_unconnected(const RTLIL::SigSpec
& port
, ModIndex
& index
)
82 pool
<ModIndex::PortInfo
> ports
= index
.query_ports(b
);
90 struct CounterExtraction
92 int width
; //counter width
93 RTLIL::Wire
* rwire
; //the register output
94 bool has_reset
; //true if we have a reset
95 bool has_ce
; //true if we have a clock enable
96 RTLIL::SigSpec rst
; //reset pin
97 bool rst_inverted
; //true if reset is active low
98 bool rst_to_max
; //true if we reset to max instead of 0
99 int count_value
; //value we count from
100 RTLIL::SigSpec ce
; //clock signal
101 RTLIL::SigSpec clk
; //clock enable, if any
102 RTLIL::SigSpec outsig
; //counter output signal
103 RTLIL::Cell
* count_mux
; //counter mux
104 RTLIL::Cell
* count_reg
; //counter register
105 RTLIL::Cell
* underflow_inv
; //inverter reduction for output-underflow detect
106 pool
<ModIndex::PortInfo
> pouts
; //Ports that take a parallel output from us
109 //attempt to extract a counter centered on the given adder cell
110 //For now we only support DOWN counters.
111 //TODO: up/down support
112 int counter_tryextract(
115 CounterExtraction
& extract
,
116 pool
<RTLIL::IdString
>& parallel_cells
,
119 SigMap
& sigmap
= index
.sigmap
;
121 //A counter with less than 2 bits makes no sense
122 //TODO: configurable min threshold
123 int a_width
= cell
->getParam("\\A_WIDTH").as_int();
124 extract
.width
= a_width
;
125 if( (a_width
< 2) || (a_width
> maxwidth
) )
128 //Second input must be a single bit
129 int b_width
= cell
->getParam("\\B_WIDTH").as_int();
133 //Both inputs must be unsigned, so don't extract anything with a signed input
134 bool a_sign
= cell
->getParam("\\A_SIGNED").as_bool();
135 bool b_sign
= cell
->getParam("\\B_SIGNED").as_bool();
139 //To be a counter, one input of the ALU must be a constant 1
140 //TODO: can A or B be swapped in synthesized RTL or is B always the 1?
141 const RTLIL::SigSpec b_port
= sigmap(cell
->getPort("\\B"));
142 if(!b_port
.is_fully_const() || (b_port
.as_int() != 1) )
145 //BI and CI must be constant 1 as well
146 const RTLIL::SigSpec bi_port
= sigmap(cell
->getPort("\\BI"));
147 if(!bi_port
.is_fully_const() || (bi_port
.as_int() != 1) )
149 const RTLIL::SigSpec ci_port
= sigmap(cell
->getPort("\\CI"));
150 if(!ci_port
.is_fully_const() || (ci_port
.as_int() != 1) )
153 //CO and X must be unconnected (exactly one connection to each port)
154 if(!is_unconnected(sigmap(cell
->getPort("\\CO")), index
))
156 if(!is_unconnected(sigmap(cell
->getPort("\\X")), index
))
159 //Y must have exactly one connection, and it has to be a $mux cell.
160 //We must have a direct bus connection from our Y to their A.
161 const RTLIL::SigSpec aluy
= sigmap(cell
->getPort("\\Y"));
162 pool
<Cell
*> y_loads
= get_other_cells(aluy
, index
, cell
);
163 if(y_loads
.size() != 1)
165 Cell
* count_mux
= *y_loads
.begin();
166 extract
.count_mux
= count_mux
;
167 if(count_mux
->type
!= "$mux")
169 if(!is_full_bus(aluy
, index
, cell
, "\\Y", count_mux
, "\\A"))
172 //B connection of the mux is our underflow value
173 const RTLIL::SigSpec underflow
= sigmap(count_mux
->getPort("\\B"));
174 if(!underflow
.is_fully_const())
176 extract
.count_value
= underflow
.as_int();
178 //S connection of the mux must come from an inverter (need not be the only load)
179 const RTLIL::SigSpec muxsel
= sigmap(count_mux
->getPort("\\S"));
180 extract
.outsig
= muxsel
;
181 pool
<Cell
*> muxsel_conns
= get_other_cells(muxsel
, index
, count_mux
);
182 Cell
* underflow_inv
= NULL
;
183 for(auto c
: muxsel_conns
)
185 if(c
->type
!= "$logic_not")
187 if(!is_full_bus(muxsel
, index
, c
, "\\Y", count_mux
, "\\S", true))
193 if(underflow_inv
== NULL
)
195 extract
.underflow_inv
= underflow_inv
;
197 //Y connection of the mux must have exactly one load, the counter's internal register, if there's no clock enable
198 //If we have a clock enable, Y drives the B input of a mux. A of that mux must come from our register
199 const RTLIL::SigSpec muxy
= sigmap(count_mux
->getPort("\\Y"));
200 pool
<Cell
*> muxy_loads
= get_other_cells(muxy
, index
, count_mux
);
201 if(muxy_loads
.size() != 1)
203 Cell
* muxload
= *muxy_loads
.begin();
204 Cell
* count_reg
= muxload
;
207 if(muxload
->type
== "$mux")
209 //This mux is probably a clock enable mux.
210 //Find our count register (should be our only load)
212 cey
= sigmap(cemux
->getPort("\\Y"));
213 pool
<Cell
*> cey_loads
= get_other_cells(cey
, index
, cemux
);
214 if(cey_loads
.size() != 1)
216 count_reg
= *cey_loads
.begin();
218 //Mux should have A driven by count Q, and B by muxy
219 //TODO: if A and B are swapped, CE polarity is inverted
220 if(sigmap(cemux
->getPort("\\B")) != muxy
)
222 if(sigmap(cemux
->getPort("\\A")) != sigmap(count_reg
->getPort("\\Q")))
224 if(sigmap(cemux
->getPort("\\Y")) != sigmap(count_reg
->getPort("\\D")))
227 //Select of the mux is our clock enable
228 extract
.has_ce
= true;
229 extract
.ce
= sigmap(cemux
->getPort("\\S"));
232 extract
.has_ce
= false;
234 extract
.count_reg
= count_reg
;
235 if(count_reg
->type
== "$dff")
236 extract
.has_reset
= false;
237 else if(count_reg
->type
== "$adff")
239 extract
.has_reset
= true;
241 //Check polarity of reset - we may have to add an inverter later on!
242 extract
.rst_inverted
= (count_reg
->getParam("\\ARST_POLARITY").as_int() != 1);
244 //Verify ARST_VALUE is zero or full scale
245 int rst_value
= count_reg
->getParam("\\ARST_VALUE").as_int();
247 extract
.rst_to_max
= false;
248 else if(rst_value
== extract
.count_value
)
249 extract
.rst_to_max
= true;
254 extract
.rst
= sigmap(count_reg
->getPort("\\ARST"));
256 //TODO: support synchronous reset
260 //Sanity check that we use the ALU output properly
263 if(!is_full_bus(muxy
, index
, count_mux
, "\\Y", cemux
, "\\B"))
265 if(!is_full_bus(cey
, index
, cemux
, "\\Y", count_reg
, "\\D"))
268 else if(!is_full_bus(muxy
, index
, count_mux
, "\\Y", count_reg
, "\\D"))
271 //TODO: Verify count_reg CLK_POLARITY is 1
273 //Register output must have exactly two loads, the inverter and ALU
274 //(unless we have a parallel output!)
275 //If we have a clock enable, 3 is OK
276 const RTLIL::SigSpec qport
= count_reg
->getPort("\\Q");
277 const RTLIL::SigSpec cnout
= sigmap(qport
);
278 pool
<Cell
*> cnout_loads
= get_other_cells(cnout
, index
, count_reg
);
279 unsigned int max_loads
= 2;
282 if(cnout_loads
.size() > max_loads
)
284 for(auto c
: cnout_loads
)
286 if(c
== underflow_inv
)
293 //If we specified a limited set of cells for parallel output, check that we only drive them
294 if(!parallel_cells
.empty())
296 //Make sure we're in the whitelist
297 if( parallel_cells
.find(c
->type
) == parallel_cells
.end())
301 //Figure out what port(s) are driven by it
302 //TODO: this can probably be done more efficiently w/o multiple iterations over our whole net?
305 pool
<ModIndex::PortInfo
> ports
= index
.query_ports(b
);
310 extract
.pouts
.insert(ModIndex::PortInfo(c
, x
.port
, 0));
315 if(!is_full_bus(cnout
, index
, count_reg
, "\\Q", underflow_inv
, "\\A", true))
317 if(!is_full_bus(cnout
, index
, count_reg
, "\\Q", cell
, "\\A", true))
320 //Look up the clock from the register
321 extract
.clk
= sigmap(count_reg
->getPort("\\CLK"));
323 //Register output net must have an INIT attribute equal to the count value
324 extract
.rwire
= cnout
.as_wire();
325 if(extract
.rwire
->attributes
.find("\\init") == extract
.rwire
->attributes
.end())
327 int rinit
= extract
.rwire
->attributes
["\\init"].as_int();
328 if(rinit
!= extract
.count_value
)
337 unsigned int& total_counters
,
338 pool
<Cell
*>& cells_to_remove
,
339 pool
<pair
<Cell
*, string
>>& cells_to_rename
,
340 pool
<RTLIL::IdString
>& parallel_cells
,
343 SigMap
& sigmap
= index
.sigmap
;
345 //Core of the counter must be an ALU
346 if (cell
->type
!= "$alu")
349 //A input is the count value. Check if it has COUNT_EXTRACT set.
350 //If it's not a wire, don't even try
351 auto port
= sigmap(cell
->getPort("\\A"));
354 RTLIL::Wire
* a_wire
= port
.as_wire();
355 bool force_extract
= false;
356 bool never_extract
= false;
357 string count_reg_src
= a_wire
->attributes
["\\src"].decode_string().c_str();
358 if(a_wire
->attributes
.find("\\COUNT_EXTRACT") != a_wire
->attributes
.end())
360 pool
<string
> sa
= a_wire
->get_strpool_attribute("\\COUNT_EXTRACT");
361 string extract_value
;
364 extract_value
= *sa
.begin();
365 log(" Signal %s declared at %s has COUNT_EXTRACT = %s\n",
367 count_reg_src
.c_str(),
368 extract_value
.c_str());
370 if(extract_value
== "FORCE")
371 force_extract
= true;
372 else if(extract_value
== "NO")
373 never_extract
= true;
374 else if(extract_value
== "AUTO")
377 log_error(" Illegal COUNT_EXTRACT value %s (must be one of FORCE, NO, AUTO)\n",
378 extract_value
.c_str());
382 //If we're explicitly told not to extract, don't infer a counter
386 //Attempt to extract a counter
387 CounterExtraction extract
;
388 int reason
= counter_tryextract(index
, cell
, extract
, parallel_cells
, maxwidth
);
390 //Nonzero code - we could not find a matchable counter.
391 //Do nothing, unless extraction was forced in which case give an error
394 static const char* reasons
[25]=
397 "counter is too large/small", //1
398 "counter does not count by one", //2
399 "counter uses signed math", //3
400 "counter does not count by one", //4
401 "ALU is not a subtractor", //5
402 "ALU is not a subtractor", //6
403 "ALU ports used outside counter", //7
404 "ALU ports used outside counter", //8
405 "ALU output used outside counter", //9
406 "ALU output is not a mux", //10
407 "ALU output is not full bus", //11
408 "Underflow value is not constant", //12
409 "No underflow detector found", //13
410 "Mux output is used outside counter", //14
411 "Counter reg is not DFF/ADFF", //15
412 "Counter input is not full bus", //16
413 "Count register is used outside counter, but not by an allowed cell", //17
414 "Register output is not full bus", //18
415 "Register output is not full bus", //19
416 "No init value found", //20
417 "Underflow value is not equal to init value", //21
418 "RESERVED, not implemented", //22, kept for compatibility but not used anymore
419 "Reset is not to zero or COUNT_TO", //23
420 "Clock enable configuration is unsupported" //24
426 "Counter extraction is set to FORCE on register %s, but a counter could not be inferred (%s)\n",
434 string countname
= string("$COUNTx$") + log_id(extract
.rwire
->name
.str());
436 //Wipe all of the old connections to the ALU
437 cell
->unsetPort("\\A");
438 cell
->unsetPort("\\B");
439 cell
->unsetPort("\\BI");
440 cell
->unsetPort("\\CI");
441 cell
->unsetPort("\\CO");
442 cell
->unsetPort("\\X");
443 cell
->unsetPort("\\Y");
444 cell
->unsetParam("\\A_SIGNED");
445 cell
->unsetParam("\\A_WIDTH");
446 cell
->unsetParam("\\B_SIGNED");
447 cell
->unsetParam("\\B_WIDTH");
448 cell
->unsetParam("\\Y_WIDTH");
450 //Change the cell type
451 cell
->type
= "$__COUNT_";
454 if(extract
.has_reset
)
456 //TODO: support other kinds of reset
457 cell
->setParam("\\RESET_MODE", RTLIL::Const("LEVEL"));
459 //If the reset is active low, infer an inverter ($__COUNT_ cells always have active high reset)
460 if(extract
.rst_inverted
)
462 auto realreset
= cell
->module
->addWire(NEW_ID
);
463 cell
->module
->addNot(NEW_ID
, extract
.rst
, RTLIL::SigSpec(realreset
));
464 cell
->setPort("\\RST", realreset
);
467 cell
->setPort("\\RST", extract
.rst
);
471 cell
->setParam("\\RESET_MODE", RTLIL::Const("RISING"));
472 cell
->setPort("\\RST", RTLIL::SigSpec(false));
475 //Hook up other stuff
476 //cell->setParam("\\CLKIN_DIVIDE", RTLIL::Const(1));
477 cell
->setParam("\\COUNT_TO", RTLIL::Const(extract
.count_value
));
478 cell
->setParam("\\WIDTH", RTLIL::Const(extract
.width
));
479 cell
->setPort("\\CLK", extract
.clk
);
480 cell
->setPort("\\OUT", extract
.outsig
);
482 //Hook up clock enable
485 cell
->setParam("\\HAS_CE", RTLIL::Const(1));
486 cell
->setPort("\\CE", extract
.ce
);
489 cell
->setParam("\\HAS_CE", RTLIL::Const(0));
491 //Hook up hard-wired ports (for now up/down are not supported), default to no parallel output
492 cell
->setParam("\\HAS_POUT", RTLIL::Const(0));
493 cell
->setParam("\\RESET_TO_MAX", RTLIL::Const(0));
494 cell
->setParam("\\DIRECTION", RTLIL::Const("DOWN"));
495 cell
->setPort("\\CE", RTLIL::Const(1));
496 cell
->setPort("\\UP", RTLIL::Const(0));
498 //Hook up any parallel outputs
499 for(auto load
: extract
.pouts
)
501 log(" Counter has parallel output to cell %s port %s\n", log_id(load
.cell
->name
), log_id(load
.port
));
503 //Find the wire hooked to the old port
504 auto sig
= load
.cell
->getPort(load
.port
);
506 //Connect it to our parallel output
507 //(this is OK to do more than once b/c they all go to the same place)
508 cell
->setPort("\\POUT", sig
);
509 cell
->setParam("\\HAS_POUT", RTLIL::Const(1));
512 //Delete the cells we've replaced (let opt_clean handle deleting the now-redundant wires)
513 cells_to_remove
.insert(extract
.count_mux
);
514 cells_to_remove
.insert(extract
.count_reg
);
515 cells_to_remove
.insert(extract
.underflow_inv
);
519 string reset_type
= "non-resettable";
520 if(extract
.has_reset
)
522 if(extract
.rst_inverted
)
523 reset_type
= "negative";
525 reset_type
= "positive";
527 //TODO: support other kind of reset
528 reset_type
+= " async resettable";
530 log(" Found %d-bit (%s) down counter %s (counting from %d) for register %s, declared at %s\n",
535 log_id(extract
.rwire
->name
),
536 count_reg_src
.c_str());
538 //Optimize the counter
539 //If we have no parallel output, and we have redundant bits, shrink us
540 if(extract
.pouts
.empty())
542 //TODO: Need to update this when we add support for counters with nonzero reset values
543 //to make sure the reset value fits in our bit space too
546 int newbits
= ceil(log2(extract
.count_value
));
547 if(extract
.width
!= newbits
)
549 cell
->setParam("\\WIDTH", RTLIL::Const(newbits
));
550 log(" Optimizing out %d unused high-order bits (new width is %d)\n",
551 extract
.width
- newbits
,
556 //Finally, rename the cell
557 cells_to_rename
.insert(pair
<Cell
*, string
>(cell
, countname
));
560 struct ExtractCounterPass
: public Pass
{
561 ExtractCounterPass() : Pass("extract_counter", "Extract GreenPak4 counter cells") { }
562 void help() YS_OVERRIDE
564 // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
566 log(" extract_counter [options] [selection]\n");
568 log("This pass converts non-resettable or async resettable down counters to\n");
569 log("counter cells. Use a target-specific 'techmap' map file to convert those cells\n");
570 log("to the actual target cells.\n");
572 log(" -maxwidth N\n");
573 log(" Only extract counters up to N bits wide\n");
575 log(" -pout X,Y,...\n");
576 log(" Only allow parallel output from the counter to the listed cell types\n");
577 log(" (if not specified, parallel outputs are not restricted)\n");
581 void execute(std::vector
<std::string
> args
, RTLIL::Design
*design
) YS_OVERRIDE
583 log_header(design
, "Executing EXTRACT_COUNTER pass (find counters in netlist).\n");
587 pool
<RTLIL::IdString
> parallel_cells
;
588 for (argidx
= 1; argidx
< args
.size(); argidx
++)
590 if (args
[argidx
] == "-pout")
592 if(argidx
+ 1 >= args
.size())
594 log_error("extract_counter -pout requires an argument\n");
598 std::string pouts
= args
[++argidx
];
600 for(size_t i
=0; i
<pouts
.length(); i
++)
604 parallel_cells
.insert(RTLIL::escape_id(tmp
));
610 parallel_cells
.insert(RTLIL::escape_id(tmp
));
614 if (args
[argidx
] == "-maxwidth" && argidx
+1 < args
.size())
616 maxwidth
= atoi(args
[++argidx
].c_str());
620 extra_args(args
, argidx
, design
);
622 //Extract all of the counters we could find
623 unsigned int total_counters
= 0;
624 for (auto module
: design
->selected_modules())
626 pool
<Cell
*> cells_to_remove
;
627 pool
<pair
<Cell
*, string
>> cells_to_rename
;
629 ModIndex
index(module
);
630 for (auto cell
: module
->selected_cells())
631 counter_worker(index
, cell
, total_counters
, cells_to_remove
, cells_to_rename
, parallel_cells
, maxwidth
);
633 for(auto cell
: cells_to_remove
)
635 //log("Removing cell %s\n", log_id(cell->name));
636 module
->remove(cell
);
639 for(auto cpair
: cells_to_rename
)
641 //log("Renaming cell %s to %s\n", log_id(cpair.first->name), cpair.second.c_str());
642 module
->rename(cpair
.first
, cpair
.second
);
647 log("Extracted %u counters\n", total_counters
);
649 } ExtractCounterPass
;
651 PRIVATE_NAMESPACE_END