diff options
-rw-r--r-- | CMakeLists.txt | 10 | ||||
-rw-r--r-- | common/command.cc | 5 | ||||
-rw-r--r-- | common/timing.cc | 32 | ||||
-rw-r--r-- | ecp5/bitstream.cc | 19 |
4 files changed, 46 insertions, 20 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index c1d9f1a6..9bd85194 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -18,9 +18,11 @@ set(link_param "") if (STATIC_BUILD) set(Boost_USE_STATIC_LIBS ON) if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") - elseif(${CMAKE_SYSTEM_NAME} MATCHES "Windows" AND MSVC) - set(CMAKE_CXX_FLAGS_RELEASE "/MT") - set(CMAKE_CXX_FLAGS_DEBUG "/MTd") + elseif(${CMAKE_SYSTEM_NAME} MATCHES "Windows") + if (MSVC) + set(CMAKE_CXX_FLAGS_RELEASE "/MT") + set(CMAKE_CXX_FLAGS_DEBUG "/MTd") + endif() if (BUILD_PYTHON) add_definitions(-DBOOST_PYTHON_STATIC_LIB) endif() @@ -285,7 +287,7 @@ foreach (family ${ARCH}) if (STATIC_BUILD) target_link_libraries(${target} LINK_PUBLIC ${CMAKE_THREAD_LIBS_INIT} ${CMAKE_DL_LIBS} ${ZLIB_LIBRARIES} ${EXPAT_LIBRARIES}) if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") - elseif(${CMAKE_SYSTEM_NAME} MATCHES "Windows" AND MSVC) + elseif(${CMAKE_SYSTEM_NAME} MATCHES "Windows") else() target_link_libraries(${target} LINK_PUBLIC -lutil) endif() diff --git a/common/command.cc b/common/command.cc index a7a19989..3dc0d968 100644 --- a/common/command.cc +++ b/common/command.cc @@ -123,6 +123,7 @@ po::options_description CommandHandler::getGeneralOptions() #endif general.add_options()("json", po::value<std::string>(), "JSON design file to ingest"); general.add_options()("write", po::value<std::string>(), "JSON design file to write"); + general.add_options()("top", po::value<std::string>(), "name of top module"); general.add_options()("seed", po::value<int>(), "seed value for random number generator"); general.add_options()("randomize-seed,r", "randomize seed value for random number generator"); @@ -277,6 +278,10 @@ int CommandHandler::executeMain(std::unique_ptr<Context> ctx) return 0; } + if (vm.count("top")) { + ctx->settings[ctx->id("frontend/top")] = vm["top"].as<std::string>(); + } + #ifndef NO_GUI if (vm.count("gui")) { Application a(argc, argv, (vm.count("gui-no-aa") > 0)); diff --git a/common/timing.cc b/common/timing.cc index ae9a95fe..40cbb36e 100644 --- a/common/timing.cc +++ b/common/timing.cc @@ -123,9 +123,9 @@ struct Timing { const auto clk_period = ctx->getDelayFromNS(1.0e9 / ctx->setting<float>("target_freq")).maxDelay(); - // First, compute the topographical order of nets to walk through the circuit, assuming it is a _acyclic_ graph + // First, compute the topological order of nets to walk through the circuit, assuming it is a _acyclic_ graph // TODO(eddieh): Handle the case where it is cyclic, e.g. combinatorial loops - std::vector<NetInfo *> topographical_order; + std::vector<NetInfo *> topological_order; std::unordered_map<const NetInfo *, std::unordered_map<ClockEvent, TimingData>> net_data; // In lieu of deleting edges from the graph, simply count the number of fanins to each output port std::unordered_map<const PortInfo *, unsigned> port_fanin; @@ -150,7 +150,7 @@ struct Timing // If output port is influenced by a clock (e.g. FF output) then add it to the ordering as a timing // start-point if (portClass == TMG_REGISTER_OUTPUT) { - topographical_order.emplace_back(o->net); + topological_order.emplace_back(o->net); for (int i = 0; i < clocks; i++) { TimingClockingInfo clkInfo = ctx->getPortClockingInfo(cell.second.get(), o->name, i); const NetInfo *clknet = get_net_or_empty(cell.second.get(), clkInfo.clock_port); @@ -161,7 +161,7 @@ struct Timing } else { if (portClass == TMG_STARTPOINT || portClass == TMG_GEN_CLOCK || portClass == TMG_IGNORE) { - topographical_order.emplace_back(o->net); + topological_order.emplace_back(o->net); TimingData td; td.false_startpoint = (portClass == TMG_GEN_CLOCK || portClass == TMG_IGNORE); td.max_arrival = 0; @@ -185,7 +185,7 @@ struct Timing } // If there is no fanin, add the port as a false startpoint if (!port_fanin.count(o) && !net_data.count(o->net)) { - topographical_order.emplace_back(o->net); + topological_order.emplace_back(o->net); TimingData td; td.false_startpoint = true; td.max_arrival = 0; @@ -200,12 +200,12 @@ struct Timing for (auto &p : ctx->ports) { if (p.second.type != PORT_IN || p.second.net == nullptr) continue; - topographical_order.emplace_back(p.second.net); + topological_order.emplace_back(p.second.net); } } - std::deque<NetInfo *> queue(topographical_order.begin(), topographical_order.end()); - // Now walk the design, from the start points identified previously, building up a topographical order + std::deque<NetInfo *> queue(topological_order.begin(), topological_order.end()); + // Now walk the design, from the start points identified previously, building up a topological order while (!queue.empty()) { const auto net = queue.front(); queue.pop_front(); @@ -229,12 +229,12 @@ struct Timing bool is_path = ctx->getCellDelay(usr.cell, usr.port, port.first, comb_delay); if (!is_path) continue; - // Decrement the fanin count, and only add to topographical order if all its fanins have already + // Decrement the fanin count, and only add to topological order if all its fanins have already // been visited auto it = port_fanin.find(&port.second); NPNR_ASSERT(it != port_fanin.end()); if (--it->second == 0) { - topographical_order.emplace_back(port.second.net); + topological_order.emplace_back(port.second.net); queue.emplace_back(port.second.net); port_fanin.erase(it); } @@ -266,8 +266,8 @@ struct Timing "timing ports, etc.\n"); } - // Go forwards topographically to find the maximum arrival time and max path length for each net - for (auto net : topographical_order) { + // Go forwards topologically to find the maximum arrival time and max path length for each net + for (auto net : topological_order) { if (!net_data.count(net)) continue; auto &nd_map = net_data.at(net); @@ -314,9 +314,9 @@ struct Timing std::unordered_map<ClockPair, std::pair<delay_t, NetInfo *>> crit_nets; - // Now go backwards topographically to determine the minimum path slack, and to distribute all path slack evenly + // Now go backwards topologically to determine the minimum path slack, and to distribute all path slack evenly // between all nets on the path - for (auto net : boost::adaptors::reverse(topographical_order)) { + for (auto net : boost::adaptors::reverse(topological_order)) { if (!net_data.count(net)) continue; auto &nd_map = net_data.at(net); @@ -482,8 +482,8 @@ struct Timing if (net_crit) { NPNR_ASSERT(crit_path); - // Go through in reverse topographical order to set required times - for (auto net : boost::adaptors::reverse(topographical_order)) { + // Go through in reverse topological order to set required times + for (auto net : boost::adaptors::reverse(topological_order)) { if (!net_data.count(net)) continue; auto &nd_map = net_data.at(net); diff --git a/ecp5/bitstream.cc b/ecp5/bitstream.cc index dbab920b..542ee6ca 100644 --- a/ecp5/bitstream.cc +++ b/ecp5/bitstream.cc @@ -915,6 +915,25 @@ void write_bitstream(Context *ctx, std::string base_config_file, std::string tex static bool drive_3v3_warning_done = false; if (iotype == "LVCMOS33") { cc.tiles[pio_tile].add_enum(pio + ".DRIVE", str_or_default(ci->attrs, ctx->id("DRIVE"), "8")); + } else if (iotype == "LVCMOS33D") { + if (bel.location.y == 0) { + // Pseudo differential top IO + NPNR_ASSERT(dir == "OUTPUT"); + NPNR_ASSERT(pio == "PIOA"); + std::string cpio_tile = get_comp_pio_tile(ctx, bel); + cc.tiles[pio_tile].add_enum("PIOA.DRIVE", str_or_default(ci->attrs, ctx->id("DRIVE"), "12")); + cc.tiles[cpio_tile].add_enum("PIOB.DRIVE", str_or_default(ci->attrs, ctx->id("DRIVE"), "12")); + } else { + std::string other; + if (pio == "PIOA") + other = "PIOB"; + else if (pio == "PIOC") + other = "PIOD"; + else + log_error("cannot set DRIVE on differential IO at location %s\n", pio.c_str()); + cc.tiles[pio_tile].add_enum(pio + ".DRIVE", str_or_default(ci->attrs, ctx->id("DRIVE"), "12")); + cc.tiles[pio_tile].add_enum(other + ".DRIVE", str_or_default(ci->attrs, ctx->id("DRIVE"), "12")); + } } else { if (!drive_3v3_warning_done) log_warning("Trellis limitation: DRIVE can only be set on 3V3 IO pins.\n"); |