Merge branch 'master' into timing_viz
This commit is contained in:
commit
5f2bf8d6df
@ -268,8 +268,7 @@ struct Timing
|
||||
auto net_delay = net_delays ? ctx->getNetinfoRouteDelay(net, usr) : delay_t();
|
||||
auto usr_arrival = net_arrival + net_delay;
|
||||
|
||||
if (portClass == TMG_REGISTER_INPUT || portClass == TMG_ENDPOINT || portClass == TMG_IGNORE ||
|
||||
portClass == TMG_CLOCK_INPUT) {
|
||||
if (portClass == TMG_ENDPOINT || portClass == TMG_IGNORE || portClass == TMG_CLOCK_INPUT) {
|
||||
// Skip
|
||||
} else {
|
||||
auto budget_override = ctx->getBudgetOverride(net, usr, net_delay);
|
||||
|
@ -2,11 +2,11 @@
|
||||
set(devices 25k 45k 85k)
|
||||
|
||||
if (NOT DEFINED TRELLIS_ROOT)
|
||||
message(FATAL_ERROR "you must define TRELLIS_ROOT using -DTRELLIS_ROOT=/path/to/prjtrellis for ECP5 support")
|
||||
message(STATUS "TRELLIS_ROOT not defined using -DTRELLIS_ROOT=/path/to/prjtrellis. Default to /usr/local/share/trellis")
|
||||
set(TRELLIS_ROOT "/usr/local/share/trellis")
|
||||
endif()
|
||||
|
||||
|
||||
file( GLOB found_pytrellis ${TRELLIS_ROOT}/libtrellis/pytrellis.*)
|
||||
file(GLOB found_pytrellis ${TRELLIS_ROOT}/libtrellis/pytrellis.*)
|
||||
|
||||
if ("${found_pytrellis}" STREQUAL "")
|
||||
message(FATAL_ERROR "failed to find pytrellis library in ${TRELLIS_ROOT}/libtrellis/")
|
||||
@ -19,7 +19,7 @@ add_library(ecp5_chipdb OBJECT ecp5/chipdbs/)
|
||||
target_compile_definitions(ecp5_chipdb PRIVATE NEXTPNR_NAMESPACE=nextpnr_${family})
|
||||
target_include_directories(ecp5_chipdb PRIVATE ${family}/)
|
||||
|
||||
if (WIN32)
|
||||
if (CMAKE_HOST_WIN32)
|
||||
set(ENV_CMD ${CMAKE_COMMAND} -E env "PYTHONPATH=\"${TRELLIS_ROOT}/libtrellis\;${TRELLIS_ROOT}/util/common\;${TRELLIS_ROOT}/timing/util\"")
|
||||
else()
|
||||
set(ENV_CMD ${CMAKE_COMMAND} -E env "PYTHONPATH=${TRELLIS_ROOT}/libtrellis:${TRELLIS_ROOT}/util/common:${TRELLIS_ROOT}/timing/util")
|
||||
|
@ -866,6 +866,17 @@ std::vector<GraphicElement> Arch::getDecalGraphics(DecalId decal) const
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
bool Arch::getCellDelay(const CellInfo *cell, IdString fromPort, IdString toPort, DelayInfo &delay) const
|
||||
{
|
||||
if (cell->type == id_ICESTORM_LC && cell->lcInfo.dffEnable) {
|
||||
if (toPort == id_O)
|
||||
return false;
|
||||
} else if (cell->type == id_ICESTORM_RAM || cell->type == id_ICESTORM_SPRAM) {
|
||||
return false;
|
||||
}
|
||||
return getCellDelayInternal(cell, fromPort, toPort, delay);
|
||||
}
|
||||
|
||||
bool Arch::getCellDelayInternal(const CellInfo *cell, IdString fromPort, IdString toPort, DelayInfo &delay) const
|
||||
{
|
||||
for (int i = 0; i < chip_info->num_timing_cells; i++) {
|
||||
const auto &tc = chip_info->cell_timing[i];
|
||||
@ -965,7 +976,7 @@ TimingPortClass Arch::getPortTimingClass(const CellInfo *cell, IdString port, in
|
||||
|
||||
return TMG_IGNORE;
|
||||
} else if (cell->type == id_ICESTORM_PLL) {
|
||||
if (port == id_PLLOUT_A || port == id_PLLOUT_B)
|
||||
if (port == id_PLLOUT_A || port == id_PLLOUT_B || port == id_PLLOUT_A_GLOBAL || port == id_PLLOUT_B_GLOBAL)
|
||||
return TMG_GEN_CLOCK;
|
||||
return TMG_IGNORE;
|
||||
} else if (cell->type == id_ICESTORM_LFOSC) {
|
||||
@ -1001,10 +1012,23 @@ TimingClockingInfo Arch::getPortClockingInfo(const CellInfo *cell, IdString port
|
||||
info.clock_port = id_CLK;
|
||||
info.edge = cell->lcInfo.negClk ? FALLING_EDGE : RISING_EDGE;
|
||||
if (port == id_O) {
|
||||
bool has_clktoq = getCellDelay(cell, id_CLK, id_O, info.clockToQ);
|
||||
bool has_clktoq = getCellDelayInternal(cell, id_CLK, id_O, info.clockToQ);
|
||||
NPNR_ASSERT(has_clktoq);
|
||||
} else {
|
||||
info.setup.delay = 100;
|
||||
if (port == id_I0 || port == id_I1 || port == id_I2 || port == id_I3) {
|
||||
DelayInfo dlut;
|
||||
bool has_ld = getCellDelayInternal(cell, port, id_O, dlut);
|
||||
NPNR_ASSERT(has_ld);
|
||||
if (args.type == ArchArgs::LP1K || args.type == ArchArgs::LP8K || args.type == ArchArgs::LP384) {
|
||||
info.setup.delay = 30 + dlut.delay;
|
||||
} else if (args.type == ArchArgs::UP5K) {
|
||||
info.setup.delay = dlut.delay - 50;
|
||||
} else {
|
||||
info.setup.delay = 20 + dlut.delay;
|
||||
}
|
||||
} else {
|
||||
info.setup.delay = 100;
|
||||
}
|
||||
info.hold.delay = 0;
|
||||
}
|
||||
} else if (cell->type == id_ICESTORM_RAM) {
|
||||
@ -1016,7 +1040,7 @@ TimingClockingInfo Arch::getPortClockingInfo(const CellInfo *cell, IdString port
|
||||
info.edge = bool_or_default(cell->params, id("NEG_CLK_W")) ? FALLING_EDGE : RISING_EDGE;
|
||||
}
|
||||
if (cell->ports.at(port).type == PORT_OUT) {
|
||||
bool has_clktoq = getCellDelay(cell, info.clock_port, port, info.clockToQ);
|
||||
bool has_clktoq = getCellDelayInternal(cell, info.clock_port, port, info.clockToQ);
|
||||
NPNR_ASSERT(has_clktoq);
|
||||
} else {
|
||||
info.setup.delay = 100;
|
||||
@ -1061,7 +1085,7 @@ TimingClockingInfo Arch::getPortClockingInfo(const CellInfo *cell, IdString port
|
||||
info.clock_port = cell->type == id_ICESTORM_SPRAM ? id_CLOCK : id_CLK;
|
||||
info.edge = RISING_EDGE;
|
||||
if (cell->ports.at(port).type == PORT_OUT) {
|
||||
bool has_clktoq = getCellDelay(cell, info.clock_port, port, info.clockToQ);
|
||||
bool has_clktoq = getCellDelayInternal(cell, info.clock_port, port, info.clockToQ);
|
||||
if (!has_clktoq)
|
||||
info.clockToQ.delay = 100;
|
||||
} else {
|
||||
|
@ -841,8 +841,11 @@ struct Arch : BaseCtx
|
||||
// -------------------------------------------------
|
||||
|
||||
// Get the delay through a cell from one port to another, returning false
|
||||
// if no path exists
|
||||
// if no path exists. This only considers combinational delays, as required by the Arch API
|
||||
bool getCellDelay(const CellInfo *cell, IdString fromPort, IdString toPort, DelayInfo &delay) const;
|
||||
// getCellDelayInternal is similar to the above, but without false path checks and including clock to out delays
|
||||
// for internal arch use only
|
||||
bool getCellDelayInternal(const CellInfo *cell, IdString fromPort, IdString toPort, DelayInfo &delay) const;
|
||||
// Get the port class, also setting clockInfoCount to the number of TimingClockingInfos associated with a port
|
||||
TimingPortClass getPortTimingClass(const CellInfo *cell, IdString port, int &clockInfoCount) const;
|
||||
// Get the TimingClockingInfo of a port
|
||||
|
Loading…
Reference in New Issue
Block a user