3
0
Fork 0
mirror of https://github.com/YosysHQ/yosys synced 2026-06-27 02:58:48 +00:00

Merge pull request #19 from YosysHQ/main

bump fork for version 0.40
This commit is contained in:
Eder Monteiro 2024-04-15 19:05:56 +00:00 committed by GitHub
commit 80d00e2f44
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
37 changed files with 889 additions and 467 deletions

View file

@ -2,9 +2,23 @@
List of major changes and improvements between releases
=======================================================
Yosys 0.39 .. Yosys 0.40-dev
Yosys 0.40 .. Yosys 0.41-dev
--------------------------
Yosys 0.39 .. Yosys 0.40
--------------------------
* New commands and options
- Added option "-vhdl2019" to "read" and "verific" pass.
* Various
- Major documentation overhaul.
- Added port statistics to "stat" command.
- Added new formatting features to cxxrtl backend.
* Verific support
- Added better support for VHDL constants import.
- Added support for VHDL 2009.
Yosys 0.38 .. Yosys 0.39
--------------------------
* New commands and options

View file

@ -10,6 +10,7 @@
# PATH (can use glob) USERNAME(S)
CODEOWNERS @nakengelhardt
passes/cmds/scratchpad.cc @nakengelhardt
frontends/rpc/ @whitequark
backends/cxxrtl/ @whitequark
@ -19,7 +20,7 @@ passes/opt/opt_lut.cc @whitequark
passes/techmap/abc9*.cc @eddiehung @Ravenslofty
backends/aiger/xaiger.cc @eddiehung
docs/ @KrystalDelusion
.github/workflows/*.yml @mmicko
## External Contributors
# Only users with write permission to the repository get review

View file

@ -142,7 +142,7 @@ LIBS += -lrt
endif
endif
YOSYS_VER := 0.39+149
YOSYS_VER := 0.40+7
# Note: We arrange for .gitcommit to contain the (short) commit hash in
# tarballs generated with git-archive(1) using .gitattributes. The git repo
@ -158,7 +158,7 @@ endif
OBJS = kernel/version_$(GIT_REV).o
bumpversion:
sed -i "/^YOSYS_VER := / s/+[0-9][0-9]*$$/+`git log --oneline 0033808.. | wc -l`/;" Makefile
sed -i "/^YOSYS_VER := / s/+[0-9][0-9]*$$/+`git log --oneline a1bb025.. | wc -l`/;" Makefile
# set 'ABCREV = default' to use abc/ as it is
#
@ -629,6 +629,7 @@ $(eval $(call add_include_file,kernel/sigtools.h))
$(eval $(call add_include_file,kernel/timinginfo.h))
$(eval $(call add_include_file,kernel/utils.h))
$(eval $(call add_include_file,kernel/yosys.h))
$(eval $(call add_include_file,kernel/yosys_common.h))
$(eval $(call add_include_file,kernel/yw.h))
$(eval $(call add_include_file,libs/ezsat/ezsat.h))
$(eval $(call add_include_file,libs/ezsat/ezminisat.h))
@ -984,16 +985,27 @@ docs/gen_images:
$(Q) $(MAKE) -C docs images
DOCS_GUIDELINE_FILES := GettingStarted CodingStyle
docs/guidelines:
$(Q) mkdir -p docs/source/temp
$(Q) cp -f $(addprefix guidelines/,$(DOCS_GUIDELINE_FILES)) docs/source/temp
docs/guidelines docs/source/generated:
$(Q) mkdir -p docs/source/generated
$(Q) cp -f $(addprefix guidelines/,$(DOCS_GUIDELINE_FILES)) docs/source/generated
# many of these will return an error which can be safely ignored, so we prefix
# the command with a '-'
DOCS_USAGE_PROGS := yosys yosys-config yosys-filterlib yosys-abc yosys-smtbmc yosys-witness
docs/usage: $(addprefix docs/source/temp/,$(DOCS_USAGE_PROGS))
docs/source/temp/%: docs/guidelines
-$(Q) ./$(PROGRAM_PREFIX)$* --help > $@ 2>&1
# some commands return an error and print the usage text to stderr
define DOC_USAGE_STDERR
docs/source/generated/$(1): $(PROGRAM_PREFIX)$(1) docs/source/generated
-$(Q) ./$$< --help 2> $$@
endef
DOCS_USAGE_STDERR := yosys-config yosys-filterlib yosys-abc
$(foreach usage,$(DOCS_USAGE_STDERR),$(eval $(call DOC_USAGE_STDERR,$(usage))))
# others print to stdout
define DOC_USAGE_STDOUT
docs/source/generated/$(1): $(PROGRAM_PREFIX)$(1) docs/source/generated
$(Q) ./$$< --help > $$@
endef
DOCS_USAGE_STDOUT := yosys yosys-smtbmc yosys-witness
$(foreach usage,$(DOCS_USAGE_STDOUT),$(eval $(call DOC_USAGE_STDOUT,$(usage))))
docs/usage: $(addprefix docs/source/generated/,$(DOCS_USAGE_STDOUT) $(DOCS_USAGE_STDERR))
docs/reqs:
$(Q) $(MAKE) -C docs reqs

View file

@ -2014,22 +2014,29 @@ void dump_sync_effect(std::ostream &f, std::string indent, const RTLIL::SigSpec
void dump_conn(std::ostream &f, std::string indent, const RTLIL::SigSpec &left, const RTLIL::SigSpec &right)
{
if (simple_lhs) {
bool all_chunks_wires = true;
for (auto &chunk : left.chunks())
if (chunk.is_wire() && reg_wires.count(chunk.wire->name))
all_chunks_wires = false;
if (!simple_lhs && all_chunks_wires) {
f << stringf("%s" "assign ", indent.c_str());
dump_sigspec(f, left);
f << stringf(" = ");
dump_sigspec(f, right);
f << stringf(";\n");
} else {
int offset = 0;
for (auto &chunk : left.chunks()) {
f << stringf("%s" "assign ", indent.c_str());
if (chunk.is_wire() && reg_wires.count(chunk.wire->name))
f << stringf("%s" "always%s\n%s ", indent.c_str(), systemverilog ? "_comb" : " @*", indent.c_str());
else
f << stringf("%s" "assign ", indent.c_str());
dump_sigspec(f, chunk);
f << stringf(" = ");
dump_sigspec(f, right.extract(offset, GetSize(chunk)));
f << stringf(";\n");
offset += GetSize(chunk);
}
} else {
f << stringf("%s" "assign ", indent.c_str());
dump_sigspec(f, left);
f << stringf(" = ");
dump_sigspec(f, right);
f << stringf(";\n");
}
}

2
docs/.gitignore vendored
View file

@ -1,6 +1,6 @@
/build/
/source/cmd
/source/temp
/source/generated
/source/_images/**/*.log
/source/_images/**/*.aux
/source/_images/**/*.pdf

View file

