From 9b0e7af6d7c84d9b252acbe0fbbf596c75fc1498 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 21 Mar 2019 20:52:29 +0100 Subject: [PATCH 1/5] Improve read_verilog debug output capabilities Signed-off-by: Clifford Wolf --- frontends/ast/ast.cc | 26 +++++++++++++++--------- frontends/ast/ast.h | 2 +- frontends/verilog/verilog_frontend.cc | 29 ++++++++++++++++++++++----- 3 files changed, 42 insertions(+), 15 deletions(-) diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index 5a1bae7a7..0442ea0db 100644 --- a/frontends/ast/ast.cc +++ b/frontends/ast/ast.cc @@ -45,7 +45,7 @@ namespace AST { // instantiate global variables (private API) namespace AST_INTERNAL { - bool flag_dump_ast1, flag_dump_ast2, flag_no_dump_ptr, flag_dump_vlog, flag_dump_rtlil, flag_nolatches, flag_nomeminit; + bool flag_dump_ast1, flag_dump_ast2, flag_no_dump_ptr, flag_dump_vlog1, flag_dump_vlog2, flag_dump_rtlil, flag_nolatches, flag_nomeminit; bool flag_nomem2reg, flag_mem2reg, flag_lib, flag_noopt, flag_icells, flag_autowire; AstNode *current_ast, *current_ast_mod; std::map current_scope; @@ -562,7 +562,8 @@ void AstNode::dumpVlog(FILE *f, std::string indent) const case AST_CONCAT: fprintf(f, "{"); - for (auto child : children) { + for (int i = GetSize(children)-1; i >= 0; i--) { + auto child = children[i]; if (!first) fprintf(f, ", "); child->dumpVlog(f, ""); @@ -926,23 +927,28 @@ static AstModule* process_module(AstNode *ast, bool defer, AstNode *original_ast ast_before_simplify = ast->clone(); if (flag_dump_ast1) { - log("Dumping Verilog AST before simplification:\n"); + log("Dumping AST before simplification:\n"); ast->dumpAst(NULL, " "); log("--- END OF AST DUMP ---\n"); } + if (flag_dump_vlog1) { + log("Dumping Verilog AST before simplification:\n"); + ast->dumpVlog(NULL, " "); + log("--- END OF AST DUMP ---\n"); + } if (!defer) { while (ast->simplify(!flag_noopt, false, false, 0, -1, false, false)) { } if (flag_dump_ast2) { - log("Dumping Verilog AST after simplification:\n"); + log("Dumping AST after simplification:\n"); ast->dumpAst(NULL, " "); log("--- END OF AST DUMP ---\n"); } - if (flag_dump_vlog) { - log("Dumping Verilog AST (as requested by dump_vlog option):\n"); + if (flag_dump_vlog2) { + log("Dumping Verilog AST after simplification:\n"); ast->dumpVlog(NULL, " "); log("--- END OF AST DUMP ---\n"); } @@ -1016,14 +1022,15 @@ static AstModule* process_module(AstNode *ast, bool defer, AstNode *original_ast } // create AstModule instances for all modules in the AST tree and add them to 'design' -void AST::process(RTLIL::Design *design, AstNode *ast, bool dump_ast1, bool dump_ast2, bool no_dump_ptr, bool dump_vlog, bool dump_rtlil, +void AST::process(RTLIL::Design *design, AstNode *ast, bool dump_ast1, bool dump_ast2, bool no_dump_ptr, bool dump_vlog1, bool dump_vlog2, bool dump_rtlil, bool nolatches, bool nomeminit, bool nomem2reg, bool mem2reg, bool lib, bool noopt, bool icells, bool nooverwrite, bool overwrite, bool defer, bool autowire) { current_ast = ast; flag_dump_ast1 = dump_ast1; flag_dump_ast2 = dump_ast2; flag_no_dump_ptr = no_dump_ptr; - flag_dump_vlog = dump_vlog; + flag_dump_vlog1 = dump_vlog1; + flag_dump_vlog2 = dump_vlog2; flag_dump_rtlil = dump_rtlil; flag_nolatches = nolatches; flag_nomeminit = nomeminit; @@ -1357,7 +1364,8 @@ std::string AstModule::derive_common(RTLIL::Design *design, dict Date: Thu, 21 Mar 2019 22:20:16 +0100 Subject: [PATCH 2/5] Improve "read_verilog -dump_vlog[12]" handling of upto ranges Signed-off-by: Clifford Wolf --- frontends/ast/ast.cc | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index 0442ea0db..d48996167 100644 --- a/frontends/ast/ast.cc +++ b/frontends/ast/ast.cc @@ -431,9 +431,12 @@ void AstNode::dumpVlog(FILE *f, std::string indent) const break; case AST_RANGE: - if (range_valid) - fprintf(f, "[%d:%d]", range_left, range_right); - else { + if (range_valid) { + if (range_swapped) + fprintf(f, "[%d:%d]", range_right, range_left); + else + fprintf(f, "[%d:%d]", range_left, range_right); + } else { for (auto child : children) { fprintf(f, "%c", first ? '[' : ':'); child->dumpVlog(f, ""); From 638be461c3a6d33aa294700249ee0bc27da69403 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 21 Mar 2019 22:19:17 +0100 Subject: [PATCH 3/5] Fix mem2reg handling of memories with upto data ports, fixes #888 Signed-off-by: Clifford Wolf --- frontends/ast/simplify.cc | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index d525c6b8a..63b71b800 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -138,9 +138,15 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, int mem_width, mem_size, addr_bits; node->meminfo(mem_width, mem_size, addr_bits); + int data_range_left = node->children[0]->range_left; + int data_range_right = node->children[0]->range_right; + + if (node->children[0]->range_swapped) + std::swap(data_range_left, data_range_right); + for (int i = 0; i < mem_size; i++) { AstNode *reg = new AstNode(AST_WIRE, new AstNode(AST_RANGE, - mkconst_int(mem_width-1, true), mkconst_int(0, true))); + mkconst_int(data_range_left, true), mkconst_int(data_range_right, true))); reg->str = stringf("%s[%d]", node->str.c_str(), i); reg->is_reg = true; reg->is_signed = node->is_signed; @@ -976,6 +982,9 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, int data_range_left = id2ast->children[0]->range_left; int data_range_right = id2ast->children[0]->range_right; + if (id2ast->children[0]->range_swapped) + std::swap(data_range_left, data_range_right); + std::stringstream sstr; sstr << "$mem2bits$" << str << "$" << filename << ":" << linenum << "$" << (autoidx++); std::string wire_id = sstr.str(); From 7cfd83c3415dd3d576539e00b91b6e283997fe52 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 22 Mar 2019 11:42:19 +0100 Subject: [PATCH 4/5] Trim init attributes when resizing FFs in "wreduce", fixes #887 Signed-off-by: Clifford Wolf --- passes/opt/wreduce.cc | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/passes/opt/wreduce.cc b/passes/opt/wreduce.cc index 1f7222e49..52245ce3e 100644 --- a/passes/opt/wreduce.cc +++ b/passes/opt/wreduce.cc @@ -54,6 +54,7 @@ struct WreduceWorker std::set work_queue_bits; pool keep_bits; dict init_bits; + pool remove_init_bits; WreduceWorker(WreduceConfig *config, Module *module) : config(config), module(module), mi(module) { } @@ -164,6 +165,7 @@ struct WreduceWorker { if (zero_ext && sig_d[i] == State::S0 && (initval[i] == State::S0 || initval[i] == State::Sx)) { module->connect(sig_q[i], State::S0); + remove_init_bits.insert(sig_q[i]); sig_d.remove(i); sig_q.remove(i); continue; @@ -171,6 +173,7 @@ struct WreduceWorker if (sign_ext && i > 0 && sig_d[i] == sig_d[i-1] && initval[i] == initval[i-1]) { module->connect(sig_q[i], sig_q[i-1]); + remove_init_bits.insert(sig_q[i]); sig_d.remove(i); sig_q.remove(i); continue; @@ -178,6 +181,7 @@ struct WreduceWorker auto info = mi.query(sig_q[i]); if (!info->is_output && GetSize(info->ports) == 1 && !keep_bits.count(mi.sigmap(sig_q[i]))) { + remove_init_bits.insert(sig_q[i]); sig_d.remove(i); sig_q.remove(i); zero_ext = false; @@ -387,13 +391,16 @@ struct WreduceWorker void run() { + // create a copy as mi.sigmap will be updated as we process the module + SigMap init_attr_sigmap = mi.sigmap; + for (auto w : module->wires()) { if (w->get_bool_attribute("\\keep")) for (auto bit : mi.sigmap(w)) keep_bits.insert(bit); if (w->attributes.count("\\init")) { Const initval = w->attributes.at("\\init"); - SigSpec initsig = mi.sigmap(w); + SigSpec initsig = init_attr_sigmap(w); int width = std::min(GetSize(initval), GetSize(initsig)); for (int i = 0; i < width; i++) init_bits[initsig[i]] = initval[i]; @@ -446,6 +453,24 @@ struct WreduceWorker module->connect(nw, SigSpec(w).extract(0, GetSize(nw))); module->swap_names(w, nw); } + + if (!remove_init_bits.empty()) { + for (auto w : module->wires()) { + if (w->attributes.count("\\init")) { + Const initval = w->attributes.at("\\init"); + Const new_initval(State::Sx, GetSize(w)); + SigSpec initsig = init_attr_sigmap(w); + int width = std::min(GetSize(initval), GetSize(initsig)); + for (int i = 0; i < width; i++) { + log_dump(initsig[i], remove_init_bits.count(initsig[i])); + if (!remove_init_bits.count(initsig[i])) + new_initval[i] = initval[i]; + } + w->attributes.at("\\init") = new_initval; + log_dump(w->name, initval, new_initval); + } + } + } } }; From 46f6a60d583d32289d70ed532c27e6cbc5ee47ed Mon Sep 17 00:00:00 2001 From: David Shah Date: Fri, 22 Mar 2019 13:57:17 +0000 Subject: [PATCH 5/5] xilinx: Add keep attribute where appropriate Signed-off-by: David Shah --- techlibs/xilinx/cells_xtra.sh | 13 ++++++----- techlibs/xilinx/cells_xtra.v | 43 +++++++++++++++++++---------------- 2 files changed, 31 insertions(+), 25 deletions(-) diff --git a/techlibs/xilinx/cells_xtra.sh b/techlibs/xilinx/cells_xtra.sh index 37c3e5480..56520ea10 100644 --- a/techlibs/xilinx/cells_xtra.sh +++ b/techlibs/xilinx/cells_xtra.sh @@ -7,6 +7,7 @@ function xtract_cell_decl() { for dir in $libdir/xeclib $libdir/retarget; do [ -f $dir/$1.v ] || continue + [ -z "$2" ] || echo $2 egrep '^\s*((end)?module|parameter|input|inout|output|(end)?function|(end)?task)' $dir/$1.v | sed -re '/UNPLACED/ d; /^\s*function/,/endfunction/ d; /^\s*task/,/endtask/ d; s,//.*,,; s/#?\(.*/(...);/; s/^(input|output|parameter)/ \1/; @@ -37,10 +38,10 @@ function xtract_cell_decl() xtract_cell_decl BUFMR xtract_cell_decl BUFMRCE xtract_cell_decl BUFR - xtract_cell_decl CAPTUREE2 + xtract_cell_decl CAPTUREE2 "(* keep *)" # xtract_cell_decl CARRY4 xtract_cell_decl CFGLUT5 - xtract_cell_decl DCIRESET + xtract_cell_decl DCIRESET "(* keep *)" xtract_cell_decl DNA_PORT xtract_cell_decl DSP48E1 xtract_cell_decl EFUSE_USR @@ -67,10 +68,10 @@ function xtract_cell_decl() xtract_cell_decl IBUFDS_GTE2 xtract_cell_decl IBUFDS_IBUFDISABLE xtract_cell_decl IBUFDS_INTERMDISABLE - xtract_cell_decl ICAPE2 + xtract_cell_decl ICAPE2 "(* keep *)" xtract_cell_decl IDDR xtract_cell_decl IDDR_2CLK - xtract_cell_decl IDELAYCTRL + xtract_cell_decl IDELAYCTRL "(* keep *)" xtract_cell_decl IDELAYE2 xtract_cell_decl IN_FIFO xtract_cell_decl IOBUF @@ -112,7 +113,7 @@ function xtract_cell_decl() xtract_cell_decl PHY_CONTROL xtract_cell_decl PLLE2_ADV xtract_cell_decl PLLE2_BASE - xtract_cell_decl PS7 + xtract_cell_decl PS7 "(* keep *)" xtract_cell_decl PULLDOWN xtract_cell_decl PULLUP xtract_cell_decl RAM128X1D @@ -136,7 +137,7 @@ function xtract_cell_decl() xtract_cell_decl ROM64X1 xtract_cell_decl SRL16E xtract_cell_decl SRLC32E - xtract_cell_decl STARTUPE2 + xtract_cell_decl STARTUPE2 "(* keep *)" xtract_cell_decl USR_ACCESSE2 xtract_cell_decl XADC } > cells_xtra.new diff --git a/techlibs/xilinx/cells_xtra.v b/techlibs/xilinx/cells_xtra.v index 995d62e18..497518d35 100644 --- a/techlibs/xilinx/cells_xtra.v +++ b/techlibs/xilinx/cells_xtra.v @@ -114,6 +114,7 @@ module BUFR (...); parameter SIM_DEVICE = "7SERIES"; endmodule +(* keep *) module CAPTUREE2 (...); parameter ONESHOT = "TRUE"; input CAP; @@ -130,6 +131,7 @@ module CFGLUT5 (...); input CDI, CE, CLK; endmodule +(* keep *) module DCIRESET (...); output LOCKED; input RST; @@ -2102,6 +2104,7 @@ module IBUFDS_INTERMDISABLE (...); input INTERMDISABLE; endmodule +(* keep *) module ICAPE2 (...); parameter [31:0] DEVICE_ID = 32'h04244093; parameter ICAP_WIDTH = "X32"; @@ -2149,6 +2152,7 @@ module IDDR_2CLK (...); input S; endmodule +(* keep *) module IDELAYCTRL (...); parameter SIM_DEVICE = "7SERIES"; output RDY; @@ -3057,6 +3061,7 @@ module PLLE2_BASE (...); input RST; endmodule +(* keep *) module PS7 (...); output DMA0DAVALID; output DMA0DRREADY; @@ -3688,6 +3693,17 @@ module PULLUP (...); output O; endmodule +module RAM128X1D (...); + parameter [127:0] INIT = 128'h00000000000000000000000000000000; + parameter [0:0] IS_WCLK_INVERTED = 1'b0; + output DPO, SPO; + input [6:0] A; + input [6:0] DPRA; + input D; + input WCLK; + input WE; +endmodule + module RAM128X1S (...); parameter [127:0] INIT = 128'h00000000000000000000000000000000; parameter [0:0] IS_WCLK_INVERTED = 1'b0; @@ -3695,25 +3711,6 @@ module RAM128X1S (...); input A0, A1, A2, A3, A4, A5, A6, D, WCLK, WE; endmodule -module RAM128X1D ( - output DPO, SPO, - input D, WCLK, WE, - input [6:0] A, DPRA -); - parameter [127:0] INIT = 128'bx; - parameter IS_WCLK_INVERTED = 0; -endmodule - -module RAM64X1D ( - output DPO, SPO, - input D, WCLK, WE, - input A0, A1, A2, A3, A4, A5, - input DPRA0, DPRA1, DPRA2, DPRA3, DPRA4, DPRA5 -); - parameter [63:0] INIT = 64'bx; - parameter IS_WCLK_INVERTED = 0; -endmodule - module RAM256X1S (...); parameter [255:0] INIT = 256'h0; parameter [0:0] IS_WCLK_INVERTED = 1'b0; @@ -3797,6 +3794,13 @@ module RAM64M (...); input WE; endmodule +module RAM64X1D (...); + parameter [63:0] INIT = 64'h0000000000000000; + parameter [0:0] IS_WCLK_INVERTED = 1'b0; + output DPO, SPO; + input A0, A1, A2, A3, A4, A5, D, DPRA0, DPRA1, DPRA2, DPRA3, DPRA4, DPRA5, WCLK, WE; +endmodule + module RAM64X1S (...); parameter [63:0] INIT = 64'h0000000000000000; parameter [0:0] IS_WCLK_INVERTED = 1'b0; @@ -3859,6 +3863,7 @@ module SRLC32E (...); input CE, CLK, D; endmodule +(* keep *) module STARTUPE2 (...); parameter PROG_USR = "FALSE"; parameter real SIM_CCLK_FREQ = 0.0;