| /* | 
 |  * Copyright (C) 2017-2020  The Project X-Ray Authors. | 
 |  * | 
 |  * Use of this source code is governed by a ISC-style | 
 |  * license that can be found in the LICENSE file or at | 
 |  * https://opensource.org/licenses/ISC | 
 |  * | 
 |  * SPDX-License-Identifier: ISC | 
 |  */ | 
 | #include <prjxray/xilinx/xc7series/configuration_bus.h> | 
 |  | 
 | #include <iostream> | 
 |  | 
 | namespace prjxray { | 
 | namespace xilinx { | 
 | namespace xc7series { | 
 |  | 
 | bool ConfigurationBus::IsValidFrameAddress(FrameAddress address) const { | 
 | 	auto addr_column = configuration_columns_.find(address.column()); | 
 | 	if (addr_column == configuration_columns_.end()) | 
 | 		return false; | 
 |  | 
 | 	return addr_column->second.IsValidFrameAddress(address); | 
 | } | 
 |  | 
 | absl::optional<FrameAddress> ConfigurationBus::GetNextFrameAddress( | 
 |     FrameAddress address) const { | 
 | 	// Find the column for the current address. | 
 | 	auto addr_column = configuration_columns_.find(address.column()); | 
 |  | 
 | 	// If the current address isn't in a known column, no way to know the | 
 | 	// next address. | 
 | 	if (addr_column == configuration_columns_.end()) | 
 | 		return {}; | 
 |  | 
 | 	// Ask the column for the next address. | 
 | 	absl::optional<FrameAddress> next_address = | 
 | 	    addr_column->second.GetNextFrameAddress(address); | 
 | 	if (next_address) | 
 | 		return next_address; | 
 |  | 
 | 	// The current column doesn't know what the next address is.  Assume | 
 | 	// that the next valid address is the beginning of the next column. | 
 | 	if (++addr_column != configuration_columns_.end()) { | 
 | 		auto next_address = FrameAddress( | 
 | 		    address.block_type(), address.is_bottom_half_rows(), | 
 | 		    address.row(), addr_column->first, 0); | 
 | 		if (addr_column->second.IsValidFrameAddress(next_address)) | 
 | 			return next_address; | 
 | 	} | 
 |  | 
 | 	// Not in this bus. | 
 | 	return {}; | 
 | } | 
 |  | 
 | }  // namespace xc7series | 
 | }  // namespace xilinx | 
 | }  // namespace prjxray | 
 |  | 
 | namespace xc7series = prjxray::xilinx::xc7series; | 
 |  | 
 | namespace YAML { | 
 |  | 
 | Node convert<xc7series::ConfigurationBus>::encode( | 
 |     const xc7series::ConfigurationBus& rhs) { | 
 | 	Node node; | 
 | 	node.SetTag("xilinx/xc7series/configuration_bus"); | 
 | 	node["configuration_columns"] = rhs.configuration_columns_; | 
 | 	return node; | 
 | } | 
 |  | 
 | bool convert<xc7series::ConfigurationBus>::decode( | 
 |     const Node& node, | 
 |     xc7series::ConfigurationBus& lhs) { | 
 | 	if (!node.Tag().empty() && | 
 | 	    node.Tag() != "xilinx/xc7series/configuration_bus") { | 
 | 		return false; | 
 | 	} | 
 |  | 
 | 	lhs.configuration_columns_ = | 
 | 	    node["configuration_columns"] | 
 | 	        .as<std::map<unsigned int, xc7series::ConfigurationColumn>>(); | 
 | 	return true; | 
 | } | 
 |  | 
 | }  // namespace YAML |