mirror of https://github.com/YosysHQ/yosys.git
add PolarFire FPGA support
This commit is contained in:
parent
a739e21a5f
commit
acddc36389
|
@ -37,6 +37,17 @@ $(eval $(call add_extra_objs,passes/pmgen/xilinx_dsp_cascade_pm.h))
|
||||||
|
|
||||||
# --------------------------------------
|
# --------------------------------------
|
||||||
|
|
||||||
|
OBJS += passes/pmgen/mchp_dsp.o
|
||||||
|
GENFILES += passes/pmgen/mchp_dsp_pm.h
|
||||||
|
GENFILES += passes/pmgen/mchp_dsp_CREG_pm.h
|
||||||
|
GENFILES += passes/pmgen/mchp_dsp_cascade_pm.h
|
||||||
|
passes/pmgen/mchp_dsp.o: passes/pmgen/mchp_dsp_pm.h passes/pmgen/mchp_dsp_CREG_pm.h passes/pmgen/mchp_dsp_cascade_pm.h
|
||||||
|
$(eval $(call add_extra_objs,passes/pmgen/mchp_dsp_pm.h))
|
||||||
|
$(eval $(call add_extra_objs,passes/pmgen/mchp_dsp_CREG_pm.h))
|
||||||
|
$(eval $(call add_extra_objs,passes/pmgen/mchp_dsp_cascade_pm.h))
|
||||||
|
|
||||||
|
# --------------------------------------
|
||||||
|
|
||||||
OBJS += passes/pmgen/peepopt.o
|
OBJS += passes/pmgen/peepopt.o
|
||||||
GENFILES += passes/pmgen/peepopt_pm.h
|
GENFILES += passes/pmgen/peepopt_pm.h
|
||||||
passes/pmgen/peepopt.o: passes/pmgen/peepopt_pm.h
|
passes/pmgen/peepopt.o: passes/pmgen/peepopt_pm.h
|
||||||
|
|
|
@ -0,0 +1,373 @@
|
||||||
|
/*
|
||||||
|
ISC License
|
||||||
|
|
||||||
|
Copyright (C) 2024 Microchip Technology Inc. and its subsidiaries
|
||||||
|
|
||||||
|
Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
purpose with or without fee is hereby granted, provided that the above
|
||||||
|
copyright notice and this permission notice appear in all copies.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "kernel/yosys.h"
|
||||||
|
#include "kernel/sigtools.h"
|
||||||
|
#include <deque>
|
||||||
|
|
||||||
|
USING_YOSYS_NAMESPACE
|
||||||
|
PRIVATE_NAMESPACE_BEGIN
|
||||||
|
|
||||||
|
#include "passes/pmgen/mchp_dsp_pm.h"
|
||||||
|
#include "passes/pmgen/mchp_dsp_CREG_pm.h"
|
||||||
|
#include "passes/pmgen/mchp_dsp_cascade_pm.h"
|
||||||
|
|
||||||
|
void mchp_dsp_pack(mchp_dsp_pm &pm)
|
||||||
|
{
|
||||||
|
auto &st = pm.st_mchp_dsp_pack;
|
||||||
|
|
||||||
|
log("Analysing %s.%s for MCHP MACC_PA packing.\n", log_id(pm.module), log_id(st.dsp));
|
||||||
|
|
||||||
|
Cell *cell = st.dsp;
|
||||||
|
//pack pre-adder
|
||||||
|
if (st.preAdderStatic) {
|
||||||
|
SigSpec &pasub = cell->connections_.at(ID(PASUB));
|
||||||
|
log(" static PASUB preadder %s (%s)\n", log_id(st.preAdderStatic), log_id(st.preAdderStatic->type));
|
||||||
|
bool D_SIGNED = st.preAdderStatic->getParam(ID::B_SIGNED).as_bool();
|
||||||
|
bool B_SIGNED = st.preAdderStatic->getParam(ID::A_SIGNED).as_bool();
|
||||||
|
st.sigB.extend_u0(18, B_SIGNED);
|
||||||
|
st.sigD.extend_u0(18, D_SIGNED);
|
||||||
|
if (st.moveBtoA)
|
||||||
|
{
|
||||||
|
cell->setPort(ID::A, st.sigA); // if pre-adder feeds into A, original sigB will be moved to port A
|
||||||
|
}
|
||||||
|
cell->setPort(ID::B, st.sigB);
|
||||||
|
cell->setPort(ID::D, st.sigD);
|
||||||
|
// MACC_PA supports both addition and subtraction with the pre-adder.
|
||||||
|
// Affects the sign of the 'D' port.
|
||||||
|
if (st.preAdderStatic->type == ID($add))
|
||||||
|
pasub[0] = State::S0;
|
||||||
|
else if (st.preAdderStatic->type == ID($sub))
|
||||||
|
pasub[0] = State::S1;
|
||||||
|
else
|
||||||
|
log_assert(!"strange pre-adder type");
|
||||||
|
|
||||||
|
pm.autoremove(st.preAdderStatic);
|
||||||
|
}
|
||||||
|
//pack post-adder
|
||||||
|
if (st.postAdderStatic) {
|
||||||
|
log(" postadder %s (%s)\n", log_id(st.postAdderStatic), log_id(st.postAdderStatic->type));
|
||||||
|
SigSpec &sub = cell->connections_.at(ID(SUB));
|
||||||
|
// Post-adder in MACC_PA also supports subtraction
|
||||||
|
// Determines the sign of the output from the multiplier.
|
||||||
|
if (st.postAdderStatic->type == ID($add))
|
||||||
|
sub[0] = State::S0;
|
||||||
|
else if (st.postAdderStatic->type == ID($sub))
|
||||||
|
sub[0] = State::S1;
|
||||||
|
else
|
||||||
|
log_assert(!"strange post-adder type");
|
||||||
|
|
||||||
|
if (st.useFeedBack) {
|
||||||
|
cell->setPort(ID(CDIN_FDBK_SEL), {State::S0, State::S1});
|
||||||
|
} else {
|
||||||
|
st.sigC.extend_u0(48, st.postAdderStatic->getParam(ID::A_SIGNED).as_bool());
|
||||||
|
cell->setPort(ID::C, st.sigC);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
pm.autoremove(st.postAdderStatic);
|
||||||
|
}
|
||||||
|
|
||||||
|
// pack registers
|
||||||
|
if (st.clock != SigBit())
|
||||||
|
{
|
||||||
|
cell->setPort(ID::CLK, st.clock);
|
||||||
|
|
||||||
|
// function to absorb a register
|
||||||
|
auto f = [&pm,cell](SigSpec &A, Cell* ff, IdString ceport, IdString rstport, IdString bypass) {
|
||||||
|
|
||||||
|
// input/output ports
|
||||||
|
SigSpec D = ff->getPort(ID::D);
|
||||||
|
SigSpec Q = pm.sigmap(ff->getPort(ID::Q));
|
||||||
|
|
||||||
|
if (!A.empty())
|
||||||
|
A.replace(Q, D);
|
||||||
|
if (rstport != IdString()) {
|
||||||
|
if (ff->type.in(ID($sdff), ID($sdffe))) {
|
||||||
|
SigSpec srst = ff->getPort(ID::SRST);
|
||||||
|
bool rstpol_n = !ff->getParam(ID::SRST_POLARITY).as_bool();
|
||||||
|
// active low sync rst
|
||||||
|
cell->setPort(rstport, rstpol_n ? srst : pm.module->Not(NEW_ID, srst));
|
||||||
|
} else if (ff->type.in(ID($adff), ID($adffe))) {
|
||||||
|
SigSpec arst = ff->getPort(ID::ARST);
|
||||||
|
bool rstpol_n = !ff->getParam(ID::ARST_POLARITY).as_bool();
|
||||||
|
// active low async rst
|
||||||
|
cell->setPort(rstport, rstpol_n ? arst : pm.module->Not(NEW_ID, arst));
|
||||||
|
} else {
|
||||||
|
// active low async/sync rst
|
||||||
|
cell->setPort(rstport, State::S1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ff->type.in(ID($dffe), ID($sdffe), ID($adffe))) {
|
||||||
|
SigSpec ce = ff->getPort(ID::EN);
|
||||||
|
bool cepol = ff->getParam(ID::EN_POLARITY).as_bool();
|
||||||
|
// enables are all active high
|
||||||
|
cell->setPort(ceport, cepol ? ce : pm.module->Not(NEW_ID, ce));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// enables are all active high
|
||||||
|
cell->setPort(ceport, State::S1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// bypass set to 0
|
||||||
|
cell->setPort(bypass, State::S0);
|
||||||
|
|
||||||
|
|
||||||
|
for (auto c : Q.chunks()) {
|
||||||
|
auto it = c.wire->attributes.find(ID::init);
|
||||||
|
if (it == c.wire->attributes.end())
|
||||||
|
continue;
|
||||||
|
for (int i = c.offset; i < c.offset+c.width; i++) {
|
||||||
|
log_assert(it->second[i] == State::S0 || it->second[i] == State::Sx);
|
||||||
|
it->second[i] = State::Sx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// NOTE: flops are not autoremoved because it is possible that they
|
||||||
|
// are only partially absorbed into DSP, or have fanouts.
|
||||||
|
if (st.ffA) {
|
||||||
|
SigSpec A = cell->getPort(ID::A);
|
||||||
|
if (st.ffA) {
|
||||||
|
f(A, st.ffA, ID(A_EN), ID(A_SRST_N), ID(A_BYPASS));
|
||||||
|
}
|
||||||
|
pm.add_siguser(A, cell);
|
||||||
|
cell->setPort(ID::A, A);
|
||||||
|
}
|
||||||
|
if (st.ffB) {
|
||||||
|
SigSpec B = cell->getPort(ID::B);
|
||||||
|
if (st.ffB) {
|
||||||
|
f(B, st.ffB, ID(B_EN), ID(B_SRST_N), ID(B_BYPASS));
|
||||||
|
}
|
||||||
|
pm.add_siguser(B, cell);
|
||||||
|
cell->setPort(ID::B, B);
|
||||||
|
}
|
||||||
|
if (st.ffD) {
|
||||||
|
SigSpec D = cell->getPort(ID::D);
|
||||||
|
if (st.ffD->type.in(ID($adff), ID($adffe))) {
|
||||||
|
f(D, st.ffD, ID(D_EN), ID(D_ARST_N), ID(D_BYPASS));
|
||||||
|
} else {
|
||||||
|
f(D, st.ffD, ID(D_EN), ID(D_SRST_N), ID(D_BYPASS));
|
||||||
|
}
|
||||||
|
|
||||||
|
pm.add_siguser(D, cell);
|
||||||
|
cell->setPort(ID::D, D);
|
||||||
|
}
|
||||||
|
if (st.ffP) {
|
||||||
|
SigSpec P; // unused
|
||||||
|
f(P, st.ffP, ID(P_EN), ID(P_SRST_N), ID(P_BYPASS));
|
||||||
|
st.ffP->connections_.at(ID::Q).replace(st.sigP, pm.module->addWire(NEW_ID, GetSize(st.sigP)));
|
||||||
|
}
|
||||||
|
|
||||||
|
log(" clock: %s (%s)\n", log_signal(st.clock), "posedge");
|
||||||
|
|
||||||
|
if (st.ffA)
|
||||||
|
log(" \t ffA:%s\n", log_id(st.ffA));
|
||||||
|
if (st.ffB)
|
||||||
|
log(" \t ffB:%s\n", log_id(st.ffB));
|
||||||
|
if (st.ffD)
|
||||||
|
log(" \t ffD:%s\n", log_id(st.ffD));
|
||||||
|
if (st.ffP)
|
||||||
|
log(" \t ffP:%s\n", log_id(st.ffP));
|
||||||
|
}
|
||||||
|
log("\n");
|
||||||
|
|
||||||
|
SigSpec P = st.sigP;
|
||||||
|
if (GetSize(P) < 48)
|
||||||
|
P.append(pm.module->addWire(NEW_ID, 48-GetSize(P)));
|
||||||
|
cell->setPort(ID::P, P);
|
||||||
|
|
||||||
|
pm.blacklist(cell);
|
||||||
|
}
|
||||||
|
|
||||||
|
// For packing cascaded DSPs
|
||||||
|
void mchp_dsp_packC(mchp_dsp_CREG_pm &pm)
|
||||||
|
{
|
||||||
|
auto &st = pm.st_mchp_dsp_packC;
|
||||||
|
|
||||||
|
log_debug("Analysing %s.%s for MCHP DSP packing (REG_C).\n", log_id(pm.module), log_id(st.dsp));
|
||||||
|
log_debug("ffC: %s\n", log_id(st.ffC, "--"));
|
||||||
|
|
||||||
|
Cell *cell = st.dsp;
|
||||||
|
|
||||||
|
if (st.clock != SigBit())
|
||||||
|
{
|
||||||
|
cell->setPort(ID::CLK, st.clock);
|
||||||
|
|
||||||
|
// same function as above, used for the last CREG we need to absorb
|
||||||
|
auto f = [&pm,cell](SigSpec &A, Cell* ff, IdString ceport, IdString rstport, IdString bypass) {
|
||||||
|
|
||||||
|
// input/output ports
|
||||||
|
SigSpec D = ff->getPort(ID::D);
|
||||||
|
SigSpec Q = pm.sigmap(ff->getPort(ID::Q));
|
||||||
|
if (!A.empty())
|
||||||
|
A.replace(Q, D);
|
||||||
|
if (rstport != IdString()) {
|
||||||
|
if (ff->type.in(ID($sdff), ID($sdffe))) {
|
||||||
|
SigSpec srst = ff->getPort(ID::SRST);
|
||||||
|
bool rstpol_n = !ff->getParam(ID::SRST_POLARITY).as_bool();
|
||||||
|
// active low sync rst
|
||||||
|
cell->setPort(rstport, rstpol_n ? srst : pm.module->Not(NEW_ID, srst));
|
||||||
|
} else if (ff->type.in(ID($adff), ID($adffe))) {
|
||||||
|
SigSpec arst = ff->getPort(ID::ARST);
|
||||||
|
bool rstpol_n = !ff->getParam(ID::ARST_POLARITY).as_bool();
|
||||||
|
// active low async rst
|
||||||
|
cell->setPort(rstport, rstpol_n ? arst : pm.module->Not(NEW_ID, arst));
|
||||||
|
} else {
|
||||||
|
// active low async/sync rst
|
||||||
|
cell->setPort(rstport, State::S1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ff->type.in(ID($dffe), ID($sdffe), ID($adffe))) {
|
||||||
|
SigSpec ce = ff->getPort(ID::EN);
|
||||||
|
bool cepol = ff->getParam(ID::EN_POLARITY).as_bool();
|
||||||
|
// enables are all active high
|
||||||
|
cell->setPort(ceport, cepol ? ce : pm.module->Not(NEW_ID, ce));
|
||||||
|
} else {
|
||||||
|
// enables are all active high
|
||||||
|
cell->setPort(ceport, State::S1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// bypass set to 0
|
||||||
|
cell->setPort(bypass, State::S0);
|
||||||
|
|
||||||
|
|
||||||
|
for (auto c : Q.chunks()) {
|
||||||
|
auto it = c.wire->attributes.find(ID::init);
|
||||||
|
if (it == c.wire->attributes.end())
|
||||||
|
continue;
|
||||||
|
for (int i = c.offset; i < c.offset+c.width; i++) {
|
||||||
|
log_assert(it->second[i] == State::S0 || it->second[i] == State::Sx);
|
||||||
|
it->second[i] = State::Sx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if (st.ffC) {
|
||||||
|
SigSpec C = cell->getPort(ID::C);
|
||||||
|
|
||||||
|
if (st.ffC->type.in(ID($adff), ID($adffe))) {
|
||||||
|
f(C, st.ffC, ID(C_EN), ID(C_ARST_N), ID(C_BYPASS));
|
||||||
|
} else {
|
||||||
|
f(C, st.ffC, ID(C_EN), ID(C_SRST_N), ID(C_BYPASS));
|
||||||
|
}
|
||||||
|
pm.add_siguser(C, cell);
|
||||||
|
cell->setPort(ID::C, C);
|
||||||
|
}
|
||||||
|
|
||||||
|
log(" clock: %s (%s)", log_signal(st.clock), "posedge");
|
||||||
|
|
||||||
|
if (st.ffC)
|
||||||
|
log(" ffC:%s", log_id(st.ffC));
|
||||||
|
log("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
pm.blacklist(cell);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct MchpDspPass : public Pass {
|
||||||
|
MchpDspPass() : Pass("mchp_dsp", "MCHP: pack resources into DSPs") { }
|
||||||
|
void help() override
|
||||||
|
{
|
||||||
|
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
|
||||||
|
log("\n");
|
||||||
|
log(" mchp_dsp [options] [selection]\n");
|
||||||
|
log("\n");
|
||||||
|
log("Pack input registers 'A', 'B', 'C', and 'D' (with optional enable/reset),\n");
|
||||||
|
log("output register 'P' (with optional enable/reset), pre-adder and/or post-adder into\n");
|
||||||
|
log("MCHP DSP resources.\n");
|
||||||
|
log("\n");
|
||||||
|
log("Multiply-accumulate operations using the post-adder with feedback on the 'C'\n");
|
||||||
|
log("input will be folded into the DSP. In this scenario only, the 'C' input can be\n");
|
||||||
|
log("used to override the current accumulation result with a new value. This will\n");
|
||||||
|
log("be added to the multiplier result to form the next accumulation result.\n");
|
||||||
|
log("\n");
|
||||||
|
log("Use of the dedicated 'PCOUT' -> 'PCIN' cascade path is detected for 'P' -> 'C'\n");
|
||||||
|
log("connections (optionally, where 'P' is right-shifted by 17-bits and used as an\n");
|
||||||
|
log("input to the post-adder. This pattern is common for summing partial products to\n");
|
||||||
|
log("implement wide multipliers). Cascade chains are limited to a mazimum length \n");
|
||||||
|
log("of 24 cells, corresponding to PolarFire (pf) devices.\n");
|
||||||
|
log("\n");
|
||||||
|
log("This pass is a no-op if the scratchpad variable 'mchp_dsp.multonly' is set\n");
|
||||||
|
log("to 1.\n");
|
||||||
|
log("\n");
|
||||||
|
log("\n");
|
||||||
|
log(" -family {pf}\n");
|
||||||
|
log(" select the family to target\n");
|
||||||
|
log(" default: pf\n");
|
||||||
|
log("\n");
|
||||||
|
}
|
||||||
|
void execute(std::vector<std::string> args, RTLIL::Design *design) override
|
||||||
|
{
|
||||||
|
log_header(design, "Executing MCHP_DSP pass (pack resources into DSPs).\n");
|
||||||
|
|
||||||
|
std::string family = "pf";
|
||||||
|
size_t argidx;
|
||||||
|
for (argidx = 1; argidx < args.size(); argidx++)
|
||||||
|
{
|
||||||
|
if ((args[argidx] == "-family") && argidx+1 < args.size()) {
|
||||||
|
family = args[++argidx];
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
extra_args(args, argidx, design);
|
||||||
|
|
||||||
|
for (auto module : design->selected_modules()) {
|
||||||
|
|
||||||
|
if (design->scratchpad_get_bool("mchp_dsp.multonly"))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
{
|
||||||
|
// For more details on PolarFire MACC_PA, consult
|
||||||
|
// the "PolarFire FPGA Macro Library Guide"
|
||||||
|
|
||||||
|
// Main pattern matching step to capture a DSP cell.
|
||||||
|
// Match for pre-adder, post-adder, as well as
|
||||||
|
// registers 'A', 'B', 'D', and 'P'. Additionally,
|
||||||
|
// check for an accumulator pattern based on whether
|
||||||
|
// a post-adder and PREG are both present AND
|
||||||
|
// if PREG feeds into this post-adder.
|
||||||
|
mchp_dsp_pm pm(module, module->selected_cells());
|
||||||
|
pm.run_mchp_dsp_pack(mchp_dsp_pack);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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). There existed the possibility
|
||||||
|
// where 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
|
||||||
|
{
|
||||||
|
mchp_dsp_CREG_pm pm(module, module->selected_cells());
|
||||||
|
pm.run_mchp_dsp_packC(mchp_dsp_packC);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Lastly, identify and utilise PCOUT -> PCIN chains
|
||||||
|
{
|
||||||
|
mchp_dsp_cascade_pm pm(module, module->selected_cells());
|
||||||
|
pm.run_mchp_dsp_cascade();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} MchpDspPass;
|
||||||
|
|
||||||
|
PRIVATE_NAMESPACE_END
|
|
@ -0,0 +1,440 @@
|
||||||
|
// ISC License
|
||||||
|
//
|
||||||
|
// Copyright (C) 2024 Microchip Technology Inc. and its subsidiaries
|
||||||
|
//
|
||||||
|
// Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
// purpose with or without fee is hereby granted, provided that the above
|
||||||
|
// copyright notice and this permission notice appear in all copies.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
|
||||||
|
|
||||||
|
// This file describes the main pattern matcher setup (of three total) that
|
||||||
|
// forms the `mchp_dsp` pass described in mchp_dsp.cc - version for
|
||||||
|
// DSP48A/DSP48A1 (Spartan 3A DSP, Spartan 6).
|
||||||
|
// At a high level, it works as follows:
|
||||||
|
// ( 1) Starting from a DSP cell. Capture DSP configurations as states
|
||||||
|
// ( 2) Match for pre-adder
|
||||||
|
// ( 3) Match for post-adder
|
||||||
|
// ( 4) Match register 'A', 'B', 'D', 'P'
|
||||||
|
// ( 5) If post-adder and PREG both present, check if PREG feeds into post-adder.
|
||||||
|
// This indicates an accumulator situation like the ASCII diagram below:
|
||||||
|
// +--------------------------------+
|
||||||
|
// |_________ |
|
||||||
|
// | /-------\ +----+ |
|
||||||
|
// +----+ +-| post- |___|PREG|---+ 'P'
|
||||||
|
// |MULT|------ | adder | +----+
|
||||||
|
// +----+ \-------/
|
||||||
|
|
||||||
|
pattern mchp_dsp_pack
|
||||||
|
|
||||||
|
state <SigBit> clock
|
||||||
|
state <SigSpec> sigA sigB sigC sigD sigP
|
||||||
|
state <Cell*> ffA ffB ffD ffP
|
||||||
|
state <Cell*> preAdderStatic postAdderStatic
|
||||||
|
state <bool> moveBtoA useFeedBack
|
||||||
|
|
||||||
|
// static ports, used to detect dsp configuration
|
||||||
|
state <SigSpec> bypassA bypassB bypassC bypassD bypassP
|
||||||
|
state <SigSpec> bypassPASUB
|
||||||
|
|
||||||
|
// Variables used for subpatterns
|
||||||
|
state <SigSpec> argQ argD
|
||||||
|
udata <bool> allowAsync
|
||||||
|
udata <SigSpec> dffD dffQ
|
||||||
|
udata <SigBit> dffclock
|
||||||
|
udata <Cell*> dff
|
||||||
|
udata <Cell*> u_preAdderStatic u_postAdderStatic
|
||||||
|
udata <IdString> u_postAddAB
|
||||||
|
state <IdString> postAddAB
|
||||||
|
|
||||||
|
// (1) Starting from a DSP cell
|
||||||
|
match dsp
|
||||||
|
select dsp->type.in(\MACC_PA)
|
||||||
|
endmatch
|
||||||
|
|
||||||
|
// detect existing signals connected to DSP
|
||||||
|
// detect configuration ports
|
||||||
|
code sigA sigB sigC sigD clock sigP
|
||||||
|
//helper function to remove unused bits
|
||||||
|
auto unextend = [](const SigSpec &sig) {
|
||||||
|
int i;
|
||||||
|
for (i = GetSize(sig)-1; i > 0; i--)
|
||||||
|
if (sig[i] != sig[i-1])
|
||||||
|
break;
|
||||||
|
// Do not remove non-const sign bit
|
||||||
|
if (sig[i].wire)
|
||||||
|
++i;
|
||||||
|
return sig.extract(0, i);
|
||||||
|
};
|
||||||
|
|
||||||
|
//unextend to remove unused bits
|
||||||
|
sigA = unextend(port(dsp, \A));
|
||||||
|
sigB = unextend(port(dsp, \B));
|
||||||
|
|
||||||
|
//update signals
|
||||||
|
sigC = port(dsp, \C, SigSpec());
|
||||||
|
sigD = port(dsp, \D, SigSpec());
|
||||||
|
|
||||||
|
|
||||||
|
SigSpec P = port(dsp, \P);
|
||||||
|
// Only care about bits that are used
|
||||||
|
int i;
|
||||||
|
for (i = GetSize(P)-1; i >= 0; i--)
|
||||||
|
if (nusers(P[i]) > 1)
|
||||||
|
break;
|
||||||
|
i++;
|
||||||
|
log_assert(nusers(P.extract_end(i)) <= 1);
|
||||||
|
// This sigP could have no users if downstream sinks (e.g. $add) is
|
||||||
|
// narrower than $mul result, for example
|
||||||
|
if (i == 0)
|
||||||
|
reject;
|
||||||
|
sigP = P.extract(0, i);
|
||||||
|
clock = port(dsp, \CLK, SigBit());
|
||||||
|
|
||||||
|
endcode
|
||||||
|
|
||||||
|
// capture static configuration ports
|
||||||
|
code bypassA bypassB bypassC bypassD bypassPASUB bypassP
|
||||||
|
bypassA = port(dsp, \A_BYPASS, SigSpec());
|
||||||
|
bypassB = port(dsp, \B_BYPASS, SigSpec());
|
||||||
|
bypassC = port(dsp, \C_BYPASS, SigSpec());
|
||||||
|
bypassD = port(dsp, \D_BYPASS, SigSpec());
|
||||||
|
bypassPASUB = port(dsp, \PASUB_BYPASS, SigSpec());
|
||||||
|
bypassP = port(dsp, \P_BYPASS, SigSpec());
|
||||||
|
endcode
|
||||||
|
|
||||||
|
// (2) Match for pre-adder
|
||||||
|
//
|
||||||
|
code sigA sigB sigD preAdderStatic moveBtoA
|
||||||
|
subpattern(preAddMatching);
|
||||||
|
preAdderStatic = u_preAdderStatic;
|
||||||
|
moveBtoA = false;
|
||||||
|
|
||||||
|
if (preAdderStatic) {
|
||||||
|
|
||||||
|
if (port(preAdderStatic, \Y) == sigA)
|
||||||
|
{
|
||||||
|
//used for packing
|
||||||
|
moveBtoA = true;
|
||||||
|
|
||||||
|
// sigA should be the input to the multiplier without the preAdd. sigB and sigD should be
|
||||||
|
//the preAdd inputs. If our "A" input into the multiplier is from the preAdd (not sigA), then
|
||||||
|
// we basically swap it.
|
||||||
|
sigA = port(dsp, \B);
|
||||||
|
}
|
||||||
|
|
||||||
|
// port B of preAdderStatic must be mapped to port D of DSP for subtraction
|
||||||
|
sigD = port(preAdderStatic, \B);
|
||||||
|
sigB = port(preAdderStatic, \A);
|
||||||
|
}
|
||||||
|
endcode
|
||||||
|
|
||||||
|
// (3) Match for post-adder
|
||||||
|
//
|
||||||
|
code postAdderStatic sigP sigC
|
||||||
|
u_postAdderStatic = nullptr;
|
||||||
|
subpattern(postAddMatching);
|
||||||
|
postAdderStatic = u_postAdderStatic;
|
||||||
|
|
||||||
|
if (postAdderStatic) {
|
||||||
|
//sigC will be whichever input to the postAdder that is NOT from the multiplier
|
||||||
|
// u_postAddAB is the input to the postAdder from the multiplier
|
||||||
|
sigC = port(postAdderStatic, u_postAddAB == \A ? \B : \A);
|
||||||
|
sigP = port(postAdderStatic, \Y);
|
||||||
|
}
|
||||||
|
endcode
|
||||||
|
|
||||||
|
|
||||||
|
// (4) Matching registers
|
||||||
|
//
|
||||||
|
// 'A' input for REG_A
|
||||||
|
code argQ bypassA sigA clock ffA
|
||||||
|
if (bypassA.is_fully_ones()){
|
||||||
|
argQ = sigA;
|
||||||
|
allowAsync = false;
|
||||||
|
subpattern(in_dffe);
|
||||||
|
if (dff) {
|
||||||
|
ffA = dff;
|
||||||
|
clock = dffclock;
|
||||||
|
sigA = dffD;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
endcode
|
||||||
|
|
||||||
|
// 'B' input for REG_B
|
||||||
|
code argQ bypassB sigB clock ffB
|
||||||
|
if (bypassB.is_fully_ones()){
|
||||||
|
argQ = sigB;
|
||||||
|
allowAsync = false;
|
||||||
|
subpattern(in_dffe);
|
||||||
|
if (dff) {
|
||||||
|
ffB = dff;
|
||||||
|
clock = dffclock;
|
||||||
|
sigB = dffD;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
endcode
|
||||||
|
|
||||||
|
// 'D' input for REG_D
|
||||||
|
code argQ bypassP sigD clock ffD
|
||||||
|
if (bypassD.is_fully_ones()){
|
||||||
|
argQ = sigD;
|
||||||
|
allowAsync = true;
|
||||||
|
subpattern(in_dffe);
|
||||||
|
if (dff) {
|
||||||
|
ffD = dff;
|
||||||
|
clock = dffclock;
|
||||||
|
sigD = dffD;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
endcode
|
||||||
|
|
||||||
|
// 'P' output for REG_P
|
||||||
|
code argD ffP sigP clock bypassP
|
||||||
|
if (bypassP.is_fully_ones() && nusers(sigP) == 2) {
|
||||||
|
argD = sigP;
|
||||||
|
allowAsync = false;
|
||||||
|
subpattern(out_dffe);
|
||||||
|
if (dff) {
|
||||||
|
ffP = dff;
|
||||||
|
clock = dffclock;
|
||||||
|
sigP = dffQ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
endcode
|
||||||
|
|
||||||
|
// (5) If post-adder and PREG both present, check if PREG feeds into post-adder via port C.
|
||||||
|
// This indicates an accumulator situation. Port C can be freed
|
||||||
|
// +--------------------------------+
|
||||||
|
// |_________ |
|
||||||
|
// | /-------\ +----+ |
|
||||||
|
// +----+ +-| post- |___|PREG|---+ 'P'
|
||||||
|
// |MULT|------ | adder | +----+
|
||||||
|
// +----+ \-------/
|
||||||
|
code useFeedBack
|
||||||
|
useFeedBack = false;
|
||||||
|
if (postAdderStatic && ffP) {
|
||||||
|
if (sigC == sigP) {
|
||||||
|
useFeedBack = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
endcode
|
||||||
|
|
||||||
|
// if any cells are absorbed, invoke the callback function
|
||||||
|
code
|
||||||
|
if (preAdderStatic || postAdderStatic)
|
||||||
|
accept;
|
||||||
|
if (ffA || ffB || ffD || ffP)
|
||||||
|
accept;
|
||||||
|
endcode
|
||||||
|
|
||||||
|
|
||||||
|
// #######################
|
||||||
|
// Subpattern for matching against post-adder
|
||||||
|
// Match 'P' output that exclusively drives one of two inputs to an $add
|
||||||
|
// cell (post-adder).
|
||||||
|
// The other input to the adder is assumed to come in from the 'C' input
|
||||||
|
|
||||||
|
subpattern postAddMatching
|
||||||
|
arg sigP
|
||||||
|
|
||||||
|
match postAdd
|
||||||
|
|
||||||
|
select postAdd->type.in($add, $sub)
|
||||||
|
select GetSize(port(postAdd, \Y)) <= 48
|
||||||
|
|
||||||
|
// AB is the port that connects MUL to ADD
|
||||||
|
choice <IdString> AB {\A, \B}
|
||||||
|
select nusers(port(postAdd, AB)) == 2
|
||||||
|
|
||||||
|
// has one input coming from multiplier
|
||||||
|
index <SigBit> port(postAdd, AB)[0] === sigP[0]
|
||||||
|
filter GetSize(port(postAdd, AB)) >= GetSize(sigP)
|
||||||
|
filter port(postAdd, AB).extract(0, GetSize(sigP)) == sigP
|
||||||
|
// Check that remainder of AB is a sign- or zero-extension
|
||||||
|
filter port(postAdd, AB).extract_end(GetSize(sigP)) == SigSpec(sigP[GetSize(sigP)-1], GetSize(port(postAdd, AB))-GetSize(sigP)) || port(postAdd, AB).extract_end(GetSize(sigP)) == SigSpec(State::S0, GetSize(port(postAdd, AB))-GetSize(sigP))
|
||||||
|
|
||||||
|
set postAddAB AB
|
||||||
|
// optional
|
||||||
|
endmatch
|
||||||
|
|
||||||
|
code
|
||||||
|
if (postAdd)
|
||||||
|
{
|
||||||
|
if (postAdd->type.in(ID($sub)) && postAddAB == \A) {
|
||||||
|
// if $sub, the multiplier output must match to $sub.B, otherwise no match
|
||||||
|
} else {
|
||||||
|
u_postAddAB = postAddAB;
|
||||||
|
u_postAdderStatic = postAdd;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
endcode
|
||||||
|
|
||||||
|
|
||||||
|
// #######################
|
||||||
|
// Subpattern for matching against pre-adder
|
||||||
|
// support static PASUB only
|
||||||
|
|
||||||
|
subpattern preAddMatching
|
||||||
|
arg sigA sigB sigD bypassB bypassD bypassPASUB
|
||||||
|
|
||||||
|
code
|
||||||
|
u_preAdderStatic = nullptr;
|
||||||
|
|
||||||
|
// Ensure that preAdder not already used
|
||||||
|
// Assume we can inspect port D to see if its all zeros.
|
||||||
|
if (!(sigD.empty() || sigD.is_fully_zero())) reject;
|
||||||
|
if (!bypassB.is_fully_ones()) reject;
|
||||||
|
if (!bypassD.is_fully_ones()) reject;
|
||||||
|
if (!bypassPASUB.is_fully_ones()) reject;
|
||||||
|
endcode
|
||||||
|
|
||||||
|
match preAdd
|
||||||
|
|
||||||
|
// can handle add or sub
|
||||||
|
select preAdd->type.in($add, $sub)
|
||||||
|
|
||||||
|
// Output has to be 18 bits or less, and only has single fanout
|
||||||
|
select GetSize(port(preAdd, \Y)) <= 18
|
||||||
|
select nusers(port(preAdd, \Y)) == 2
|
||||||
|
|
||||||
|
// Adder inputs must be 18 bits or less
|
||||||
|
select GetSize(port(preAdd, \A)) <= 18
|
||||||
|
select GetSize(port(preAdd, \B)) <= 18
|
||||||
|
|
||||||
|
// Output feeds into one of multiplier input
|
||||||
|
filter port(preAdd, \Y) == sigB || port(preAdd, \Y) == sigA
|
||||||
|
|
||||||
|
// optional
|
||||||
|
endmatch
|
||||||
|
|
||||||
|
code
|
||||||
|
if (preAdd)
|
||||||
|
{
|
||||||
|
u_preAdderStatic = preAdd;
|
||||||
|
}
|
||||||
|
endcode
|
||||||
|
|
||||||
|
// #######################
|
||||||
|
// Subpattern for matching against input registers, based on knowledge of the
|
||||||
|
// 'Q' input.
|
||||||
|
subpattern in_dffe
|
||||||
|
arg argQ clock
|
||||||
|
|
||||||
|
code
|
||||||
|
dff = nullptr;
|
||||||
|
if (argQ.empty())
|
||||||
|
reject;
|
||||||
|
for (const auto &c : argQ.chunks()) {
|
||||||
|
// Abandon matches when 'Q' is a constant
|
||||||
|
if (!c.wire)
|
||||||
|
reject;
|
||||||
|
// Abandon matches when 'Q' has the keep attribute set
|
||||||
|
if (c.wire->get_bool_attribute(\keep))
|
||||||
|
reject;
|
||||||
|
// Abandon matches when 'Q' has a non-zero init attribute set
|
||||||
|
Const init = c.wire->attributes.at(\init, Const());
|
||||||
|
if (!init.empty())
|
||||||
|
for (auto b : init.extract(c.offset, c.width))
|
||||||
|
if (b != State::Sx && b != State::S0)
|
||||||
|
reject;
|
||||||
|
}
|
||||||
|
endcode
|
||||||
|
|
||||||
|
match ff
|
||||||
|
// reg D has async rst
|
||||||
|
// reg A, B has sync rst
|
||||||
|
select ff->type.in($dff, $dffe, $sdff, $sdffe, $adff, $adffe)
|
||||||
|
// does not support clock inversion
|
||||||
|
select param(ff, \CLK_POLARITY).as_bool()
|
||||||
|
|
||||||
|
// it is possible that only part of a dff output matches argQ
|
||||||
|
slice offset GetSize(port(ff, \D))
|
||||||
|
index <SigBit> port(ff, \Q)[offset] === argQ[0]
|
||||||
|
|
||||||
|
// Check that the rest of argQ is present
|
||||||
|
filter GetSize(port(ff, \Q)) >= offset + GetSize(argQ)
|
||||||
|
filter port(ff, \Q).extract(offset, GetSize(argQ)) == argQ
|
||||||
|
|
||||||
|
// only consider async rst flops when flag is set
|
||||||
|
filter !ff->type.in($adff, $adffe) || allowAsync
|
||||||
|
|
||||||
|
// clock must be consistent
|
||||||
|
filter clock == SigBit() || port(ff, \CLK) == clock
|
||||||
|
endmatch
|
||||||
|
|
||||||
|
code argQ
|
||||||
|
// Check that reset value, if present, is fully 0.
|
||||||
|
bool noResetFlop = ff->type.in($dff, $dffe);
|
||||||
|
bool srstZero = ff->type.in($sdff, $sdffe) && param(ff, \SRST_VALUE).is_fully_zero();
|
||||||
|
bool arstZero = ff->type.in($adff, $adffe) && param(ff, \ARST_VALUE).is_fully_zero();
|
||||||
|
bool resetLegal = noResetFlop || srstZero || arstZero;
|
||||||
|
if (resetLegal)
|
||||||
|
{
|
||||||
|
SigSpec Q = port(ff, \Q);
|
||||||
|
dff = ff;
|
||||||
|
dffclock = port(ff, \CLK);
|
||||||
|
dffD = argQ;
|
||||||
|
SigSpec D = port(ff, \D);
|
||||||
|
argQ = Q;
|
||||||
|
dffD.replace(argQ, D);
|
||||||
|
}
|
||||||
|
|
||||||
|
endcode
|
||||||
|
// #######################
|
||||||
|
|
||||||
|
|
||||||
|
subpattern out_dffe
|
||||||
|
arg argD argQ clock
|
||||||
|
|
||||||
|
code
|
||||||
|
dff = nullptr;
|
||||||
|
for (auto c : argD.chunks())
|
||||||
|
// Abandon matches when 'D' has the keep attribute set
|
||||||
|
if (c.wire->get_bool_attribute(\keep))
|
||||||
|
reject;
|
||||||
|
endcode
|
||||||
|
|
||||||
|
match ff
|
||||||
|
select ff->type.in($dff, $dffe, $sdff, $sdffe)
|
||||||
|
// does not support clock inversion
|
||||||
|
select param(ff, \CLK_POLARITY).as_bool()
|
||||||
|
|
||||||
|
slice offset GetSize(port(ff, \D))
|
||||||
|
index <SigBit> port(ff, \D)[offset] === argD[0]
|
||||||
|
|
||||||
|
// Check that the rest of argD is present
|
||||||
|
filter GetSize(port(ff, \D)) >= offset + GetSize(argD)
|
||||||
|
filter port(ff, \D).extract(offset, GetSize(argD)) == argD
|
||||||
|
|
||||||
|
filter clock == SigBit() || port(ff, \CLK) == clock
|
||||||
|
endmatch
|
||||||
|
|
||||||
|
code argQ
|
||||||
|
SigSpec D = port(ff, \D);
|
||||||
|
SigSpec Q = port(ff, \Q);
|
||||||
|
argQ = argD;
|
||||||
|
argQ.replace(D, Q);
|
||||||
|
|
||||||
|
// Abandon matches when 'Q' has a non-zero init attribute set
|
||||||
|
for (auto c : argQ.chunks()) {
|
||||||
|
Const init = c.wire->attributes.at(\init, Const());
|
||||||
|
if (!init.empty())
|
||||||
|
for (auto b : init.extract(c.offset, c.width))
|
||||||
|
if (b != State::Sx && b != State::S0)
|
||||||
|
reject;
|
||||||
|
}
|
||||||
|
|
||||||
|
dff = ff;
|
||||||
|
dffQ = argQ;
|
||||||
|
dffclock = port(ff, \CLK);
|
||||||
|
endcode
|
|
@ -0,0 +1,169 @@
|
||||||
|
// ISC License
|
||||||
|
//
|
||||||
|
// Copyright (C) 2024 Microchip Technology Inc. and its subsidiaries
|
||||||
|
//
|
||||||
|
// Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
// purpose with or without fee is hereby granted, provided that the above
|
||||||
|
// copyright notice and this permission notice appear in all copies.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
|
||||||
|
|
||||||
|
// This file describes the second of three pattern matcher setups that
|
||||||
|
// forms the `mchp_dsp` pass described in mchp_dsp.cc
|
||||||
|
// At a high level, it works as follows:
|
||||||
|
// (1) Starting from a DSP 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:
|
||||||
|
// - Running CREG packing after mchp_dsp_pack 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
|
||||||
|
// where a register got packed as a CREG into a downstream DSP, while it should
|
||||||
|
// have otherwise been a PREG of an upstream DSP that had not been visited.
|
||||||
|
// yet.
|
||||||
|
// - The reason this is separated out from the mchp_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 mchp_dsp.pmg, it is necessary
|
||||||
|
// to reconstruct this database. Separating the two patterns into
|
||||||
|
// independent files causes two smaller, more specific, databases.
|
||||||
|
|
||||||
|
pattern mchp_dsp_packC
|
||||||
|
|
||||||
|
udata <std::function<SigSpec(const SigSpec&)>> unextend
|
||||||
|
state <SigBit> clock
|
||||||
|
state <SigSpec> sigC sigP
|
||||||
|
state <Cell*> ffC
|
||||||
|
|
||||||
|
// Variables used for subpatterns
|
||||||
|
state <SigSpec> argQ argD
|
||||||
|
state <int> ffoffset
|
||||||
|
udata <SigSpec> dffD dffQ
|
||||||
|
udata <SigBit> dffclock
|
||||||
|
udata <Cell*> dff
|
||||||
|
|
||||||
|
// (1) Starting from a DSP cell that (a) doesn't have a CREG already,
|
||||||
|
// and (b) uses the 'C' port
|
||||||
|
match dsp
|
||||||
|
select dsp->type.in(\MACC_PA)
|
||||||
|
select port(dsp, \C_BYPASS, SigSpec()).is_fully_ones()
|
||||||
|
select nusers(port(dsp, \C, SigSpec())) > 1
|
||||||
|
endmatch
|
||||||
|
|
||||||
|
code sigC sigP clock
|
||||||
|
//helper function to remove unused bits
|
||||||
|
unextend = [](const SigSpec &sig) {
|
||||||
|
int i;
|
||||||
|
for (i = GetSize(sig)-1; i > 0; i--)
|
||||||
|
if (sig[i] != sig[i-1])
|
||||||
|
break;
|
||||||
|
// Do not remove non-const sign bit
|
||||||
|
if (sig[i].wire)
|
||||||
|
++i;
|
||||||
|
return sig.extract(0, i);
|
||||||
|
};
|
||||||
|
sigC = unextend(port(dsp, \C, SigSpec()));
|
||||||
|
|
||||||
|
SigSpec P = port(dsp, \P);
|
||||||
|
|
||||||
|
// Only care about those bits that are used
|
||||||
|
int i;
|
||||||
|
for (i = GetSize(P)-1; i >= 0; i--)
|
||||||
|
if (nusers(P[i]) > 1)
|
||||||
|
break;
|
||||||
|
i++;
|
||||||
|
log_assert(nusers(P.extract_end(i)) <= 1);
|
||||||
|
sigP = P.extract(0, i);
|
||||||
|
|
||||||
|
clock = port(dsp, \CLK, SigBit());
|
||||||
|
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 the in_dffe subpattern)
|
||||||
|
code argQ ffC sigC clock
|
||||||
|
argQ = sigC;
|
||||||
|
subpattern(in_dffe);
|
||||||
|
if (dff) {
|
||||||
|
ffC = dff;
|
||||||
|
clock = dffclock;
|
||||||
|
sigC = dffD;
|
||||||
|
}
|
||||||
|
endcode
|
||||||
|
|
||||||
|
code
|
||||||
|
if (ffC)
|
||||||
|
accept;
|
||||||
|
endcode
|
||||||
|
|
||||||
|
// #######################
|
||||||
|
|
||||||
|
// Subpattern for matching against input registers, based on knowledge of the
|
||||||
|
// 'Q' input.
|
||||||
|
subpattern in_dffe
|
||||||
|
arg argQ clock
|
||||||
|
|
||||||
|
code
|
||||||
|
dff = nullptr;
|
||||||
|
if (argQ.empty())
|
||||||
|
reject;
|
||||||
|
for (const auto &c : argQ.chunks()) {
|
||||||
|
// Abandon matches when 'Q' is a constant
|
||||||
|
if (!c.wire)
|
||||||
|
reject;
|
||||||
|
// Abandon matches when 'Q' has the keep attribute set
|
||||||
|
if (c.wire->get_bool_attribute(\keep))
|
||||||
|
reject;
|
||||||
|
// Abandon matches when 'Q' has a non-zero init attribute set
|
||||||
|
// (not supported by DSP48E1)
|
||||||
|
Const init = c.wire->attributes.at(\init, Const());
|
||||||
|
if (!init.empty())
|
||||||
|
for (auto b : init.extract(c.offset, c.width))
|
||||||
|
if (b != State::Sx && b != State::S0)
|
||||||
|
reject;
|
||||||
|
}
|
||||||
|
endcode
|
||||||
|
|
||||||
|
match ff
|
||||||
|
select ff->type.in($dff, $dffe, $sdff, $sdffe, $adff, $adffe)
|
||||||
|
// does not support clock inversion
|
||||||
|
select param(ff, \CLK_POLARITY).as_bool()
|
||||||
|
|
||||||
|
slice offset GetSize(port(ff, \D))
|
||||||
|
index <SigBit> port(ff, \Q)[offset] === argQ[0]
|
||||||
|
|
||||||
|
// Check that the rest of argQ is present
|
||||||
|
filter GetSize(port(ff, \Q)) >= offset + GetSize(argQ)
|
||||||
|
filter port(ff, \Q).extract(offset, GetSize(argQ)) == argQ
|
||||||
|
|
||||||
|
filter clock == SigBit() || port(ff, \CLK) == clock
|
||||||
|
endmatch
|
||||||
|
|
||||||
|
code argQ
|
||||||
|
// Check that reset value, if present, is fully 0.
|
||||||
|
bool noResetFlop = ff->type.in($dff, $dffe);
|
||||||
|
bool srstZero = ff->type.in($sdff, $sdffe) && param(ff, \SRST_VALUE).is_fully_zero();
|
||||||
|
bool arstZero = ff->type.in($adff, $adffe) && param(ff, \ARST_VALUE).is_fully_zero();
|
||||||
|
bool resetLegal = noResetFlop || srstZero || arstZero;
|
||||||
|
if (resetLegal)
|
||||||
|
{
|
||||||
|
SigSpec Q = port(ff, \Q);
|
||||||
|
dff = ff;
|
||||||
|
dffclock = port(ff, \CLK);
|
||||||
|
dffD = argQ;
|
||||||
|
SigSpec D = port(ff, \D);
|
||||||
|
argQ = Q;
|
||||||
|
dffD.replace(argQ, D);
|
||||||
|
}
|
||||||
|
|
||||||
|
endcode
|
|
@ -0,0 +1,238 @@
|
||||||
|
// ISC License
|
||||||
|
//
|
||||||
|
// Copyright (C) 2024 Microchip Technology Inc. and its subsidiaries
|
||||||
|
//
|
||||||
|
// Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
// purpose with or without fee is hereby granted, provided that the above
|
||||||
|
// copyright notice and this permission notice appear in all copies.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
|
||||||
|
|
||||||
|
// This file describes the third of three pattern matcher setups that
|
||||||
|
// forms the `mchp_dsp` pass described in mchp_dsp.cc
|
||||||
|
// At a high level, it works as follows:
|
||||||
|
// (1) Starting from a DSP cell that
|
||||||
|
// (a) CDIN_FDBK_SEL is set to default "00"
|
||||||
|
// (b) doesn't already use the 'PCOUT' port
|
||||||
|
// (2) Match another DSP cell that
|
||||||
|
// (a) does not have the CREG enabled,
|
||||||
|
// (b) 'C' port is driven by the 'P' output of the previous DSP cell
|
||||||
|
// (c) has its 'PCIN' port unused
|
||||||
|
// (3) Recursively go to (2) until no more matches possible, keeping track
|
||||||
|
// of the longest possible chain found
|
||||||
|
// (4) The longest chain is then divided into chunks of no more than
|
||||||
|
// MAX_DSP_CASCADE in length (to prevent long cascades that exceed the
|
||||||
|
// height of a DSP column) with each DSP in each chunk being rewritten
|
||||||
|
// to use [ABP]COUT -> [ABP]CIN cascading as appropriate
|
||||||
|
|
||||||
|
pattern mchp_dsp_cascade
|
||||||
|
|
||||||
|
udata <std::function<SigSpec(const SigSpec&)>> unextend
|
||||||
|
udata <vector<std::tuple<Cell*,int>>> chain longest_chain
|
||||||
|
udata <std::set<Cell*>> visited
|
||||||
|
state <Cell*> next
|
||||||
|
state <SigSpec> clock
|
||||||
|
|
||||||
|
// Variables used for subpatterns
|
||||||
|
state <SigSpec> argQ argD
|
||||||
|
state <int> ffoffset
|
||||||
|
udata <SigSpec> dffD dffQ
|
||||||
|
udata <SigBit> dffclock
|
||||||
|
udata <Cell*> dff
|
||||||
|
|
||||||
|
// Maximum of 24 cascaded blocks
|
||||||
|
code
|
||||||
|
#define MAX_DSP_CASCADE 24
|
||||||
|
endcode
|
||||||
|
|
||||||
|
// NOTE: Chain vector
|
||||||
|
// +--------+ +--------+
|
||||||
|
// | first |----> | next | ----> ...
|
||||||
|
// +--------+ +--------+
|
||||||
|
// first.COUT cascades to next.CIN, so on and so forth
|
||||||
|
|
||||||
|
// Helper function to remove unused bits
|
||||||
|
code
|
||||||
|
unextend = [](const SigSpec &sig) {
|
||||||
|
int i;
|
||||||
|
for (i = GetSize(sig)-1; i > 0; i--)
|
||||||
|
if (sig[i] != sig[i-1])
|
||||||
|
break;
|
||||||
|
// Do not remove non-const sign bit
|
||||||
|
if (sig[i].wire)
|
||||||
|
++i;
|
||||||
|
return sig.extract(0, i);
|
||||||
|
};
|
||||||
|
endcode
|
||||||
|
|
||||||
|
// (1) Starting from a DSP cell that
|
||||||
|
// (a) CDIN_FDBK_SEL is set to default "00"
|
||||||
|
// (b) doesn't already use the 'PCOUT' port
|
||||||
|
match first
|
||||||
|
select first->type.in(\MACC_PA) && port(first, \CDIN_FDBK_SEL, Const(0, 2)) == Const::from_string("00")
|
||||||
|
select nusers(port(first, \CDOUT, SigSpec())) <= 1
|
||||||
|
endmatch
|
||||||
|
|
||||||
|
// (4) The longest chain is then divided into chunks of no more than
|
||||||
|
// MAX_DSP_CASCADE in length (to prevent long cascades that exceed the
|
||||||
|
// height of a DSP column) with each DSP in each chunk being rewritten
|
||||||
|
// to use [ABP]COUT -> [ABP]CIN cascading as appropriate
|
||||||
|
code
|
||||||
|
visited.clear();
|
||||||
|
visited.insert(first);
|
||||||
|
|
||||||
|
longest_chain.clear();
|
||||||
|
chain.emplace_back(first, -1);
|
||||||
|
subpattern(tail);
|
||||||
|
finally
|
||||||
|
|
||||||
|
// longest cascade chain has been found with DSP "first" being the head of the chain
|
||||||
|
// do some post processing
|
||||||
|
|
||||||
|
chain.pop_back();
|
||||||
|
visited.clear();
|
||||||
|
log_assert(chain.empty());
|
||||||
|
|
||||||
|
if (GetSize(longest_chain) > 1) {
|
||||||
|
Cell *dsp = std::get<0>(longest_chain.front());
|
||||||
|
|
||||||
|
Cell *dsp_pcin;
|
||||||
|
int SHIFT = -1;
|
||||||
|
for (int i = 1; i < GetSize(longest_chain); i++) {
|
||||||
|
log_assert(dsp->type.in(\MACC_PA));
|
||||||
|
|
||||||
|
std::tie(dsp_pcin,SHIFT) = longest_chain[i];
|
||||||
|
|
||||||
|
// Chain length exceeds the maximum cascade length, must split it up
|
||||||
|
if (i % MAX_DSP_CASCADE > 0) {
|
||||||
|
Wire *cascade = module->addWire(NEW_ID, 48);
|
||||||
|
|
||||||
|
// zero port C and move wire to cascade
|
||||||
|
dsp_pcin->setPort(ID(C), Const(0, 48));
|
||||||
|
dsp_pcin->setPort(ID(CDIN), cascade);
|
||||||
|
dsp->setPort(ID(CDOUT), cascade);
|
||||||
|
|
||||||
|
// Configure wire to cascade the dsps
|
||||||
|
add_siguser(cascade, dsp_pcin);
|
||||||
|
add_siguser(cascade, dsp);
|
||||||
|
|
||||||
|
// configure mux to use cascade for signal E
|
||||||
|
SigSpec cdin_fdbk_sel = port(dsp_pcin, \CDIN_FDBK_SEL, Const(0, 2));
|
||||||
|
cdin_fdbk_sel[1] = State::S1;
|
||||||
|
dsp_pcin->setPort(\CDIN_FDBK_SEL, cdin_fdbk_sel);
|
||||||
|
|
||||||
|
// check if shifting is required for wide multiplier implmentation
|
||||||
|
if (SHIFT == 17)
|
||||||
|
{
|
||||||
|
dsp_pcin->setPort(\ARSHFT17, State::S1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
log_debug("PCOUT -> PCIN cascade for %s -> %s\n", log_id(dsp), log_id(dsp_pcin));
|
||||||
|
|
||||||
|
} else {
|
||||||
|
log_debug(" Blocking %s -> %s cascade (exceeds max: %d)\n", log_id(dsp), log_id(dsp_pcin), MAX_DSP_CASCADE);
|
||||||
|
}
|
||||||
|
|
||||||
|
dsp = dsp_pcin;
|
||||||
|
}
|
||||||
|
|
||||||
|
accept;
|
||||||
|
}
|
||||||
|
endcode
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------
|
||||||
|
|
||||||
|
subpattern tail
|
||||||
|
arg first
|
||||||
|
arg next
|
||||||
|
|
||||||
|
// (2) Match another DSP cell that
|
||||||
|
// (a) does not have the CREG enabled,
|
||||||
|
// (b) 'C' port is driven by the 'P' output of the previous DSP cell
|
||||||
|
// (c) has its 'PCIN' port unused
|
||||||
|
match nextP
|
||||||
|
// find candidates where nextP.C port is driven (maybe partially) by chain's tail DSP.P port
|
||||||
|
// and with no registers in between (since cascade path cannot be pipelined)
|
||||||
|
|
||||||
|
// reg C must not be used
|
||||||
|
select port(nextP, \C_BYPASS, SigSpec()).is_fully_ones()
|
||||||
|
|
||||||
|
// must be same DSP type
|
||||||
|
select nextP->type.in(\MACC_PA)
|
||||||
|
|
||||||
|
// port C should be driven by something
|
||||||
|
select nusers(port(nextP, \C, SigSpec())) > 1
|
||||||
|
|
||||||
|
// CIN must be unused
|
||||||
|
select nusers(port(nextP, \PCIN, SigSpec())) == 0
|
||||||
|
|
||||||
|
// should not have internal feedback connection
|
||||||
|
select port(nextP, \CDIN_FDBK_SEL, SigSpec()).is_fully_zero()
|
||||||
|
|
||||||
|
// SHIFT should be unused
|
||||||
|
select port(nextP, \ARSHFT17_BYPASS).is_fully_ones()
|
||||||
|
select port(nextP, \ARSHFT17).is_fully_zero()
|
||||||
|
select nusers(port(nextP, \ARSHFT17, SigSpec())) == 0
|
||||||
|
|
||||||
|
// current DSP cell can be cascaded with the back of the cascade chain
|
||||||
|
// index <SigBit> port(nextP, \C)[0] === port(std::get<0>(chain.back()), \P)[0] || port(nextP, \C)[0] === port(std::get<0>(chain.back()), \P)[17]
|
||||||
|
filter port(nextP, \C)[0] == port(std::get<0>(chain.back()), \P)[0] || port(nextP, \C)[0] == port(std::get<0>(chain.back()), \P)[17]
|
||||||
|
|
||||||
|
// semioptional
|
||||||
|
|
||||||
|
optional
|
||||||
|
endmatch
|
||||||
|
|
||||||
|
code next
|
||||||
|
next = nextP;
|
||||||
|
|
||||||
|
// keep DSP type consistent in the chain
|
||||||
|
// currently since we only have one type anyways, this line is always false
|
||||||
|
if (next && next->type != first->type) reject;
|
||||||
|
|
||||||
|
// break infinite recursion when there's a combinational loop
|
||||||
|
if (visited.count(next) > 0) reject;
|
||||||
|
|
||||||
|
endcode
|
||||||
|
|
||||||
|
// (3) Recursively go to (2) until no more matches possible, recording the
|
||||||
|
// longest possible chain
|
||||||
|
code
|
||||||
|
if (next) {
|
||||||
|
SigSpec driver_sigP = port(std::get<0>(chain.back()), \P);
|
||||||
|
int shift = 0;
|
||||||
|
if (port(next, \C)[0] == port(std::get<0>(chain.back()), \P)[17]) shift = 17;
|
||||||
|
|
||||||
|
chain.emplace_back(next, shift);
|
||||||
|
visited.insert(next);
|
||||||
|
|
||||||
|
SigSpec sigC = unextend(port(next, \C));
|
||||||
|
|
||||||
|
// Make sure driverDSP.P === DSP.C
|
||||||
|
if (GetSize(sigC) + shift <= GetSize(driver_sigP) && driver_sigP.extract(shift, GetSize(sigC)) == sigC)
|
||||||
|
{
|
||||||
|
subpattern(tail);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} else {
|
||||||
|
if (GetSize(chain) > GetSize(longest_chain))
|
||||||
|
longest_chain = chain;
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
if (next)
|
||||||
|
{
|
||||||
|
visited.erase(next);
|
||||||
|
chain.pop_back();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
endcode
|
|
@ -0,0 +1,191 @@
|
||||||
|
# ISC License
|
||||||
|
#
|
||||||
|
# Copyright (C) 2024 Microchip Technology Inc. and its subsidiaries
|
||||||
|
#
|
||||||
|
# Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
# purpose with or without fee is hereby granted, provided that the above
|
||||||
|
# copyright notice and this permission notice appear in all copies.
|
||||||
|
#
|
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# LSRAM true dual-port
|
||||||
|
ram block $__LSRAM_TDP_ {
|
||||||
|
|
||||||
|
# Cost of a given cell is assumed to be:
|
||||||
|
# (cost-widthscale) + [widthscale * (used_bits/14)]
|
||||||
|
cost 129;
|
||||||
|
|
||||||
|
# INIT is supported
|
||||||
|
init any;
|
||||||
|
|
||||||
|
# port A and port B are allowed to have different widths, but they MUST have
|
||||||
|
# WIDTH values of the same set.
|
||||||
|
# Example: Port A has a Data Width of 1. Then Port B's Data Width must be either
|
||||||
|
# 1, 2, 4, 8, or 16 (both values are in the 'WIDTH_1' set).
|
||||||
|
# WIDTH_1 = {1, 2, 4, 8, 16}
|
||||||
|
# WIDTH_2 = {5, 10, 20}
|
||||||
|
|
||||||
|
# "byte" specifies how many data bits correspond to one write enable bit.
|
||||||
|
# "byte" must be larger than width, or width must be a multipler of "byte"
|
||||||
|
# if "byte" > WIDTH, a single enable wire is inferred
|
||||||
|
# otherwise, WIDTH/byte number of enable wires are inferred
|
||||||
|
#
|
||||||
|
# WIDTH = {1, 2, 4, 5, 8, 10} requires 1 enable wire
|
||||||
|
# WIDTH = {16, 20} requires 2 enable wire
|
||||||
|
|
||||||
|
option "WIDTH_CONFIG" "REGULAR" {
|
||||||
|
|
||||||
|
# Data-Width | Address bits
|
||||||
|
# 1 | 14
|
||||||
|
# 2 | 13
|
||||||
|
# 4 | 12
|
||||||
|
# 8 | 11
|
||||||
|
# 16 | 10
|
||||||
|
|
||||||
|
# 14 address bits
|
||||||
|
abits 14;
|
||||||
|
|
||||||
|
widths 1 2 4 8 16 per_port;
|
||||||
|
byte 8;
|
||||||
|
}
|
||||||
|
option "WIDTH_CONFIG" "ALIGN" {
|
||||||
|
|
||||||
|
# Data-Width | Address bits
|
||||||
|
# 5 | 12
|
||||||
|
# 10 | 11
|
||||||
|
# 20 | 10
|
||||||
|
|
||||||
|
# Quick "hack" to fix address bit alignment by setting address bits to 12.
|
||||||
|
# If abits=14, tool will think there are 14 bits for width=5, 13 bits for width=10, 12 bits for width=20
|
||||||
|
# THe LSRAM_map.v file detects if this option is being used, and adjusts the address port alignments accordingly.
|
||||||
|
abits 12;
|
||||||
|
|
||||||
|
widths 5 10 20 per_port;
|
||||||
|
byte 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
port srsw "A" "B" {
|
||||||
|
|
||||||
|
# read & write width must be same
|
||||||
|
width tied;
|
||||||
|
|
||||||
|
# clock polarity is rising
|
||||||
|
clock posedge;
|
||||||
|
|
||||||
|
# A/B read-enable
|
||||||
|
rden;
|
||||||
|
|
||||||
|
|
||||||
|
# initial value of read port data (not supported)
|
||||||
|
rdinit none;
|
||||||
|
|
||||||
|
# write modes (<A/B>_WMODE)
|
||||||
|
# 1. Simple Write: read-data port holds prev value (similar to "NO_CHANGE" for RAMB18E1)
|
||||||
|
# 2. Feed-through: read-data port takes new write value (similar to "WRITE_FIRST" for RAMB18E1)
|
||||||
|
# 3. Read-Before-Write: read-data port holds old value while being written (similar to "READ_FIRST" for RAMB18E1)
|
||||||
|
|
||||||
|
portoption "WRITE_MODE" "NO_CHANGE" {
|
||||||
|
|
||||||
|
# Read-write interaction
|
||||||
|
rdwr no_change;
|
||||||
|
|
||||||
|
# Write transparency:
|
||||||
|
# For write ports, define behaviour when another synchronous read port
|
||||||
|
# reads from the same memory cell that said write port is writing to at the same time.
|
||||||
|
wrtrans all old;
|
||||||
|
}
|
||||||
|
portoption "WRITE_MODE" "WRITE_FIRST" {
|
||||||
|
# bits corresponding to high A/B_WEN are updated
|
||||||
|
rdwr new_only;
|
||||||
|
wrtrans all new;
|
||||||
|
}
|
||||||
|
portoption "WRITE_MODE" "READ_FIRST" {
|
||||||
|
rdwr old;
|
||||||
|
|
||||||
|
wrtrans all old;
|
||||||
|
}
|
||||||
|
|
||||||
|
# generate params to indicate if read or write is used for each port
|
||||||
|
optional_rw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# two-port configuration
|
||||||
|
ram block $__LSRAM_SDP_ {
|
||||||
|
|
||||||
|
# since two-port configuration is dedicated for wide-read/write,
|
||||||
|
# we want to prioritize this configuration over TDP to avoid tool picking multiple TDP RAMs
|
||||||
|
# inplace of a single SDP RAM for wide read/write. This means the cost of a single SDP should
|
||||||
|
# be less than 2 TDP.
|
||||||
|
cost 129;
|
||||||
|
init any;
|
||||||
|
|
||||||
|
option "WIDTH_CONFIG" "REGULAR" {
|
||||||
|
|
||||||
|
# Data-Width | Address bits
|
||||||
|
# 1 | 14
|
||||||
|
# 2 | 13
|
||||||
|
# 4 | 12
|
||||||
|
# 8 | 11
|
||||||
|
# 16 | 10
|
||||||
|
# 32 | 9
|
||||||
|
|
||||||
|
abits 14;
|
||||||
|
|
||||||
|
widths 1 2 4 8 16 32 per_port;
|
||||||
|
|
||||||
|
# width = 32, byte-write size is 8, ignore other widths
|
||||||
|
byte 8;
|
||||||
|
|
||||||
|
}
|
||||||
|
option "WIDTH_CONFIG" "ALIGN" {
|
||||||
|
|
||||||
|
# Data-Width | Address bits
|
||||||
|
# 5 | 12
|
||||||
|
# 10 | 11
|
||||||
|
# 20 | 10
|
||||||
|
# 40 | 9
|
||||||
|
|
||||||
|
# Same trick as TSP RAM for alignment
|
||||||
|
abits 12;
|
||||||
|
widths 5 10 20 40 per_port;
|
||||||
|
byte 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
port sw "W" {
|
||||||
|
|
||||||
|
# only consider wide write
|
||||||
|
|
||||||
|
option "WIDTH_CONFIG" "REGULAR" width 32;
|
||||||
|
option "WIDTH_CONFIG" "ALIGN" width 40;
|
||||||
|
|
||||||
|
clock posedge;
|
||||||
|
|
||||||
|
# only simple write supported for two-port mode
|
||||||
|
wrtrans all old;
|
||||||
|
|
||||||
|
optional;
|
||||||
|
}
|
||||||
|
port sr "R" {
|
||||||
|
|
||||||
|
option "WIDTH_CONFIG" "REGULAR" width 32;
|
||||||
|
option "WIDTH_CONFIG" "ALIGN" width 40;
|
||||||
|
|
||||||
|
|
||||||
|
clock posedge;
|
||||||
|
rden;
|
||||||
|
rdinit none;
|
||||||
|
optional;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,323 @@
|
||||||
|
/*
|
||||||
|
ISC License
|
||||||
|
|
||||||
|
Copyright (C) 2024 Microchip Technology Inc. and its subsidiaries
|
||||||
|
|
||||||
|
Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
purpose with or without fee is hereby granted, provided that the above
|
||||||
|
copyright notice and this permission notice appear in all copies.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// See document PolarFire Family Fabric User Guide
|
||||||
|
// section 4.1 for port list.
|
||||||
|
|
||||||
|
|
||||||
|
//LSRAM true dual-port
|
||||||
|
module $__LSRAM_TDP_ (...);
|
||||||
|
|
||||||
|
parameter INIT = 0;
|
||||||
|
parameter ADDR_BITS = 14;
|
||||||
|
|
||||||
|
parameter OPTION_WIDTH_CONFIG = "A";
|
||||||
|
|
||||||
|
parameter PORT_A_WIDTH = 1;
|
||||||
|
parameter PORT_A_WR_EN_WIDTH = 1;
|
||||||
|
parameter PORT_A_RD_USED = 0;
|
||||||
|
parameter PORT_A_WR_USED = 0;
|
||||||
|
parameter PORT_A_OPTION_WRITE_MODE = "NO_CHANGE";
|
||||||
|
|
||||||
|
parameter PORT_B_WIDTH = 1;
|
||||||
|
parameter PORT_B_WR_EN_WIDTH = 1;
|
||||||
|
parameter PORT_B_RD_USED = 0;
|
||||||
|
parameter PORT_B_WR_USED = 0;
|
||||||
|
parameter PORT_B_OPTION_WRITE_MODE = "NO_CHANGE";
|
||||||
|
|
||||||
|
|
||||||
|
input PORT_A_CLK;
|
||||||
|
input PORT_A_RD_EN;
|
||||||
|
input [ADDR_BITS-1:0] PORT_A_ADDR;
|
||||||
|
input [PORT_A_WIDTH-1:0] PORT_A_WR_DATA;
|
||||||
|
input [PORT_A_WR_EN_WIDTH-1:0] PORT_A_WR_EN;
|
||||||
|
output [PORT_A_WIDTH-1:0] PORT_A_RD_DATA;
|
||||||
|
|
||||||
|
|
||||||
|
input PORT_B_CLK;
|
||||||
|
input PORT_B_RD_EN;
|
||||||
|
input [ADDR_BITS-1:0] PORT_B_ADDR;
|
||||||
|
input [PORT_B_WIDTH-1:0] PORT_B_WR_DATA;
|
||||||
|
input [PORT_B_WR_EN_WIDTH-1:0] PORT_B_WR_EN;
|
||||||
|
output [PORT_B_WIDTH-1:0] PORT_B_RD_DATA;
|
||||||
|
|
||||||
|
|
||||||
|
`include "brams_defs.vh"
|
||||||
|
|
||||||
|
// address wires
|
||||||
|
wire [ADDR_BITS-1:0] A_address;
|
||||||
|
wire [ADDR_BITS-1:0] B_address;
|
||||||
|
assign A_address = (OPTION_WIDTH_CONFIG == "REGULAR") ? PORT_A_ADDR : {PORT_A_ADDR, 2'b00};
|
||||||
|
assign B_address = (OPTION_WIDTH_CONFIG == "REGULAR") ? PORT_B_ADDR : {PORT_B_ADDR, 2'b00};
|
||||||
|
|
||||||
|
// if port is not used, set block sel to 0 to disable it (read-data output is set to 0)
|
||||||
|
parameter PORT_A_RD_USED = 0;
|
||||||
|
parameter PORT_A_WR_USED = 0;
|
||||||
|
wire [2:0] A_BLK_SEL = (PORT_A_RD_USED == 1 || PORT_A_WR_USED == 1) ? 3'b111 : 3'b000;
|
||||||
|
wire [2:0] B_BLK_SEL = (PORT_B_RD_USED == 1 || PORT_B_WR_USED == 1) ? 3'b111 : 3'b000;
|
||||||
|
|
||||||
|
// wires for write data
|
||||||
|
generate
|
||||||
|
wire [19:0] A_write_data;
|
||||||
|
wire [19:0] B_write_data;
|
||||||
|
if (PORT_A_WIDTH == 16) begin
|
||||||
|
assign A_write_data[7:0] = PORT_A_WR_DATA[7:0];
|
||||||
|
assign A_write_data[17:10] = PORT_A_WR_DATA[15:8];
|
||||||
|
assign A_write_data[9:8] = 2'b0;
|
||||||
|
assign A_write_data[19:18] = 2'b0;
|
||||||
|
end else begin
|
||||||
|
assign A_write_data[PORT_A_WIDTH-1:0] = PORT_A_WR_DATA;
|
||||||
|
end
|
||||||
|
|
||||||
|
if (PORT_B_WIDTH == 16) begin
|
||||||
|
assign B_write_data[7:0] = PORT_B_WR_DATA[7:0];
|
||||||
|
assign B_write_data[17:10] = PORT_B_WR_DATA[15:8];
|
||||||
|
assign B_write_data[9:8] = 2'b0;
|
||||||
|
assign B_write_data[19:18] = 2'b0;
|
||||||
|
end else begin
|
||||||
|
assign B_write_data[PORT_B_WIDTH-1:0] = PORT_B_WR_DATA;
|
||||||
|
end
|
||||||
|
endgenerate
|
||||||
|
|
||||||
|
// wires for read data
|
||||||
|
wire [19:0] A_read_data;
|
||||||
|
assign PORT_A_RD_DATA = A_read_data[PORT_A_WIDTH-1:0];
|
||||||
|
wire [19:0] B_read_data;
|
||||||
|
assign PORT_B_RD_DATA = B_read_data[PORT_B_WIDTH-1:0];
|
||||||
|
|
||||||
|
// byte-write enables
|
||||||
|
wire [1:0] A_write_EN = (PORT_A_WR_EN_WIDTH == 1) ? {1'b0, PORT_A_WR_EN} : PORT_A_WR_EN;
|
||||||
|
wire [1:0] B_write_EN = (PORT_B_WR_EN_WIDTH == 1) ? {1'b0, PORT_B_WR_EN} : PORT_B_WR_EN;
|
||||||
|
|
||||||
|
// port width
|
||||||
|
wire [2:0] A_width = (PORT_A_WIDTH == 1) ? 3'b000 :
|
||||||
|
(PORT_A_WIDTH == 2) ? 3'b001 :
|
||||||
|
(PORT_A_WIDTH == 4 || PORT_A_WIDTH == 5) ? 3'b010 :
|
||||||
|
(PORT_A_WIDTH == 8 || PORT_A_WIDTH == 10) ? 3'b011 : 3'b100;
|
||||||
|
wire [2:0] B_width = (PORT_B_WIDTH == 1) ? 3'b000 :
|
||||||
|
(PORT_B_WIDTH == 2) ? 3'b001 :
|
||||||
|
(PORT_B_WIDTH == 4 || PORT_B_WIDTH == 5) ? 3'b010 :
|
||||||
|
(PORT_B_WIDTH == 8 || PORT_B_WIDTH == 10) ? 3'b011 : 3'b100;
|
||||||
|
|
||||||
|
// write modes
|
||||||
|
wire [1:0] A_write_mode = PORT_A_OPTION_WRITE_MODE == "NO_CHANGE" ? 2'b00 :
|
||||||
|
PORT_A_OPTION_WRITE_MODE == "WRITE_FIRST" ? 2'b01 : 2'b10;
|
||||||
|
wire [1:0] B_write_mode = PORT_B_OPTION_WRITE_MODE == "NO_CHANGE" ? 2'b00 :
|
||||||
|
PORT_B_OPTION_WRITE_MODE == "WRITE_FIRST" ? 2'b01 : 2'b10;
|
||||||
|
|
||||||
|
RAM1K20 #(
|
||||||
|
`PARAMS_INIT_LSRAM
|
||||||
|
) _TECHMAP_REPLACE_ (
|
||||||
|
|
||||||
|
// port A
|
||||||
|
.A_ADDR(A_address),
|
||||||
|
.A_BLK_EN(A_BLK_SEL),
|
||||||
|
.A_CLK(PORT_A_CLK),
|
||||||
|
.A_DIN(A_write_data),
|
||||||
|
.A_DOUT(A_read_data),
|
||||||
|
.A_WEN(A_write_EN),
|
||||||
|
.A_REN(PORT_A_RD_EN),
|
||||||
|
.A_WIDTH(A_width),
|
||||||
|
.A_WMODE(A_write_mode),
|
||||||
|
.A_BYPASS(1'b1),
|
||||||
|
.A_DOUT_EN(1'b1),
|
||||||
|
.A_DOUT_SRST_N(1'b1),
|
||||||
|
.A_DOUT_ARST_N(1'b1),
|
||||||
|
|
||||||
|
// port B
|
||||||
|
.B_ADDR(B_address),
|
||||||
|
.B_BLK_EN(B_BLK_SEL),
|
||||||
|
.B_CLK(PORT_B_CLK),
|
||||||
|
.B_DIN(B_write_data),
|
||||||
|
.B_DOUT(B_read_data),
|
||||||
|
.B_WEN(B_write_EN),
|
||||||
|
.B_REN(PORT_B_RD_EN),
|
||||||
|
.B_WIDTH(B_width),
|
||||||
|
.B_WMODE(B_write_mode),
|
||||||
|
.B_BYPASS(1'b1),
|
||||||
|
.B_DOUT_EN(1'b1),
|
||||||
|
.B_DOUT_SRST_N(1'b1),
|
||||||
|
.B_DOUT_ARST_N(1'b1),
|
||||||
|
|
||||||
|
// Disable ECC for TDP
|
||||||
|
.ECC_EN(1'b0),
|
||||||
|
.ECC_BYPASS(1'b1),
|
||||||
|
.BUSY_FB(1'b0)
|
||||||
|
|
||||||
|
);
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
// single dual port configuration
|
||||||
|
module $__LSRAM_SDP_ (...);
|
||||||
|
|
||||||
|
parameter INIT = 0;
|
||||||
|
parameter OPTION_WIDTH_CONFIG = "REGULAR";
|
||||||
|
parameter ADDR_BITS = 14;
|
||||||
|
|
||||||
|
parameter PORT_W_WIDTH = 1;
|
||||||
|
parameter PORT_W_WR_EN_WIDTH = 4;
|
||||||
|
parameter PORT_W_USED = 1;
|
||||||
|
|
||||||
|
parameter PORT_R_WIDTH = 1;
|
||||||
|
parameter PORT_R_USED = 0;
|
||||||
|
|
||||||
|
input PORT_W_CLK;
|
||||||
|
input [ADDR_BITS-1:0] PORT_W_ADDR;
|
||||||
|
input [PORT_W_WIDTH-1:0] PORT_W_WR_DATA;
|
||||||
|
input [PORT_W_WR_EN_WIDTH-1:0] PORT_W_WR_EN;
|
||||||
|
|
||||||
|
input PORT_R_CLK;
|
||||||
|
input PORT_R_RD_EN;
|
||||||
|
input [ADDR_BITS-1:0] PORT_R_ADDR;
|
||||||
|
output [PORT_R_WIDTH-1:0] PORT_R_RD_DATA;
|
||||||
|
input PORT_R_RD_SRST;
|
||||||
|
|
||||||
|
`include "brams_defs.vh"
|
||||||
|
|
||||||
|
|
||||||
|
// address wires
|
||||||
|
wire [ADDR_BITS-1:0] A_address;
|
||||||
|
wire [ADDR_BITS-1:0] B_address;
|
||||||
|
assign A_address = (OPTION_WIDTH_CONFIG == "REGULAR") ? PORT_R_ADDR : {PORT_R_ADDR, 2'b00};
|
||||||
|
assign B_address = (OPTION_WIDTH_CONFIG == "REGULAR") ? PORT_W_ADDR : {PORT_W_ADDR, 2'b00};
|
||||||
|
|
||||||
|
// if port is not used, set block sel to 0 to disable it (read-data output is set to 0)
|
||||||
|
// port A is for read, port B for write
|
||||||
|
parameter PORT_W_USED = 0;
|
||||||
|
parameter PORT_R_USED = 0;
|
||||||
|
wire [2:0] A_BLK_SEL = (PORT_R_USED == 1) ? 3'b111 : 3'b000;
|
||||||
|
wire [2:0] B_BLK_SEL = (PORT_W_USED == 1) ? 3'b111 : 3'b000;
|
||||||
|
|
||||||
|
// read/write data & write enables
|
||||||
|
// Currently support only wide write, width = {32, 40}
|
||||||
|
generate
|
||||||
|
wire [19:0] A_write_data;
|
||||||
|
wire [19:0] B_write_data;
|
||||||
|
wire [1:0] A_write_EN;
|
||||||
|
wire [1:0] B_write_EN;
|
||||||
|
|
||||||
|
// write port (A provides MSB)
|
||||||
|
if (PORT_W_WIDTH == 32) begin
|
||||||
|
|
||||||
|
assign B_write_data[3:0] = PORT_W_WR_DATA[3:0];
|
||||||
|
assign B_write_data[8:5] = PORT_W_WR_DATA[7:4];
|
||||||
|
assign B_write_data[13:10] = PORT_W_WR_DATA[11:8];
|
||||||
|
assign B_write_data[18:15] = PORT_W_WR_DATA[15:12];
|
||||||
|
assign B_write_data[4] = 1'b0;
|
||||||
|
assign B_write_data[9] = 1'b0;
|
||||||
|
assign B_write_data[14] = 1'b0;
|
||||||
|
assign B_write_data[19] = 1'b0;
|
||||||
|
|
||||||
|
assign A_write_data[3:0] = PORT_W_WR_DATA[19:16];
|
||||||
|
assign A_write_data[8:5] = PORT_W_WR_DATA[23:20];
|
||||||
|
assign A_write_data[13:10] = PORT_W_WR_DATA[27:24];
|
||||||
|
assign A_write_data[18:15] = PORT_W_WR_DATA[31:28];
|
||||||
|
assign A_write_data[4] = 1'b0;
|
||||||
|
assign A_write_data[9] = 1'b0;
|
||||||
|
assign A_write_data[14] = 1'b0;
|
||||||
|
assign A_write_data[19] = 1'b0;
|
||||||
|
|
||||||
|
end else if (PORT_W_WIDTH == 40) begin
|
||||||
|
assign B_write_data = PORT_W_WR_DATA[19:0];
|
||||||
|
assign A_write_data = PORT_W_WR_DATA[39:20];
|
||||||
|
end
|
||||||
|
|
||||||
|
// byte-write enables
|
||||||
|
assign A_write_EN = PORT_W_WR_EN[1:0];
|
||||||
|
assign B_write_EN = PORT_W_WR_EN[3:2];
|
||||||
|
|
||||||
|
// read ports (A provides MSB)
|
||||||
|
wire [19:0] A_read_data;
|
||||||
|
wire [19:0] B_read_data;
|
||||||
|
if (PORT_R_WIDTH == 32) begin
|
||||||
|
assign PORT_R_RD_DATA[3:0] = B_read_data[3:0];
|
||||||
|
assign PORT_R_RD_DATA[8:5] = B_read_data[7:4];
|
||||||
|
assign PORT_R_RD_DATA[13:10] = B_read_data[11:8];
|
||||||
|
assign PORT_R_RD_DATA[18:15] = B_read_data[15:12];
|
||||||
|
|
||||||
|
assign PORT_R_RD_DATA[19:16] = A_read_data[3:0];
|
||||||
|
assign PORT_R_RD_DATA[23:20] = A_read_data[8:5];
|
||||||
|
assign PORT_R_RD_DATA[27:24] = A_read_data[13:10];
|
||||||
|
assign PORT_R_RD_DATA[31:28] = A_read_data[18:15];
|
||||||
|
end else if (PORT_R_WIDTH == 40) begin
|
||||||
|
assign PORT_R_RD_DATA[19:0] = B_read_data[19:0];
|
||||||
|
assign PORT_R_RD_DATA[39:20] = A_read_data[19:0];
|
||||||
|
end
|
||||||
|
|
||||||
|
endgenerate
|
||||||
|
|
||||||
|
// port width
|
||||||
|
wire [2:0] A_width = (PORT_R_WIDTH == 1) ? 3'b000 :
|
||||||
|
(PORT_R_WIDTH == 2) ? 3'b001 :
|
||||||
|
(PORT_R_WIDTH == 4 || PORT_R_WIDTH == 5) ? 3'b010 :
|
||||||
|
(PORT_R_WIDTH == 8 || PORT_R_WIDTH == 10) ? 3'b011 :
|
||||||
|
(PORT_R_WIDTH == 16 || PORT_R_WIDTH == 20) ? 3'b100 : 3'b101;
|
||||||
|
wire [2:0] B_width = (PORT_W_WIDTH == 1) ? 3'b000 :
|
||||||
|
(PORT_W_WIDTH == 2) ? 3'b001 :
|
||||||
|
(PORT_W_WIDTH == 4 || PORT_W_WIDTH == 5) ? 3'b010 :
|
||||||
|
(PORT_W_WIDTH == 8 || PORT_W_WIDTH == 10) ? 3'b011 :
|
||||||
|
(PORT_W_WIDTH == 16 || PORT_W_WIDTH == 20) ? 3'b100 : 3'b101;
|
||||||
|
|
||||||
|
// write modes
|
||||||
|
wire [1:0] A_write_mode = 2'b00;
|
||||||
|
wire [1:0] B_write_mode = 2'b00;
|
||||||
|
|
||||||
|
RAM1K20 #(
|
||||||
|
`PARAMS_INIT_LSRAM
|
||||||
|
) _TECHMAP_REPLACE_ (
|
||||||
|
// port A - read
|
||||||
|
.A_ADDR(A_address),
|
||||||
|
.A_BLK_EN(A_BLK_SEL),
|
||||||
|
.A_CLK(PORT_R_CLK),
|
||||||
|
.A_DIN(A_write_data),
|
||||||
|
.A_DOUT(A_read_data),
|
||||||
|
.A_WEN(A_write_EN),
|
||||||
|
.A_REN(PORT_R_RD_EN),
|
||||||
|
.A_WIDTH(A_width),
|
||||||
|
.A_WMODE(A_write_mode),
|
||||||
|
.A_BYPASS(1'b1),
|
||||||
|
.A_DOUT_EN(1'b1),
|
||||||
|
.A_DOUT_SRST_N(1'b1),
|
||||||
|
.A_DOUT_ARST_N(1'b1),
|
||||||
|
|
||||||
|
// port B - write
|
||||||
|
.B_ADDR(B_address),
|
||||||
|
.B_BLK_EN(B_BLK_SEL),
|
||||||
|
.B_CLK(PORT_W_CLK),
|
||||||
|
.B_DIN(B_write_data),
|
||||||
|
.B_DOUT(B_read_data),
|
||||||
|
.B_WEN(B_write_EN),
|
||||||
|
.B_REN(PORT_R_RD_EN),
|
||||||
|
.B_WIDTH(B_width),
|
||||||
|
.B_WMODE(B_write_mode),
|
||||||
|
.B_BYPASS(1'b1),
|
||||||
|
.B_DOUT_EN(1'b1),
|
||||||
|
.B_DOUT_SRST_N(1'b1),
|
||||||
|
.B_DOUT_ARST_N(1'b1),
|
||||||
|
|
||||||
|
// Disable ECC for SDP
|
||||||
|
.ECC_EN(1'b0),
|
||||||
|
.ECC_BYPASS(1'b1),
|
||||||
|
|
||||||
|
.BUSY_FB(1'b0)
|
||||||
|
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
endmodule
|
|
@ -0,0 +1,31 @@
|
||||||
|
# ISC License
|
||||||
|
#
|
||||||
|
# Copyright (C) 2024 Microchip Technology Inc. and its subsidiaries
|
||||||
|
#
|
||||||
|
# Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
# purpose with or without fee is hereby granted, provided that the above
|
||||||
|
# copyright notice and this permission notice appear in all copies.
|
||||||
|
#
|
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
OBJS += techlibs/mchp/synth_mchp.o
|
||||||
|
OBJS += techlibs/mchp/mchp_dffopt.o
|
||||||
|
|
||||||
|
$(eval $(call add_share_file,share/mchp,techlibs/mchp/arith_map.v))
|
||||||
|
$(eval $(call add_share_file,share/mchp,techlibs/mchp/cells_map.v))
|
||||||
|
$(eval $(call add_share_file,share/mchp,techlibs/mchp/cells_sim.v))
|
||||||
|
$(eval $(call add_share_file,share/mchp,techlibs/mchp/pf_dsp_map.v))
|
||||||
|
|
||||||
|
$(eval $(call add_share_file,share/mchp,techlibs/mchp/brams_defs.vh))
|
||||||
|
$(eval $(call add_share_file,share/mchp,techlibs/mchp/LSRAM_map.v))
|
||||||
|
$(eval $(call add_share_file,share/mchp,techlibs/mchp/LSRAM.txt))
|
||||||
|
$(eval $(call add_share_file,share/mchp,techlibs/mchp/uSRAM_map.v))
|
||||||
|
$(eval $(call add_share_file,share/mchp,techlibs/mchp/uSRAM.txt))
|
|
@ -0,0 +1,105 @@
|
||||||
|
/*
|
||||||
|
ISC License
|
||||||
|
|
||||||
|
Copyright (C) 2024 Microchip Technology Inc. and its subsidiaries
|
||||||
|
|
||||||
|
Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
purpose with or without fee is hereby granted, provided that the above
|
||||||
|
copyright notice and this permission notice appear in all copies.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Based on Macro Library for PolarFire https://coredocs.s3.amazonaws.com/Libero/2021_2/Tool/pf_mlg.pdf
|
||||||
|
// NOTE: prefix module names with \$__ so that mapping prioritizes these cells over internal Yosys cells
|
||||||
|
|
||||||
|
|
||||||
|
(* techmap_celltype = "$_MUX4_" *)
|
||||||
|
module \$__mchp_MUX4_ (A, B, C, D, S, T, Y);
|
||||||
|
input A, B, C, D, S, T;
|
||||||
|
output Y;
|
||||||
|
MX4 _TECHMAP_REPLACE_.MUX4(.D3(D), .D2(C), .D1(B), .D0(A), .S1(T), .S0(S), .Y(Y));
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
|
||||||
|
(* techmap_celltype = "$reduce_xor" *)
|
||||||
|
module \$__mchp_XOR8_ (A, Y);
|
||||||
|
parameter A_SIGNED = 0;
|
||||||
|
parameter A_WIDTH = 0;
|
||||||
|
parameter Y_WIDTH = 0;
|
||||||
|
|
||||||
|
input [A_WIDTH-1:0] A;
|
||||||
|
output [Y_WIDTH-1:0] Y;
|
||||||
|
|
||||||
|
// check if mapping should proceed
|
||||||
|
generate
|
||||||
|
if (A_WIDTH != 8 || A_SIGNED || Y_WIDTH != 1) begin
|
||||||
|
wire _TECHMAP_FAIL_ = 1;
|
||||||
|
end
|
||||||
|
endgenerate
|
||||||
|
|
||||||
|
|
||||||
|
XOR8 _TECHMAP_REPLACE_.XOR8 (.A(A[0]), .B(A[1]), .C(A[2]), .D(A[3]), .E(A[4]), .F(A[5]), .G(A[6]), .H(A[7]), .Y(Y));
|
||||||
|
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
(* techmap_celltype = "$alu" *)
|
||||||
|
module \$__SF2_ALU (A, B, CI, BI, X, Y, CO);
|
||||||
|
parameter A_SIGNED = 0;
|
||||||
|
parameter B_SIGNED = 0;
|
||||||
|
parameter A_WIDTH = 1;
|
||||||
|
parameter B_WIDTH = 1;
|
||||||
|
parameter Y_WIDTH = 1;
|
||||||
|
|
||||||
|
(* force_downto *)
|
||||||
|
input [A_WIDTH-1:0] A;
|
||||||
|
(* force_downto *)
|
||||||
|
input [B_WIDTH-1:0] B;
|
||||||
|
(* force_downto *)
|
||||||
|
output [Y_WIDTH-1:0] X, Y;
|
||||||
|
|
||||||
|
input CI, BI;
|
||||||
|
(* force_downto *)
|
||||||
|
output [Y_WIDTH-1:0] CO;
|
||||||
|
|
||||||
|
wire _TECHMAP_FAIL_ = Y_WIDTH <= 2;
|
||||||
|
|
||||||
|
(* force_downto *)
|
||||||
|
wire [Y_WIDTH-1:0] AA, BB;
|
||||||
|
\$pos #(.A_SIGNED(A_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(Y_WIDTH)) A_conv (.A(A), .Y(AA));
|
||||||
|
\$pos #(.A_SIGNED(B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(Y_WIDTH)) B_conv (.A(B), .Y(BB));
|
||||||
|
|
||||||
|
(* force_downto *)
|
||||||
|
wire [Y_WIDTH-1:0] C = {CO, CI};
|
||||||
|
|
||||||
|
genvar i;
|
||||||
|
generate for (i = 0; i < Y_WIDTH; i = i + 1) begin:slice
|
||||||
|
ARI1 #(
|
||||||
|
// See section 1.4 of PolarFire Macro Library
|
||||||
|
|
||||||
|
// G = F1 = A[i] & (B[i]^BI)
|
||||||
|
// Y = F0 = A[i]^B[i]^BI
|
||||||
|
// P = Y
|
||||||
|
// ADCB
|
||||||
|
.INIT(20'b 01_11_0010_1000_1001_0110)
|
||||||
|
) carry (
|
||||||
|
.A(1'b0),
|
||||||
|
.B(AA[i]),
|
||||||
|
.C(BB[i]),
|
||||||
|
.D(BI),
|
||||||
|
.FCI(C[i]),
|
||||||
|
.Y(X[i]),
|
||||||
|
.S(Y[i]),
|
||||||
|
.FCO(CO[i])
|
||||||
|
);
|
||||||
|
end endgenerate
|
||||||
|
endmodule
|
||||||
|
|
|
@ -0,0 +1,48 @@
|
||||||
|
/*
|
||||||
|
ISC License
|
||||||
|
|
||||||
|
Copyright (C) 2024 Microchip Technology Inc. and its subsidiaries
|
||||||
|
|
||||||
|
Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
purpose with or without fee is hereby granted, provided that the above
|
||||||
|
copyright notice and this permission notice appear in all copies.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
`define PARAMS_INIT_LSRAM \
|
||||||
|
.INIT0(slice_init_LSRAM(00)), \
|
||||||
|
.INIT1(slice_init_LSRAM(01)), \
|
||||||
|
.INIT2(slice_init_LSRAM(02)), \
|
||||||
|
.INIT3(slice_init_LSRAM(03)), \
|
||||||
|
.INIT4(slice_init_LSRAM(04)), \
|
||||||
|
.INIT5(slice_init_LSRAM(05)), \
|
||||||
|
.INIT6(slice_init_LSRAM(06)), \
|
||||||
|
.INIT7(slice_init_LSRAM(07)), \
|
||||||
|
.INIT8(slice_init_LSRAM(08)), \
|
||||||
|
.INIT9(slice_init_LSRAM(09)), \
|
||||||
|
.INIT10(slice_init_LSRAM(10)), \
|
||||||
|
.INIT11(slice_init_LSRAM(11)), \
|
||||||
|
.INIT12(slice_init_LSRAM(12)), \
|
||||||
|
.INIT13(slice_init_LSRAM(13)), \
|
||||||
|
.INIT14(slice_init_LSRAM(14)), \
|
||||||
|
.INIT15(slice_init_LSRAM(15)), \
|
||||||
|
.INIT16(slice_init_LSRAM(16)), \
|
||||||
|
.INIT17(slice_init_LSRAM(17)), \
|
||||||
|
.INIT18(slice_init_LSRAM(18)), \
|
||||||
|
.INIT19(slice_init_LSRAM(19))
|
||||||
|
|
||||||
|
// Helper function for initializing the LSRAM
|
||||||
|
function [1023:0] slice_init_LSRAM;
|
||||||
|
input integer slice_idx;
|
||||||
|
integer i;
|
||||||
|
for (i = 0; i < 1024; i = i + 1)
|
||||||
|
slice_init_LSRAM[i] = INIT[(slice_idx * 1024 + i)];
|
||||||
|
endfunction
|
||||||
|
|
|
@ -0,0 +1,104 @@
|
||||||
|
/*
|
||||||
|
ISC License
|
||||||
|
|
||||||
|
Copyright (C) 2024 Microchip Technology Inc. and its subsidiaries
|
||||||
|
|
||||||
|
Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
purpose with or without fee is hereby granted, provided that the above
|
||||||
|
copyright notice and this permission notice appear in all copies.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// DFFs
|
||||||
|
module \$_DFFE_PN0P_ (input D, C, R, E, output Q);
|
||||||
|
SLE _TECHMAP_REPLACE_ (.D(D), .CLK(C), .EN(E), .ALn(R), .ADn(1'b1), .SLn(1'b1), .SD(1'b0), .LAT(1'b0), .Q(Q));
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module \$_DFFE_PN1P_ (input D, C, R, E, output Q);
|
||||||
|
SLE _TECHMAP_REPLACE_ (.D(D), .CLK(C), .EN(E), .ALn(R), .ADn(1'b0), .SLn(1'b1), .SD(1'b0), .LAT(1'b0), .Q(Q));
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
// for sync set/reset registers, we can pass them into ABC9. So we need to follow the simplification idiom
|
||||||
|
// and map to intermediate cell types
|
||||||
|
module \$_SDFFCE_PN0P_ (input D, C, R, E, output Q);
|
||||||
|
MCHP_SYNC_RESET_DFF _TECHMAP_REPLACE_ (.D(D), .CLK(C), .Reset(R), .En(E), .Q(Q));
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module \$_SDFFCE_PN1P_ (input D, C, R, E, output Q);
|
||||||
|
MCHP_SYNC_SET_DFF _TECHMAP_REPLACE_ (.D(D), .CLK(C), .Set(R), .En(E), .Q(Q));
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
|
||||||
|
// LATCHES
|
||||||
|
|
||||||
|
module \$_DLATCH_PN0_ (input D, R, E, output Q);
|
||||||
|
SLE _TECHMAP_REPLACE_ (.D(D), .CLK(E), .EN(1'b1), .ALn(R), .ADn(1'b1), .SLn(1'b1), .SD(1'b0), .LAT(1'b1), .Q(Q));
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module \$_DLATCH_PN1_ (input D, R, E, output Q);
|
||||||
|
SLE _TECHMAP_REPLACE_ (.D(D), .CLK(E), .EN(1'b1), .ALn(R), .ADn(1'b0), .SLn(1'b1), .SD(1'b0), .LAT(1'b1), .Q(Q));
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module \$_DLATCH_P_ (input D, E, output Q);
|
||||||
|
SLE _TECHMAP_REPLACE_ (.D(D), .CLK(E), .EN(1'b1), .ALn(1'b1), .ADn(1'b0), .SLn(1'b1), .SD(1'b0), .LAT(1'b1), .Q(Q));
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
// map intermediate flops to SLE
|
||||||
|
`ifdef FINAL_MAP
|
||||||
|
module MCHP_SYNC_SET_DFF(
|
||||||
|
input D,
|
||||||
|
input CLK,
|
||||||
|
input Set,
|
||||||
|
input En,
|
||||||
|
output Q);
|
||||||
|
SLE _TECHMAP_REPLACE_ (.D(D), .CLK(CLK), .EN(En), .ALn(1'b1), .ADn(1'b0), .SLn(Set), .SD(1'b1), .LAT(1'b0), .Q(Q));
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module MCHP_SYNC_RESET_DFF(
|
||||||
|
input D,
|
||||||
|
input CLK,
|
||||||
|
input Reset,
|
||||||
|
input En,
|
||||||
|
output Q);
|
||||||
|
SLE _TECHMAP_REPLACE_ (.D(D), .CLK(CLK), .EN(En), .ALn(1'b1), .ADn(1'b0), .SLn(Reset), .SD(1'b0), .LAT(1'b0), .Q(Q));
|
||||||
|
endmodule
|
||||||
|
`endif
|
||||||
|
|
||||||
|
|
||||||
|
// LUT
|
||||||
|
|
||||||
|
`ifndef NO_LUT
|
||||||
|
module \$lut (A, Y);
|
||||||
|
parameter WIDTH = 0;
|
||||||
|
parameter LUT = 0;
|
||||||
|
|
||||||
|
(* force_downto *)
|
||||||
|
input [WIDTH-1:0] A;
|
||||||
|
output Y;
|
||||||
|
|
||||||
|
generate
|
||||||
|
if (WIDTH == 1) begin
|
||||||
|
CFG1 #(.INIT(LUT)) _TECHMAP_REPLACE_ (.Y(Y), .A(A[0]));
|
||||||
|
end else
|
||||||
|
if (WIDTH == 2) begin
|
||||||
|
CFG2 #(.INIT(LUT)) _TECHMAP_REPLACE_ (.Y(Y), .A(A[0]), .B(A[1]));
|
||||||
|
end else
|
||||||
|
if (WIDTH == 3) begin
|
||||||
|
CFG3 #(.INIT(LUT)) _TECHMAP_REPLACE_ (.Y(Y), .A(A[0]), .B(A[1]), .C(A[2]));
|
||||||
|
end else
|
||||||
|
if (WIDTH == 4) begin
|
||||||
|
CFG4 #(.INIT(LUT)) _TECHMAP_REPLACE_ (.Y(Y), .A(A[0]), .B(A[1]), .C(A[2]), .D(A[3]));
|
||||||
|
end else begin
|
||||||
|
wire _TECHMAP_FAIL_ = 1;
|
||||||
|
end
|
||||||
|
endgenerate
|
||||||
|
endmodule
|
||||||
|
`endif
|
||||||
|
|
|
@ -0,0 +1,849 @@
|
||||||
|
/*
|
||||||
|
ISC License
|
||||||
|
|
||||||
|
Copyright (C) 2024 Microchip Technology Inc. and its subsidiaries
|
||||||
|
|
||||||
|
Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
purpose with or without fee is hereby granted, provided that the above
|
||||||
|
copyright notice and this permission notice appear in all copies.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Macro Library for PolarFire https://coredocs.s3.amazonaws.com/Libero/2021_2/Tool/pf_mlg.pdf
|
||||||
|
|
||||||
|
module AND2 (
|
||||||
|
input A, B,
|
||||||
|
output Y
|
||||||
|
);
|
||||||
|
assign Y = A & B;
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module AND3 (
|
||||||
|
input A, B, C,
|
||||||
|
output Y
|
||||||
|
);
|
||||||
|
assign Y = A & B & C;
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module AND4 (
|
||||||
|
input A, B, C, D,
|
||||||
|
output Y
|
||||||
|
);
|
||||||
|
assign Y = A & B & C & D;
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
(* abc9_lut=1 *)
|
||||||
|
module CFG1 (
|
||||||
|
output Y,
|
||||||
|
input A
|
||||||
|
);
|
||||||
|
parameter [1:0] INIT = 2'h0;
|
||||||
|
assign Y = INIT >> A;
|
||||||
|
specify
|
||||||
|
(A => Y) = 127;
|
||||||
|
endspecify
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
(* abc9_lut=2 *)
|
||||||
|
module CFG2 (
|
||||||
|
output Y,
|
||||||
|
input A,
|
||||||
|
input B
|
||||||
|
);
|
||||||
|
parameter [3:0] INIT = 4'h0;
|
||||||
|
assign Y = INIT >> {B, A};
|
||||||
|
specify
|
||||||
|
(A => Y) = 238;
|
||||||
|
(B => Y) = 127;
|
||||||
|
endspecify
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
(* abc9_lut=3 *)
|
||||||
|
module CFG3 (
|
||||||
|
output Y,
|
||||||
|
input A,
|
||||||
|
input B,
|
||||||
|
input C
|
||||||
|
);
|
||||||
|
parameter [7:0] INIT = 8'h0;
|
||||||
|
assign Y = INIT >> {C, B, A};
|
||||||
|
specify
|
||||||
|
(A => Y) = 407;
|
||||||
|
(B => Y) = 238;
|
||||||
|
(C => Y) = 127;
|
||||||
|
endspecify
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
(* abc9_lut=3 *)
|
||||||
|
module CFG4 (
|
||||||
|
output Y,
|
||||||
|
input A,
|
||||||
|
input B,
|
||||||
|
input C,
|
||||||
|
input D
|
||||||
|
);
|
||||||
|
parameter [15:0] INIT = 16'h0;
|
||||||
|
assign Y = INIT >> {D, C, B, A};
|
||||||
|
specify
|
||||||
|
(A => Y) = 472;
|
||||||
|
(B => Y) = 407;
|
||||||
|
(C => Y) = 238;
|
||||||
|
(D => Y) = 127;
|
||||||
|
endspecify
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module BUFF (
|
||||||
|
input A,
|
||||||
|
output Y
|
||||||
|
);
|
||||||
|
assign Y = A;
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module BUFD (
|
||||||
|
input A,
|
||||||
|
output Y
|
||||||
|
);
|
||||||
|
assign Y = A;
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module CLKINT (
|
||||||
|
input A,
|
||||||
|
(* clkbuf_driver *)
|
||||||
|
output Y
|
||||||
|
);
|
||||||
|
assign Y = A;
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module CLKINT_PRESERVE (
|
||||||
|
input A,
|
||||||
|
(* clkbuf_driver *)
|
||||||
|
output Y
|
||||||
|
);
|
||||||
|
assign Y = A;
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module GCLKINT (
|
||||||
|
input A, EN,
|
||||||
|
(* clkbuf_driver *)
|
||||||
|
output Y
|
||||||
|
);
|
||||||
|
assign Y = A & EN;
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module RCLKINT (
|
||||||
|
input A,
|
||||||
|
(* clkbuf_driver *)
|
||||||
|
output Y
|
||||||
|
);
|
||||||
|
assign Y = A;
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module RGCLKINT (
|
||||||
|
input A, EN,
|
||||||
|
(* clkbuf_driver *)
|
||||||
|
output Y
|
||||||
|
);
|
||||||
|
assign Y = A & EN;
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
// sequential elements
|
||||||
|
|
||||||
|
// MCHP_SYNC_SET_DFF and MCHP_SYNC_RESET_DFF are intermediate cell types to implement the simplification idiom for abc9 flow
|
||||||
|
// see: https://yosyshq.readthedocs.io/projects/yosys/en/latest/yosys_internals/extending_yosys/abc_flow.html
|
||||||
|
|
||||||
|
(* abc9_flop, lib_whitebox *)
|
||||||
|
module MCHP_SYNC_SET_DFF(
|
||||||
|
input D,
|
||||||
|
input CLK,
|
||||||
|
input Set,
|
||||||
|
input En,
|
||||||
|
output Q);
|
||||||
|
parameter [0:0] INIT = 1'b0; // unused
|
||||||
|
always @(posedge CLK) begin
|
||||||
|
if (En == 1) begin
|
||||||
|
if (Set == 0)
|
||||||
|
Q <= 1;
|
||||||
|
else
|
||||||
|
Q <= D;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
specify
|
||||||
|
$setup(D , posedge CLK &&& En && Set, 0); // neg setup not supported?
|
||||||
|
$setup(En, posedge CLK, 109);
|
||||||
|
$setup(Set, posedge CLK &&& En, 404);
|
||||||
|
if (En && !Set) (posedge CLK => (Q : 1'b1)) = 303;
|
||||||
|
if (En && Set) (posedge CLK => (Q : D)) = 303;
|
||||||
|
endspecify
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
(* abc9_flop, lib_whitebox *)
|
||||||
|
module MCHP_SYNC_RESET_DFF(
|
||||||
|
input D,
|
||||||
|
input CLK,
|
||||||
|
input Reset,
|
||||||
|
input En,
|
||||||
|
output Q);
|
||||||
|
parameter [0:0] INIT = 1'b0; // unused
|
||||||
|
always @(posedge C) begin
|
||||||
|
if (En == 1) begin
|
||||||
|
if (Reset == 0)
|
||||||
|
Q <= 0;
|
||||||
|
else
|
||||||
|
Q <= D;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
specify
|
||||||
|
$setup(D , posedge CLK &&& En && Reset, 0); // neg setup not supported?
|
||||||
|
$setup(En, posedge CLK, 109);
|
||||||
|
$setup(Reset, posedge CLK &&& En, 404);
|
||||||
|
if (En && !Reset) (posedge CLK => (Q : 1'b0)) = 303;
|
||||||
|
if (En && Reset) (posedge CLK => (Q : D)) = 303;
|
||||||
|
endspecify
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module SLE (
|
||||||
|
output Q,
|
||||||
|
input ADn,
|
||||||
|
input ALn,
|
||||||
|
(* clkbuf_sink *)
|
||||||
|
input CLK,
|
||||||
|
input D,
|
||||||
|
input LAT,
|
||||||
|
input SD,
|
||||||
|
input EN,
|
||||||
|
input SLn
|
||||||
|
);
|
||||||
|
reg q_latch, q_ff;
|
||||||
|
|
||||||
|
always @(posedge CLK, negedge ALn) begin
|
||||||
|
if (!ALn) begin
|
||||||
|
q_ff <= !ADn;
|
||||||
|
end else if (EN) begin
|
||||||
|
if (!SLn)
|
||||||
|
q_ff <= SD;
|
||||||
|
else
|
||||||
|
q_ff <= D;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
always @* begin
|
||||||
|
if (!ALn) begin
|
||||||
|
q_latch <= !ADn;
|
||||||
|
end else if (CLK && EN) begin
|
||||||
|
if (!SLn)
|
||||||
|
q_ff <= SD;
|
||||||
|
else
|
||||||
|
q_ff <= D;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
assign Q = LAT ? q_latch : q_ff;
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
(* abc9_box, lib_whitebox *)
|
||||||
|
module ARI1 (
|
||||||
|
(* abc9_carry *)
|
||||||
|
input FCI,
|
||||||
|
(* abc9_carry *)
|
||||||
|
output FCO,
|
||||||
|
|
||||||
|
input A, B, C, D,
|
||||||
|
output Y, S
|
||||||
|
);
|
||||||
|
parameter [19:0] INIT = 20'h0;
|
||||||
|
wire [2:0] Fsel = {D, C, B};
|
||||||
|
wire F0 = INIT[Fsel];
|
||||||
|
wire F1 = INIT[8 + Fsel];
|
||||||
|
wire Yout = A ? F1 : F0;
|
||||||
|
assign Y = Yout;
|
||||||
|
assign S = FCI ^ Yout;
|
||||||
|
wire G = INIT[16] ? (INIT[17] ? F1 : F0) : INIT[17];
|
||||||
|
wire P = INIT[19] ? 1'b1 : (INIT[18] ? Yout : 1'b0);
|
||||||
|
assign FCO = P ? FCI : G;
|
||||||
|
|
||||||
|
specify
|
||||||
|
//pin to pin path delay
|
||||||
|
(A => Y ) = 472;
|
||||||
|
(B => Y ) = 407;
|
||||||
|
(C => Y ) = 238;
|
||||||
|
(D => Y ) = 127;
|
||||||
|
(A => S ) = 572;
|
||||||
|
(B => S ) = 507;
|
||||||
|
(C => S ) = 338;
|
||||||
|
(D => S ) = 227;
|
||||||
|
(FCI => S ) = 100;
|
||||||
|
(A => FCO ) = 522;
|
||||||
|
(B => FCO ) = 457;
|
||||||
|
(C => FCO ) = 288;
|
||||||
|
(D => FCO ) = 177;
|
||||||
|
(FCI => FCO ) = 50;
|
||||||
|
endspecify
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
// module FCEND_BUFF
|
||||||
|
// module FCINIT_BUFF
|
||||||
|
// module FLASH_FREEZE
|
||||||
|
// module OSCILLATOR
|
||||||
|
// module SYSCTRL_RESET_STATUS
|
||||||
|
// module LIVE_PROBE_FB
|
||||||
|
|
||||||
|
(* blackbox *)
|
||||||
|
module GCLKBUF (
|
||||||
|
(* iopad_external_pin *)
|
||||||
|
input PAD,
|
||||||
|
input EN,
|
||||||
|
(* clkbuf_driver *)
|
||||||
|
output Y
|
||||||
|
);
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
(* blackbox *)
|
||||||
|
module GCLKBUF_DIFF (
|
||||||
|
(* iopad_external_pin *)
|
||||||
|
input PADP,
|
||||||
|
(* iopad_external_pin *)
|
||||||
|
input PADN,
|
||||||
|
input EN,
|
||||||
|
(* clkbuf_driver *)
|
||||||
|
output Y
|
||||||
|
);
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
(* blackbox *)
|
||||||
|
module GCLKBIBUF (
|
||||||
|
input D,
|
||||||
|
input E,
|
||||||
|
input EN,
|
||||||
|
(* iopad_external_pin *)
|
||||||
|
inout PAD,
|
||||||
|
(* clkbuf_driver *)
|
||||||
|
output Y
|
||||||
|
);
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
// module DFN1
|
||||||
|
// module DFN1C0
|
||||||
|
// module DFN1E1
|
||||||
|
// module DFN1E1C0
|
||||||
|
// module DFN1E1P0
|
||||||
|
// module DFN1P0
|
||||||
|
// module DLN1
|
||||||
|
// module DLN1C0
|
||||||
|
// module DLN1P0
|
||||||
|
|
||||||
|
module INV (
|
||||||
|
input A,
|
||||||
|
output Y
|
||||||
|
);
|
||||||
|
assign Y = !A;
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module INVD (
|
||||||
|
input A,
|
||||||
|
output Y
|
||||||
|
);
|
||||||
|
assign Y = !A;
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module MX2 (
|
||||||
|
input A, B, S,
|
||||||
|
output Y
|
||||||
|
);
|
||||||
|
assign Y = S ? B : A;
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module MX4 (
|
||||||
|
input D0, D1, D2, D3, S0, S1,
|
||||||
|
output Y
|
||||||
|
);
|
||||||
|
assign Y = S1 ? (S0 ? D3 : D2) : (S0 ? D1 : D0);
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module NAND2 (
|
||||||
|
input A, B,
|
||||||
|
output Y
|
||||||
|
);
|
||||||
|
assign Y = !(A & B);
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module NAND3 (
|
||||||
|
input A, B, C,
|
||||||
|
output Y
|
||||||
|
);
|
||||||
|
assign Y = !(A & B & C);
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module NAND4 (
|
||||||
|
input A, B, C, D,
|
||||||
|
output Y
|
||||||
|
);
|
||||||
|
assign Y = !(A & B & C & D);
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module NOR2 (
|
||||||
|
input A, B,
|
||||||
|
output Y
|
||||||
|
);
|
||||||
|
assign Y = !(A | B);
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module NOR3 (
|
||||||
|
input A, B, C,
|
||||||
|
output Y
|
||||||
|
);
|
||||||
|
assign Y = !(A | B | C);
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module NOR4 (
|
||||||
|
input A, B, C, D,
|
||||||
|
output Y
|
||||||
|
);
|
||||||
|
assign Y = !(A | B | C | D);
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module OR2 (
|
||||||
|
input A, B,
|
||||||
|
output Y
|
||||||
|
);
|
||||||
|
assign Y = A | B;
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module OR3 (
|
||||||
|
input A, B, C,
|
||||||
|
output Y
|
||||||
|
);
|
||||||
|
assign Y = A | B | C;
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module OR4 (
|
||||||
|
input A, B, C, D,
|
||||||
|
output Y
|
||||||
|
);
|
||||||
|
assign Y = A | B | C | D;
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module XOR2 (
|
||||||
|
input A, B,
|
||||||
|
output Y
|
||||||
|
);
|
||||||
|
assign Y = A ^ B;
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module XOR3 (
|
||||||
|
input A, B, C,
|
||||||
|
output Y
|
||||||
|
);
|
||||||
|
assign Y = A ^ B ^ C;
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module XOR4 (
|
||||||
|
input A, B, C, D,
|
||||||
|
output Y
|
||||||
|
);
|
||||||
|
assign Y = A ^ B ^ C ^ D;
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module XOR8 (
|
||||||
|
input A, B, C, D, E, F, G, H,
|
||||||
|
output Y
|
||||||
|
);
|
||||||
|
assign Y = A ^ B ^ C ^ D ^ E ^ F ^ G ^ H;
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
// module UJTAG
|
||||||
|
|
||||||
|
module BIBUF (
|
||||||
|
input D,
|
||||||
|
input E,
|
||||||
|
(* iopad_external_pin *)
|
||||||
|
inout PAD,
|
||||||
|
output Y
|
||||||
|
);
|
||||||
|
parameter IOSTD = "";
|
||||||
|
assign PAD = E ? D : 1'bz;
|
||||||
|
assign Y = PAD;
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
(* blackbox *)
|
||||||
|
module BIBUF_DIFF (
|
||||||
|
input D,
|
||||||
|
input E,
|
||||||
|
(* iopad_external_pin *)
|
||||||
|
inout PADP,
|
||||||
|
(* iopad_external_pin *)
|
||||||
|
inout PADN,
|
||||||
|
output Y
|
||||||
|
);
|
||||||
|
parameter IOSTD = "";
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module CLKBIBUF (
|
||||||
|
input D,
|
||||||
|
input E,
|
||||||
|
(* iopad_external_pin *)
|
||||||
|
inout PAD,
|
||||||
|
(* clkbuf_driver *)
|
||||||
|
output Y
|
||||||
|
);
|
||||||
|
parameter IOSTD = "";
|
||||||
|
assign PAD = E ? D : 1'bz;
|
||||||
|
assign Y = PAD;
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module CLKBUF (
|
||||||
|
(* iopad_external_pin *)
|
||||||
|
input PAD,
|
||||||
|
(* clkbuf_driver *)
|
||||||
|
output Y
|
||||||
|
);
|
||||||
|
parameter IOSTD = "";
|
||||||
|
assign Y = PAD;
|
||||||
|
specify
|
||||||
|
(PAD => Y) = 50;
|
||||||
|
endspecify
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
(* blackbox *)
|
||||||
|
module CLKBUF_DIFF (
|
||||||
|
(* iopad_external_pin *)
|
||||||
|
input PADP,
|
||||||
|
(* iopad_external_pin *)
|
||||||
|
input PADN,
|
||||||
|
(* clkbuf_driver *)
|
||||||
|
output Y
|
||||||
|
);
|
||||||
|
parameter IOSTD = "";
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module INBUF (
|
||||||
|
(* iopad_external_pin *)
|
||||||
|
input PAD,
|
||||||
|
output Y
|
||||||
|
);
|
||||||
|
parameter IOSTD = "";
|
||||||
|
assign Y = PAD;
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
(* blackbox *)
|
||||||
|
module INBUF_DIFF (
|
||||||
|
(* iopad_external_pin *)
|
||||||
|
input PADP,
|
||||||
|
(* iopad_external_pin *)
|
||||||
|
input PADN,
|
||||||
|
output Y
|
||||||
|
);
|
||||||
|
parameter IOSTD = "";
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module OUTBUF (
|
||||||
|
input D,
|
||||||
|
(* iopad_external_pin *)
|
||||||
|
output PAD
|
||||||
|
);
|
||||||
|
parameter IOSTD = "";
|
||||||
|
assign PAD = D;
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
(* blackbox *)
|
||||||
|
module OUTBUF_DIFF (
|
||||||
|
input D,
|
||||||
|
(* iopad_external_pin *)
|
||||||
|
output PADP,
|
||||||
|
(* iopad_external_pin *)
|
||||||
|
output PADN
|
||||||
|
);
|
||||||
|
parameter IOSTD = "";
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module TRIBUFF (
|
||||||
|
input D,
|
||||||
|
input E,
|
||||||
|
(* iopad_external_pin *)
|
||||||
|
output PAD
|
||||||
|
);
|
||||||
|
parameter IOSTD = "";
|
||||||
|
assign PAD = E ? D : 1'bz;
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
(* blackbox *)
|
||||||
|
module TRIBUFF_DIFF (
|
||||||
|
input D,
|
||||||
|
input E,
|
||||||
|
(* iopad_external_pin *)
|
||||||
|
output PADP,
|
||||||
|
(* iopad_external_pin *)
|
||||||
|
output PADN
|
||||||
|
);
|
||||||
|
parameter IOSTD = "";
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
// module DDR_IN
|
||||||
|
// module DDR_OUT
|
||||||
|
// module RAM1K18
|
||||||
|
// module RAM64x18
|
||||||
|
// module MACC
|
||||||
|
|
||||||
|
(* blackbox *)
|
||||||
|
module SYSRESET (
|
||||||
|
(* iopad_external_pin *)
|
||||||
|
input DEVRST_N,
|
||||||
|
output POWER_ON_RESET_N);
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
|
||||||
|
(* blackbox *)
|
||||||
|
module XTLOSC (
|
||||||
|
(* iopad_external_pin *)
|
||||||
|
input XTL,
|
||||||
|
output CLKOUT);
|
||||||
|
parameter [1:0] MODE = 2'h3;
|
||||||
|
parameter real FREQUENCY = 20.0;
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
(* blackbox *)
|
||||||
|
module RAM1K18 (
|
||||||
|
input [13:0] A_ADDR,
|
||||||
|
input [2:0] A_BLK,
|
||||||
|
(* clkbuf_sink *)
|
||||||
|
input A_CLK,
|
||||||
|
input [17:0] A_DIN,
|
||||||
|
output [17:0] A_DOUT,
|
||||||
|
input [1:0] A_WEN,
|
||||||
|
input [2:0] A_WIDTH,
|
||||||
|
input A_WMODE,
|
||||||
|
input A_ARST_N,
|
||||||
|
input A_DOUT_LAT,
|
||||||
|
input A_DOUT_ARST_N,
|
||||||
|
(* clkbuf_sink *)
|
||||||
|
input A_DOUT_CLK,
|
||||||
|
input A_DOUT_EN,
|
||||||
|
input A_DOUT_SRST_N,
|
||||||
|
|
||||||
|
input [13:0] B_ADDR,
|
||||||
|
input [2:0] B_BLK,
|
||||||
|
(* clkbuf_sink *)
|
||||||
|
input B_CLK,
|
||||||
|
input [17:0] B_DIN,
|
||||||
|
output [17:0] B_DOUT,
|
||||||
|
input [1:0] B_WEN,
|
||||||
|
input [2:0] B_WIDTH,
|
||||||
|
input B_WMODE,
|
||||||
|
input B_ARST_N,
|
||||||
|
input B_DOUT_LAT,
|
||||||
|
input B_DOUT_ARST_N,
|
||||||
|
(* clkbuf_sink *)
|
||||||
|
input B_DOUT_CLK,
|
||||||
|
input B_DOUT_EN,
|
||||||
|
input B_DOUT_SRST_N,
|
||||||
|
|
||||||
|
input A_EN,
|
||||||
|
input B_EN,
|
||||||
|
input SII_LOCK,
|
||||||
|
output BUSY);
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
(* blackbox *)
|
||||||
|
module RAM64x18 (
|
||||||
|
input [9:0] A_ADDR,
|
||||||
|
input [1:0] A_BLK,
|
||||||
|
input [2:0] A_WIDTH,
|
||||||
|
output [17:0] A_DOUT,
|
||||||
|
input A_DOUT_ARST_N,
|
||||||
|
(* clkbuf_sink *)
|
||||||
|
input A_DOUT_CLK,
|
||||||
|
input A_DOUT_EN,
|
||||||
|
input A_DOUT_LAT,
|
||||||
|
input A_DOUT_SRST_N,
|
||||||
|
(* clkbuf_sink *)
|
||||||
|
input A_ADDR_CLK,
|
||||||
|
input A_ADDR_EN,
|
||||||
|
input A_ADDR_LAT,
|
||||||
|
input A_ADDR_SRST_N,
|
||||||
|
input A_ADDR_ARST_N,
|
||||||
|
|
||||||
|
input [9:0] B_ADDR,
|
||||||
|
input [1:0] B_BLK,
|
||||||
|
input [2:0] B_WIDTH,
|
||||||
|
output [17:0] B_DOUT,
|
||||||
|
input B_DOUT_ARST_N,
|
||||||
|
(* clkbuf_sink *)
|
||||||
|
input B_DOUT_CLK,
|
||||||
|
input B_DOUT_EN,
|
||||||
|
input B_DOUT_LAT,
|
||||||
|
input B_DOUT_SRST_N,
|
||||||
|
(* clkbuf_sink *)
|
||||||
|
input B_ADDR_CLK,
|
||||||
|
input B_ADDR_EN,
|
||||||
|
input B_ADDR_LAT,
|
||||||
|
input B_ADDR_SRST_N,
|
||||||
|
input B_ADDR_ARST_N,
|
||||||
|
|
||||||
|
input [9:0] C_ADDR,
|
||||||
|
(* clkbuf_sink *)
|
||||||
|
input C_CLK,
|
||||||
|
input [17:0] C_DIN,
|
||||||
|
input C_WEN,
|
||||||
|
input [1:0] C_BLK,
|
||||||
|
input [2:0] C_WIDTH,
|
||||||
|
|
||||||
|
input A_EN,
|
||||||
|
input B_EN,
|
||||||
|
input C_EN,
|
||||||
|
input SII_LOCK,
|
||||||
|
output BUSY);
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
(* blackbox *)
|
||||||
|
module MACC_PA (
|
||||||
|
input DOTP,
|
||||||
|
input SIMD,
|
||||||
|
input OVFL_CARRYOUT_SEL,
|
||||||
|
input CLK,
|
||||||
|
input AL_N,
|
||||||
|
input [17:0] A,
|
||||||
|
input A_BYPASS,
|
||||||
|
input A_SRST_N,
|
||||||
|
input A_EN,
|
||||||
|
input [17:0] B,
|
||||||
|
input B_BYPASS,
|
||||||
|
input B_SRST_N,
|
||||||
|
input B_EN,
|
||||||
|
input [17:0] D,
|
||||||
|
input D_BYPASS,
|
||||||
|
input D_ARST_N,
|
||||||
|
input D_SRST_N,
|
||||||
|
input D_EN,
|
||||||
|
input CARRYIN,
|
||||||
|
input [47:0] C,
|
||||||
|
input C_BYPASS,
|
||||||
|
input C_ARST_N,
|
||||||
|
input C_SRST_N,
|
||||||
|
input C_EN,
|
||||||
|
input [47:0] CDIN,
|
||||||
|
output [47:0] P,
|
||||||
|
output OVFL_CARRYOUT,
|
||||||
|
input P_BYPASS,
|
||||||
|
input P_SRST_N,
|
||||||
|
input P_EN,
|
||||||
|
output [47:0] CDOUT,
|
||||||
|
input PASUB,
|
||||||
|
input PASUB_BYPASS,
|
||||||
|
input PASUB_AD_N,
|
||||||
|
input PASUB_SL_N,
|
||||||
|
input PASUB_SD_N,
|
||||||
|
input PASUB_EN,
|
||||||
|
input [1:0] CDIN_FDBK_SEL,
|
||||||
|
input CDIN_FDBK_SEL_BYPASS,
|
||||||
|
input [1:0] CDIN_FDBK_SEL_AD_N,
|
||||||
|
input CDIN_FDBK_SEL_SL_N,
|
||||||
|
input [1:0] CDIN_FDBK_SEL_SD_N,
|
||||||
|
input CDIN_FDBK_SEL_EN,
|
||||||
|
input ARSHFT17,
|
||||||
|
input ARSHFT17_BYPASS,
|
||||||
|
input ARSHFT17_AD_N,
|
||||||
|
input ARSHFT17_SL_N,
|
||||||
|
input ARSHFT17_SD_N,
|
||||||
|
input ARSHFT17_EN,
|
||||||
|
input SUB,
|
||||||
|
input SUB_BYPASS,
|
||||||
|
input SUB_AD_N,
|
||||||
|
input SUB_SL_N,
|
||||||
|
input SUB_SD_N,
|
||||||
|
input SUB_EN
|
||||||
|
);
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
(* blackbox *)
|
||||||
|
module RAM1K20 (
|
||||||
|
input [13:0] A_ADDR,
|
||||||
|
input [2:0] A_BLK_EN,
|
||||||
|
input A_CLK,
|
||||||
|
input [19:0] A_DIN,
|
||||||
|
output [19:0] A_DOUT,
|
||||||
|
input [1:0] A_WEN,
|
||||||
|
input A_REN,
|
||||||
|
input [2:0] A_WIDTH,
|
||||||
|
input [1:0] A_WMODE,
|
||||||
|
input A_BYPASS,
|
||||||
|
input A_DOUT_EN,
|
||||||
|
input A_DOUT_SRST_N,
|
||||||
|
input A_DOUT_ARST_N,
|
||||||
|
input [13:0] B_ADDR,
|
||||||
|
input [2:0] B_BLK_EN,
|
||||||
|
input B_CLK,
|
||||||
|
input [19:0] B_DIN,
|
||||||
|
output [19:0] B_DOUT,
|
||||||
|
input [1:0] B_WEN,
|
||||||
|
input B_REN,
|
||||||
|
input [2:0] B_WIDTH,
|
||||||
|
input [1:0] B_WMODE,
|
||||||
|
input B_BYPASS,
|
||||||
|
input B_DOUT_EN,
|
||||||
|
input B_DOUT_SRST_N,
|
||||||
|
input B_DOUT_ARST_N,
|
||||||
|
input ECC_EN,
|
||||||
|
input ECC_BYPASS,
|
||||||
|
output SB_CORRECT,
|
||||||
|
output DB_DETECT,
|
||||||
|
input BUSY_FB,
|
||||||
|
output ACCESS_BUSY
|
||||||
|
);
|
||||||
|
parameter INIT0 = 1024'h0;
|
||||||
|
parameter INIT1 = 1024'h0;
|
||||||
|
parameter INIT2 = 1024'h0;
|
||||||
|
parameter INIT3 = 1024'h0;
|
||||||
|
parameter INIT4 = 1024'h0;
|
||||||
|
parameter INIT5 = 1024'h0;
|
||||||
|
parameter INIT6 = 1024'h0;
|
||||||
|
parameter INIT7 = 1024'h0;
|
||||||
|
parameter INIT8 = 1024'h0;
|
||||||
|
parameter INIT9 = 1024'h0;
|
||||||
|
parameter INIT10 = 1024'h0;
|
||||||
|
parameter INIT11 = 1024'h0;
|
||||||
|
parameter INIT12 = 1024'h0;
|
||||||
|
parameter INIT13 = 1024'h0;
|
||||||
|
parameter INIT14 = 1024'h0;
|
||||||
|
parameter INIT15 = 1024'h0;
|
||||||
|
parameter INIT16 = 1024'h0;
|
||||||
|
parameter INIT17 = 1024'h0;
|
||||||
|
parameter INIT18 = 1024'h0;
|
||||||
|
parameter INIT19 = 1024'h0;
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
(* blackbox *)
|
||||||
|
module RAM64x12 (
|
||||||
|
input R_CLK,
|
||||||
|
input [5:0] R_ADDR,
|
||||||
|
input R_ADDR_BYPASS,
|
||||||
|
input R_ADDR_EN,
|
||||||
|
input R_ADDR_SL_N,
|
||||||
|
input R_ADDR_SD,
|
||||||
|
input R_ADDR_AL_N,
|
||||||
|
input R_ADDR_AD_N,
|
||||||
|
input BLK_EN,
|
||||||
|
output [11:0] R_DATA,
|
||||||
|
input R_DATA_BYPASS,
|
||||||
|
input R_DATA_EN,
|
||||||
|
input R_DATA_SL_N,
|
||||||
|
input R_DATA_SD,
|
||||||
|
input R_DATA_AL_N,
|
||||||
|
input R_DATA_AD_N,
|
||||||
|
|
||||||
|
input W_CLK,
|
||||||
|
input [5:0] W_ADDR,
|
||||||
|
input [11:0] W_DATA,
|
||||||
|
input W_EN,
|
||||||
|
|
||||||
|
input BUSY_FB,
|
||||||
|
output ACCESS_BUSY
|
||||||
|
);
|
||||||
|
endmodule
|
|
@ -0,0 +1,340 @@
|
||||||
|
/*
|
||||||
|
ISC License
|
||||||
|
|
||||||
|
Copyright (C) 2024 Microchip Technology Inc. and its subsidiaries
|
||||||
|
|
||||||
|
Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
purpose with or without fee is hereby granted, provided that the above
|
||||||
|
copyright notice and this permission notice appear in all copies.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "kernel/yosys.h"
|
||||||
|
#include "kernel/sigtools.h"
|
||||||
|
|
||||||
|
USING_YOSYS_NAMESPACE
|
||||||
|
PRIVATE_NAMESPACE_BEGIN
|
||||||
|
|
||||||
|
typedef std::pair<Const, std::vector<SigBit>> LutData;
|
||||||
|
|
||||||
|
// Compute a LUT implementing (select ^ select_inv) ? alt_data : data. Returns true if successful.
|
||||||
|
bool merge_lut(LutData &result, const LutData &data, const LutData select, bool select_inv, SigBit alt_data, int max_lut_size) {
|
||||||
|
// First, gather input signals -- insert new signals at the beginning
|
||||||
|
// of the vector, so they don't disturb the likely-critical D LUT input
|
||||||
|
// timings.
|
||||||
|
result.second = data.second;
|
||||||
|
// D lut inputs initially start at 0.
|
||||||
|
int idx_data = 0;
|
||||||
|
// Now add the control input LUT inputs.
|
||||||
|
std::vector<int> idx_sel;
|
||||||
|
for (auto bit : select.second) {
|
||||||
|
int idx = -1;
|
||||||
|
for (int i = 0; i < GetSize(result.second); i++)
|
||||||
|
if (result.second[i] == bit)
|
||||||
|
idx = i;
|
||||||
|
if (idx == -1) {
|
||||||
|
idx = 0;
|
||||||
|
// Insert new signal at the beginning and bump all indices.
|
||||||
|
result.second.insert(result.second.begin(), bit);
|
||||||
|
idx_data++;
|
||||||
|
for (int &sidx : idx_sel)
|
||||||
|
sidx++;
|
||||||
|
}
|
||||||
|
idx_sel.push_back(idx);
|
||||||
|
}
|
||||||
|
// Insert the Q signal, if any, to the slowest input -- it will have
|
||||||
|
// no problem meeting timing.
|
||||||
|
// This is to emulate CLK_EN, where output data is retained
|
||||||
|
int idx_alt = -1;
|
||||||
|
if (alt_data.wire) {
|
||||||
|
// Check if we already have it.
|
||||||
|
for (int i = 0; i < GetSize(result.second); i++)
|
||||||
|
if (result.second[i] == alt_data)
|
||||||
|
idx_alt = i;
|
||||||
|
// If not, add it.
|
||||||
|
if (idx_alt == -1) {
|
||||||
|
idx_alt = 0;
|
||||||
|
result.second.insert(result.second.begin(), alt_data);
|
||||||
|
idx_data++;
|
||||||
|
for (int &sidx : idx_sel)
|
||||||
|
sidx++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If LUT would be too large, bail.
|
||||||
|
if (GetSize(result.second) > max_lut_size)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Okay, we're doing it — compute the LUT mask.
|
||||||
|
result.first = Const(0, 1 << GetSize(result.second));
|
||||||
|
for (int i = 0; i < GetSize(result.first); i++) {
|
||||||
|
int sel_lut_idx = 0;
|
||||||
|
for (int j = 0; j < GetSize(select.second); j++)
|
||||||
|
if (i & 1 << idx_sel[j])
|
||||||
|
sel_lut_idx |= 1 << j;
|
||||||
|
bool select_val = (select.first.bits[sel_lut_idx] == State::S1);
|
||||||
|
bool new_bit;
|
||||||
|
if (select_val ^ select_inv) {
|
||||||
|
// Use alt_data.
|
||||||
|
if (alt_data.wire)
|
||||||
|
new_bit = (i & 1 << idx_alt) != 0;
|
||||||
|
else
|
||||||
|
new_bit = alt_data.data == State::S1;
|
||||||
|
} else {
|
||||||
|
// Use original LUT.
|
||||||
|
int lut_idx = i >> idx_data & ((1 << GetSize(data.second)) - 1);
|
||||||
|
new_bit = data.first.bits[lut_idx] == State::S1;
|
||||||
|
}
|
||||||
|
result.first.bits[i] = new_bit ? State::S1 : State::S0;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct MchpDffOptPass : public Pass {
|
||||||
|
MchpDffOptPass() : Pass("mchp_dffopt", "MCHP: optimize FF control signal usage") { }
|
||||||
|
void help() override
|
||||||
|
{
|
||||||
|
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
|
||||||
|
log("\n");
|
||||||
|
log(" mchp_dffopt [options] [selection]\n");
|
||||||
|
log("\n");
|
||||||
|
log("Converts hardware clock enable and set/reset signals on FFs to emulation\n");
|
||||||
|
log("using LUTs, if doing so would improve area. Operates on post-techmap LUT, DFF\n");
|
||||||
|
log("cells. \n");
|
||||||
|
log("\n");
|
||||||
|
}
|
||||||
|
void execute(std::vector<std::string> args, RTLIL::Design *design) override
|
||||||
|
{
|
||||||
|
log_header(design, "Executing MCHP_DFFOPT pass (optimize FF control signal usage).\n");
|
||||||
|
|
||||||
|
size_t argidx;
|
||||||
|
int max_lut_size = 4;
|
||||||
|
|
||||||
|
extra_args(args, argidx, design);
|
||||||
|
|
||||||
|
for (auto module : design->selected_modules())
|
||||||
|
{
|
||||||
|
log("Optimizing FFs in %s.\n", log_id(module));
|
||||||
|
|
||||||
|
SigMap sigmap(module);
|
||||||
|
dict<SigBit, pair<LutData, Cell *>> bit_to_lut;
|
||||||
|
dict<SigBit, int> bit_uses;
|
||||||
|
|
||||||
|
// Gather LUTs.
|
||||||
|
for (auto cell : module->selected_cells())
|
||||||
|
{
|
||||||
|
for (auto port : cell->connections())
|
||||||
|
for (auto bit : port.second)
|
||||||
|
bit_uses[sigmap(bit)]++;
|
||||||
|
if (cell->get_bool_attribute(ID::keep))
|
||||||
|
continue;
|
||||||
|
if (cell->type == ID(INV)) {
|
||||||
|
SigBit sigout = sigmap(cell->getPort(ID::Y));
|
||||||
|
SigBit sigin = sigmap(cell->getPort(ID::A));
|
||||||
|
bit_to_lut[sigout] = make_pair(LutData(Const(1, 2), {sigin}), cell); // INIT = 01
|
||||||
|
} else if (cell->type.in(ID(CFG1), ID(CFG2), ID(CFG3), ID(CFG4))) {
|
||||||
|
SigBit sigout = sigmap(cell->getPort(ID::Y));
|
||||||
|
const Const &init = cell->getParam(ID::INIT);
|
||||||
|
std::vector<SigBit> sigin;
|
||||||
|
sigin.push_back(sigmap(cell->getPort(ID(A))));
|
||||||
|
if (cell->type == ID(CFG1))
|
||||||
|
goto lut_sigin_done;
|
||||||
|
sigin.push_back(sigmap(cell->getPort(ID(B))));
|
||||||
|
if (cell->type == ID(CFG2))
|
||||||
|
goto lut_sigin_done;
|
||||||
|
sigin.push_back(sigmap(cell->getPort(ID(C))));
|
||||||
|
if (cell->type == ID(CFG3))
|
||||||
|
goto lut_sigin_done;
|
||||||
|
sigin.push_back(sigmap(cell->getPort(ID(D))));
|
||||||
|
|
||||||
|
lut_sigin_done:
|
||||||
|
bit_to_lut[sigout] = make_pair(LutData(init, sigin), cell);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (auto wire : module->wires())
|
||||||
|
if (wire->port_output || wire->port_input)
|
||||||
|
for (int i = 0; i < GetSize(wire); i++)
|
||||||
|
bit_uses[sigmap(SigBit(wire, i))]++;
|
||||||
|
|
||||||
|
// Iterate through FFs.
|
||||||
|
for (auto cell : module->selected_cells())
|
||||||
|
{
|
||||||
|
|
||||||
|
if (!cell->type.in(ID(SLE))) // not a SLE
|
||||||
|
continue;
|
||||||
|
if (cell->getPort(ID(LAT)).is_fully_ones()) // skip latch
|
||||||
|
continue;
|
||||||
|
if (cell->get_bool_attribute(ID::keep)) // keep attribute
|
||||||
|
continue;
|
||||||
|
if (!cell->getPort(ID(ALn)).is_fully_ones()) // async FF
|
||||||
|
continue;
|
||||||
|
|
||||||
|
|
||||||
|
const bool hasSyncLoad = cell->getPort(ID(SLn)).is_wire();
|
||||||
|
const bool has_s = hasSyncLoad && cell->getPort(ID(SD)).is_fully_ones();
|
||||||
|
const bool has_r = hasSyncLoad && cell->getPort(ID(SD)).is_fully_zero();
|
||||||
|
|
||||||
|
// SLE cannot have both synchronous set and reset implemented at the same time
|
||||||
|
log_assert(!(has_s && has_r));
|
||||||
|
|
||||||
|
// Don't bother if D has more than one use.
|
||||||
|
SigBit sig_D = sigmap(cell->getPort(ID::D));
|
||||||
|
if (bit_uses[sig_D] > 2)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Find the D LUT.
|
||||||
|
auto it_D = bit_to_lut.find(sig_D);
|
||||||
|
if (it_D == bit_to_lut.end())
|
||||||
|
continue;
|
||||||
|
LutData lut_d = it_D->second.first;
|
||||||
|
Cell *cell_d = it_D->second.second;
|
||||||
|
|
||||||
|
|
||||||
|
LutData lut_d_post_ce;
|
||||||
|
LutData lut_d_post_s;
|
||||||
|
LutData lut_d_post_r;
|
||||||
|
bool worthy_post_ce = false;
|
||||||
|
bool worthy_post_s = false;
|
||||||
|
bool worthy_post_r = false;
|
||||||
|
|
||||||
|
// First, unmap CE.
|
||||||
|
SigBit sig_Q = sigmap(cell->getPort(ID::Q));
|
||||||
|
SigBit sig_CE = sigmap(cell->getPort(ID(EN)));
|
||||||
|
LutData lut_ce = LutData(Const(2, 2), {sig_CE}); // INIT = 10
|
||||||
|
auto it_CE = bit_to_lut.find(sig_CE);
|
||||||
|
if (it_CE != bit_to_lut.end())
|
||||||
|
lut_ce = it_CE->second.first;
|
||||||
|
if (sig_CE.wire) {
|
||||||
|
// Merge CE LUT and D LUT into one. If it cannot be done, nothing to do about this FF.
|
||||||
|
if (!merge_lut(lut_d_post_ce, lut_d, lut_ce, true, sig_Q, max_lut_size))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// If this gets rid of a CE LUT, it's worth it. If not, it still may be worth it, if we can remove set/reset as well.
|
||||||
|
if (it_CE != bit_to_lut.end())
|
||||||
|
worthy_post_ce = true;
|
||||||
|
} else if (sig_CE.data != State::S1) {
|
||||||
|
// Strange. Should not happen in a reasonable flow, so bail.
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
lut_d_post_ce = lut_d;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Second, unmap S, if any.
|
||||||
|
lut_d_post_s = lut_d_post_ce;
|
||||||
|
if (has_s) {
|
||||||
|
SigBit sig_S = sigmap(cell->getPort(ID(SLn)));
|
||||||
|
LutData lut_s = LutData(Const(2, 2), {sig_S}); // INIT = 10
|
||||||
|
bool inv_s = true; // active low
|
||||||
|
auto it_S = bit_to_lut.find(sig_S);
|
||||||
|
if (it_S != bit_to_lut.end())
|
||||||
|
lut_s = it_S->second.first;
|
||||||
|
if (sig_S.wire) {
|
||||||
|
// Merge S LUT and D LUT into one. If it cannot be done, try to at least merge CE.
|
||||||
|
if (!merge_lut(lut_d_post_s, lut_d_post_ce, lut_s, inv_s, SigBit(State::S1), max_lut_size))
|
||||||
|
goto unmap;
|
||||||
|
// If this gets rid of an S LUT, it's worth it.
|
||||||
|
if (it_S != bit_to_lut.end())
|
||||||
|
worthy_post_s = true;
|
||||||
|
} else if (sig_S.data != (inv_s ? State::S1 : State::S0)) {
|
||||||
|
// Strange. Should not happen in a reasonable flow, so bail.
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Third, unmap R, if any.
|
||||||
|
lut_d_post_r = lut_d_post_s;
|
||||||
|
if (has_r) {
|
||||||
|
SigBit sig_R = sigmap(cell->getPort(ID(SLn)));
|
||||||
|
LutData lut_r = LutData(Const(2, 2), {sig_R}); // INIT = 10
|
||||||
|
bool inv_r = true; // active low
|
||||||
|
auto it_R = bit_to_lut.find(sig_R);
|
||||||
|
if (it_R != bit_to_lut.end())
|
||||||
|
lut_r = it_R->second.first;
|
||||||
|
if (sig_R.wire) {
|
||||||
|
// Merge R LUT and D LUT into one. If it cannot be done, try to at least merge CE/S.
|
||||||
|
if (!merge_lut(lut_d_post_r, lut_d_post_s, lut_r, inv_r, SigBit(State::S0), max_lut_size))
|
||||||
|
goto unmap;
|
||||||
|
// If this gets rid of an S LUT, it's worth it.
|
||||||
|
if (it_R != bit_to_lut.end())
|
||||||
|
worthy_post_r = true;
|
||||||
|
} else if (sig_R.data != (inv_r ? State::S1 : State::S0)) {
|
||||||
|
// Strange. Should not happen in a reasonable flow, so bail.
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unmap:
|
||||||
|
|
||||||
|
// SLE cannot have both synchronous set and reset implemented at the same time
|
||||||
|
log_assert(!(worthy_post_r && worthy_post_s));
|
||||||
|
|
||||||
|
LutData final_lut;
|
||||||
|
if (worthy_post_r) {
|
||||||
|
final_lut = lut_d_post_r;
|
||||||
|
} else if (worthy_post_s) {
|
||||||
|
final_lut = lut_d_post_s;
|
||||||
|
} else if (worthy_post_ce) {
|
||||||
|
final_lut = lut_d_post_ce;
|
||||||
|
} else {
|
||||||
|
// Nothing to do here.
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string ports;
|
||||||
|
if (worthy_post_r) ports += " + R";
|
||||||
|
if (worthy_post_s) ports += " + S";
|
||||||
|
if (worthy_post_ce) ports += " + CE";
|
||||||
|
log(" Merging D%s LUTs for %s/%s (%d -> %d)\n", ports.c_str(), log_id(cell), log_id(sig_Q.wire), GetSize(lut_d.second), GetSize(final_lut.second));
|
||||||
|
|
||||||
|
// Okay, we're doing it. Unmap ports.
|
||||||
|
if ((has_s && worthy_post_s) || worthy_post_r) {
|
||||||
|
cell->setPort(ID(SLn), Const(1, 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
// if we made it this far, clk enable is always merged into D
|
||||||
|
cell->setPort(ID(EN), Const(1, 1));
|
||||||
|
|
||||||
|
// Create the new LUT.
|
||||||
|
Cell *lut_cell = nullptr;
|
||||||
|
switch (GetSize(final_lut.second)) {
|
||||||
|
case 1:
|
||||||
|
lut_cell = module->addCell(NEW_ID, ID(CFG1));
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
lut_cell = module->addCell(NEW_ID, ID(CFG2));
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
lut_cell = module->addCell(NEW_ID, ID(CFG3));
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
lut_cell = module->addCell(NEW_ID, ID(CFG4));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
log_assert(!"unknown lut size");
|
||||||
|
}
|
||||||
|
lut_cell->attributes = cell_d->attributes;
|
||||||
|
Wire *lut_out = module->addWire(NEW_ID);
|
||||||
|
lut_cell->setParam(ID::INIT, final_lut.first);
|
||||||
|
cell->setPort(ID::D, lut_out);
|
||||||
|
lut_cell->setPort(ID::Y, lut_out);
|
||||||
|
lut_cell->setPort(ID(A), final_lut.second[0]);
|
||||||
|
if (GetSize(final_lut.second) >= 2)
|
||||||
|
lut_cell->setPort(ID(B), final_lut.second[1]);
|
||||||
|
if (GetSize(final_lut.second) >= 3)
|
||||||
|
lut_cell->setPort(ID(C), final_lut.second[2]);
|
||||||
|
if (GetSize(final_lut.second) >= 4)
|
||||||
|
lut_cell->setPort(ID(D), final_lut.second[3]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} MchpDffOptPass;
|
||||||
|
|
||||||
|
PRIVATE_NAMESPACE_END
|
||||||
|
|
|
@ -0,0 +1,95 @@
|
||||||
|
/*
|
||||||
|
ISC License
|
||||||
|
|
||||||
|
Copyright (C) 2024 Microchip Technology Inc. and its subsidiaries
|
||||||
|
|
||||||
|
Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
purpose with or without fee is hereby granted, provided that the above
|
||||||
|
copyright notice and this permission notice appear in all copies.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
module \$__MUL18X18 (input [17:0] A, input [17:0] B, output [35:0] Y);
|
||||||
|
parameter A_SIGNED = 0;
|
||||||
|
parameter B_SIGNED = 0;
|
||||||
|
parameter A_WIDTH = 0;
|
||||||
|
parameter B_WIDTH = 0;
|
||||||
|
parameter Y_WIDTH = 0;
|
||||||
|
|
||||||
|
wire [47:0] P_48;
|
||||||
|
// For pin descriptions, see Section 9 of PolarFire FPGA Macro Library Guide:
|
||||||
|
// https://coredocs.s3.amazonaws.com/Libero/2021_2/Tool/pf_mlg.pdf
|
||||||
|
MACC_PA _TECHMAP_REPLACE_ (
|
||||||
|
.DOTP(1'b0),
|
||||||
|
.SIMD(1'b0),
|
||||||
|
.OVFL_CARRYOUT_SEL(1'b0),
|
||||||
|
|
||||||
|
.AL_N(1'b1),
|
||||||
|
.A(A),
|
||||||
|
.A_BYPASS(1'b1),
|
||||||
|
.A_SRST_N(1'b1),
|
||||||
|
.A_EN(1'b1),
|
||||||
|
|
||||||
|
.B(B),
|
||||||
|
.B_BYPASS(1'b1),
|
||||||
|
.B_SRST_N(1'b1),
|
||||||
|
.B_EN(1'b1),
|
||||||
|
|
||||||
|
.D(18'b0),
|
||||||
|
.D_BYPASS(1'b1),
|
||||||
|
.D_ARST_N(1'b1),
|
||||||
|
.D_SRST_N(1'b1),
|
||||||
|
.D_EN(1'b1),
|
||||||
|
|
||||||
|
.CARRYIN(1'b0),
|
||||||
|
.C(48'b0),
|
||||||
|
.C_BYPASS(1'b1),
|
||||||
|
.C_ARST_N(1'b1),
|
||||||
|
.C_SRST_N(1'b1),
|
||||||
|
.C_EN(1'b1),
|
||||||
|
|
||||||
|
|
||||||
|
.P(P_48),
|
||||||
|
|
||||||
|
.P_BYPASS(1'b1),
|
||||||
|
.P_SRST_N(1'b1),
|
||||||
|
.P_EN(1'b1),
|
||||||
|
|
||||||
|
.PASUB(1'b0),
|
||||||
|
.PASUB_BYPASS(1'b1),
|
||||||
|
.PASUB_AD_N(1'b0),
|
||||||
|
.PASUB_SL_N(1'b1),
|
||||||
|
.PASUB_SD_N(1'b0),
|
||||||
|
.PASUB_EN(1'b1),
|
||||||
|
|
||||||
|
.CDIN_FDBK_SEL(2'b00),
|
||||||
|
.CDIN_FDBK_SEL_BYPASS(1'b1),
|
||||||
|
.CDIN_FDBK_SEL_AD_N(2'b00),
|
||||||
|
.CDIN_FDBK_SEL_SL_N(1'b1),
|
||||||
|
.CDIN_FDBK_SEL_SD_N(2'b00),
|
||||||
|
.CDIN_FDBK_SEL_EN(1'b1),
|
||||||
|
|
||||||
|
.ARSHFT17(1'b0),
|
||||||
|
.ARSHFT17_BYPASS(1'b1),
|
||||||
|
.ARSHFT17_AD_N(1'b0),
|
||||||
|
.ARSHFT17_SL_N(1'b1),
|
||||||
|
.ARSHFT17_SD_N(1'b0),
|
||||||
|
.ARSHFT17_EN(1'b1),
|
||||||
|
|
||||||
|
.SUB(1'b0),
|
||||||
|
.SUB_BYPASS(1'b1),
|
||||||
|
.SUB_AD_N(1'b0),
|
||||||
|
.SUB_SL_N(1'b1),
|
||||||
|
.SUB_SD_N(1'b0),
|
||||||
|
.SUB_EN(1'b1)
|
||||||
|
|
||||||
|
);
|
||||||
|
assign Y = P_48;
|
||||||
|
endmodule
|
|
@ -0,0 +1,543 @@
|
||||||
|
/*
|
||||||
|
ISC License
|
||||||
|
|
||||||
|
Copyright (C) 2024 Microchip Technology Inc. and its subsidiaries
|
||||||
|
|
||||||
|
Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
purpose with or without fee is hereby granted, provided that the above
|
||||||
|
copyright notice and this permission notice appear in all copies.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "kernel/register.h"
|
||||||
|
#include "kernel/celltypes.h"
|
||||||
|
#include "kernel/rtlil.h"
|
||||||
|
#include "kernel/log.h"
|
||||||
|
|
||||||
|
USING_YOSYS_NAMESPACE
|
||||||
|
PRIVATE_NAMESPACE_BEGIN
|
||||||
|
|
||||||
|
struct SynthMchpPass : public ScriptPass
|
||||||
|
{
|
||||||
|
SynthMchpPass() : ScriptPass("synth_mchp", "synthesis for Microchip FPGAs") { }
|
||||||
|
|
||||||
|
void help() override
|
||||||
|
{
|
||||||
|
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
|
||||||
|
log("\n");
|
||||||
|
log(" synth_mchp [options]\n");
|
||||||
|
log("\n");
|
||||||
|
log("This command runs synthesis for Microchip FPGAs. Operating on\n");
|
||||||
|
log("partly selected designs is not supported (you must submit a fully-selected \n");
|
||||||
|
log("design). This command creates netlists that are compatible with Microchip \n");
|
||||||
|
log("PolarFire devices.\n");
|
||||||
|
log("\n");
|
||||||
|
log(" -top <module>\n");
|
||||||
|
log(" use the specified module as the top module\n");
|
||||||
|
log("\n");
|
||||||
|
log(" -family <family>\n");
|
||||||
|
log(" Run synthesis for the specified Microchip architecture. \n");
|
||||||
|
log(" Generate the synthesis netlist for the specified family.\n");
|
||||||
|
log(" supported values:\n");
|
||||||
|
log(" - pf: PolarFire\n");
|
||||||
|
log("\n");
|
||||||
|
log(" -edif <file>\n");
|
||||||
|
log(" Write the design to the specified edif file. Writing of an output file\n");
|
||||||
|
log(" is omitted if this parameter is not specified.\n");
|
||||||
|
log("\n");
|
||||||
|
log(" -blif <file>\n");
|
||||||
|
log(" Write the design to the specified BLIF file. Writing of an output file\n");
|
||||||
|
log(" is omitted if this parameter is not specified.\n");
|
||||||
|
log("\n");
|
||||||
|
log(" -nobram\n");
|
||||||
|
log(" Do not use block RAM cells in output netlist\n");
|
||||||
|
log("\n");
|
||||||
|
log(" -nocarry\n");
|
||||||
|
log(" Do not use ARI1 cells in output netlist\n");
|
||||||
|
log("\n");
|
||||||
|
log(" -nodsp\n");
|
||||||
|
log(" Do not use MATH blocks to implement multipliers and associated logic\n");
|
||||||
|
log("\n");
|
||||||
|
log(" -noiopad\n");
|
||||||
|
log(" Disable I/O buffer insertion (useful for hierarchical or \n");
|
||||||
|
log(" out-of-context flows)\n");
|
||||||
|
log("\n");
|
||||||
|
log(" -noclkbuf\n");
|
||||||
|
log(" Disable automatic clock buffer insertion\n");
|
||||||
|
log("\n");
|
||||||
|
log(" -run <from_label>:<to_label>\n");
|
||||||
|
log(" Only run the commands between the labels (see below). an empty\n");
|
||||||
|
log(" 'from_label' is synonymous to 'begin', and empty 'to_label' is\n");
|
||||||
|
log(" synonymous to the end of the command list.\n");
|
||||||
|
log("\n");
|
||||||
|
log(" -flatten\n");
|
||||||
|
log(" Flatten design before synthesis.\n");
|
||||||
|
log("\n");
|
||||||
|
log(" -flatten_before_abc\n");
|
||||||
|
log(" Flatten design before abc tech mapping.\n");
|
||||||
|
log("\n");
|
||||||
|
log(" -dff\n");
|
||||||
|
log(" Run 'abc'/'abc9' with -dff option\n");
|
||||||
|
log("\n");
|
||||||
|
log(" -retime\n");
|
||||||
|
log(" Run 'abc' with '-D 1' option to enable flip-flop retiming.\n");
|
||||||
|
log(" implies -dff.\n");
|
||||||
|
log("\n");
|
||||||
|
log(" -abc9\n");
|
||||||
|
log(" Use new ABC9 flow (EXPERIMENTAL)\n");
|
||||||
|
log("\n");
|
||||||
|
log("\n");
|
||||||
|
log("The following commands are executed by this synthesis command:\n");
|
||||||
|
help_script();
|
||||||
|
log("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string top_opt, edif_file, blif_file, family;
|
||||||
|
bool flatten, retime, noiopad, noclkbuf, nobram, nocarry, nowidelut, nodsp;
|
||||||
|
bool abc9, dff;
|
||||||
|
bool flatten_before_abc;
|
||||||
|
int lut_size;
|
||||||
|
|
||||||
|
// debug dump switches
|
||||||
|
bool debug_memory, debug_carry;
|
||||||
|
|
||||||
|
void clear_flags() override
|
||||||
|
{
|
||||||
|
top_opt = "-auto-top";
|
||||||
|
edif_file.clear();
|
||||||
|
blif_file.clear();
|
||||||
|
family = "pf";
|
||||||
|
flatten = false;
|
||||||
|
retime = false;
|
||||||
|
noiopad = false;
|
||||||
|
noclkbuf = false;
|
||||||
|
nocarry = false;
|
||||||
|
nobram = false;
|
||||||
|
nowidelut = false;
|
||||||
|
nodsp = false;
|
||||||
|
abc9 = false;
|
||||||
|
dff = false;
|
||||||
|
flatten_before_abc = false;
|
||||||
|
lut_size = 4;
|
||||||
|
|
||||||
|
debug_memory = false;
|
||||||
|
debug_carry = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void execute(std::vector<std::string> args, RTLIL::Design *design) override
|
||||||
|
{
|
||||||
|
std::string run_from, run_to;
|
||||||
|
clear_flags();
|
||||||
|
|
||||||
|
size_t argidx;
|
||||||
|
for (argidx = 1; argidx < args.size(); argidx++)
|
||||||
|
{
|
||||||
|
if (args[argidx] == "-top" && argidx+1 < args.size()) {
|
||||||
|
top_opt = "-top " + args[++argidx];
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if ((args[argidx] == "-family" || args[argidx] == "-arch") && argidx+1 < args.size()) {
|
||||||
|
family = args[++argidx];
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (args[argidx] == "-edif" && argidx+1 < args.size()) {
|
||||||
|
edif_file = args[++argidx];
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (args[argidx] == "-blif" && argidx+1 < args.size()) {
|
||||||
|
blif_file = args[++argidx];
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (args[argidx] == "-run" && argidx+1 < args.size()) {
|
||||||
|
size_t pos = args[argidx+1].find(':');
|
||||||
|
if (pos == std::string::npos)
|
||||||
|
break;
|
||||||
|
run_from = args[++argidx].substr(0, pos);
|
||||||
|
run_to = args[argidx].substr(pos+1);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (args[argidx] == "-flatten") {
|
||||||
|
flatten = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (args[argidx] == "-flatten_before_abc") {
|
||||||
|
flatten_before_abc = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (args[argidx] == "-retime") {
|
||||||
|
dff = true;
|
||||||
|
retime = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (args[argidx] == "-nocarry") {
|
||||||
|
nocarry = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (args[argidx] == "-nowidelut") {
|
||||||
|
nowidelut = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (args[argidx] == "-iopad") {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (args[argidx] == "-noiopad") {
|
||||||
|
noiopad = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (args[argidx] == "-noclkbuf") {
|
||||||
|
noclkbuf = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (args[argidx] == "-nocarry") {
|
||||||
|
nocarry = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (args[argidx] == "-nobram") {
|
||||||
|
nobram = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (args[argidx] == "-abc9") {
|
||||||
|
abc9 = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (args[argidx] == "-nodsp") {
|
||||||
|
nodsp = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (args[argidx] == "-dff") {
|
||||||
|
dff = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (args[argidx] == "-debug_memory") {
|
||||||
|
debug_memory = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (args[argidx] == "-debug_carry") {
|
||||||
|
debug_carry = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
extra_args(args, argidx, design);
|
||||||
|
|
||||||
|
if (family == "pf") {
|
||||||
|
lut_size = 4;
|
||||||
|
} else {
|
||||||
|
log_cmd_error("Invalid Microchip -family setting: '%s'.\n", family.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!design->full_selection())
|
||||||
|
log_cmd_error("This command only operates on fully selected designs!\n");
|
||||||
|
|
||||||
|
if (abc9 && retime)
|
||||||
|
log_cmd_error("-retime option not currently compatible with -abc9!\n");
|
||||||
|
|
||||||
|
|
||||||
|
log_header(design, "Executing SYNTH_MCHP pass.\n");
|
||||||
|
log_push();
|
||||||
|
|
||||||
|
run_script(design, run_from, run_to);
|
||||||
|
|
||||||
|
log_pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
void script() override
|
||||||
|
{
|
||||||
|
std::string lut_size_s = std::to_string(lut_size);
|
||||||
|
if (help_mode)
|
||||||
|
lut_size_s = "[4]";
|
||||||
|
|
||||||
|
if (check_label("begin")) {
|
||||||
|
std::string read_args;
|
||||||
|
read_args += " -lib -specify +/mchp/cells_sim.v";
|
||||||
|
run("read_verilog" + read_args);
|
||||||
|
|
||||||
|
run(stringf("hierarchy -check %s", top_opt.c_str()));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (check_label("prepare")) {
|
||||||
|
run("proc");
|
||||||
|
if (flatten || help_mode)
|
||||||
|
run("flatten", "(with '-flatten')");
|
||||||
|
if (active_design)
|
||||||
|
active_design->scratchpad_unset("tribuf.added_something");
|
||||||
|
run("tribuf -logic");
|
||||||
|
if (noiopad && active_design && active_design->scratchpad_get_bool("tribuf.added_something"))
|
||||||
|
log_error("Tristate buffers are unsupported without the '-iopad' option.\n");
|
||||||
|
run("deminout");
|
||||||
|
run("opt_expr");
|
||||||
|
run("opt_clean");
|
||||||
|
run("check");
|
||||||
|
run("opt -nodffe -nosdff");
|
||||||
|
run("fsm");
|
||||||
|
run("opt");
|
||||||
|
|
||||||
|
run("wreduce");
|
||||||
|
run("peepopt");
|
||||||
|
run("opt_clean");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (check_label("map_dsp", "(skip if '-nodsp')")) {
|
||||||
|
if (!nodsp || help_mode) {
|
||||||
|
run("memory_dff"); // mchp_dsp will merge registers, reserve memory port registers first
|
||||||
|
if (help_mode)
|
||||||
|
run("techmap -map +/mul2dsp.v -map +/mchp/{family}_dsp_map.v {options}");
|
||||||
|
else if (family == "pf") // Microchip - map multipliers to DSP
|
||||||
|
run("techmap -map +/mul2dsp.v -map +/mchp/pf_dsp_map.v -D DSP_A_MAXWIDTH=18 -D DSP_B_MAXWIDTH=18 "
|
||||||
|
"-D DSP_A_MAXWIDTH_PARTIAL=18 " // Partial multipliers are intentionally
|
||||||
|
// limited to 18x18 in order to take
|
||||||
|
// advantage of the (PCOUT >> 17) -> PCIN
|
||||||
|
// dedicated cascade chain capability
|
||||||
|
"-D DSP_A_MINWIDTH=2 -D DSP_B_MINWIDTH=2 " // Blocks Nx1 multipliers
|
||||||
|
"-D DSP_Y_MINWIDTH=9 "
|
||||||
|
"-D DSP_SIGNEDONLY=1 -D DSP_NAME=$__MUL18X18");
|
||||||
|
|
||||||
|
run("select a:mul2dsp");
|
||||||
|
run("setattr -unset mul2dsp");
|
||||||
|
run("opt_expr -fine");
|
||||||
|
run("wreduce");
|
||||||
|
run("select -clear");
|
||||||
|
if (help_mode)
|
||||||
|
run("mchp_dsp -family <family>");
|
||||||
|
else if (family == "pf") // Microchip - absorb cells into DSP
|
||||||
|
run("mchp_dsp -family " + family);
|
||||||
|
|
||||||
|
run("chtype -set $mul t:$__soft_mul");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (check_label("coarse")) {
|
||||||
|
run("techmap -map +/cmp2lut.v -map +/cmp2lcu.v -D LUT_WIDTH=" + lut_size_s);
|
||||||
|
run("alumacc");
|
||||||
|
run("share");
|
||||||
|
run("opt");
|
||||||
|
run("memory -nomap");
|
||||||
|
run("opt_clean");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (check_label("map_memory")) {
|
||||||
|
std::string params = "";
|
||||||
|
std::string LSRAM_map = "+/mchp/LSRAM_map.v";
|
||||||
|
std::string uSRAM_map = "+/mchp/uSRAM_map.v";
|
||||||
|
if (debug_memory) run("write_verilog -noexpr memory_map_pre.vm");
|
||||||
|
if (help_mode) {
|
||||||
|
params = " [...]";
|
||||||
|
} else {
|
||||||
|
|
||||||
|
if (family == "pf") {
|
||||||
|
// cost of a single bit for memory lowered to soft logic
|
||||||
|
params += " -logic-cost-rom 0.015625";
|
||||||
|
|
||||||
|
params += " -lib +/mchp/LSRAM.txt";
|
||||||
|
params += " -lib +/mchp/uSRAM.txt";
|
||||||
|
LSRAM_map = "+/mchp/LSRAM_map.v";
|
||||||
|
uSRAM_map = "+/mchp/uSRAM_map.v";
|
||||||
|
}
|
||||||
|
if (nobram) params += " -no-auto-block";
|
||||||
|
}
|
||||||
|
|
||||||
|
// transform memories into intermediate cells
|
||||||
|
// Cost based transformation. The cost is assigned by us for each cell.
|
||||||
|
run("memory_libmap" + params);
|
||||||
|
if (debug_memory) run("write_verilog -noexpr memory_map_libmap.vm");
|
||||||
|
|
||||||
|
// map intermediate cells to actual RAM macros
|
||||||
|
// NOTE: order doesnt matter here
|
||||||
|
run("techmap -map " + LSRAM_map);
|
||||||
|
run("techmap -map " + uSRAM_map);
|
||||||
|
if (debug_memory) run("write_verilog -noexpr memory_map_final.vm");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (check_label("map_ffram")) {
|
||||||
|
run("opt -fast -full");
|
||||||
|
|
||||||
|
|
||||||
|
// blast unmapped RAM to flops or LUTs
|
||||||
|
run("memory_map");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (check_label("fine")) {
|
||||||
|
run("opt -full");
|
||||||
|
|
||||||
|
if (debug_carry) run("write_verilog -noexpr ARI1_cells.vm");
|
||||||
|
|
||||||
|
if (!nocarry) {
|
||||||
|
// converts $mux -> $_MUX_ to allow muxcover to work
|
||||||
|
run("simplemap t:$mux");
|
||||||
|
|
||||||
|
// converts $and/$or/$xor to gate representation for extract_reduce to work
|
||||||
|
run("simplemap t:$xor"); // only mapping reduce_xor
|
||||||
|
|
||||||
|
// mapping based on Yosys internal gates
|
||||||
|
if (debug_carry) run("write_verilog -noexpr ARI1_pre.vm");
|
||||||
|
|
||||||
|
// collapse $_AND_/$_OR_/$_XOR_ chains into reduction cells
|
||||||
|
run("extract_reduce");
|
||||||
|
|
||||||
|
if (debug_carry) run("write_verilog -noexpr ARI1_extract_reduce.vm");
|
||||||
|
|
||||||
|
// pack mux trees into $_MUX4_
|
||||||
|
run("muxcover -nodecode -mux4=220");
|
||||||
|
|
||||||
|
if (debug_carry) run("write_verilog -noexpr ARI1_muxcover.vm");
|
||||||
|
|
||||||
|
run("techmap -map +/mchp/arith_map.v");
|
||||||
|
if (debug_carry) run("write_verilog -noexpr ARI1_post.vm");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// convert all remaining cells to gates
|
||||||
|
run("techmap -map +/techmap.v");
|
||||||
|
|
||||||
|
run("opt -fast");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (check_label("map_cells")) {
|
||||||
|
// Needs to be done before logic optimization, so that inverters (inserted
|
||||||
|
// here because of negative-polarity output enable) are handled.
|
||||||
|
if (help_mode || !noiopad) {
|
||||||
|
run("iopadmap -bits -inpad INBUF Y:PAD -outpad OUTBUF D:PAD -toutpad TRIBUFF E:D:PAD -tinoutpad BIBUF E:Y:D:PAD", "(unless -noiobs)");
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string techmap_args = "-map +/techmap.v -map +/mchp/cells_map.v";
|
||||||
|
run("techmap " + techmap_args);
|
||||||
|
run("clean");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (check_label("map_ffs")) {
|
||||||
|
// dfflegalize : Converts FFs to types supported by the target
|
||||||
|
// this can convert less capable cells into more capable cells (e.g. dff -> dffe)
|
||||||
|
|
||||||
|
// Based on PolarFire® FPGA Macro Library Guide
|
||||||
|
// D-flop:
|
||||||
|
// active high enable
|
||||||
|
// active low clear or active low set
|
||||||
|
// Latch:
|
||||||
|
// active low clear or active low set
|
||||||
|
// SLE (can implement D-flop/Latch):
|
||||||
|
// active high EN
|
||||||
|
// active low async load (set/reset) with static load configuration via ADn (Q = ~ADn)
|
||||||
|
// active low sync load (set/reset) with static load configuration via SD
|
||||||
|
// static latch configuration bit
|
||||||
|
// init not supported
|
||||||
|
|
||||||
|
// Yosys internal cell description
|
||||||
|
// see: https://yosyshq.readthedocs.io/projects/yosys/en/latest/yosys_internals/formats/cell_library.html
|
||||||
|
// see: common/simcells.v
|
||||||
|
// $_DFF_[NP]_ (regular dff)
|
||||||
|
// $_DFFE_[NP][NP]_ (enable)
|
||||||
|
// $_DFF_[NP][NP][01]_ (async reset to 0/1)
|
||||||
|
// $_DFFE_[NP][NP][01][NP]_ (async reset to 0/1 + enable)
|
||||||
|
// $_ALDFF_[NP][NP]_ (async load)
|
||||||
|
// $_ALDFFE_[NP][NP][NP]_ (async load + enable)
|
||||||
|
// $_DFFSR_[NP][NP][NP]_ (async set & reset)
|
||||||
|
// $_DFFSRE_[NP][NP][NP][NP]_ (async set & reset + enable)
|
||||||
|
// $_SDFF_[NP][NP][01]_ (sync reset to 0/1)
|
||||||
|
// $_SDFFE_[NP][NP][01][NP]_ (sync reset to 0/1 + enable, reset prioritize over enable)
|
||||||
|
// $_SDFFCE_[NP][NP][01][NP]_ (sync reset to 0/1 + enable, enable prioritize over reset)
|
||||||
|
// $_SR_[NP][NP]_ (set/reset latch)
|
||||||
|
// $_DLATCH_[NP]_ (D-latch)
|
||||||
|
// $_DLATCH_[NP][NP][01]_ (D-latch + reset to 0/1)
|
||||||
|
// $_DLATCHSR_[NP][NP][NP]_ (D-latch + set + reset)
|
||||||
|
|
||||||
|
|
||||||
|
if (family == "pf") {
|
||||||
|
std::string params = "";
|
||||||
|
|
||||||
|
|
||||||
|
// D-flop with async reset and enable
|
||||||
|
// posedge CLK, active low reset to 1 or 0, active high EN
|
||||||
|
params += " -cell $_DFFE_PN?P_ 01";
|
||||||
|
|
||||||
|
// D-flop with sync reset and enable, enable takes priority over reset
|
||||||
|
// posedge CLK, active low reset to 1 or 0, active high EN
|
||||||
|
params += " -cell $_SDFFCE_PN?P_ 01";
|
||||||
|
|
||||||
|
// D-latch + reset to 0/1
|
||||||
|
// posedge CLK, active low reset to 1 or 0
|
||||||
|
params += " -cell $_DLATCH_PN?_ 01";
|
||||||
|
|
||||||
|
run("dfflegalize" + params, "(Converts FFs to supported types)");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (abc9 || help_mode) {
|
||||||
|
if (dff || help_mode)
|
||||||
|
run("zinit -all w:* t:$_SDFFCE_*", "('-dff' only)");
|
||||||
|
run("techmap -D NO_LUT -map +/mchp/cells_map.v", "('-abc9' only)");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (check_label("map_luts")) {
|
||||||
|
run("opt_expr -mux_undef -noclkinv");
|
||||||
|
if (flatten_before_abc)
|
||||||
|
run("flatten");
|
||||||
|
if (help_mode)
|
||||||
|
run("abc -luts 2:2,3,6:5[,10,20] [-dff] [-D 1]", "(option for '-nowidelut', '-dff', '-retime')");
|
||||||
|
else if (abc9) {
|
||||||
|
|
||||||
|
std::string abc9_opts;
|
||||||
|
// for the if command in abc to specify wire delay between adjects LUTs (default = 0)
|
||||||
|
// NOTE: should not have 0 wire delay between LUTs,
|
||||||
|
// otherwise abc might use LUT2+LUT3 instead of single LUT4
|
||||||
|
abc9_opts += " -W 300";
|
||||||
|
if (nowidelut)
|
||||||
|
abc9_opts += stringf(" -maxlut %d", lut_size);
|
||||||
|
if (dff)
|
||||||
|
abc9_opts += " -dff";
|
||||||
|
run("abc9" + abc9_opts);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
std::string abc_opts = " -lut " + lut_size_s;
|
||||||
|
if (dff)
|
||||||
|
abc_opts += " -dff";
|
||||||
|
if (retime)
|
||||||
|
abc_opts += " -D 1";
|
||||||
|
run("abc" + abc_opts);
|
||||||
|
}
|
||||||
|
run("clean");
|
||||||
|
|
||||||
|
if (help_mode || !abc9)
|
||||||
|
run("techmap -D NO_LUT -map +/mchp/cells_map.v", "(only if not '-abc9')");
|
||||||
|
std::string techmap_args = "-map +/mchp/cells_map.v -D FINAL_MAP";
|
||||||
|
techmap_args += " -D LUT_WIDTH=" + lut_size_s;
|
||||||
|
run("techmap " + techmap_args);
|
||||||
|
|
||||||
|
if (help_mode || lut_size == 4)
|
||||||
|
run("mchp_dffopt");
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
run("clkbufmap -buf CLKINT Y:A -inpad CLKBUF Y:PAD");
|
||||||
|
|
||||||
|
run("clean -purge");
|
||||||
|
|
||||||
|
|
||||||
|
if (check_label("check")) {
|
||||||
|
run("hierarchy -check");
|
||||||
|
run("stat");
|
||||||
|
run("check -noinit");
|
||||||
|
run("blackbox =A:whitebox");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (check_label("edif")) {
|
||||||
|
if (!edif_file.empty() || help_mode)
|
||||||
|
run(stringf("write_edif -pvector bra %s", edif_file.c_str()));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (check_label("blif")) {
|
||||||
|
if (!blif_file.empty() || help_mode)
|
||||||
|
run(stringf("write_blif %s", blif_file.c_str()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} SynthMchpPass;
|
||||||
|
|
||||||
|
PRIVATE_NAMESPACE_END
|
|
@ -0,0 +1,38 @@
|
||||||
|
/*
|
||||||
|
ISC License
|
||||||
|
|
||||||
|
Copyright (C) 2024 Microchip Technology Inc. and its subsidiaries
|
||||||
|
|
||||||
|
Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
purpose with or without fee is hereby granted, provided that the above
|
||||||
|
copyright notice and this permission notice appear in all copies.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
module Registers(
|
||||||
|
input clk,
|
||||||
|
input en,
|
||||||
|
input rst,
|
||||||
|
input D,
|
||||||
|
output Q
|
||||||
|
);
|
||||||
|
parameter LOAD_DATA = 1;
|
||||||
|
|
||||||
|
// active low async reset
|
||||||
|
always @(posedge clk, negedge rst) begin
|
||||||
|
if (rst == 0) begin
|
||||||
|
Q <= LOAD_DATA;
|
||||||
|
end else if(en) begin
|
||||||
|
Q <= D;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
endmodule
|
|
@ -0,0 +1,23 @@
|
||||||
|
# ISC License
|
||||||
|
#
|
||||||
|
# Copyright (C) 2024 Microchip Technology Inc. and its subsidiaries
|
||||||
|
#
|
||||||
|
# Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
# purpose with or without fee is hereby granted, provided that the above
|
||||||
|
# copyright notice and this permission notice appear in all copies.
|
||||||
|
#
|
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
|
||||||
|
# read verilog files
|
||||||
|
read_verilog Registers.v
|
||||||
|
|
||||||
|
synth_mchp -top Registers -abc9 -family pf -noiopad
|
||||||
|
|
||||||
|
# write final outputfile
|
||||||
|
write_verilog -noexpr Registers.vm
|
|
@ -0,0 +1,34 @@
|
||||||
|
/*
|
||||||
|
ISC License
|
||||||
|
|
||||||
|
Copyright (C) 2024 Microchip Technology Inc. and its subsidiaries
|
||||||
|
|
||||||
|
Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
purpose with or without fee is hereby granted, provided that the above
|
||||||
|
copyright notice and this permission notice appear in all copies.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
module carryout (cout,out,a, b,c);
|
||||||
|
parameter n = 6;
|
||||||
|
parameter k = 2;
|
||||||
|
output reg [k*(n+1)-1:0] out;
|
||||||
|
output reg cout;
|
||||||
|
input [n:0] a;
|
||||||
|
input [n:0] b;
|
||||||
|
input [n-1:0] c;
|
||||||
|
|
||||||
|
always @(a,b,c)
|
||||||
|
begin
|
||||||
|
{cout,out} = a * b + c;
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule
|
|
@ -0,0 +1,21 @@
|
||||||
|
# ISC License
|
||||||
|
#
|
||||||
|
# Copyright (C) 2024 Microchip Technology Inc. and its subsidiaries
|
||||||
|
#
|
||||||
|
# Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
# purpose with or without fee is hereby granted, provided that the above
|
||||||
|
# copyright notice and this permission notice appear in all copies.
|
||||||
|
#
|
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
|
||||||
|
read_verilog carryout.v
|
||||||
|
|
||||||
|
synth_mchp -top carryout -abc9 -family pf -noiopad
|
||||||
|
|
||||||
|
write_verilog -noexpr carryout.vm
|
|
@ -0,0 +1,38 @@
|
||||||
|
/*
|
||||||
|
ISC License
|
||||||
|
|
||||||
|
Copyright (C) 2024 Microchip Technology Inc. and its subsidiaries
|
||||||
|
|
||||||
|
Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
purpose with or without fee is hereby granted, provided that the above
|
||||||
|
copyright notice and this permission notice appear in all copies.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
module cascade(
|
||||||
|
input signed [5:0] in_A,
|
||||||
|
input signed [4:0] in_B,
|
||||||
|
input signed [4:0] in_D,
|
||||||
|
output signed [11:0] out_P,
|
||||||
|
|
||||||
|
input signed [4:0] casA,
|
||||||
|
input signed [4:0] casB
|
||||||
|
|
||||||
|
);
|
||||||
|
|
||||||
|
wire signed [9:0] cascade;
|
||||||
|
// first dsp
|
||||||
|
assign cascade = casA * casB;
|
||||||
|
|
||||||
|
// second dsp
|
||||||
|
assign out_P = in_A * (in_B + in_D) + cascade;
|
||||||
|
|
||||||
|
|
||||||
|
endmodule
|
|
@ -0,0 +1,21 @@
|
||||||
|
# ISC License
|
||||||
|
#
|
||||||
|
# Copyright (C) 2024 Microchip Technology Inc. and its subsidiaries
|
||||||
|
#
|
||||||
|
# Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
# purpose with or without fee is hereby granted, provided that the above
|
||||||
|
# copyright notice and this permission notice appear in all copies.
|
||||||
|
#
|
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
|
||||||
|
read_verilog cascade.v
|
||||||
|
|
||||||
|
synth_mchp -top cascade -abc9 -family pf -noiopad
|
||||||
|
|
||||||
|
write_verilog -noexpr cascade.vm
|
|
@ -0,0 +1,42 @@
|
||||||
|
/*
|
||||||
|
ISC License
|
||||||
|
|
||||||
|
Copyright (C) 2024 Microchip Technology Inc. and its subsidiaries
|
||||||
|
|
||||||
|
Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
purpose with or without fee is hereby granted, provided that the above
|
||||||
|
copyright notice and this permission notice appear in all copies.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
module dff_opt(
|
||||||
|
input clk,
|
||||||
|
input [1:0] D_comb,
|
||||||
|
input [1:0] EN_comb,
|
||||||
|
input [1:0] RST_comb,
|
||||||
|
output bar
|
||||||
|
);
|
||||||
|
|
||||||
|
// DFF with enable that can be merged into D
|
||||||
|
|
||||||
|
reg foo;
|
||||||
|
|
||||||
|
assign bar = foo;
|
||||||
|
|
||||||
|
// sync reset
|
||||||
|
always@(posedge clk) begin
|
||||||
|
if (&RST_comb) begin
|
||||||
|
foo <= 0;
|
||||||
|
end else begin
|
||||||
|
foo <= &D_comb;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule
|
|
@ -0,0 +1,21 @@
|
||||||
|
# ISC License
|
||||||
|
#
|
||||||
|
# Copyright (C) 2024 Microchip Technology Inc. and its subsidiaries
|
||||||
|
#
|
||||||
|
# Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
# purpose with or without fee is hereby granted, provided that the above
|
||||||
|
# copyright notice and this permission notice appear in all copies.
|
||||||
|
#
|
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
read_verilog dff_opt.v
|
||||||
|
|
||||||
|
synth_mchp -top dff_opt -abc9 -family pf -noiopad
|
||||||
|
|
||||||
|
# write final outputfile
|
||||||
|
write_verilog -noexpr dff_opt.vm
|
|
@ -0,0 +1,30 @@
|
||||||
|
/*
|
||||||
|
ISC License
|
||||||
|
|
||||||
|
Copyright (C) 2024 Microchip Technology Inc. and its subsidiaries
|
||||||
|
|
||||||
|
Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
purpose with or without fee is hereby granted, provided that the above
|
||||||
|
copyright notice and this permission notice appear in all copies.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
module full_dsp(
|
||||||
|
input signed[5:0] in_A,
|
||||||
|
input signed [4:0] in_B,
|
||||||
|
input signed [11:0] in_C,
|
||||||
|
input signed [4:0] in_D,
|
||||||
|
|
||||||
|
output signed [12:0] out_Y
|
||||||
|
);
|
||||||
|
|
||||||
|
assign out_Y = ((in_D + in_B)*in_A)+in_C;
|
||||||
|
|
||||||
|
|
||||||
|
endmodule
|
|
@ -0,0 +1,21 @@
|
||||||
|
# ISC License
|
||||||
|
#
|
||||||
|
# Copyright (C) 2024 Microchip Technology Inc. and its subsidiaries
|
||||||
|
#
|
||||||
|
# Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
# purpose with or without fee is hereby granted, provided that the above
|
||||||
|
# copyright notice and this permission notice appear in all copies.
|
||||||
|
#
|
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
|
||||||
|
read_verilog full_dsp.v
|
||||||
|
|
||||||
|
synth_mchp -top full_dsp -abc9 -family pf -noiopad
|
||||||
|
|
||||||
|
write_verilog -noexpr full_dsp.vm
|
|
@ -0,0 +1,25 @@
|
||||||
|
/*
|
||||||
|
ISC License
|
||||||
|
|
||||||
|
Copyright (C) 2024 Microchip Technology Inc. and its subsidiaries
|
||||||
|
|
||||||
|
Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
purpose with or without fee is hereby granted, provided that the above
|
||||||
|
copyright notice and this permission notice appear in all copies.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
module large_mult(
|
||||||
|
input signed [20:0] in1,
|
||||||
|
input signed [17:0] in2,
|
||||||
|
output signed [38:0] out1
|
||||||
|
);
|
||||||
|
assign out1 = in1 * in2;
|
||||||
|
endmodule
|
|
@ -0,0 +1,21 @@
|
||||||
|
# ISC License
|
||||||
|
#
|
||||||
|
# Copyright (C) 2024 Microchip Technology Inc. and its subsidiaries
|
||||||
|
#
|
||||||
|
# Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
# purpose with or without fee is hereby granted, provided that the above
|
||||||
|
# copyright notice and this permission notice appear in all copies.
|
||||||
|
#
|
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
|
||||||
|
read_verilog large_mult.v
|
||||||
|
|
||||||
|
synth_mchp -top large_mult -abc9 -family pf -noiopad
|
||||||
|
|
||||||
|
write_verilog -noexpr large_mult.vm
|
|
@ -0,0 +1,43 @@
|
||||||
|
/*
|
||||||
|
ISC License
|
||||||
|
|
||||||
|
Copyright (C) 2024 Microchip Technology Inc. and its subsidiaries
|
||||||
|
|
||||||
|
Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
purpose with or without fee is hereby granted, provided that the above
|
||||||
|
copyright notice and this permission notice appear in all copies.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
module mac(
|
||||||
|
input clk,
|
||||||
|
input signed [4:0] in_A,
|
||||||
|
input signed [4:0] in_B,
|
||||||
|
input signed [4:0] in_D,
|
||||||
|
output reg signed [11:0] out_P,
|
||||||
|
|
||||||
|
input srst_P,
|
||||||
|
|
||||||
|
input signed [4:0] casA,
|
||||||
|
input signed [4:0] casB
|
||||||
|
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
// sync reset P
|
||||||
|
always@(posedge clk) begin
|
||||||
|
if (~srst_P) begin
|
||||||
|
out_P <= 12'h000;
|
||||||
|
end else begin
|
||||||
|
out_P <= in_A * (in_B + in_D) + out_P;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule
|
|
@ -0,0 +1,24 @@
|
||||||
|
# ISC License
|
||||||
|
#
|
||||||
|
# Copyright (C) 2024 Microchip Technology Inc. and its subsidiaries
|
||||||
|
#
|
||||||
|
# Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
# purpose with or without fee is hereby granted, provided that the above
|
||||||
|
# copyright notice and this permission notice appear in all copies.
|
||||||
|
#
|
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
|
||||||
|
# read verilog files
|
||||||
|
read_verilog mac.v
|
||||||
|
|
||||||
|
# run the synth flow, specifies top module and additional parameters
|
||||||
|
synth_mchp -top mac -abc9 -family pf -noiopad
|
||||||
|
|
||||||
|
# write final outputfile
|
||||||
|
write_verilog -noexpr mac.vm
|
|
@ -0,0 +1,30 @@
|
||||||
|
/*
|
||||||
|
ISC License
|
||||||
|
|
||||||
|
Copyright (C) 2024 Microchip Technology Inc. and its subsidiaries
|
||||||
|
|
||||||
|
Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
purpose with or without fee is hereby granted, provided that the above
|
||||||
|
copyright notice and this permission notice appear in all copies.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
module postAdd_mult(
|
||||||
|
input signed[17:0] in_A,
|
||||||
|
input signed [17:0] in_B,
|
||||||
|
input signed [17:0] in_C,
|
||||||
|
|
||||||
|
output signed [35:0] out_Y
|
||||||
|
);
|
||||||
|
|
||||||
|
assign out_Y = (in_B*in_A)+in_C;
|
||||||
|
|
||||||
|
|
||||||
|
endmodule
|
|
@ -0,0 +1,21 @@
|
||||||
|
# ISC License
|
||||||
|
#
|
||||||
|
# Copyright (C) 2024 Microchip Technology Inc. and its subsidiaries
|
||||||
|
#
|
||||||
|
# Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
# purpose with or without fee is hereby granted, provided that the above
|
||||||
|
# copyright notice and this permission notice appear in all copies.
|
||||||
|
#
|
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
|
||||||
|
read_verilog postAdd_mult.v
|
||||||
|
|
||||||
|
synth_mchp -top postAdd_mult -abc9 -family pf -noiopad
|
||||||
|
|
||||||
|
write_verilog -noexpr postAdd_mult.vm
|
|
@ -0,0 +1,32 @@
|
||||||
|
/*
|
||||||
|
ISC License
|
||||||
|
|
||||||
|
Copyright (C) 2024 Microchip Technology Inc. and its subsidiaries
|
||||||
|
|
||||||
|
Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
purpose with or without fee is hereby granted, provided that the above
|
||||||
|
copyright notice and this permission notice appear in all copies.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
module post_adder(
|
||||||
|
input signed [5:0] in_A,
|
||||||
|
input signed [4:0] in_B,
|
||||||
|
input signed [4:0] in_D,
|
||||||
|
input signed [11:0] in_C,
|
||||||
|
|
||||||
|
output [12:0] out_Y
|
||||||
|
);
|
||||||
|
|
||||||
|
assign out_Y = (in_D + in_B) * in_A + in_C;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
endmodule
|
|
@ -0,0 +1,21 @@
|
||||||
|
# ISC License
|
||||||
|
#
|
||||||
|
# Copyright (C) 2024 Microchip Technology Inc. and its subsidiaries
|
||||||
|
#
|
||||||
|
# Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
# purpose with or without fee is hereby granted, provided that the above
|
||||||
|
# copyright notice and this permission notice appear in all copies.
|
||||||
|
#
|
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
|
||||||
|
read_verilog post_adder.v
|
||||||
|
|
||||||
|
synth_mchp -top post_adder -abc9 -family pf
|
||||||
|
|
||||||
|
write_verilog -noexpr post_adder.vm
|
|
@ -0,0 +1,30 @@
|
||||||
|
/*
|
||||||
|
ISC License
|
||||||
|
|
||||||
|
Copyright (C) 2024 Microchip Technology Inc. and its subsidiaries
|
||||||
|
|
||||||
|
Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
purpose with or without fee is hereby granted, provided that the above
|
||||||
|
copyright notice and this permission notice appear in all copies.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
module pre_adder_dsp(
|
||||||
|
input signed [5:0] in_A,
|
||||||
|
input signed [4:0] in_B,
|
||||||
|
input signed [4:0] in_D,
|
||||||
|
|
||||||
|
output [11:0] out_Y
|
||||||
|
);
|
||||||
|
|
||||||
|
assign out_Y = in_A * (in_B + in_D);
|
||||||
|
|
||||||
|
|
||||||
|
endmodule
|
|
@ -0,0 +1,21 @@
|
||||||
|
# ISC License
|
||||||
|
#
|
||||||
|
# Copyright (C) 2024 Microchip Technology Inc. and its subsidiaries
|
||||||
|
#
|
||||||
|
# Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
# purpose with or without fee is hereby granted, provided that the above
|
||||||
|
# copyright notice and this permission notice appear in all copies.
|
||||||
|
#
|
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
|
||||||
|
read_verilog pre_adder_dsp.v
|
||||||
|
|
||||||
|
synth_mchp -top pre_adder_dsp -abc9 -family pf -noiopad
|
||||||
|
|
||||||
|
write_verilog -noexpr pre_adder_dsp.vm
|
|
@ -0,0 +1,39 @@
|
||||||
|
/*
|
||||||
|
ISC License
|
||||||
|
|
||||||
|
Copyright (C) 2024 Microchip Technology Inc. and its subsidiaries
|
||||||
|
|
||||||
|
Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
purpose with or without fee is hereby granted, provided that the above
|
||||||
|
copyright notice and this permission notice appear in all copies.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
module ram_SDP(data,waddr,we,clk,q);
|
||||||
|
parameter d_width = 32;
|
||||||
|
parameter addr_width = 8;
|
||||||
|
parameter mem_depth = 256;
|
||||||
|
input [d_width-1:0] data;
|
||||||
|
input [addr_width-1:0] waddr;
|
||||||
|
input we, clk;
|
||||||
|
output reg [d_width-1:0] q;
|
||||||
|
|
||||||
|
reg [d_width-1:0] mem [mem_depth-1:0];
|
||||||
|
|
||||||
|
always @(posedge clk) begin
|
||||||
|
if (we) begin
|
||||||
|
mem[waddr] <= data;
|
||||||
|
end else begin
|
||||||
|
q <= mem[waddr];
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
# ISC License
|
||||||
|
#
|
||||||
|
# Copyright (C) 2024 Microchip Technology Inc. and its subsidiaries
|
||||||
|
#
|
||||||
|
# Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
# purpose with or without fee is hereby granted, provided that the above
|
||||||
|
# copyright notice and this permission notice appear in all copies.
|
||||||
|
#
|
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
|
||||||
|
read_verilog ram_SDP.v
|
||||||
|
|
||||||
|
synth_mchp -top ram_SDP -abc9 -family pf -noiopad
|
||||||
|
|
||||||
|
write_verilog -noexpr ram_SDP.vm
|
|
@ -0,0 +1,56 @@
|
||||||
|
/*
|
||||||
|
ISC License
|
||||||
|
|
||||||
|
Copyright (C) 2024 Microchip Technology Inc. and its subsidiaries
|
||||||
|
|
||||||
|
Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
purpose with or without fee is hereby granted, provided that the above
|
||||||
|
copyright notice and this permission notice appear in all copies.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
module ram_TDP (clka,clkb,wea,addra,dataina,qa,web,addrb,datainb,qb);
|
||||||
|
parameter addr_width = 10;
|
||||||
|
parameter data_width = 2;
|
||||||
|
input clka,clkb,wea,web;
|
||||||
|
input [data_width - 1 : 0] dataina,datainb;
|
||||||
|
input [addr_width - 1 : 0] addra,addrb;
|
||||||
|
output reg [data_width - 1 : 0] qa,qb;
|
||||||
|
reg [addr_width - 1 : 0] addra_reg, addrb_reg;
|
||||||
|
reg [data_width - 1 : 0] mem [(2**addr_width) - 1 : 0];
|
||||||
|
|
||||||
|
always @ (posedge clka)
|
||||||
|
begin
|
||||||
|
addra_reg <= addra;
|
||||||
|
if(wea)
|
||||||
|
mem[addra] <= dataina;
|
||||||
|
end
|
||||||
|
|
||||||
|
always @ (posedge clkb)
|
||||||
|
begin
|
||||||
|
addrb_reg <= addrb;
|
||||||
|
if(web)
|
||||||
|
mem[addrb] <= datainb;
|
||||||
|
end
|
||||||
|
|
||||||
|
always @ (posedge clka)
|
||||||
|
begin
|
||||||
|
if(~wea)
|
||||||
|
qa <= mem[addra];
|
||||||
|
else qa <= dataina;
|
||||||
|
end
|
||||||
|
|
||||||
|
always @ (posedge clkb)
|
||||||
|
begin
|
||||||
|
if(~web)
|
||||||
|
qb <= mem[addrb];
|
||||||
|
else qb <= datainb;
|
||||||
|
end
|
||||||
|
endmodule
|
|
@ -0,0 +1,21 @@
|
||||||
|
# ISC License
|
||||||
|
#
|
||||||
|
# Copyright (C) 2024 Microchip Technology Inc. and its subsidiaries
|
||||||
|
#
|
||||||
|
# Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
# purpose with or without fee is hereby granted, provided that the above
|
||||||
|
# copyright notice and this permission notice appear in all copies.
|
||||||
|
#
|
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
|
||||||
|
read_verilog ram_TDP.v
|
||||||
|
|
||||||
|
synth_mchp -top ram_TDP -abc9 -family pf -noiopad -debug_memory
|
||||||
|
|
||||||
|
write_verilog -noexpr ram_TDP.vm
|
|
@ -0,0 +1,29 @@
|
||||||
|
/*
|
||||||
|
ISC License
|
||||||
|
|
||||||
|
Copyright (C) 2024 Microchip Technology Inc. and its subsidiaries
|
||||||
|
|
||||||
|
Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
purpose with or without fee is hereby granted, provided that the above
|
||||||
|
copyright notice and this permission notice appear in all copies.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
module reduce(
|
||||||
|
input [7:0] data,
|
||||||
|
output Y
|
||||||
|
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
assign Y = ^data;
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
# ISC License
|
||||||
|
#
|
||||||
|
# Copyright (C) 2024 Microchip Technology Inc. and its subsidiaries
|
||||||
|
#
|
||||||
|
# Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
# purpose with or without fee is hereby granted, provided that the above
|
||||||
|
# copyright notice and this permission notice appear in all copies.
|
||||||
|
#
|
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
|
||||||
|
read_verilog reduce.v
|
||||||
|
|
||||||
|
synth_mchp -top reduce -abc9 -family pf -noiopad
|
||||||
|
|
||||||
|
write_verilog -noexpr reduce.vm
|
|
@ -0,0 +1,122 @@
|
||||||
|
/*
|
||||||
|
ISC License
|
||||||
|
|
||||||
|
Copyright (C) 2024 Microchip Technology Inc. and its subsidiaries
|
||||||
|
|
||||||
|
Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
purpose with or without fee is hereby granted, provided that the above
|
||||||
|
copyright notice and this permission notice appear in all copies.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
module reg_c(
|
||||||
|
input clk,
|
||||||
|
|
||||||
|
// active high
|
||||||
|
input en_A,
|
||||||
|
input en_B,
|
||||||
|
input en_D,
|
||||||
|
input en_P,
|
||||||
|
|
||||||
|
// active low
|
||||||
|
input srst_A,
|
||||||
|
input srst_B,
|
||||||
|
input srst_D,
|
||||||
|
input srst_P,
|
||||||
|
|
||||||
|
// active low
|
||||||
|
input arst_D,
|
||||||
|
|
||||||
|
input srst_C,
|
||||||
|
input arst_C,
|
||||||
|
|
||||||
|
|
||||||
|
input signed [5:0] in_A,
|
||||||
|
input signed [4:0] in_B,
|
||||||
|
input signed [4:0] in_C,
|
||||||
|
input signed [4:0] in_D,
|
||||||
|
|
||||||
|
|
||||||
|
output reg [11:0] out_P
|
||||||
|
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
// MACC_PA takes active low resets
|
||||||
|
wire srst_A_N;
|
||||||
|
wire srst_B_N;
|
||||||
|
wire srst_C_N;
|
||||||
|
wire srst_D_N;
|
||||||
|
wire srst_P_N;
|
||||||
|
assign srst_A_N = ~srst_A;
|
||||||
|
assign srst_B_N = ~srst_B;
|
||||||
|
assign srst_C_N = ~srst_C;
|
||||||
|
assign srst_D_N = ~srst_D;
|
||||||
|
assign srst_P_N = ~srst_P;
|
||||||
|
|
||||||
|
// input reg
|
||||||
|
reg signed [5:0] reg_A;
|
||||||
|
reg signed [4:0] reg_B;
|
||||||
|
reg signed [4:0] reg_C;
|
||||||
|
reg signed [4:0] reg_D;
|
||||||
|
|
||||||
|
// sync reset A
|
||||||
|
always@(posedge clk) begin
|
||||||
|
// if (~srst_A_N) begin
|
||||||
|
if (srst_A_N) begin
|
||||||
|
reg_A = 6'b000000;
|
||||||
|
end else begin
|
||||||
|
reg_A = in_A;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// sync reset B
|
||||||
|
always@(posedge clk) begin
|
||||||
|
if (srst_B_N) begin
|
||||||
|
reg_B = 5'b00000;
|
||||||
|
end else begin
|
||||||
|
reg_B = in_B;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// async reset D
|
||||||
|
always@(posedge clk, negedge arst_D) begin
|
||||||
|
if (~arst_D) begin
|
||||||
|
reg_D = 5'b00000;
|
||||||
|
end else begin
|
||||||
|
reg_D = in_D;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
// sync reset C
|
||||||
|
always@(posedge clk) begin
|
||||||
|
if (srst_C_N) begin
|
||||||
|
reg_C = 5'b00000;
|
||||||
|
end else begin
|
||||||
|
reg_C = in_C;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// sync reset P
|
||||||
|
always@(posedge clk) begin
|
||||||
|
if (srst_P_N) begin
|
||||||
|
out_P = 12'h000;
|
||||||
|
end else begin
|
||||||
|
out_P = reg_A * (reg_B + reg_D) + reg_C;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule
|
|
@ -0,0 +1,21 @@
|
||||||
|
# ISC License
|
||||||
|
#
|
||||||
|
# Copyright (C) 2024 Microchip Technology Inc. and its subsidiaries
|
||||||
|
#
|
||||||
|
# Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
# purpose with or without fee is hereby granted, provided that the above
|
||||||
|
# copyright notice and this permission notice appear in all copies.
|
||||||
|
#
|
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
|
||||||
|
read_verilog reg_c.v
|
||||||
|
|
||||||
|
synth_mchp -top reg_c -abc9 -family pf -noiopad
|
||||||
|
|
||||||
|
write_verilog -noexpr reg_c.vm
|
|
@ -0,0 +1,97 @@
|
||||||
|
/*
|
||||||
|
ISC License
|
||||||
|
|
||||||
|
Copyright (C) 2024 Microchip Technology Inc. and its subsidiaries
|
||||||
|
|
||||||
|
Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
purpose with or without fee is hereby granted, provided that the above
|
||||||
|
copyright notice and this permission notice appear in all copies.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
module reg_test(
|
||||||
|
input clk,
|
||||||
|
|
||||||
|
// active high
|
||||||
|
input en_A,
|
||||||
|
input en_B,
|
||||||
|
input en_D,
|
||||||
|
input en_P,
|
||||||
|
|
||||||
|
// active low
|
||||||
|
input srst_A,
|
||||||
|
input srst_B,
|
||||||
|
input srst_D,
|
||||||
|
input srst_P,
|
||||||
|
|
||||||
|
// active low
|
||||||
|
input arst_D,
|
||||||
|
|
||||||
|
input signed [5:0] in_A,
|
||||||
|
input signed [4:0] in_B,
|
||||||
|
input signed [4:0] in_D,
|
||||||
|
|
||||||
|
output reg [11:0] out_P
|
||||||
|
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
// MACC_PA takes active low resets
|
||||||
|
wire srst_A_N;
|
||||||
|
wire srst_B_N;
|
||||||
|
wire srst_D_N;
|
||||||
|
wire srst_P_N;
|
||||||
|
assign srst_A_N = ~srst_A;
|
||||||
|
assign srst_B_N = ~srst_B;
|
||||||
|
assign srst_D_N = ~srst_D;
|
||||||
|
assign srst_P_N = ~srst_P;
|
||||||
|
|
||||||
|
// input reg
|
||||||
|
reg signed [5:0] reg_A;
|
||||||
|
reg signed [4:0] reg_B;
|
||||||
|
reg signed [4:0] reg_D;
|
||||||
|
|
||||||
|
// sync reset A
|
||||||
|
always@(posedge clk) begin
|
||||||
|
if (srst_A_N) begin
|
||||||
|
reg_A = 6'b000000;
|
||||||
|
end else begin
|
||||||
|
reg_A = in_A;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
// sync reset B
|
||||||
|
always@(posedge clk) begin
|
||||||
|
if (srst_B_N) begin
|
||||||
|
reg_B = 5'b00000;
|
||||||
|
end else begin
|
||||||
|
reg_B = in_B;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
// async reset D
|
||||||
|
always@(posedge clk, negedge arst_D) begin
|
||||||
|
if (~arst_D) begin
|
||||||
|
reg_D = 5'b00000;
|
||||||
|
end else begin
|
||||||
|
reg_D = in_D;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
// sync reset P
|
||||||
|
always@(posedge clk) begin
|
||||||
|
if (srst_P_N) begin
|
||||||
|
out_P = 12'h000;
|
||||||
|
end else begin
|
||||||
|
out_P = reg_A * (reg_B + reg_D);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule
|
|
@ -0,0 +1,21 @@
|
||||||
|
# ISC License
|
||||||
|
#
|
||||||
|
# Copyright (C) 2024 Microchip Technology Inc. and its subsidiaries
|
||||||
|
#
|
||||||
|
# Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
# purpose with or without fee is hereby granted, provided that the above
|
||||||
|
# copyright notice and this permission notice appear in all copies.
|
||||||
|
#
|
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
|
||||||
|
read_verilog reg_test.v
|
||||||
|
|
||||||
|
synth_mchp -top reg_test -abc9 -family pf -noiopad
|
||||||
|
|
||||||
|
write_verilog -noexpr reg_test.vm
|
|
@ -0,0 +1,28 @@
|
||||||
|
/*
|
||||||
|
ISC License
|
||||||
|
|
||||||
|
Copyright (C) 2024 Microchip Technology Inc. and its subsidiaries
|
||||||
|
|
||||||
|
Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
purpose with or without fee is hereby granted, provided that the above
|
||||||
|
copyright notice and this permission notice appear in all copies.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
module signed_mult(
|
||||||
|
input signed [17:0] in_A,
|
||||||
|
input signed [17:0] in_B,
|
||||||
|
|
||||||
|
output signed [35:0] out_Y
|
||||||
|
);
|
||||||
|
|
||||||
|
assign out_Y = in_A * in_B;
|
||||||
|
|
||||||
|
endmodule
|
|
@ -0,0 +1,21 @@
|
||||||
|
# ISC License
|
||||||
|
#
|
||||||
|
# Copyright (C) 2024 Microchip Technology Inc. and its subsidiaries
|
||||||
|
#
|
||||||
|
# Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
# purpose with or without fee is hereby granted, provided that the above
|
||||||
|
# copyright notice and this permission notice appear in all copies.
|
||||||
|
#
|
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
|
||||||
|
read_verilog signed_mult.v
|
||||||
|
|
||||||
|
synth_mchp -top signed_mult -abc9 -family pf -noiopad
|
||||||
|
|
||||||
|
write_verilog -noexpr signed_mult.vm
|
|
@ -0,0 +1,37 @@
|
||||||
|
/*
|
||||||
|
ISC License
|
||||||
|
|
||||||
|
Copyright (C) 2024 Microchip Technology Inc. and its subsidiaries
|
||||||
|
|
||||||
|
Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
purpose with or without fee is hereby granted, provided that the above
|
||||||
|
copyright notice and this permission notice appear in all copies.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
module simple_ram (clk,wr,addr,din,dout);
|
||||||
|
input clk;
|
||||||
|
input [19:0] din;
|
||||||
|
input wr;
|
||||||
|
input [9:0] addr;
|
||||||
|
output [19:0] dout;
|
||||||
|
|
||||||
|
|
||||||
|
reg [9:0] addr_reg;
|
||||||
|
reg [19:0] mem [0:1023] ;
|
||||||
|
assign dout = mem[addr_reg];
|
||||||
|
|
||||||
|
always@(posedge clk) begin
|
||||||
|
addr_reg <= addr;
|
||||||
|
if(wr)
|
||||||
|
mem[addr]<= din;
|
||||||
|
end
|
||||||
|
endmodule
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
# ISC License
|
||||||
|
#
|
||||||
|
# Copyright (C) 2024 Microchip Technology Inc. and its subsidiaries
|
||||||
|
#
|
||||||
|
# Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
# purpose with or without fee is hereby granted, provided that the above
|
||||||
|
# copyright notice and this permission notice appear in all copies.
|
||||||
|
#
|
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
|
||||||
|
read_verilog simple_ram.v
|
||||||
|
|
||||||
|
synth_mchp -top simple_ram -abc9 -family pf -noiopad
|
||||||
|
|
||||||
|
write_verilog -noexpr simple_ram.vm
|
|
@ -0,0 +1,28 @@
|
||||||
|
/*
|
||||||
|
ISC License
|
||||||
|
|
||||||
|
Copyright (C) 2024 Microchip Technology Inc. and its subsidiaries
|
||||||
|
|
||||||
|
Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
purpose with or without fee is hereby granted, provided that the above
|
||||||
|
copyright notice and this permission notice appear in all copies.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
module unsigned_mult(
|
||||||
|
input [10:0] in_A,
|
||||||
|
input signed [10:0] in_B,
|
||||||
|
|
||||||
|
output [21:0] out_Y
|
||||||
|
);
|
||||||
|
|
||||||
|
assign out_Y = in_A * in_B;
|
||||||
|
|
||||||
|
endmodule
|
|
@ -0,0 +1,21 @@
|
||||||
|
# ISC License
|
||||||
|
#
|
||||||
|
# Copyright (C) 2024 Microchip Technology Inc. and its subsidiaries
|
||||||
|
#
|
||||||
|
# Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
# purpose with or without fee is hereby granted, provided that the above
|
||||||
|
# copyright notice and this permission notice appear in all copies.
|
||||||
|
#
|
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
|
||||||
|
read_verilog unsigned_mult.v
|
||||||
|
|
||||||
|
synth_mchp -top unsigned_mult -abc9 -family pf -noiopad
|
||||||
|
|
||||||
|
write_verilog -noexpr unsigned_mult.vm
|
|
@ -0,0 +1,38 @@
|
||||||
|
/*
|
||||||
|
ISC License
|
||||||
|
|
||||||
|
Copyright (C) 2024 Microchip Technology Inc. and its subsidiaries
|
||||||
|
|
||||||
|
Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
purpose with or without fee is hereby granted, provided that the above
|
||||||
|
copyright notice and this permission notice appear in all copies.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
module uram_ar(data,waddr,we,clk,q);
|
||||||
|
parameter d_width = 27;
|
||||||
|
parameter addr_width = 2;
|
||||||
|
parameter mem_depth = 4;
|
||||||
|
input [d_width-1:0] data;
|
||||||
|
input [addr_width-1:0] waddr;
|
||||||
|
input we, clk;
|
||||||
|
output [d_width-1:0] q;
|
||||||
|
|
||||||
|
reg [d_width-1:0] mem [mem_depth-1:0];
|
||||||
|
|
||||||
|
assign q = mem[waddr];
|
||||||
|
|
||||||
|
always @(posedge clk) begin
|
||||||
|
if (we)
|
||||||
|
mem[waddr] <= data;
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule
|
|
@ -0,0 +1,21 @@
|
||||||
|
# ISC License
|
||||||
|
#
|
||||||
|
# Copyright (C) 2024 Microchip Technology Inc. and its subsidiaries
|
||||||
|
#
|
||||||
|
# Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
# purpose with or without fee is hereby granted, provided that the above
|
||||||
|
# copyright notice and this permission notice appear in all copies.
|
||||||
|
#
|
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
|
||||||
|
read_verilog uram_ar.v
|
||||||
|
|
||||||
|
synth_mchp -top uram_ar -abc9 -family pf -noiopad
|
||||||
|
|
||||||
|
write_verilog -noexpr uram_ar.vm
|
|
@ -0,0 +1,32 @@
|
||||||
|
/*
|
||||||
|
ISC License
|
||||||
|
|
||||||
|
Copyright (C) 2024 Microchip Technology Inc. and its subsidiaries
|
||||||
|
|
||||||
|
Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
purpose with or without fee is hereby granted, provided that the above
|
||||||
|
copyright notice and this permission notice appear in all copies.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
module uram_sr(clk, wr, raddr, din, waddr, dout);
|
||||||
|
input clk;
|
||||||
|
input [11:0] din;
|
||||||
|
input wr;
|
||||||
|
input [5:0] waddr, raddr;
|
||||||
|
output [11:0] dout;
|
||||||
|
reg [5:0] raddr_reg;
|
||||||
|
reg [11:0] mem [0:63];
|
||||||
|
assign dout = mem[raddr_reg];
|
||||||
|
always@(posedge clk) begin
|
||||||
|
raddr_reg <= raddr; if(wr)
|
||||||
|
mem[waddr]<= din;
|
||||||
|
end
|
||||||
|
endmodule
|
|
@ -0,0 +1,21 @@
|
||||||
|
# ISC License
|
||||||
|
#
|
||||||
|
# Copyright (C) 2024 Microchip Technology Inc. and its subsidiaries
|
||||||
|
#
|
||||||
|
# Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
# purpose with or without fee is hereby granted, provided that the above
|
||||||
|
# copyright notice and this permission notice appear in all copies.
|
||||||
|
#
|
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
|
||||||
|
read_verilog uram_sr.v
|
||||||
|
|
||||||
|
synth_mchp -top uram_sr -abc9 -family pf -noiopad
|
||||||
|
|
||||||
|
write_verilog -noexpr uram_sr.vm
|
|
@ -0,0 +1,48 @@
|
||||||
|
/*
|
||||||
|
ISC License
|
||||||
|
|
||||||
|
Copyright (C) 2024 Microchip Technology Inc. and its subsidiaries
|
||||||
|
|
||||||
|
Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
purpose with or without fee is hereby granted, provided that the above
|
||||||
|
copyright notice and this permission notice appear in all copies.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
module widemux(
|
||||||
|
input [3:0] data,
|
||||||
|
input S0,
|
||||||
|
input S1,
|
||||||
|
output Y
|
||||||
|
|
||||||
|
);
|
||||||
|
|
||||||
|
wire A, B;
|
||||||
|
|
||||||
|
always @ (*) begin
|
||||||
|
if (S0)begin
|
||||||
|
A = data[1];
|
||||||
|
B = data[3];
|
||||||
|
end else begin
|
||||||
|
A = data[0];
|
||||||
|
B = data[2];
|
||||||
|
end
|
||||||
|
|
||||||
|
if (S1)begin
|
||||||
|
Y = A;
|
||||||
|
end else begin
|
||||||
|
Y = B;
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
# ISC License
|
||||||
|
#
|
||||||
|
# Copyright (C) 2024 Microchip Technology Inc. and its subsidiaries
|
||||||
|
#
|
||||||
|
# Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
# purpose with or without fee is hereby granted, provided that the above
|
||||||
|
# copyright notice and this permission notice appear in all copies.
|
||||||
|
#
|
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
|
||||||
|
read_verilog widemux.v
|
||||||
|
|
||||||
|
synth_mchp -top widemux -abc9 -family pf -noiopad
|
||||||
|
|
||||||
|
write_verilog -noexpr widemux.vm
|
|
@ -0,0 +1,69 @@
|
||||||
|
# ISC License
|
||||||
|
#
|
||||||
|
# Copyright (C) 2024 Microchip Technology Inc. and its subsidiaries
|
||||||
|
#
|
||||||
|
# Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
# purpose with or without fee is hereby granted, provided that the above
|
||||||
|
# copyright notice and this permission notice appear in all copies.
|
||||||
|
#
|
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
|
||||||
|
# asynchronous read
|
||||||
|
ram block $__uSRAM_AR_ {
|
||||||
|
|
||||||
|
#(LSRAM cost)/3
|
||||||
|
cost 43;
|
||||||
|
|
||||||
|
# INIT supported
|
||||||
|
init any;
|
||||||
|
|
||||||
|
abits 6;
|
||||||
|
widths 12 per_port;
|
||||||
|
|
||||||
|
# single write enable wire
|
||||||
|
port sw "W" {
|
||||||
|
clock posedge;
|
||||||
|
|
||||||
|
# collision not supported, but write takes precedence and read data is invalid while writing to
|
||||||
|
# the same address
|
||||||
|
wrtrans all new;
|
||||||
|
|
||||||
|
optional;
|
||||||
|
}
|
||||||
|
port ar "R" {
|
||||||
|
optional;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# synchronous read
|
||||||
|
# NOTE: synchronous read can be realized by the address pipeline register or data pipeline register.
|
||||||
|
# This assumes address is synchronized
|
||||||
|
ram block $__uSRAM_SR_ {
|
||||||
|
|
||||||
|
cost 42;
|
||||||
|
|
||||||
|
init any;
|
||||||
|
abits 6;
|
||||||
|
widths 12 per_port;
|
||||||
|
|
||||||
|
port sw "W" {
|
||||||
|
clock posedge;
|
||||||
|
|
||||||
|
# collision not supported
|
||||||
|
wrtrans all new;
|
||||||
|
|
||||||
|
optional;
|
||||||
|
}
|
||||||
|
port sr "R" {
|
||||||
|
clock posedge;
|
||||||
|
rden;
|
||||||
|
rdinit none;
|
||||||
|
optional;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,118 @@
|
||||||
|
/*
|
||||||
|
ISC License
|
||||||
|
|
||||||
|
Copyright (C) 2024 Microchip Technology Inc. and its subsidiaries
|
||||||
|
|
||||||
|
Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
purpose with or without fee is hereby granted, provided that the above
|
||||||
|
copyright notice and this permission notice appear in all copies.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// See document PolarFire Family Fabric User Guide
|
||||||
|
// section 4.2 for port list.
|
||||||
|
|
||||||
|
// Asynchronous read
|
||||||
|
module $__uSRAM_AR_ (...);
|
||||||
|
|
||||||
|
parameter INIT = 0;
|
||||||
|
parameter ADDR_BITS = 6;
|
||||||
|
|
||||||
|
parameter PORT_W_WIDTH = 12;
|
||||||
|
parameter PORT_R_WIDTH = 12;
|
||||||
|
parameter PORT_R_USED = 0;
|
||||||
|
parameter PORT_W_USED = 0;
|
||||||
|
|
||||||
|
input PORT_W_CLK;
|
||||||
|
input [ADDR_BITS-1:0] PORT_W_ADDR;
|
||||||
|
input [PORT_W_WIDTH-1:0] PORT_W_WR_DATA;
|
||||||
|
input PORT_W_WR_EN;
|
||||||
|
|
||||||
|
input [ADDR_BITS-1:0] PORT_R_ADDR;
|
||||||
|
output [PORT_R_WIDTH-1:0] PORT_R_RD_DATA;
|
||||||
|
|
||||||
|
RAM64x12 _TECHMAP_REPLACE_ (
|
||||||
|
.R_ADDR(PORT_R_ADDR),
|
||||||
|
.R_ADDR_BYPASS(1'b1),
|
||||||
|
.R_ADDR_EN(1'b0),
|
||||||
|
.R_ADDR_SL_N(1'b1),
|
||||||
|
.R_ADDR_SD(1'b0),
|
||||||
|
.R_ADDR_AL_N(1'b1),
|
||||||
|
.R_ADDR_AD_N(1'b0),
|
||||||
|
.BLK_EN(PORT_R_USED ? 1'b1 : 1'b0),
|
||||||
|
.R_DATA(PORT_R_RD_DATA),
|
||||||
|
.R_DATA_BYPASS(1'b1),
|
||||||
|
.R_DATA_EN(1'b0),
|
||||||
|
.R_DATA_SL_N(1'b1),
|
||||||
|
.R_DATA_SD(1'b0),
|
||||||
|
.R_DATA_AL_N(1'b1),
|
||||||
|
.R_DATA_AD_N(1'b0),
|
||||||
|
|
||||||
|
.W_CLK(PORT_W_CLK),
|
||||||
|
.W_ADDR(PORT_W_ADDR),
|
||||||
|
.W_DATA(PORT_W_WR_DATA),
|
||||||
|
.W_EN(PORT_W_WR_EN),
|
||||||
|
|
||||||
|
.BUSY_FB(1'b0)
|
||||||
|
);
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
// Synchronous read
|
||||||
|
module $__uSRAM_SR_ (...);
|
||||||
|
|
||||||
|
parameter INIT = 0;
|
||||||
|
parameter ADDR_BITS = 6;
|
||||||
|
|
||||||
|
parameter PORT_W_WIDTH = 12;
|
||||||
|
parameter PORT_R_WIDTH = 12;
|
||||||
|
parameter PORT_R_USED = 0;
|
||||||
|
parameter PORT_W_USED = 0;
|
||||||
|
|
||||||
|
input PORT_W_CLK;
|
||||||
|
input [ADDR_BITS-1:0] PORT_W_ADDR;
|
||||||
|
input [PORT_W_WIDTH-1:0] PORT_W_WR_DATA;
|
||||||
|
input PORT_W_WR_EN;
|
||||||
|
|
||||||
|
// Read port clock and enable signal
|
||||||
|
// that async read uSRAM doesn't have
|
||||||
|
input PORT_R_CLK;
|
||||||
|
input PORT_R_RD_EN;
|
||||||
|
input [ADDR_BITS-1:0] PORT_R_ADDR;
|
||||||
|
output [PORT_R_WIDTH-1:0] PORT_R_RD_DATA;
|
||||||
|
|
||||||
|
RAM64x12 _TECHMAP_REPLACE_ (
|
||||||
|
.R_CLK(PORT_R_CLK),
|
||||||
|
.R_ADDR(PORT_R_ADDR),
|
||||||
|
.R_ADDR_BYPASS(1'b0),
|
||||||
|
.R_ADDR_EN(PORT_R_RD_EN),
|
||||||
|
.R_ADDR_SL_N(1'b1),
|
||||||
|
.R_ADDR_SD(1'b0),
|
||||||
|
.R_ADDR_AL_N(1'b1),
|
||||||
|
.R_ADDR_AD_N(1'b0),
|
||||||
|
.BLK_EN(PORT_R_USED ? 1'b1 : 1'b0),
|
||||||
|
.R_DATA(PORT_R_RD_DATA),
|
||||||
|
.R_DATA_BYPASS(1'b1),
|
||||||
|
.R_DATA_EN(1'b0),
|
||||||
|
.R_DATA_SL_N(1'b1),
|
||||||
|
.R_DATA_SD(1'b0),
|
||||||
|
.R_DATA_AL_N(1'b1),
|
||||||
|
.R_DATA_AD_N(1'b0),
|
||||||
|
|
||||||
|
.W_CLK(PORT_W_CLK),
|
||||||
|
.W_ADDR(PORT_W_ADDR),
|
||||||
|
.W_DATA(PORT_W_WR_DATA),
|
||||||
|
.W_EN(PORT_W_WR_EN),
|
||||||
|
|
||||||
|
.BUSY_FB(1'b0)
|
||||||
|
);
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
Loading…
Reference in New Issue