yosys/tests/bind/cell_list.sv

27 lines
659 B
Systemverilog
Raw Normal View History

Add support for parsing the SystemVerilog 'bind' construct This doesn't do anything useful yet: the patch just adds support for the syntax to the lexer and parser and adds some tests to check the syntax parses properly. This generates AST nodes, but doesn't yet generate RTLIL. Since our existing hierarchical_identifier parser doesn't allow bit selects (so you can't do something like foo[1].bar[2].baz), I've also not added support for a trailing bit select (the "constant_bit_select" non-terminal in "bind_target_instance" in the spec). If we turn out to need this in future, we'll want to augment hierarchical_identifier and its other users too. Note that you can't easily use the BNF from the spec: bind_directive ::= "bind" bind_target_scope [ : bind_target_instance_list] bind_instantiation ; | "bind" bind_target_instance bind_instantiation ; even if you fix the lookahead problem, because code like this matches both branches in the BNF: bind a b b_i (.*); The problem is that 'a' could either be a module name or a degenerate hierarchical reference. This seems to be a genuine syntactic ambiguity, which the spec resolves (p739) by saying that we have to wait until resolution time (the hierarchy pass) and take whatever is defined, treating 'a' as an instance name if it names both an instance and a module. To keep the parser simple, it currently accepts this invalid syntax: bind a.b : c d e (.*); This is invalid because we're in the first branch of the BNF above, so the "a.b" term should match bind_target_scope: a module or interface identifier, not an arbitrary hierarchical identifier. This will fail in the hierarchy pass (when it's implemented in a future patch).
2020-05-21 11:36:29 -05:00
// An example of specifying multiple bind instances in a single directive. This
// also uses explicit bound names.
module foo (input logic a0, input logic b0, output logic c0,
input logic a1, input logic b1, output logic c1);
// Magic happens here...
endmodule
module bar (input a, input b, output c);
assign c = a ^ b;
endmodule
module top ();
logic u0, v0, w0;
logic u1, v1, w1;
foo foo0 (.a0 (u0), .b0 (v0), .c0 (w0),
.a1 (u1), .b1 (v1), .c1 (w1));
bind foo bar bar0 (.a(a0), .b(b0), .c(c0)), bar1 (.a(a1), .b(b1), .c(c1));
always_comb begin
assert(w0 == u0 ^ v0);
assert(w1 == u1 ^ v1);
end
endmodule