From 27eb3be7dae5038099aab8299e0f1d9d675fd855 Mon Sep 17 00:00:00 2001 From: gatecat Date: Sun, 9 May 2021 19:48:04 +0100 Subject: [PATCH] mistral: Add stub RBF generation Signed-off-by: gatecat --- mistral/arch.h | 1 + mistral/base_bitstream.cc | 18 +++++---- mistral/bitstream.cc | 84 +++++++++++++++++++++++++++++++++++++++ mistral/main.cc | 14 ++++++- 4 files changed, 108 insertions(+), 9 deletions(-) create mode 100644 mistral/bitstream.cc diff --git a/mistral/arch.h b/mistral/arch.h index 24b45938..e22d26fd 100644 --- a/mistral/arch.h +++ b/mistral/arch.h @@ -483,6 +483,7 @@ struct Arch : BaseArch // ------------------------------------------------- void init_base_bitstream(); // base_bitstream.cc + void build_bitstream(); // bitstream.cc }; NEXTPNR_NAMESPACE_END diff --git a/mistral/base_bitstream.cc b/mistral/base_bitstream.cc index 95199b18..bf85c6b9 100644 --- a/mistral/base_bitstream.cc +++ b/mistral/base_bitstream.cc @@ -33,15 +33,17 @@ void default_sx120f(CycloneV *cv) cv->bmux_m_set(CycloneV::PMA3, CycloneV::xy2pos(0, 23), CycloneV::FFPLL_IQCLK_DIRECTION, 1, CycloneV::UP); cv->bmux_m_set(CycloneV::PMA3, CycloneV::xy2pos(0, 35), CycloneV::FFPLL_IQCLK_DIRECTION, 0, CycloneV::UP); cv->bmux_m_set(CycloneV::PMA3, CycloneV::xy2pos(0, 35), CycloneV::FFPLL_IQCLK_DIRECTION, 1, CycloneV::UP); - cv->bmux_b_set(CycloneV::PMA3, CycloneV::xy2pos(0, 35), CycloneV::FPLL_DRV_EN, -1, false); - cv->bmux_m_set(CycloneV::PMA3, CycloneV::xy2pos(0, 35), CycloneV::HCLK_TOP_OUT_DRIVER, -1, CycloneV::TRISTATE); + cv->bmux_b_set(CycloneV::PMA3, CycloneV::xy2pos(0, 35), CycloneV::FPLL_DRV_EN, 0, 0); + cv->bmux_m_set(CycloneV::PMA3, CycloneV::xy2pos(0, 35), CycloneV::HCLK_TOP_OUT_DRIVER, 0, CycloneV::TRISTATE); // Default PLL config - cv->bmux_b_set(CycloneV::FPLL, CycloneV::xy2pos(0, 73), CycloneV::PL_AUX_ATB_EN0, -1, true); - cv->bmux_b_set(CycloneV::FPLL, CycloneV::xy2pos(0, 73), CycloneV::PL_AUX_ATB_EN0_PRECOMP, -1, true); - cv->bmux_b_set(CycloneV::FPLL, CycloneV::xy2pos(0, 73), CycloneV::PL_AUX_ATB_EN1, -1, true); - cv->bmux_b_set(CycloneV::FPLL, CycloneV::xy2pos(0, 73), CycloneV::PL_AUX_ATB_EN1_PRECOMP, -1, true); - cv->bmux_b_set(CycloneV::FPLL, CycloneV::xy2pos(0, 73), CycloneV::PL_AUX_BG_KICKSTART, -1, true); - cv->bmux_b_set(CycloneV::FPLL, CycloneV::xy2pos(0, 73), CycloneV::PL_AUX_VBGMON_POWERDOWN, -1, true); + cv->bmux_b_set(CycloneV::FPLL, CycloneV::xy2pos(0, 73), CycloneV::PL_AUX_ATB_EN0, 0, 1); + cv->bmux_b_set(CycloneV::FPLL, CycloneV::xy2pos(0, 73), CycloneV::PL_AUX_ATB_EN0_PRECOMP, 0, 1); + cv->bmux_b_set(CycloneV::FPLL, CycloneV::xy2pos(0, 73), CycloneV::PL_AUX_ATB_EN1, 0, 1); + cv->bmux_b_set(CycloneV::FPLL, CycloneV::xy2pos(0, 73), CycloneV::PL_AUX_ATB_EN1_PRECOMP, 0, 1); + cv->bmux_b_set(CycloneV::FPLL, CycloneV::xy2pos(0, 73), CycloneV::PL_AUX_BG_KICKSTART, 0, 1); + cv->bmux_b_set(CycloneV::FPLL, CycloneV::xy2pos(0, 73), CycloneV::PL_AUX_VBGMON_POWERDOWN, 0, 1); + // Default TERM config + cv->bmux_b_set(CycloneV::TERM, CycloneV::xy2pos(89, 34), CycloneV::INTOSC_2_EN, 0, 0); // Discover these mux values using // grep 'i [_A-Z0-9.]* 1' empty.bt diff --git a/mistral/bitstream.cc b/mistral/bitstream.cc new file mode 100644 index 00000000..9ed3a161 --- /dev/null +++ b/mistral/bitstream.cc @@ -0,0 +1,84 @@ +/* + * nextpnr -- Next Generation Place and Route + * + * Copyright (C) 2021 gatecat + * + * 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 "log.h" +#include "nextpnr.h" +#include "util.h" + +NEXTPNR_NAMESPACE_BEGIN +namespace { +struct MistralBitgen +{ + MistralBitgen(Context *ctx) : ctx(ctx), cv(ctx->cyclonev){}; + Context *ctx; + CycloneV *cv; + + void init() + { + ctx->init_base_bitstream(); + // Default options + cv->opt_b_set(CycloneV::ALLOW_DEVICE_WIDE_OUTPUT_ENABLE_DIS, true); + cv->opt_n_set(CycloneV::CRC_DIVIDE_ORDER, 8); + cv->opt_b_set(CycloneV::CVP_CONF_DONE_EN, true); + cv->opt_b_set(CycloneV::DEVICE_WIDE_RESET_EN, true); + cv->opt_n_set(CycloneV::DRIVE_STRENGTH, 8); + cv->opt_b_set(CycloneV::IOCSR_READY_FROM_CSR_DONE_EN, true); + cv->opt_b_set(CycloneV::NCEO_DIS, true); + cv->opt_b_set(CycloneV::OCT_DONE_DIS, true); + cv->opt_r_set(CycloneV::OPT_A, 0x1dff); + cv->opt_r_set(CycloneV::OPT_B, 0xffffff402dffffffULL); + cv->opt_b_set(CycloneV::RELEASE_CLEARS_BEFORE_TRISTATES_DIS, true); + cv->opt_b_set(CycloneV::RETRY_CONFIG_ON_ERROR_EN, true); + cv->opt_r_set(CycloneV::START_UP_CLOCK, 0x3F); + } + + void write_routing() + { + for (auto net : sorted(ctx->nets)) { + NetInfo *ni = net.second; + for (auto wire : sorted_ref(ni->wires)) { + PipId pip = wire.second.pip; + if (pip == PipId()) + continue; + WireId src = ctx->getPipSrcWire(pip), dst = ctx->getPipDstWire(pip); + // Only write out routes that are entirely in the Mistral domain. Everything else is dealt with + // specially + if (src.is_nextpnr_created() || dst.is_nextpnr_created()) + continue; + cv->rnode_link(src.node, dst.node); + } + } + } + + void run() + { + cv->clear(); + init(); + write_routing(); + } +}; +} // namespace + +void Arch::build_bitstream() +{ + MistralBitgen gen(getCtx()); + gen.run(); +} + +NEXTPNR_NAMESPACE_END diff --git a/mistral/main.cc b/mistral/main.cc index d5816693..9147a68b 100644 --- a/mistral/main.cc +++ b/mistral/main.cc @@ -50,12 +50,24 @@ po::options_description MistralCommandHandler::getArchOptions() specific.add_options()("mistral", po::value(), "path to mistral root"); specific.add_options()("device", po::value(), "device name (e.g. 5CSEBA6U23I7)"); specific.add_options()("qsf", po::value(), "path to QSF constraints file"); + specific.add_options()("rbf", po::value(), "RBF bitstream to write"); + return specific; } void MistralCommandHandler::customBitstream(Context *ctx) { - // TODO: rbf gen via mistral + if (vm.count("rbf")) { + std::string filename = vm["rbf"].as(); + ctx->build_bitstream(); + std::vector data; + ctx->cyclonev->rbf_save(data); + + std::ofstream out(filename, std::ios::binary); + if (!out) + log_error("Failed to open output RBF file %s.\n", filename.c_str()); + out.write(reinterpret_cast(data.data()), data.size()); + } } std::unique_ptr MistralCommandHandler::createContext(std::unordered_map &values)