Merge branch 'master' of github.com:YosysHQ/yosys

This commit is contained in:
Clifford Wolf 2018-12-23 15:44:19 +01:00
commit d938ce7ab6
7 changed files with 58 additions and 22 deletions

View File

@ -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 <filename>\n");
log(" tcl <filename> [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<std::string> args, RTLIL::Design *design) YS_OVERRIDE {
void execute(std::vector<std::string> 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<Tcl_Obj*> 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

View File

@ -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
@ -253,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).
@ -262,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} \\
@ -273,6 +274,27 @@ 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}, 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
{\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 +317,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 +370,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}

View File

@ -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

View File

@ -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);

View File

@ -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))

View File

@ -1,7 +1,7 @@
bram $__ANLOGIC_DRAM16X4
init 0
abits 4
dbits 2
dbits 4
groups 2
ports 1 1
wrmode 0 1

View File

@ -176,7 +176,7 @@ struct SynthAnlogicPass : public ScriptPass
if (check_label("map_luts"))
{
run("abc -lut 6");
run("abc -lut 4:6");
run("clean");
}