From 7854d5ba217788bb66881237feac8ba2748758b9 Mon Sep 17 00:00:00 2001 From: Icenowy Zheng Date: Tue, 18 Dec 2018 14:38:44 +0800 Subject: [PATCH 1/8] anlogic: fix dbits of Anlogic Eagle DRAM16X4 The dbits of DRAM16X4 is wrong set to 2, which leads to waste of DRAM bits. Fix the dbits number in the RAM configuration. Signed-off-by: Icenowy Zheng --- techlibs/anlogic/drams.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/techlibs/anlogic/drams.txt b/techlibs/anlogic/drams.txt index 2bff14a03..eb94775ae 100644 --- a/techlibs/anlogic/drams.txt +++ b/techlibs/anlogic/drams.txt @@ -1,7 +1,7 @@ bram $__ANLOGIC_DRAM16X4 init 0 abits 4 - dbits 2 + dbits 4 groups 2 ports 1 1 wrmode 0 1 From c9513c695a76124ef1155343e3c058767c418051 Mon Sep 17 00:00:00 2001 From: Icenowy Zheng Date: Wed, 19 Dec 2018 09:36:53 +0800 Subject: [PATCH 2/8] Anlogic: let LUT5/6 have more cost than LUT4- According to the datasheet of Anlogic Eagle FPGAs, The LUTs natively in an Anlogic FPGA is LUT4 (in MSLICEs) and "Enhanced LUT5" (in LSLICEs). An "Enhanced LUT5" can be divided into two LUT4s. So a LUT5 will cost around 2x resource of a LUT4, and a LUT6 will cost 2x resource of a LUT5. Change the -lut parameter passed to the abc command to pass this cost info to the ABC process. Signed-off-by: Icenowy Zheng --- techlibs/anlogic/synth_anlogic.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/techlibs/anlogic/synth_anlogic.cc b/techlibs/anlogic/synth_anlogic.cc index a4eafeddf..9c44599ea 100644 --- a/techlibs/anlogic/synth_anlogic.cc +++ b/techlibs/anlogic/synth_anlogic.cc @@ -176,7 +176,7 @@ struct SynthAnlogicPass : public ScriptPass if (check_label("map_luts")) { - run("abc -lut 6"); + run("abc -lut 4:6"); run("clean"); } From 3993ba71f7eb663fba73c0da4e35183b076168dd Mon Sep 17 00:00:00 2001 From: Icenowy Zheng Date: Wed, 19 Dec 2018 10:23:58 +0800 Subject: [PATCH 3/8] anlogic: fix Makefile.inc During the addition of DRAM inferring support, the installation of eagle_bb.v is accidentally removed. Fix this issue. Signed-off-by: Icenowy Zheng --- techlibs/anlogic/Makefile.inc | 1 + 1 file changed, 1 insertion(+) diff --git a/techlibs/anlogic/Makefile.inc b/techlibs/anlogic/Makefile.inc index 59be83fd0..f37b5e7e9 100644 --- a/techlibs/anlogic/Makefile.inc +++ b/techlibs/anlogic/Makefile.inc @@ -5,5 +5,6 @@ OBJS += techlibs/anlogic/anlogic_eqn.o $(eval $(call add_share_file,share/anlogic,techlibs/anlogic/cells_map.v)) $(eval $(call add_share_file,share/anlogic,techlibs/anlogic/arith_map.v)) $(eval $(call add_share_file,share/anlogic,techlibs/anlogic/cells_sim.v)) +$(eval $(call add_share_file,share/anlogic,techlibs/anlogic/eagle_bb.v)) $(eval $(call add_share_file,share/anlogic,techlibs/anlogic/drams.txt)) $(eval $(call add_share_file,share/anlogic,techlibs/anlogic/drams_map.v)) From a9ff81dd82d347b5ed867f142e61271aa40d85ee Mon Sep 17 00:00:00 2001 From: whitequark Date: Thu, 20 Dec 2018 04:37:28 +0000 Subject: [PATCH 4/8] manual: document $meminit cell and memory_* passes. --- manual/CHAPTER_CellLib.tex | 27 +++++++++++++++++++++------ manual/CHAPTER_Overview.tex | 4 ++-- 2 files changed, 23 insertions(+), 8 deletions(-) diff --git a/manual/CHAPTER_CellLib.tex b/manual/CHAPTER_CellLib.tex index 277e89328..6589bb2e7 100644 --- a/manual/CHAPTER_CellLib.tex +++ b/manual/CHAPTER_CellLib.tex @@ -211,14 +211,15 @@ Add information about {\tt \$sr} cells (set-reset flip-flops) and d-type latches \subsection{Memories} \label{sec:memcells} -Memories are either represented using RTLIL::Memory objects and {\tt \$memrd} and {\tt \$memwr} cells -or simply by using {\tt \$mem} cells. +Memories are either represented using RTLIL::Memory objects, {\tt \$memrd}, {\tt \$memwr}, and {\tt \$meminit} +cells, or by {\tt \$mem} cells alone. In the first alternative the RTLIL::Memory objects hold the general metadata for the memory (bit width, size in number of words, etc.) and for each port a {\tt \$memrd} (read port) or {\tt \$memwr} (write port) cell is created. Having individual cells for read and write ports has the advantage that they can be consolidated using resource sharing passes. In some cases this drastically reduces the number of required -ports on the memory cell. +ports on the memory cell. In this alternative, memory initialization data is represented by {\tt \$meminit} cells, +which allow delaying constant folding for initialization addresses and data until after the frontend finishes. The {\tt \$memrd} cells have a clock input \B{CLK}, an enable input \B{EN}, an address input \B{ADDR}, and a data output \B{DATA}. They also have the @@ -273,6 +274,15 @@ edge if this parameter is {\tt 1'b0}. The cell with the higher integer value in this parameter wins a write conflict. \end{itemize} +The {\tt \$meminit} cells have an address input \B{ADDR} and a data input \B{DATA}. Both of the inputs +must resolve to a constant for synthesis to succeed. If two {\tt \$meminit} cells have the same +\B{MEMID} parameter and \B{ADDR} input, the contents of that memory at that address is undefined. + +\begin{itemize} +\item \B{MEMID} \\ +The name of the RTLIL::Memory object that is associated with this initialization cell. +\end{itemize} + The HDL frontend models a memory using RTLIL::Memory objects and asynchronous {\tt \$memrd} and {\tt \$memwr} cells. The {\tt memory} pass (i.e.~its various sub-passes) migrates {\tt \$dff} cells into the {\tt \$memrd} and {\tt \$memwr} cells making them synchronous, then @@ -295,6 +305,9 @@ The number of address bits. \item \B{WIDTH} \\ The number of data bits per word. +\item \B{INIT} \\ +The initial memory contents. + \item \B{RD\_PORTS} \\ The number of read ports on this memory cell. @@ -345,9 +358,11 @@ This input is \B{WR\_PORTS}*\B{ABITS} bits wide, containing all address signals This input is \B{WR\_PORTS}*\B{WIDTH} bits wide, containing all data signals for the write ports. \end{itemize} -The {\tt techmap} pass can be used to manually map {\tt \$mem} cells to -specialized memory cells on the target architecture, such as block ram resources -on an FPGA. +The {\tt memory\_collect} pass can be used to convert discrete {\tt \$memrd}, {\tt \$memwr}, and {\tt \$meminit} cells +belonging to the same memory to a single {\tt \$mem} cell, whereas the {\tt memory\_unpack} pass performs the inverse operation. +The {\tt memory\_dff} pass can combine asynchronous memory ports that are fed by or feeding registers into synchronous memory ports. +The {\tt memory\_bram} pass can be used to recognize {\tt \$mem} cells that can be implemented with a block RAM resource on an FPGA. +The {\tt memory\_map} pass can be used to implement {\tt \$mem} cells as basic logic: word-wide DFFs and address decoders. \subsection{Finite State Machines} diff --git a/manual/CHAPTER_Overview.tex b/manual/CHAPTER_Overview.tex index 964875d57..2feb0f1cb 100644 --- a/manual/CHAPTER_Overview.tex +++ b/manual/CHAPTER_Overview.tex @@ -428,8 +428,8 @@ memory object has the following properties: All read accesses to the memory are transformed to {\tt \$memrd} cells and all write accesses to {\tt \$memwr} cells by the language frontend. These cells consist of independent read- and write-ports -to the memory. The \B{MEMID} parameter on these cells is used to link them together and to the -RTLIL::Memory object they belong to. +to the memory. Memory initialization is transformed to {\tt \$meminit} cells by the language frontend. +The \B{MEMID} parameter on these cells is used to link them together and to the RTLIL::Memory object they belong to. The rationale behind using separate cells for the individual ports versus creating a large multiport memory cell right in the language frontend is that From 2ca237e08665e4307da5bf40b7f3e17ca3e640db Mon Sep 17 00:00:00 2001 From: whitequark Date: Thu, 20 Dec 2018 07:29:46 +0000 Subject: [PATCH 5/8] tcl: add support for passing arguments to scripts. --- kernel/yosys.cc | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/kernel/yosys.cc b/kernel/yosys.cc index f002955ad..6884305d9 100644 --- a/kernel/yosys.cc +++ b/kernel/yosys.cc @@ -166,7 +166,7 @@ std::string vstringf(const char *fmt, va_list ap) std::string string; char *str = NULL; -#if defined(_WIN32 )|| defined(__CYGWIN__) +#if defined(_WIN32 )|| defined(__CYGWIN__) int sz = 64, rc; while (1) { va_list apc; @@ -637,8 +637,9 @@ extern Tcl_Interp *yosys_get_tcl_interp() struct TclPass : public Pass { TclPass() : Pass("tcl", "execute a TCL script file") { } void help() YS_OVERRIDE { + // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); - log(" tcl \n"); + log(" tcl [args]\n"); log("\n"); log("This command executes the tcl commands in the specified file.\n"); log("Use 'yosys cmd' to run the yosys command 'cmd' from tcl.\n"); @@ -648,14 +649,24 @@ struct TclPass : public Pass { log("'proc' and 'rename' are wrapped to tcl commands 'procs' and 'renames'\n"); log("in order to avoid a name collision with the built in commands.\n"); log("\n"); + log("If any arguments are specified, these arguments are provided to the script via\n"); + log("the standard $argc and $argv variables.\n"); + log("\n"); } - void execute(std::vector args, RTLIL::Design *design) YS_OVERRIDE { + void execute(std::vector args, RTLIL::Design *) YS_OVERRIDE { if (args.size() < 2) log_cmd_error("Missing script file.\n"); - if (args.size() > 2) - extra_args(args, 1, design, false); - if (Tcl_EvalFile(yosys_get_tcl_interp(), args[1].c_str()) != TCL_OK) - log_cmd_error("TCL interpreter returned an error: %s\n", Tcl_GetStringResult(yosys_get_tcl_interp())); + + std::vector script_args; + for (auto it = args.begin() + 2; it != args.end(); ++it) + script_args.push_back(Tcl_NewStringObj((*it).c_str(), (*it).size())); + + Tcl_Interp *interp = yosys_get_tcl_interp(); + Tcl_ObjSetVar2(interp, Tcl_NewStringObj("argc", 4), NULL, Tcl_NewIntObj(script_args.size()), 0); + Tcl_ObjSetVar2(interp, Tcl_NewStringObj("argv", 4), NULL, Tcl_NewListObj(script_args.size(), script_args.data()), 0); + Tcl_ObjSetVar2(interp, Tcl_NewStringObj("argv0", 5), NULL, Tcl_NewStringObj(args[1].c_str(), args[1].size()), 0); + if (Tcl_EvalFile(interp, args[1].c_str()) != TCL_OK) + log_cmd_error("TCL interpreter returned an error: %s\n", Tcl_GetStringResult(interp)); } } TclPass; #endif From c04908c99740e616cae454aa6a5d7a3dd13af2fa Mon Sep 17 00:00:00 2001 From: whitequark Date: Thu, 20 Dec 2018 07:59:40 +0000 Subject: [PATCH 6/8] manual: fix typos. --- manual/CHAPTER_CellLib.tex | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/manual/CHAPTER_CellLib.tex b/manual/CHAPTER_CellLib.tex index 6589bb2e7..65a79020f 100644 --- a/manual/CHAPTER_CellLib.tex +++ b/manual/CHAPTER_CellLib.tex @@ -254,7 +254,7 @@ enable bit for each data bit), an address input \B{ADDR} and a data input \begin{itemize} \item \B{MEMID} \\ -The name of the RTLIL::Memory object that is associated with this read port. +The name of the RTLIL::Memory object that is associated with this write port. \item \B{ABITS} \\ The number of address bits (width of the \B{ADDR} input port). @@ -263,7 +263,7 @@ The number of address bits (width of the \B{ADDR} input port). The number of data bits (width of the \B{DATA} output port). \item \B{CLK\_ENABLE} \\ -When this parameter is non-zero, the clock is used. Otherwise this read port is asynchronous and +When this parameter is non-zero, the clock is used. Otherwise this write port is asynchronous and the \B{CLK} input is not used. \item \B{CLK\_POLARITY} \\ From 0c318e7db513bed1844f594ae780f854ed08e18f Mon Sep 17 00:00:00 2001 From: whitequark Date: Fri, 21 Dec 2018 02:01:27 +0000 Subject: [PATCH 7/8] memory_collect: do not truncate 'x from \INIT. The semantics of an RTLIL constant that has less bits than its declared bit width is zero padding. Therefore, if the output of memory_collect will be used for simulation, truncating 'x from the end of \INIT will produce incorrect simulation results. --- passes/memory/memory_collect.cc | 3 --- 1 file changed, 3 deletions(-) diff --git a/passes/memory/memory_collect.cc b/passes/memory/memory_collect.cc index 70d98713c..369fcc84e 100644 --- a/passes/memory/memory_collect.cc +++ b/passes/memory/memory_collect.cc @@ -184,9 +184,6 @@ Cell *handle_memory(Module *module, RTLIL::Memory *memory) mem->parameters["\\OFFSET"] = Const(memory->start_offset); mem->parameters["\\SIZE"] = Const(memory->size); mem->parameters["\\ABITS"] = Const(addr_bits); - - while (GetSize(init_data) > 1 && init_data.bits.back() == State::Sx && init_data.bits[GetSize(init_data)-2] == State::Sx) - init_data.bits.pop_back(); mem->parameters["\\INIT"] = init_data; log_assert(sig_wr_clk.size() == wr_ports); From 182d84ad54cff315e7afb07f5353a477e4c410f4 Mon Sep 17 00:00:00 2001 From: whitequark Date: Fri, 21 Dec 2018 01:26:08 +0000 Subject: [PATCH 8/8] manual: make description of $meminit ports match reality. --- manual/CHAPTER_CellLib.tex | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/manual/CHAPTER_CellLib.tex b/manual/CHAPTER_CellLib.tex index 65a79020f..d40a600ed 100644 --- a/manual/CHAPTER_CellLib.tex +++ b/manual/CHAPTER_CellLib.tex @@ -274,13 +274,25 @@ edge if this parameter is {\tt 1'b0}. The cell with the higher integer value in this parameter wins a write conflict. \end{itemize} -The {\tt \$meminit} cells have an address input \B{ADDR} and a data input \B{DATA}. Both of the inputs -must resolve to a constant for synthesis to succeed. If two {\tt \$meminit} cells have the same -\B{MEMID} parameter and \B{ADDR} input, the contents of that memory at that address is undefined. +The {\tt \$meminit} cells have an address input \B{ADDR} and a data input \B{DATA}, with the width +of the \B{DATA} port equal to \B{WIDTH} parameter times \B{WORDS} parameter. Both of the inputs +must resolve to a constant for synthesis to succeed. \begin{itemize} \item \B{MEMID} \\ The name of the RTLIL::Memory object that is associated with this initialization cell. + +\item \B{ABITS} \\ +The number of address bits (width of the \B{ADDR} input port). + +\item \B{WIDTH} \\ +The number of data bits per memory location. + +\item \B{WORDS} \\ +The number of consecutive memory locations initialized by this cell. + +\item \B{PRIORITY} \\ +The cell with the higher integer value in this parameter wins an initialization conflict. \end{itemize} The HDL frontend models a memory using RTLIL::Memory objects and asynchronous