plug in module manager

This commit is contained in:
tangxifan 2019-08-23 17:39:29 -06:00
parent 1b4de2b335
commit 8eebca9daa
9 changed files with 134 additions and 96 deletions

View File

@ -12,6 +12,39 @@
* Public Constructors
******************************************************************************/
/******************************************************************************
* Public Accessors
******************************************************************************/
/* Find the name of a module */
std::string ModuleManager::module_name(const ModuleId& module_id) const {
/* Validate the module_id */
VTR_ASSERT(valid_module_id(module_id));
return names_[module_id];
}
/* Get the string of a module port type */
std::string ModuleManager::module_port_type_str(const enum e_module_port_type& port_type) const {
std::array<const char*, NUM_MODULE_PORT_TYPES> MODULE_PORT_TYPE_STRING = {{"GLOBAL PORTS", "INOUT PORTS", "INPUT PORTS", "OUTPUT PORTS", "CLOCK PORTS"}};
return MODULE_PORT_TYPE_STRING[port_type];
}
/* Find a list of ports of a module by a given types */
std::vector<BasicPort> ModuleManager::module_ports_by_type(const ModuleId& module_id, const enum e_module_port_type& port_type) const {
/* Validate the module_id */
VTR_ASSERT(valid_module_id(module_id));
std::vector<BasicPort> ports;
for (const auto& port : port_ids_[module_id]) {
/* Skip unmatched ports */
if (port_type != port_types_[module_id][port]) {
continue;
}
ports.push_back(ports_[module_id][port]);
}
return ports;
}
/******************************************************************************
* Public Mutators
******************************************************************************/

View File

@ -32,6 +32,10 @@ class ModuleManager {
NUM_MODULE_PORT_TYPES
};
public: /* Public Constructors */
public: /* Public accessors */
std::string module_name(const ModuleId& module_id) const;
std::string module_port_type_str(const enum e_module_port_type& port_type) const;
std::vector<BasicPort> module_ports_by_type(const ModuleId& module_id, const enum e_module_port_type& port_type) const;
public: /* Public mutators */
/* Add a module */
ModuleId add_module(const std::string& name);

View File