@ -48,6 +48,7 @@ help:
clean: clean-examples
rm -rf $(BUILDDIR)/*
rm -rf source/cmd util/__pycache__
rm -rf source/generated
$(MAKE) -C source/_images clean
.PHONY: html

View file

@ -11,7 +11,7 @@ The ``yosys-config`` tool (an auto-generated shell-script) can be used to query
compiler options and other information needed for building loadable modules for
Yosys. See :doc:`/yosys_internals/extending_yosys/extensions` for details.
.. literalinclude:: /temp/yosys-config
.. literalinclude:: /generated/yosys-config
:start-at: Usage
.. _sec:filterlib:
@ -25,7 +25,7 @@ The ``yosys-filterlib`` tool is a small utility that can be used to strip or
extract information from a Liberty file. This can be useful for removing
sensitive or proprietary information such as timing or other trade secrets.
.. literalinclude:: /temp/yosys-filterlib
.. literalinclude:: /generated/yosys-filterlib
:start-at: Usage
yosys-abc
@ -36,9 +36,8 @@ been accepted upstream. Not all versions of Yosys work with all versions of ABC.
So Yosys comes with its own yosys-abc to avoid compatibility issues between the
two.
.. literalinclude:: /temp/yosys-abc
.. literalinclude:: /generated/yosys-abc
:start-at: usage
:end-before: UC Berkeley
yosys-smtbmc
------------
@ -46,7 +45,7 @@ yosys-smtbmc
The ``yosys-smtbmc`` tool is a utility used by SBY for interacting with smt
solvers.
.. literalinclude:: /temp/yosys-smtbmc
.. literalinclude:: /generated/yosys-smtbmc
yosys-witness
-------------
@ -55,7 +54,7 @@ yosys-witness
This is used in SBY and SCY for producing traces in a consistent format
independent of the solver.
.. literalinclude:: /temp/yosys-witness
.. literalinclude:: /generated/yosys-witness
:start-at: Usage
.. note:: ``yosys-witness`` requires `click`_ Python package for use.

View file

@ -4,7 +4,7 @@
Command line reference
================================================================================
.. literalinclude:: /temp/yosys
.. literalinclude:: /generated/yosys
:start-at: Usage
.. toctree::

View file

@ -1,2 +1,3 @@
my_cmd.so
my_cmd.d
*.log

View file

@ -13,18 +13,18 @@ my_cmd.so: my_cmd.cc
$(YOSYS)-config --exec --cxx $(subst $(DATDIR),../../../../share,$(CXXFLAGS)) --ldflags -o my_cmd.so -shared my_cmd.cc --ldlibs
test0.log: my_cmd.so
$(YOSYS) -Ql test0.log_new -m ./my_cmd.so -p 'my_cmd foo bar' absval_ref.v
$(YOSYS) -QTl test0.log_new -m ./my_cmd.so -p 'my_cmd foo bar' -f verilog absval_ref.v
mv test0.log_new test0.log
test1.log: my_cmd.so
$(YOSYS) -Ql test1.log_new -m ./my_cmd.so -p 'clean; test1; dump' absval_ref.v
$(YOSYS) -QTl test1.log_new -m ./my_cmd.so -p 'clean; test1; dump' -f verilog absval_ref.v
mv test1.log_new test1.log
test1.dot: my_cmd.so
$(YOSYS) -m ./my_cmd.so -p 'test1; show -format dot -prefix test1'
test2.log: my_cmd.so
$(YOSYS) -Ql test2.log_new -m ./my_cmd.so -p 'hierarchy -top test; test2' sigmap_test.v
$(YOSYS) -QTl test2.log_new -m ./my_cmd.so -p 'hierarchy -top test; test2' -f verilog sigmap_test.v
mv test2.log_new test2.log
.PHONY: clean

View file

@ -619,6 +619,48 @@ Finite state machines
Add a brief description of the ``$fsm`` cell type.
Coarse arithmetics
~~~~~~~~~~~~~~~~~~~~~
The ``$macc`` cell type represents a generalized multiply and accumulate operation. The cell is purely combinational. It outputs the result of summing up a sequence of products and other injected summands.
.. code-block::
Y = 0 +- a0factor1 * a0factor2 +- a1factor1 * a1factor2 +- ...
+ B[0] + B[1] + ...
The A port consists of concatenated pairs of multiplier inputs ("factors").
A zero length factor2 acts as a constant 1, turning factor1 into a simple summand.
In this pseudocode, ``u(foo)`` means an unsigned int that's foo bits long.
.. code-block::
struct A {
u(CONFIG.mul_info[0].factor1_len) a0factor1;
u(CONFIG.mul_info[0].factor2_len) a0factor2;
u(CONFIG.mul_info[1].factor1_len) a1factor1;
u(CONFIG.mul_info[1].factor2_len) a1factor2;
...
};
The cell's ``CONFIG`` parameter determines the layout of cell port ``A``.
The CONFIG parameter carries the following information:
.. code-block::
struct CONFIG {
u4 num_bits;
struct mul_info {
bool is_signed;
bool is_subtract;
u(num_bits) factor1_len;
u(num_bits) factor2_len;
}[num_ports];
};
B is an array of concatenated 1-bit-wide unsigned integers to also be summed up.
Specify rules
~~~~~~~~~~~~~
@ -1152,4 +1194,4 @@ file via ABC using the abc pass.
.. todo:: Add information about ``$lut`` and ``$sop`` cells.
.. todo:: Add information about ``$alu``, ``$macc``, ``$fa``, and ``$lcu`` cells.
.. todo:: Add information about ``$alu``, ``$fa``, and ``$lcu`` cells.

View file

@ -14,6 +14,7 @@ ifneq ($(DISABLE_VERIFIC_VHDL),1)
$(Q) cp -r $(VERIFIC_DIR)/vhdl_packages/vdbs_1987/. share/verific.new/vhdl_vdbs_1987
$(Q) cp -r $(VERIFIC_DIR)/vhdl_packages/vdbs_1993/. share/verific.new/vhdl_vdbs_1993
$(Q) cp -r $(VERIFIC_DIR)/vhdl_packages/vdbs_2008/. share/verific.new/vhdl_vdbs_2008
$(Q) cp -r $(VERIFIC_DIR)/vhdl_packages/vdbs_2019/. share/verific.new/vhdl_vdbs_2019
endif
$(Q) chmod -R a+rX share/verific.new
$(Q) mv share/verific.new share/verific

View file

@ -214,23 +214,120 @@ RTLIL::IdString VerificImporter::new_verific_id(Verific::DesignObj *obj)
return s;
}
// When used as attributes or parameter values Verific constants come already processed.
// - Real string values are already under quotes
// - Numeric values with specified width are always converted to binary
// - Rest of user defined values are handled as 32bit integers
// - There could be some internal values that are strings without quotes
// so we check if value is all digits or not
//
// Note: For signed values, verific uses <len>'sb<bits> and decimal values can
// also be negative.
static const RTLIL::Const verific_const(const char *value, bool allow_string = true, bool output_signed = false)
RTLIL::Const mkconst_str(const std::string &str)
{
size_t found;
RTLIL::Const val;
std::vector<RTLIL::State> data;
data.reserve(str.size() * 8);
for (size_t i = 0; i < str.size(); i++) {
unsigned char ch = str[str.size() - i - 1];
for (int j = 0; j < 8; j++) {
data.push_back((ch & 1) ? State::S1 : State::S0);
ch = ch >> 1;
}
}
val.bits = data;
val.flags |= RTLIL::CONST_FLAG_STRING;
return val;
}
static const RTLIL::Const extract_vhdl_boolean(std::string &val)
{
if (val == "false")
return RTLIL::Const::from_string("0");
if (val == "true")
return RTLIL::Const::from_string("1");
log_error("Expecting VHDL boolean value.\n");
}
static const RTLIL::Const extract_vhdl_bit(std::string &val, std::string &typ)
{
if (val.size()==3 && val[0]=='\'' && val.back()=='\'')
return RTLIL::Const::from_string(val.substr(1,val.size()-2));
log_error("Error parsing VHDL %s.\n", typ.c_str());
}
static const RTLIL::Const extract_vhdl_bit_vector(std::string &val, std::string &typ)
{
if (val.size()>1 && val[0]=='\"' && val.back()=='\"') {
RTLIL::Const c = RTLIL::Const::from_string(val.substr(1,val.size()-2));
if (typ == "signed")
c.flags |= RTLIL::CONST_FLAG_SIGNED;
return c;
}
log_error("Error parsing VHDL %s.\n", typ.c_str());
}
static const RTLIL::Const extract_vhdl_integer(std::string &val)
{
char *end;
return RTLIL::Const((int)std::strtol(val.c_str(), &end, 10), 32);
}
static const RTLIL::Const extract_vhdl_char(std::string &val)
{
if (val.size()==3 && val[0]=='\"' && val.back()=='\"')
return RTLIL::Const((int)val[1], 32);
log_error("Error parsing VHDL character.\n");
}
static const RTLIL::Const extract_real_value(std::string &val)
{
RTLIL::Const c = mkconst_str(val);
c.flags |= RTLIL::CONST_FLAG_REAL;
return c;
}
static const RTLIL::Const extract_vhdl_string(std::string &val)
{
if (!(val.size()>1 && val[0]=='\"' && val.back()=='\"'))
log_error("Error parsing VHDL string.\n");
return RTLIL::Const(val.substr(1,val.size()-2));
}
static const RTLIL::Const extract_vhdl_const(const char *value, bool output_signed)
{
RTLIL::Const c;
char *end;
int decimal;
bool is_signed = false;
RTLIL::Const c;
std::string val = std::string(value);
if (val.size()>1 && val[0]=='\"' && val.back()=='\"') {
std::string data = val.substr(1,val.size()-2);
bool isBinary = std::all_of(data.begin(), data.end(), [](char c) {return c=='1' || c=='0'; });
if (isBinary)
c = RTLIL::Const::from_string(data);
else
c = RTLIL::Const(data);
} else if (val.size()==3 && val[0]=='\'' && val.back()=='\'') {
c = RTLIL::Const::from_string(val.substr(1,val.size()-2));
} else if ((value[0] == '-' || (value[0] >= '0' && value[0] <= '9')) &&
((decimal = std::strtol(value, &end, 10)), !end[0])) {
is_signed = output_signed;
c = RTLIL::Const((int)decimal, 32);
} else if (val == "false") {
c = RTLIL::Const::from_string("0");
} else if (val == "true") {
c = RTLIL::Const::from_string("1");
} else {
c = mkconst_str(val);
log_warning("encoding value '%s' as string.\n", value);
}
if (is_signed)
c.flags |= RTLIL::CONST_FLAG_SIGNED;
return c;
}
static const RTLIL::Const extract_verilog_const(const char *value, bool allow_string, bool output_signed)
{
RTLIL::Const c;
char *end;
int decimal;
bool is_signed = false;
size_t found;
std::string val = std::string(value);
if (allow_string && val.size()>1 && val[0]=='\"' && val.back()=='\"') {
c = RTLIL::Const(val.substr(1,val.size()-2));
} else if ((found = val.find("'sb")) != std::string::npos) {
@ -245,15 +342,56 @@ static const RTLIL::Const verific_const(const char *value, bool allow_string = t
} else if (allow_string) {
c = RTLIL::Const(val);
} else {
log_error("expected numeric constant but found '%s'", value);
c = mkconst_str(val);
log_warning("encoding value '%s' as string.\n", value);
}
if (is_signed)
c.flags |= RTLIL::CONST_FLAG_SIGNED;
return c;
}
// When used as attributes or parameter values Verific constants come already processed.
// - Real string values are already under quotes
// - Numeric values with specified width are always converted to binary
// - Rest of user defined values are handled as 32bit integers
// - There could be some internal values that are strings without quotes
// so we check if value is all digits or not
//
// Note: For signed values, verific uses <len>'sb<bits> and decimal values can
// also be negative.
static const RTLIL::Const verific_const(const char* type_name, const char *value, DesignObj *obj, bool allow_string = true, bool output_signed = false)
{
std::string val = std::string(value);
// VHDL
if (obj->IsFromVhdl()) {
if (type_name) {
std::string typ = std::string(type_name);
transform(typ.begin(), typ.end(), typ.begin(), ::tolower);
if (typ == "integer" || typ == "natural" || typ=="positive") return extract_vhdl_integer(val);
else if (typ =="boolean") return extract_vhdl_boolean(val);
else if (typ == "bit" || typ =="std_logic" || typ == "std_ulogic") return extract_vhdl_bit(val,typ);
else if (typ == "character") return extract_vhdl_char(val);
else if (typ == "bit_vector" || typ == "std_logic_vector" || typ == "std_ulogic_vector" ||
typ == "unsigned" || typ == "signed") return extract_vhdl_bit_vector(val,typ);
else if (typ == "real") return extract_real_value(val);
else if (typ == "string") return extract_vhdl_string(val);
else {
if (val.size()>1 && val[0]=='\"' && val.back()=='\"')
return RTLIL::Const(val.substr(1,val.size()-2));
else if (val.size()==3 && val[0]=='\'' && val.back()=='\'')
return RTLIL::Const(val.substr(1,val.size()-2));
else
return RTLIL::Const(val);
}
} else extract_vhdl_const(value, output_signed);
}
// SystemVerilog
if (type_name && strcmp(type_name, "real")==0) {
return extract_real_value(val);
} else
return extract_verilog_const(value, allow_string, output_signed);
}
static const std::string verific_unescape(const char *value)
{
std::string val = std::string(value);
@ -276,7 +414,7 @@ void VerificImporter::import_attributes(dict<RTLIL::IdString, RTLIL::Const> &att
FOREACH_ATTRIBUTE(obj, mi, attr) {
if (attr->Key()[0] == ' ' || attr->Value() == nullptr)
continue;
attributes[RTLIL::escape_id(attr->Key())] = verific_const(attr->Value());
attributes[RTLIL::escape_id(attr->Key())] = verific_const(nullptr, attr->Value(), obj);
}
if (nl) {
@ -298,7 +436,7 @@ void VerificImporter::import_attributes(dict<RTLIL::IdString, RTLIL::Const> &att
const char *k, *v;
FOREACH_MAP_ITEM(type_range->GetEnumIdMap(), mi, &k, &v) {
if (nl->IsFromVerilog()) {
auto const value = verific_const(v, false);
auto const value = verific_const(type_name, v, nl, false);
attributes.emplace(stringf("\\enum_value_%s", value.as_string().c_str()), RTLIL::escape_id(k));
}
@ -1292,6 +1430,7 @@ void VerificImporter::import_netlist(RTLIL::Design *design, Netlist *nl, std::ma
}
import_attributes(module->attributes, nl, nl);
module->set_string_attribute(ID::hdlname, nl->CellBaseName());
module->set_string_attribute(ID(library), nl->Owner()->Owner()->Name());
#ifdef VERIFIC_VHDL_SUPPORT
if (nl->IsFromVhdl()) {
NameSpace name_space(0);
@ -1304,7 +1443,8 @@ void VerificImporter::import_netlist(RTLIL::Design *design, Netlist *nl, std::ma
MapIter mi;
FOREACH_PARAMETER_OF_NETLIST(nl, mi, param_name, param_value) {
module->avail_parameters(RTLIL::escape_id(param_name));
module->parameter_default_values[RTLIL::escape_id(param_name)] = verific_const(param_value);
const TypeRange *tr = nl->GetTypeRange(param_name) ;
module->parameter_default_values[RTLIL::escape_id(param_name)] = verific_const(tr->GetTypeName(), param_value, nl);
}
SetIter si;
@ -2004,7 +2144,8 @@ void VerificImporter::import_netlist(RTLIL::Design *design, Netlist *nl, std::ma
const char *param_value ;
if (is_blackbox(inst->View())) {
FOREACH_PARAMETER_OF_INST(inst, mi2, param_name, param_value) {
cell->setParam(RTLIL::escape_id(param_name), verific_const(param_value));
const TypeRange *tr = inst->View()->GetTypeRange(param_name) ;
cell->setParam(RTLIL::escape_id(param_name), verific_const(tr->GetTypeName(), param_value, inst->View()));
}
}
@ -2699,7 +2840,7 @@ struct VerificPass : public Pass {
log("\n");
log("\n");
#ifdef VERIFIC_VHDL_SUPPORT
log(" verific {-vhdl87|-vhdl93|-vhdl2k|-vhdl2008|-vhdl} <vhdl-file>..\n");
log(" verific {-vhdl87|-vhdl93|-vhdl2k|-vhdl2008|-vhdl2019|-vhdl} <vhdl-file>..\n");
log("\n");
log("Load the specified VHDL files into Verific.\n");
log("\n");
@ -3436,6 +3577,29 @@ struct VerificPass : public Pass {
goto check_error;
}
if (GetSize(args) > argidx && (args[argidx] == "-vhdl2019")) {
vhdl_file::SetDefaultLibraryPath((proc_share_dirname() + "verific/vhdl_vdbs_2019").c_str());
bool flag_lib = false;
for (argidx++; argidx < GetSize(args); argidx++) {
if (args[argidx] == "-lib") {
flag_lib = true;
continue;
}
if (args[argidx].compare(0, 1, "-") == 0) {
cmd_error(args, argidx, "unknown option");
goto check_error;
}
Map map(POINTER_HASH);
add_units_to_map(map, work, flag_lib);
std::string filename = frontent_rewrite(args, argidx, tmp_files);
if (!vhdl_file::Analyze(filename.c_str(), work.c_str(), vhdl_file::VHDL_2019))
log_cmd_error("Reading `%s' in VHDL_2019 mode failed.\n", filename.c_str());
set_units_to_blackbox(map, work, flag_lib);
}
verific_import_pending = true;
goto check_error;
}
if (GetSize(args) > argidx && (args[argidx] == "-vhdl2008" || args[argidx] == "-vhdl")) {
vhdl_file::SetDefaultLibraryPath((proc_share_dirname() + "verific/vhdl_vdbs_2008").c_str());
bool flag_lib = false;
@ -3979,7 +4143,7 @@ struct ReadPass : public Pass {
log("\n");
log("\n");
#ifdef VERIFIC_VHDL_SUPPORT
log(" read {-vhdl87|-vhdl93|-vhdl2k|-vhdl2008|-vhdl} <vhdl-file>..\n");
log(" read {-vhdl87|-vhdl93|-vhdl2k|-vhdl2008|-vhdl2019|-vhdl} <vhdl-file>..\n");
log("\n");
log("Load the specified VHDL files. (Requires Verific.)\n");
log("\n");
@ -4083,7 +4247,7 @@ struct ReadPass : public Pass {
}
#ifdef VERIFIC_VHDL_SUPPORT
if (args[1] == "-vhdl87" || args[1] == "-vhdl93" || args[1] == "-vhdl2k" || args[1] == "-vhdl2008" || args[1] == "-vhdl") {
if (args[1] == "-vhdl87" || args[1] == "-vhdl93" || args[1] == "-vhdl2k" || args[1] == "-vhdl2008" || args[1] == "-vhdl2019" || args[1] == "-vhdl") {
if (use_verific) {
args[0] = "verific";
Pass::call(design, args);

View file

@ -17,11 +17,11 @@
*
*/
#include "kernel/yosys.h"
#ifndef LOG_H
#define LOG_H
#include "kernel/yosys_common.h"
#include <time.h>
#include <regex>
@ -449,4 +449,6 @@ void log_dump_args_worker(const char *p, T first, Args ... args)
YOSYS_NAMESPACE_END
#include "kernel/yosys.h"
#endif

View file

@ -17,11 +17,12 @@
*
*/
#include "kernel/yosys.h"
#ifndef REGISTER_H
#define REGISTER_H
#include "kernel/yosys_common.h"
#include "kernel/yosys.h"
YOSYS_NAMESPACE_BEGIN
struct Pass

View file

@ -17,11 +17,12 @@
*
*/
#include "kernel/yosys.h"
#ifndef RTLIL_H
#define RTLIL_H
#include "kernel/yosys_common.h"
#include "kernel/yosys.h"
YOSYS_NAMESPACE_BEGIN
namespace RTLIL

View file

@ -39,323 +39,7 @@
#ifndef YOSYS_H
#define YOSYS_H
#include <map>
#include <set>
#include <tuple>
#include <vector>
#include <string>
#include <algorithm>
#include <functional>
#include <unordered_map>
#include <unordered_set>
#include <initializer_list>
#include <stdexcept>
#include <memory>
#include <cmath>
#include <cstddef>
#include <sstream>
#include <fstream>
#include <istream>
#include <ostream>
#include <iostream>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <stdio.h>
#include <limits.h>
#include <sys/stat.h>
#include <errno.h>
#ifdef WITH_PYTHON
#include <Python.h>
#endif
#ifndef _YOSYS_
# error It looks like you are trying to build Yosys without the config defines set. \
When building Yosys with a custom make system, make sure you set all the \
defines the Yosys Makefile would set for your build configuration.
#endif
#ifdef YOSYS_ENABLE_TCL
# include <tcl.h>
# ifdef YOSYS_MXE_HACKS
extern Tcl_Command Tcl_CreateCommand(Tcl_Interp *interp, const char *cmdName, Tcl_CmdProc *proc, ClientData clientData, Tcl_CmdDeleteProc *deleteProc);
extern Tcl_Interp *Tcl_CreateInterp(void);
extern void Tcl_Preserve(ClientData data);
extern void Tcl_Release(ClientData clientData);
extern int Tcl_InterpDeleted(Tcl_Interp *interp);
extern void Tcl_DeleteInterp(Tcl_Interp *interp);
extern int Tcl_Eval(Tcl_Interp *interp, const char *script);
extern int Tcl_EvalFile(Tcl_Interp *interp, const char *fileName);
extern void Tcl_Finalize(void);
extern int Tcl_GetCommandInfo(Tcl_Interp *interp, const char *cmdName, Tcl_CmdInfo *infoPtr);
extern const char *Tcl_GetStringResult(Tcl_Interp *interp);
extern Tcl_Obj *Tcl_NewStringObj(const char *bytes, int length);
extern Tcl_Obj *Tcl_NewIntObj(int intValue);
extern Tcl_Obj *Tcl_NewListObj(int objc, Tcl_Obj *const objv[]);
extern Tcl_Obj *Tcl_ObjSetVar2(Tcl_Interp *interp, Tcl_Obj *part1Ptr, Tcl_Obj *part2Ptr, Tcl_Obj *newValuePtr, int flags);
# endif
# undef CONST
# undef INLINE
#endif
#ifdef _WIN32
# undef NOMINMAX
# define NOMINMAX 1
# undef YY_NO_UNISTD_H
# define YY_NO_UNISTD_H 1
# include <windows.h>
# include <io.h>
# include <direct.h>
# define strtok_r strtok_s
# define strdup _strdup
# define snprintf _snprintf
# define getcwd _getcwd
# define mkdir _mkdir
# define popen _popen
# define pclose _pclose
# ifndef __MINGW32__
# define PATH_MAX MAX_PATH
# define isatty _isatty
# define fileno _fileno
# endif
// The following defines conflict with our identifiers:
# undef CONST
// `wingdi.h` defines a TRANSPARENT macro that conflicts with X(TRANSPARENT) entry in kernel/constids.inc
# undef TRANSPARENT
#endif
#ifndef PATH_MAX
# define PATH_MAX 4096
#endif
#define YOSYS_NAMESPACE Yosys
#define PRIVATE_NAMESPACE_BEGIN namespace {
#define PRIVATE_NAMESPACE_END }
#define YOSYS_NAMESPACE_BEGIN namespace Yosys {
#define YOSYS_NAMESPACE_END }
#define YOSYS_NAMESPACE_PREFIX Yosys::
#define USING_YOSYS_NAMESPACE using namespace Yosys;
#if defined(__GNUC__) || defined(__clang__)
# define YS_ATTRIBUTE(...) __attribute__((__VA_ARGS__))
#elif defined(_MSC_VER)
# define YS_ATTRIBUTE(...)
#else
# define YS_ATTRIBUTE(...)
#endif
#if defined(__GNUC__) || defined(__clang__)
# define YS_MAYBE_UNUSED __attribute__((__unused__))
#else
# define YS_MAYBE_UNUSED
#endif
#if __cplusplus >= 201703L
# define YS_FALLTHROUGH [[fallthrough]];
#elif defined(__clang__)
# define YS_FALLTHROUGH [[clang::fallthrough]];
#elif defined(__GNUC__)
# define YS_FALLTHROUGH [[gnu::fallthrough]];
#else
# define YS_FALLTHROUGH
#endif
YOSYS_NAMESPACE_BEGIN
// Note: All headers included in hashlib.h must be included
// outside of YOSYS_NAMESPACE before this or bad things will happen.
#ifdef HASHLIB_H
# undef HASHLIB_H
# include "kernel/hashlib.h"
#else
# include "kernel/hashlib.h"
# undef HASHLIB_H
#endif
using std::vector;
using std::string;
using std::tuple;
using std::pair;
using std::make_tuple;
using std::make_pair;
using std::get;
using std::min;
using std::max;
// A primitive shared string implementation that does not
// move its .c_str() when the object is copied or moved.
struct shared_str {
std::shared_ptr<string> content;
shared_str() { }
shared_str(string s) { content = std::shared_ptr<string>(new string(s)); }
shared_str(const char *s) { content = std::shared_ptr<string>(new string(s)); }
const char *c_str() const { return content->c_str(); }
const string &str() const { return *content; }
bool operator==(const shared_str &other) const { return *content == *other.content; }
unsigned int hash() const { return hashlib::hash_ops<std::string>::hash(*content); }
};
using hashlib::mkhash;
using hashlib::mkhash_init;
using hashlib::mkhash_add;
using hashlib::mkhash_xorshift;
using hashlib::hash_ops;
using hashlib::hash_cstr_ops;
using hashlib::hash_ptr_ops;
using hashlib::hash_obj_ops;
using hashlib::dict;
using hashlib::idict;
using hashlib::pool;
using hashlib::mfp;
namespace RTLIL {
struct IdString;
struct Const;
struct SigBit;
struct SigSpec;
struct Wire;
struct Cell;
struct Memory;
struct Process;
struct Module;
struct Design;
struct Monitor;
enum State : unsigned char;
}
namespace AST {
struct AstNode;
}
using RTLIL::IdString;
using RTLIL::Const;
using RTLIL::SigBit;
using RTLIL::SigSpec;
using RTLIL::Wire;
using RTLIL::Cell;
using RTLIL::Module;
using RTLIL::Design;
namespace hashlib {
template<> struct hash_ops<RTLIL::Wire*> : hash_obj_ops {};
template<> struct hash_ops<RTLIL::Cell*> : hash_obj_ops {};
template<> struct hash_ops<RTLIL::Memory*> : hash_obj_ops {};
template<> struct hash_ops<RTLIL::Process*> : hash_obj_ops {};
template<> struct hash_ops<RTLIL::Module*> : hash_obj_ops {};
template<> struct hash_ops<RTLIL::Design*> : hash_obj_ops {};
template<> struct hash_ops<RTLIL::Monitor*> : hash_obj_ops {};
template<> struct hash_ops<AST::AstNode*> : hash_obj_ops {};
template<> struct hash_ops<const RTLIL::Wire*> : hash_obj_ops {};
template<> struct hash_ops<const RTLIL::Cell*> : hash_obj_ops {};
template<> struct hash_ops<const RTLIL::Memory*> : hash_obj_ops {};
template<> struct hash_ops<const RTLIL::Process*> : hash_obj_ops {};
template<> struct hash_ops<const RTLIL::Module*> : hash_obj_ops {};
template<> struct hash_ops<const RTLIL::Design*> : hash_obj_ops {};
template<> struct hash_ops<const RTLIL::Monitor*> : hash_obj_ops {};
template<> struct hash_ops<const AST::AstNode*> : hash_obj_ops {};
}
void memhasher_on();
void memhasher_off();
void memhasher_do();
extern bool memhasher_active;
inline void memhasher() { if (memhasher_active) memhasher_do(); }
void yosys_banner();
int ceil_log2(int x) YS_ATTRIBUTE(const);
inline std::string vstringf(const char *fmt, va_list ap)
{
// For the common case of strings shorter than 128, save a heap
// allocation by using a stack allocated buffer.
const int kBufSize = 128;
char buf[kBufSize];
buf[0] = '\0';
va_list apc;
va_copy(apc, ap);
int n = vsnprintf(buf, kBufSize, fmt, apc);
va_end(apc);
if (n < kBufSize)
return std::string(buf);
std::string string;
char *str = NULL;
#if defined(_WIN32 )|| defined(__CYGWIN__)
int sz = 2 * kBufSize, rc;
while (1) {
va_copy(apc, ap);
str = (char*)realloc(str, sz);
rc = vsnprintf(str, sz, fmt, apc);
va_end(apc);
if (rc >= 0 && rc < sz)
break;
sz *= 2;
}
if (str != NULL) {
string = str;
free(str);
}
return string;
#else
if (vasprintf(&str, fmt, ap) < 0)
str = NULL;
if (str != NULL) {
string = str;
free(str);
}
return string;
#endif
}
std::string stringf(const char *fmt, ...) YS_ATTRIBUTE(format(printf, 1, 2));
inline std::string stringf(const char *fmt, ...)
{
std::string string;
va_list ap;
va_start(ap, fmt);
string = vstringf(fmt, ap);
va_end(ap);
return string;
}
int readsome(std::istream &f, char *s, int n);
std::string next_token(std::string &text, const char *sep = " \t\r\n", bool long_strings = false);
std::vector<std::string> split_tokens(const std::string &text, const char *sep = " \t\r\n");
bool patmatch(const char *pattern, const char *string);
#if !defined(YOSYS_DISABLE_SPAWN)
int run_command(const std::string &command, std::function<void(const std::string&)> process_line = std::function<void(const std::string&)>());
#endif
std::string get_base_tmpdir();
std::string make_temp_file(std::string template_str = get_base_tmpdir() + "/yosys_XXXXXX");
std::string make_temp_dir(std::string template_str = get_base_tmpdir() + "/yosys_XXXXXX");
bool check_file_exists(std::string filename, bool is_exec = false);
bool check_directory_exists(const std::string& dirname);
bool is_absolute_path(std::string filename);
void remove_directory(std::string dirname);
bool create_directory(const std::string& dirname);
std::string escape_filename_spaces(const std::string& filename);
template<typename T> int GetSize(const T &obj) { return obj.size(); }
inline int GetSize(RTLIL::Wire *wire);
extern int autoidx;
extern int yosys_xtrace;
YOSYS_NAMESPACE_END
#include "kernel/yosys_common.h"
#include "kernel/log.h"
#include "kernel/rtlil.h"
@ -363,14 +47,6 @@ YOSYS_NAMESPACE_END
YOSYS_NAMESPACE_BEGIN
using RTLIL::State;
using RTLIL::SigChunk;
using RTLIL::SigSig;
namespace hashlib {
template<> struct hash_ops<RTLIL::State> : hash_ops<int> {};
}
void yosys_setup();
#ifdef WITH_PYTHON
@ -385,26 +61,6 @@ Tcl_Interp *yosys_get_tcl_interp();
extern RTLIL::Design *yosys_design;
RTLIL::IdString new_id(std::string file, int line, std::string func);
RTLIL::IdString new_id_suffix(std::string file, int line, std::string func, std::string suffix);
#define NEW_ID \
YOSYS_NAMESPACE_PREFIX new_id(__FILE__, __LINE__, __FUNCTION__)
#define NEW_ID_SUFFIX(suffix) \
YOSYS_NAMESPACE_PREFIX new_id_suffix(__FILE__, __LINE__, __FUNCTION__, suffix)
// Create a statically allocated IdString object, using for example ID::A or ID($add).
//
// Recipe for Converting old code that is using conversion of strings like ID::A and
// "$add" for creating IdStrings: Run below SED command on the .cc file and then use for
// example "meld foo.cc foo.cc.orig" to manually compile errors, if necessary.
//
// sed -i.orig -r 's/"\\\\([a-zA-Z0-9_]+)"/ID(\1)/g; s/"(\$[a-zA-Z0-9_]+)"/ID(\1)/g;' <filename>
//
#define ID(_id) ([]() { const char *p = "\\" #_id, *q = p[1] == '$' ? p+1 : p; \
static const YOSYS_NAMESPACE_PREFIX RTLIL::IdString id(q); return id; })()
namespace ID = RTLIL::ID;
RTLIL::Design *yosys_get_design();
std::string proc_self_dirname();
std::string proc_share_dirname();

