bug fixing in memory module generation; some work should be done to merge nets and uniquifying nets!!!

This commit is contained in:
tangxifan 2019-11-04 18:05:50 -07:00
parent 69bc858e62
commit 5d507ae8ee
6 changed files with 159 additions and 15 deletions

View File

@ -304,6 +304,35 @@ bool module_net_is_local_wire(const ModuleManager& module_manager,
return true; return true;
} }
/********************************************************************
* Identify if a net is an output short connection inside a module:
* The short connection is defined as the direct connection
* between two outputs port of the module
*
* module
* +-----------------------------+
* |
* src------>+--------------->|--->outputA
* | |
* | |
* +--------------->|--->outputB
* +-----------------------------+
*******************************************************************/
bool module_net_include_output_short_connection(const ModuleManager& module_manager,
const ModuleId& module_id, const ModuleNetId& module_net) {
/* Check all the sink modules of the net */
size_t contain_num_module_output = 0;
for (ModuleId sink_module : module_manager.net_sink_modules(module_id, module_net)) {
if (module_id == sink_module) {
contain_num_module_output++;
}
}
/* If we have found more than 1 module outputs, it indicated output short connection! */
return (1 < contain_num_module_output);
}
/******************************************************************** /********************************************************************
* Identify if a net is a local short connection inside a module: * Identify if a net is a local short connection inside a module:
* The short connection is defined as the direct connection * The short connection is defined as the direct connection

View File

@ -50,6 +50,9 @@ void add_pb_type_ports_to_module_manager(ModuleManager& module_manager,
bool module_net_is_local_wire(const ModuleManager& module_manager, bool module_net_is_local_wire(const ModuleManager& module_manager,
const ModuleId& module_id, const ModuleNetId& module_net); const ModuleId& module_id, const ModuleNetId& module_net);
bool module_net_include_output_short_connection(const ModuleManager& module_manager,
const ModuleId& module_id, const ModuleNetId& module_net);
bool module_net_include_local_short_connection(const ModuleManager& module_manager, bool module_net_include_local_short_connection(const ModuleManager& module_manager,
const ModuleId& module_id, const ModuleNetId& module_net); const ModuleId& module_id, const ModuleNetId& module_net);

View File

@ -106,16 +106,20 @@ void add_module_output_nets_to_mem_modules(ModuleManager& module_manager,
* j-th pin of output port of the i-th child module is wired to the j + i*W -th * j-th pin of output port of the i-th child module is wired to the j + i*W -th
* pin of output port of the memory module, where W is the size of port * pin of output port of the memory module, where W is the size of port
* 3. It assumes fixed port name for output ports * 3. It assumes fixed port name for output ports
*
* We cache the module nets that have been created because they will be used later
********************************************************************/ ********************************************************************/
static static
void add_module_output_nets_to_chain_mem_modules(ModuleManager& module_manager, std::vector<ModuleNetId> add_module_output_nets_to_chain_mem_modules(ModuleManager& module_manager,
const ModuleId& mem_module, const ModuleId& mem_module,
const std::string& mem_module_output_name, const std::string& mem_module_output_name,
const CircuitLibrary& circuit_lib, const CircuitLibrary& circuit_lib,
const CircuitPortId& circuit_port, const CircuitPortId& circuit_port,
const ModuleId& child_module, const ModuleId& child_module,
const size_t& child_index, const size_t& child_index,
const size_t& child_instance) { const size_t& child_instance) {
std::vector<ModuleNetId> module_nets;
/* Wire inputs of parent module to inputs of child modules */ /* Wire inputs of parent module to inputs of child modules */
ModulePortId src_port_id = module_manager.find_module_port(child_module, circuit_lib.port_lib_name(circuit_port)); ModulePortId src_port_id = module_manager.find_module_port(child_module, circuit_lib.port_lib_name(circuit_port));
ModulePortId sink_port_id = module_manager.find_module_port(mem_module, mem_module_output_name); ModulePortId sink_port_id = module_manager.find_module_port(mem_module, mem_module_output_name);
@ -128,7 +132,12 @@ void add_module_output_nets_to_chain_mem_modules(ModuleManager& module_manager,
/* Sink node of the input net is the input of sram module */ /* Sink node of the input net is the input of sram module */
size_t sink_pin_id = child_index * circuit_lib.port_size(circuit_port) + module_manager.module_port(mem_module, sink_port_id).pins()[pin_id]; size_t sink_pin_id = child_index * circuit_lib.port_size(circuit_port) + module_manager.module_port(mem_module, sink_port_id).pins()[pin_id];
module_manager.add_module_net_sink(mem_module, net, mem_module, 0, sink_port_id, sink_pin_id); module_manager.add_module_net_sink(mem_module, net, mem_module, 0, sink_port_id, sink_pin_id);
/* Cache the nets */
module_nets.push_back(net);
} }
return module_nets;
} }
/******************************************************************** /********************************************************************
@ -155,9 +164,13 @@ void add_module_output_nets_to_chain_mem_modules(ModuleManager& module_manager,
static static
void add_module_nets_to_cmos_memory_chain_module(ModuleManager& module_manager, void add_module_nets_to_cmos_memory_chain_module(ModuleManager& module_manager,
const ModuleId& parent_module, const ModuleId& parent_module,
const std::vector<ModuleNetId>& output_nets,
const CircuitLibrary& circuit_lib, const CircuitLibrary& circuit_lib,
const CircuitPortId& model_input_port, const CircuitPortId& model_input_port,
const CircuitPortId& model_output_port) { const CircuitPortId& model_output_port) {
/* Counter for the nets */
size_t net_counter = 0;
for (size_t mem_index = 0; mem_index < module_manager.configurable_children(parent_module).size(); ++mem_index) { for (size_t mem_index = 0; mem_index < module_manager.configurable_children(parent_module).size(); ++mem_index) {
ModuleId net_src_module_id; ModuleId net_src_module_id;
size_t net_src_instance_id; size_t net_src_instance_id;
@ -203,11 +216,21 @@ void add_module_nets_to_cmos_memory_chain_module(ModuleManager& module_manager,
/* Create a net for each pin */ /* Create a net for each pin */
for (size_t pin_id = 0; pin_id < net_src_port.pins().size(); ++pin_id) { for (size_t pin_id = 0; pin_id < net_src_port.pins().size(); ++pin_id) {
/* Create a net and add source and sink to it */ /* Create a net and add source and sink to it */
ModuleNetId net = module_manager.create_module_net(parent_module); ModuleNetId net;
if (0 == mem_index) {
net = module_manager.create_module_net(parent_module);
} else {
net = output_nets[net_counter];
}
/* Add net source */ /* Add net source */
module_manager.add_module_net_source(parent_module, net, net_src_module_id, net_src_instance_id, net_src_port_id, net_src_port.pins()[pin_id]); module_manager.add_module_net_source(parent_module, net, net_src_module_id, net_src_instance_id, net_src_port_id, net_src_port.pins()[pin_id]);
/* Add net sink */ /* Add net sink */
module_manager.add_module_net_sink(parent_module, net, net_sink_module_id, net_sink_instance_id, net_sink_port_id, net_sink_port.pins()[pin_id]); module_manager.add_module_net_sink(parent_module, net, net_sink_module_id, net_sink_instance_id, net_sink_port_id, net_sink_port.pins()[pin_id]);
/* Update net counter */
if (0 < mem_index) {
net_counter++;
}
} }
} }
@ -237,12 +260,17 @@ void add_module_nets_to_cmos_memory_chain_module(ModuleManager& module_manager,
/* Create a net for each pin */ /* Create a net for each pin */
for (size_t pin_id = 0; pin_id < net_src_port.pins().size(); ++pin_id) { for (size_t pin_id = 0; pin_id < net_src_port.pins().size(); ++pin_id) {
/* Create a net and add source and sink to it */ /* Create a net and add source and sink to it */
ModuleNetId net = module_manager.create_module_net(parent_module); ModuleNetId net = output_nets[net_counter];
/* Add net source */ /* Add net source */
module_manager.add_module_net_source(parent_module, net, net_src_module_id, net_src_instance_id, net_src_port_id, net_src_port.pins()[pin_id]); module_manager.add_module_net_source(parent_module, net, net_src_module_id, net_src_instance_id, net_src_port_id, net_src_port.pins()[pin_id]);
/* Add net sink */ /* Add net sink */
module_manager.add_module_net_sink(parent_module, net, net_sink_module_id, net_sink_instance_id, net_sink_port_id, net_sink_port.pins()[pin_id]); module_manager.add_module_net_sink(parent_module, net, net_sink_module_id, net_sink_instance_id, net_sink_port_id, net_sink_port.pins()[pin_id]);
/* Update net counter */
net_counter++;
} }
VTR_ASSERT(net_counter == output_nets.size());
} }
/********************************************************************* /*********************************************************************
@ -381,6 +409,9 @@ void build_memory_chain_module(ModuleManager& module_manager,
/* Find the sram module in the module manager */ /* Find the sram module in the module manager */
ModuleId sram_mem_module = module_manager.find_module(circuit_lib.model_name(sram_model)); ModuleId sram_mem_module = module_manager.find_module(circuit_lib.model_name(sram_model));
/* Cache the output nets for non-inverted data output */
std::vector<ModuleNetId> mem_output_nets;
/* Instanciate each submodule */ /* Instanciate each submodule */
for (size_t i = 0; i < num_mems; ++i) { for (size_t i = 0; i < num_mems; ++i) {
size_t sram_mem_instance = module_manager.num_instance(mem_module, sram_mem_module); size_t sram_mem_instance = module_manager.num_instance(mem_module, sram_mem_module);
@ -396,13 +427,18 @@ void build_memory_chain_module(ModuleManager& module_manager,
VTR_ASSERT( 1 == iport); VTR_ASSERT( 1 == iport);
port_name = generate_configuration_chain_inverted_data_out_name(); port_name = generate_configuration_chain_inverted_data_out_name();
} }
add_module_output_nets_to_chain_mem_modules(module_manager, mem_module, port_name, circuit_lib, sram_output_ports[iport], std::vector<ModuleNetId> output_nets = add_module_output_nets_to_chain_mem_modules(module_manager, mem_module,
sram_mem_module, i, sram_mem_instance); port_name, circuit_lib, sram_output_ports[iport],
sram_mem_module, i, sram_mem_instance);
/* Cache only for regular data outputs */
if (0 == iport) {
mem_output_nets.insert(mem_output_nets.end(), output_nets.begin(), output_nets.end());
}
} }
} }
/* Build module nets to wire the configuration chain */ /* Build module nets to wire the configuration chain */
add_module_nets_to_cmos_memory_chain_module(module_manager, mem_module, add_module_nets_to_cmos_memory_chain_module(module_manager, mem_module, mem_output_nets,
circuit_lib, sram_input_ports[0], sram_output_ports[0]); circuit_lib, sram_input_ports[0], sram_output_ports[0]);

View File

@ -113,7 +113,7 @@ void write_include_netlists (char* src_dir_formatted,
top_testbench_verilog_file_postfix); top_testbench_verilog_file_postfix);
fprintf(fp, "`elsif %s\n", autochecked_simulation_flag); fprintf(fp, "`elsif %s\n", autochecked_simulation_flag);
*/ */
fprintf(fp, "`include \"%s%s%s\"\n", src_dir_formatted, fprintf(fp, "\t`include \"%s%s%s\"\n", src_dir_formatted,
chomped_circuit_name, chomped_circuit_name,
autocheck_top_testbench_verilog_file_postfix); autocheck_top_testbench_verilog_file_postfix);
fprintf(fp, "`endif\n"); fprintf(fp, "`endif\n");

View File

@ -169,6 +169,50 @@ std::vector<BasicPort> find_verilog_module_local_wires(const ModuleManager& modu
return local_wires; return local_wires;
} }
/********************************************************************
* Print a Verilog wire connection
* We search all the sinks of the net,
* if we find a module output, we try to find the next module output
* among the sinks of the net
* For each module output (except the first one), we print a wire connection
*******************************************************************/
static
void print_verilog_module_output_short_connection(std::fstream& fp,
const ModuleManager& module_manager,
const ModuleId& module_id,
const ModuleNetId& module_net) {
/* Ensure a valid file stream */
check_file_handler(fp);
bool first_port = true;
BasicPort src_port;
/* We have found a module input, now check all the sink modules of the net */
for (ModuleNetSinkId net_sink : module_manager.module_net_sinks(module_id, module_net)) {
ModuleId sink_module = module_manager.net_sink_modules(module_id, module_net)[net_sink];
if (module_id != sink_module) {
continue;
}
/* Find the sink port and pin information */
ModulePortId sink_port_id = module_manager.net_sink_ports(module_id, module_net)[net_sink];
size_t sink_pin = module_manager.net_sink_pins(module_id, module_net)[net_sink];
BasicPort sink_port(module_manager.module_port(module_id, sink_port_id).get_name(), sink_pin, sink_pin);
/* For the first module output, this is the source port, we do nothing and go to the next */
if (true == first_port) {
src_port = sink_port;
/* Flip the flag */
first_port = false;
continue;
}
/* We need to print a wire connection here */
print_verilog_wire_connection(fp, sink_port, src_port, false);
}
}
/******************************************************************** /********************************************************************
* Print a Verilog wire connection * Print a Verilog wire connection
* We search all the sources of the net, * We search all the sources of the net,
@ -242,6 +286,36 @@ void print_verilog_module_local_short_connections(std::fstream& fp,
} }
} }
/********************************************************************
* Print output short connections inside a Verilog module
* The output short connection is defined as the direct connection
* between two output ports of the module
* This type of connection is not covered when printing Verilog instances
* Therefore, they are covered in this function
*
* module
* +-----------------------------+
* |
* src------>+--------------->|--->outputA
* | |
* | |
* +--------------->|--->outputB
* +-----------------------------+
*******************************************************************/
static
void print_verilog_module_output_short_connections(std::fstream& fp,
const ModuleManager& module_manager,
const ModuleId& module_id) {
/* Local wires come from the child modules */
for (ModuleNetId module_net : module_manager.module_nets(module_id)) {
/* We only care the nets that indicate short connections */
if (false == module_net_include_output_short_connection(module_manager, module_id, module_net)) {
continue;
}
print_verilog_module_output_short_connection(fp, module_manager, module_id, module_net);
}
}
/******************************************************************** /********************************************************************
* Write a Verilog instance to a file * Write a Verilog instance to a file
* This function will name the input and output connections to * This function will name the input and output connections to
@ -372,6 +446,8 @@ void write_verilog_module_to_file(std::fstream& fp,
/* Print local connection (from module inputs to output! */ /* Print local connection (from module inputs to output! */
print_verilog_module_local_short_connections(fp, module_manager, module_id); print_verilog_module_local_short_connections(fp, module_manager, module_id);
print_verilog_module_output_short_connections(fp, module_manager, module_id);
/* Print an empty line as splitter */ /* Print an empty line as splitter */
fp << std::endl; fp << std::endl;

View File

@ -547,7 +547,7 @@ void print_verilog_top_testbench_generic_stimulus(std::fstream& fp,
print_verilog_comment(fp, std::string("----- Actual operating clock is triggered only when " + config_done_port.get_name() + " is enabled -----")); print_verilog_comment(fp, std::string("----- Actual operating clock is triggered only when " + config_done_port.get_name() + " is enabled -----"));
fp << "\tassign " << generate_verilog_port(VERILOG_PORT_CONKT, op_clock_port); fp << "\tassign " << generate_verilog_port(VERILOG_PORT_CONKT, op_clock_port);
fp << " = " << generate_verilog_port(VERILOG_PORT_CONKT, op_clock_register_port); fp << " = " << generate_verilog_port(VERILOG_PORT_CONKT, op_clock_register_port);
fp << " & (~" << generate_verilog_port(VERILOG_PORT_CONKT, config_done_port) << ")"; fp << " & " << generate_verilog_port(VERILOG_PORT_CONKT, config_done_port);
fp << ";" << std::endl; fp << ";" << std::endl;
fp << std::endl; fp << std::endl;