@ -32,6 +32,8 @@
#include "fpga_x2p_globals.h"
#include "fpga_bitstream.h"
#include "module_manager.h"
/* Include SynVerilog headers */
#include "verilog_global.h"
#include "verilog_utils.h"
@ -148,6 +150,9 @@ void vpr_fpga_verilog(t_vpr_setup vpr_setup,
t_sram_orgz_info* sram_verilog_orgz_info = NULL;
/* Module manager for the Verilog modules created */
ModuleManager module_manager;
/* Check if the routing architecture we support*/
if (UNI_DIRECTIONAL != vpr_setup.RoutingArch.directionality) {
vpr_printf(TIO_MESSAGE_ERROR, "FPGA synthesizable Verilog dumping only support uni-directional routing architecture!\n");
@ -269,7 +274,7 @@ void vpr_fpga_verilog(t_vpr_setup vpr_setup,
vpr_setup.FPGA_SPICE_Opts.SynVerilogOpts.dump_explicit_verilog);
/* Dump internal structures of submodules */
dump_verilog_submodules(sram_verilog_orgz_info, src_dir_path, submodule_dir_path,
dump_verilog_submodules(module_manager, sram_verilog_orgz_info, src_dir_path, submodule_dir_path,
Arch, &vpr_setup.RoutingArch,
vpr_setup.FPGA_SPICE_Opts.SynVerilogOpts);

View File

@ -13,6 +13,8 @@
/* FPGA-X2P context header files */
#include "fpga_x2p_utils.h"
#include "module_manager.h"
#include "module_manager_utils.h"
/* FPGA-Verilog context header files */
#include "verilog_global.h"
@ -136,7 +138,8 @@ void print_verilog_invbuf_body(std::fstream& fp,
* or tapered buffer to a file
***********************************************/
static
void print_verilog_invbuf_module(std::fstream& fp,
void print_verilog_invbuf_module(ModuleManager& module_manager,
std::fstream& fp,
const CircuitLibrary& circuit_lib,
const CircuitModelId& circuit_model) {
/* Ensure a valid file handler*/
@ -178,30 +181,11 @@ void print_verilog_invbuf_module(std::fstream& fp,
}
}
/* dump module body */
print_verilog_module_definition(fp, circuit_lib.model_name(circuit_model));
/* Create a Verilog Module based on the circuit model, and add to module manager */
ModuleId module_id = add_circuit_model_to_module_manager(module_manager, circuit_lib, circuit_model);
/* TODO: print global ports, this should be handled by ModuleManager */
for (const auto& port : global_ports) {
/* Configure each global port */
BasicPort basic_port(circuit_lib.port_lib_name(port), circuit_lib.port_size(port));
/* Print port */
fp << "\t" << generate_verilog_port(VERILOG_PORT_INPUT, basic_port) << "," << std::endl;
}
/* Dump ports */
BasicPort input_port;
/* Configure each input port */
input_port.set_name(circuit_lib.port_lib_name(input_ports[0]));
input_port.set_width(circuit_lib.port_size(input_ports[0]));
fp << "\t" << generate_verilog_port(VERILOG_PORT_INPUT, input_port) << "," << std::endl;
BasicPort output_port;
/* Configure each input port */
output_port.set_name(circuit_lib.port_lib_name(output_ports[0]));
output_port.set_width(circuit_lib.port_size(output_ports[0]));
fp << "\t" << generate_verilog_port(VERILOG_PORT_OUTPUT, output_port) << std::endl;
fp << ");" << std::endl;
/* dump module definition + ports */
print_verilog_module_declaration(fp, module_manager, module_id);
/* Finish dumping ports */
/* Assign logics : depending on topology */
@ -239,7 +223,8 @@ void print_verilog_invbuf_module(std::fstream& fp,
* either transmission-gate or pass-transistor
***********************************************/
static
void print_verilog_passgate_module(std::fstream& fp,
void print_verilog_passgate_module(ModuleManager& module_manager,
std::fstream& fp,
const CircuitLibrary& circuit_lib,
const CircuitModelId& circuit_model) {
/* Ensure a valid file handler*/
@ -284,37 +269,12 @@ void print_verilog_passgate_module(std::fstream& fp,
*/
VTR_ASSERT( (1 == output_ports.size()) && (1 == circuit_lib.port_size(output_ports[0])) );
/* Print Verilog module */
print_verilog_module_definition(fp, circuit_lib.model_name(circuit_model));
/* Create a Verilog Module based on the circuit model, and add to module manager */
ModuleId module_id = add_circuit_model_to_module_manager(module_manager, circuit_lib, circuit_model);
/* TODO: print global ports, this should be handled by ModuleManager */
for (const auto& port : global_ports) {
/* Configure each global port */
BasicPort basic_port(circuit_lib.port_lib_name(port), circuit_lib.port_size(port));
/* Print port */
fp << "\t" << generate_verilog_port(VERILOG_PORT_INPUT, basic_port) << "," << std::endl;
}
for (const auto& input_port : input_ports) {
/* Configure each global port */
BasicPort basic_port(circuit_lib.port_lib_name(input_port), circuit_lib.port_size(input_port));
/* Print port */
fp << "\t" << generate_verilog_port(VERILOG_PORT_INPUT, basic_port) << "," << std::endl;
}
/* Configure each global port */
for (const auto& output_port : output_ports) {
BasicPort basic_port(circuit_lib.port_lib_name(output_port), circuit_lib.port_size(output_port));
/* Print port */
fp << "\t" << generate_verilog_port(VERILOG_PORT_OUTPUT, basic_port);
/* Last port does not need a comma */
if (output_port != output_ports.back()) {
fp << "," << std::endl;
} else {
fp << std::endl;
}
}
fp << ");" << std::endl;
/* dump module definition + ports */
print_verilog_module_declaration(fp, module_manager, module_id);
/* Finish dumping ports */
/* Dump logics: we propagate input to the output when the gate is '1'
* the input is blocked from output when the gate is '0'
@ -474,7 +434,8 @@ void print_verilog_mux2_gate_body(std::fstream& fp,
* 3. 2-input MUX
***********************************************/
static
void print_verilog_gate_module(std::fstream& fp,
void print_verilog_gate_module(ModuleManager& module_manager,
std::fstream& fp,
const CircuitLibrary& circuit_lib,
const CircuitModelId& circuit_model) {
/* Ensure a valid file handler*/
@ -491,37 +452,12 @@ void print_verilog_gate_module(std::fstream& fp,
*/
VTR_ASSERT( (1 == output_ports.size()) && (1 == circuit_lib.port_size(output_ports[0])) );
/* Print Verilog module */
print_verilog_module_definition(fp, circuit_lib.model_name(circuit_model));
/* Create a Verilog Module based on the circuit model, and add to module manager */
ModuleId module_id = add_circuit_model_to_module_manager(module_manager, circuit_lib, circuit_model);
/* TODO: print global ports, this should be handled by ModuleManager */
for (const auto& port : global_ports) {
/* Configure each global port */
BasicPort basic_port(circuit_lib.port_lib_name(port), circuit_lib.port_size(port));
/* Print port */
fp << "\t" << generate_verilog_port(VERILOG_PORT_INPUT, basic_port) << "," << std::endl;
}
for (const auto& input_port : input_ports) {
/* Configure each global port */
BasicPort basic_port(circuit_lib.port_lib_name(input_port), circuit_lib.port_size(input_port));
/* Print port */
fp << "\t" << generate_verilog_port(VERILOG_PORT_INPUT, basic_port) << "," << std::endl;
}
/* Configure each global port */
for (const auto& output_port : output_ports) {
BasicPort basic_port(circuit_lib.port_lib_name(output_port), circuit_lib.port_size(output_port));
/* Print port */
fp << "\t" << generate_verilog_port(VERILOG_PORT_OUTPUT, basic_port);
/* Last port does not need a comma */
if (output_port != output_ports.back()) {
fp << "," << std::endl;
} else {
fp << std::endl;
}
}
fp << ");" << std::endl;
/* dump module definition + ports */
print_verilog_module_declaration(fp, module_manager, module_id);
/* Finish dumping ports */
/* Dump logics */
switch (circuit_lib.gate_type(circuit_model)) {
@ -554,7 +490,8 @@ void print_verilog_gate_module(std::fstream& fp,
* include inverters, buffers, transmission-gates,
* etc.
***********************************************/
void print_verilog_submodule_essentials(const std::string& verilog_dir,
void print_verilog_submodule_essentials(ModuleManager& module_manager,
const std::string& verilog_dir,
const std::string& submodule_dir,
const CircuitLibrary& circuit_lib) {
/* TODO: remove .bak when this part is completed and tested */
@ -582,15 +519,15 @@ void print_verilog_submodule_essentials(const std::string& verilog_dir,
continue;
}
if (SPICE_MODEL_INVBUF == circuit_lib.model_type(circuit_model)) {
print_verilog_invbuf_module(fp, circuit_lib, circuit_model);
print_verilog_invbuf_module(module_manager, fp, circuit_lib, circuit_model);
continue;
}
if (SPICE_MODEL_PASSGATE == circuit_lib.model_type(circuit_model)) {
print_verilog_passgate_module(fp, circuit_lib, circuit_model);
print_verilog_passgate_module(module_manager, fp, circuit_lib, circuit_model);
continue;
}
if (SPICE_MODEL_GATE == circuit_lib.model_type(circuit_model)) {
print_verilog_gate_module(fp, circuit_lib, circuit_model);
print_verilog_gate_module(module_manager, fp, circuit_lib, circuit_model);
continue;
}
}

View File

@ -12,7 +12,8 @@
#include <string>
#include "circuit_library.h"
void print_verilog_submodule_essentials(const std::string& verilog_dir,
void print_verilog_submodule_essentials(ModuleManager& module_manager,
const std::string& verilog_dir,
const std::string& submodule_dir,
const CircuitLibrary& circuit_lib);

View File

@ -3506,7 +3506,8 @@ void dump_verilog_submodule_templates(t_sram_orgz_info* cur_sram_orgz_info,
/* Dump verilog files of submodules to be used in FPGA components :
* 1. MUXes
*/
void dump_verilog_submodules(t_sram_orgz_info* cur_sram_orgz_info,
void dump_verilog_submodules(ModuleManager& module_manager,
t_sram_orgz_info* cur_sram_orgz_info,
char* verilog_dir,
char* submodule_dir,
t_arch Arch,
@ -3515,7 +3516,8 @@ void dump_verilog_submodules(t_sram_orgz_info* cur_sram_orgz_info,
/* 0. basic units: inverter, buffers and pass-gate logics, */
vpr_printf(TIO_MESSAGE_INFO, "Generating essential modules...\n");
print_verilog_submodule_essentials(std::string(verilog_dir),
print_verilog_submodule_essentials(module_manager,
std::string(verilog_dir),
std::string(submodule_dir),
Arch.spice->circuit_lib);

View File

@ -1,6 +1,10 @@
#ifndef VERILOG_SUBMODULES_H
#define VERILOG_SUBMODULES_H
void dump_verilog_submodules(t_sram_orgz_info* cur_sram_orgz_info,
#include "module_manager.h"
void dump_verilog_submodules(ModuleManager& module_manager,
t_sram_orgz_info* cur_sram_orgz_info,
char* verilog_dir,
char* submodule_dir,
t_arch Arch,

View File

@ -82,7 +82,52 @@ void print_verilog_module_definition(std::fstream& fp,
}
/************************************************
* Print a Verilog module definition
* Print a Verilog module ports based on the module id
***********************************************/
void print_verilog_module_ports(std::fstream& fp,
const ModuleManager& module_manager, const ModuleId& module_id) {
check_file_handler(fp);
/* port type2type mapping */
std::map<ModuleManager::e_module_port_type, enum e_dump_verilog_port_type> port_type2type_map;
port_type2type_map[ModuleManager::MODULE_GLOBAL_PORT] = VERILOG_PORT_INPUT;
port_type2type_map[ModuleManager::MODULE_INOUT_PORT] = VERILOG_PORT_INOUT;
port_type2type_map[ModuleManager::MODULE_INPUT_PORT] = VERILOG_PORT_INPUT;
port_type2type_map[ModuleManager::MODULE_OUTPUT_PORT] = VERILOG_PORT_OUTPUT;
port_type2type_map[ModuleManager::MODULE_CLOCK_PORT] = VERILOG_PORT_INPUT;
/* Port sequence: global, inout, input, output and clock ports, */
size_t port_cnt = 0;
for (const auto& kv : port_type2type_map) {
for (const auto& port : module_manager.module_ports_by_type(module_id, kv.first)) {
if (0 != port_cnt) {
/* Do not dump a comma for the first port */
fp << ", //----- " << module_manager.module_port_type_str(kv.first) << " -----" << std::endl;
}
/* Print port */
fp << "\t" << generate_verilog_port(kv.second, port) << std::endl;
port_cnt++;
}
}
}
/************************************************
* Print a Verilog module declaration (definition + port list
***********************************************/
void print_verilog_module_declaration(std::fstream& fp,
const ModuleManager& module_manager, const ModuleId& module_id) {
check_file_handler(fp);
print_verilog_module_definition(fp, module_manager.module_name(module_id));
print_verilog_module_ports(fp, module_manager, module_id);
fp << std::endl << ");" << std::endl;
}
/************************************************
* Print an end line for a Verilog module
***********************************************/
void print_verilog_module_end(std::fstream& fp,
const std::string& module_name) {

View File

@ -8,6 +8,7 @@
#include <string>
#include "device_port.h"
#include "module_manager.h"
void print_verilog_file_header(std::fstream& fp,
const std::string& usage);
@ -21,6 +22,12 @@ void print_verilog_comment(std::fstream& fp,
void print_verilog_module_definition(std::fstream& fp,
const std::string& module_name);
void print_verilog_module_ports(std::fstream& fp,
const ModuleManager& module_manager, const ModuleId& module_id);
void print_verilog_module_declaration(std::fstream& fp,
const ModuleManager& module_manager, const ModuleId& module_id);
void print_verilog_module_end(std::fstream& fp,
const std::string& module_name);