mirror of
https://github.com/YosysHQ/yosys
synced 2026-02-13 20:33:04 +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_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("ffA2: %s\n", log_id(st.ffA2, "--"));
|
||||
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;
|
||||
|
||||
if (st.preAdd) {
|
||||
log(" preadder %s (%s)\n", log_id(st.preAdd), log_id(st.preAdd->type));
|
||||
bool A_SIGNED = st.preAdd->getParam(ID::A_SIGNED).as_bool();
|
||||
bool D_SIGNED = st.preAdd->getParam(ID::B_SIGNED).as_bool();
|
||||
if (st.sigA == st.preAdd->getPort(ID::B))
|
||||
if (st.preAdd || st.preSub) {
|
||||
Cell* preAdder = st.preAdd ? st.preAdd : st.preSub;
|
||||
|
||||
log(" preadder %s (%s)\n", log_id(preAdder), log_id(preAdder->type));
|
||||
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);
|
||||
st.sigA.extend_u0(30, A_SIGNED);
|
||||
st.sigD.extend_u0(25, D_SIGNED);
|
||||
cell->setPort(ID::A, st.sigA);
|
||||
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->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"));
|
||||
|
||||
pm.autoremove(st.preAdd);
|
||||
pm.autoremove(preAdder);
|
||||
}
|
||||
if (st.postAdd) {
|
||||
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
|
||||
// ( 3) Match the driver of the 'A' and 'D' inputs for a possible $add cell
|
||||
// (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
|
||||
// If pre-adder was not present, move ADREG to A2REG
|
||||
// If A2REG, then match 'A' input for A1REG
|
||||
|
|
@ -152,13 +154,41 @@ code sigA sigD
|
|||
}
|
||||
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
|
||||
// If pre-adder was not present, move ADREG to A2REG
|
||||
// Then match 'A' input for A1REG
|
||||
code argQ ffAD sigA clock ffA2 ffA1
|
||||
// Only search for ffA2 if there was a pre-adder
|
||||
// (otherwise ffA2 would have been matched as ffAD)
|
||||
if (preAdd) {
|
||||
if (preAdd || preSub) {
|
||||
if (param(dsp, \AREG).as_int() == 0) {
|
||||
argQ = sigA;
|
||||
subpattern(in_dffe);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue