aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG1
-rw-r--r--Makefile1
-rw-r--r--frontends/ast/simplify.cc16
-rw-r--r--frontends/verilog/verilog_parser.y4
-rw-r--r--manual/CHAPTER_Overview.tex7
-rw-r--r--misc/py_wrap_generator.py40
-rw-r--r--passes/techmap/abc9_exe.cc2
-rw-r--r--techlibs/xilinx/abc9_map.v80
-rw-r--r--tests/memfile/.gitignore1
-rw-r--r--tests/memfile/content1.dat64
-rw-r--r--tests/memfile/memory.v23
-rwxr-xr-xtests/memfile/run-test.sh49
-rw-r--r--tests/various/bug1614.ys5
13 files changed, 245 insertions, 48 deletions
diff --git a/CHANGELOG b/CHANGELOG
index ca7196091..e0b0eb05e 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -60,6 +60,7 @@ Yosys 0.9 .. Yosys 0.9-dev
- Added "scratchpad" pass
- Added "abc9 -dff"
- Added "synth_xilinx -dff"
+ - Improved support of $readmem[hb] Memory Content File inclusion
- Added "opt_lut_ins" pass
Yosys 0.8 .. Yosys 0.9
diff --git a/Makefile b/Makefile
index 43c4d0890..e9dfd9df0 100644
--- a/Makefile
+++ b/Makefile
@@ -728,6 +728,7 @@ test: $(TARGETS) $(EXTRA_TARGETS)
+cd tests/arch/anlogic && bash run-test.sh $(SEEDOPT)
+cd tests/arch/gowin && bash run-test.sh $(SEEDOPT)
+cd tests/rpc && bash run-test.sh
+ +cd tests/memfile && bash run-test.sh
@echo ""
@echo " Passed \"make test\"."
@echo ""
diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc
index 8855d9954..fe0412699 100644
--- a/frontends/ast/simplify.cc
+++ b/frontends/ast/simplify.cc
@@ -2903,9 +2903,19 @@ AstNode *AstNode::readmem(bool is_readmemh, std::string mem_filename, AstNode *m
std::ifstream f;
f.open(mem_filename.c_str());
- yosys_input_files.insert(mem_filename);
-
- if (f.fail())
+ if (f.fail()) {
+#ifdef _WIN32
+ char slash = '\\';
+#else
+ char slash = '/';
+#endif
+ std::string path = filename.substr(0, filename.find_last_of(slash)+1);
+ f.open(path + mem_filename.c_str());
+ yosys_input_files.insert(path + mem_filename);
+ } else {
+ yosys_input_files.insert(mem_filename);
+ }
+ if (f.fail() || GetSize(mem_filename) == 0)
log_file_error(filename, linenum, "Can not open file `%s` for %s.\n", mem_filename.c_str(), str.c_str());
log_assert(GetSize(memory->children) == 2 && memory->children[1]->type == AST_RANGE && memory->children[1]->range_valid);
diff --git a/frontends/verilog/verilog_parser.y b/frontends/verilog/verilog_parser.y
index 2c7304cc4..8840cf4e8 100644
--- a/frontends/verilog/verilog_parser.y
+++ b/frontends/verilog/verilog_parser.y
@@ -476,7 +476,7 @@ wire_type:
astbuf3 = new AstNode(AST_WIRE);
current_wire_rand = false;
current_wire_const = false;
- } wire_type_token_list delay {
+ } wire_type_token_list {
$$ = astbuf3;
};
@@ -1240,7 +1240,7 @@ wire_decl:
}
if (astbuf2 && astbuf2->children.size() != 2)
frontend_verilog_yyerror("wire/reg/logic packed dimension must be of the form: [<expr>:<expr>], [<expr>+:<expr>], or [<expr>-:<expr>]");
- } wire_name_list {
+ } delay wire_name_list {
delete astbuf1;
if (astbuf2 != NULL)
delete astbuf2;
diff --git a/manual/CHAPTER_Overview.tex b/manual/CHAPTER_Overview.tex
index 3009bf2c0..be37d8d39 100644
--- a/manual/CHAPTER_Overview.tex
+++ b/manual/CHAPTER_Overview.tex
@@ -234,6 +234,8 @@ An RTLIL::Wire object has the following properties:
\item The wire name
\item A list of attributes
\item A width (buses are just wires with a width > 1)
+\item Bus direction (MSB to LSB or vice versa)
+\item Lowest valid bit index (LSB or MSB depending on bus direction)
\item If the wire is a port: port number and direction (input/output/inout)
\end{itemize}
@@ -246,6 +248,11 @@ This makes some aspects of RTLIL more complex but enables Yosys to be used for
coarse grain synthesis where the cells of the target architecture operate on
entire signal vectors instead of single bit wires.
+In Verilog and VHDL, busses may have arbitrary bounds, and LSB can have either
+the lowest or the highest bit index. In RTLIL, bit 0 always corresponds to LSB;
+however, information from the HDL frontend is preserved so that the bus will be
+correctly indexed in error messages, backend output, constraint files, etc.
+
An RTLIL::Cell object has the following properties:
\begin{itemize}
diff --git a/misc/py_wrap_generator.py b/misc/py_wrap_generator.py
index 9b4e644c0..fac5b48a4 100644
--- a/misc/py_wrap_generator.py
+++ b/misc/py_wrap_generator.py
@@ -721,6 +721,7 @@ class WClass:
name = None
namespace = None
link_type = None
+ base_class = None
id_ = None
string_id = None
hash_id = None
@@ -732,6 +733,7 @@ class WClass:
def __init__(self, name, link_type, id_, string_id = None, hash_id = None, needs_clone = False):
self.name = name
self.namespace = None
+ self.base_class = None
self.link_type = link_type
self.id_ = id_
self.string_id = string_id
@@ -804,6 +806,8 @@ class WClass:
for con in self.found_constrs:
text += con.gen_decl()
+ if self.base_class is not None:
+ text += "\n\t\tvirtual ~" + self.name + "() { };"
for var in self.found_vars:
text += var.gen_decl()
for fun in self.found_funs:
@@ -908,15 +912,19 @@ class WClass:
def gen_boost_py(self):
body = self.gen_boost_py_body()
+ base_info = ""
+ if self.base_class is not None:
+ base_info = ", bases<" + (self.base_class.name) + ">"
+
if self.link_type == link_types.derive:
- text = "\n\t\tclass_<" + self.name + ">(\"Cpp" + self.name + "\""
+ text = "\n\t\tclass_<" + self.name + base_info + ">(\"Cpp" + self.name + "\""
text += body
text += "\n\t\tclass_<" + self.name
text += "Wrap, boost::noncopyable"
text += ">(\"" + self.name + "\""
text += body
else:
- text = "\n\t\tclass_<" + self.name + ">(\"" + self.name + "\""
+ text = "\n\t\tclass_<" + self.name + base_info + ">(\"" + self.name + "\""
text += body
return text
@@ -1971,9 +1979,21 @@ def parse_header(source):
for namespace in impl_namespaces:
complete_namespace += "::" + namespace
debug("\tFound " + struct_name + " in " + complete_namespace,2)
+
+ base_class_name = None
+ if len(ugly_line.split(" : ")) > 1: # class is derived
+ deriv_str = ugly_line.split(" : ")[1]
+ if len(deriv_str.split("::")) > 1: # namespace of base class is given
+ base_class_name = deriv_str.split("::", 1)[1]
+ else:
+ base_class_name = deriv_str.split(" ")[0]
+ debug("\t " + struct_name + " is derived from " + base_class_name,2)
+ base_class = class_by_name(base_class_name)
+
class_ = (class_by_name(struct_name), ugly_line.count("{"))#calc_ident(line))
if struct_name in classnames:
class_[0].namespace = complete_namespace
+ class_[0].base_class = base_class
i += 1
continue
@@ -2142,6 +2162,21 @@ def expand_functions():
new_funs.extend(expand_function(fun))
class_.found_funs = new_funs
+def inherit_members():
+ for source in sources:
+ for class_ in source.classes:
+ if class_.base_class:
+ base_funs = copy.deepcopy(class_.base_class.found_funs)
+ for fun in base_funs:
+ fun.member_of = class_
+ fun.namespace = class_.namespace
+ base_vars = copy.deepcopy(class_.base_class.found_vars)
+ for var in base_vars:
+ var.member_of = class_
+ var.namespace = class_.namespace
+ class_.found_funs.extend(base_funs)
+ class_.found_vars.extend(base_vars)
+
def clean_duplicates():
for source in sources:
for class_ in source.classes:
@@ -2178,6 +2213,7 @@ def gen_wrappers(filename, debug_level_ = 0):
parse_header(source)
expand_functions()
+ inherit_members()
clean_duplicates()
import shutil
diff --git a/passes/techmap/abc9_exe.cc b/passes/techmap/abc9_exe.cc
index d3db0065c..898285c69 100644
--- a/passes/techmap/abc9_exe.cc
+++ b/passes/techmap/abc9_exe.cc
@@ -362,7 +362,7 @@ struct Abc9ExePass : public Pass {
}
void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
{
- log_header(design, "Executing ABC9_MAP pass (technology mapping using ABC9).\n");
+ log_header(design, "Executing ABC9_EXE pass (technology mapping using ABC9).\n");
#ifdef ABCEXTERNAL
std::string exe_file = ABCEXTERNAL;
diff --git a/techlibs/xilinx/abc9_map.v b/techlibs/xilinx/abc9_map.v
index 7dc027176..539fa4547 100644
--- a/techlibs/xilinx/abc9_map.v
+++ b/techlibs/xilinx/abc9_map.v
@@ -215,11 +215,11 @@ module FDCE (output Q, (* techmap_autopurge *) input C, CE, D, CLR);
.IS_PRE_INVERTED(IS_CLR_INVERTED)
) _TECHMAP_REPLACE_ (
.D(~D), .Q($Q), .C(C), .CE(CE), .PRE(CLR)
- // ^^^ Note that async
- // control is not directly
- // supported by abc9 but its
- // behaviour is captured by
- // $__ABC9_ASYNC1 below
+ // ^^^ Note that async
+ // control is not directly
+ // supported by abc9 but its
+ // behaviour is captured by
+ // $__ABC9_ASYNC1 below
);
// Since this is an async flop, async behaviour is dealt with here
$__ABC9_ASYNC1 abc_async (.A($QQ), .S(CLR ^ IS_CLR_INVERTED), .Y(QQ));
@@ -233,11 +233,11 @@ module FDCE (output Q, (* techmap_autopurge *) input C, CE, D, CLR);
.IS_CLR_INVERTED(IS_CLR_INVERTED)
) _TECHMAP_REPLACE_ (
.D(D), .Q($Q), .C(C), .CE(CE), .CLR(CLR)
- // ^^^ Note that async
- // control is not directly
- // supported by abc9 but its
- // behaviour is captured by
- // $__ABC9_ASYNC0 below
+ // ^^^ Note that async
+ // control is not directly
+ // supported by abc9 but its
+ // behaviour is captured by
+ // $__ABC9_ASYNC0 below
);
// Since this is an async flop, async behaviour is dealt with here
$__ABC9_ASYNC0 abc_async (.A($QQ), .S(CLR ^ IS_CLR_INVERTED), .Y(QQ));
@@ -258,11 +258,11 @@ module FDCE_1 (output Q, (* techmap_autopurge *) input C, CE, D, CLR);
.INIT(1'b0)
) _TECHMAP_REPLACE_ (
.D(~D), .Q($Q), .C(C), .CE(CE), .PRE(CLR)
- // ^^^ Note that async
- // control is not directly
- // supported by abc9 but its
- // behaviour is captured by
- // $__ABC9_ASYNC1 below
+ // ^^^ Note that async
+ // control is not directly
+ // supported by abc9 but its
+ // behaviour is captured by
+ // $__ABC9_ASYNC1 below
);
$__ABC9_ASYNC1 abc_async (.A($QQ), .S(CLR), .Y(QQ));
end
@@ -272,11 +272,11 @@ module FDCE_1 (output Q, (* techmap_autopurge *) input C, CE, D, CLR);
.INIT(1'b0)
) _TECHMAP_REPLACE_ (
.D(D), .Q($Q), .C(C), .CE(CE), .CLR(CLR)
- // ^^^ Note that async
- // control is not directly
- // supported by abc9 but its
- // behaviour is captured by
- // $__ABC9_ASYNC0 below
+ // ^^^ Note that async
+ // control is not directly
+ // supported by abc9 but its
+ // behaviour is captured by
+ // $__ABC9_ASYNC0 below
);
$__ABC9_ASYNC0 abc_async (.A($QQ), .S(CLR), .Y(QQ));
end endgenerate
@@ -303,11 +303,11 @@ module FDPE (output Q, (* techmap_autopurge *) input C, CE, D, PRE);
.IS_CLR_INVERTED(IS_PRE_INVERTED),
) _TECHMAP_REPLACE_ (
.D(~D), .Q($Q), .C(C), .CE(CE), .CLR(PRE)
- // ^^^ Note that async
- // control is not directly
- // supported by abc9 but its
- // behaviour is captured by
- // $__ABC9_ASYNC0 below
+ // ^^^ Note that async
+ // control is not directly
+ // supported by abc9 but its
+ // behaviour is captured by
+ // $__ABC9_ASYNC0 below
);
$__ABC9_ASYNC0 abc_async (.A($QQ), .S(PRE ^ IS_PRE_INVERTED), .Y(QQ));
end
@@ -320,11 +320,11 @@ module FDPE (output Q, (* techmap_autopurge *) input C, CE, D, PRE);
.IS_PRE_INVERTED(IS_PRE_INVERTED),
) _TECHMAP_REPLACE_ (
.D(D), .Q($Q), .C(C), .CE(CE), .PRE(PRE)
- // ^^^ Note that async
- // control is not directly
- // supported by abc9 but its
- // behaviour is captured by
- // $__ABC9_ASYNC1 below
+ // ^^^ Note that async
+ // control is not directly
+ // supported by abc9 but its
+ // behaviour is captured by
+ // $__ABC9_ASYNC1 below
);
$__ABC9_ASYNC1 abc_async (.A($QQ), .S(PRE ^ IS_PRE_INVERTED), .Y(QQ));
end endgenerate
@@ -344,11 +344,11 @@ module FDPE_1 (output Q, (* techmap_autopurge *) input C, CE, D, PRE);
.INIT(1'b0)
) _TECHMAP_REPLACE_ (
.D(~D), .Q($Q), .C(C), .CE(CE), .CLR(PRE)
- // ^^^ Note that async
- // control is not directly
- // supported by abc9 but its
- // behaviour is captured by
- // $__ABC9_ASYNC0 below
+ // ^^^ Note that async
+ // control is not directly
+ // supported by abc9 but its
+ // behaviour is captured by
+ // $__ABC9_ASYNC0 below
);
$__ABC9_ASYNC0 abc_async (.A($QQ), .S(PRE), .Y(QQ));
end
@@ -358,11 +358,11 @@ module FDPE_1 (output Q, (* techmap_autopurge *) input C, CE, D, PRE);
.INIT(1'b0)
) _TECHMAP_REPLACE_ (
.D(D), .Q($Q), .C(C), .CE(CE), .PRE(PRE)
- // ^^^ Note that async
- // control is not directly
- // supported by abc9 but its
- // behaviour is captured by
- // $__ABC9_ASYNC1 below
+ // ^^^ Note that async
+ // control is not directly
+ // supported by abc9 but its
+ // behaviour is captured by
+ // $__ABC9_ASYNC1 below
);
$__ABC9_ASYNC1 abc_async (.A($QQ), .S(PRE), .Y(QQ));
end endgenerate
diff --git a/tests/memfile/.gitignore b/tests/memfile/.gitignore
new file mode 100644
index 000000000..61b0d4264
--- /dev/null
+++ b/tests/memfile/.gitignore
@@ -0,0 +1 @@
+temp*
diff --git a/tests/memfile/content1.dat b/tests/memfile/content1.dat
new file mode 100644
index 000000000..4d1c67c26
--- /dev/null
+++ b/tests/memfile/content1.dat
@@ -0,0 +1,64 @@
+00001111000000001111111100000000
+00001111000000001111111100000000
+00001111000000001111111100000000
+00001111000000001111111100000000
+00001111000000001111111100000000
+00001111000000001111111100000000
+00001111000000001111111100000000
+00001111000000001111111100000000
+00001111000000001111111100000000
+00001111000000001111111100000000
+00001111000000001111111100000000
+00001111000000001111111100000000
+00001111000000001111111100000000
+00001111000000001111111100000000
+00001111000000001111111100000000
+00001111000000001111111100000000
+00001111000000001111111100000000
+00001111000000001111111100000000
+00001111000000001111111100000000
+00001111000000001111111100000000
+00001111000000001111111100000000
+00001111000000001111111100000000
+00001111000000001111111100000000
+00001111000000001111111100000000
+00001111000000001111111100000000
+00001111000000001111111100000000
+00001111000000001111111100000000
+00001111000000001111111100000000
+00001111000000001111111100000000
+00001111000000001111111100000000
+00001111000000001111111100000000
+00001111000000001111111100000000
+00001111000000001111111100000000
+00001111000000001111111100000000
+00001111000000001111111100000000
+00001111000000001111111100000000
+00001111000000001111111100000000
+00001111000000001111111100000000
+00001111000000001111111100000000
+00001111000000001111111100000000
+00001111000000001111111100000000
+00001111000000001111111100000000
+00001111000000001111111100000000
+00001111000000001111111100000000
+00001111000000001111111100000000
+00001111000000001111111100000000
+00001111000000001111111100000000
+00001111000000001111111100000000
+00001111000000001111111100000000
+00001111000000001111111100000000
+00001111000000001111111100000000
+00001111000000001111111100000000
+00001111000000001111111100000000
+00001111000000001111111100000000
+00001111000000001111111100000000
+00001111000000001111111100000000
+00001111000000001111111100000000
+00001111000000001111111100000000
+00001111000000001111111100000000
+00001111000000001111111100000000
+00001111000000001111111100000000
+00001111000000001111111100000000
+00001111000000001111111100000000
+00001111000000001111111100000000
diff --git a/tests/memfile/memory.v b/tests/memfile/memory.v
new file mode 100644
index 000000000..57106eae8
--- /dev/null
+++ b/tests/memfile/memory.v
@@ -0,0 +1,23 @@
+// A memory initialized with an external file
+
+module memory (
+ input clk_i,
+ input we_i,
+ input [5:0] addr_i,
+ input [31:0] data_i,
+ output reg [31:0] data_o
+);
+
+parameter MEMFILE = "";
+
+reg [31:0] mem [0:63];
+
+initial $readmemb(MEMFILE,mem);
+
+always @(posedge clk_i) begin
+ if (we_i)
+ mem[addr_i] <= data_i;
+ data_o <= mem[addr_i];
+end
+
+endmodule
diff --git a/tests/memfile/run-test.sh b/tests/memfile/run-test.sh
new file mode 100755
index 000000000..e43ddd093
--- /dev/null
+++ b/tests/memfile/run-test.sh
@@ -0,0 +1,49 @@
+#!/bin/bash
+
+set -e
+
+mkdir -p temp
+cp content1.dat temp/content2.dat
+
+cd ..
+
+echo "Running from the parent directory with content1.dat"
+../yosys -qp "read_verilog -defer memfile/memory.v; chparam -set MEMFILE \"content1.dat\" memory"
+echo "Running from the parent directory with temp/content2.dat"
+../yosys -qp "read_verilog -defer memfile/memory.v; chparam -set MEMFILE \"temp/content2.dat\" memory"
+echo "Running from the parent directory with memfile/temp/content2.dat"
+../yosys -qp "read_verilog -defer memfile/memory.v; chparam -set MEMFILE \"memfile/temp/content2.dat\" memory"
+
+cd memfile
+
+echo "Running from the same directory with content1.dat"
+../../yosys -qp "read_verilog -defer memory.v; chparam -set MEMFILE \"content1.dat\" memory"
+echo "Running from the same directory with temp/content2.dat"
+../../yosys -qp "read_verilog -defer memory.v; chparam -set MEMFILE \"temp/content2.dat\" memory"
+
+cd temp
+
+echo "Running from a child directory with content1.dat"
+../../../yosys -qp "read_verilog -defer ../memory.v; chparam -set MEMFILE \"content1.dat\" memory"
+echo "Running from a child directory with temp/content2.dat"
+../../../yosys -qp "read_verilog -defer ../memory.v; chparam -set MEMFILE \"temp/content2.dat\" memory"
+echo "Running from a child directory with content2.dat"
+../../../yosys -qp "read_verilog -defer ../memory.v; chparam -set MEMFILE \"temp/content2.dat\" memory"
+
+cd ..
+
+echo "Checking a failure when zero length filename is provided"
+if ../../yosys -qp "read_verilog memory.v"; then
+ echo "The execution should fail but it didn't happen, which is WRONG."
+ exit 1
+else
+ echo "Execution failed, which is OK."
+fi
+
+echo "Checking a failure when not existing filename is provided"
+if ../../yosys -qp "read_verilog -defer memory.v; chparam -set MEMFILE \"content3.dat\" memory"; then
+ echo "The execution should fail but it didn't happen, which is WRONG."
+ exit 1
+else
+ echo "Execution failed, which is OK."
+fi
diff --git a/tests/various/bug1614.ys b/tests/various/bug1614.ys
new file mode 100644
index 000000000..6fbe84a4c
--- /dev/null
+++ b/tests/various/bug1614.ys
@@ -0,0 +1,5 @@
+read_verilog <<EOT
+module testcase;
+ wire [3:0] #1 a = 4'b0000;
+endmodule
+EOT