diff options
Diffstat (limited to 'ice40')
-rw-r--r-- | ice40/hx1k.cc | 106 | ||||
-rw-r--r-- | ice40/hx8k.cc | 106 | ||||
-rw-r--r-- | ice40/lp1k.cc | 106 | ||||
-rw-r--r-- | ice40/lp384.cc | 106 | ||||
-rw-r--r-- | ice40/lp8k.cc | 106 | ||||
-rw-r--r-- | ice40/main.cc | 27 | ||||
-rw-r--r-- | ice40/up5k.cc | 106 |
7 files changed, 663 insertions, 0 deletions
diff --git a/ice40/hx1k.cc b/ice40/hx1k.cc new file mode 100644 index 0000000..741c954 --- /dev/null +++ b/ice40/hx1k.cc @@ -0,0 +1,106 @@ +/* + * nextpnr -- Next Generation Place and Route + * + * Copyright (C) 2018 Clifford Wolf <clifford@symbioticeda.com> + * Copyright (C) 2018 Miodrag Milanovic <miodrag@symbioticeda.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" + +USING_NEXTPNR_NAMESPACE + +class HX1KTest : public ::testing::Test +{ + protected: + virtual void SetUp() + { + chipArgs.type = ArchArgs::HX1K; + chipArgs.package = "tq144"; + ctx = new Context(chipArgs); + } + + virtual void TearDown() { delete ctx; } + + ArchArgs chipArgs; + Context *ctx; +}; + +TEST_F(HX1KTest, bel_names) +{ + int bel_count = 0; + for (auto bel : ctx->getBels()) { + auto name = ctx->getBelName(bel); + ASSERT_EQ(bel, ctx->getBelByName(name)); + bel_count++; + } + ASSERT_EQ(bel_count, 1418); +} + +TEST_F(HX1KTest, wire_names) +{ + int wire_count = 0; + for (auto wire : ctx->getWires()) { + auto name = ctx->getWireName(wire); + assert(wire == ctx->getWireByName(name)); + wire_count++; + } + ASSERT_EQ(wire_count, 32802); +} + +TEST_F(HX1KTest, pip_names) +{ + int pip_count = 0; + for (auto pip : ctx->getPips()) { + auto name = ctx->getPipName(pip); + assert(pip == ctx->getPipByName(name)); + pip_count++; + } + ASSERT_EQ(pip_count, 345504); +} + +TEST_F(HX1KTest, uphill_to_downhill) +{ + for (auto dst : ctx->getWires()) { + for (auto uphill_pip : ctx->getPipsUphill(dst)) { + bool found_downhill = false; + for (auto downhill_pip : ctx->getPipsDownhill(ctx->getPipSrcWire(uphill_pip))) { + if (uphill_pip == downhill_pip) { + ASSERT_FALSE(found_downhill); + found_downhill = true; + } + } + ASSERT_TRUE(found_downhill); + } + } +} + +TEST_F(HX1KTest, downhill_to_uphill) +{ + for (auto dst : ctx->getWires()) { + for (auto downhill_pip : ctx->getPipsDownhill(dst)) { + bool found_uphill = false; + for (auto uphill_pip : ctx->getPipsUphill(ctx->getPipDstWire(downhill_pip))) { + if (uphill_pip == downhill_pip) { + ASSERT_FALSE(found_uphill); + found_uphill = true; + } + } + ASSERT_TRUE(found_uphill); + } + } +} diff --git a/ice40/hx8k.cc b/ice40/hx8k.cc new file mode 100644 index 0000000..517df0d --- /dev/null +++ b/ice40/hx8k.cc @@ -0,0 +1,106 @@ +/* + * nextpnr -- Next Generation Place and Route + * + * Copyright (C) 2018 Clifford Wolf <clifford@symbioticeda.com> + * Copyright (C) 2018 Miodrag Milanovic <miodrag@symbioticeda.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" + +USING_NEXTPNR_NAMESPACE + +class HX8KTest : public ::testing::Test +{ + protected: + virtual void SetUp() + { + chipArgs.type = ArchArgs::HX8K; + chipArgs.package = "ct256"; + ctx = new Context(chipArgs); + } + + virtual void TearDown() { delete ctx; } + + ArchArgs chipArgs; + Context *ctx; +}; + +TEST_F(HX8KTest, bel_names) +{ + int bel_count = 0; + for (auto bel : ctx->getBels()) { + auto name = ctx->getBelName(bel); + ASSERT_EQ(bel, ctx->getBelByName(name)); + bel_count++; + } + ASSERT_EQ(bel_count, 7979); +} + +TEST_F(HX8KTest, wire_names) +{ + int wire_count = 0; + for (auto wire : ctx->getWires()) { + auto name = ctx->getWireName(wire); + assert(wire == ctx->getWireByName(name)); + wire_count++; + } + ASSERT_EQ(wire_count, 165894); +} + +TEST_F(HX8KTest, pip_names) +{ + int pip_count = 0; + for (auto pip : ctx->getPips()) { + auto name = ctx->getPipName(pip); + assert(pip == ctx->getPipByName(name)); + pip_count++; + } + ASSERT_EQ(pip_count, 1806080); +} + +TEST_F(HX8KTest, uphill_to_downhill) +{ + for (auto dst : ctx->getWires()) { + for (auto uphill_pip : ctx->getPipsUphill(dst)) { + bool found_downhill = false; + for (auto downhill_pip : ctx->getPipsDownhill(ctx->getPipSrcWire(uphill_pip))) { + if (uphill_pip == downhill_pip) { + ASSERT_FALSE(found_downhill); + found_downhill = true; + } + } + ASSERT_TRUE(found_downhill); + } + } +} + +TEST_F(HX8KTest, downhill_to_uphill) +{ + for (auto dst : ctx->getWires()) { + for (auto downhill_pip : ctx->getPipsDownhill(dst)) { + bool found_uphill = false; + for (auto uphill_pip : ctx->getPipsUphill(ctx->getPipDstWire(downhill_pip))) { + if (uphill_pip == downhill_pip) { + ASSERT_FALSE(found_uphill); + found_uphill = true; + } + } + ASSERT_TRUE(found_uphill); + } + } +} diff --git a/ice40/lp1k.cc b/ice40/lp1k.cc new file mode 100644 index 0000000..2fdba08 --- /dev/null +++ b/ice40/lp1k.cc @@ -0,0 +1,106 @@ +/* + * nextpnr -- Next Generation Place and Route + * + * Copyright (C) 2018 Clifford Wolf <clifford@symbioticeda.com> + * Copyright (C) 2018 Miodrag Milanovic <miodrag@symbioticeda.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" + +USING_NEXTPNR_NAMESPACE + +class LP1KTest : public ::testing::Test +{ + protected: + virtual void SetUp() + { + chipArgs.type = ArchArgs::LP1K; + chipArgs.package = "tq144"; + ctx = new Context(chipArgs); + } + + virtual void TearDown() { delete ctx; } + + ArchArgs chipArgs; + Context *ctx; +}; + +TEST_F(LP1KTest, bel_names) +{ + int bel_count = 0; + for (auto bel : ctx->getBels()) { + auto name = ctx->getBelName(bel); + ASSERT_EQ(bel, ctx->getBelByName(name)); + bel_count++; + } + ASSERT_EQ(bel_count, 1418); +} + +TEST_F(LP1KTest, wire_names) +{ + int wire_count = 0; + for (auto wire : ctx->getWires()) { + auto name = ctx->getWireName(wire); + assert(wire == ctx->getWireByName(name)); + wire_count++; + } + ASSERT_EQ(wire_count, 32802); +} + +TEST_F(LP1KTest, pip_names) +{ + int pip_count = 0; + for (auto pip : ctx->getPips()) { + auto name = ctx->getPipName(pip); + assert(pip == ctx->getPipByName(name)); + pip_count++; + } + ASSERT_EQ(pip_count, 345504); +} + +TEST_F(LP1KTest, uphill_to_downhill) +{ + for (auto dst : ctx->getWires()) { + for (auto uphill_pip : ctx->getPipsUphill(dst)) { + bool found_downhill = false; + for (auto downhill_pip : ctx->getPipsDownhill(ctx->getPipSrcWire(uphill_pip))) { + if (uphill_pip == downhill_pip) { + ASSERT_FALSE(found_downhill); + found_downhill = true; + } + } + ASSERT_TRUE(found_downhill); + } + } +} + +TEST_F(LP1KTest, downhill_to_uphill) +{ + for (auto dst : ctx->getWires()) { + for (auto downhill_pip : ctx->getPipsDownhill(dst)) { + bool found_uphill = false; + for (auto uphill_pip : ctx->getPipsUphill(ctx->getPipDstWire(downhill_pip))) { + if (uphill_pip == downhill_pip) { + ASSERT_FALSE(found_uphill); + found_uphill = true; + } + } + ASSERT_TRUE(found_uphill); + } + } +} diff --git a/ice40/lp384.cc b/ice40/lp384.cc new file mode 100644 index 0000000..a030b77 --- /dev/null +++ b/ice40/lp384.cc @@ -0,0 +1,106 @@ +/* + * nextpnr -- Next Generation Place and Route + * + * Copyright (C) 2018 Clifford Wolf <clifford@symbioticeda.com> + * Copyright (C) 2018 Miodrag Milanovic <miodrag@symbioticeda.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" + +USING_NEXTPNR_NAMESPACE + +class LP384Test : public ::testing::Test +{ + protected: + virtual void SetUp() + { + chipArgs.type = ArchArgs::LP384; + chipArgs.package = "qn32"; + ctx = new Context(chipArgs); + } + + virtual void TearDown() { delete ctx; } + + ArchArgs chipArgs; + Context *ctx; +}; + +TEST_F(LP384Test, bel_names) +{ + int bel_count = 0; + for (auto bel : ctx->getBels()) { + auto name = ctx->getBelName(bel); + ASSERT_EQ(bel, ctx->getBelByName(name)); + bel_count++; + } + ASSERT_EQ(bel_count, 449); +} + +TEST_F(LP384Test, wire_names) +{ + int wire_count = 0; + for (auto wire : ctx->getWires()) { + auto name = ctx->getWireName(wire); + assert(wire == ctx->getWireByName(name)); + wire_count++; + } + ASSERT_EQ(wire_count, 9830); +} + +TEST_F(LP384Test, pip_names) +{ + int pip_count = 0; + for (auto pip : ctx->getPips()) { + auto name = ctx->getPipName(pip); + assert(pip == ctx->getPipByName(name)); + pip_count++; + } + ASSERT_EQ(pip_count, 94544); +} + +TEST_F(LP384Test, uphill_to_downhill) +{ + for (auto dst : ctx->getWires()) { + for (auto uphill_pip : ctx->getPipsUphill(dst)) { + bool found_downhill = false; + for (auto downhill_pip : ctx->getPipsDownhill(ctx->getPipSrcWire(uphill_pip))) { + if (uphill_pip == downhill_pip) { + ASSERT_FALSE(found_downhill); + found_downhill = true; + } + } + ASSERT_TRUE(found_downhill); + } + } +} + +TEST_F(LP384Test, downhill_to_uphill) +{ + for (auto dst : ctx->getWires()) { + for (auto downhill_pip : ctx->getPipsDownhill(dst)) { + bool found_uphill = false; + for (auto uphill_pip : ctx->getPipsUphill(ctx->getPipDstWire(downhill_pip))) { + if (uphill_pip == downhill_pip) { + ASSERT_FALSE(found_uphill); + found_uphill = true; + } + } + ASSERT_TRUE(found_uphill); + } + } +} diff --git a/ice40/lp8k.cc b/ice40/lp8k.cc new file mode 100644 index 0000000..7fe6ac3 --- /dev/null +++ b/ice40/lp8k.cc @@ -0,0 +1,106 @@ +/* + * nextpnr -- Next Generation Place and Route + * + * Copyright (C) 2018 Clifford Wolf <clifford@symbioticeda.com> + * Copyright (C) 2018 Miodrag Milanovic <miodrag@symbioticeda.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" + +USING_NEXTPNR_NAMESPACE + +class LP8KTest : public ::testing::Test +{ + protected: + virtual void SetUp() + { + chipArgs.type = ArchArgs::LP8K; + chipArgs.package = "ct256"; + ctx = new Context(chipArgs); + } + + virtual void TearDown() { delete ctx; } + + ArchArgs chipArgs; + Context *ctx; +}; + +TEST_F(LP8KTest, bel_names) +{ + int bel_count = 0; + for (auto bel : ctx->getBels()) { + auto name = ctx->getBelName(bel); + ASSERT_EQ(bel, ctx->getBelByName(name)); + bel_count++; + } + ASSERT_EQ(bel_count, 7979); +} + +TEST_F(LP8KTest, wire_names) +{ + int wire_count = 0; + for (auto wire : ctx->getWires()) { + auto name = ctx->getWireName(wire); + assert(wire == ctx->getWireByName(name)); + wire_count++; + } + ASSERT_EQ(wire_count, 165894); +} + +TEST_F(LP8KTest, pip_names) +{ + int pip_count = 0; + for (auto pip : ctx->getPips()) { + auto name = ctx->getPipName(pip); + assert(pip == ctx->getPipByName(name)); + pip_count++; + } + ASSERT_EQ(pip_count, 1806080); +} + +TEST_F(LP8KTest, uphill_to_downhill) +{ + for (auto dst : ctx->getWires()) { + for (auto uphill_pip : ctx->getPipsUphill(dst)) { + bool found_downhill = false; + for (auto downhill_pip : ctx->getPipsDownhill(ctx->getPipSrcWire(uphill_pip))) { + if (uphill_pip == downhill_pip) { + ASSERT_FALSE(found_downhill); + found_downhill = true; + } + } + ASSERT_TRUE(found_downhill); + } + } +} + +TEST_F(LP8KTest, downhill_to_uphill) +{ + for (auto dst : ctx->getWires()) { + for (auto downhill_pip : ctx->getPipsDownhill(dst)) { + bool found_uphill = false; + for (auto uphill_pip : ctx->getPipsUphill(ctx->getPipDstWire(downhill_pip))) { + if (uphill_pip == downhill_pip) { + ASSERT_FALSE(found_uphill); + found_uphill = true; + } + } + ASSERT_TRUE(found_uphill); + } + } +} diff --git a/ice40/main.cc b/ice40/main.cc new file mode 100644 index 0000000..60b9fda --- /dev/null +++ b/ice40/main.cc @@ -0,0 +1,27 @@ +/* + * nextpnr -- Next Generation Place and Route + * + * Copyright (C) 2018 Miodrag Milanovic <miodrag@symbioticeda.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" + +int main(int argc, char **argv) +{ + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/ice40/up5k.cc b/ice40/up5k.cc new file mode 100644 index 0000000..582876e --- /dev/null +++ b/ice40/up5k.cc @@ -0,0 +1,106 @@ +/* + * nextpnr -- Next Generation Place and Route + * + * Copyright (C) 2018 Clifford Wolf <clifford@symbioticeda.com> + * Copyright (C) 2018 Miodrag Milanovic <miodrag@symbioticeda.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" + +USING_NEXTPNR_NAMESPACE + +class UP5KTest : public ::testing::Test +{ + protected: + virtual void SetUp() + { + chipArgs.type = ArchArgs::UP5K; + chipArgs.package = "sg48"; + ctx = new Context(chipArgs); + } + + virtual void TearDown() { delete ctx; } + + ArchArgs chipArgs; + Context *ctx; +}; + +TEST_F(UP5KTest, bel_names) +{ + int bel_count = 0; + for (auto bel : ctx->getBels()) { + auto name = ctx->getBelName(bel); + ASSERT_EQ(bel, ctx->getBelByName(name)); + bel_count++; + } + ASSERT_EQ(bel_count, 5438); +} + +TEST_F(UP5KTest, wire_names) +{ + int wire_count = 0; + for (auto wire : ctx->getWires()) { + auto name = ctx->getWireName(wire); + assert(wire == ctx->getWireByName(name)); + wire_count++; + } + ASSERT_EQ(wire_count, 124503); +} + +TEST_F(UP5KTest, pip_names) +{ + int pip_count = 0; + for (auto pip : ctx->getPips()) { + auto name = ctx->getPipName(pip); + assert(pip == ctx->getPipByName(name)); + pip_count++; + } + ASSERT_EQ(pip_count, 1324704); +} + +TEST_F(UP5KTest, uphill_to_downhill) +{ + for (auto dst : ctx->getWires()) { + for (auto uphill_pip : ctx->getPipsUphill(dst)) { + bool found_downhill = false; + for (auto downhill_pip : ctx->getPipsDownhill(ctx->getPipSrcWire(uphill_pip))) { + if (uphill_pip == downhill_pip) { + ASSERT_FALSE(found_downhill); + found_downhill = true; + } + } + ASSERT_TRUE(found_downhill); + } + } +} + +TEST_F(UP5KTest, downhill_to_uphill) +{ + for (auto dst : ctx->getWires()) { + for (auto downhill_pip : ctx->getPipsDownhill(dst)) { + bool found_uphill = false; + for (auto uphill_pip : ctx->getPipsUphill(ctx->getPipDstWire(downhill_pip))) { + if (uphill_pip == downhill_pip) { + ASSERT_FALSE(found_uphill); + found_uphill = true; + } + } + ASSERT_TRUE(found_uphill); + } + } +} |