[core] code complete for upgrading netlist generator w.r.t. ccff v2
This commit is contained in:
parent
5500b9a289
commit
592765af48
|
@ -26,10 +26,14 @@ CircuitModelId ConfigProtocol::memory_model() const { return memory_model_; }
|
|||
|
||||
int ConfigProtocol::num_regions() const { return num_regions_; }
|
||||
|
||||
std::vector<openfpga::BasicPort> ConfigProtocol::prog_clock_ports() const {
|
||||
std::vector<openfpga::BasicPort> ConfigProtocol::prog_clock_port_info() const {
|
||||
return prog_clk_port_;
|
||||
}
|
||||
|
||||
std::vector<openfpga::BasicPort> ConfigProtocol::prog_clock_pins() const {
|
||||
std::vector<openfpga::BasicPort> keys;
|
||||
for (const auto& [k, v] : prog_clk_ccff_head_indices_) {
|
||||
keys.push_back(k);
|
||||
for (auto pin : prog_clk_port_.pins()) {
|
||||
keys.push_back(openfpga::BasicPort(prog_clk_port_.get_name(), pin, pin));
|
||||
}
|
||||
return keys;
|
||||
}
|
||||
|
@ -52,11 +56,15 @@ std::string ConfigProtocol::prog_clock_port_ccff_head_indices_str(
|
|||
std::vector<size_t> ConfigProtocol::prog_clock_port_ccff_head_indices(
|
||||
const openfpga::BasicPort& port) const {
|
||||
std::vector<size_t> ret;
|
||||
auto result = prog_clk_ccff_head_indices_.find(port);
|
||||
if (result != prog_clk_ccff_head_indices_.end()) {
|
||||
return result->second;
|
||||
if (port.get_width() != 1) {
|
||||
VTR_LOG_ERROR("The programming clock pin must have a width of 1 while the width specified is %ld!\n", port.get_width());
|
||||
}
|
||||
return ret;
|
||||
VTR_ASSERT(port.get_width == 1);
|
||||
if (!prog_clk_port_.contained(port)) {
|
||||
VTR_LOG_ERROR("The programming clock pin '%s[%ld]' is not out of the range [%ld, %ld]!\n", port.get_name().c_str(), port.get_lsb(), prog_clk_port_.get_lsb(), prog_clk_port_.get_msb());
|
||||
}
|
||||
VTR_ASSERT(prog_clk_port_.contained(port));
|
||||
return prog_clk_ccff_head_indices_[port.get_lsb()];
|
||||
}
|
||||
|
||||
e_blwl_protocol_type ConfigProtocol::bl_protocol_type() const {
|
||||
|
@ -107,6 +115,11 @@ void ConfigProtocol::set_num_regions(const int& num_regions) {
|
|||
num_regions_ = num_regions;
|
||||
}
|
||||
|
||||
void ConfigProtocol::set_prog_clock(const openfpga::BasicPort& port) {
|
||||
prog_clk_port_ = port;
|
||||
prog_clk_ccff_head_indices_.resize(prog_clk_port_.get_width());
|
||||
}
|
||||
|
||||
void ConfigProtocol::set_prog_clock_port_ccff_head_indices_pair(
|
||||
const openfpga::BasicPort& port, const std::string& indices_str) {
|
||||
openfpga::StringToken tokenizer(indices_str);
|
||||
|
@ -115,15 +128,22 @@ void ConfigProtocol::set_prog_clock_port_ccff_head_indices_pair(
|
|||
for (std::string token : tokenizer.split(INDICE_STRING_DELIM_)) {
|
||||
token_int.push_back(std::stoi(token));
|
||||
}
|
||||
auto result = prog_clk_ccff_head_indices_.find(port);
|
||||
if (result != prog_clk_ccff_head_indices_.end()) {
|
||||
if (port.get_width() != 1) {
|
||||
VTR_LOG_ERROR("The programming clock pin must have a width of 1 while the width specified is %ld!\n", port.get_width());
|
||||
}
|
||||
VTR_ASSERT(port.get_width == 1);
|
||||
if (!prog_clk_port_.contained(port)) {
|
||||
VTR_LOG_ERROR("The programming clock pin '%s[%ld]' is not out of the range [%ld, %ld]!\n", port.get_name().c_str(), port.get_lsb(), prog_clk_port_.get_lsb(), prog_clk_port_.get_msb());
|
||||
}
|
||||
VTR_ASSERT(prog_clk_port_.contained(port));
|
||||
if (!prog_clk_ccff_head_indices_[port.get_lsb()].empty()) {
|
||||
VTR_LOG_WARN(
|
||||
"Overwrite the pair between programming clock port '%s[%d:%d]' and ccff "
|
||||
"head indices (previous: '%s', current: '%s')!\n",
|
||||
port.get_name().c_str(), port.get_lsb(), port.get_msb(),
|
||||
prog_clock_port_ccff_head_indices_str(port).c_str(), indices_str.c_str());
|
||||
}
|
||||
prog_clk_ccff_head_indices_[port] = token_int;
|
||||
prog_clk_ccff_head_indices_[port.get_lsb()] = token_int;
|
||||
}
|
||||
|
||||
void ConfigProtocol::set_bl_protocol_type(const e_blwl_protocol_type& type) {
|
||||
|
|
|
@ -181,11 +181,39 @@ static void read_xml_config_organization(pugi::xml_node& xml_config_orgz,
|
|||
|
||||
/* Parse Configuration chain protocols */
|
||||
if (config_protocol.type() == CONFIG_MEM_SCAN_CHAIN) {
|
||||
/* First pass: Get the programming clock port size */
|
||||
openfpga::BasicPort prog_clk_port;
|
||||
for (pugi::xml_node xml_progclk : xml_config_orgz.children()) {
|
||||
/* Error out if the XML child has an invalid name! */
|
||||
if (xml_progclk.name() !=
|
||||
std::string(XML_CONFIG_PROTOCOL_CCFF_PROG_CLOCK_NODE_NAME)) {
|
||||
bad_tag(xml_progclk, loc_data, xml_config_orgz, {"programming_clock"});
|
||||
bad_tag(xml_progclk, loc_data, xml_config_orgz, {XML_CONFIG_PROTOCOL_CCFF_PROG_CLOCK_NODE_NAME});
|
||||
}
|
||||
std::string port_attr =
|
||||
get_attribute(xml_progclk, XML_CONFIG_PROTOCOL_CCFF_PROG_CLOCK_PORT_ATTR,
|
||||
loc_data)
|
||||
.as_string();
|
||||
openfpga::BasicPort port = openfpga::PortParser(port_attr).port();
|
||||
if (prog_clk_port.get_name().empty()) {
|
||||
prog_clk_port.set_name(port.get_name());
|
||||
prog_clk_port.set_width(port.get_lsb(), port.get_msb());
|
||||
} else {
|
||||
if (prog_clk_port.get_name() != port.get_name()) {
|
||||
archfpga_throw(loc_data.filename_c_str(), loc_data.line(xml_progclk),
|
||||
"Expect same name for all the programming clocks (This: %s, Others: %s)!\n", port.get_name().c_str(), prog_clk_port.get_name().c_str());
|
||||
}
|
||||
if (prog_clk_port.get_msb() < port.get_msb()) {
|
||||
prog_clk_port.set_msb(port.get_msb());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Second pass: fill the clock detailed connections */
|
||||
for (pugi::xml_node xml_progclk : xml_config_orgz.children()) {
|
||||
/* Error out if the XML child has an invalid name! */
|
||||
if (xml_progclk.name() !=
|
||||
std::string(XML_CONFIG_PROTOCOL_CCFF_PROG_CLOCK_NODE_NAME)) {
|
||||
bad_tag(xml_progclk, loc_data, xml_config_orgz, {XML_CONFIG_PROTOCOL_CCFF_PROG_CLOCK_NODE_NAME});
|
||||
}
|
||||
read_xml_ccff_prog_clock(xml_progclk, loc_data, config_protocol);
|
||||
}
|
||||
|
|
|
@ -1269,4 +1269,50 @@ int add_top_module_global_ports_from_grid_modules(
|
|||
return status;
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
* Build the connection between the programming clock port at the top module and each configurable children
|
||||
* Note that each programming clock pin drive one or more configuration regions
|
||||
* For example:
|
||||
* - pin[0] -> region 0, 1
|
||||
* - pin[1] -> region 2, 3
|
||||
*******************************************************************/
|
||||
void add_top_module_nets_prog_clock(ModuleManager& module_manager,
|
||||
const ModuleId& top_module,
|
||||
const ModulePortId& src_port,
|
||||
const ConfigProtocol& config_protocol) {
|
||||
BasicPort src_port_info = module_manager.module_port(top_module, src_port);
|
||||
for (size_t pin : src_port_info.pins()) {
|
||||
/* Create the net */
|
||||
ModuleNetId net = create_module_source_pin_net(
|
||||
module_manager, top_module, top_module, 0,
|
||||
src_port, src_port_info.pins()[pin_id]);
|
||||
/* Find all the sink nodes and build the connection one by one */
|
||||
for (size_t iregion : config_protocol.prog_clock_port_ccff_head_indices(BasicPort(src_port_info.get_name(), pin, pin))) {
|
||||
ConfigRegionId config_region = ConfigRegionId(iregion);
|
||||
for (size_t mem_index = 0; mem_index < module_manager
|
||||
.region_configurable_children(
|
||||
top_module, config_region)
|
||||
.size();
|
||||
++mem_index) {
|
||||
ModuleId net_sink_module_id = module_manager.region_configurable_children(
|
||||
top_module, config_region)[mem_index];
|
||||
size_t net_sink_instance_id =
|
||||
module_manager.region_configurable_child_instances(
|
||||
top_module, config_region)[mem_index];
|
||||
ModulePortId net_sink_port_id =
|
||||
module_manager.find_module_port(net_sink_module_id, src_port_info.get_name());
|
||||
BasicPort net_sink_port =
|
||||
module_manager.module_port(net_sink_module_id, net_sink_port_id);
|
||||
VTR_ASSERT(1 == net_sink_port.get_width());
|
||||
for (size_t net_sink_pin_id : net_sink_port.pins()) {
|
||||
/* Add net sink */
|
||||
module_manager.add_module_net_sink(top_module, net, net_sink_module_id,
|
||||
net_sink_instance_id, net_sink_port_id,
|
||||
net_sink_port.pins()[net_sink_pin_id])
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} /* end namespace openfpga */
|
||||
|
|
|
@ -41,6 +41,8 @@ int add_top_module_global_ports_from_grid_modules(
|
|||
const vtr::Matrix<size_t>& grid_instance_ids, const ClockNetwork& clk_ntwk,
|
||||
const RRClockSpatialLookup& rr_clock_lookup);
|
||||
|
||||
void add_top_module_nets_prog_clock(ModuleManager& module_manager, const ModuleId& top_module, const ModulePortId& src_port, const ConfigProtocol& config_protocol);
|
||||
|
||||
} /* end namespace openfpga */
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue