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:
parent
b47bb5c810
commit
cf82b38478
3 changed files with 134 additions and 6 deletions
|
@ -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;
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue