Skip to content

Commit

Permalink
✨ CFE Clocking Scheme (#44)
Browse files Browse the repository at this point in the history
* ✨ Added the CFE clocking scheme proposed in 'CFE: a convenient, flexible, and efficient clocking scheme for quantum-dot cellular automata'

* 🎨 Re-formatted clocking scheme array representation code

* 📝 Added CFE clocking to the documentation

* ✏️ Fixed typo and CFE source paper [skip ci]
  • Loading branch information
marcelwa committed Aug 5, 2022
1 parent b031532 commit 94d3eeb
Show file tree
Hide file tree
Showing 8 changed files with 205 additions and 12 deletions.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -124,9 +124,9 @@ Built-in schemes are
|:--------------------------------------------------------:|:------------------------------------------------------------------------:|:-------------------------------------------------------------------------:|
| <img src="docs/_static/use.png" alt="USE" height="200"/> | <img src="docs/_static/res.png" alt="RES" height="200"/> | <img src="docs/_static/esp.png" alt="2DDWave" height="200"/> |

| [BANCS](https://ieeexplore.ieee.org/document/8533251) |
|:------------------------------------------------------------:|
| <img src="docs/_static/bancs.png" alt="BANCS" height="300"/> |
| [CFE](https://ietresearch.onlinelibrary.wiley.com/doi/10.1049/iet-cds.2019.0096) | [BANCS](https://ieeexplore.ieee.org/document/8533251) |
|:------------------------------------------------------------------------------------:|:------------------------------------------------------------:|
| <img src="docs/_static/cfe.png" alt="CFE" height="200"/> | <img src="docs/_static/bancs.png" alt="BANCS" height="300"/> |

plus the mentioned irregular open clocking that works via a clock map instead of a regular extrapolated cutout.

Expand Down
2 changes: 1 addition & 1 deletion cli/cmd/physical_design/exact.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ class exact_command : public command
{
add_option("--clk_scheme,-s", clocking,
"Clocking scheme to use {OPEN[3|4], COLUMNAR[3|4], ROW[3|4] 2DDWAVE[3|4], 2DDWAVEHEX[3|4], USE, "
"RES, ESP, BANCS}",
"RES, ESP, CFE, BANCS}",
true);
add_option("--upper_bound,-u", ps.upper_bound, "Number of FCN gate tiles to use at maximum");
add_option("--fixed_size,-f", ps.fixed_size, "Execute only one iteration with the given number of tiles");
Expand Down
3 changes: 2 additions & 1 deletion cli/cmd/physical_design/onepass.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,8 @@ class onepass_command : public command
"resulting from this approach might be desynchronized. I/Os are always located at the "
"layout's borders.")
{
add_option("--clk_scheme,-s", clocking, "Clocking scheme to use {2DDWAVE[3|4], USE, RES, ESP, BANCS}", true);
add_option("--clk_scheme,-s", clocking, "Clocking scheme to use {2DDWAVE[3|4], USE, RES, ESP, CFE, BANCS}",
true);
add_option("--upper_bound,-u", ps.upper_bound, "Number of FCN gate tiles to use at maximum");
add_option("--fixed_size,-f", ps.fixed_size, "Execute only one iteration with the given number of tiles");
add_option("--timeout,-t", ps.timeout, "Timeout in seconds");
Expand Down
Binary file added docs/_static/cfe.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
8 changes: 8 additions & 0 deletions docs/layouts/clocking_scheme.rst
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,14 @@ ESP

.. doxygenfunction:: fiction::esp_clocking

CFE
###

.. figure:: /_static/cfe.png
:width: 200

.. doxygenfunction:: fiction::cfe_clocking

BANCS
#####

Expand Down
87 changes: 81 additions & 6 deletions include/fiction/layouts/clocking_scheme.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,7 @@ static constexpr const char* twoddwave_hex = "2DDWAVEHEX";
static constexpr const char* use = "USE";
static constexpr const char* res = "RES";
static constexpr const char* esp = "ESP";
static constexpr const char* cfe = "CFE";
static constexpr const char* bancs = "BANCS";
} // namespace clock_name

Expand Down Expand Up @@ -349,11 +350,23 @@ static auto twoddwave_clocking(const num_clks& n = num_clks::FOUR) noexcept
template <typename Lyt>
static auto twoddwave_hex_clocking(const num_clks& n = num_clks::FOUR) noexcept
{
// clang-format off

static constexpr std::array<std::array<typename clocking_scheme<clock_zone<Lyt>>::clock_number, 3u>, 6u>
odd_3_cutout{{{{0, 1, 2}}, {{1, 2, 0}}, {{1, 2, 0}}, {{2, 0, 1}}, {{2, 0, 1}}, {{0, 1, 2}}}};
odd_3_cutout{{{{0, 1, 2}},
{{1, 2, 0}},
{{1, 2, 0}},
{{2, 0, 1}},
{{2, 0, 1}},
{{0, 1, 2}}}};

static constexpr std::array<std::array<typename clocking_scheme<clock_zone<Lyt>>::clock_number, 3u>, 6u>
even_3_cutout{{{{0, 1, 2}}, {{0, 1, 2}}, {{1, 2, 0}}, {{1, 2, 0}}, {{2, 0, 1}}, {{2, 0, 1}}}};
even_3_cutout{{{{0, 1, 2}},
{{0, 1, 2}},
{{1, 2, 0}},
{{1, 2, 0}},
{{2, 0, 1}},
{{2, 0, 1}}}};

static constexpr std::array<std::array<typename clocking_scheme<clock_zone<Lyt>>::clock_number, 4u>, 8u>
odd_4_cutout{{{{0, 1, 2, 3}},
Expand All @@ -375,6 +388,8 @@ static auto twoddwave_hex_clocking(const num_clks& n = num_clks::FOUR) noexcept
{{3, 0, 1, 2}},
{{3, 0, 1, 2}}}};

// clang-format on

static const typename clocking_scheme<clock_zone<Lyt>>::clock_function odd_row_twoddwave_hex_3_clock_function =
[](const clock_zone<Lyt>& cz) noexcept { return odd_3_cutout[cz.y % 6ul][cz.x % 3ul]; };

Expand Down Expand Up @@ -516,16 +531,23 @@ static auto twoddwave_hex_clocking(const num_clks& n = num_clks::FOUR) noexcept
template <typename Lyt>
static auto use_clocking() noexcept
{
// clang-format off

static const typename clocking_scheme<clock_zone<Lyt>>::clock_function use_clock_function =
[](const clock_zone<Lyt>& cz) noexcept
{
constexpr std::array<std::array<typename clocking_scheme<clock_zone<Lyt>>::clock_number, 4u>, 4u> cutout{
{{{0, 1, 2, 3}}, {{3, 2, 1, 0}}, {{2, 3, 0, 1}}, {{1, 0, 3, 2}}}};
{{{0, 1, 2, 3}},
{{3, 2, 1, 0}},
{{2, 3, 0, 1}},
{{1, 0, 3, 2}}}};

return cutout[cz.y % 4ul][cz.x % 4ul];
};

return clocking_scheme{clock_name::use, use_clock_function, std::min(Lyt::max_fanin_size, 2u), 2u, 4u, true};

// clang-format on
}
/**
* Returns the RES clocking as defined in "An efficient clocking scheme for quantum-dot cellular automata" by
Expand All @@ -538,16 +560,23 @@ static auto use_clocking() noexcept
template <typename Lyt>
static auto res_clocking() noexcept
{
// clang-format off

static const typename clocking_scheme<clock_zone<Lyt>>::clock_function res_clock_function =
[](const clock_zone<Lyt>& cz) noexcept
{
constexpr std::array<std::array<typename clocking_scheme<clock_zone<Lyt>>::clock_number, 4u>, 4u> cutout{
{{{3, 0, 1, 2}}, {{0, 1, 0, 3}}, {{1, 2, 3, 0}}, {{0, 3, 2, 1}}}};
{{{3, 0, 1, 2}},
{{0, 1, 0, 3}},
{{1, 2, 3, 0}},
{{0, 3, 2, 1}}}};

return cutout[cz.y % 4ul][cz.x % 4ul];
};

return clocking_scheme{clock_name::res, res_clock_function, std::min(Lyt::max_fanin_size, 3u), 3u, 4u, true};

// clang-format on
}
/**
* Returns the ESP (Zig-Zag) clocking as defined in "Regular Clocking based Emerging Technique in QCA Targeting Low
Expand All @@ -560,16 +589,52 @@ static auto res_clocking() noexcept
template <typename Lyt>
static auto esp_clocking() noexcept
{
// clang-format off

static const typename clocking_scheme<clock_zone<Lyt>>::clock_function esp_clock_function =
[](const clock_zone<Lyt>& cz) noexcept
{
constexpr std::array<std::array<typename clocking_scheme<clock_zone<Lyt>>::clock_number, 4u>, 4u> cutout{
{{{3, 0, 1, 2}}, {{0, 1, 2, 3}}, {{1, 2, 3, 0}}, {{0, 3, 2, 1}}}};
{{{3, 0, 1, 2}},
{{0, 1, 2, 3}},
{{1, 2, 3, 0}},
{{0, 3, 2, 1}}}};

return cutout[cz.y % 4ul][cz.x % 4ul];
};

return clocking_scheme{clock_name::esp, esp_clock_function, std::min(Lyt::max_fanin_size, 3u), 3u, 4u, true};

// clang-format on
}
/**
* Returns the CFE clocking as defined in "CFE: a convenient, flexible, and efficient clocking scheme for quantum-dot
* cellular automata" by Feifei Deng, Guang-Jun Xie, Xin Cheng, Zhang Zhang, and Yongqiang Zhang in IET Circuits,
* Devices & Systems 2020.
*
* @tparam Lyt Clocked layout type.
* @return CFE clocking scheme.
*/
template <typename Lyt>
static auto cfe_clocking() noexcept
{
// clang-format off

static const typename clocking_scheme<clock_zone<Lyt>>::clock_function cfe_clock_function =
[](const clock_zone<Lyt>& cz) noexcept
{
constexpr std::array<std::array<typename clocking_scheme<clock_zone<Lyt>>::clock_number, 4u>, 4u> cutout{
{{{0, 1, 0, 1}},
{{3, 2, 3, 2}},
{{0, 1, 0, 1}},
{{3, 2, 3, 2}}}};

return cutout[cz.y % 4ul][cz.x % 4ul];
};

return clocking_scheme{clock_name::cfe, cfe_clock_function, std::min(Lyt::max_fanin_size, 3u), 3u, 4u, true};

// clang-format on
}
/**
* Returns the BANCS clocking as defined in "BANCS: Bidirectional Alternating Nanomagnetic Clocking Scheme" by
Expand All @@ -581,16 +646,25 @@ static auto esp_clocking() noexcept
template <typename Lyt>
static auto bancs_clocking() noexcept
{
// clang-format off

static const typename clocking_scheme<clock_zone<Lyt>>::clock_function bancs_clock_function =
[](const clock_zone<Lyt>& cz) noexcept
{
constexpr std::array<std::array<typename clocking_scheme<clock_zone<Lyt>>::clock_number, 3u>, 6u> cutout{
{{{0, 1, 2}}, {{2, 1, 0}}, {{2, 0, 1}}, {{1, 0, 2}}, {{1, 2, 0}}, {{0, 2, 1}}}};
{{{0, 1, 2}},
{{2, 1, 0}},
{{2, 0, 1}},
{{1, 0, 2}},
{{1, 2, 0}},
{{0, 2, 1}}}};

return cutout[cz.y % 6ul][cz.x % 3ul];
};

return clocking_scheme{clock_name::bancs, bancs_clock_function, std::min(Lyt::max_fanin_size, 2u), 2u, 3u, true};

// clang-format on
}
/**
* Returns a smart pointer to the given scheme.
Expand Down Expand Up @@ -655,6 +729,7 @@ std::optional<clocking_scheme<clock_zone<Lyt>>> get_clocking_scheme(const std::s
{clock_name::use, use_clocking<Lyt>()},
{clock_name::res, res_clocking<Lyt>()},
{clock_name::esp, esp_clocking<Lyt>()},
{clock_name::cfe, cfe_clocking<Lyt>()},
{clock_name::bancs, bancs_clocking<Lyt>()}};

auto upper_name = name;
Expand Down
26 changes: 26 additions & 0 deletions test/algorithms/physical_design/exact.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,22 @@ exact_physical_design_params<Lyt>&& res(exact_physical_design_params<Lyt>&& ps)
return std::move(ps);
}

template <typename Lyt>
exact_physical_design_params<Lyt>&& esp(exact_physical_design_params<Lyt>&& ps) noexcept
{
ps.scheme = std::make_shared<clocking_scheme<coordinate<Lyt>>>(esp_clocking<Lyt>());

return std::move(ps);
}

template <typename Lyt>
exact_physical_design_params<Lyt>&& cfe(exact_physical_design_params<Lyt>&& ps) noexcept
{
ps.scheme = std::make_shared<clocking_scheme<coordinate<Lyt>>>(cfe_clocking<Lyt>());

return std::move(ps);
}

template <typename Lyt>
exact_physical_design_params<Lyt>&& crossings(exact_physical_design_params<Lyt>&& ps) noexcept
{
Expand Down Expand Up @@ -279,6 +295,16 @@ TEST_CASE("Exact Cartesian physical design", "[exact]")
check_with_gate_library<qca_cell_clk_lyt, qca_one_library>(
blueprints::and_or_network<mockturtle::mig_network>(), res(crossings(configuration<cart_gate_clk_lyt>())));
}
SECTION("ESP clocking")
{
check_with_gate_library<qca_cell_clk_lyt, qca_one_library>(
blueprints::and_or_network<mockturtle::mig_network>(), esp(crossings(configuration<cart_gate_clk_lyt>())));
}
SECTION("CFE clocking")
{
check_with_gate_library<qca_cell_clk_lyt, qca_one_library>(
blueprints::and_or_network<mockturtle::mig_network>(), cfe(crossings(configuration<cart_gate_clk_lyt>())));
}
SECTION("Border I/O")
{
check_with_gate_library<qca_cell_clk_lyt, qca_one_library>(
Expand Down
85 changes: 84 additions & 1 deletion test/layouts/clocking_scheme.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1617,6 +1617,86 @@ TEST_CASE("4-phase RES", "[clocking-scheme]")
CHECK(res4({3 + 4, 3 + 4}) == 1);
}

TEST_CASE("4-phase CFE", "[clocking-scheme]")
{
using clk_lyt = clocked_layout<cartesian_layout<offset::ucoord_t>>;

const auto cfe4 = cfe_clocking<clk_lyt>();

CHECK(cfe4.num_clocks == 4u);
CHECK(cfe4.max_in_degree == 3u);
CHECK(cfe4.max_out_degree == 3u);
CHECK(cfe4.is_regular());

CHECK(cfe4({0, 0}) == 0);
CHECK(cfe4({0, 1}) == 3);
CHECK(cfe4({0, 2}) == 0);
CHECK(cfe4({0, 3}) == 3);
CHECK(cfe4({1, 0}) == 1);
CHECK(cfe4({1, 1}) == 2);
CHECK(cfe4({1, 2}) == 1);
CHECK(cfe4({1, 3}) == 2);
CHECK(cfe4({2, 0}) == 0);
CHECK(cfe4({2, 1}) == 3);
CHECK(cfe4({2, 2}) == 0);
CHECK(cfe4({2, 3}) == 3);
CHECK(cfe4({3, 0}) == 1);
CHECK(cfe4({3, 1}) == 2);
CHECK(cfe4({3, 2}) == 1);
CHECK(cfe4({3, 3}) == 2);

CHECK(cfe4({0 + 4, 0}) == 0);
CHECK(cfe4({0 + 4, 1}) == 3);
CHECK(cfe4({0 + 4, 2}) == 0);
CHECK(cfe4({0 + 4, 3}) == 3);
CHECK(cfe4({1 + 4, 0}) == 1);
CHECK(cfe4({1 + 4, 1}) == 2);
CHECK(cfe4({1 + 4, 2}) == 1);
CHECK(cfe4({1 + 4, 3}) == 2);
CHECK(cfe4({2 + 4, 0}) == 0);
CHECK(cfe4({2 + 4, 1}) == 3);
CHECK(cfe4({2 + 4, 2}) == 0);
CHECK(cfe4({2 + 4, 3}) == 3);
CHECK(cfe4({3 + 4, 0}) == 1);
CHECK(cfe4({3 + 4, 1}) == 2);
CHECK(cfe4({3 + 4, 2}) == 1);
CHECK(cfe4({3 + 4, 3}) == 2);

CHECK(cfe4({0, 0 + 4}) == 0);
CHECK(cfe4({0, 1 + 4}) == 3);
CHECK(cfe4({0, 2 + 4}) == 0);
CHECK(cfe4({0, 3 + 4}) == 3);
CHECK(cfe4({1, 0 + 4}) == 1);
CHECK(cfe4({1, 1 + 4}) == 2);
CHECK(cfe4({1, 2 + 4}) == 1);
CHECK(cfe4({1, 3 + 4}) == 2);
CHECK(cfe4({2, 0 + 4}) == 0);
CHECK(cfe4({2, 1 + 4}) == 3);
CHECK(cfe4({2, 2 + 4}) == 0);
CHECK(cfe4({2, 3 + 4}) == 3);
CHECK(cfe4({3, 0 + 4}) == 1);
CHECK(cfe4({3, 1 + 4}) == 2);
CHECK(cfe4({3, 2 + 4}) == 1);
CHECK(cfe4({3, 3 + 4}) == 2);

CHECK(cfe4({0 + 4, 0 + 4}) == 0);
CHECK(cfe4({0 + 4, 1 + 4}) == 3);
CHECK(cfe4({0 + 4, 2 + 4}) == 0);
CHECK(cfe4({0 + 4, 3 + 4}) == 3);
CHECK(cfe4({1 + 4, 0 + 4}) == 1);
CHECK(cfe4({1 + 4, 1 + 4}) == 2);
CHECK(cfe4({1 + 4, 2 + 4}) == 1);
CHECK(cfe4({1 + 4, 3 + 4}) == 2);
CHECK(cfe4({2 + 4, 0 + 4}) == 0);
CHECK(cfe4({2 + 4, 1 + 4}) == 3);
CHECK(cfe4({2 + 4, 2 + 4}) == 0);
CHECK(cfe4({2 + 4, 3 + 4}) == 3);
CHECK(cfe4({3 + 4, 0 + 4}) == 1);
CHECK(cfe4({3 + 4, 1 + 4}) == 2);
CHECK(cfe4({3 + 4, 2 + 4}) == 1);
CHECK(cfe4({3 + 4, 3 + 4}) == 2);
}

TEST_CASE("3-phase BANCS", "[clocking-scheme]")
{
using clk_lyt = clocked_layout<cartesian_layout<offset::ucoord_t>>;
Expand Down Expand Up @@ -1847,6 +1927,7 @@ TEST_CASE("Clocking lookup", "[clocking-scheme]")
check({"use", "USE", "uSe", "UsE"}, clock_name::use);
check({"res", "RES", "rEs", "ReS"}, clock_name::res);
check({"esp", "ESP", "eSp", "EsP"}, clock_name::esp);
check({"cfe", "CFE", "cFe", "CfE"}, clock_name::cfe);
check({"bancs", "BANCS", "BaNCs", "banCS"}, clock_name::bancs);

CHECK(!get_clocking_scheme<clk_lyt>("").has_value());
Expand All @@ -1857,6 +1938,7 @@ TEST_CASE("Clocking lookup", "[clocking-scheme]")
CHECK(!get_clocking_scheme<clk_lyt>("SUE").has_value());
CHECK(!get_clocking_scheme<clk_lyt>("ERS").has_value());
CHECK(!get_clocking_scheme<clk_lyt>("EPS").has_value());
CHECK(!get_clocking_scheme<clk_lyt>("CEF").has_value());
CHECK(!get_clocking_scheme<clk_lyt>("BNCS").has_value());
}

Expand All @@ -1872,6 +1954,7 @@ TEST_CASE("Linear schemes", "[clocking-scheme]")
CHECK(!is_linear_scheme<clk_lyt>(*get_clocking_scheme<clk_lyt>(clock_name::open)));
CHECK(!is_linear_scheme<clk_lyt>(*get_clocking_scheme<clk_lyt>(clock_name::use)));
CHECK(!is_linear_scheme<clk_lyt>(*get_clocking_scheme<clk_lyt>(clock_name::res)));
CHECK(!is_linear_scheme<clk_lyt>(*get_clocking_scheme<clk_lyt>(clock_name::bancs)));
CHECK(!is_linear_scheme<clk_lyt>(*get_clocking_scheme<clk_lyt>(clock_name::esp)));
CHECK(!is_linear_scheme<clk_lyt>(*get_clocking_scheme<clk_lyt>(clock_name::cfe)));
CHECK(!is_linear_scheme<clk_lyt>(*get_clocking_scheme<clk_lyt>(clock_name::bancs)));
}

0 comments on commit 94d3eeb

Please sign in to comment.