mirror of
https://github.com/YosysHQ/yosys
synced 2026-05-30 21:57:47 +00:00
Add support for subtraction in preadder
This commit is contained in:
parent
6dbe03f0f5
commit
44afd4bbdd
2 changed files with 44 additions and 8 deletions
|
|
@ -263,6 +263,7 @@ void xilinx_dsp_pack(xilinx_dsp_pm &pm)
|
||||||
log("Analysing %s.%s for Xilinx DSP packing.\n", log_id(pm.module), log_id(st.dsp));
|
log("Analysing %s.%s for Xilinx DSP packing.\n", log_id(pm.module), log_id(st.dsp));
|
||||||
|
|
||||||
log_debug("preAdd: %s\n", log_id(st.preAdd, "--"));
|
log_debug("preAdd: %s\n", log_id(st.preAdd, "--"));
|
||||||
|
log_debug("preSub: %s\n", log_id(st.preSub, "--"));
|
||||||
log_debug("ffAD: %s\n", log_id(st.ffAD, "--"));
|
log_debug("ffAD: %s\n", log_id(st.ffAD, "--"));
|
||||||
log_debug("ffA2: %s\n", log_id(st.ffA2, "--"));
|
log_debug("ffA2: %s\n", log_id(st.ffA2, "--"));
|
||||||
log_debug("ffA1: %s\n", log_id(st.ffA1, "--"));
|
log_debug("ffA1: %s\n", log_id(st.ffA1, "--"));
|
||||||
|
|
@ -278,17 +279,22 @@ void xilinx_dsp_pack(xilinx_dsp_pm &pm)
|
||||||
|
|
||||||
Cell *cell = st.dsp;
|
Cell *cell = st.dsp;
|
||||||
|
|
||||||
if (st.preAdd) {
|
if (st.preAdd || st.preSub) {
|
||||||
log(" preadder %s (%s)\n", log_id(st.preAdd), log_id(st.preAdd->type));
|
Cell* preAdder = st.preAdd ? st.preAdd : st.preSub;
|
||||||
bool A_SIGNED = st.preAdd->getParam(ID::A_SIGNED).as_bool();
|
|
||||||
bool D_SIGNED = st.preAdd->getParam(ID::B_SIGNED).as_bool();
|
log(" preadder %s (%s)\n", log_id(preAdder), log_id(preAdder->type));
|
||||||
if (st.sigA == st.preAdd->getPort(ID::B))
|
bool A_SIGNED = preAdder->getParam(ID::A_SIGNED).as_bool();
|
||||||
|
bool D_SIGNED = preAdder->getParam(ID::B_SIGNED).as_bool();
|
||||||
|
if (st.sigA == preAdder->getPort(ID::B))
|
||||||
std::swap(A_SIGNED, D_SIGNED);
|
std::swap(A_SIGNED, D_SIGNED);
|
||||||
st.sigA.extend_u0(30, A_SIGNED);
|
st.sigA.extend_u0(30, A_SIGNED);
|
||||||
st.sigD.extend_u0(25, D_SIGNED);
|
st.sigD.extend_u0(25, D_SIGNED);
|
||||||
cell->setPort(ID::A, st.sigA);
|
cell->setPort(ID::A, st.sigA);
|
||||||
cell->setPort(ID::D, st.sigD);
|
cell->setPort(ID::D, st.sigD);
|
||||||
cell->setPort(ID(INMODE), Const::from_string("00100"));
|
if (preAdder->type == ID($add))
|
||||||
|
cell->setPort(ID(INMODE), Const::from_string("00100"));
|
||||||
|
else
|
||||||
|
cell->setPort(ID(INMODE), Const::from_string("01100"));
|
||||||
|
|
||||||
if (st.ffAD) {
|
if (st.ffAD) {
|
||||||
if (st.ffAD->type.in(ID($dffe), ID($sdffe))) {
|
if (st.ffAD->type.in(ID($dffe), ID($sdffe))) {
|
||||||
|
|
@ -303,7 +309,7 @@ void xilinx_dsp_pack(xilinx_dsp_pm &pm)
|
||||||
|
|
||||||
cell->setParam(ID(USE_DPORT), Const("TRUE"));
|
cell->setParam(ID(USE_DPORT), Const("TRUE"));
|
||||||
|
|
||||||
pm.autoremove(st.preAdd);
|
pm.autoremove(preAdder);
|
||||||
}
|
}
|
||||||
if (st.postAdd) {
|
if (st.postAdd) {
|
||||||
log(" postadder %s (%s)\n", log_id(st.postAdd), log_id(st.postAdd->type));
|
log(" postadder %s (%s)\n", log_id(st.postAdd), log_id(st.postAdd->type));
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,8 @@
|
||||||
// If ADREG matched, treat 'A' input as input of ADREG
|
// If ADREG matched, treat 'A' input as input of ADREG
|
||||||
// ( 3) Match the driver of the 'A' and 'D' inputs for a possible $add cell
|
// ( 3) Match the driver of the 'A' and 'D' inputs for a possible $add cell
|
||||||
// (pre-adder)
|
// (pre-adder)
|
||||||
|
// (3.1) Match the driver of the 'A' and 'D' inputs for a possible $sub cell
|
||||||
|
// (pre-adder)
|
||||||
// ( 4) If pre-adder was present, find match 'A' input for A2REG
|
// ( 4) If pre-adder was present, find match 'A' input for A2REG
|
||||||
// If pre-adder was not present, move ADREG to A2REG
|
// If pre-adder was not present, move ADREG to A2REG
|
||||||
// If A2REG, then match 'A' input for A1REG
|
// If A2REG, then match 'A' input for A1REG
|
||||||
|
|
@ -152,13 +154,41 @@ code sigA sigD
|
||||||
}
|
}
|
||||||
endcode
|
endcode
|
||||||
|
|
||||||
|
// (3.1) Match the driver of the 'A' and 'D' inputs for a possible $sub cell
|
||||||
|
// (pre-adder)
|
||||||
|
match preSub
|
||||||
|
if sigD.empty() || sigD.is_fully_zero()
|
||||||
|
// Ensure that preAdder not already used
|
||||||
|
if param(dsp, \USE_DPORT).decode_string() == "FALSE"
|
||||||
|
if port(dsp, \INMODE, Const(0, 5)).is_fully_zero()
|
||||||
|
|
||||||
|
select preSub->type.in($sub)
|
||||||
|
// Output has to be 25 bits or less
|
||||||
|
select GetSize(port(preSub, \Y)) <= 25
|
||||||
|
select nusers(port(preSub, \Y)) == 2
|
||||||
|
// D port has to be 25 bits or less
|
||||||
|
select GetSize(port(preSub, \A)) <= 25
|
||||||
|
// A port has to be 30 bits or less
|
||||||
|
select GetSize(port(preSub, \B)) <= 30
|
||||||
|
index <SigSpec> port(preSub, \Y) === sigA
|
||||||
|
|
||||||
|
optional
|
||||||
|
endmatch
|
||||||
|
|
||||||
|
code sigA sigD
|
||||||
|
if (preSub) {
|
||||||
|
sigD = port(preSub, \A);
|
||||||
|
sigA = port(preSub, \B);
|
||||||
|
}
|
||||||
|
endcode
|
||||||
|
|
||||||
// (4) If pre-adder was present, find match 'A' input for A2REG
|
// (4) If pre-adder was present, find match 'A' input for A2REG
|
||||||
// If pre-adder was not present, move ADREG to A2REG
|
// If pre-adder was not present, move ADREG to A2REG
|
||||||
// Then match 'A' input for A1REG
|
// Then match 'A' input for A1REG
|
||||||
code argQ ffAD sigA clock ffA2 ffA1
|
code argQ ffAD sigA clock ffA2 ffA1
|
||||||
// Only search for ffA2 if there was a pre-adder
|
// Only search for ffA2 if there was a pre-adder
|
||||||
// (otherwise ffA2 would have been matched as ffAD)
|
// (otherwise ffA2 would have been matched as ffAD)
|
||||||
if (preAdd) {
|
if (preAdd || preSub) {
|
||||||
if (param(dsp, \AREG).as_int() == 0) {
|
if (param(dsp, \AREG).as_int() == 0) {
|
||||||
argQ = sigA;
|
argQ = sigA;
|
||||||
subpattern(in_dffe);
|
subpattern(in_dffe);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue