3
0
Fork 0
mirror of https://github.com/YosysHQ/yosys synced 2025-10-01 13:39:30 +00:00

Add comments for xilinx_dsp

This commit is contained in:
Eddie Hung 2019-10-04 12:40:34 -07:00
parent b47bb5c810
commit cf82b38478
3 changed files with 134 additions and 6 deletions

View file

@ -1,3 +1,25 @@
// This file describes the second of three pattern matcher setups that
// forms the `xilinx_dsp` pass described in xilinx_dsp.cc
// At a high level, it works as follows:
// (1) Starting from a DSP48E1 cell that (a) doesn't have a CREG already,
// and (b) uses the 'C' port
// (2) Match the driver of the 'C' input to a possible $dff cell (CREG)
// (attached to at most two $mux cells that implement clock-enable or
// reset functionality, using a subpattern discussed below)
// Notes:
// - Separating out CREG packing is necessary since there is no guarantee
// that the cell ordering corresponds to the "expected" case (i.e. the order
// in which they appear in the source) thus the possiblity existed that a
// register got packed as a CREG into a downstream DSP that should have
// otherwise been a PREG of an upstream DSP that had not been visited yet
// - The reason this is separated out from the xilinx_dsp.pmg file is
// for efficiency --- each *.pmg file creates a class of the same basename,
// which when constructed, creates a custom database tailored to the
// pattern(s) contained within. Since the pattern in this file must be
// executed after the pattern contained in xilinx_dsp.pmg, it is necessary
// to reconstruct this database. Separating the two patterns into
// independent files causes two smaller, more specific, databases.
pattern xilinx_dsp_packC
udata <std::function<SigSpec(const SigSpec&)>> unextend
@ -15,13 +37,15 @@ udata <SigBit> dffclock
udata <Cell*> dff dffcemux dffrstmux
udata <bool> dffcepol dffrstpol
// (1) Starting from a DSP48E1 cell that (a) doesn't have a CREG already,
// and (b) uses the 'C' port
match dsp
select dsp->type.in(\DSP48E1)
select param(dsp, \CREG, 1).as_int() == 0
select nusers(port(dsp, \C, SigSpec())) > 1
endmatch
code argQ ffC ffCcemux ffCrstmux ffCcepol ffCrstpol sigC sigP clock
code sigC sigP
unextend = [](const SigSpec &sig) {
int i;
for (i = GetSize(sig)-1; i > 0; i--)
@ -47,7 +71,14 @@ code argQ ffC ffCcemux ffCrstmux ffCcepol ffCrstpol sigC sigP clock
}
else
sigP = P;
endcode
// (2) Match the driver of the 'C' input to a possible $dff cell (CREG)
// (attached to at most two $mux cells that implement clock-enable or
// reset functionality, using a subpattern discussed below)
code argQ ffC ffCcemux ffCrstmux ffCcepol ffCrstpol sigC clock
// TODO: Any downside to allowing this?
// If this DSP implements an accumulator, do not attempt to match
if (sigC == sigP)
reject;