mirror of https://github.com/YosysHQ/yosys.git
Add sign and op checks.
This commit is contained in:
parent
7fef67a141
commit
1414012676
|
|
@ -15,21 +15,35 @@ match add
|
|||
endmatch
|
||||
|
||||
code
|
||||
SigSpec mul_out = port(mul, \Y);
|
||||
IdString add_AB;
|
||||
Cell *mac = module->addCell(NEW_ID, "$__NX_MAC18X18");
|
||||
IdString add_C = (add_AB == \A) ? \B : \A;
|
||||
if (mul->getParam(\A_SIGNED).as_bool() != mul->getParam(\B_SIGNED).as_bool()) {
|
||||
reject;
|
||||
}
|
||||
|
||||
mac->setPort(\A, port(mul, \A));
|
||||
mac->setPort(\B, port(mul, \B));
|
||||
mac->setPort(\C, port(add, add_C));
|
||||
mac->setPort(\Y, port(add, \Y));
|
||||
mac->setParam(\A_SIGNED, mul->getParam(\A_SIGNED));
|
||||
mac->setParam(\B_SIGNED, mul->getParam(\B_SIGNED));
|
||||
mac->setParam(\SUBTRACT, add->type == $sub ? State::S1 : State::S0);
|
||||
{
|
||||
SigSpec mul_out = port(mul, \Y);
|
||||
IdString add_AB;
|
||||
|
||||
autoremove(mul);
|
||||
autoremove(add);
|
||||
if (GetSize(port(add, \A)) >= GetSize(mul_out) && port(add, \A).extract(0, GetSize(mul_out)) == mul_out) {
|
||||
add_AB = \A;
|
||||
} else if (GetSize(port(add, \B)) >= GetSize(mul_out) && port(add, \B).extract(0, GetSize(mul_out)) == mul_out) {
|
||||
add_AB = \B;
|
||||
} else {
|
||||
reject;
|
||||
}
|
||||
|
||||
Cell *mac = module->addCell(NEW_ID, "$__NX_MAC18X18");
|
||||
IdString add_C = (add_AB == \A) ? \B : \A;
|
||||
|
||||
mac->setPort(\A, port(mul, \A));
|
||||
mac->setPort(\B, port(mul, \B));
|
||||
mac->setPort(\C, port(add, add_C));
|
||||
mac->setPort(\Y, port(add, \Y));
|
||||
mac->setParam(\A_SIGNED, mul->getParam(\A_SIGNED));
|
||||
mac->setParam(\SUBTRACT, add->type == $sub ? State::S1 : State::S0);
|
||||
|
||||
autoremove(mul);
|
||||
autoremove(add);
|
||||
}
|
||||
|
||||
accept;
|
||||
endcode
|
||||
|
|
@ -57,41 +71,53 @@ endmatch
|
|||
code
|
||||
SigSpec preadd_out = port(preadd, \Y);
|
||||
IdString actual_mul_AB;
|
||||
Cell *mac = module->addCell(NEW_ID, "$__NX_PREADD18X18");
|
||||
|
||||
IdString mul_other = (actual_mul_AB == \A) ? \B : \A;
|
||||
IdString sgn_AC = (mul_other == \A) ? \B_SIGNED : \A_SIGNED;
|
||||
IdString sgn_B = (mul_other == \A) ? \A_SIGNED : \B_SIGNED;
|
||||
|
||||
SigSpec sig_A = port(preadd, \A);
|
||||
SigSpec sig_C = port(preadd, \B);
|
||||
SigSpec sig_B = port(mul, mul_other);
|
||||
|
||||
sig_A.extend_u0(18, false);
|
||||
sig_C.extend_u0(18, false);
|
||||
sig_B.extend_u0(18, false);
|
||||
|
||||
mac->setPort(\A, sig_A.extract(0, 18));
|
||||
mac->setPort(\C, sig_C.extract(0, 18));
|
||||
mac->setPort(\B, sig_B.extract(0, 18));
|
||||
|
||||
if (pipe_ff) {
|
||||
mac->setPort(\Y, port(pipe_ff, \Q));
|
||||
mac->setPort(\CLK, port(pipe_ff, \CLK));
|
||||
mac->setParam(\PIPELINED, State::S1);
|
||||
if (GetSize(port(mul, \A)) >= GetSize(preadd_out) && port(mul, \A).extract(0, GetSize(preadd_out)) == preadd_out) {
|
||||
actual_mul_AB = \A;
|
||||
} else if (GetSize(port(mul, \B)) >= GetSize(preadd_out) && port(mul, \B).extract(0, GetSize(preadd_out)) == preadd_out) {
|
||||
actual_mul_AB = \B;
|
||||
} else {
|
||||
mac->setPort(\Y, port(mul, \Y));
|
||||
mac->setPort(\CLK, State::S0);
|
||||
mac->setParam(\PIPELINED, State::S0);
|
||||
reject;
|
||||
}
|
||||
|
||||
mac->setParam(\A_SIGNED, mul->getParam(sgn_AC));
|
||||
mac->setParam(\B_SIGNED, mul->getParam(sgn_B));
|
||||
mac->setParam(\C_SIGNED, mul->getParam(sgn_AC));
|
||||
{
|
||||
Cell *mac = module->addCell(NEW_ID, "$__NX_PREADD18X18");
|
||||
|
||||
IdString mul_other = (actual_mul_AB == \A) ? \B : \A;
|
||||
IdString sgn_AC = (mul_other == \A) ? \B_SIGNED : \A_SIGNED;
|
||||
IdString sgn_B = (mul_other == \A) ? \A_SIGNED : \B_SIGNED;
|
||||
|
||||
SigSpec sig_A = port(preadd, \A);
|
||||
SigSpec sig_C = port(preadd, \B);
|
||||
SigSpec sig_B = port(mul, mul_other);
|
||||
|
||||
sig_A.extend_u0(18, false);
|
||||
sig_C.extend_u0(18, false);
|
||||
sig_B.extend_u0(18, false);
|
||||
|
||||
mac->setPort(\A, sig_A.extract(0, 18));
|
||||
mac->setPort(\C, sig_C.extract(0, 18));
|
||||
mac->setPort(\B, sig_B.extract(0, 18));
|
||||
|
||||
if (pipe_ff) {
|
||||
mac->setPort(\Y, port(pipe_ff, \Q));
|
||||
mac->setPort(\CLK, port(pipe_ff, \CLK));
|
||||
mac->setParam(\PIPELINED, State::S1);
|
||||
} else {
|
||||
mac->setPort(\Y, port(mul, \Y));
|
||||
mac->setPort(\CLK, State::S0);
|
||||
mac->setParam(\PIPELINED, State::S0);
|
||||
}
|
||||
|
||||
mac->setParam(\A_SIGNED, mul->getParam(sgn_AC));
|
||||
mac->setParam(\B_SIGNED, mul->getParam(sgn_B));
|
||||
mac->setParam(\C_SIGNED, mul->getParam(sgn_AC));
|
||||
|
||||
if (pipe_ff) autoremove(pipe_ff);
|
||||
autoremove(mul);
|
||||
autoremove(preadd);
|
||||
}
|
||||
|
||||
if (pipe_ff) autoremove(pipe_ff);
|
||||
autoremove(mul);
|
||||
autoremove(preadd);
|
||||
accept;
|
||||
endcode
|
||||
|
||||
|
|
@ -136,30 +162,47 @@ match mul0
|
|||
endmatch
|
||||
|
||||
code
|
||||
Cell *mac = module->addCell(NEW_ID, "$__NX_MAC9X9WIDE_4LANE");
|
||||
bool is_signed = mul0->getParam(\A_SIGNED).as_bool();
|
||||
auto ext9 = [&](SigSpec s) {
|
||||
s.extend_u0(9, is_signed);
|
||||
return s;
|
||||
};
|
||||
|
||||
mac->setPort(\A0, ext9(port(mul0, \A)));
|
||||
mac->setPort(\B0, ext9(port(mul0, \B)));
|
||||
mac->setPort(\A1, ext9(port(mul1, \A)));
|
||||
mac->setPort(\B1, ext9(port(mul1, \B)));
|
||||
mac->setPort(\A2, ext9(port(mul2, \A)));
|
||||
mac->setPort(\B2, ext9(port(mul2, \B)));
|
||||
mac->setPort(\A3, ext9(port(mul3, \A)));
|
||||
mac->setPort(\B3, ext9(port(mul3, \B)));
|
||||
mac->setPort(\Y, port(add_top, \Y));
|
||||
mac->setParam(\SIGNED, mul0->getParam(\A_SIGNED));
|
||||
if (
|
||||
mul0->getParam(\B_SIGNED).as_bool() != is_signed ||
|
||||
mul1->getParam(\A_SIGNED).as_bool() != is_signed ||
|
||||
mul1->getParam(\B_SIGNED).as_bool() != is_signed ||
|
||||
mul2->getParam(\A_SIGNED).as_bool() != is_signed ||
|
||||
mul2->getParam(\B_SIGNED).as_bool() != is_signed ||
|
||||
mul3->getParam(\A_SIGNED).as_bool() != is_signed ||
|
||||
mul3->getParam(\B_SIGNED).as_bool() != is_signed
|
||||
) {
|
||||
reject;
|
||||
}
|
||||
|
||||
{
|
||||
Cell *mac = module->addCell(NEW_ID, "$__NX_MAC9X9WIDE_4LANE");
|
||||
|
||||
auto ext9 = [&](SigSpec s) {
|
||||
s.extend_u0(9, is_signed);
|
||||
return s;
|
||||
};
|
||||
|
||||
mac->setPort(\A0, ext9(port(mul0, \A)));
|
||||
mac->setPort(\B0, ext9(port(mul0, \B)));
|
||||
mac->setPort(\A1, ext9(port(mul1, \A)));
|
||||
mac->setPort(\B1, ext9(port(mul1, \B)));
|
||||
mac->setPort(\A2, ext9(port(mul2, \A)));
|
||||
mac->setPort(\B2, ext9(port(mul2, \B)));
|
||||
mac->setPort(\A3, ext9(port(mul3, \A)));
|
||||
mac->setPort(\B3, ext9(port(mul3, \B)));
|
||||
mac->setPort(\Y, port(add_top, \Y));
|
||||
mac->setParam(\SIGNED, is_signed ? State::S1 : State::S0);
|
||||
|
||||
autoremove(add_top);
|
||||
autoremove(add_mid);
|
||||
autoremove(add_bot);
|
||||
autoremove(mul0);
|
||||
autoremove(mul1);
|
||||
autoremove(mul2);
|
||||
autoremove(mul3);
|
||||
}
|
||||
|
||||
autoremove(add_top);
|
||||
autoremove(add_mid);
|
||||
autoremove(add_bot);
|
||||
autoremove(mul0);
|
||||
autoremove(mul1);
|
||||
autoremove(mul2);
|
||||
autoremove(mul3);
|
||||
accept;
|
||||
endcode
|
||||
endcode
|
||||
Loading…
Reference in New Issue