aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile2
-rw-r--r--backends/spice/spice.cc22
-rw-r--r--frontends/ast/simplify.cc3
-rw-r--r--frontends/verilog/verilog_parser.y88
-rw-r--r--passes/opt/opt_share.cc4
-rw-r--r--tests/opt/opt_share_bug2538.ys20
-rw-r--r--tests/svtypes/typedef_struct_port.sv111
-rw-r--r--tests/svtypes/typedef_struct_port.ys6
-rw-r--r--tests/various/.gitignore1
-rw-r--r--tests/verilog/wire_and_var.sv33
-rw-r--r--tests/verilog/wire_and_var.ys9
11 files changed, 253 insertions, 46 deletions
diff --git a/Makefile b/Makefile
index 8602a3f3c..a6e7f07fc 100644
--- a/Makefile
+++ b/Makefile
@@ -126,7 +126,7 @@ LDFLAGS += -rdynamic
LDLIBS += -lrt
endif
-YOSYS_VER := 0.9+3833
+YOSYS_VER := 0.9+3845
GIT_REV := $(shell cd $(YOSYS_SRC) && git rev-parse --short HEAD 2> /dev/null || echo UNKNOWN)
OBJS = kernel/version_$(GIT_REV).o
diff --git a/backends/spice/spice.cc b/backends/spice/spice.cc
index aa20f106a..ca5c680c9 100644
--- a/backends/spice/spice.cc
+++ b/backends/spice/spice.cc
@@ -64,7 +64,7 @@ static void print_spice_net(std::ostream &f, RTLIL::SigBit s, std::string &neg,
}
}
-static void print_spice_module(std::ostream &f, RTLIL::Module *module, RTLIL::Design *design, std::string &neg, std::string &pos, std::string &ncpf, bool big_endian, bool use_inames)
+static void print_spice_module(std::ostream &f, RTLIL::Module *module, RTLIL::Design *design, std::string &neg, std::string &pos, std::string &buf, std::string &ncpf, bool big_endian, bool use_inames)
{
SigMap sigmap(module);
idict<IdString, 1> inums;
@@ -121,10 +121,10 @@ static void print_spice_module(std::ostream &f, RTLIL::Module *module, RTLIL::De
for (auto &conn : module->connections())
for (int i = 0; i < conn.first.size(); i++) {
- f << stringf("V%d", conn_counter++);
- print_spice_net(f, conn.first.extract(i, 1), neg, pos, ncpf, nc_counter, use_inames, inums);
+ f << (buf == "DC" ? stringf("V%d", conn_counter++) : stringf("X%d", cell_counter++));
print_spice_net(f, conn.second.extract(i, 1), neg, pos, ncpf, nc_counter, use_inames, inums);
- f << stringf(" DC 0\n");
+ print_spice_net(f, conn.first.extract(i, 1), neg, pos, ncpf, nc_counter, use_inames, inums);
+ f << (buf == "DC" ? " DC 0\n" : stringf(" %s\n", buf.c_str()));
}
}
@@ -148,6 +148,10 @@ struct SpiceBackend : public Backend {
log(" -pos net_name\n");
log(" set the net name for constant 1 (default: Vdd)\n");
log("\n");
+ log(" -buf DC|subckt_name\n");
+ log(" set the name for jumper element (default: DC)\n");
+ log(" (used to connect different nets)\n");
+ log("\n");
log(" -nc_prefix\n");
log(" prefix for not-connected nets (default: _NC)\n");
log("\n");
@@ -164,7 +168,7 @@ struct SpiceBackend : public Backend {
std::string top_module_name;
RTLIL::Module *top_module = NULL;
bool big_endian = false, use_inames = false;
- std::string neg = "Vss", pos = "Vdd", ncpf = "_NC";
+ std::string neg = "Vss", pos = "Vdd", ncpf = "_NC", buf = "DC";
log_header(design, "Executing SPICE backend.\n");
@@ -187,6 +191,10 @@ struct SpiceBackend : public Backend {
pos = args[++argidx];
continue;
}
+ if (args[argidx] == "-buf" && argidx+1 < args.size()) {
+ buf = args[++argidx];
+ continue;
+ }
if (args[argidx] == "-nc_prefix" && argidx+1 < args.size()) {
ncpf = args[++argidx];
continue;
@@ -241,14 +249,14 @@ struct SpiceBackend : public Backend {
*f << stringf(" %s", spice_id2str(wire->name).c_str());
}
*f << stringf("\n");
- print_spice_module(*f, module, design, neg, pos, ncpf, big_endian, use_inames);
+ print_spice_module(*f, module, design, neg, pos, buf, ncpf, big_endian, use_inames);
*f << stringf(".ENDS %s\n\n", spice_id2str(module->name).c_str());
}
if (!top_module_name.empty()) {
if (top_module == NULL)
log_error("Can't find top module `%s'!\n", top_module_name.c_str());
- print_spice_module(*f, top_module, design, neg, pos, ncpf, big_endian, use_inames);
+ print_spice_module(*f, top_module, design, neg, pos, buf, ncpf, big_endian, use_inames);
*f << stringf("\n");
}
diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc
index d4242f1e7..fc2976c83 100644
--- a/frontends/ast/simplify.cc
+++ b/frontends/ast/simplify.cc
@@ -1330,6 +1330,9 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
if (template_node->type == AST_STRUCT || template_node->type == AST_UNION) {
// replace with wire representing the packed structure
newNode = make_packed_struct(template_node, str);
+ // add original input/output attribute to resolved wire
+ newNode->is_input = this->is_input;
+ newNode->is_output = this->is_output;
current_scope[str] = this;
goto apply_newNode;
}
diff --git a/frontends/verilog/verilog_parser.y b/frontends/verilog/verilog_parser.y
index 6c4b06d7f..2886db0e5 100644
--- a/frontends/verilog/verilog_parser.y
+++ b/frontends/verilog/verilog_parser.y
@@ -282,7 +282,7 @@ static void rewriteAsMemoryNode(AstNode *node, AstNode *rangeNode)
%token TOK_OR_ASSIGN TOK_XOR_ASSIGN TOK_AND_ASSIGN TOK_SUB_ASSIGN
%type <ast> range range_or_multirange non_opt_range non_opt_multirange range_or_signed_int
-%type <ast> wire_type expr basic_expr concat_list rvalue lvalue lvalue_concat_list
+%type <ast> wire_type expr basic_expr concat_list rvalue lvalue lvalue_concat_list non_io_wire_type io_wire_type
%type <string> opt_label opt_sva_label tok_prim_wrapper hierarchical_id hierarchical_type_id integral_number
%type <string> type_name
%type <ast> opt_enum_init enum_type struct_type non_wire_data_type
@@ -619,26 +619,19 @@ non_opt_delay:
delay:
non_opt_delay | %empty;
-wire_type:
- {
- astbuf3 = new AstNode(AST_WIRE);
- current_wire_rand = false;
- current_wire_const = false;
- } wire_type_token_list {
- $$ = astbuf3;
- SET_RULE_LOC(@$, @2, @$);
- };
+io_wire_type:
+ { astbuf3 = new AstNode(AST_WIRE); current_wire_rand = false; current_wire_const = false; }
+ wire_type_token_io wire_type_const_rand opt_wire_type_token wire_type_signedness
+ { $$ = astbuf3; SET_RULE_LOC(@$, @2, @$); };
-wire_type_token_list:
- wire_type_token |
- wire_type_token_list wire_type_token |
- wire_type_token_io |
- hierarchical_type_id {
- astbuf3->is_custom_type = true;
- astbuf3->children.push_back(new AstNode(AST_WIRETYPE));
- astbuf3->children.back()->str = *$1;
- delete $1;
- };
+non_io_wire_type:
+ { astbuf3 = new AstNode(AST_WIRE); current_wire_rand = false; current_wire_const = false; }
+ wire_type_const_rand wire_type_token wire_type_signedness
+ { $$ = astbuf3; SET_RULE_LOC(@$, @2, @$); };
+
+wire_type:
+ io_wire_type |
+ non_io_wire_type;
wire_type_token_io:
TOK_INPUT {
@@ -652,8 +645,24 @@ wire_type_token_io:
astbuf3->is_output = true;
};
+wire_type_signedness:
+ TOK_SIGNED { astbuf3->is_signed = true; } |
+ TOK_UNSIGNED { astbuf3->is_signed = false; } |
+ %empty;
+
+wire_type_const_rand:
+ TOK_CONST { current_wire_const = true; } |
+ TOK_RAND { current_wire_rand = true; } |
+ %empty;
+
+opt_wire_type_token:
+ wire_type_token | %empty;
+
wire_type_token:
- TOK_WIRE {
+ hierarchical_type_id {
+ astbuf3->is_custom_type = true;
+ astbuf3->children.push_back(new AstNode(AST_WIRETYPE));
+ astbuf3->children.back()->str = *$1;
} |
TOK_WOR {
astbuf3->is_wor = true;
@@ -661,20 +670,27 @@ wire_type_token:
TOK_WAND {
astbuf3->is_wand = true;
} |
+ // wires
+ TOK_WIRE {
+ } |
+ TOK_WIRE logic_type {
+ } |
+ // regs
TOK_REG {
astbuf3->is_reg = true;
} |
- TOK_LOGIC {
- astbuf3->is_logic = true;
+ TOK_VAR TOK_REG {
+ astbuf3->is_reg = true;
} |
+ // logics
TOK_VAR {
astbuf3->is_logic = true;
} |
- TOK_INTEGER {
- astbuf3->is_reg = true;
- astbuf3->range_left = 31;
- astbuf3->range_right = 0;
- astbuf3->is_signed = true;
+ TOK_VAR logic_type {
+ astbuf3->is_logic = true;
+ } |
+ logic_type {
+ astbuf3->is_logic = true;
} |
TOK_GENVAR {
astbuf3->type = AST_GENVAR;
@@ -682,15 +698,15 @@ wire_type_token:
astbuf3->is_signed = true;
astbuf3->range_left = 31;
astbuf3->range_right = 0;
+ };
+
+logic_type:
+ TOK_LOGIC {
} |
- TOK_SIGNED {
+ TOK_INTEGER {
+ astbuf3->range_left = 31;
+ astbuf3->range_right = 0;
astbuf3->is_signed = true;
- } |
- TOK_RAND {
- current_wire_rand = true;
- } |
- TOK_CONST {
- current_wire_const = true;
};
non_opt_range:
@@ -1803,7 +1819,7 @@ type_name: TOK_ID // first time seen
;
typedef_decl:
- TOK_TYPEDEF wire_type range type_name range_or_multirange ';' {
+ TOK_TYPEDEF non_io_wire_type range type_name range_or_multirange ';' {
astbuf1 = $2;
astbuf2 = checkRange(astbuf1, $3);
if (astbuf2)
diff --git a/passes/opt/opt_share.cc b/passes/opt/opt_share.cc
index 53296699c..62a478673 100644
--- a/passes/opt/opt_share.cc
+++ b/passes/opt/opt_share.cc
@@ -244,8 +244,8 @@ void merge_operators(RTLIL::Module *module, RTLIL::Cell *mux, const std::vector<
}
if (shared_op->type.in(ID($alu))) {
- shared_op->setPort(ID::X, module->addWire(NEW_ID, GetSize(new_sig_out)));
- shared_op->setPort(ID::CO, module->addWire(NEW_ID, GetSize(new_sig_out)));
+ shared_op->setPort(ID::X, module->addWire(NEW_ID, GetSize(new_out)));
+ shared_op->setPort(ID::CO, module->addWire(NEW_ID, GetSize(new_out)));
}
bool is_fine = shared_op->type.in(FINE_BITWISE_OPS);
diff --git a/tests/opt/opt_share_bug2538.ys b/tests/opt/opt_share_bug2538.ys
new file mode 100644
index 000000000..7261c6695
--- /dev/null
+++ b/tests/opt/opt_share_bug2538.ys
@@ -0,0 +1,20 @@
+read_verilog <<EOT
+
+module top(...);
+
+input [3:0] A;
+input S;
+output [1:0] Y;
+
+wire [3:0] A1 = A + 1;
+wire [3:0] A2 = A + 2;
+assign Y = S ? A1[3:2] : A2[3:2];
+
+endmodule
+
+EOT
+
+proc
+alumacc
+equiv_opt -assert opt_share
+
diff --git a/tests/svtypes/typedef_struct_port.sv b/tests/svtypes/typedef_struct_port.sv
new file mode 100644
index 000000000..ecc03bee8
--- /dev/null
+++ b/tests/svtypes/typedef_struct_port.sv
@@ -0,0 +1,111 @@
+package p;
+
+typedef struct packed {
+ byte a;
+ byte b;
+} p_t;
+
+typedef logic [31:0] l_t;
+
+endpackage
+
+module foo1(
+ input p::p_t p,
+ output p::p_t o
+);
+ assign o = p;
+endmodule
+
+module foo2(p, o);
+ input p::p_t p;
+ output p::p_t o;
+ assign o = p;
+endmodule
+
+module foo3(input p::l_t p, input p::l_t o);
+ assign o = p;
+endmodule
+
+module foo4(input logic [15:0] p, input logic [15:0] o);
+ assign o = p;
+endmodule
+
+module test_parser(a,b,c,d,e,f,g,h,i);
+input [7:0] a; // no explicit net declaration - net is unsigned
+input [7:0] b;
+input signed [7:0] c;
+input signed [7:0] d; // no explicit net declaration - net is signed
+output [7:0] e; // no explicit net declaration - net is unsigned
+output [7:0] f;
+output signed [7:0] g;
+output signed [7:0] h; // no explicit net declaration - net is signed
+output unsigned [7:0] i;
+wire signed [7:0] b; // port b inherits signed attribute from net decl.
+wire [7:0] c; // net c inherits signed attribute from port
+logic signed [7:0] f;// port f inherits signed attribute from logic decl.
+logic [7:0] g; // logic g inherits signed attribute from port
+
+ assign a = 8'b10001111;
+ assign b = 8'b10001111;
+ assign c = 8'b10001111;
+ assign d = 8'b10001111;
+ assign e = 8'b10001111;
+ assign f = 8'b10001111;
+ assign g = 8'b10001111;
+ assign h = 8'b10001111;
+ assign i = 8'b10001111;
+ always_comb begin
+ assert($unsigned(143) == a);
+ assert($signed(-113) == b);
+ assert($signed(-113) == c);
+ assert($signed(-113) == d);
+ assert($unsigned(143) == e);
+ assert($unsigned(143) == f);
+ assert($signed(-113) == g);
+ assert($signed(-113) == h);
+ assert($unsigned(143) == i);
+ end
+endmodule
+
+module top;
+ p::p_t ps;
+ assign ps.a = 8'hAA;
+ assign ps.b = 8'h55;
+ foo1 foo(.p(ps));
+
+ p::p_t body;
+ assign body.a = 8'hBB;
+ assign body.b = 8'h66;
+ foo2 foo_b(.p(body));
+
+ typedef p::l_t local_alias;
+
+ local_alias l_s;
+ assign l_s = 32'hAAAAAAAA;
+ foo3 foo_l(.p(l_s));
+
+ typedef logic [15:0] sl_t;
+
+ sl_t sl_s;
+ assign sl_s = 16'hBBBB;
+ foo4 foo_sl(.p(sl_s));
+
+ typedef sl_t local_alias_st;
+
+ local_alias_st lsl_s;
+ assign lsl_s = 16'hCCCC;
+ foo4 foo_lsl(.p(lsl_s));
+
+ const logic j = 1'b1;
+
+ always_comb begin
+ assert(8'hAA == ps.a);
+ assert(8'h55 == ps.b);
+ assert(8'hBB == body.a);
+ assert(8'h66 == body.b);
+ assert(32'hAAAAAAAA == l_s);
+ assert(16'hBBBB == sl_s);
+ assert(16'hCCCC == lsl_s);
+ assert(1'b1 == j);
+ end
+endmodule
diff --git a/tests/svtypes/typedef_struct_port.ys b/tests/svtypes/typedef_struct_port.ys
new file mode 100644
index 000000000..5b75c3105
--- /dev/null
+++ b/tests/svtypes/typedef_struct_port.ys
@@ -0,0 +1,6 @@
+read_verilog -sv typedef_struct_port.sv
+hierarchy; proc; opt
+select -module top
+sat -verify -seq 1 -tempinduct -prove-asserts -show-all
+select -module test_parser
+sat -verify -seq 1 -tempinduct -prove-asserts -show-all
diff --git a/tests/various/.gitignore b/tests/various/.gitignore
index 12d4e5048..2bb6c7179 100644
--- a/tests/various/.gitignore
+++ b/tests/various/.gitignore
@@ -4,3 +4,4 @@
/write_gzip.v.gz
/run-test.mk
/plugin.so
+/plugin.so.dSYM
diff --git a/tests/verilog/wire_and_var.sv b/tests/verilog/wire_and_var.sv
new file mode 100644
index 000000000..79c7c04c6
--- /dev/null
+++ b/tests/verilog/wire_and_var.sv
@@ -0,0 +1,33 @@
+`define TEST(kwd) \
+ kwd kwd``_1; \
+ kwd kwd``_2; \
+ initial kwd``_1 = 1; \
+ assign kwd``_2 = 1;
+
+`define TEST_VAR(kwd) \
+ var kwd var_``kwd``_1; \
+ var kwd var_``kwd``_2; \
+ initial var_``kwd``_1 = 1; \
+ assign var_``kwd``_2 = 1;
+
+`define TEST_WIRE(kwd) \
+ wire kwd wire_``kwd``_1; \
+ wire kwd wire_``kwd``_2; \
+ initial wire_``kwd``_1 = 1; \
+ assign wire_``kwd``_2 = 1;
+
+module top;
+
+`TEST(wire) // wire assigned in a block
+`TEST(reg) // reg assigned in a continuous assignment
+`TEST(logic)
+`TEST(integer)
+
+`TEST_VAR(reg) // reg assigned in a continuous assignment
+`TEST_VAR(logic)
+`TEST_VAR(integer)
+
+`TEST_WIRE(logic) // wire assigned in a block
+`TEST_WIRE(integer) // wire assigned in a block
+
+endmodule
diff --git a/tests/verilog/wire_and_var.ys b/tests/verilog/wire_and_var.ys
new file mode 100644
index 000000000..9359a9d55
--- /dev/null
+++ b/tests/verilog/wire_and_var.ys
@@ -0,0 +1,9 @@
+logger -expect warning "wire '\\wire_1' is assigned in a block" 1
+logger -expect warning "reg '\\reg_2' is assigned in a continuous assignment" 1
+
+logger -expect warning "reg '\\var_reg_2' is assigned in a continuous assignment" 1
+
+logger -expect warning "wire '\\wire_logic_1' is assigned in a block" 1
+logger -expect warning "wire '\\wire_integer_1' is assigned in a block" 1
+
+read_verilog -sv wire_and_var.sv