
* ng-ultra: new architecture * Implementation as in D2 deliverable * Support for nxdesignsuite-24.0.0.0-20240429T102300 * Save memory by directly outputing json * Add support for bidirectional IOs * cleanup * Create BFRs properly * Add IOM insertion * Cleanup * Block certain pips depending of DDFR mode * Add LUT bypass to improve routability * Add bypass for CSC mode of GCK * Fix IOM case * Initial memory support * Better RF/XRF handling * fix * RF placement and legalization * Disconnect non available ports for NX_RAM * cleanup * Add RFB/RAM context support for latest release * Remove ports that must not be used * Proper port used only on RFB * Add structure for clock sinks * Use cell type where applicable * Add clock sinks for other cell types * Validation check fixes * Commented too restrictive placement * Added more crossbar wire type * Hande IO termination input * Fail early due to NX tools limitation for now * Validations and fixes for RAM I/Os * Fix for latest version of tools * Use ctx->idf where applicable * warn if RAM ports are not actually used * Fix IOM packing * Fix CY packing * Change how constants are handled on CY * Post placement optimization for CY * Address comments for PR * pack and export GCK, WFG and PLL * Cover more global routing cases * Constraing to location if provided * Place at LOC * Pack and export DSP * wip * wip * notes * wip * wip * Validate DSPs * DSP cascading * Check mandatory parameters for DSP * existing gck * wip * export all the rest for bitstream * CDC packing * add more sinks * place FIFO * map rest of FIFO ports * enable pll by default * cleanup * Initial XLUT support * Fix statistics * Properly duplicate GCKs * RRSTO and WRSTO are not used on XFIFO * Fix for latest version of JSON format * Implement GCK limitations * cleanup * cleanup * Add more signals and use lowskew name * cleanup code a bit * Fix wfb * detect cascaded GCKs * Handle DFR * Route dfr clock properly * Cleanup * Cleanup bitstream code * Review issues addressed * Move helper routines * Expose private members for unit tests * cleanup * remove scale factor * make all location helper arrays static * Addressed review comments * Support post-routing CSC and SCC * Support NX_BFF * Place CSS and SCC only on allowed locations * Support latest Impulse * ng_ultra: Expand bounding box further for left-edge IO Signed-off-by: gatecat <gatecat@ds0.me> * Export all IO parameters in bitstream * Handle new CSV order or parameters and additional validation * Add some more undocumented values for CSV * Support for old and new CSV formats * Initial DDFR support * Display warning message once per file * Address review issues * Fix crash on memory access * Make boundbox fit NG-Ultra internal design * Update attributes after dff rewrite * Implement basic NG-Ultra LUT-DFF unit tests * Always use first seen xbar input Signed-off-by: gatecat <gatecat@ds0.me> * Simplified crossbar pip detection * Change order to prevent issues with some unconnected constants * Pack LUT and multiple DFF in stripe * Place DFF chains * Improve large DFF chains * Rename to pack_dff_chains * Better use XLUTs when possible * pack output DFF together with XLUT * option to disable XLUT optimiziations * Make more optimizations optional * fix to use pre-increment * GCK for lowskew signals * Bugfix for nets that are not part of lowskew network * Fix bitstream export for PLL cell * Remove separate route lowskew * Allow WFG mode 2 * Merge inverter into GCK * Add CSC per TILE when needed * Improve reusage of existing cell for CSC * Take preferred CSC * Cleanup * When in place CSC size not important * Cleanup * Reset and Load restriction * make csc optimisation optional * Proper count for IO resources * Detect when there is no next cell for DSP chain * Do not incorporate loops in XLUT * Check if output exists * Update copyright for delivery * Make building NG-Ultra chip database optional, follow filename convention * Ported drawing code to new API * Update expandBoundingBox for NG-Ultra * Copyright and license update * Add README information * cleanup and constids * Using ctx->idf where applicable * remove if_using_basecluster * refactor extra data usage * refactor to use create_cell_ptr only * optimized getCSC * optimize critical path a bit * clangformat * disable clangformat where applicable --------- Signed-off-by: gatecat <gatecat@ds0.me> Co-authored-by: Lofty <dan.ravensloft@gmail.com> Co-authored-by: gatecat <gatecat@ds0.me>
162 lines
5.8 KiB
C++
162 lines
5.8 KiB
C++
/*
|
|
* nextpnr -- Next Generation Place and Route
|
|
*
|
|
* Copyright (C) 2024 The Project Beyond Authors.
|
|
*
|
|
* 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 <vector>
|
|
#include "command.h"
|
|
#include "gtest/gtest.h"
|
|
#include "nextpnr.h"
|
|
#include "uarch/ng-ultra/ng_ultra.h"
|
|
#include "uarch/ng-ultra/pack.h"
|
|
#define HIMBAECHEL_CONSTIDS "uarch/ng-ultra/constids.inc"
|
|
#include "himbaechel_constids.h"
|
|
|
|
USING_NEXTPNR_NAMESPACE
|
|
|
|
class NGUltraLutDffTest : public ::testing::Test
|
|
{
|
|
protected:
|
|
virtual void SetUp()
|
|
{
|
|
init_share_dirname();
|
|
chipArgs.device = "NG-ULTRA";
|
|
ctx = new Context(chipArgs);
|
|
ctx->uarch->init(ctx);
|
|
ctx->late_init();
|
|
impl = (NgUltraImpl *)(ctx->uarch.get());
|
|
}
|
|
|
|
virtual void TearDown() { delete ctx; }
|
|
|
|
int const_autoidx = 0;
|
|
NetInfo *add_constant_driver(const char *name, char constval)
|
|
{
|
|
IdString cell_name = ctx->idf("%s%s%d", name, (constval == '1' ? "$VCC$" : "$GND$"), const_autoidx++);
|
|
CellInfo *cc = ctx->createCell(cell_name, ctx->id(constval == '1' ? "VCC" : "GND"));
|
|
cc->ports[ctx->id("Y")].name = ctx->id("Y");
|
|
cc->ports[ctx->id("Y")].type = PORT_OUT;
|
|
NetInfo *net = ctx->createNet(cell_name);
|
|
cc->connectPort(ctx->id("Y"), net);
|
|
return net;
|
|
}
|
|
|
|
void add_port(CellInfo *cell, const std::string &name, PortType dir)
|
|
{
|
|
IdString id = ctx->id(name);
|
|
cell->ports[id].name = id;
|
|
cell->ports[id].type = dir;
|
|
};
|
|
|
|
int evaluate_lut(int I1, int I2, int I3, int I4, int lut_table)
|
|
{
|
|
int S1 = I4 ? (lut_table >> 8) & 0xff : lut_table & 0xff;
|
|
int S2 = I3 ? (S1 >> 4 & 0xf) : S1 & 0xf;
|
|
int S3 = I2 ? (S2 >> 2 & 0x3) : S2 & 0x3;
|
|
int O = I1 ? (S3 >> 1 & 0x1) : S3 & 0x1;
|
|
return O;
|
|
}
|
|
|
|
ArchArgs chipArgs;
|
|
Context *ctx;
|
|
NgUltraImpl *impl;
|
|
};
|
|
|
|
TEST_F(NGUltraLutDffTest, pack_constants)
|
|
{
|
|
NgUltraPacker packer(ctx, impl);
|
|
packer.pack_constants();
|
|
ASSERT_EQ(ctx->cells.size(), 2LU);
|
|
}
|
|
|
|
TEST_F(NGUltraLutDffTest, remove_constants)
|
|
{
|
|
NgUltraPacker packer(ctx, impl);
|
|
packer.pack_constants();
|
|
impl->remove_constants();
|
|
ASSERT_EQ(ctx->cells.size(), 0LU);
|
|
}
|
|
|
|
TEST_F(NGUltraLutDffTest, remove_unused_gnd)
|
|
{
|
|
NgUltraPacker packer(ctx, impl);
|
|
CellInfo *cell = ctx->createCell(ctx->id("TEST"), id_NX_LUT);
|
|
add_port(cell, "I1", PORT_IN);
|
|
add_port(cell, "I2", PORT_IN);
|
|
add_port(cell, "I3", PORT_IN);
|
|
add_port(cell, "I4", PORT_IN);
|
|
cell->connectPort(id_I1, add_constant_driver("TEST", '1'));
|
|
cell->connectPort(id_I2, add_constant_driver("TEST", '1'));
|
|
cell->connectPort(id_I3, add_constant_driver("TEST", '1'));
|
|
|
|
ASSERT_EQ(ctx->cells.size(), 4LU);
|
|
packer.pack_constants();
|
|
ASSERT_EQ(ctx->cells.size(), 3LU);
|
|
impl->remove_constants();
|
|
ASSERT_EQ(ctx->cells.size(), 2LU);
|
|
ASSERT_EQ(ctx->cells.find(ctx->id("$PACKER_GND_DRV")), ctx->cells.end());
|
|
ASSERT_NE(ctx->cells.find(ctx->id("$PACKER_VCC_DRV")), ctx->cells.end());
|
|
ASSERT_EQ(ctx->nets.find(ctx->id("$PACKER_GND")), ctx->nets.end());
|
|
ASSERT_NE(ctx->nets.find(ctx->id("$PACKER_VCC")), ctx->nets.end());
|
|
}
|
|
|
|
TEST_F(NGUltraLutDffTest, remove_unused_vcc)
|
|
{
|
|
NgUltraPacker packer(ctx, impl);
|
|
CellInfo *cell = ctx->createCell(ctx->id("TEST"), id_NX_LUT);
|
|
add_port(cell, "I1", PORT_IN);
|
|
add_port(cell, "I2", PORT_IN);
|
|
add_port(cell, "I3", PORT_IN);
|
|
add_port(cell, "I4", PORT_IN);
|
|
cell->connectPort(id_I1, add_constant_driver("TEST", '0'));
|
|
cell->connectPort(id_I2, add_constant_driver("TEST", '0'));
|
|
cell->connectPort(id_I3, add_constant_driver("TEST", '0'));
|
|
|
|
ASSERT_EQ(ctx->cells.size(), 4LU);
|
|
packer.pack_constants();
|
|
ASSERT_EQ(ctx->cells.size(), 3LU);
|
|
impl->remove_constants();
|
|
ASSERT_EQ(ctx->cells.size(), 2LU);
|
|
ASSERT_NE(ctx->cells.find(ctx->id("$PACKER_GND_DRV")), ctx->cells.end());
|
|
ASSERT_EQ(ctx->cells.find(ctx->id("$PACKER_VCC_DRV")), ctx->cells.end());
|
|
ASSERT_NE(ctx->nets.find(ctx->id("$PACKER_GND")), ctx->nets.end());
|
|
ASSERT_EQ(ctx->nets.find(ctx->id("$PACKER_VCC")), ctx->nets.end());
|
|
}
|
|
|
|
TEST_F(NGUltraLutDffTest, make_init_with_const_input)
|
|
{
|
|
NgUltraPacker packer(ctx, impl);
|
|
for (int lut_table = 0; lut_table < 0x10000; lut_table++) {
|
|
for (int lut = 0; lut < 16; lut++) {
|
|
int I4 = (lut & 8) ? 1 : 0;
|
|
int I3 = (lut & 4) ? 1 : 0;
|
|
int I2 = (lut & 2) ? 1 : 0;
|
|
int I1 = (lut & 1) ? 1 : 0;
|
|
|
|
int tab1 = packer.make_init_with_const_input(lut_table, 0, I1);
|
|
int tab2 = packer.make_init_with_const_input(tab1, 1, I2);
|
|
int tab3 = packer.make_init_with_const_input(tab2, 2, I3);
|
|
int tab4 = packer.make_init_with_const_input(tab3, 3, I4);
|
|
|
|
ASSERT_EQ(evaluate_lut(I1, I2, I3, I4, lut_table), evaluate_lut(I1, I2, I3, I4, tab1));
|
|
ASSERT_EQ(evaluate_lut(I1, I2, I3, I4, lut_table), evaluate_lut(I1, I2, I3, I4, tab2));
|
|
ASSERT_EQ(evaluate_lut(I1, I2, I3, I4, lut_table), evaluate_lut(I1, I2, I3, I4, tab3));
|
|
ASSERT_EQ(evaluate_lut(I1, I2, I3, I4, lut_table), evaluate_lut(I1, I2, I3, I4, tab4));
|
|
}
|
|
}
|
|
}
|