Implement basic NG-Ultra LUT-DFF unit tests
This commit is contained in:
parent
61a12a0e15
commit
64fa81d26a
@ -334,6 +334,7 @@ foreach (family ${ARCH})
|
||||
|
||||
if (BUILD_TESTS)
|
||||
set(family_targets ${family_targets} ${PROGRAM_PREFIX}nextpnr-${family}-test)
|
||||
set(family_test_targets ${PROGRAM_PREFIX}nextpnr-${family}-test)
|
||||
endif()
|
||||
|
||||
# Include the family-specific CMakeFile
|
||||
|
@ -5,4 +5,10 @@ foreach(uarch ${HIMBAECHEL_UARCHES})
|
||||
foreach(target ${family_targets})
|
||||
target_sources(${target} PRIVATE ${HM_UARCH_FILES})
|
||||
endforeach()
|
||||
if (BUILD_TESTS)
|
||||
foreach(target ${family_test_targets})
|
||||
aux_source_directory(${family}/uarch/${uarch}/tests/ HM_UARCH_TEST_FILES)
|
||||
target_sources(${target} PRIVATE ${HM_UARCH_TEST_FILES})
|
||||
endforeach()
|
||||
endif()
|
||||
endforeach(uarch)
|
||||
|
161
himbaechel/uarch/ng-ultra/tests/lut_dff.cc
Normal file
161
himbaechel/uarch/ng-ultra/tests/lut_dff.cc
Normal file
@ -0,0 +1,161 @@
|
||||
/*
|
||||
* nextpnr -- Next Generation Place and Route
|
||||
*
|
||||
* Copyright (C) 2024 Miodrag Milanovic <micko@yosyshq.com>
|
||||
*
|
||||
* 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 "gtest/gtest.h"
|
||||
#include "nextpnr.h"
|
||||
#include "command.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->id(std::string(name) + (constval == '1' ? "$VCC$" : "$GND$") + std::to_string(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));
|
||||
}
|
||||
}
|
||||
}
|
32
himbaechel/uarch/ng-ultra/tests/main.cc
Normal file
32
himbaechel/uarch/ng-ultra/tests/main.cc
Normal file
@ -0,0 +1,32 @@
|
||||
/*
|
||||
* nextpnr -- Next Generation Place and Route
|
||||
*
|
||||
* Copyright (C) 2024 Miodrag Milanovic <micko@yosyshq.com>
|
||||
*
|
||||
* 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 "log.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
USING_NEXTPNR_NAMESPACE
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
// TODO: Remove for delivery, useful while checking tests
|
||||
log_streams.push_back(std::make_pair(&std::cerr, LogLevel::LOG_MSG));
|
||||
::testing::InitGoogleTest(&argc, argv);
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
Loading…
Reference in New Issue
Block a user