add missing files and developing essential gates
This commit is contained in:
parent
60e8d2b29f
commit
5f55fc7b49
|
@ -1 +1 @@
|
|||
run002
|
||||
run003
|
|
@ -202,7 +202,7 @@ size_t check_one_circuit_model_port_type_and_size_required(const CircuitLibrary&
|
|||
|
||||
size_t num_err = 0;
|
||||
|
||||
std::vector<CircuitPortId> ports = circuit_lib.model_ports_by_type(circuit_model, port_type_to_check, include_global_ports);
|
||||
std::vector<CircuitPortId> ports = circuit_lib.model_ports_by_type(circuit_model, port_type_to_check, false == include_global_ports);
|
||||
if (num_ports_to_check != ports.size()) {
|
||||
vpr_printf(TIO_MESSAGE_ERROR,
|
||||
"Expect %d %s ports for a %s circuit model, but only have %d %s ports!\n",
|
||||
|
|
|
@ -352,6 +352,30 @@ std::vector<CircuitPortId> CircuitLibrary::model_global_ports(const CircuitModel
|
|||
return global_ports;
|
||||
}
|
||||
|
||||
/* Recursively find all the global ports in the circuit model / sub circuit_model */
|
||||
std::vector<CircuitPortId> CircuitLibrary::model_global_ports_by_type(const CircuitModelId& model_id,
|
||||
const enum e_spice_model_port_type& type) const {
|
||||
/* validate the model_id */
|
||||
VTR_ASSERT(valid_model_id(model_id));
|
||||
|
||||
/* Search all the ports */
|
||||
std::vector<CircuitPortId> global_ports;
|
||||
for (auto port : model_ports(model_id)) {
|
||||
/* By pass non-global ports*/
|
||||
if (false == port_is_global(port)) {
|
||||
continue;
|
||||
}
|
||||
/* We skip unmatched ports */
|
||||
if ( type != port_type(port) ) {
|
||||
continue;
|
||||
}
|
||||
/* This is a global port, update global_ports */
|
||||
global_ports.push_back(port);
|
||||
}
|
||||
|
||||
return global_ports;
|
||||
}
|
||||
|
||||
/* Find the ports of a circuit model by a given type, return a list of qualified ports */
|
||||
std::vector<CircuitPortId> CircuitLibrary::model_ports_by_type(const CircuitModelId& model_id,
|
||||
const enum e_spice_model_port_type& type) const {
|
||||
|
@ -371,7 +395,7 @@ std::vector<CircuitPortId> CircuitLibrary::model_ports_by_type(const CircuitMode
|
|||
*/
|
||||
std::vector<CircuitPortId> CircuitLibrary::model_ports_by_type(const CircuitModelId& model_id,
|
||||
const enum e_spice_model_port_type& type,
|
||||
const bool& include_global_port) const {
|
||||
const bool& ignore_global_port) const {
|
||||
std::vector<CircuitPortId> port_ids;
|
||||
for (const auto& port_id : model_port_lookup_[model_id][type]) {
|
||||
/* We skip unmatched ports */
|
||||
|
@ -379,7 +403,7 @@ std::vector<CircuitPortId> CircuitLibrary::model_ports_by_type(const CircuitMode
|
|||
continue;
|
||||
}
|
||||
/* We skip global ports if specified */
|
||||
if ( (false == include_global_port)
|
||||
if ( (true == ignore_global_port)
|
||||
&& (true == port_is_global(port_id)) ) {
|
||||
continue;
|
||||
}
|
||||
|
@ -388,7 +412,6 @@ std::vector<CircuitPortId> CircuitLibrary::model_ports_by_type(const CircuitMode
|
|||
return port_ids;
|
||||
}
|
||||
|
||||
|
||||
/* Create a vector for all the ports whose directionality is input
|
||||
* This includes all the ports other than whose types are OUPUT or INOUT
|
||||
*/
|
||||
|
|
|
@ -233,6 +233,8 @@ class CircuitLibrary {
|
|||
size_t num_model_ports_by_type(const CircuitModelId& model_id, const enum e_spice_model_port_type& port_type, const bool& include_global_port) const;
|
||||
std::vector<CircuitPortId> model_ports(const CircuitModelId& model_id) const;
|
||||
std::vector<CircuitPortId> model_global_ports(const CircuitModelId& model_id) const;
|
||||
std::vector<CircuitPortId> model_global_ports_by_type(const CircuitModelId& model_id,
|
||||
const enum e_spice_model_port_type& type) const;
|
||||
std::vector<CircuitPortId> model_ports_by_type(const CircuitModelId& model_id, const enum e_spice_model_port_type& port_type) const;
|
||||
std::vector<CircuitPortId> model_ports_by_type(const CircuitModelId& model_id, const enum e_spice_model_port_type& port_type, const bool& include_global_port) const;
|
||||
std::vector<CircuitPortId> model_input_ports(const CircuitModelId& model_id) const;
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
/************************************************
|
||||
* This file includes functions to
|
||||
* generate module/port names for Verilog
|
||||
* and SPICE netlists
|
||||
***********************************************/
|
||||
#include "vtr_assert.h"
|
||||
|
||||
#include "fpga_x2p_naming.h"
|
||||
|
||||
/************************************************
|
||||
* Generate the module name for a multiplexer in Verilog format
|
||||
***********************************************/
|
||||
std::string generate_verilog_mux_subckt_name(const CircuitLibrary& circuit_lib,
|
||||
const CircuitModelId& circuit_model,
|
||||
const size_t& mux_size,
|
||||
const std::string& postfix) {
|
||||
std::string module_name = circuit_lib.model_name(circuit_model);
|
||||
module_name += "_size";
|
||||
module_name += std::to_string(mux_size);
|
||||
module_name += postfix;
|
||||
|
||||
return module_name;
|
||||
}
|
||||
|
||||
/************************************************
|
||||
* Generate the module name of a branch for a
|
||||
* multiplexer in Verilog format
|
||||
***********************************************/
|
||||
std::string generate_verilog_mux_branch_subckt_name(const CircuitLibrary& circuit_lib,
|
||||
const CircuitModelId& circuit_model,
|
||||
const size_t& mux_size,
|
||||
const std::string& postfix) {
|
||||
/* If the tgate spice model of this MUX is a MUX2 standard cell,
|
||||
* the mux_subckt name will be the name of the standard cell
|
||||
*/
|
||||
CircuitModelId subckt_model = circuit_lib.pass_gate_logic_model(circuit_model);
|
||||
if (SPICE_MODEL_GATE == circuit_lib.model_type(subckt_model)) {
|
||||
VTR_ASSERT (SPICE_MODEL_GATE_MUX2 == circuit_lib.gate_type(subckt_model));
|
||||
return circuit_lib.model_name(subckt_model);
|
||||
}
|
||||
|
||||
return generate_verilog_mux_subckt_name(circuit_lib, circuit_model, mux_size, postfix);
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
/************************************************
|
||||
* Header file for fpga_x2p_naming.cpp
|
||||
* Include functions to generate module/port names
|
||||
* for Verilog and SPICE netlists
|
||||
***********************************************/
|
||||
|
||||
#ifndef FPGA_X2P_NAMING_H
|
||||
#define FPGA_X2P_NAMING_H
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "circuit_library.h"
|
||||
|
||||
std::string generate_verilog_mux_subckt_name(const CircuitLibrary& circuit_lib,
|
||||
const CircuitModelId& circuit_model,
|
||||
const size_t& mux_size,
|
||||
const std::string& posfix) ;
|
||||
|
||||
std::string generate_verilog_mux_branch_subckt_name(const CircuitLibrary& circuit_lib,
|
||||
const CircuitModelId& circuit_model,
|
||||
const size_t& mux_size,
|
||||
const std::string& posfix);
|
||||
|
||||
#endif
|
|
@ -12,6 +12,7 @@
|
|||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <algorithm>
|
||||
|
||||
/* Include vpr structs*/
|
||||
#include "util.h"
|
||||
|
@ -63,6 +64,7 @@ char* my_gettime() {
|
|||
return c_time_string;
|
||||
}
|
||||
|
||||
|
||||
char* format_dir_path(char* dir_path) {
|
||||
int len = strlen(dir_path); /* String length without the last "\0"*/
|
||||
int i;
|
||||
|
@ -82,6 +84,26 @@ char* format_dir_path(char* dir_path) {
|
|||
return ret;
|
||||
}
|
||||
|
||||
/************************************************
|
||||
* Format a path of directory:
|
||||
* 1. Replace "\" with "/"
|
||||
* 2. add a "/" if the string does not end with a "/"
|
||||
***********************************************/
|
||||
std::string format_dir_path(const std::string& dir_path) {
|
||||
std::string ret = dir_path;
|
||||
|
||||
/* Replace "\" with "/" */
|
||||
std::replace(ret.begin(), ret.end(), '\\', '/');
|
||||
|
||||
/* Complete the string with a "/" if it does not end with that */
|
||||
if ('/' != ret.back()) {
|
||||
ret.push_back('/');
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int try_access_file(char* file_path) {
|
||||
/* F_OK checks existence and also R_OK, W_OK, X_OK,
|
||||
* for readable, writable, excutable
|
||||
|
@ -3228,7 +3250,7 @@ int count_cb_info_num_ipin_rr_nodes(t_cb cur_cb_info) {
|
|||
|
||||
/* Add a subckt file name to a linked list */
|
||||
t_llist* add_one_subckt_file_name_to_llist(t_llist* cur_head,
|
||||
char* subckt_file_path) {
|
||||
const char* subckt_file_path) {
|
||||
t_llist* new_head = NULL;
|
||||
|
||||
if (NULL == cur_head) {
|
||||
|
|
|
@ -10,7 +10,8 @@ void check_file_handler(std::fstream& fp);
|
|||
|
||||
char* my_gettime();
|
||||
|
||||
char* format_dir_path(char* dir_path);
|
||||
char* format_dir_path(char* dir_path); /* TODO: TO BE REMOVED !!! */
|
||||
std::string format_dir_path(const std::string& dir_path);
|
||||
|
||||
int try_access_file(char* file_path);
|
||||
|
||||
|
@ -380,7 +381,7 @@ boolean is_cb_exist(t_rr_type cb_type,
|
|||
int count_cb_info_num_ipin_rr_nodes(t_cb cur_cb_info);
|
||||
|
||||
t_llist* add_one_subckt_file_name_to_llist(t_llist* cur_head,
|
||||
char* subckt_file_path);
|
||||
const char* subckt_file_path);
|
||||
|
||||
boolean check_subckt_file_exist_in_llist(t_llist* subckt_llist_head,
|
||||
char* subckt_file_name);
|
||||
|
|
|
@ -16,12 +16,253 @@
|
|||
|
||||
/* FPGA-Verilog context header files */
|
||||
#include "verilog_global.h"
|
||||
#include "verilog_writer_utils.h"
|
||||
#include "verilog_submodule_essential.h"
|
||||
|
||||
void dump_verilog_submodule_essentials(const std::string& verilog_dir,
|
||||
const std::string& submodule_dir,
|
||||
const CircuitLibrary& circuit_lib) {
|
||||
std::string verilog_fname = submodule_dir + essentials_verilog_file_name;
|
||||
|
||||
/************************************************
|
||||
* Print a Verilog module of inverter or buffer
|
||||
* or tapered buffer to a file
|
||||
***********************************************/
|
||||
static
|
||||
void print_verilog_invbuf_module(std::fstream& fp,
|
||||
const CircuitLibrary& circuit_lib,
|
||||
const CircuitModelId& circuit_model) {
|
||||
/* Ensure a valid file handler*/
|
||||
check_file_handler(fp);
|
||||
|
||||
fp << "//----- Verilog module for " << circuit_lib.model_name(circuit_model) << " -----" << std::endl;
|
||||
|
||||
/* Find the input port, output port and global inputs*/
|
||||
std::vector<CircuitPortId> input_ports = circuit_lib.model_ports_by_type(circuit_model, SPICE_MODEL_PORT_INPUT, true);
|
||||
std::vector<CircuitPortId> output_ports = circuit_lib.model_ports_by_type(circuit_model, SPICE_MODEL_PORT_OUTPUT, true);
|
||||
std::vector<CircuitPortId> global_ports = circuit_lib.model_global_ports_by_type(circuit_model, SPICE_MODEL_PORT_INPUT);
|
||||
|
||||
/* Make sure:
|
||||
* There is only 1 input port and 1 output port,
|
||||
* each size of which is 1
|
||||
*/
|
||||
VTR_ASSERT( (1 == input_ports.size()) && (1 == circuit_lib.port_size(input_ports[0])) );
|
||||
VTR_ASSERT( (1 == output_ports.size()) && (1 == circuit_lib.port_size(output_ports[0])) );
|
||||
|
||||
/* TODO: move the check codes to check_circuit_library.h */
|
||||
/* If the circuit model is power-gated, we need to find at least one global config_enable signals */
|
||||
if (true == circuit_lib.is_power_gated(circuit_model)) {
|
||||
/* Check all the ports we have are good for a power-gated circuit model */
|
||||
size_t num_err = 0;
|
||||
/* We need at least one global port */
|
||||
if (0 == global_ports.size()) {
|
||||
num_err++;
|
||||
}
|
||||
/* All the global ports should be config_enable */
|
||||
for (const auto& port : global_ports) {
|
||||
if (false == circuit_lib.port_is_config_enable(port)) {
|
||||
num_err++;
|
||||
}
|
||||
}
|
||||
/* Report errors if there are any */
|
||||
if (0 < num_err) {
|
||||
vpr_printf(TIO_MESSAGE_ERROR,
|
||||
"Inverter/buffer circuit model (name=%s) is power-gated. At least one config-enable global port is required!\n",
|
||||
circuit_lib.model_name(circuit_model).c_str());
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
/* dump module body */
|
||||
fp << "module " << circuit_lib.model_name(circuit_model) << " (" << std::endl;
|
||||
|
||||
/* TODO: print global ports */
|
||||
for (const auto& port : global_ports) {
|
||||
BasicPort basic_port;
|
||||
/* Configure each input port */
|
||||
basic_port.set_name(circuit_lib.port_prefix(port));
|
||||
basic_port.set_width(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;
|
||||
/* Finish dumping ports */
|
||||
|
||||
// /* Assign logics : depending on topology */
|
||||
// switch (invbuf_spice_model->design_tech_info.buffer_info->type) {
|
||||
// case SPICE_MODEL_BUF_INV:
|
||||
// if (TRUE == invbuf_spice_model->design_tech_info.power_gated) {
|
||||
// /* Create a sensitive list */
|
||||
// fprintf(fp, "reg %s_reg;\n", output_port[0]->lib_name);
|
||||
// fprintf(fp, "always @(");
|
||||
// /* Power-gate port first*/
|
||||
// for (iport = 0; iport < num_powergate_port; iport++) {
|
||||
// fprintf(fp, "%s,", powergate_port[iport]->lib_name);
|
||||
// }
|
||||
// fprintf(fp, "%s) begin\n",
|
||||
// input_port[0]->lib_name);
|
||||
// /* Dump the case of power-gated */
|
||||
// fprintf(fp, " if (");
|
||||
// port_cnt = 0; /* Initialize the counter: decide if we need to put down '&&' */
|
||||
// for (iport = 0; iport < num_powergate_port; iport++) {
|
||||
// if (0 == powergate_port[iport]->default_val) {
|
||||
// for (ipin = 0; ipin < powergate_port[iport]->size; ipin++) {
|
||||
// if ( 0 < port_cnt ) {
|
||||
// fprintf(fp, "\n\t&&");
|
||||
// }
|
||||
// /* Power-gated signal are disable during operating, enabled during configuration,
|
||||
// * Therefore, we need to reverse them here
|
||||
// */
|
||||
// fprintf(fp, "(~%s[%d])",
|
||||
// powergate_port[iport]->lib_name,
|
||||
// ipin);
|
||||
// port_cnt++; /* Update port counter*/
|
||||
// }
|
||||
// } else {
|
||||
// assert (1 == powergate_port[iport]->default_val);
|
||||
// for (ipin = 0; ipin < powergate_port[iport]->size; ipin++) {
|
||||
// if ( 0 < port_cnt ) {
|
||||
// fprintf(fp, "\n\t&&");
|
||||
// }
|
||||
// /* Power-gated signal are disable during operating, enabled during configuration,
|
||||
// * Therefore, we need to reverse them here
|
||||
// */
|
||||
// fprintf(fp, "(%s[%d])",
|
||||
// powergate_port[iport]->lib_name,
|
||||
// ipin);
|
||||
// port_cnt++; /* Update port counter*/
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// fprintf(fp, ") begin\n");
|
||||
// fprintf(fp, "\t\tassign %s_reg = ~%s;\n",
|
||||
// output_port[0]->lib_name,
|
||||
// input_port[0]->lib_name);
|
||||
// fprintf(fp, "\tend else begin\n");
|
||||
// fprintf(fp, "\t\tassign %s_reg = 1'bz;\n",
|
||||
// output_port[0]->lib_name);
|
||||
// fprintf(fp, "\tend\n");
|
||||
// fprintf(fp, "end\n");
|
||||
// fprintf(fp, "assign %s = %s_reg;\n",
|
||||
// output_port[0]->lib_name,
|
||||
// output_port[0]->lib_name);
|
||||
// } else {
|
||||
// fprintf(fp, "assign %s = (%s === 1'bz)? $random : ~%s;\n",
|
||||
// output_port[0]->lib_name,
|
||||
// input_port[0]->lib_name,
|
||||
// input_port[0]->lib_name);
|
||||
// }
|
||||
// break;
|
||||
// case SPICE_MODEL_BUF_BUF:
|
||||
// if (TRUE == invbuf_spice_model->design_tech_info.power_gated) {
|
||||
// /* Create a sensitive list */
|
||||
// fprintf(fp, "reg %s_reg;\n", output_port[0]->lib_name);
|
||||
// fprintf(fp, "always @(");
|
||||
// /* Power-gate port first*/
|
||||
// for (iport = 0; iport < num_powergate_port; iport++) {
|
||||
// fprintf(fp, "%s,", powergate_port[iport]->lib_name);
|
||||
// }
|
||||
// fprintf(fp, "%s) begin\n",
|
||||
// input_port[0]->lib_name);
|
||||
// /* Dump the case of power-gated */
|
||||
// fprintf(fp, " if (");
|
||||
// port_cnt = 0; /* Initialize the counter: decide if we need to put down '&&' */
|
||||
// for (iport = 0; iport < num_powergate_port; iport++) {
|
||||
// if (0 == powergate_port[iport]->default_val) {
|
||||
// for (ipin = 0; ipin < powergate_port[iport]->size; ipin++) {
|
||||
// if ( 0 < port_cnt ) {
|
||||
// fprintf(fp, "\n\t&&");
|
||||
// }
|
||||
// /* Power-gated signal are disable during operating, enabled during configuration,
|
||||
// * Therefore, we need to reverse them here
|
||||
// */
|
||||
// fprintf(fp, "(~%s[%d])",
|
||||
// powergate_port[iport]->lib_name,
|
||||
// ipin);
|
||||
// port_cnt++; /* Update port counter*/
|
||||
// }
|
||||
// } else {
|
||||
// assert (1 == powergate_port[iport]->default_val);
|
||||
// for (ipin = 0; ipin < powergate_port[iport]->size; ipin++) {
|
||||
// if ( 0 < port_cnt ) {
|
||||
// fprintf(fp, "\n\t&&");
|
||||
// }
|
||||
// /* Power-gated signal are disable during operating, enabled during configuration,
|
||||
// * Therefore, we need to reverse them here
|
||||
// */
|
||||
// fprintf(fp, "(%s[%d])",
|
||||
// powergate_port[iport]->lib_name,
|
||||
// ipin);
|
||||
// port_cnt++; /* Update port counter*/
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// fprintf(fp, ") begin\n");
|
||||
// fprintf(fp, "\t\tassign %s_reg = %s;\n",
|
||||
// output_port[0]->lib_name,
|
||||
// input_port[0]->lib_name);
|
||||
// fprintf(fp, "\tend else begin\n");
|
||||
// fprintf(fp, "\t\tassign %s_reg = 1'bz;\n",
|
||||
// output_port[0]->lib_name);
|
||||
// fprintf(fp, "\tend\n");
|
||||
// fprintf(fp, "end\n");
|
||||
// fprintf(fp, "assign %s = %s_reg;\n",
|
||||
// output_port[0]->lib_name,
|
||||
// output_port[0]->lib_name);
|
||||
//
|
||||
// } else if (FALSE == invbuf_spice_model->design_tech_info.buffer_info->tapered_buf) {
|
||||
// fprintf(fp, "assign %s = (%s === 1'bz)? $random : %s;\n",
|
||||
// output_port[0]->lib_name,
|
||||
// input_port[0]->lib_name,
|
||||
// input_port[0]->lib_name);
|
||||
// } else {
|
||||
// assert (TRUE == invbuf_spice_model->design_tech_info.buffer_info->tapered_buf);
|
||||
// fprintf(fp, "assign %s = (%s === 1'bz)? $random : ",
|
||||
// output_port[0]->lib_name,
|
||||
// input_port[0]->lib_name);
|
||||
// /* depend on the stage, we may invert the output */
|
||||
// if (1 == invbuf_spice_model->design_tech_info.buffer_info->tap_buf_level % 2) {
|
||||
// fprintf(fp, "~");
|
||||
// }
|
||||
// fprintf(fp, "%s;\n",
|
||||
// input_port[0]->lib_name);
|
||||
// }
|
||||
// break;
|
||||
// default:
|
||||
// vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid topology for spice model (%s)!\n",
|
||||
// __FILE__, __LINE__, invbuf_spice_model->name);
|
||||
// exit(1);
|
||||
// }
|
||||
//
|
||||
// /* Print timing info */
|
||||
// dump_verilog_submodule_timing(fp, invbuf_spice_model);
|
||||
//
|
||||
// dump_verilog_submodule_signal_init(fp, invbuf_spice_model);
|
||||
|
||||
fp << "endmodule" << std::endl << std::endl;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/************************************************
|
||||
* Generate the Verilog netlist for essential gates
|
||||
* include inverters, buffers, transmission-gates,
|
||||
* etc.
|
||||
***********************************************/
|
||||
void print_verilog_submodule_essentials(const std::string& verilog_dir,
|
||||
const std::string& submodule_dir,
|
||||
const CircuitLibrary& circuit_lib) {
|
||||
/* TODO: remove .bak when this part is completed and tested */
|
||||
std::string verilog_fname = submodule_dir + essentials_verilog_file_name + ".bak";
|
||||
std::fstream fp;
|
||||
|
||||
/* Create the file stream */
|
||||
|
@ -33,9 +274,34 @@ void dump_verilog_submodule_essentials(const std::string& verilog_dir,
|
|||
vpr_printf(TIO_MESSAGE_INFO,
|
||||
"Generating Verilog netlist (%s) for essential gates...\n",
|
||||
__FILE__, __LINE__, essentials_verilog_file_name);
|
||||
|
||||
print_verilog_file_header(fp, "Essential gates");
|
||||
|
||||
print_verilog_include_defines_preproc_file(fp, verilog_dir);
|
||||
|
||||
for (const auto& circuit_model : circuit_lib.models()) {
|
||||
/* By pass user-defined modules */
|
||||
if (!circuit_lib.model_verilog_netlist(circuit_model).empty()) {
|
||||
continue;
|
||||
}
|
||||
if (SPICE_MODEL_INVBUF == circuit_lib.model_type(circuit_model)) {
|
||||
print_verilog_invbuf_module(fp, circuit_lib, circuit_model);
|
||||
}
|
||||
/*
|
||||
if (SPICE_MODEL_PASSGATE == spice_models[imodel].type) {
|
||||
dump_verilog_passgate_module(fp, &(spice_models[imodel]));
|
||||
}
|
||||
if (SPICE_MODEL_GATE == spice_models[imodel].type) {
|
||||
dump_verilog_gate_module(fp, &(spice_models[imodel]));
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
/* Close file handler*/
|
||||
fp.close();
|
||||
|
||||
/* Add fname to the linked list */
|
||||
submodule_verilog_subckt_file_path_head = add_one_subckt_file_name_to_llist(submodule_verilog_subckt_file_path_head, verilog_fname.c_str());
|
||||
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -12,8 +12,8 @@
|
|||
#include <string>
|
||||
#include "circuit_library.h"
|
||||
|
||||
void dump_verilog_submodule_essentials(const std::string& verilog_dir,
|
||||
const std::string& submodule_dir,
|
||||
const CircuitLibrary& circuit_lib);
|
||||
void print_verilog_submodule_essentials(const std::string& verilog_dir,
|
||||
const std::string& submodule_dir,
|
||||
const CircuitLibrary& circuit_lib);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -45,8 +45,9 @@ void generate_verilog_cmos_mux_branch_module_structural(std::fstream& fp,
|
|||
}
|
||||
|
||||
/* Get model ports of tgate */
|
||||
std::vector<CircuitPortId> tgate_input_ports = circuit_lib.model_ports_by_type(tgate_model, SPICE_MODEL_PORT_INPUT);
|
||||
std::vector<CircuitPortId> tgate_output_ports = circuit_lib.model_ports_by_type(tgate_model, SPICE_MODEL_PORT_OUTPUT);
|
||||
std::vector<CircuitPortId> tgate_input_ports = circuit_lib.model_ports_by_type(tgate_model, SPICE_MODEL_PORT_INPUT, true);
|
||||
std::vector<CircuitPortId> tgate_output_ports = circuit_lib.model_ports_by_type(tgate_model, SPICE_MODEL_PORT_OUTPUT, true);
|
||||
std::vector<CircuitPortId> tgate_global_ports = circuit_lib.model_global_ports_by_type(tgate_model, SPICE_MODEL_PORT_INPUT);
|
||||
VTR_ASSERT(3 == tgate_input_ports.size());
|
||||
VTR_ASSERT(1 == tgate_output_ports.size());
|
||||
|
||||
|
@ -95,7 +96,14 @@ void generate_verilog_cmos_mux_branch_module_structural(std::fstream& fp,
|
|||
mem_inv_port.set_width(num_mems);
|
||||
|
||||
/* TODO: Generate global ports */
|
||||
|
||||
for (const auto& port : tgate_global_ports) {
|
||||
BasicPort basic_port;
|
||||
/* Configure each input port */
|
||||
basic_port.set_name(circuit_lib.port_prefix(port));
|
||||
basic_port.set_width(circuit_lib.port_size(port));
|
||||
/* Print port */
|
||||
fp << "\t" << generate_verilog_port(VERILOG_PORT_INPUT, basic_port) << "," << std::endl;
|
||||
}
|
||||
|
||||
/* TODO: add a module to the Module Manager */
|
||||
|
||||
|
@ -116,6 +124,7 @@ void generate_verilog_cmos_mux_branch_module_structural(std::fstream& fp,
|
|||
/* Transmission gates are connected to each input and also the output*/
|
||||
fp << "\t" << circuit_lib.model_name(tgate_model) << " " << circuit_lib.model_prefix(tgate_model) << "_0 ";
|
||||
/* Dump explicit port map if required */
|
||||
/* TODO: add global port support for tgate model */
|
||||
if (true == circuit_lib.dump_explicit_port_map(tgate_model)) {
|
||||
fp << " (";
|
||||
fp << " ." << circuit_lib.port_lib_name(tgate_input_ports[0]) << "(" << "in[0]" << "),";
|
||||
|
|
|
@ -2,17 +2,64 @@
|
|||
* Include functions for most frequently
|
||||
* used Verilog writers
|
||||
***********************************************/
|
||||
#include <chrono>
|
||||
#include <ctime>
|
||||
#include <string>
|
||||
#include <fstream>
|
||||
#include "vtr_assert.h"
|
||||
|
||||
/* Device-level header files */
|
||||
|
||||
/* FPGA-X2P context header files */
|
||||
#include "spice_types.h"
|
||||
#include "fpga_x2p_utils.h"
|
||||
|
||||
/* FPGA-Verilog context header files */
|
||||
#include "verilog_global.h"
|
||||
#include "verilog_writer_utils.h"
|
||||
|
||||
/************************************************
|
||||
* Generate header comments for a Verilog netlist
|
||||
* include the description
|
||||
***********************************************/
|
||||
void print_verilog_file_header(std::fstream& fp,
|
||||
const std::string& usage) {
|
||||
check_file_handler(fp);
|
||||
|
||||
auto end = std::chrono::system_clock::now();
|
||||
std::time_t end_time = std::chrono::system_clock::to_time_t(end);
|
||||
|
||||
fp << "//-------------------------------------------" << std::endl;
|
||||
fp << "//\tFPGA Synthesizable Verilog Netlist" << std::endl;
|
||||
fp << "//\tDescription: " << usage << std::endl;
|
||||
fp << "//\tAuthor: Xifan TANG" << std::endl;
|
||||
fp << "//\t Organization: University of Utah" << std::endl;
|
||||
fp << "//\tDate: " << std::ctime(&end_time) << std::endl;
|
||||
fp << "//-------------------------------------------" << std::endl;
|
||||
fp << "//----- Time scale -----" << std::endl;
|
||||
fp << "`timescale 1ns / 1ps" << std::endl;
|
||||
fp << "\n";
|
||||
}
|
||||
|
||||
|
||||
/************************************************
|
||||
* Generate include files for a Verilog netlist
|
||||
***********************************************/
|
||||
void print_verilog_include_defines_preproc_file(std::fstream& fp,
|
||||
const std::string& verilog_dir) {
|
||||
check_file_handler(fp);
|
||||
|
||||
/* Generate the file name */
|
||||
std::string include_file_path = format_dir_path(verilog_dir);
|
||||
include_file_path += defines_verilog_file_name;
|
||||
|
||||
fp << "//------ Include defines: preproc flags -----" << std::endl;
|
||||
fp << "`include \"" << include_file_path << "\"" << std::endl;
|
||||
fp << "//------ End Include defines: preproc flags -----" << std::endl;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* Generate a string of a Verilog port */
|
||||
std::string generate_verilog_port(const enum e_dump_verilog_port_type& verilog_port_type,
|
||||
const BasicPort& port_info) {
|
||||
|
|
|
@ -9,6 +9,12 @@
|
|||
#include <string>
|
||||
#include "device_port.h"
|
||||
|
||||
void print_verilog_file_header(std::fstream& fp,
|
||||
const std::string& usage);
|
||||
|
||||
void print_verilog_include_defines_preproc_file(std::fstream& fp,
|
||||
const std::string& verilog_dir);
|
||||
|
||||
std::string generate_verilog_port(const enum e_dump_verilog_port_type& dump_port_type,
|
||||
const BasicPort& port_info);
|
||||
|
||||
|
|
Loading…
Reference in New Issue