developing verilog writer for modules

This commit is contained in:
tangxifan 2019-10-10 14:43:32 -06:00
parent edad988ebb
commit e5956467fd
5 changed files with 252 additions and 1 deletions

View File

@ -2,6 +2,7 @@
* Memember functions for data structure ModuleManager
******************************************************************************/
#include <string>
#include <numeric>
#include <algorithm>
#include "vtr_assert.h"
@ -12,6 +13,49 @@
* Public Constructors
******************************************************************************/
/**************************************************
* Public Accessors : Aggregates
*************************************************/
/* Find all the modules */
ModuleManager::module_range ModuleManager::modules() const {
return vtr::make_range(ids_.begin(), ids_.end());
}
/* Find all the nets belonging to a module */
ModuleManager::module_net_range ModuleManager::module_nets(const ModuleId& module) const {
/* Validate the module_id */
VTR_ASSERT(valid_module_id(module));
return vtr::make_range(net_ids_[module].begin(), net_ids_[module].end());
}
/* Find all the child modules under a parent module */
std::vector<ModuleId> ModuleManager::child_modules(const ModuleId& parent_module) const {
/* Validate the module_id */
VTR_ASSERT(valid_module_id(parent_module));
return children_[parent_module];
}
/* Find all the instances under a parent module */
std::vector<size_t> ModuleManager::child_module_instances(const ModuleId& parent_module, const ModuleId& child_module) const {
/* Validate the module_id */
VTR_ASSERT(valid_module_id(parent_module));
/* Ensure that the child module is in the child list of parent module */
size_t child_index = children_[parent_module].size();
for (size_t i = 0; i < children_[parent_module].size(); ++i) {
if (child_module == children_[parent_module][i]) {
child_index = i;
break;
}
}
VTR_ASSERT(child_index != children_[parent_module].size());
/* Create a vector, with sequentially increasing numbers */
std::vector<size_t> instance_range(num_child_instances_[parent_module][child_index]);
std::iota(instance_range.begin(), instance_range.end(), 0);
return instance_range;
}
/******************************************************************************
* Public Accessors
******************************************************************************/
@ -20,6 +64,13 @@ size_t ModuleManager::num_modules() const {
return ids_.size();
}
/* Return number of net of a module */
size_t ModuleManager::num_nets(const ModuleId& module) const {
/* Validate the module_id */
VTR_ASSERT(valid_module_id(module));
return net_ids_[module].size();
}
/* Find the name of a module */
std::string ModuleManager::module_name(const ModuleId& module_id) const {
/* Validate the module_id */
@ -120,7 +171,6 @@ std::string ModuleManager::port_preproc_flag(const ModuleId& module, const Modul
return port_preproc_flags_[module][port];
}
/* Find a net from an instance of a module */
ModuleNetId ModuleManager::module_instance_port_net(const ModuleId& parent_module,
const ModuleId& child_module, const size_t& child_instance,
@ -156,6 +206,70 @@ std::string ModuleManager::net_name(const ModuleId& module, const ModuleNetId& n
return net_names_[module][net];
}
/* Find the source modules of a net */
std::vector<ModuleId> ModuleManager::net_source_modules(const ModuleId& module, const ModuleNetId& net) const {
/* Validate module net */
VTR_ASSERT(valid_module_net_id(module, net));
return net_src_module_ids_[module][net];
}
/* Find the ids of source instances of a net */
std::vector<size_t> ModuleManager::net_source_instances(const ModuleId& module, const ModuleNetId& net) const {
/* Validate module net */
VTR_ASSERT(valid_module_net_id(module, net));
return net_src_instance_ids_[module][net];
}
/* Find the source ports of a net */
std::vector<ModulePortId> ModuleManager::net_source_ports(const ModuleId& module, const ModuleNetId& net) const {
/* Validate module net */
VTR_ASSERT(valid_module_net_id(module, net));
return net_src_port_ids_[module][net];
}
/* Find the source pin indices of a net */
std::vector<size_t> ModuleManager::net_source_pins(const ModuleId& module, const ModuleNetId& net) const {
/* Validate module net */
VTR_ASSERT(valid_module_net_id(module, net));
return net_src_pin_ids_[module][net];
}
/* Find the sink modules of a net */
std::vector<ModuleId> ModuleManager::net_sink_modules(const ModuleId& module, const ModuleNetId& net) const {
/* Validate module net */
VTR_ASSERT(valid_module_net_id(module, net));
return net_sink_module_ids_[module][net];
}
/* Find the ids of sink instances of a net */
std::vector<size_t> ModuleManager::net_sink_instances(const ModuleId& module, const ModuleNetId& net) const {
/* Validate module net */
VTR_ASSERT(valid_module_net_id(module, net));
return net_sink_instance_ids_[module][net];
}
/* Find the sink ports of a net */
std::vector<ModulePortId> ModuleManager::net_sink_ports(const ModuleId& module, const ModuleNetId& net) const {
/* Validate module net */
VTR_ASSERT(valid_module_net_id(module, net));
return net_sink_port_ids_[module][net];
}
/* Find the sink pin indices of a net */
std::vector<size_t> ModuleManager::net_sink_pins(const ModuleId& module, const ModuleNetId& net) const {
/* Validate module net */
VTR_ASSERT(valid_module_net_id(module, net));
return net_sink_pin_ids_[module][net];
}
/******************************************************************************
* Public Mutators
******************************************************************************/

View File

@ -32,9 +32,29 @@ class ModuleManager {
MODULE_CLOCK_PORT,
NUM_MODULE_PORT_TYPES
};
public: /* Public Constructors */
public: /* Types and ranges */
typedef vtr::vector<ModuleId, ModuleId>::const_iterator module_iterator;
typedef vtr::vector<ModuleNetId, ModuleNetId>::const_iterator module_net_iterator;
typedef vtr::Range<module_iterator> module_range;
typedef vtr::Range<module_net_iterator> module_net_range;
public: /* Public aggregators */
/* Find all the modules */
module_range modules() const;
/* Find all the nets belonging to a module */
module_net_range module_nets(const ModuleId& module) const;
/* Find all the child modules under a parent module */
std::vector<ModuleId> child_modules(const ModuleId& parent_module) const;
/* Find all the instances under a parent module */
std::vector<size_t> child_module_instances(const ModuleId& parent_module, const ModuleId& child_module) const;
public: /* Public accessors */
size_t num_modules() const;
size_t num_nets(const ModuleId& module) const;
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;
@ -58,6 +78,22 @@ class ModuleManager {
const ModulePortId& child_port, const size_t& child_pin) const;
/* Find the name of net */
std::string net_name(const ModuleId& module, const ModuleNetId& net) const;
/* Find the source modules of a net */
std::vector<ModuleId> net_source_modules(const ModuleId& module, const ModuleNetId& net) const;
/* Find the ids of source instances of a net */
std::vector<size_t> net_source_instances(const ModuleId& module, const ModuleNetId& net) const;
/* Find the source ports of a net */
std::vector<ModulePortId> net_source_ports(const ModuleId& module, const ModuleNetId& net) const;
/* Find the source pin indices of a net */
std::vector<size_t> net_source_pins(const ModuleId& module, const ModuleNetId& net) const;
/* Find the sink modules of a net */
std::vector<ModuleId> net_sink_modules(const ModuleId& module, const ModuleNetId& net) const;
/* Find the ids of sink instances of a net */
std::vector<size_t> net_sink_instances(const ModuleId& module, const ModuleNetId& net) const;
/* Find the sink ports of a net */
std::vector<ModulePortId> net_sink_ports(const ModuleId& module, const ModuleNetId& net) const;
/* Find the sink pin indices of a net */
std::vector<size_t> net_sink_pins(const ModuleId& module, const ModuleNetId& net) const;
public: /* Public mutators */
/* Add a module */
ModuleId add_module(const std::string& name);

View File

@ -0,0 +1,85 @@
/********************************************************************
* This file includes functions to write a Verilog module
* based on its definition in Module Manager
*
* Note that Verilog writer functions are just an outputter for the
* module definition.
* You should NOT modify any content of the module manager
* Please use const keyword to restrict this!
*******************************************************************/
#include "vtr_assert.h"
#include "fpga_x2p_utils.h"
#include "verilog_writer_utils.h"
#include "verilog_module_writer.h"
/********************************************************************
* Collect all the nets that are going to be local wires
* And organize it in a vector of ports
* Verilog wire writter function will use the output of this function
* to write up local wire declaration in Verilog format
*
* Here is the strategy to identify local wires:
* Iterate over the nets inside the module.
* A net is a local wire if it connects between two instances,
* This is valid when all the sinks of the net are pins/ports of instances
*******************************************************************/
static
std::vector<BasicPort> find_verilog_module_local_wires(const ModuleManager& module_manager,
const ModuleId& module_id) {
std::vector<BasicPort> local_wire_ports;
/* Find local wires between instances */
for (ModuleNetId module_net : module_manager.module_nets(module_id)) {
/* A flag to identify local wire */
bool is_local_wire = false;
/* Each net must only one 1 source */
VTR_ASSERT(1 == module_manager.net_source_modules(module_id, module_net).size());
/* Check if source module is the module itself */
if (module_id != module_manager.net_source_modules(module_id, module_net)[0]) {
is_local_wire = true;
}
/* Check all the sink modules of the net */
for (ModuleId sink_module : module_manager.net_sink_modules(module_id, module_net)) {
if (module_id == sink_module) {
is_local_wire = false;
}
}
/* TODO: Push the Verilog port the list, try to combine the ports if we can */
}
return local_wire_ports;
}
/********************************************************************
* Write a Verilog module to a file
* This is a key function, maybe most frequently called in our Verilog writer
* Note that file stream must be valid
*******************************************************************/
void writer_verilog_module_to_file(std::fstream& fp,
const ModuleManager& module_manager,
const ModuleId& module_id) {
/* Ensure a valid file stream */
check_file_handler(fp);
/* Ensure we have a valid module_id */
VTR_ASSERT(module_manager.valid_module_id(module_id));
/* Print module declaration */
print_verilog_module_declaration(fp, module_manager, module_id);
/* TODO: Print internal wires */
/* TODO: Print instances */
for (ModuleId child_module : module_manager.child_modules(module_id)) {
for (size_t instance : module_manager.child_module_instances(module_id, child_module)) {
/* Print an instance */
}
}
/* Print an end for the module */
print_verilog_module_end(fp, module_manager.module_name(module_id));
}

View File

@ -0,0 +1,15 @@
/********************************************************************
* Header file for verilog_module_writer.cpp
*******************************************************************/
#ifndef VERILOG_MODULE_WRITER_H
#define VERILOG_MODULE_WRITER_H
#include <fstream>
#include "module_manager.h"
void writer_verilog_module_to_file(std::fstream& fp,
const ModuleManager& module_manager,
const ModuleId& module_id);
#endif

View File

@ -7,6 +7,7 @@
#define VERILOG_WRITER_UTILS_H
#include <string>
#include "verilog_global.h"
#include "device_port.h"
#include "module_manager.h"