bug fixing in memory module generation; some work should be done to merge nets and uniquifying nets!!!
This commit is contained in:
parent
69bc858e62
commit
5d507ae8ee
|
@ -304,6 +304,35 @@ bool module_net_is_local_wire(const ModuleManager& module_manager,
|
|||
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:
|
||||
* The short connection is defined as the direct connection
|
||||
|
|
|
@ -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,
|
||||
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,
|
||||
const ModuleId& module_id, const ModuleNetId& module_net);
|
||||
|
||||
|
|
|
@ -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
|
||||
* pin of output port of the memory module, where W is the size of port
|
||||
* 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
|
||||
void add_module_output_nets_to_chain_mem_modules(ModuleManager& module_manager,
|
||||
const ModuleId& mem_module,
|
||||
const std::string& mem_module_output_name,
|
||||
const CircuitLibrary& circuit_lib,
|
||||
const CircuitPortId& circuit_port,
|
||||
const ModuleId& child_module,
|
||||
const size_t& child_index,
|
||||
const size_t& child_instance) {
|
||||
std::vector<ModuleNetId> add_module_output_nets_to_chain_mem_modules(ModuleManager& module_manager,
|
||||
const ModuleId& mem_module,
|
||||
const std::string& mem_module_output_name,
|
||||
const CircuitLibrary& circuit_lib,
|
||||
const CircuitPortId& circuit_port,
|
||||
const ModuleId& child_module,
|
||||
const size_t& child_index,
|
||||
const size_t& child_instance) {
|
||||
std::vector<ModuleNetId> module_nets;
|
||||
|
||||
/* 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 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 */
|
||||
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);
|
||||
|
||||
/* 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
|
||||
void add_module_nets_to_cmos_memory_chain_module(ModuleManager& module_manager,
|
||||
const ModuleId& parent_module,
|
||||
const std::vector<ModuleNetId>& output_nets,
|
||||
const CircuitLibrary& circuit_lib,
|
||||
const CircuitPortId& model_input_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) {
|
||||
ModuleId net_src_module_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 */
|
||||
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 */
|
||||
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 */
|
||||
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 */
|
||||
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 */
|
||||
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 */
|
||||
ModuleNetId net = module_manager.create_module_net(parent_module);
|
||||
ModuleNetId net = output_nets[net_counter];
|
||||
/* 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]);
|
||||
/* 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]);
|
||||
|
||||
/* 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 */
|
||||
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 */
|
||||
for (size_t i = 0; i < num_mems; ++i) {
|
||||
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);
|
||||
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],
|
||||
sram_mem_module, i, sram_mem_instance);
|
||||
std::vector<ModuleNetId> output_nets = add_module_output_nets_to_chain_mem_modules(module_manager, mem_module,
|
||||
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 */
|
||||
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]);
|
||||
|
||||
|
||||
|
|
|
@ -113,7 +113,7 @@ void write_include_netlists (char* src_dir_formatted,
|
|||
top_testbench_verilog_file_postfix);
|
||||
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,
|
||||
autocheck_top_testbench_verilog_file_postfix);
|
||||
fprintf(fp, "`endif\n");
|
||||
|
|
|
@ -169,6 +169,50 @@ std::vector<BasicPort> find_verilog_module_local_wires(const ModuleManager& modu
|
|||
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
|
||||
* 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
|
||||
* 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_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 */
|
||||
fp << std::endl;
|
||||
|
|
|
@ -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 -----"));
|
||||
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, config_done_port) << ")";
|
||||
fp << " & " << generate_verilog_port(VERILOG_PORT_CONKT, config_done_port);
|
||||
fp << ";" << std::endl;
|
||||
|
||||
fp << std::endl;
|
||||
|
|
Loading…
Reference in New Issue