374 if (cell->
type ==
"$_NOT_") {
375 f <<
stringf(
"%s" "assign ", indent.c_str());
385 if (cell->
type.
in(
"$_AND_",
"$_NAND_",
"$_OR_",
"$_NOR_",
"$_XOR_",
"$_XNOR_")) {
386 f <<
stringf(
"%s" "assign ", indent.c_str());
389 if (cell->
type.
in(
"$_NAND_",
"$_NOR_",
"$_XNOR_"))
393 if (cell->
type.
in(
"$_AND_",
"$_NAND_"))
395 if (cell->
type.
in(
"$_OR_",
"$_NOR_"))
397 if (cell->
type.
in(
"$_XOR_",
"$_XNOR_"))
402 if (cell->
type.
in(
"$_NAND_",
"$_NOR_",
"$_XNOR_"))
408 if (cell->
type ==
"$_MUX_") {
409 f <<
stringf(
"%s" "assign ", indent.c_str());
422 if (cell->
type.
in(
"$_AOI3_",
"$_OAI3_")) {
423 f <<
stringf(
"%s" "assign ", indent.c_str());
427 f <<
stringf(cell->
type ==
"$_AOI3_" ?
" & " :
" | ");
429 f <<
stringf(cell->
type ==
"$_AOI3_" ?
") |" :
") &");
437 if (cell->
type.
in(
"$_AOI4_",
"$_OAI4_")) {
438 f <<
stringf(
"%s" "assign ", indent.c_str());
442 f <<
stringf(cell->
type ==
"$_AOI4_" ?
" & " :
" | ");
444 f <<
stringf(cell->
type ==
"$_AOI4_" ?
") |" :
") &");
448 f <<
stringf(cell->
type ==
"$_AOI4_" ?
" & " :
" | ");
456 std::string reg_name =
cellname(cell);
459 if (!out_is_reg_wire)
460 f <<
stringf(
"%s" "reg %s;\n", indent.c_str(), reg_name.c_str());
463 f <<
stringf(
"%s" "always @(%sedge ", indent.c_str(), cell->
type[6] ==
'P' ?
"pos" :
"neg");
465 if (cell->
type[7] !=
'_') {
466 f <<
stringf(
" or %sedge ", cell->
type[7] ==
'P' ?
"pos" :
"neg");
471 if (cell->
type[7] !=
'_') {
472 f <<
stringf(
"%s" " if (%s", indent.c_str(), cell->
type[7] ==
'P' ?
"" :
"!");
475 f <<
stringf(
"%s" " %s <= %c;\n", indent.c_str(), reg_name.c_str(), cell->
type[8]);
476 f <<
stringf(
"%s" " else\n", indent.c_str());
479 f <<
stringf(
"%s" " %s <= ", indent.c_str(), reg_name.c_str());
483 if (!out_is_reg_wire) {
484 f <<
stringf(
"%s" "assign ", indent.c_str());
486 f <<
stringf(
" = %s;\n", reg_name.c_str());
494 char pol_c = cell->
type[8], pol_s = cell->
type[9], pol_r = cell->
type[10];
496 std::string reg_name =
cellname(cell);
499 if (!out_is_reg_wire)
500 f <<
stringf(
"%s" "reg %s;\n", indent.c_str(), reg_name.c_str());
503 f <<
stringf(
"%s" "always @(%sedge ", indent.c_str(), pol_c ==
'P' ?
"pos" :
"neg");
505 f <<
stringf(
" or %sedge ", pol_s ==
'P' ?
"pos" :
"neg");
507 f <<
stringf(
" or %sedge ", pol_r ==
'P' ?
"pos" :
"neg");
511 f <<
stringf(
"%s" " if (%s", indent.c_str(), pol_r ==
'P' ?
"" :
"!");
514 f <<
stringf(
"%s" " %s <= 0;\n", indent.c_str(), reg_name.c_str());
516 f <<
stringf(
"%s" " else if (%s", indent.c_str(), pol_s ==
'P' ?
"" :
"!");
519 f <<
stringf(
"%s" " %s <= 1;\n", indent.c_str(), reg_name.c_str());
521 f <<
stringf(
"%s" " else\n", indent.c_str());
522 f <<
stringf(
"%s" " %s <= ", indent.c_str(), reg_name.c_str());
526 if (!out_is_reg_wire) {
527 f <<
stringf(
"%s" "assign ", indent.c_str());
529 f <<
stringf(
" = %s;\n", reg_name.c_str());
535 #define HANDLE_UNIOP(_type, _operator) \
536 if (cell->type ==_type) { dump_cell_expr_uniop(f, indent, cell, _operator); return true; }
537 #define HANDLE_BINOP(_type, _operator) \
538 if (cell->type ==_type) { dump_cell_expr_binop(f, indent, cell, _operator); return true; }
583 if (cell->
type ==
"$mux")
585 f <<
stringf(
"%s" "assign ", indent.c_str());
598 if (cell->
type ==
"$pmux" || cell->
type ==
"$pmux_safe")
600 int width = cell->
parameters[
"\\WIDTH"].as_int();
602 std::string func_name =
cellname(cell);
604 f <<
stringf(
"%s" "function [%d:0] %s;\n", indent.c_str(), width-1, func_name.c_str());
605 f <<
stringf(
"%s" " input [%d:0] a;\n", indent.c_str(), width-1);
606 f <<
stringf(
"%s" " input [%d:0] b;\n", indent.c_str(), s_width*width-1);
607 f <<
stringf(
"%s" " input [%d:0] s;\n", indent.c_str(), s_width-1);
611 f <<
stringf(
"%s" " (* parallel_case *)\n", indent.c_str());
612 f <<
stringf(
"%s" " casez (s)", indent.c_str());
613 if (cell->
type !=
"$pmux_safe")
614 f <<
stringf(
noattr ?
" // synopsys parallel_case\n" :
"\n");
616 for (
int i = 0; i < s_width; i++)
618 f <<
stringf(
"%s" " %d'b", indent.c_str(), s_width);
620 for (
int j = s_width-1; j >= 0; j--)
621 f <<
stringf(
"%c", j == i ?
'1' : cell->
type ==
"$pmux_safe" ?
'0' :
'?');
624 f <<
stringf(
"%s" " %s = b[%d:%d];\n", indent.c_str(), func_name.c_str(), (i+1)*width-1, i*width);
627 f <<
stringf(
"%s" " default:\n", indent.c_str());
628 f <<
stringf(
"%s" " %s = a;\n", indent.c_str(), func_name.c_str());
630 f <<
stringf(
"%s" " endcase\n", indent.c_str());
631 f <<
stringf(
"%s" "endfunction\n", indent.c_str());
633 f <<
stringf(
"%s" "assign ", indent.c_str());
635 f <<
stringf(
" = %s(", func_name.c_str());
645 if (cell->
type ==
"$slice")
647 f <<
stringf(
"%s" "assign ", indent.c_str());
655 if (cell->
type ==
"$concat")
657 f <<
stringf(
"%s" "assign ", indent.c_str());
667 if (cell->
type ==
"$dff" || cell->
type ==
"$adff")
670 bool pol_clk, pol_arst =
false;
672 sig_clk = cell->
getPort(
"\\CLK");
673 pol_clk = cell->
parameters[
"\\CLK_POLARITY"].as_bool();
675 if (cell->
type ==
"$adff") {
676 sig_arst = cell->
getPort(
"\\ARST");
677 pol_arst = cell->
parameters[
"\\ARST_POLARITY"].as_bool();
681 std::string reg_name =
cellname(cell);
684 if (!out_is_reg_wire)
685 f <<
stringf(
"%s" "reg [%d:0] %s;\n", indent.c_str(), cell->
parameters[
"\\WIDTH"].as_int()-1, reg_name.c_str());
687 f <<
stringf(
"%s" "always @(%sedge ", indent.c_str(), pol_clk ?
"pos" :
"neg");
689 if (cell->
type ==
"$adff") {
690 f <<
stringf(
" or %sedge ", pol_arst ?
"pos" :
"neg");
695 if (cell->
type ==
"$adff") {
696 f <<
stringf(
"%s" " if (%s", indent.c_str(), pol_arst ?
"" :
"!");
699 f <<
stringf(
"%s" " %s <= ", indent.c_str(), reg_name.c_str());
702 f <<
stringf(
"%s" " else\n", indent.c_str());
705 f <<
stringf(
"%s" " %s <= ", indent.c_str(), reg_name.c_str());
709 if (!out_is_reg_wire) {
710 f <<
stringf(
"%s" "assign ", indent.c_str());
712 f <<
stringf(
" = %s;\n", reg_name.c_str());
std::string stringf(const char *fmt,...)
bool is_reg_wire(RTLIL::SigSpec sig, std::string ®_name)
std::string cellname(RTLIL::Cell *cell)
std::map< RTLIL::IdString, RTLIL::Const > parameters
bool in(T first, Args...rest)
void dump_sigspec(std::ostream &f, const RTLIL::SigSpec &sig)
const RTLIL::SigSpec & getPort(RTLIL::IdString portname) const
#define HANDLE_BINOP(_type, _operator)
std::string substr(size_t pos=0, size_t len=std::string::npos) const
void dump_cell_expr_port(std::ostream &f, RTLIL::Cell *cell, std::string port, bool gen_signed=true)
#define HANDLE_UNIOP(_type, _operator)
void dump_attributes(std::ostream &f, std::string indent, std::map< RTLIL::IdString, RTLIL::Const > &attributes, char term= '\n')
USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN bool noattr