bug fixed for local encoders and module nets creation
This commit is contained in:
parent
b2f57ecf81
commit
fe433f3e50
|
@ -1028,6 +1028,161 @@ vtr::vector<MuxOutputId, ModuleNetId> build_mux_module_output_buffers(ModuleMana
|
|||
return mux_output_nets;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* This function will
|
||||
* 1. Build local encoders for a MUX module (if specified)
|
||||
* 2. Build nets between memory ports of a MUX module and branch circuits
|
||||
* This happens when local encoders are not needed
|
||||
*
|
||||
* MUX module
|
||||
* +---------------------
|
||||
* | mux_mem_nets/mux_mem_inv_nets
|
||||
* | |
|
||||
* | v +---------
|
||||
* mem-+-------->|
|
||||
* | | Branch Module
|
||||
* | |
|
||||
*
|
||||
* 3. Build nets between local encoders and memory ports of a MUX module
|
||||
* This happens when local encoders are needed
|
||||
* 4. Build nets between local encoders and branch circuits
|
||||
* This happens when local encoders are needed
|
||||
*
|
||||
* MUX module
|
||||
* +---------------------
|
||||
* |
|
||||
* | +-------+ mux_mem_nets/mux_mem_inv_nets
|
||||
* | | | |
|
||||
* mem--+------>| | v +---------
|
||||
* | | Local |-------->|
|
||||
* | |Encoder| | Branch
|
||||
* | | | | Module
|
||||
* | | | |
|
||||
* | | | |
|
||||
*
|
||||
*********************************************************************/
|
||||
static
|
||||
void build_mux_module_local_encoders_and_memory_nets(ModuleManager& module_manager,
|
||||
const ModuleId& mux_module,
|
||||
const CircuitLibrary& circuit_lib,
|
||||
const CircuitModelId& mux_model,
|
||||
const std::vector<CircuitPortId>& mux_sram_ports,
|
||||
const MuxGraph& mux_graph,
|
||||
vtr::vector<MuxMemId, ModuleNetId>& mux_mem_nets,
|
||||
vtr::vector<MuxMemId, ModuleNetId>& mux_mem_inv_nets) {
|
||||
|
||||
/* Create nets here, and we will configure the net source later */
|
||||
for (size_t mem = 0; mem < mux_graph.num_memory_bits(); ++mem) {
|
||||
ModuleNetId mem_net = module_manager.create_module_net(mux_module);
|
||||
mux_mem_nets.push_back(mem_net);
|
||||
ModuleNetId mem_inv_net = module_manager.create_module_net(mux_module);
|
||||
mux_mem_inv_nets.push_back(mem_inv_net);
|
||||
}
|
||||
|
||||
if (false == circuit_lib.mux_use_local_encoder(mux_model)) {
|
||||
/* Add mem and mem_inv nets here */
|
||||
size_t mem_net_cnt = 0;
|
||||
for (const auto& port : mux_sram_ports) {
|
||||
ModulePortId mem_port_id = module_manager.find_module_port(mux_module, circuit_lib.port_lib_name(port));
|
||||
BasicPort mem_port = module_manager.module_port(mux_module, mem_port_id);
|
||||
for (const size_t& pin : mem_port.pins()) {
|
||||
MuxMemId mem_id = MuxMemId(mem_net_cnt);
|
||||
/* Set the module net source */
|
||||
module_manager.add_module_net_source(mux_module, mux_mem_nets[mem_id], mux_module, 0, mem_port_id, pin);
|
||||
/* Update counter */
|
||||
mem_net_cnt++;
|
||||
}
|
||||
}
|
||||
VTR_ASSERT(mem_net_cnt == mux_graph.num_memory_bits());
|
||||
|
||||
/* Add mem and mem_inv nets here */
|
||||
size_t mem_inv_net_cnt = 0;
|
||||
for (const auto& port : mux_sram_ports) {
|
||||
ModulePortId mem_inv_port_id = module_manager.find_module_port(mux_module, std::string(circuit_lib.port_lib_name(port) + "_inv"));
|
||||
BasicPort mem_inv_port = module_manager.module_port(mux_module, mem_inv_port_id);
|
||||
for (const size_t& pin : mem_inv_port.pins()) {
|
||||
MuxMemId mem_id = MuxMemId(mem_inv_net_cnt);
|
||||
/* Set the module net source */
|
||||
module_manager.add_module_net_source(mux_module, mux_mem_inv_nets[mem_id], mux_module, 0, mem_inv_port_id, pin);
|
||||
/* Update counter */
|
||||
mem_inv_net_cnt++;
|
||||
}
|
||||
}
|
||||
VTR_ASSERT(mem_inv_net_cnt == mux_graph.num_memory_bits());
|
||||
return; /* Finish here if local encoders are not required */
|
||||
}
|
||||
|
||||
/* Add local decoder instance here */
|
||||
VTR_ASSERT(true == circuit_lib.mux_use_local_encoder(mux_model));
|
||||
BasicPort decoder_data_port(generate_mux_local_decoder_data_port_name(), mux_graph.num_memory_bits());
|
||||
BasicPort decoder_data_inv_port(generate_mux_local_decoder_data_inv_port_name(), mux_graph.num_memory_bits());
|
||||
|
||||
/* Local port to record the LSB and MSB of each level, here, we deposite (0, 0) */
|
||||
ModulePortId mux_module_sram_port_id = module_manager.find_module_port(mux_module, circuit_lib.port_lib_name(mux_sram_ports[0]));
|
||||
BasicPort lvl_addr_port(circuit_lib.port_lib_name(mux_sram_ports[0]), 0);
|
||||
BasicPort lvl_data_port(decoder_data_port.get_name(), 0);
|
||||
BasicPort lvl_data_inv_port(decoder_data_inv_port.get_name(), 0);
|
||||
|
||||
/* Counter for mem index */
|
||||
size_t mem_net_cnt = 0;
|
||||
size_t mem_inv_net_cnt = 0;
|
||||
|
||||
for (const auto& lvl : mux_graph.levels()) {
|
||||
size_t addr_size = find_mux_local_decoder_addr_size(mux_graph.num_memory_bits_at_level(lvl));
|
||||
size_t data_size = mux_graph.num_memory_bits_at_level(lvl);
|
||||
/* Update the LSB and MSB of addr and data port for the current level */
|
||||
lvl_addr_port.rotate(addr_size);
|
||||
lvl_data_port.rotate(data_size);
|
||||
lvl_data_inv_port.rotate(data_size);
|
||||
|
||||
std::string decoder_module_name = generate_mux_local_decoder_subckt_name(addr_size, data_size);
|
||||
ModuleId decoder_module = module_manager.find_module(decoder_module_name);
|
||||
VTR_ASSERT(ModuleId::INVALID() != decoder_module);
|
||||
|
||||
size_t decoder_instance = module_manager.num_instance(mux_module, decoder_module);
|
||||
module_manager.add_child_module(mux_module, decoder_module);
|
||||
|
||||
/* Add module nets to connect sram ports of MUX to address port */
|
||||
ModulePortId decoder_module_addr_port_id = module_manager.find_module_port(decoder_module, generate_mux_local_decoder_addr_port_name());
|
||||
BasicPort decoder_module_addr_port = module_manager.module_port(decoder_module, decoder_module_addr_port_id);
|
||||
VTR_ASSERT(decoder_module_addr_port.get_width() == lvl_addr_port.get_width());
|
||||
|
||||
/* Build pin-to-pin net connection */
|
||||
for (size_t pin_id = 0; pin_id < lvl_addr_port.pins().size(); ++pin_id) {
|
||||
ModuleNetId net = module_manager.create_module_net(mux_module);
|
||||
module_manager.add_module_net_source(mux_module, net, mux_module, 0, mux_module_sram_port_id, lvl_addr_port.pins()[pin_id]);
|
||||
module_manager.add_module_net_sink(mux_module, net, decoder_module, decoder_instance, decoder_module_addr_port_id, decoder_module_addr_port.pins()[pin_id]);
|
||||
}
|
||||
|
||||
/* Add module nets to connect data port to MUX mem ports */
|
||||
ModulePortId decoder_module_data_port_id = module_manager.find_module_port(decoder_module, generate_mux_local_decoder_data_port_name());
|
||||
BasicPort decoder_module_data_port = module_manager.module_port(decoder_module, decoder_module_data_port_id);
|
||||
|
||||
/* Build pin-to-pin net connection */
|
||||
for (const size_t& pin : decoder_module_data_port.pins()) {
|
||||
ModuleNetId net = mux_mem_nets[MuxMemId(mem_net_cnt)];
|
||||
module_manager.add_module_net_source(mux_module, net, decoder_module, decoder_instance, decoder_module_data_port_id, pin);
|
||||
module_manager.set_net_name(mux_module, net, std::string(decoder_module_data_port.get_name() + "_" + std::to_string(pin) + "_"));
|
||||
/* Add the module nets to mux_mem_nets cache */
|
||||
mem_net_cnt++;
|
||||
}
|
||||
|
||||
ModulePortId decoder_module_data_inv_port_id = module_manager.find_module_port(decoder_module, generate_mux_local_decoder_data_inv_port_name());
|
||||
BasicPort decoder_module_data_inv_port = module_manager.module_port(decoder_module, decoder_module_data_inv_port_id);
|
||||
|
||||
/* Build pin-to-pin net connection */
|
||||
for (const size_t& pin : decoder_module_data_inv_port.pins()) {
|
||||
ModuleNetId net = mux_mem_inv_nets[MuxMemId(mem_inv_net_cnt)];
|
||||
module_manager.add_module_net_source(mux_module, net, decoder_module, decoder_instance, decoder_module_data_inv_port_id, pin);
|
||||
module_manager.set_net_name(mux_module, net, std::string(decoder_module_data_inv_port.get_name() + "_" + std::to_string(pin) + "_"));
|
||||
/* Add the module nets to mux_mem_inv_nets cache */
|
||||
mem_inv_net_cnt++;
|
||||
}
|
||||
}
|
||||
VTR_ASSERT(mem_net_cnt == mux_graph.num_memory_bits());
|
||||
VTR_ASSERT(mem_inv_net_cnt == mux_graph.num_memory_bits());
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* Generate module of a CMOS multiplexer with the given size
|
||||
* The module will consist of three parts:
|
||||
|
@ -1140,117 +1295,11 @@ void build_cmos_mux_module(ModuleManager& module_manager,
|
|||
/* Create module nets for mem and mem_inv ports */
|
||||
vtr::vector<MuxMemId, ModuleNetId> mux_mem_nets;
|
||||
vtr::vector<MuxMemId, ModuleNetId> mux_mem_inv_nets;
|
||||
/* Create nets here, and we will configure the net source later */
|
||||
for (size_t mem = 0; mem < mux_graph.num_memory_bits(); ++mem) {
|
||||
ModuleNetId mem_net = module_manager.create_module_net(mux_module);
|
||||
mux_mem_nets.push_back(mem_net);
|
||||
ModuleNetId mem_inv_net = module_manager.create_module_net(mux_module);
|
||||
mux_mem_inv_nets.push_back(mem_inv_net);
|
||||
}
|
||||
|
||||
if (false == circuit_lib.mux_use_local_encoder(mux_model)) {
|
||||
/* Add mem and mem_inv nets here */
|
||||
size_t mem_net_cnt = 0;
|
||||
for (const auto& port : mux_sram_ports) {
|
||||
ModulePortId mem_port_id = module_manager.find_module_port(mux_module, circuit_lib.port_lib_name(port));
|
||||
BasicPort mem_port = module_manager.module_port(mux_module, mem_port_id);
|
||||
for (const size_t& pin : mem_port.pins()) {
|
||||
MuxMemId mem_id = MuxMemId(mem_net_cnt);
|
||||
/* Set the module net source */
|
||||
module_manager.add_module_net_source(mux_module, mux_mem_nets[mem_id], mux_module, 0, mem_port_id, pin);
|
||||
/* Update counter */
|
||||
mem_net_cnt++;
|
||||
}
|
||||
}
|
||||
VTR_ASSERT(mem_net_cnt == mux_graph.num_memory_bits());
|
||||
|
||||
/* Add mem and mem_inv nets here */
|
||||
size_t mem_inv_net_cnt = 0;
|
||||
for (const auto& port : mux_sram_ports) {
|
||||
ModulePortId mem_inv_port_id = module_manager.find_module_port(mux_module, std::string(circuit_lib.port_lib_name(port) + "_inv"));
|
||||
BasicPort mem_inv_port = module_manager.module_port(mux_module, mem_inv_port_id);
|
||||
for (const size_t& pin : mem_inv_port.pins()) {
|
||||
MuxMemId mem_id = MuxMemId(mem_inv_net_cnt);
|
||||
/* Set the module net source */
|
||||
module_manager.add_module_net_source(mux_module, mux_mem_inv_nets[mem_id], mux_module, 0, mem_inv_port_id, pin);
|
||||
/* Update counter */
|
||||
mem_inv_net_cnt++;
|
||||
}
|
||||
}
|
||||
VTR_ASSERT(mem_inv_net_cnt == mux_graph.num_memory_bits());
|
||||
} else {
|
||||
/* Add local decoder instance here */
|
||||
VTR_ASSERT(true == circuit_lib.mux_use_local_encoder(mux_model));
|
||||
BasicPort decoder_data_port(generate_mux_local_decoder_data_port_name(), mux_graph.num_memory_bits());
|
||||
BasicPort decoder_data_inv_port(generate_mux_local_decoder_data_inv_port_name(), mux_graph.num_memory_bits());
|
||||
|
||||
/* Local port to record the LSB and MSB of each level, here, we deposite (0, 0) */
|
||||
ModulePortId mux_module_sram_port_id = module_manager.find_module_port(mux_module, circuit_lib.port_lib_name(mux_sram_ports[0]));
|
||||
BasicPort lvl_addr_port(circuit_lib.port_lib_name(mux_sram_ports[0]), 0);
|
||||
BasicPort lvl_data_port(decoder_data_port.get_name(), 0);
|
||||
BasicPort lvl_data_inv_port(decoder_data_inv_port.get_name(), 0);
|
||||
|
||||
/* Counter for mem index */
|
||||
size_t mem_net_cnt = 0;
|
||||
size_t mem_inv_net_cnt = 0;
|
||||
|
||||
for (const auto& lvl : mux_graph.levels()) {
|
||||
size_t addr_size = find_mux_local_decoder_addr_size(mux_graph.num_memory_bits_at_level(lvl));
|
||||
size_t data_size = mux_graph.num_memory_bits_at_level(lvl);
|
||||
/* Update the LSB and MSB of addr and data port for the current level */
|
||||
lvl_addr_port.rotate(addr_size);
|
||||
lvl_data_port.rotate(data_size);
|
||||
lvl_data_inv_port.rotate(data_size);
|
||||
|
||||
std::string decoder_module_name = generate_mux_local_decoder_subckt_name(addr_size, data_size);
|
||||
ModuleId decoder_module = module_manager.find_module(decoder_module_name);
|
||||
VTR_ASSERT(ModuleId::INVALID() != decoder_module);
|
||||
|
||||
size_t decoder_instance = module_manager.num_instance(mux_module, decoder_module);
|
||||
module_manager.add_child_module(mux_module, decoder_module);
|
||||
|
||||
/* Add module nets to connect sram ports of MUX to address port */
|
||||
ModulePortId decoder_module_addr_port_id = module_manager.find_module_port(decoder_module, generate_mux_local_decoder_addr_port_name());
|
||||
BasicPort decoder_module_addr_port = module_manager.module_port(decoder_module, decoder_module_addr_port_id);
|
||||
VTR_ASSERT(decoder_module_addr_port.get_width() == lvl_addr_port.get_width());
|
||||
|
||||
/* Build pin-to-pin net connection */
|
||||
for (size_t pin_id = 0; pin_id < lvl_addr_port.pins().size(); ++pin_id) {
|
||||
ModuleNetId net = module_manager.create_module_net(mux_module);
|
||||
module_manager.add_module_net_source(mux_module, net, mux_module, 0, mux_module_sram_port_id, lvl_addr_port.pins()[pin_id]);
|
||||
module_manager.add_module_net_sink(mux_module, net, decoder_module, decoder_instance, decoder_module_addr_port_id, decoder_module_addr_port.pins()[pin_id]);
|
||||
}
|
||||
|
||||
/* Add module nets to connect data port to MUX mem ports */
|
||||
ModulePortId decoder_module_data_port_id = module_manager.find_module_port(decoder_module, generate_mux_local_decoder_data_port_name());
|
||||
BasicPort decoder_module_data_port = module_manager.module_port(decoder_module, decoder_module_data_port_id);
|
||||
|
||||
/* Build pin-to-pin net connection */
|
||||
for (const size_t& pin : decoder_module_data_port.pins()) {
|
||||
ModuleNetId net = module_manager.create_module_net(mux_module);
|
||||
module_manager.add_module_net_source(mux_module, net, decoder_module, decoder_instance, decoder_module_data_port_id, pin);
|
||||
module_manager.set_net_name(mux_module, net, std::string(decoder_module_data_port.get_name() + "_" + std::to_string(pin) + "_"));
|
||||
/* Add the module nets to mux_mem_nets cache */
|
||||
mux_mem_nets[MuxMemId(mem_net_cnt)] = net;
|
||||
mem_net_cnt++;
|
||||
}
|
||||
|
||||
ModulePortId decoder_module_data_inv_port_id = module_manager.find_module_port(decoder_module, generate_mux_local_decoder_data_inv_port_name());
|
||||
BasicPort decoder_module_data_inv_port = module_manager.module_port(decoder_module, decoder_module_data_inv_port_id);
|
||||
|
||||
/* Build pin-to-pin net connection */
|
||||
for (const size_t& pin : decoder_module_data_inv_port.pins()) {
|
||||
ModuleNetId net = module_manager.create_module_net(mux_module);
|
||||
module_manager.add_module_net_source(mux_module, net, decoder_module, decoder_instance, decoder_module_data_inv_port_id, pin);
|
||||
module_manager.set_net_name(mux_module, net, std::string(decoder_module_data_inv_port.get_name() + "_" + std::to_string(pin) + "_"));
|
||||
/* Add the module nets to mux_mem_inv_nets cache */
|
||||
mux_mem_inv_nets[MuxMemId(mem_inv_net_cnt)] = net;
|
||||
mem_inv_net_cnt++;
|
||||
}
|
||||
}
|
||||
VTR_ASSERT(mem_net_cnt == mux_graph.num_memory_bits());
|
||||
VTR_ASSERT(mem_inv_net_cnt == mux_graph.num_memory_bits());
|
||||
}
|
||||
build_mux_module_local_encoders_and_memory_nets(module_manager, mux_module,
|
||||
circuit_lib, mux_model, mux_sram_ports,
|
||||
mux_graph,
|
||||
mux_mem_nets, mux_mem_inv_nets);
|
||||
|
||||
/* Print the internal logic in Verilog codes */
|
||||
/* Print the Multiplexing structure in Verilog codes
|
||||
|
|
|
@ -64,28 +64,8 @@ BasicPort generate_verilog_port_for_module_net(const ModuleManager& module_manag
|
|||
/* Reach here, this is a local wire */
|
||||
std::string net_name;
|
||||
|
||||
if (false == module_manager.net_name(module_id, module_net).empty()) {
|
||||
net_name = module_manager.net_name(module_id, module_net);
|
||||
printf("net_name:%s\n", net_name.c_str());
|
||||
}
|
||||
|
||||
/* Each net must only one 1 source */
|
||||
if (1 != module_manager.net_source_modules(module_id, module_net).size()) {
|
||||
for (auto src_module : module_manager.net_source_modules(module_id, module_net)) {
|
||||
printf("net_source_module: %s\n",
|
||||
module_manager.module_name(src_module).c_str());
|
||||
}
|
||||
for (auto sink_module : module_manager.net_sink_modules(module_id, module_net)) {
|
||||
printf("net_sink_module: %s\n",
|
||||
module_manager.module_name(sink_module).c_str());
|
||||
for (auto sink_port : module_manager.net_sink_ports(module_id, module_net)) {
|
||||
printf("\tnet_sink_port: %s\n",
|
||||
module_manager.module_port(sink_module, sink_port).get_name().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
VTR_ASSERT(1 == module_manager.net_source_modules(module_id, module_net).size());
|
||||
}
|
||||
|
||||
/* Get the source module */
|
||||
ModuleId net_src_module = module_manager.net_source_modules(module_id, module_net)[ModuleNetSrcId(0)];
|
||||
|
@ -121,11 +101,17 @@ std::vector<BasicPort> find_verilog_module_local_wires(const ModuleManager& modu
|
|||
|
||||
/* Local wires come from the child modules */
|
||||
for (ModuleNetId module_net : module_manager.module_nets(module_id)) {
|
||||
/* Bypass dangling nets */
|
||||
/* Bypass dangling nets:
|
||||
* Xifan Tang: I comment this part because it will shadow our problems in creating module graph
|
||||
* Indeed this make a robust and a smooth Verilog module writing
|
||||
* But I do want the module graph create is nice and clean !!!
|
||||
*/
|
||||
/*
|
||||
if ( (0 == module_manager.net_source_modules(module_id, module_net).size())
|
||||
&& (0 == module_manager.net_source_modules(module_id, module_net).size()) ) {
|
||||
continue;
|
||||
}
|
||||
*/
|
||||
|
||||
/* We only care local wires */
|
||||
if (false == module_net_is_local_wire(module_manager, module_id, module_net)) {
|
||||
|
|
Loading…
Reference in New Issue