[core] code complete for upgrading netlist generator w.r.t. ccff v2

This commit is contained in:
tangxifan 2023-04-23 13:57:37 +08:00
parent 5500b9a289
commit 592765af48
4 changed files with 107 additions and 11 deletions

View File

@ -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) {

View File

@ -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);
}

View File

@ -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 */

View File

@ -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