From 04582f2fb79e08a4a8264add98b2080d329379db Mon Sep 17 00:00:00 2001 From: Charlotte Date: Wed, 28 Jun 2023 11:51:32 +1000 Subject: [PATCH] verilog_backend: emit sync `$print` cells with same triggers together Sort by PRIORITY, ensuring output order. --- backends/verilog/verilog_backend.cc | 124 +++++--- tests/fmt/always_full.v | 424 ++++++++++++++-------------- tests/fmt/always_full_tb.cc | 11 +- tests/fmt/always_full_tb.v | 6 +- tests/fmt/run-test.sh | 6 + 5 files changed, 297 insertions(+), 274 deletions(-) diff --git a/backends/verilog/verilog_backend.cc b/backends/verilog/verilog_backend.cc index 573fa6d5b..ca119427f 100644 --- a/backends/verilog/verilog_backend.cc +++ b/backends/verilog/verilog_backend.cc @@ -1006,6 +1006,41 @@ void dump_cell_expr_binop(std::ostream &f, std::string indent, RTLIL::Cell *cell f << stringf(";\n"); } +void dump_cell_expr_print(std::ostream &f, std::string indent, RTLIL::Cell *cell) +{ + Fmt fmt = {}; + fmt.parse_rtlil(cell); + std::vector args = fmt.emit_verilog(); + + f << stringf("%s" "$write(", indent.c_str()); + bool first = true; + for (auto &arg : args) { + if (first) { + first = false; + } else { + f << ", "; + } + switch (arg.type) { + case VerilogFmtArg::STRING: + dump_const(f, RTLIL::Const(arg.str)); + break; + case VerilogFmtArg::INTEGER: + f << (arg.signed_ ? "$signed(" : "$unsigned("); + dump_sigspec(f, arg.sig); + f << ")"; + break; + case VerilogFmtArg::TIME: + if (arg.realtime) + f << "$realtime"; + else + f << "$time"; + break; + default: log_abort(); + } + } + f << stringf(");\n"); +} + bool dump_cell_expr(std::ostream &f, std::string indent, RTLIL::Cell *cell) { if (cell->type == ID($_NOT_)) { @@ -1756,58 +1791,17 @@ bool dump_cell_expr(std::ostream &f, std::string indent, RTLIL::Cell *cell) if (cell->type == ID($print)) { - Fmt fmt = {}; - fmt.parse_rtlil(cell); - std::vector args = fmt.emit_verilog(); + // Sync $print cells are accumulated and handled in dump_module. + if (cell->getParam(ID::TRG_ENABLE).as_bool()) + return true; - if (cell->getParam(ID::TRG_ENABLE).as_bool()) { - f << stringf("%s" "always @(", indent.c_str()); - for (size_t i = 0; i < (size_t)cell->getParam(ID::TRG_WIDTH).as_int(); i++) { - if (i != 0) - f << " or "; - if (cell->getParam(ID::TRG_POLARITY)[i]) - f << "posedge "; - else - f << "negedge "; - dump_sigspec(f, cell->getPort(ID::TRG)[i]); - } - f << ")\n"; - } else { - f << stringf("%s" "always @*\n", indent.c_str()); - } + f << stringf("%s" "always @*\n", indent.c_str()); f << stringf("%s" " if (", indent.c_str()); dump_sigspec(f, cell->getPort(ID::EN)); f << stringf(")\n"); - f << stringf("%s" " $write(", indent.c_str()); - bool first = true; - for (auto &arg : args) { - if (first) { - first = false; - } else { - f << ", "; - } - switch (arg.type) { - case VerilogFmtArg::STRING: - dump_const(f, RTLIL::Const(arg.str)); - break; - case VerilogFmtArg::INTEGER: - f << (arg.signed_ ? "$signed(" : "$unsigned("); - dump_sigspec(f, arg.sig); - f << ")"; - break; - case VerilogFmtArg::TIME: - if (arg.realtime) - f << "$realtime"; - else - f << "$time"; - break; - default: log_abort(); - } - } - f << stringf(");\n"); - + dump_cell_expr_print(f, indent + " ", cell); return true; } @@ -1899,6 +1893,34 @@ void dump_cell(std::ostream &f, std::string indent, RTLIL::Cell *cell) } } +void dump_sync_print(std::ostream &f, std::string indent, const RTLIL::SigSpec &trg, const RTLIL::Const &polarity, std::vector &cells) +{ + f << stringf("%s" "always @(", indent.c_str()); + for (int i = 0; i < trg.size(); i++) { + if (i != 0) + f << " or "; + if (polarity[i]) + f << "posedge "; + else + f << "negedge "; + dump_sigspec(f, trg[i]); + } + f << ") begin\n"; + + std::sort(cells.begin(), cells.end(), [](const RTLIL::Cell *a, const RTLIL::Cell *b) { + return a->getParam(ID::PRIORITY).as_int() > b->getParam(ID::PRIORITY).as_int(); + }); + for (auto cell : cells) { + f << stringf("%s" " if (", indent.c_str()); + dump_sigspec(f, cell->getPort(ID::EN)); + f << stringf(")\n"); + + dump_cell_expr_print(f, indent + " ", cell); + } + + f << stringf("%s" "end\n", indent.c_str()); +} + void dump_conn(std::ostream &f, std::string indent, const RTLIL::SigSpec &left, const RTLIL::SigSpec &right) { if (simple_lhs) { @@ -2080,6 +2102,8 @@ void dump_process(std::ostream &f, std::string indent, RTLIL::Process *proc, boo void dump_module(std::ostream &f, std::string indent, RTLIL::Module *module) { + std::map, std::vector> sync_print_cells; + reg_wires.clear(); reset_auto_counter(module); active_module = module; @@ -2110,6 +2134,11 @@ void dump_module(std::ostream &f, std::string indent, RTLIL::Module *module) std::set> reg_bits; for (auto cell : module->cells()) { + if (cell->type == ID($print) && cell->getParam(ID::TRG_ENABLE).as_bool()) { + sync_print_cells[make_pair(cell->getPort(ID::TRG), cell->getParam(ID::TRG_POLARITY))].push_back(cell); + continue; + } + if (!RTLIL::builtin_ff_cell_types().count(cell->type) || !cell->hasPort(ID::Q) || cell->type.in(ID($ff), ID($_FF_))) continue; @@ -2165,6 +2194,9 @@ void dump_module(std::ostream &f, std::string indent, RTLIL::Module *module) for (auto cell : module->cells()) dump_cell(f, indent + " ", cell); + for (auto &it : sync_print_cells) + dump_sync_print(f, indent + " ", it.first.first, it.first.second, it.second); + for (auto it = module->processes.begin(); it != module->processes.end(); ++it) dump_process(f, indent + " ", it->second); diff --git a/tests/fmt/always_full.v b/tests/fmt/always_full.v index d573bed31..4d3df7a61 100644 --- a/tests/fmt/always_full.v +++ b/tests/fmt/always_full.v @@ -1,243 +1,235 @@ -module always_full(input clk, output reg fin); - - reg [7:0] counter = 0; +module always_full(input clk); always @(posedge clk) begin - counter <= counter + 1; + $display("==> small unsigned %%d"); + $display(":%d:", 16'haa); + $display(":%-d:", 16'haa); + $display(":%+d:", 16'haa); + $display(":%+-d:", 16'haa); + $display(":%0d:", 16'haa); + $display(":%-0d:", 16'haa); + $display(":%+0d:", 16'haa); + $display(":%+-0d:", 16'haa); + $display(":%20d:", 16'haa); + $display(":%-20d:", 16'haa); + $display(":%+20d:", 16'haa); + $display(":%+-20d:", 16'haa); + $display(":%020d:", 16'haa); + $display(":%-020d:", 16'haa); + $display(":%+020d:", 16'haa); + $display(":%+-020d:", 16'haa); - if (counter == 0) fin <= 0; + $display("==> big unsigned %%d"); + $display(":%d:", 16'haaaa); + $display(":%-d:", 16'haaaa); + $display(":%+d:", 16'haaaa); + $display(":%+-d:", 16'haaaa); + $display(":%0d:", 16'haaaa); + $display(":%-0d:", 16'haaaa); + $display(":%+0d:", 16'haaaa); + $display(":%+-0d:", 16'haaaa); + $display(":%20d:", 16'haaaa); + $display(":%-20d:", 16'haaaa); + $display(":%+20d:", 16'haaaa); + $display(":%+-20d:", 16'haaaa); + $display(":%020d:", 16'haaaa); + $display(":%-020d:", 16'haaaa); + $display(":%+020d:", 16'haaaa); + $display(":%+-020d:", 16'haaaa); - if (counter == 2) $display("==> small unsigned %%d"); - if (counter == 3) $display(":%d:", 16'haa); - if (counter == 4) $display(":%-d:", 16'haa); - if (counter == 5) $display(":%+d:", 16'haa); - if (counter == 6) $display(":%+-d:", 16'haa); - if (counter == 7) $display(":%0d:", 16'haa); - if (counter == 8) $display(":%-0d:", 16'haa); - if (counter == 9) $display(":%+0d:", 16'haa); - if (counter == 10) $display(":%+-0d:", 16'haa); - if (counter == 11) $display(":%20d:", 16'haa); - if (counter == 12) $display(":%-20d:", 16'haa); - if (counter == 13) $display(":%+20d:", 16'haa); - if (counter == 14) $display(":%+-20d:", 16'haa); - if (counter == 15) $display(":%020d:", 16'haa); - if (counter == 16) $display(":%-020d:", 16'haa); - if (counter == 17) $display(":%+020d:", 16'haa); - if (counter == 18) $display(":%+-020d:", 16'haa); + $display("==> small signed %%d"); + $display(":%d:", 16'shaa); + $display(":%-d:", 16'shaa); + $display(":%+d:", 16'shaa); + $display(":%+-d:", 16'shaa); + $display(":%0d:", 16'shaa); + $display(":%-0d:", 16'shaa); + $display(":%+0d:", 16'shaa); + $display(":%+-0d:", 16'shaa); + $display(":%20d:", 16'shaa); + $display(":%-20d:", 16'shaa); + $display(":%+20d:", 16'shaa); + $display(":%+-20d:", 16'shaa); + $display(":%020d:", 16'shaa); + $display(":%-020d:", 16'shaa); + $display(":%+020d:", 16'shaa); + $display(":%+-020d:", 16'shaa); - if (counter == 19) $display("==> big unsigned %%d"); - if (counter == 20) $display(":%d:", 16'haaaa); - if (counter == 21) $display(":%-d:", 16'haaaa); - if (counter == 22) $display(":%+d:", 16'haaaa); - if (counter == 23) $display(":%+-d:", 16'haaaa); - if (counter == 24) $display(":%0d:", 16'haaaa); - if (counter == 25) $display(":%-0d:", 16'haaaa); - if (counter == 26) $display(":%+0d:", 16'haaaa); - if (counter == 27) $display(":%+-0d:", 16'haaaa); - if (counter == 28) $display(":%20d:", 16'haaaa); - if (counter == 29) $display(":%-20d:", 16'haaaa); - if (counter == 30) $display(":%+20d:", 16'haaaa); - if (counter == 31) $display(":%+-20d:", 16'haaaa); - if (counter == 32) $display(":%020d:", 16'haaaa); - if (counter == 33) $display(":%-020d:", 16'haaaa); - if (counter == 34) $display(":%+020d:", 16'haaaa); - if (counter == 35) $display(":%+-020d:", 16'haaaa); + $display("==> big signed %%d"); + $display(":%d:", 16'shaaaa); + $display(":%-d:", 16'shaaaa); + $display(":%+d:", 16'shaaaa); + $display(":%+-d:", 16'shaaaa); + $display(":%0d:", 16'shaaaa); + $display(":%-0d:", 16'shaaaa); + $display(":%+0d:", 16'shaaaa); + $display(":%+-0d:", 16'shaaaa); + $display(":%20d:", 16'shaaaa); + $display(":%-20d:", 16'shaaaa); + $display(":%+20d:", 16'shaaaa); + $display(":%+-20d:", 16'shaaaa); + $display(":%020d:", 16'shaaaa); + $display(":%-020d:", 16'shaaaa); + $display(":%+020d:", 16'shaaaa); + $display(":%+-020d:", 16'shaaaa); - if (counter == 36) $display("==> small signed %%d"); - if (counter == 37) $display(":%d:", 16'shaa); - if (counter == 38) $display(":%-d:", 16'shaa); - if (counter == 39) $display(":%+d:", 16'shaa); - if (counter == 40) $display(":%+-d:", 16'shaa); - if (counter == 41) $display(":%0d:", 16'shaa); - if (counter == 42) $display(":%-0d:", 16'shaa); - if (counter == 43) $display(":%+0d:", 16'shaa); - if (counter == 44) $display(":%+-0d:", 16'shaa); - if (counter == 45) $display(":%20d:", 16'shaa); - if (counter == 46) $display(":%-20d:", 16'shaa); - if (counter == 47) $display(":%+20d:", 16'shaa); - if (counter == 48) $display(":%+-20d:", 16'shaa); - if (counter == 49) $display(":%020d:", 16'shaa); - if (counter == 50) $display(":%-020d:", 16'shaa); - if (counter == 51) $display(":%+020d:", 16'shaa); - if (counter == 52) $display(":%+-020d:", 16'shaa); + $display("==> small unsigned %%h"); + $display(":%h:", 16'haa); + $display(":%-h:", 16'haa); + $display(":%0h:", 16'haa); + $display(":%-0h:", 16'haa); + $display(":%20h:", 16'haa); + $display(":%-20h:", 16'haa); + $display(":%020h:", 16'haa); + $display(":%-020h:", 16'haa); - if (counter == 53) $display("==> big signed %%d"); - if (counter == 54) $display(":%d:", 16'shaaaa); - if (counter == 55) $display(":%-d:", 16'shaaaa); - if (counter == 56) $display(":%+d:", 16'shaaaa); - if (counter == 57) $display(":%+-d:", 16'shaaaa); - if (counter == 58) $display(":%0d:", 16'shaaaa); - if (counter == 59) $display(":%-0d:", 16'shaaaa); - if (counter == 60) $display(":%+0d:", 16'shaaaa); - if (counter == 61) $display(":%+-0d:", 16'shaaaa); - if (counter == 62) $display(":%20d:", 16'shaaaa); - if (counter == 63) $display(":%-20d:", 16'shaaaa); - if (counter == 64) $display(":%+20d:", 16'shaaaa); - if (counter == 65) $display(":%+-20d:", 16'shaaaa); - if (counter == 66) $display(":%020d:", 16'shaaaa); - if (counter == 67) $display(":%-020d:", 16'shaaaa); - if (counter == 68) $display(":%+020d:", 16'shaaaa); - if (counter == 69) $display(":%+-020d:", 16'shaaaa); + $display("==> big unsigned %%h"); + $display(":%h:", 16'haaaa); + $display(":%-h:", 16'haaaa); + $display(":%0h:", 16'haaaa); + $display(":%-0h:", 16'haaaa); + $display(":%20h:", 16'haaaa); + $display(":%-20h:", 16'haaaa); + $display(":%020h:", 16'haaaa); + $display(":%-020h:", 16'haaaa); - if (counter == 70) $display("==> small unsigned %%h"); - if (counter == 71) $display(":%h:", 16'haa); - if (counter == 72) $display(":%-h:", 16'haa); - if (counter == 73) $display(":%0h:", 16'haa); - if (counter == 74) $display(":%-0h:", 16'haa); - if (counter == 75) $display(":%20h:", 16'haa); - if (counter == 76) $display(":%-20h:", 16'haa); - if (counter == 77) $display(":%020h:", 16'haa); - if (counter == 78) $display(":%-020h:", 16'haa); + $display("==> small signed %%h"); + $display(":%h:", 16'shaa); + $display(":%-h:", 16'shaa); + $display(":%0h:", 16'shaa); + $display(":%-0h:", 16'shaa); + $display(":%20h:", 16'shaa); + $display(":%-20h:", 16'shaa); + $display(":%020h:", 16'shaa); + $display(":%-020h:", 16'shaa); - if (counter == 79) $display("==> big unsigned %%h"); - if (counter == 80) $display(":%h:", 16'haaaa); - if (counter == 81) $display(":%-h:", 16'haaaa); - if (counter == 82) $display(":%0h:", 16'haaaa); - if (counter == 83) $display(":%-0h:", 16'haaaa); - if (counter == 84) $display(":%20h:", 16'haaaa); - if (counter == 85) $display(":%-20h:", 16'haaaa); - if (counter == 86) $display(":%020h:", 16'haaaa); - if (counter == 87) $display(":%-020h:", 16'haaaa); + $display("==> big signed %%h"); + $display(":%h:", 16'shaaaa); + $display(":%-h:", 16'shaaaa); + $display(":%0h:", 16'shaaaa); + $display(":%-0h:", 16'shaaaa); + $display(":%20h:", 16'shaaaa); + $display(":%-20h:", 16'shaaaa); + $display(":%020h:", 16'shaaaa); + $display(":%-020h:", 16'shaaaa); - if (counter == 88) $display("==> small signed %%h"); - if (counter == 89) $display(":%h:", 16'shaa); - if (counter == 90) $display(":%-h:", 16'shaa); - if (counter == 91) $display(":%0h:", 16'shaa); - if (counter == 92) $display(":%-0h:", 16'shaa); - if (counter == 93) $display(":%20h:", 16'shaa); - if (counter == 94) $display(":%-20h:", 16'shaa); - if (counter == 95) $display(":%020h:", 16'shaa); - if (counter == 96) $display(":%-020h:", 16'shaa); + $display("==> small unsigned %%o"); + $display(":%o:", 16'haa); + $display(":%-o:", 16'haa); + $display(":%0o:", 16'haa); + $display(":%-0o:", 16'haa); + $display(":%20o:", 16'haa); + $display(":%-20o:", 16'haa); + $display(":%020o:", 16'haa); + $display(":%-020o:", 16'haa); - if (counter == 97) $display("==> big signed %%h"); - if (counter == 98) $display(":%h:", 16'shaaaa); - if (counter == 99) $display(":%-h:", 16'shaaaa); - if (counter == 100) $display(":%0h:", 16'shaaaa); - if (counter == 101) $display(":%-0h:", 16'shaaaa); - if (counter == 102) $display(":%20h:", 16'shaaaa); - if (counter == 103) $display(":%-20h:", 16'shaaaa); - if (counter == 104) $display(":%020h:", 16'shaaaa); - if (counter == 105) $display(":%-020h:", 16'shaaaa); + $display("==> big unsigned %%o"); + $display(":%o:", 16'haaaa); + $display(":%-o:", 16'haaaa); + $display(":%0o:", 16'haaaa); + $display(":%-0o:", 16'haaaa); + $display(":%20o:", 16'haaaa); + $display(":%-20o:", 16'haaaa); + $display(":%020o:", 16'haaaa); + $display(":%-020o:", 16'haaaa); - if (counter == 106) $display("==> small unsigned %%o"); - if (counter == 107) $display(":%o:", 16'haa); - if (counter == 108) $display(":%-o:", 16'haa); - if (counter == 109) $display(":%0o:", 16'haa); - if (counter == 110) $display(":%-0o:", 16'haa); - if (counter == 111) $display(":%20o:", 16'haa); - if (counter == 112) $display(":%-20o:", 16'haa); - if (counter == 113) $display(":%020o:", 16'haa); - if (counter == 114) $display(":%-020o:", 16'haa); + $display("==> small signed %%o"); + $display(":%o:", 16'shaa); + $display(":%-o:", 16'shaa); + $display(":%0o:", 16'shaa); + $display(":%-0o:", 16'shaa); + $display(":%20o:", 16'shaa); + $display(":%-20o:", 16'shaa); + $display(":%020o:", 16'shaa); + $display(":%-020o:", 16'shaa); - if (counter == 115) $display("==> big unsigned %%o"); - if (counter == 116) $display(":%o:", 16'haaaa); - if (counter == 117) $display(":%-o:", 16'haaaa); - if (counter == 118) $display(":%0o:", 16'haaaa); - if (counter == 119) $display(":%-0o:", 16'haaaa); - if (counter == 120) $display(":%20o:", 16'haaaa); - if (counter == 121) $display(":%-20o:", 16'haaaa); - if (counter == 122) $display(":%020o:", 16'haaaa); - if (counter == 123) $display(":%-020o:", 16'haaaa); + $display("==> big signed %%o"); + $display(":%o:", 16'shaaaa); + $display(":%-o:", 16'shaaaa); + $display(":%0o:", 16'shaaaa); + $display(":%-0o:", 16'shaaaa); + $display(":%20o:", 16'shaaaa); + $display(":%-20o:", 16'shaaaa); + $display(":%020o:", 16'shaaaa); + $display(":%-020o:", 16'shaaaa); - if (counter == 124) $display("==> small signed %%o"); - if (counter == 125) $display(":%o:", 16'shaa); - if (counter == 126) $display(":%-o:", 16'shaa); - if (counter == 127) $display(":%0o:", 16'shaa); - if (counter == 128) $display(":%-0o:", 16'shaa); - if (counter == 129) $display(":%20o:", 16'shaa); - if (counter == 130) $display(":%-20o:", 16'shaa); - if (counter == 131) $display(":%020o:", 16'shaa); - if (counter == 132) $display(":%-020o:", 16'shaa); + $display("==> small unsigned %%b"); + $display(":%b:", 16'haa); + $display(":%-b:", 16'haa); + $display(":%0b:", 16'haa); + $display(":%-0b:", 16'haa); + $display(":%20b:", 16'haa); + $display(":%-20b:", 16'haa); + $display(":%020b:", 16'haa); + $display(":%-020b:", 16'haa); - if (counter == 133) $display("==> big signed %%o"); - if (counter == 134) $display(":%o:", 16'shaaaa); - if (counter == 135) $display(":%-o:", 16'shaaaa); - if (counter == 136) $display(":%0o:", 16'shaaaa); - if (counter == 137) $display(":%-0o:", 16'shaaaa); - if (counter == 138) $display(":%20o:", 16'shaaaa); - if (counter == 139) $display(":%-20o:", 16'shaaaa); - if (counter == 140) $display(":%020o:", 16'shaaaa); - if (counter == 141) $display(":%-020o:", 16'shaaaa); + $display("==> big unsigned %%b"); + $display(":%b:", 16'haaaa); + $display(":%-b:", 16'haaaa); + $display(":%0b:", 16'haaaa); + $display(":%-0b:", 16'haaaa); + $display(":%20b:", 16'haaaa); + $display(":%-20b:", 16'haaaa); + $display(":%020b:", 16'haaaa); + $display(":%-020b:", 16'haaaa); - if (counter == 142) $display("==> small unsigned %%b"); - if (counter == 143) $display(":%b:", 16'haa); - if (counter == 144) $display(":%-b:", 16'haa); - if (counter == 145) $display(":%0b:", 16'haa); - if (counter == 146) $display(":%-0b:", 16'haa); - if (counter == 147) $display(":%20b:", 16'haa); - if (counter == 148) $display(":%-20b:", 16'haa); - if (counter == 149) $display(":%020b:", 16'haa); - if (counter == 150) $display(":%-020b:", 16'haa); + $display("==> small signed %%b"); + $display(":%b:", 16'shaa); + $display(":%-b:", 16'shaa); + $display(":%0b:", 16'shaa); + $display(":%-0b:", 16'shaa); + $display(":%20b:", 16'shaa); + $display(":%-20b:", 16'shaa); + $display(":%020b:", 16'shaa); + $display(":%-020b:", 16'shaa); - if (counter == 151) $display("==> big unsigned %%b"); - if (counter == 152) $display(":%b:", 16'haaaa); - if (counter == 153) $display(":%-b:", 16'haaaa); - if (counter == 154) $display(":%0b:", 16'haaaa); - if (counter == 155) $display(":%-0b:", 16'haaaa); - if (counter == 156) $display(":%20b:", 16'haaaa); - if (counter == 157) $display(":%-20b:", 16'haaaa); - if (counter == 158) $display(":%020b:", 16'haaaa); - if (counter == 159) $display(":%-020b:", 16'haaaa); + $display("==> big signed %%b"); + $display(":%b:", 16'shaaaa); + $display(":%-b:", 16'shaaaa); + $display(":%0b:", 16'shaaaa); + $display(":%-0b:", 16'shaaaa); + $display(":%20b:", 16'shaaaa); + $display(":%-20b:", 16'shaaaa); + $display(":%020b:", 16'shaaaa); + $display(":%-020b:", 16'shaaaa); - if (counter == 160) $display("==> small signed %%b"); - if (counter == 161) $display(":%b:", 16'shaa); - if (counter == 162) $display(":%-b:", 16'shaa); - if (counter == 163) $display(":%0b:", 16'shaa); - if (counter == 164) $display(":%-0b:", 16'shaa); - if (counter == 165) $display(":%20b:", 16'shaa); - if (counter == 166) $display(":%-20b:", 16'shaa); - if (counter == 167) $display(":%020b:", 16'shaa); - if (counter == 168) $display(":%-020b:", 16'shaa); + $display("==> time %%t"); + $display(":%t:", $time); + $display(":%-t:", $time); + $display(":%0t:", $time); + $display(":%-0t:", $time); + $display(":%10t:", $time); + $display(":%-10t:", $time); + $display(":%015t:", $time); + $display(":%-015t:", $time); - if (counter == 169) $display("==> big signed %%b"); - if (counter == 170) $display(":%b:", 16'shaaaa); - if (counter == 171) $display(":%-b:", 16'shaaaa); - if (counter == 172) $display(":%0b:", 16'shaaaa); - if (counter == 173) $display(":%-0b:", 16'shaaaa); - if (counter == 174) $display(":%20b:", 16'shaaaa); - if (counter == 175) $display(":%-20b:", 16'shaaaa); - if (counter == 176) $display(":%020b:", 16'shaaaa); - if (counter == 177) $display(":%-020b:", 16'shaaaa); + $display("===> %%s"); + $display(":%10s:", "foo"); + $display(":%010s:", "foo"); + $display(":%-10s:", "foo"); + $display(":%-010s:", "foo"); - if (counter == 178) $display("==> time %%t"); - if (counter == 179) $display(":%t:", $time); - if (counter == 180) $display(":%-t:", $time); - if (counter == 181) $display(":%0t:", $time); - if (counter == 182) $display(":%-0t:", $time); - if (counter == 183) $display(":%10t:", $time); - if (counter == 184) $display(":%-10t:", $time); - if (counter == 185) $display(":%015t:", $time); - if (counter == 186) $display(":%-015t:", $time); + $display("===> %%c"); + $display(":%10c:", "foo"); + $display(":%010c:", "foo"); + $display(":%-10c:", "foo"); + $display(":%-010c:", "foo"); - if (counter == 187) $display("===> %%s"); - if (counter == 188) $display(":%10s:", "foo"); - if (counter == 189) $display(":%010s:", "foo"); - if (counter == 190) $display(":%-10s:", "foo"); - if (counter == 191) $display(":%-010s:", "foo"); + $display("==> aliases"); + $display(":%x:", 16'shaa); + $display(":%X:", 16'shaa); + $display(":%H:", 16'shaa); + $display(":%O:", 16'shaa); + $display(":%B:", 16'shaa); - if (counter == 192) $display("===> %%c"); - if (counter == 193) $display(":%10c:", "foo"); - if (counter == 194) $display(":%010c:", "foo"); - if (counter == 195) $display(":%-10c:", "foo"); - if (counter == 196) $display(":%-010c:", "foo"); + $display("==> default base"); + $displayh(16'haa); + $displayo(16'haa); + $displayb(16'haa); - if (counter == 197) $display("==> aliases"); - if (counter == 198) $display(":%x:", 16'shaa); - if (counter == 199) $display(":%X:", 16'shaa); - if (counter == 200) $display(":%H:", 16'shaa); - if (counter == 201) $display(":%O:", 16'shaa); - if (counter == 202) $display(":%B:", 16'shaa); - - if (counter == 203) $display("==> default base"); - if (counter == 204) $displayh(16'haa); - if (counter == 205) $displayo(16'haa); - if (counter == 206) $displayb(16'haa); - - if (counter == 207) $display("==> write/format"); - if (counter == 208) $display("%d", 1, "%d", 1); - - if (counter == 209) fin <= 1; + $display("==> write/format"); + $display("%d", 1, "%d", 1); end diff --git a/tests/fmt/always_full_tb.cc b/tests/fmt/always_full_tb.cc index 8bf1022d3..bd98020de 100644 --- a/tests/fmt/always_full_tb.cc +++ b/tests/fmt/always_full_tb.cc @@ -4,12 +4,7 @@ int main() { cxxrtl_design::p_always__full uut; - - while (true) { - uut.p_clk.set(!uut.p_clk); - uut.step(); - - if (uut.p_fin.get()) - return 0; - } + uut.p_clk.set(!uut.p_clk); + uut.step(); + return 0; } diff --git a/tests/fmt/always_full_tb.v b/tests/fmt/always_full_tb.v index 1edd35b67..0c2599cc2 100644 --- a/tests/fmt/always_full_tb.v +++ b/tests/fmt/always_full_tb.v @@ -1,14 +1,12 @@ module always_full_tb; reg clk = 0; - wire fin; - always_full uut (.clk(clk), .fin(fin)); + always_full uut (.clk(clk)); always begin #1 clk <= ~clk; - - if (fin) $finish; + #1 $finish; end endmodule diff --git a/tests/fmt/run-test.sh b/tests/fmt/run-test.sh index 44759dbc1..ba5aea9f6 100644 --- a/tests/fmt/run-test.sh +++ b/tests/fmt/run-test.sh @@ -61,6 +61,12 @@ test_cxxrtl () { test_cxxrtl always_full test_cxxrtl always_comb +# Ensure Verilog backend preserves behaviour of always block with multiple $displays. +../../yosys -p "read_verilog always_full.v; prep; clean" -o yosys-always_full-1.v +iverilog -o iverilog-always_full-1 yosys-always_full-1.v always_full_tb.v +./iverilog-always_full-1 |grep -v '\$finish called' >iverilog-always_full-1.log +diff iverilog-always_full.log iverilog-always_full-1.log + ../../yosys -p "read_verilog display_lm.v" >yosys-display_lm.log ../../yosys -p "read_verilog display_lm.v; write_cxxrtl yosys-display_lm.cc" ${CC:-gcc} -std=c++11 -o yosys-display_lm_cc -I../.. display_lm_tb.cc -lstdc++