mirror of https://github.com/YosysHQ/yosys.git
Merge branch 'master' of github.com:YosysHQ/yosys
This commit is contained in:
commit
d938ce7ab6
|
@ -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
|
||||
|
|
|
@ -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}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
bram $__ANLOGIC_DRAM16X4
|
||||
init 0
|
||||
abits 4
|
||||
dbits 2
|
||||
dbits 4
|
||||
groups 2
|
||||
ports 1 1
|
||||
wrmode 0 1
|
||||
|
|
|
@ -176,7 +176,7 @@ struct SynthAnlogicPass : public ScriptPass
|
|||
|
||||
if (check_label("map_luts"))
|
||||
{
|
||||
run("abc -lut 6");
|
||||
run("abc -lut 4:6");
|
||||
run("clean");
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue