verilog: fix buf/not primitives with multiple outputs

From IEEE1364-2005, section 7.3 buf and not gates:

> These two logic gates shall have one input and one or more outputs.
> The last terminal in the terminal list shall connect to the input of the
> logic gate, and the other terminals shall connect to the outputs of
> the logic gate.

yosys does not follow this and instead interprets the first argument as
the output, the second as the input and ignores the rest.
This commit is contained in:
Xiretza 2021-03-17 00:18:36 +01:00 committed by Zachary Snow
parent dd6d34f461
commit 092e923330
2 changed files with 30 additions and 4 deletions

View File

@ -2223,6 +2223,21 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
children.push_back(node); children.push_back(node);
did_something = true; did_something = true;
} }
else if (str == "buf" || str == "not")
{
AstNode *input = children_list.back();
if (str == "not")
input = new AstNode(AST_BIT_NOT, input);
newNode = new AstNode(AST_GENBLOCK);
for (auto it = children_list.begin(); it != std::prev(children_list.end()); it++) {
newNode->children.push_back(new AstNode(AST_ASSIGN, *it, input->clone()));
newNode->children.back()->was_checked = true;
}
delete input;
did_something = true;
}
else else
{ {
AstNodeType op_type = AST_NONE; AstNodeType op_type = AST_NONE;
@ -2240,10 +2255,6 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
op_type = AST_BIT_XOR; op_type = AST_BIT_XOR;
if (str == "xnor") if (str == "xnor")
op_type = AST_BIT_XOR, invert_results = true; op_type = AST_BIT_XOR, invert_results = true;
if (str == "buf")
op_type = AST_POS;
if (str == "not")
op_type = AST_POS, invert_results = true;
log_assert(op_type != AST_NONE); log_assert(op_type != AST_NONE);
AstNode *node = children_list[1]; AstNode *node = children_list[1];

View File

@ -0,0 +1,15 @@
module verilog_primitives (
input wire in1, in2, in3,
output wire out_buf0, out_buf1, out_buf2, out_buf3, out_buf4,
output wire out_not0, out_not1, out_not2,
output wire out_xnor
);
buf u_buf0 (out_buf0, in1);
buf u_buf1 (out_buf1, out_buf2, out_buf3, out_buf4, in2);
not u_not0 (out_not0, out_not1, out_not2, in1);
xnor u_xnor0 (out_xnor, in1, in2, in3);
endmodule