379
kernel/yosys_common.h Normal file
View file

@ -0,0 +1,379 @@
/* -*- c++ -*-
* yosys -- Yosys Open SYnthesis Suite
*
* Copyright (C) 2012 Claire Xenia Wolf <claire@yosyshq.com>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
*/
#ifndef YOSYS_COMMON_H
#define YOSYS_COMMON_H
#include <map>
#include <set>
#include <tuple>
#include <vector>
#include <string>
#include <algorithm>
#include <functional>
#include <unordered_map>
#include <unordered_set>
#include <initializer_list>
#include <stdexcept>
#include <memory>
#include <cmath>
#include <cstddef>
#include <sstream>
#include <fstream>
#include <istream>
#include <ostream>
#include <iostream>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <stdio.h>
#include <limits.h>
#include <sys/stat.h>
#include <errno.h>
#ifdef WITH_PYTHON
#include <Python.h>
#endif
#ifndef _YOSYS_
# error It looks like you are trying to build Yosys without the config defines set. \
When building Yosys with a custom make system, make sure you set all the \
defines the Yosys Makefile would set for your build configuration.
#endif
#ifdef YOSYS_ENABLE_TCL
# include <tcl.h>
# ifdef YOSYS_MXE_HACKS
extern Tcl_Command Tcl_CreateCommand(Tcl_Interp *interp, const char *cmdName, Tcl_CmdProc *proc, ClientData clientData, Tcl_CmdDeleteProc *deleteProc);
extern Tcl_Interp *Tcl_CreateInterp(void);
extern void Tcl_Preserve(ClientData data);
extern void Tcl_Release(ClientData clientData);
extern int Tcl_InterpDeleted(Tcl_Interp *interp);
extern void Tcl_DeleteInterp(Tcl_Interp *interp);
extern int Tcl_Eval(Tcl_Interp *interp, const char *script);
extern int Tcl_EvalFile(Tcl_Interp *interp, const char *fileName);
extern void Tcl_Finalize(void);
extern int Tcl_GetCommandInfo(Tcl_Interp *interp, const char *cmdName, Tcl_CmdInfo *infoPtr);
extern const char *Tcl_GetStringResult(Tcl_Interp *interp);
extern Tcl_Obj *Tcl_NewStringObj(const char *bytes, int length);
extern Tcl_Obj *Tcl_NewIntObj(int intValue);
extern Tcl_Obj *Tcl_NewListObj(int objc, Tcl_Obj *const objv[]);
extern Tcl_Obj *Tcl_ObjSetVar2(Tcl_Interp *interp, Tcl_Obj *part1Ptr, Tcl_Obj *part2Ptr, Tcl_Obj *newValuePtr, int flags);
# endif
# undef CONST
# undef INLINE
#endif
#ifdef _WIN32
# undef NOMINMAX
# define NOMINMAX 1
# undef YY_NO_UNISTD_H
# define YY_NO_UNISTD_H 1
# include <windows.h>
# include <io.h>
# include <direct.h>
# define strtok_r strtok_s
# define strdup _strdup
# define snprintf _snprintf
# define getcwd _getcwd
# define mkdir _mkdir
# define popen _popen
# define pclose _pclose
# ifndef __MINGW32__
# define PATH_MAX MAX_PATH
# define isatty _isatty
# define fileno _fileno
# endif
// The following defines conflict with our identifiers:
# undef CONST
// `wingdi.h` defines a TRANSPARENT macro that conflicts with X(TRANSPARENT) entry in kernel/constids.inc
# undef TRANSPARENT
#endif
#ifndef PATH_MAX
# define PATH_MAX 4096
#endif
#define YOSYS_NAMESPACE Yosys
#define PRIVATE_NAMESPACE_BEGIN namespace {
#define PRIVATE_NAMESPACE_END }
#define YOSYS_NAMESPACE_BEGIN namespace Yosys {
#define YOSYS_NAMESPACE_END }
#define YOSYS_NAMESPACE_PREFIX Yosys::
#define USING_YOSYS_NAMESPACE using namespace Yosys;
#if defined(__GNUC__) || defined(__clang__)
# define YS_ATTRIBUTE(...) __attribute__((__VA_ARGS__))
#elif defined(_MSC_VER)
# define YS_ATTRIBUTE(...)
#else
# define YS_ATTRIBUTE(...)
#endif
#if defined(__GNUC__) || defined(__clang__)
# define YS_MAYBE_UNUSED __attribute__((__unused__))
#else
# define YS_MAYBE_UNUSED
#endif
#if __cplusplus >= 201703L
# define YS_FALLTHROUGH [[fallthrough]];
#elif defined(__clang__)
# define YS_FALLTHROUGH [[clang::fallthrough]];
#elif defined(__GNUC__)
# define YS_FALLTHROUGH [[gnu::fallthrough]];
#else
# define YS_FALLTHROUGH
#endif
YOSYS_NAMESPACE_BEGIN
// Note: All headers included in hashlib.h must be included
// outside of YOSYS_NAMESPACE before this or bad things will happen.
#ifdef HASHLIB_H
# undef HASHLIB_H
# include "kernel/hashlib.h"
#else
# include "kernel/hashlib.h"
# undef HASHLIB_H
#endif
using std::vector;
using std::string;
using std::tuple;
using std::pair;
using std::make_tuple;
using std::make_pair;
using std::get;
using std::min;
using std::max;
// A primitive shared string implementation that does not
// move its .c_str() when the object is copied or moved.
struct shared_str {
std::shared_ptr<string> content;
shared_str() { }
shared_str(string s) { content = std::shared_ptr<string>(new string(s)); }
shared_str(const char *s) { content = std::shared_ptr<string>(new string(s)); }
const char *c_str() const { return content->c_str(); }
const string &str() const { return *content; }
bool operator==(const shared_str &other) const { return *content == *other.content; }
unsigned int hash() const { return hashlib::hash_ops<std::string>::hash(*content); }
};
using hashlib::mkhash;
using hashlib::mkhash_init;
using hashlib::mkhash_add;
using hashlib::mkhash_xorshift;
using hashlib::hash_ops;
using hashlib::hash_cstr_ops;
using hashlib::hash_ptr_ops;
using hashlib::hash_obj_ops;
using hashlib::dict;
using hashlib::idict;
using hashlib::pool;
using hashlib::mfp;
namespace RTLIL {
struct IdString;
struct Const;
struct SigBit;
struct SigSpec;
struct Wire;
struct Cell;
struct Memory;
struct Process;
struct Module;
struct Design;
struct Monitor;
struct Selection;
struct SigChunk;
enum State : unsigned char;
typedef std::pair<SigSpec, SigSpec> SigSig;
namespace ID {}
}
namespace AST {
struct AstNode;
}
using RTLIL::IdString;
using RTLIL::Const;
using RTLIL::SigBit;
using RTLIL::SigSpec;
using RTLIL::Wire;
using RTLIL::Cell;
using RTLIL::Module;
using RTLIL::Design;
using RTLIL::State;
using RTLIL::SigChunk;
using RTLIL::SigSig;
namespace hashlib {
template<> struct hash_ops<RTLIL::Wire*> : hash_obj_ops {};
template<> struct hash_ops<RTLIL::Cell*> : hash_obj_ops {};
template<> struct hash_ops<RTLIL::Memory*> : hash_obj_ops {};
template<> struct hash_ops<RTLIL::Process*> : hash_obj_ops {};
template<> struct hash_ops<RTLIL::Module*> : hash_obj_ops {};
template<> struct hash_ops<RTLIL::Design*> : hash_obj_ops {};
template<> struct hash_ops<RTLIL::Monitor*> : hash_obj_ops {};
template<> struct hash_ops<AST::AstNode*> : hash_obj_ops {};
template<> struct hash_ops<const RTLIL::Wire*> : hash_obj_ops {};
template<> struct hash_ops<const RTLIL::Cell*> : hash_obj_ops {};
template<> struct hash_ops<const RTLIL::Memory*> : hash_obj_ops {};
template<> struct hash_ops<const RTLIL::Process*> : hash_obj_ops {};
template<> struct hash_ops<const RTLIL::Module*> : hash_obj_ops {};
template<> struct hash_ops<const RTLIL::Design*> : hash_obj_ops {};
template<> struct hash_ops<const RTLIL::Monitor*> : hash_obj_ops {};
template<> struct hash_ops<const AST::AstNode*> : hash_obj_ops {};
}
void memhasher_on();
void memhasher_off();
void memhasher_do();
extern bool memhasher_active;
inline void memhasher() { if (memhasher_active) memhasher_do(); }
void yosys_banner();
int ceil_log2(int x) YS_ATTRIBUTE(const);
inline std::string vstringf(const char *fmt, va_list ap)
{
// For the common case of strings shorter than 128, save a heap
// allocation by using a stack allocated buffer.
const int kBufSize = 128;
char buf[kBufSize];
buf[0] = '\0';
va_list apc;
va_copy(apc, ap);
int n = vsnprintf(buf, kBufSize, fmt, apc);
va_end(apc);
if (n < kBufSize)
return std::string(buf);
std::string string;
char *str = NULL;
#if defined(_WIN32 )|| defined(__CYGWIN__)
int sz = 2 * kBufSize, rc;
while (1) {
va_copy(apc, ap);
str = (char*)realloc(str, sz);
rc = vsnprintf(str, sz, fmt, apc);
va_end(apc);
if (rc >= 0 && rc < sz)
break;
sz *= 2;
}
if (str != NULL) {
string = str;
free(str);
}
return string;
#else
if (vasprintf(&str, fmt, ap) < 0)
str = NULL;
if (str != NULL) {
string = str;
free(str);
}
return string;
#endif
}
std::string stringf(const char *fmt, ...) YS_ATTRIBUTE(format(printf, 1, 2));
inline std::string stringf(const char *fmt, ...)
{
std::string string;
va_list ap;
va_start(ap, fmt);
string = vstringf(fmt, ap);
va_end(ap);
return string;
}
int readsome(std::istream &f, char *s, int n);
std::string next_token(std::string &text, const char *sep = " \t\r\n", bool long_strings = false);
std::vector<std::string> split_tokens(const std::string &text, const char *sep = " \t\r\n");
bool patmatch(const char *pattern, const char *string);
#if !defined(YOSYS_DISABLE_SPAWN)
int run_command(const std::string &command, std::function<void(const std::string&)> process_line = std::function<void(const std::string&)>());
#endif
std::string get_base_tmpdir();
std::string make_temp_file(std::string template_str = get_base_tmpdir() + "/yosys_XXXXXX");
std::string make_temp_dir(std::string template_str = get_base_tmpdir() + "/yosys_XXXXXX");
bool check_file_exists(std::string filename, bool is_exec = false);
bool check_directory_exists(const std::string& dirname);
bool is_absolute_path(std::string filename);
void remove_directory(std::string dirname);
bool create_directory(const std::string& dirname);
std::string escape_filename_spaces(const std::string& filename);
template<typename T> int GetSize(const T &obj) { return obj.size(); }
inline int GetSize(RTLIL::Wire *wire);
extern int autoidx;
extern int yosys_xtrace;
RTLIL::IdString new_id(std::string file, int line, std::string func);
RTLIL::IdString new_id_suffix(std::string file, int line, std::string func, std::string suffix);
#define NEW_ID \
YOSYS_NAMESPACE_PREFIX new_id(__FILE__, __LINE__, __FUNCTION__)
#define NEW_ID_SUFFIX(suffix) \
YOSYS_NAMESPACE_PREFIX new_id_suffix(__FILE__, __LINE__, __FUNCTION__, suffix)
// Create a statically allocated IdString object, using for example ID::A or ID($add).
//
// Recipe for Converting old code that is using conversion of strings like ID::A and
// "$add" for creating IdStrings: Run below SED command on the .cc file and then use for
// example "meld foo.cc foo.cc.orig" to manually compile errors, if necessary.
//
// sed -i.orig -r 's/"\\\\([a-zA-Z0-9_]+)"/ID(\1)/g; s/"(\$[a-zA-Z0-9_]+)"/ID(\1)/g;' <filename>
//
#define ID(_id) ([]() { const char *p = "\\" #_id, *q = p[1] == '$' ? p+1 : p; \
static const YOSYS_NAMESPACE_PREFIX RTLIL::IdString id(q); return id; })()
namespace ID = RTLIL::ID;
namespace hashlib {
template<> struct hash_ops<RTLIL::State> : hash_ops<int> {};
}
YOSYS_NAMESPACE_END
#endif

