bug fixing for datapath mux size in Verilog generation

This commit is contained in:
tangxifan 2019-09-03 18:09:21 -06:00
parent 4d183a3fe4
commit b6bb433edc
4 changed files with 52 additions and 21 deletions

View File

@ -27,7 +27,7 @@ class MuxLibrary {
const MuxGraph& mux_graph(const MuxId& mux_id) const;
/* Get a mux circuit model id */
CircuitModelId mux_circuit_model(const MuxId& mux_id) const;
/* Find the maximum mux size */
/* Find the mux sizes */
size_t max_mux_size() const;
public: /* Public mutators */
/* Add a mux to the library */

View File

@ -17,6 +17,32 @@ bool valid_mux_implementation_num_inputs(const size_t& mux_size) {
return (2 <= mux_size);
}
/**************************************************
* Find the actual number of datapath inputs for a multiplexer implementation
* 1. if there are no requirements on constant inputs, mux_size is the actual one
* 2. if there exist constant inputs, mux_size should minus 1
* This function is mainly used to recover the number of datapath inputs
* for MUXGraphs which is a generic representation without labelling datapath inputs
*************************************************/
size_t find_mux_num_datapath_inputs(const CircuitLibrary& circuit_lib,
const CircuitModelId& circuit_model,
const size_t& mux_size) {
/* Should be either MUX or LUT
* LUTs do have an tree-like MUX, but there is no need for a constant input!
*/
VTR_ASSERT ((SPICE_MODEL_MUX == circuit_lib.model_type(circuit_model))
|| (SPICE_MODEL_LUT == circuit_lib.model_type(circuit_model)) );
if (SPICE_MODEL_LUT == circuit_lib.model_type(circuit_model)) {
return mux_size;
}
if (true == circuit_lib.mux_add_const_input(circuit_model)) {
return mux_size - 1;
}
return mux_size;
}
/**************************************************
* Find the actual number of inputs for a multiplexer implementation
* 1. if there are no requirements on constant inputs, mux_size is the actual one
@ -31,7 +57,7 @@ size_t find_mux_implementation_num_inputs(const CircuitLibrary& circuit_lib,
VTR_ASSERT ((SPICE_MODEL_MUX == circuit_lib.model_type(circuit_model))
|| (SPICE_MODEL_LUT == circuit_lib.model_type(circuit_model)) );
if (SPICE_MODEL_LUT == circuit_lib.model_type(circuit_model)) {
if (SPICE_MODEL_LUT == circuit_lib.model_type(circuit_model)) {
return mux_size;
}

View File

@ -12,11 +12,14 @@
bool valid_mux_implementation_num_inputs(const size_t& mux_size);
size_t find_mux_num_datapath_inputs(const CircuitLibrary& circuit_lib,
const CircuitModelId& circuit_model,
const size_t& mux_size);
size_t find_mux_implementation_num_inputs(const CircuitLibrary& circuit_lib,
const CircuitModelId& circuit_model,
const size_t& mux_size);
enum e_spice_model_structure find_mux_implementation_structure(const CircuitLibrary& circuit_lib,
const CircuitModelId& circuit_model,
const size_t& mux_size);

View File

@ -15,6 +15,7 @@
#include "module_manager.h"
#include "physical_types.h"
#include "vpr_types.h"
#include "mux_utils.h"
/* FPGA-X2P context header files */
#include "spice_types.h"
@ -720,8 +721,8 @@ void generate_verilog_cmos_mux_module(ModuleManager& module_manager,
check_file_handler(fp);
/* Generate the Verilog netlist according to the mux_graph */
/* TODO: Find out the number of data-path inputs */
size_t num_inputs = mux_graph.num_inputs();
/* Find out the number of data-path inputs */
size_t num_inputs = find_mux_num_datapath_inputs(circuit_lib, circuit_model, mux_graph.num_inputs());
/* Find out the number of outputs */
size_t num_outputs = mux_graph.num_outputs();
/* Find out the number of memory bits */
@ -758,21 +759,21 @@ void generate_verilog_cmos_mux_module(ModuleManager& module_manager,
}
/* Add each input port
* Treat MUX and LUT differently
* 1. MUXes: we do not have a specific input sizes, it is inferred by architecture
* 2. LUTes: we do have a specific input sizes
* 1. MUXes: we do not have a specific input/output sizes, it is inferred by architecture
* 2. LUTes: we do have specific input/output sizes,
* but the inputs of MUXes are the SRAM ports of LUTs
* and the SRAM ports of MUXes are the inputs of LUTs
*/
size_t input_port_cnt = 0;
for (const auto& port : mux_input_ports) {
BasicPort input_port(circuit_lib.port_lib_name(port), num_inputs);
if (SPICE_MODEL_LUT == circuit_lib.model_type(circuit_model)) {
input_port.set_width(circuit_lib.port_size(port));
}
module_manager.add_port(module_id, input_port, ModuleManager::MODULE_INPUT_PORT);
/* Update counter */
input_port_cnt++;
}
/* Add each output port
* Treat MUX and LUT differently
* 1. MUXes: we do not have a specific output sizes, it is inferred by architecture
* 2. LUTes: we do have a specific input sizes
*/
/* Double check: We should have only 1 input port generated here! */
VTR_ASSERT(1 == input_port_cnt);
for (const auto& port : mux_output_ports) {
BasicPort output_port(circuit_lib.port_lib_name(port), num_outputs);
if (SPICE_MODEL_LUT == circuit_lib.model_type(circuit_model)) {
@ -780,7 +781,7 @@ void generate_verilog_cmos_mux_module(ModuleManager& module_manager,
}
module_manager.add_port(module_id, output_port, ModuleManager::MODULE_OUTPUT_PORT);
}
/* Add each memory port */
size_t sram_port_cnt = 0;
for (const auto& port : mux_sram_ports) {
/* Multiplexing structure does not mode_sram_ports, they are handled in LUT modules
@ -796,9 +797,7 @@ void generate_verilog_cmos_mux_module(ModuleManager& module_manager,
/* Update counter */
sram_port_cnt++;
}
/* Double check: We should have only 1 sram port outputted here! */
VTR_ASSERT(1 == sram_port_cnt);
/* dump module definition + ports */
print_verilog_module_declaration(fp, module_manager, module_id);
@ -822,7 +821,9 @@ void generate_verilog_mux_module(ModuleManager& module_manager,
std::fstream& fp,
const CircuitModelId& circuit_model,
const MuxGraph& mux_graph) {
std::string module_name = generate_verilog_mux_subckt_name(circuit_lib, circuit_model, mux_graph.num_inputs(), std::string(""));
std::string module_name = generate_verilog_mux_subckt_name(circuit_lib, circuit_model,
find_mux_num_datapath_inputs(circuit_lib, circuit_model, mux_graph.num_inputs()),
std::string(""));
/* Multiplexers built with different technology is in different organization */
switch (circuit_lib.design_tech_type(circuit_model)) {
@ -885,7 +886,8 @@ void print_verilog_submodule_muxes(ModuleManager& module_manager,
/* Create branch circuits, which are N:1 one-level or 2:1 tree-like MUXes */
for (auto branch_mux_graph : branch_mux_graphs) {
generate_verilog_mux_branch_module(module_manager, circuit_lib, fp, mux_circuit_model,
mux_graph.num_inputs(), branch_mux_graph);
find_mux_num_datapath_inputs(circuit_lib, mux_circuit_model, mux_graph.num_inputs()),
branch_mux_graph);
}
}