View file

@ -36,7 +36,8 @@ struct cell_area_t {
struct statdata_t
{
#define STAT_INT_MEMBERS X(num_wires) X(num_wire_bits) X(num_pub_wires) X(num_pub_wire_bits) \
X(num_memories) X(num_memory_bits) X(num_cells) X(num_processes)
X(num_ports) X(num_port_bits) X(num_memories) X(num_memory_bits) X(num_cells) \
X(num_processes)
#define STAT_NUMERIC_MEMBERS STAT_INT_MEMBERS X(area)
@ -90,6 +91,11 @@ struct statdata_t
for (auto wire : mod->selected_wires())
{
if (wire->port_input || wire->port_output) {
num_ports++;
num_port_bits += wire->width;
}
if (wire->name.isPublic()) {
num_pub_wires++;
num_pub_wire_bits += wire->width;
@ -239,6 +245,8 @@ struct statdata_t
log(" Number of wire bits: %6u\n", num_wire_bits);
log(" Number of public wires: %6u\n", num_pub_wires);
log(" Number of public wire bits: %6u\n", num_pub_wire_bits);
log(" Number of ports: %6u\n", num_ports);
log(" Number of port bits: %6u\n", num_port_bits);
log(" Number of memories: %6u\n", num_memories);
log(" Number of memory bits: %6u\n", num_memory_bits);
log(" Number of processes: %6u\n", num_processes);
@ -284,6 +292,8 @@ struct statdata_t
log(" \"num_wire_bits\": %u,\n", num_wire_bits);
log(" \"num_pub_wires\": %u,\n", num_pub_wires);
log(" \"num_pub_wire_bits\": %u,\n", num_pub_wire_bits);
log(" \"num_ports\": %u,\n", num_ports);
log(" \"num_port_bits\": %u,\n", num_port_bits);
log(" \"num_memories\": %u,\n", num_memories);
log(" \"num_memory_bits\": %u,\n", num_memory_bits);
log(" \"num_processes\": %u,\n", num_processes);
@ -494,6 +504,8 @@ struct StatPass : public Pass {
design->scratchpad_set_int("stat.num_wire_bits", data.num_wire_bits);
design->scratchpad_set_int("stat.num_pub_wires", data.num_pub_wires);
design->scratchpad_set_int("stat.num_pub_wire_bits", data.num_pub_wire_bits);
design->scratchpad_set_int("stat.num_ports", data.num_ports);
design->scratchpad_set_int("stat.num_port_bits", data.num_port_bits);
design->scratchpad_set_int("stat.num_memories", data.num_memories);
design->scratchpad_set_int("stat.num_memory_bits", data.num_memory_bits);
design->scratchpad_set_int("stat.num_processes", data.num_processes);

View file

@ -415,7 +415,7 @@ struct MemoryMapPass : public Pass {
log(" to any of the values.\n");
log("\n");
log(" -iattr\n");
log(" for -attr, ignore case of <value>.\n");
log(" for -attr, suppress case sensitivity in matching of <value>.\n");
log("\n");
log(" -rom-only\n");
log(" only perform conversion for ROMs (memories with no write ports).\n");

View file

@ -443,13 +443,6 @@ bool rmunused_module_signals(RTLIL::Module *module, bool purge_mode, bool verbos
if (!raw_used_signals.check_any(s1)) {
// delete wires that aren't used by anything directly
goto delete_this_wire;
} else
if (!used_signals.check_any(s2)) {
// this path shouldn't be possible: this wire is used directly (otherwise it would get cleaned up above), and indirectly
// used wires are a superset of those used directly
log_assert(false);
// delete wires that aren't used by anything indirectly, even though other wires may alias it
goto delete_this_wire;
}
if (0)

View file

@ -183,7 +183,7 @@ struct OptDemorganPass : public Pass {
{
log_header(design, "Executing OPT_DEMORGAN pass (push inverters through $reduce_* cells).\n");
int argidx = 0;
int argidx = 1;
extra_args(args, argidx, design);
unsigned int cells_changed = 0;

View file

@ -237,7 +237,7 @@ struct InitValWorker
return true;
if (ff.has_ce && initconst(ff.sig_ce.as_bit()) == (ff.pol_ce ? State::S0 : State::S1))
continue;
if (ff.has_srst && initconst(ff.sig_ce.as_bit()) == (ff.pol_srst ? State::S1 : State::S0))
if (ff.has_srst && initconst(ff.sig_srst.as_bit()) == (ff.pol_srst ? State::S1 : State::S0))
continue;
return true;

View file

@ -35,3 +35,4 @@ $(eval $(call add_share_file,share,techlibs/common/abc9_map.v))
$(eval $(call add_share_file,share,techlibs/common/abc9_unmap.v))
$(eval $(call add_share_file,share,techlibs/common/cmp2lcu.v))
$(eval $(call add_share_file,share,techlibs/common/cmp2softlogic.v))
$(eval $(call add_share_file,share/choices,techlibs/common/choices/kogge-stone.v))

View file

@ -0,0 +1,54 @@
/*
* yosys -- Yosys Open SYnthesis Suite
*
* Copyright (C) 2024 Martin Povišer <povik@cutebit.org>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
*/
(* techmap_celltype = "$lcu" *)
module _80_lcu_kogge_stone (P, G, CI, CO);
parameter WIDTH = 2;
(* force_downto *)
input [WIDTH-1:0] P, G;
input CI;
(* force_downto *)
output [WIDTH-1:0] CO;
integer i, j;
(* force_downto *)
reg [WIDTH-1:0] p, g;
wire [1023:0] _TECHMAP_DO_ = "proc; opt -fast";
always @* begin
p = P;
g = G;
// in almost all cases CI will be constant zero
g[0] = g[0] | (p[0] & CI);
for (i = 0; i < $clog2(WIDTH); i = i + 1) begin
// iterate in reverse so we don't confuse a result from this stage and the previous
for (j = WIDTH - 1; j >= 2**i; j = j - 1) begin
g[j] = g[j] | p[j] & g[j - 2**i];
p[j] = p[j] & p[j - 2**i];
end
end
end
assign CO = g;
endmodule

View file

@ -902,18 +902,34 @@ endgenerate
endmodule
// --------------------------------------------------------
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
//-
//- $macc (A, B, Y)
//-
//- Multiply and accumulate.
//- A building block for summing any number of negated and unnegated signals
//- and arithmetic products of pairs of signals. Cell port A concatenates pairs
//- of signals to be multiplied together. When the second signal in a pair is zero
//- length, a constant 1 is used instead as the second factor. Cell port B
//- concatenates 1-bit-wide signals to also be summed, such as "carry in" in adders.
//- Typically created by the `alumacc` pass, which transforms $add and $mul
//- into $macc cells.
module \$macc (A, B, Y);
parameter A_WIDTH = 0;
parameter B_WIDTH = 0;
parameter Y_WIDTH = 0;
// CONFIG determines the layout of A, as explained below
parameter CONFIG = 4'b0000;
parameter CONFIG_WIDTH = 4;
input [A_WIDTH-1:0] A;
input [B_WIDTH-1:0] B;
output reg [Y_WIDTH-1:0] Y;
// In the terms used for this cell, there's mixed meanings for the term "port". To disambiguate:
// A cell port is for example the A input (it is constructed in C++ as cell->setPort(ID::A, ...))
// Multiplier ports are pairs of multiplier inputs ("factors").
// If the second signal in such a pair is zero length, no multiplication is necessary, and the first signal is just added to the sum.
input [A_WIDTH-1:0] A; // Cell port A is the concatenation of all arithmetic ports
input [B_WIDTH-1:0] B; // Cell port B is the concatenation of single-bit unsigned signals to be also added to the sum
output reg [Y_WIDTH-1:0] Y; // Output sum
// Xilinx XSIM does not like $clog2() below..
function integer my_clog2;
@ -929,10 +945,42 @@ function integer my_clog2;
end
endfunction
// Bits that a factor's length field in CONFIG per factor in cell port A
localparam integer num_bits = CONFIG[3:0] > 0 ? CONFIG[3:0] : 1;
// Number of multiplier ports
localparam integer num_ports = (CONFIG_WIDTH-4) / (2 + 2*num_bits);
// Minium bit width of an induction variable to iterate over all bits of cell port A
localparam integer num_abits = my_clog2(A_WIDTH) > 0 ? my_clog2(A_WIDTH) : 1;
// In this pseudocode, u(foo) means an unsigned int that's foo bits long.
// The CONFIG parameter carries the following information:
// struct CONFIG {
// u4 num_bits;
// struct port_field {
// bool is_signed;
// bool is_subtract;
// u(num_bits) factor1_len;
// u(num_bits) factor2_len;
// }[num_ports];
// };
// The A cell port carries the following information:
// struct A {
// u(CONFIG.port_field[0].factor1_len) port0factor1;
// u(CONFIG.port_field[0].factor2_len) port0factor2;
// u(CONFIG.port_field[1].factor1_len) port1factor1;
// u(CONFIG.port_field[1].factor2_len) port1factor2;
// ...
// };
// and log(sizeof(A)) is num_abits.
// No factor1 may have a zero length.
// A factor2 having a zero length implies factor2 is replaced with a constant 1.
// Additionally, B is an array of 1-bit-wide unsigned integers to also be summed up.
// Finally, we have:
// Y = port0factor1 * port0factor2 + port1factor1 * port1factor2 + ...
// * B[0] + B[1] + ...
function [2*num_ports*num_abits-1:0] get_port_offsets;
input [CONFIG_WIDTH-1:0] cfg;
integer i, cursor;

View file

@ -207,7 +207,7 @@ module _90_fa (A, B, C, X, Y);
endmodule
(* techmap_celltype = "$lcu" *)
module _90_lcu (P, G, CI, CO);
module _90_lcu_brent_kung (P, G, CI, CO);
parameter WIDTH = 2;
(* force_downto *)

View file

@ -113,7 +113,31 @@ module EFX_GBUFCE(
endmodule
module EFX_RAM_5K(
module EFX_RAM_5K
# (
parameter READ_WIDTH = 20,
parameter WRITE_WIDTH = 20,
localparam READ_ADDR_WIDTH =
(READ_WIDTH == 16) ? 8 : // 256x16
(READ_WIDTH == 8) ? 9 : // 512x8
(READ_WIDTH == 4) ? 10 : // 1024x4
(READ_WIDTH == 2) ? 11 : // 2048x2
(READ_WIDTH == 1) ? 12 : // 4096x1
(READ_WIDTH == 20) ? 8 : // 256x20
(READ_WIDTH == 10) ? 9 : // 512x10
(READ_WIDTH == 5) ? 10 : -1, // 1024x5
localparam WRITE_ADDR_WIDTH =
(WRITE_WIDTH == 16) ? 8 : // 256x16
(WRITE_WIDTH == 8) ? 9 : // 512x8
(WRITE_WIDTH == 4) ? 10 : // 1024x4
(WRITE_WIDTH == 2) ? 11 : // 2048x2
(WRITE_WIDTH == 1) ? 12 : // 4096x1
(WRITE_WIDTH == 20) ? 8 : // 256x20
(WRITE_WIDTH == 10) ? 9 : // 512x10
(WRITE_WIDTH == 5) ? 10 : -1 // 1024x5
)
(
input [WRITE_WIDTH-1:0] WDATA,
input [WRITE_ADDR_WIDTH-1:0] WADDR,
input WE,
@ -126,8 +150,6 @@ module EFX_RAM_5K(
(* clkbuf_sink *)
input RCLK
);
parameter READ_WIDTH = 20;
parameter WRITE_WIDTH = 20;
parameter OUTPUT_REG = 1'b0;
parameter RCLK_POLARITY = 1'b1;
parameter RE_POLARITY = 1'b1;
@ -155,25 +177,4 @@ module EFX_RAM_5K(
parameter INIT_11 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_12 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_13 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
localparam READ_ADDR_WIDTH =
(READ_WIDTH == 16) ? 8 : // 256x16
(READ_WIDTH == 8) ? 9 : // 512x8
(READ_WIDTH == 4) ? 10 : // 1024x4
(READ_WIDTH == 2) ? 11 : // 2048x2
(READ_WIDTH == 1) ? 12 : // 4096x1
(READ_WIDTH == 20) ? 8 : // 256x20
(READ_WIDTH == 10) ? 9 : // 512x10
(READ_WIDTH == 5) ? 10 : -1; // 1024x5
localparam WRITE_ADDR_WIDTH =
(WRITE_WIDTH == 16) ? 8 : // 256x16
(WRITE_WIDTH == 8) ? 9 : // 512x8
(WRITE_WIDTH == 4) ? 10 : // 1024x4
(WRITE_WIDTH == 2) ? 11 : // 2048x2
(WRITE_WIDTH == 1) ? 12 : // 4096x1
(WRITE_WIDTH == 20) ? 8 : // 256x20
(WRITE_WIDTH == 10) ? 9 : // 512x10
(WRITE_WIDTH == 5) ? 10 : -1; // 1024x5
endmodule

View file

@ -1,4 +1,4 @@
*.log
/run-test.mk
run-test.mk
+*_synth.v
+*_testbench

View file

@ -16,7 +16,7 @@ for arch in ../../techlibs/*; do
done
else
echo -n "Test $path ->"
iverilog -t null -I$arch $path
iverilog -t null -I$arch -g2005-sv $path
echo " ok"
fi
done

View file

@ -1,4 +1,14 @@
module RAM_9b1B (
module RAM_9b1B
#(
parameter INIT = 0,
parameter OPTION_INIT = "UNDEFINED",
parameter PORT_R_WIDTH = 9,
parameter PORT_W_WIDTH = 9,
parameter PORT_R_CLK_POL = 0,
parameter PORT_W_CLK_POL = 0,
parameter PORT_W_WR_EN_WIDTH = 1
)
(
input PORT_R_CLK,
input [6:0] PORT_R_ADDR,
output reg [PORT_R_WIDTH-1:0] PORT_R_RD_DATA,
@ -8,14 +18,6 @@ module RAM_9b1B (
input [PORT_W_WIDTH-1:0] PORT_W_WR_DATA
);
parameter INIT = 0;
parameter OPTION_INIT = "UNDEFINED";
parameter PORT_R_WIDTH = 9;
parameter PORT_W_WIDTH = 9;
parameter PORT_R_CLK_POL = 0;
parameter PORT_W_CLK_POL = 0;
parameter PORT_W_WR_EN_WIDTH = 1;
reg [8:0] mem [0:15];
integer i;

View file

@ -1,4 +1,11 @@
module RAM_WREN (
module RAM_WREN #(
parameter ABITS=4,
parameter WIDTH=8,
parameter PORT_A_WR_EN_WIDTH=1,
parameter PORT_A_WR_BE_WIDTH=0,
parameter OPTION_BYTESIZE=WIDTH,
parameter WB=OPTION_BYTESIZE
)(
input PORT_A_CLK,
input [ABITS-1:0] PORT_A_ADDR,
input [WIDTH-1:0] PORT_A_WR_DATA,
@ -7,13 +14,6 @@ module RAM_WREN (
input [PORT_A_WR_BE_WIDTH-1:0] PORT_A_WR_BE
);
parameter ABITS=4;
parameter WIDTH=8;
parameter PORT_A_WR_EN_WIDTH=1;
parameter PORT_A_WR_BE_WIDTH=0;
parameter OPTION_BYTESIZE=WIDTH;
parameter WB=OPTION_BYTESIZE;
reg [WIDTH-1:0] mem [0:2**ABITS-1];
integer i;

View file

@ -2,13 +2,15 @@
// expect-rd-ports 1
// expect-rd-clk \clk
module ram2 (input clk,
module ram2 #(
parameter SIZE = 5 // Address size
) (input clk,
input sel,
input we,
input [SIZE-1:0] adr,
input [63:0] dat_i,
output reg [63:0] dat_o);
parameter SIZE = 5; // Address size
reg [63:0] mem [0:(1 << SIZE)-1];
integer i;

View file

@ -1,2 +1,3 @@
*.log
*.out
*.err

View file

@ -0,0 +1 @@
test_cell -s 1711533949 -n 10 -map +/techmap.v -map +/choices/kogge-stone.v $lcu

View file

@ -1,6 +1,10 @@
/*.log
/*.out
/*.err
/run-test.mk
/const_arst.v
/const_sr.v
/doubleslash.v
/roundtrip_proc_1.v
/roundtrip_proc_2.v
/assign_to_reg.v

View file

@ -0,0 +1,22 @@
# https://github.com/yosyshq/yosys/issues/2035
read_ilang <<END
module \top
wire width 1 input 0 \halfbrite
wire width 2 output 1 \r_on
process $1
assign \r_on [1:0] 2'00
assign \r_on [1:0] 2'11
switch \halfbrite [0]
case 1'1
assign \r_on [1] 1'0
end
end
end
END
proc_prune
write_verilog assign_to_reg.v
design -reset
logger -expect-no-warnings
read_verilog assign_to_reg.v