commit
c1da9e3ef1
|
@ -75,6 +75,9 @@ python3 openfpga_flow/scripts/run_fpga_task.py fabric_key/generate_vanilla_key -
|
|||
python3 openfpga_flow/scripts/run_fpga_task.py fabric_key/generate_random_key --debug --show_thread_logs
|
||||
python3 openfpga_flow/scripts/run_fpga_task.py fabric_key/load_external_key --debug --show_thread_logs
|
||||
|
||||
echo -e "Testing Power-gating designs";
|
||||
python3 openfpga_flow/scripts/run_fpga_task.py power_gated_design/power_gated_inverter --show_thread_logs --debug
|
||||
|
||||
# Verify MCNC big20 benchmark suite with ModelSim
|
||||
# Please make sure you have ModelSim installed in the environment
|
||||
# Otherwise, it will fail
|
||||
|
|
|
@ -302,7 +302,9 @@ size_t check_sram_circuit_model_ports(const CircuitLibrary& circuit_lib,
|
|||
return num_err;
|
||||
}
|
||||
|
||||
/* Check all the ports make sure, they satisfy the restriction */
|
||||
/************************************************************************
|
||||
* Check all the ports make sure, they satisfy the restriction
|
||||
***********************************************************************/
|
||||
static
|
||||
size_t check_circuit_library_ports(const CircuitLibrary& circuit_lib) {
|
||||
size_t num_err = 0;
|
||||
|
@ -435,6 +437,94 @@ size_t check_circuit_library_ports(const CircuitLibrary& circuit_lib) {
|
|||
return num_err;
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* Check the port requirements for a power-gated circuit model
|
||||
* - It must have at least 2 global ports and which are config enable signals
|
||||
* - It must have an Enable port which control power gating
|
||||
* - It must have an EnableB port which control power gating
|
||||
***********************************************************************/
|
||||
static
|
||||
int check_power_gated_circuit_model(const CircuitLibrary& circuit_lib,
|
||||
const CircuitModelId& circuit_model) {
|
||||
int num_err = 0;
|
||||
|
||||
std::vector<CircuitPortId> global_ports = circuit_lib.model_global_ports_by_type(circuit_model, CIRCUIT_MODEL_PORT_INPUT, true, true);
|
||||
|
||||
/* If the circuit model is power-gated, we need to find at least one global config_enable signals */
|
||||
VTR_ASSERT(true == circuit_lib.is_power_gated(circuit_model));
|
||||
/* Check all the ports we have are good for a power-gated circuit model */
|
||||
/* We need at least one global port */
|
||||
if (2 > global_ports.size()) {
|
||||
VTR_LOGF_ERROR(__FILE__, __LINE__,
|
||||
"Expect at least two global ports (a pair of EN/Enb) for circuit model '%s' which is power-gated!\n",
|
||||
circuit_lib.model_name(circuit_model).c_str());
|
||||
num_err++;
|
||||
}
|
||||
/* All the global ports should be config_enable */
|
||||
int num_config_enable_ports = 0;
|
||||
for (const auto& port : global_ports) {
|
||||
if (true == circuit_lib.port_is_config_enable(port)) {
|
||||
num_config_enable_ports++;
|
||||
}
|
||||
}
|
||||
|
||||
if (2 != num_config_enable_ports) {
|
||||
VTR_LOGF_ERROR(__FILE__, __LINE__,
|
||||
"Circuit model '%s' is power-gated. Two config-enable global ports are required!\n",
|
||||
circuit_lib.model_name(circuit_model).c_str());
|
||||
num_err++;
|
||||
}
|
||||
/* Report errors if there are any */
|
||||
if (0 < num_err) {
|
||||
return num_err;
|
||||
}
|
||||
|
||||
/* Try to find a pair of Enable and ENb ports from the global ports */
|
||||
CircuitPortId en_port = CircuitPortId::INVALID();
|
||||
CircuitPortId enb_port = CircuitPortId::INVALID();
|
||||
for (const auto& port : global_ports) {
|
||||
/* Focus on config_enable ports which are power-gate control signals */
|
||||
if (false == circuit_lib.port_is_config_enable(port)) {
|
||||
continue;
|
||||
}
|
||||
if (0 == circuit_lib.port_default_value(port)) {
|
||||
en_port = port;
|
||||
} else {
|
||||
VTR_ASSERT(1 == circuit_lib.port_default_value(port));
|
||||
enb_port = port;
|
||||
}
|
||||
}
|
||||
/* We must have valid EN/ENb ports */
|
||||
if (false == circuit_lib.valid_circuit_port_id(en_port)) {
|
||||
VTR_LOGF_ERROR(__FILE__, __LINE__,
|
||||
"Fail to find an enable port for the circuit model '%s' is power-gated!\n",
|
||||
circuit_lib.model_name(circuit_model).c_str());
|
||||
}
|
||||
if (false == circuit_lib.valid_circuit_port_id(enb_port)) {
|
||||
VTR_LOGF_ERROR(__FILE__, __LINE__,
|
||||
"Fail to find an inverted enable port for the circuit model '%s' is power-gated!\n",
|
||||
circuit_lib.model_name(circuit_model).c_str());
|
||||
}
|
||||
|
||||
return num_err;
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* Check the port requirements for each power-gated circuit model
|
||||
***********************************************************************/
|
||||
static
|
||||
int check_power_gated_circuit_models(const CircuitLibrary& circuit_lib) {
|
||||
int num_err = 0;
|
||||
|
||||
for (const CircuitModelId& circuit_model : circuit_lib.models()) {
|
||||
if (true == circuit_lib.is_power_gated(circuit_model)) {
|
||||
num_err += check_power_gated_circuit_model(circuit_lib, circuit_model);
|
||||
}
|
||||
}
|
||||
|
||||
return num_err;
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* Check points to make sure we have a valid circuit library
|
||||
* Detailed checkpoints:
|
||||
|
@ -541,6 +631,9 @@ bool check_circuit_library(const CircuitLibrary& circuit_lib) {
|
|||
num_err += check_required_default_circuit_model(circuit_lib, CIRCUIT_MODEL_CHAN_WIRE);
|
||||
num_err += check_required_default_circuit_model(circuit_lib, CIRCUIT_MODEL_WIRE);
|
||||
|
||||
/* 11. Check power-gated inverter/buffer models */
|
||||
num_err += check_power_gated_circuit_models(circuit_lib);
|
||||
|
||||
/* If we have any errors, exit */
|
||||
|
||||
if (0 < num_err) {
|
||||
|
|
|
@ -238,7 +238,7 @@ std::string generate_routing_block_netlist_name(const std::string& prefix,
|
|||
std::string generate_routing_block_netlist_name(const std::string& prefix,
|
||||
const vtr::Point<size_t>& coordinate,
|
||||
const std::string& postfix) {
|
||||
return std::string( prefix + std::to_string(coordinate.x()) + std::string("_") + std::to_string(coordinate.y()) + postfix );
|
||||
return std::string( prefix + std::to_string(coordinate.x()) + std::string("__") + std::to_string(coordinate.y()) + std::string("_") + postfix );
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
|
@ -968,10 +968,8 @@ std::string generate_mux_sram_port_name(const CircuitLibrary& circuit_lib,
|
|||
std::string generate_logical_tile_netlist_name(const std::string& prefix,
|
||||
const t_pb_graph_node* pb_graph_head,
|
||||
const std::string& postfix) {
|
||||
/* This must be the root node */
|
||||
VTR_ASSERT(true == pb_graph_head->is_root());
|
||||
/* Add the name of physical block */
|
||||
std::string module_name = prefix + std::string(pb_graph_head->pb_type->name);
|
||||
std::string module_name = prefix + generate_physical_block_module_name(pb_graph_head->pb_type);
|
||||
|
||||
module_name += postfix;
|
||||
|
||||
|
@ -1183,8 +1181,9 @@ std::string generate_grid_block_instance_name(const std::string& prefix,
|
|||
module_name += generate_grid_block_netlist_name(block_name, is_block_io, io_side, std::string());
|
||||
module_name += std::string("_");
|
||||
module_name += std::to_string(grid_coord.x());
|
||||
module_name += std::string("_");
|
||||
module_name += std::string("__");
|
||||
module_name += std::to_string(grid_coord.y());
|
||||
module_name += std::string("_");
|
||||
|
||||
return module_name;
|
||||
}
|
||||
|
@ -1244,7 +1243,6 @@ std::string generate_physical_block_module_name(t_pb_type* physical_pb_type) {
|
|||
return module_name;
|
||||
}
|
||||
|
||||
|
||||
/*********************************************************************
|
||||
* Generate the instance name for physical block with a given index
|
||||
**********************************************************************/
|
||||
|
|
|
@ -17,6 +17,8 @@
|
|||
/* Headers from openfpgautil library */
|
||||
#include "openfpga_digest.h"
|
||||
|
||||
#include "circuit_library_utils.h"
|
||||
|
||||
#include "spice_constants.h"
|
||||
#include "spice_writer_utils.h"
|
||||
#include "spice_essential_gates.h"
|
||||
|
@ -112,7 +114,157 @@ int print_spice_transistor_wrapper(NetlistManager& netlist_manager,
|
|||
}
|
||||
|
||||
/************************************************
|
||||
* Generate the SPICE subckt for an inverter
|
||||
* Generate the SPICE subckt for a power gated inverter
|
||||
* The Enable signal controlled the power gating
|
||||
* Schematic
|
||||
* LVDD
|
||||
* |
|
||||
* -
|
||||
* ENb[0] -o||
|
||||
* -
|
||||
* |
|
||||
* -
|
||||
* ENb[1] -o||
|
||||
* -
|
||||
* |
|
||||
* ...
|
||||
* |
|
||||
* -
|
||||
* +-o||
|
||||
* | -
|
||||
* | |
|
||||
* in-->+ +--> OUT
|
||||
* | |
|
||||
* | -
|
||||
* +--||
|
||||
* -
|
||||
* ...
|
||||
* |
|
||||
* -
|
||||
* EN[1] -||
|
||||
* -
|
||||
* |
|
||||
* -
|
||||
* EN[0] -||
|
||||
* -
|
||||
* |
|
||||
* LGND
|
||||
*
|
||||
***********************************************/
|
||||
static
|
||||
int print_spice_powergated_inverter_subckt(std::fstream& fp,
|
||||
const ModuleManager& module_manager,
|
||||
const ModuleId& module_id,
|
||||
const CircuitLibrary& circuit_lib,
|
||||
const CircuitModelId& circuit_model,
|
||||
const TechnologyLibrary& tech_lib,
|
||||
const TechnologyModelId& tech_model) {
|
||||
if (false == valid_file_stream(fp)) {
|
||||
return CMD_EXEC_FATAL_ERROR;
|
||||
}
|
||||
|
||||
/* Print the inverter subckt definition */
|
||||
print_spice_subckt_definition(fp, module_manager, module_id);
|
||||
|
||||
/* Find the input and output ports:
|
||||
* we do NOT support global ports here,
|
||||
* it should be handled in another type of inverter subckt (power-gated)
|
||||
*/
|
||||
std::vector<CircuitPortId> input_ports = circuit_lib.model_ports_by_type(circuit_model, CIRCUIT_MODEL_PORT_INPUT, true);
|
||||
std::vector<CircuitPortId> output_ports = circuit_lib.model_ports_by_type(circuit_model, CIRCUIT_MODEL_PORT_OUTPUT, true);
|
||||
|
||||
/* 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])) );
|
||||
|
||||
/* If the circuit model is power-gated, we need to find at least one global config_enable signals */
|
||||
VTR_ASSERT(true == circuit_lib.is_power_gated(circuit_model));
|
||||
CircuitPortId en_port = find_circuit_model_power_gate_en_port(circuit_lib, circuit_model);
|
||||
CircuitPortId enb_port = find_circuit_model_power_gate_enb_port(circuit_lib, circuit_model);
|
||||
VTR_ASSERT(true == circuit_lib.valid_circuit_port_id(en_port));
|
||||
VTR_ASSERT(true == circuit_lib.valid_circuit_port_id(enb_port));
|
||||
|
||||
/* TODO: may consider use size/bin to compact layout etc. */
|
||||
for (size_t i = 0; i < circuit_lib.buffer_size(circuit_model); ++i) {
|
||||
/* Write power-gating transistor pairs using the technology model
|
||||
* Note that for a mulit-bit power gating port, we should cascade the transistors
|
||||
*/
|
||||
bool first_enb_pin = true;
|
||||
size_t last_enb_pin;
|
||||
for (const auto& power_gate_pin : circuit_lib.pins(enb_port)) {
|
||||
BasicPort enb_pin(circuit_lib.port_prefix(enb_port), power_gate_pin, power_gate_pin);
|
||||
fp << "Xpmos_powergate_" << i << "_pin_" << power_gate_pin << " ";
|
||||
/* For the first pin, we should connect it to local VDD*/
|
||||
if (true == first_enb_pin) {
|
||||
fp << circuit_lib.port_prefix(output_ports[0]) << "_pmos_pg_" << power_gate_pin << " ";
|
||||
fp << generate_spice_port(enb_pin) << " ";
|
||||
fp << "LVDD ";
|
||||
fp << "LVDD ";
|
||||
first_enb_pin = false;
|
||||
} else {
|
||||
VTR_ASSERT_SAFE(false == first_enb_pin);
|
||||
fp << circuit_lib.port_prefix(output_ports[0]) << "_pmos_pg_" << last_enb_pin << " ";
|
||||
fp << generate_spice_port(enb_pin) << " ";
|
||||
fp << circuit_lib.port_prefix(output_ports[0]) << "_pmos_pg_" << power_gate_pin << " ";
|
||||
fp << "LVDD ";
|
||||
}
|
||||
fp << tech_lib.transistor_model_name(tech_model, TECH_LIB_TRANSISTOR_PMOS) << TRANSISTOR_WRAPPER_POSTFIX;
|
||||
|
||||
/* Cache the last pin*/
|
||||
last_enb_pin = power_gate_pin;
|
||||
}
|
||||
|
||||
bool first_en_pin = true;
|
||||
size_t last_en_pin;
|
||||
for (const auto& power_gate_pin : circuit_lib.pins(en_port)) {
|
||||
BasicPort en_pin(circuit_lib.port_prefix(en_port), power_gate_pin, power_gate_pin);
|
||||
fp << "Xnmos_powergate_" << i << "_pin_" << power_gate_pin << " ";
|
||||
/* For the first pin, we should connect it to local VDD*/
|
||||
if (true == first_en_pin) {
|
||||
fp << circuit_lib.port_prefix(output_ports[0]) << "_nmos_pg_" << power_gate_pin << " ";
|
||||
fp << generate_spice_port(en_pin) << " ";
|
||||
fp << "LGND ";
|
||||
fp << "LGND ";
|
||||
first_en_pin = false;
|
||||
} else {
|
||||
VTR_ASSERT_SAFE(false == first_enb_pin);
|
||||
fp << circuit_lib.port_prefix(output_ports[0]) << "_nmos_pg_" << last_en_pin << " ";
|
||||
fp << circuit_lib.port_prefix(en_port) << " ";
|
||||
fp << circuit_lib.port_prefix(output_ports[0]) << "_nmos_pg_" << power_gate_pin << " ";
|
||||
fp << "LGND ";
|
||||
}
|
||||
fp << tech_lib.transistor_model_name(tech_model, TECH_LIB_TRANSISTOR_NMOS) << TRANSISTOR_WRAPPER_POSTFIX;
|
||||
|
||||
/* Cache the last pin*/
|
||||
last_enb_pin = power_gate_pin;
|
||||
}
|
||||
|
||||
/* Write transistor pairs using the technology model */
|
||||
fp << "Xpmos_" << i << " ";
|
||||
fp << circuit_lib.port_prefix(output_ports[0]) << " ";
|
||||
fp << circuit_lib.port_prefix(input_ports[0]) << " ";
|
||||
fp << circuit_lib.port_prefix(output_ports[0]) << "_pmos_pg_" << circuit_lib.pins(enb_port).back() << " ";
|
||||
fp << "LVDD ";
|
||||
fp << tech_lib.transistor_model_name(tech_model, TECH_LIB_TRANSISTOR_PMOS) << TRANSISTOR_WRAPPER_POSTFIX;
|
||||
|
||||
fp << "Xnmos_" << i << " ";
|
||||
fp << circuit_lib.port_prefix(output_ports[0]) << " ";
|
||||
fp << circuit_lib.port_prefix(input_ports[0]) << " ";
|
||||
fp << circuit_lib.port_prefix(output_ports[0]) << " _nmos_pg_" << circuit_lib.pins(en_port).back() << " ";
|
||||
fp << "LGND ";
|
||||
fp << tech_lib.transistor_model_name(tech_model, TECH_LIB_TRANSISTOR_NMOS) << TRANSISTOR_WRAPPER_POSTFIX;
|
||||
}
|
||||
|
||||
print_spice_subckt_end(fp, module_manager.module_name(module_id));
|
||||
|
||||
return CMD_EXEC_SUCCESS;
|
||||
}
|
||||
|
||||
/************************************************
|
||||
* Generate the SPICE subckt for a regular inverter
|
||||
* Schematic
|
||||
* LVDD
|
||||
* |
|
||||
|
@ -130,7 +282,7 @@ int print_spice_transistor_wrapper(NetlistManager& netlist_manager,
|
|||
*
|
||||
***********************************************/
|
||||
static
|
||||
int print_spice_inverter_subckt(std::fstream& fp,
|
||||
int print_spice_regular_inverter_subckt(std::fstream& fp,
|
||||
const ModuleManager& module_manager,
|
||||
const ModuleId& module_id,
|
||||
const CircuitLibrary& circuit_lib,
|
||||
|
@ -181,6 +333,35 @@ int print_spice_inverter_subckt(std::fstream& fp,
|
|||
return CMD_EXEC_SUCCESS;
|
||||
}
|
||||
|
||||
/************************************************
|
||||
* Generate the SPICE subckt for an inverter
|
||||
* Branch on the different circuit topologies
|
||||
***********************************************/
|
||||
static
|
||||
int print_spice_inverter_subckt(std::fstream& fp,
|
||||
const ModuleManager& module_manager,
|
||||
const ModuleId& module_id,
|
||||
const CircuitLibrary& circuit_lib,
|
||||
const CircuitModelId& circuit_model,
|
||||
const TechnologyLibrary& tech_lib,
|
||||
const TechnologyModelId& tech_model) {
|
||||
int status = CMD_EXEC_SUCCESS;
|
||||
if (true == circuit_lib.is_power_gated(circuit_model)) {
|
||||
status = print_spice_powergated_inverter_subckt(fp,
|
||||
module_manager, module_id,
|
||||
circuit_lib, circuit_model,
|
||||
tech_lib, tech_model);
|
||||
} else {
|
||||
VTR_ASSERT_SAFE(false == circuit_lib.is_power_gated(circuit_model));
|
||||
status = print_spice_regular_inverter_subckt(fp,
|
||||
module_manager, module_id,
|
||||
circuit_lib, circuit_model,
|
||||
tech_lib, tech_model);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/************************************************
|
||||
* Generate the SPICE netlist for essential gates:
|
||||
* - inverters and their templates
|
||||
|
|
|
@ -45,14 +45,15 @@ void print_verilog_power_gated_invbuf_body(std::fstream& fp,
|
|||
/* Create a sensitive list */
|
||||
fp << "\treg " << circuit_lib.port_prefix(output_port) << "_reg;" << std::endl;
|
||||
|
||||
fp << "\talways @(" << std::endl;
|
||||
fp << "\talways @(";
|
||||
/* Power-gate port first*/
|
||||
for (const auto& power_gate_port : power_gate_ports) {
|
||||
/* Skip first comma to dump*/
|
||||
if (0 < &power_gate_port - &power_gate_ports[0]) {
|
||||
fp << ",";
|
||||
/* Only config_enable signal will be considered */
|
||||
if (false == circuit_lib.port_is_config_enable(power_gate_port)) {
|
||||
continue;
|
||||
}
|
||||
fp << circuit_lib.port_prefix(power_gate_port);
|
||||
fp << ", ";
|
||||
}
|
||||
fp << circuit_lib.port_prefix(input_port) << ") begin" << std::endl;
|
||||
|
||||
|
@ -61,6 +62,10 @@ void print_verilog_power_gated_invbuf_body(std::fstream& fp,
|
|||
/* For the first pin, we skip output comma */
|
||||
size_t port_cnt = 0;
|
||||
for (const auto& power_gate_port : power_gate_ports) {
|
||||
/* Only config_enable signal will be considered */
|
||||
if (false == circuit_lib.port_is_config_enable(power_gate_port)) {
|
||||
continue;
|
||||
}
|
||||
for (const auto& power_gate_pin : circuit_lib.pins(power_gate_port)) {
|
||||
if (0 < port_cnt) {
|
||||
fp << std::endl << "\t\t&&";
|
||||
|
@ -70,7 +75,7 @@ void print_verilog_power_gated_invbuf_body(std::fstream& fp,
|
|||
/* Power-gated signal are disable during operating, enabled during configuration,
|
||||
* Therefore, we need to reverse them here
|
||||
*/
|
||||
if (0 == circuit_lib.port_default_value(power_gate_port)) {
|
||||
if (1 == circuit_lib.port_default_value(power_gate_port)) {
|
||||
fp << "~";
|
||||
}
|
||||
|
||||
|
@ -161,30 +166,6 @@ void print_verilog_invbuf_module(const ModuleManager& module_manager,
|
|||
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) {
|
||||
VTR_LOGF_ERROR(__FILE__, __LINE__,
|
||||
"Inverter/buffer circuit model '%s' is power-gated. At least one config-enable global port is required!\n",
|
||||
circuit_lib.model_name(circuit_model).c_str());
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
/* Create a Verilog Module based on the circuit model, and add to module manager */
|
||||
ModuleId module_id = module_manager.find_module(circuit_lib.model_name(circuit_model));
|
||||
VTR_ASSERT(true == module_manager.valid_module_id(module_id));
|
||||
|
|
|
@ -63,14 +63,12 @@ namespace openfpga {
|
|||
*
|
||||
*******************************************************************/
|
||||
static
|
||||
void print_verilog_primitive_block(std::fstream& fp,
|
||||
void print_verilog_primitive_block(NetlistManager& netlist_manager,
|
||||
const ModuleManager& module_manager,
|
||||
const std::string& subckt_dir,
|
||||
t_pb_graph_node* primitive_pb_graph_node,
|
||||
const bool& use_explicit_mapping,
|
||||
const bool& verbose) {
|
||||
/* Ensure a valid file handler */
|
||||
VTR_ASSERT(true == valid_file_stream(fp));
|
||||
|
||||
/* Ensure a valid pb_graph_node */
|
||||
if (nullptr == primitive_pb_graph_node) {
|
||||
VTR_LOGF_ERROR(__FILE__, __LINE__,
|
||||
|
@ -78,6 +76,24 @@ void print_verilog_primitive_block(std::fstream& fp,
|
|||
exit(1);
|
||||
}
|
||||
|
||||
/* Give a name to the Verilog netlist */
|
||||
/* Create the file name for Verilog */
|
||||
std::string verilog_fname(subckt_dir
|
||||
+ generate_logical_tile_netlist_name(std::string(), primitive_pb_graph_node, std::string(VERILOG_NETLIST_FILE_POSTFIX))
|
||||
);
|
||||
|
||||
VTR_LOG("Writing Verilog netlist '%s' for primitive pb_type '%s' ...",
|
||||
verilog_fname.c_str(), primitive_pb_graph_node->pb_type->name);
|
||||
VTR_LOGV(verbose, "\n");
|
||||
|
||||
/* Create the file stream */
|
||||
std::fstream fp;
|
||||
fp.open(verilog_fname, std::fstream::out | std::fstream::trunc);
|
||||
|
||||
check_file_stream(verilog_fname.c_str(), fp);
|
||||
|
||||
print_verilog_file_header(fp, std::string("Verilog modules for primitive pb_type: " + std::string(primitive_pb_graph_node->pb_type->name)));
|
||||
|
||||
/* Generate the module name for this primitive pb_graph_node*/
|
||||
std::string primitive_module_name = generate_physical_block_module_name(primitive_pb_graph_node->pb_type);
|
||||
|
||||
|
@ -93,8 +109,13 @@ void print_verilog_primitive_block(std::fstream& fp,
|
|||
/* Write the verilog module */
|
||||
write_verilog_module_to_file(fp, module_manager, primitive_module, use_explicit_mapping);
|
||||
|
||||
/* Add an empty line as a splitter */
|
||||
fp << std::endl;
|
||||
/* Close file handler */
|
||||
fp.close();
|
||||
|
||||
/* Add fname to the netlist name list */
|
||||
NetlistId nlist_id = netlist_manager.add_netlist(verilog_fname);
|
||||
VTR_ASSERT(NetlistId::INVALID() != nlist_id);
|
||||
netlist_manager.set_netlist_type(nlist_id, NetlistManager::LOGIC_BLOCK_NETLIST);
|
||||
|
||||
VTR_LOGV(verbose, "Done\n");
|
||||
}
|
||||
|
@ -115,14 +136,13 @@ void print_verilog_primitive_block(std::fstream& fp,
|
|||
* to its parent in module manager
|
||||
*******************************************************************/
|
||||
static
|
||||
void rec_print_verilog_logical_tile(std::fstream& fp,
|
||||
void rec_print_verilog_logical_tile(NetlistManager& netlist_manager,
|
||||
const ModuleManager& module_manager,
|
||||
const VprDeviceAnnotation& device_annotation,
|
||||
const std::string& subckt_dir,
|
||||
t_pb_graph_node* physical_pb_graph_node,
|
||||
const bool& use_explicit_mapping,
|
||||
const bool& verbose) {
|
||||
/* Check the file handler*/
|
||||
VTR_ASSERT(true == valid_file_stream(fp));
|
||||
|
||||
/* Check cur_pb_graph_node*/
|
||||
if (nullptr == physical_pb_graph_node) {
|
||||
|
@ -143,8 +163,9 @@ void rec_print_verilog_logical_tile(std::fstream& fp,
|
|||
if (false == is_primitive_pb_type(physical_pb_type)) {
|
||||
for (int ipb = 0; ipb < physical_mode->num_pb_type_children; ++ipb) {
|
||||
/* Go recursive to visit the children */
|
||||
rec_print_verilog_logical_tile(fp,
|
||||
rec_print_verilog_logical_tile(netlist_manager,
|
||||
module_manager, device_annotation,
|
||||
subckt_dir,
|
||||
&(physical_pb_graph_node->child_pb_graph_nodes[physical_mode->index][ipb][0]),
|
||||
use_explicit_mapping,
|
||||
verbose);
|
||||
|
@ -156,7 +177,9 @@ void rec_print_verilog_logical_tile(std::fstream& fp,
|
|||
* explict port mapping. This aims to avoid any port sequence issues!!!
|
||||
*/
|
||||
if (true == is_primitive_pb_type(physical_pb_type)) {
|
||||
print_verilog_primitive_block(fp, module_manager,
|
||||
print_verilog_primitive_block(netlist_manager,
|
||||
module_manager,
|
||||
subckt_dir,
|
||||
physical_pb_graph_node,
|
||||
true,
|
||||
verbose);
|
||||
|
@ -164,6 +187,24 @@ void rec_print_verilog_logical_tile(std::fstream& fp,
|
|||
return;
|
||||
}
|
||||
|
||||
/* Give a name to the Verilog netlist */
|
||||
/* Create the file name for Verilog */
|
||||
std::string verilog_fname(subckt_dir
|
||||
+ generate_logical_tile_netlist_name(std::string(), physical_pb_graph_node, std::string(VERILOG_NETLIST_FILE_POSTFIX))
|
||||
);
|
||||
|
||||
VTR_LOG("Writing Verilog netlist '%s' for pb_type '%s' ...",
|
||||
verilog_fname.c_str(), physical_pb_type->name);
|
||||
VTR_LOGV(verbose, "\n");
|
||||
|
||||
/* Create the file stream */
|
||||
std::fstream fp;
|
||||
fp.open(verilog_fname, std::fstream::out | std::fstream::trunc);
|
||||
|
||||
check_file_stream(verilog_fname.c_str(), fp);
|
||||
|
||||
print_verilog_file_header(fp, std::string("Verilog modules for pb_type: " + std::string(physical_pb_type->name)));
|
||||
|
||||
/* Generate the name of the Verilog module for this pb_type */
|
||||
std::string pb_module_name = generate_physical_block_module_name(physical_pb_type);
|
||||
|
||||
|
@ -172,7 +213,7 @@ void rec_print_verilog_logical_tile(std::fstream& fp,
|
|||
VTR_ASSERT(true == module_manager.valid_module_id(pb_module));
|
||||
|
||||
VTR_LOGV(verbose,
|
||||
"Writing Verilog codes of logical tile block '%s'...",
|
||||
"Writing Verilog codes of pb_type '%s'...",
|
||||
module_manager.module_name(pb_module).c_str());
|
||||
|
||||
/* Comment lines */
|
||||
|
@ -183,8 +224,13 @@ void rec_print_verilog_logical_tile(std::fstream& fp,
|
|||
|
||||
print_verilog_comment(fp, std::string("----- END Physical programmable logic block Verilog module: " + std::string(physical_pb_type->name) + " -----"));
|
||||
|
||||
/* Add an empty line as a splitter */
|
||||
fp << std::endl;
|
||||
/* Close file handler */
|
||||
fp.close();
|
||||
|
||||
/* Add fname to the netlist name list */
|
||||
NetlistId nlist_id = netlist_manager.add_netlist(verilog_fname);
|
||||
VTR_ASSERT(NetlistId::INVALID() != nlist_id);
|
||||
netlist_manager.set_netlist_type(nlist_id, NetlistManager::LOGIC_BLOCK_NETLIST);
|
||||
|
||||
VTR_LOGV(verbose, "Done\n");
|
||||
}
|
||||
|
@ -201,23 +247,10 @@ void print_verilog_logical_tile_netlist(NetlistManager& netlist_manager,
|
|||
t_pb_graph_node* pb_graph_head,
|
||||
const bool& use_explicit_mapping,
|
||||
const bool& verbose) {
|
||||
/* Give a name to the Verilog netlist */
|
||||
/* Create the file name for Verilog */
|
||||
std::string verilog_fname(subckt_dir
|
||||
+ generate_logical_tile_netlist_name(std::string(LOGICAL_MODULE_VERILOG_FILE_NAME_PREFIX), pb_graph_head, std::string(VERILOG_NETLIST_FILE_POSTFIX))
|
||||
);
|
||||
|
||||
VTR_LOG("Writing Verilog netlist '%s' for logic tile '%s' ...",
|
||||
verilog_fname.c_str(), pb_graph_head->pb_type->name);
|
||||
VTR_LOGV(verbose, "\n");
|
||||
|
||||
/* Create the file stream */
|
||||
std::fstream fp;
|
||||
fp.open(verilog_fname, std::fstream::out | std::fstream::trunc);
|
||||
|
||||
check_file_stream(verilog_fname.c_str(), fp);
|
||||
|
||||
print_verilog_file_header(fp, std::string("Verilog modules for logical tile: " + std::string(pb_graph_head->pb_type->name) + "]"));
|
||||
VTR_LOG("Writing Verilog netlists for logic tile '%s' ...",
|
||||
pb_graph_head->pb_type->name);
|
||||
VTR_LOG("\n");
|
||||
|
||||
/* Print Verilog modules for all the pb_types/pb_graph_nodes
|
||||
* use a Depth-First Search Algorithm to print the sub-modules
|
||||
|
@ -226,23 +259,14 @@ void print_verilog_logical_tile_netlist(NetlistManager& netlist_manager,
|
|||
* to its parent in module manager
|
||||
*/
|
||||
/* Print Verilog modules starting from the top-level pb_type/pb_graph_node, and traverse the graph in a recursive way */
|
||||
rec_print_verilog_logical_tile(fp, module_manager,
|
||||
rec_print_verilog_logical_tile(netlist_manager,
|
||||
module_manager,
|
||||
device_annotation,
|
||||
subckt_dir,
|
||||
pb_graph_head,
|
||||
use_explicit_mapping,
|
||||
verbose);
|
||||
|
||||
/* Add an empty line as a splitter */
|
||||
fp << std::endl;
|
||||
|
||||
/* Close file handler */
|
||||
fp.close();
|
||||
|
||||
/* Add fname to the netlist name list */
|
||||
NetlistId nlist_id = netlist_manager.add_netlist(verilog_fname);
|
||||
VTR_ASSERT(NetlistId::INVALID() != nlist_id);
|
||||
netlist_manager.set_netlist_type(nlist_id, NetlistManager::LOGIC_BLOCK_NETLIST);
|
||||
|
||||
VTR_LOG("Done\n");
|
||||
VTR_LOG("\n");
|
||||
}
|
||||
|
@ -270,7 +294,7 @@ void print_verilog_physical_tile_netlist(NetlistManager& netlist_manager,
|
|||
/* Give a name to the Verilog netlist */
|
||||
/* Create the file name for Verilog */
|
||||
std::string verilog_fname(subckt_dir
|
||||
+ generate_grid_block_netlist_name(std::string(phy_block_type->name),
|
||||
+ generate_grid_block_netlist_name(std::string(GRID_MODULE_NAME_PREFIX) + std::string(phy_block_type->name),
|
||||
is_io_type(phy_block_type),
|
||||
border_side,
|
||||
std::string(VERILOG_NETLIST_FILE_POSTFIX))
|
||||
|
|
|
@ -287,4 +287,62 @@ bool check_configurable_memory_circuit_model(const e_config_protocol_type& confi
|
|||
return (0 == num_err);
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* Try to find the enable port control power-gate for a power-gated circuit model
|
||||
* We will return the first port that meet the requirement:
|
||||
* - a global port
|
||||
* - its function is labelled as config_enable
|
||||
* - default value is 0
|
||||
* Return invalid id if not found
|
||||
***********************************************************************/
|
||||
CircuitPortId find_circuit_model_power_gate_en_port(const CircuitLibrary& circuit_lib,
|
||||
const CircuitModelId& circuit_model) {
|
||||
VTR_ASSERT(true == circuit_lib.is_power_gated(circuit_model));
|
||||
std::vector<CircuitPortId> global_ports = circuit_lib.model_global_ports_by_type(circuit_model, CIRCUIT_MODEL_PORT_INPUT, true, true);
|
||||
|
||||
/* Try to find an ENABLE port from the global ports */
|
||||
CircuitPortId en_port = CircuitPortId::INVALID();
|
||||
for (const auto& port : global_ports) {
|
||||
/* Focus on config_enable ports which are power-gate control signals */
|
||||
if (false == circuit_lib.port_is_config_enable(port)) {
|
||||
continue;
|
||||
}
|
||||
if (1 == circuit_lib.port_default_value(port)) {
|
||||
en_port = port;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return en_port;
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* Try to find the enableB port control power-gate for a power-gated circuit model
|
||||
* We will return the first port that meet the requirement:
|
||||
* - a global port
|
||||
* - its function is labelled as config_enable
|
||||
* - default value is 1
|
||||
* Return invalid id if not found
|
||||
***********************************************************************/
|
||||
CircuitPortId find_circuit_model_power_gate_enb_port(const CircuitLibrary& circuit_lib,
|
||||
const CircuitModelId& circuit_model) {
|
||||
CircuitPortId enb_port = CircuitPortId::INVALID();
|
||||
VTR_ASSERT(true == circuit_lib.is_power_gated(circuit_model));
|
||||
std::vector<CircuitPortId> global_ports = circuit_lib.model_global_ports_by_type(circuit_model, CIRCUIT_MODEL_PORT_INPUT, true, true);
|
||||
|
||||
/* Try to find an ENABLE_B port from the global ports */
|
||||
for (const auto& port : global_ports) {
|
||||
/* Focus on config_enable ports which are power-gate control signals */
|
||||
if (false == circuit_lib.port_is_config_enable(port)) {
|
||||
continue;
|
||||
}
|
||||
if (0 == circuit_lib.port_default_value(port)) {
|
||||
enb_port = port;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return enb_port;
|
||||
}
|
||||
|
||||
} /* end namespace openfpga */
|
||||
|
|
|
@ -43,6 +43,12 @@ bool check_configurable_memory_circuit_model(const e_config_protocol_type& confi
|
|||
const CircuitLibrary& circuit_lib,
|
||||
const CircuitModelId& config_mem_circuit_model);
|
||||
|
||||
CircuitPortId find_circuit_model_power_gate_en_port(const CircuitLibrary& circuit_lib,
|
||||
const CircuitModelId& circuit_model);
|
||||
|
||||
CircuitPortId find_circuit_model_power_gate_enb_port(const CircuitLibrary& circuit_lib,
|
||||
const CircuitModelId& circuit_model);
|
||||
|
||||
} /* end namespace openfpga */
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,35 +1,35 @@
|
|||
<fabric_key>
|
||||
<key id="0" name="sb_2__2_" value="0" alias="sb_2__2_"/>
|
||||
<key id="1" name="grid_clb" value="3" alias="grid_clb_2_2"/>
|
||||
<key id="1" name="grid_clb" value="3" alias="grid_clb_2__2_"/>
|
||||
<key id="2" name="sb_0__1_" value="0" alias="sb_0__1_"/>
|
||||
<key id="3" name="cby_0__1_" value="0" alias="cby_0__1_"/>
|
||||
<key id="4" name="grid_clb" value="2" alias="grid_clb_2_1"/>
|
||||
<key id="5" name="grid_io_left" value="0" alias="grid_io_left_0_1"/>
|
||||
<key id="4" name="grid_clb" value="2" alias="grid_clb_2__1_"/>
|
||||
<key id="5" name="grid_io_left" value="0" alias="grid_io_left_0__1_"/>
|
||||
<key id="6" name="sb_1__0_" value="0" alias="sb_1__0_"/>
|
||||
<key id="7" name="sb_1__1_" value="0" alias="sb_1__1_"/>
|
||||
<key id="8" name="cbx_1__1_" value="1" alias="cbx_2__1_"/>
|
||||
<key id="9" name="cby_1__1_" value="1" alias="cby_1__2_"/>
|
||||
<key id="10" name="grid_io_right" value="1" alias="grid_io_right_3_2"/>
|
||||
<key id="10" name="grid_io_right" value="1" alias="grid_io_right_3__2_"/>
|
||||
<key id="11" name="cbx_1__0_" value="1" alias="cbx_2__0_"/>
|
||||
<key id="12" name="cby_1__1_" value="0" alias="cby_1__1_"/>
|
||||
<key id="13" name="grid_io_right" value="0" alias="grid_io_right_3_1"/>
|
||||
<key id="14" name="grid_io_bottom" value="0" alias="grid_io_bottom_1_0"/>
|
||||
<key id="13" name="grid_io_right" value="0" alias="grid_io_right_3__1_"/>
|
||||
<key id="14" name="grid_io_bottom" value="0" alias="grid_io_bottom_1__0_"/>
|
||||
<key id="15" name="cby_2__1_" value="0" alias="cby_2__1_"/>
|
||||
<key id="16" name="sb_2__1_" value="0" alias="sb_2__1_"/>
|
||||
<key id="17" name="cbx_1__0_" value="0" alias="cbx_1__0_"/>
|
||||
<key id="18" name="grid_clb" value="1" alias="grid_clb_1_2"/>
|
||||
<key id="18" name="grid_clb" value="1" alias="grid_clb_1__2_"/>
|
||||
<key id="19" name="cbx_1__2_" value="0" alias="cbx_1__2_"/>
|
||||
<key id="20" name="cbx_1__2_" value="1" alias="cbx_2__2_"/>
|
||||
<key id="21" name="sb_2__0_" value="0" alias="sb_2__0_"/>
|
||||
<key id="22" name="sb_1__2_" value="0" alias="sb_1__2_"/>
|
||||
<key id="23" name="cby_0__1_" value="1" alias="cby_0__2_"/>
|
||||
<key id="24" name="sb_0__0_" value="0" alias="sb_0__0_"/>
|
||||
<key id="25" name="grid_clb" value="0" alias="grid_clb_1_1"/>
|
||||
<key id="25" name="grid_clb" value="0" alias="grid_clb_1__1_"/>
|
||||
<key id="26" name="cby_2__1_" value="1" alias="cby_2__2_"/>
|
||||
<key id="27" name="grid_io_top" value="1" alias="grid_io_top_2_3"/>
|
||||
<key id="27" name="grid_io_top" value="1" alias="grid_io_top_2__3_"/>
|
||||
<key id="28" name="sb_0__2_" value="0" alias="sb_0__2_"/>
|
||||
<key id="29" name="grid_io_bottom" value="1" alias="grid_io_bottom_2_0"/>
|
||||
<key id="29" name="grid_io_bottom" value="1" alias="grid_io_bottom_2__0_"/>
|
||||
<key id="30" name="cbx_1__1_" value="0" alias="cbx_1__1_"/>
|
||||
<key id="31" name="grid_io_top" value="0" alias="grid_io_top_1_3"/>
|
||||
<key id="32" name="grid_io_left" value="1" alias="grid_io_left_0_2"/>
|
||||
<key id="31" name="grid_io_top" value="0" alias="grid_io_top_1__3_"/>
|
||||
<key id="32" name="grid_io_left" value="1" alias="grid_io_left_0__2_"/>
|
||||
</fabric_key>
|
||||
|
|
|
@ -23,5 +23,6 @@ Note that an OpenFPGA architecture can be applied to multiple VPR architecture f
|
|||
- stdcell: If circuit designs are built with standard cells only
|
||||
- tree\_mux: If routing multiplexers are built with a tree-like structure
|
||||
- <feature_size>: The technology node which the delay numbers are extracted from.
|
||||
- powergate : The FPGA has power-gating techniques applied. If not defined, there is no power-gating.
|
||||
|
||||
Other features are used in naming should be listed here.
|
||||
|
|
|
@ -0,0 +1,206 @@
|
|||
<!-- Architecture annotation for OpenFPGA framework
|
||||
This annotation supports the k6_N10_40nm.xml
|
||||
- General purpose logic block
|
||||
- K = 6, N = 10, I = 40
|
||||
- Single mode
|
||||
- Routing architecture
|
||||
- L = 4, fc_in = 0.15, fc_out = 0.1
|
||||
-->
|
||||
<openfpga_architecture>
|
||||
<technology_library>
|
||||
<device_library>
|
||||
<device_model name="logic" type="transistor">
|
||||
<lib type="industry" corner="TOP_TT" ref="M" path="${OPENFPGA_PATH}/openfpga_flow/tech/PTM_45nm/45nm.pm"/>
|
||||
<design vdd="0.9" pn_ratio="2"/>
|
||||
<pmos name="pch" chan_length="40e-9" min_width="140e-9" variation="logic_transistor_var"/>
|
||||
<nmos name="nch" chan_length="40e-9" min_width="140e-9" variation="logic_transistor_var"/>
|
||||
</device_model>
|
||||
<device_model name="io" type="transistor">
|
||||
<lib type="academia" ref="M" path="${OPENFPGA_PATH}/openfpga_flow/tech/PTM_45nm/45nm.pm"/>
|
||||
<design vdd="2.5" pn_ratio="3"/>
|
||||
<pmos name="pch_25" chan_length="270e-9" min_width="320e-9" variation="io_transistor_var"/>
|
||||
<nmos name="nch_25" chan_length="270e-9" min_width="320e-9" variation="io_transistor_var"/>
|
||||
</device_model>
|
||||
</device_library>
|
||||
<variation_library>
|
||||
<variation name="logic_transistor_var" abs_deviation="0.1" num_sigma="3"/>
|
||||
<variation name="io_transistor_var" abs_deviation="0.1" num_sigma="3"/>
|
||||
</variation_library>
|
||||
</technology_library>
|
||||
<circuit_library>
|
||||
<!-- An inverter with a pair of power-gate control signals
|
||||
en port: when it is '1', it is power gated
|
||||
enb port: when it is '0', it is power gated
|
||||
-->
|
||||
<circuit_model type="inv_buf" name="INVTX1" prefix="INVTX1" is_default="true">
|
||||
<design_technology type="cmos" power_gated="true" topology="inverter" size="1"/>
|
||||
<device_technology device_model_name="logic"/>
|
||||
<port type="input" prefix="in" size="1"/>
|
||||
<port type="input" prefix="en" size="1" is_global="true" default_val="0" is_config_enable="true"/>
|
||||
<port type="input" prefix="enb" size="1" is_global="true" default_val="1" is_config_enable="true"/>
|
||||
<port type="output" prefix="out" size="1"/>
|
||||
<delay_matrix type="rise" in_port="in" out_port="out">
|
||||
10e-12
|
||||
</delay_matrix>
|
||||
<delay_matrix type="fall" in_port="in" out_port="out">
|
||||
10e-12
|
||||
</delay_matrix>
|
||||
</circuit_model>
|
||||
<circuit_model type="inv_buf" name="buf4" prefix="buf4" is_default="false">
|
||||
<design_technology type="cmos" topology="buffer" size="1" num_level="2" f_per_stage="4"/>
|
||||
<device_technology device_model_name="logic"/>
|
||||
<port type="input" prefix="in" size="1"/>
|
||||
<port type="output" prefix="out" size="1"/>
|
||||
<delay_matrix type="rise" in_port="in" out_port="out">
|
||||
10e-12
|
||||
</delay_matrix>
|
||||
<delay_matrix type="fall" in_port="in" out_port="out">
|
||||
10e-12
|
||||
</delay_matrix>
|
||||
</circuit_model>
|
||||
<circuit_model type="inv_buf" name="tap_buf4" prefix="tap_buf4" is_default="false">
|
||||
<design_technology type="cmos" topology="buffer" size="1" num_level="3" f_per_stage="4"/>
|
||||
<device_technology device_model_name="logic"/>
|
||||
<port type="input" prefix="in" size="1"/>
|
||||
<port type="output" prefix="out" size="1"/>
|
||||
<delay_matrix type="rise" in_port="in" out_port="out">
|
||||
10e-12
|
||||
</delay_matrix>
|
||||
<delay_matrix type="fall" in_port="in" out_port="out">
|
||||
10e-12
|
||||
</delay_matrix>
|
||||
</circuit_model>
|
||||
<circuit_model type="pass_gate" name="TGATE" prefix="TGATE" is_default="true">
|
||||
<design_technology type="cmos" topology="transmission_gate" nmos_size="1" pmos_size="2"/>
|
||||
<device_technology device_model_name="logic"/>
|
||||
<input_buffer exist="false"/>
|
||||
<output_buffer exist="false"/>
|
||||
<port type="input" prefix="in" size="1"/>
|
||||
<port type="input" prefix="sel" size="1"/>
|
||||
<port type="input" prefix="selb" size="1"/>
|
||||
<port type="output" prefix="out" size="1"/>
|
||||
<delay_matrix type="rise" in_port="in sel selb" out_port="out">
|
||||
10e-12 5e-12 5e-12
|
||||
</delay_matrix>
|
||||
<delay_matrix type="fall" in_port="in sel selb" out_port="out">
|
||||
10e-12 5e-12 5e-12
|
||||
</delay_matrix>
|
||||
</circuit_model>
|
||||
<circuit_model type="chan_wire" name="chan_segment" prefix="track_seg" is_default="true">
|
||||
<design_technology type="cmos"/>
|
||||
<input_buffer exist="false"/>
|
||||
<output_buffer exist="false"/>
|
||||
<port type="input" prefix="in" size="1"/>
|
||||
<port type="output" prefix="out" size="1"/>
|
||||
<wire_param model_type="pi" R="101" C="22.5e-15" num_level="1"/> <!-- model_type could be T, res_val and cap_val DON'T CARE -->
|
||||
</circuit_model>
|
||||
<circuit_model type="wire" name="direct_interc" prefix="direct_interc" is_default="true">
|
||||
<design_technology type="cmos"/>
|
||||
<input_buffer exist="false"/>
|
||||
<output_buffer exist="false"/>
|
||||
<port type="input" prefix="in" size="1"/>
|
||||
<port type="output" prefix="out" size="1"/>
|
||||
<wire_param model_type="pi" R="0" C="0" num_level="1"/> <!-- model_type could be T, res_val cap_val should be defined -->
|
||||
</circuit_model>
|
||||
<circuit_model type="mux" name="mux_2level" prefix="mux_2level" dump_structural_verilog="true">
|
||||
<design_technology type="cmos" structure="multi_level" num_level="2" add_const_input="true" const_input_val="1"/>
|
||||
<input_buffer exist="true" circuit_model_name="INVTX1"/>
|
||||
<output_buffer exist="true" circuit_model_name="INVTX1"/>
|
||||
<pass_gate_logic circuit_model_name="TGATE"/>
|
||||
<port type="input" prefix="in" size="1"/>
|
||||
<port type="output" prefix="out" size="1"/>
|
||||
<port type="sram" prefix="sram" size="1"/>
|
||||
</circuit_model>
|
||||
<circuit_model type="mux" name="mux_2level_tapbuf" prefix="mux_2level_tapbuf" dump_structural_verilog="true">
|
||||
<design_technology type="cmos" structure="multi_level" num_level="2" add_const_input="true" const_input_val="1"/>
|
||||
<input_buffer exist="true" circuit_model_name="INVTX1"/>
|
||||
<output_buffer exist="true" circuit_model_name="tap_buf4"/>
|
||||
<pass_gate_logic circuit_model_name="TGATE"/>
|
||||
<port type="input" prefix="in" size="1"/>
|
||||
<port type="output" prefix="out" size="1"/>
|
||||
<port type="sram" prefix="sram" size="1"/>
|
||||
</circuit_model>
|
||||
<circuit_model type="mux" name="mux_1level_tapbuf" prefix="mux_1level_tapbuf" is_default="true" dump_structural_verilog="true">
|
||||
<design_technology type="cmos" structure="one_level" add_const_input="true" const_input_val="1"/>
|
||||
<input_buffer exist="true" circuit_model_name="INVTX1"/>
|
||||
<output_buffer exist="true" circuit_model_name="tap_buf4"/>
|
||||
<pass_gate_logic circuit_model_name="TGATE"/>
|
||||
<port type="input" prefix="in" size="1"/>
|
||||
<port type="output" prefix="out" size="1"/>
|
||||
<port type="sram" prefix="sram" size="1"/>
|
||||
</circuit_model>
|
||||
<!--DFF subckt ports should be defined as <D> <Q> <CLK> <RESET> <SET> -->
|
||||
<circuit_model type="ff" name="static_dff" prefix="dff" spice_netlist="${OPENFPGA_PATH}/openfpga_flow/SpiceNetlists/ff.sp" verilog_netlist="${OPENFPGA_PATH}/openfpga_flow/VerilogNetlists/ff.v">
|
||||
<design_technology type="cmos"/>
|
||||
<input_buffer exist="true" circuit_model_name="INVTX1"/>
|
||||
<output_buffer exist="true" circuit_model_name="INVTX1"/>
|
||||
<port type="input" prefix="D" size="1"/>
|
||||
<port type="input" prefix="set" size="1" is_global="true" default_val="0" is_set="true"/>
|
||||
<port type="input" prefix="reset" size="1" is_global="true" default_val="0" is_reset="true"/>
|
||||
<port type="output" prefix="Q" size="1"/>
|
||||
<port type="clock" prefix="clk" size="1" is_global="true" default_val="0" />
|
||||
</circuit_model>
|
||||
<circuit_model type="lut" name="lut4" prefix="lut4" dump_structural_verilog="true">
|
||||
<design_technology type="cmos"/>
|
||||
<input_buffer exist="true" circuit_model_name="INVTX1"/>
|
||||
<output_buffer exist="true" circuit_model_name="INVTX1"/>
|
||||
<lut_input_inverter exist="true" circuit_model_name="INVTX1"/>
|
||||
<lut_input_buffer exist="true" circuit_model_name="buf4"/>
|
||||
<pass_gate_logic circuit_model_name="TGATE"/>
|
||||
<port type="input" prefix="in" size="4"/>
|
||||
<port type="output" prefix="out" size="1"/>
|
||||
<port type="sram" prefix="sram" size="16"/>
|
||||
</circuit_model>
|
||||
<!--Scan-chain DFF subckt ports should be defined as <D> <Q> <Qb> <CLK> <RESET> <SET> -->
|
||||
<circuit_model type="sram" name="config_latch" prefix="config_latch" spice_netlist="${OPENFPGA_PATH}/openfpga_flow/SpiceNetlists/config_latch.sp" verilog_netlist="${OPENFPGA_PATH}/openfpga_flow/VerilogNetlists/config_latch.v">
|
||||
<design_technology type="cmos"/>
|
||||
<input_buffer exist="true" circuit_model_name="INVTX1"/>
|
||||
<output_buffer exist="true" circuit_model_name="INVTX1"/>
|
||||
<port type="input" prefix="pReset" lib_name="reset" size="1" is_global="true" default_val="0" is_reset="true" is_prog="true"/>
|
||||
<port type="bl" prefix="bl" size="1"/>
|
||||
<port type="wl" prefix="wl" size="1"/>
|
||||
<port type="output" prefix="Q" size="1"/>
|
||||
<port type="output" prefix="Qb" size="1"/>
|
||||
<port type="clock" prefix="prog_clk" lib_name="clk" size="1" is_global="true" default_val="0" is_prog="true"/>
|
||||
</circuit_model>
|
||||
<circuit_model type="iopad" name="iopad" prefix="iopad" spice_netlist="${OPENFPGA_PATH}/openfpga_flow/SpiceNetlists/io.sp" verilog_netlist="${OPENFPGA_PATH}/openfpga_flow/VerilogNetlists/io.v">
|
||||
<design_technology type="cmos"/>
|
||||
<input_buffer exist="true" circuit_model_name="INVTX1"/>
|
||||
<output_buffer exist="true" circuit_model_name="INVTX1"/>
|
||||
<port type="inout" prefix="pad" size="1" is_global="true" is_io="true"/>
|
||||
<port type="sram" prefix="en" size="1" mode_select="true" circuit_model_name="config_latch" default_val="1"/>
|
||||
<port type="input" prefix="outpad" size="1"/>
|
||||
<port type="output" prefix="inpad" size="1"/>
|
||||
</circuit_model>
|
||||
</circuit_library>
|
||||
<configuration_protocol>
|
||||
<organization type="frame_based" circuit_model_name="config_latch"/>
|
||||
</configuration_protocol>
|
||||
<connection_block>
|
||||
<switch name="ipin_cblock" circuit_model_name="mux_2level_tapbuf"/>
|
||||
</connection_block>
|
||||
<switch_block>
|
||||
<switch name="0" circuit_model_name="mux_2level_tapbuf"/>
|
||||
</switch_block>
|
||||
<routing_segment>
|
||||
<segment name="L4" circuit_model_name="chan_segment"/>
|
||||
</routing_segment>
|
||||
<pb_type_annotations>
|
||||
<!-- physical pb_type binding in complex block IO -->
|
||||
<pb_type name="io" physical_mode_name="physical" idle_mode_name="inpad"/>
|
||||
<pb_type name="io[physical].iopad" circuit_model_name="iopad" mode_bits="1"/>
|
||||
<pb_type name="io[inpad].inpad" physical_pb_type_name="io[physical].iopad" mode_bits="1"/>
|
||||
<pb_type name="io[outpad].outpad" physical_pb_type_name="io[physical].iopad" mode_bits="0"/>
|
||||
<!-- End physical pb_type binding in complex block IO -->
|
||||
|
||||
<!-- physical pb_type binding in complex block CLB -->
|
||||
<!-- physical mode will be the default mode if not specified -->
|
||||
<pb_type name="clb">
|
||||
<!-- Binding interconnect to circuit models as their physical implementation, if not defined, we use the default model -->
|
||||
<interconnect name="crossbar" circuit_model_name="mux_2level"/>
|
||||
</pb_type>
|
||||
<pb_type name="clb.fle[n1_lut4].ble4.lut4" circuit_model_name="lut4"/>
|
||||
<pb_type name="clb.fle[n1_lut4].ble4.ff" circuit_model_name="static_dff"/>
|
||||
<!-- End physical pb_type binding in complex block IO -->
|
||||
</pb_type_annotations>
|
||||
</openfpga_architecture>
|
|
@ -0,0 +1,33 @@
|
|||
# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
|
||||
# Configuration file for running experiments
|
||||
# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
|
||||
# timeout_each_job : FPGA Task script splits fpga flow into multiple jobs
|
||||
# Each job execute fpga_flow script on combination of architecture & benchmark
|
||||
# timeout_each_job is timeout for each job
|
||||
# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
|
||||
|
||||
[GENERAL]
|
||||
run_engine=openfpga_shell
|
||||
openfpga_shell_template=${PATH:OPENFPGA_PATH}/openfpga_flow/OpenFPGAShellScripts/fast_configuration_example_script.openfpga
|
||||
power_tech_file = ${PATH:OPENFPGA_PATH}/openfpga_flow/tech/PTM_45nm/45nm.xml
|
||||
power_analysis = true
|
||||
spice_output=false
|
||||
verilog_output=true
|
||||
timeout_each_job = 20*60
|
||||
fpga_flow=yosys_vpr
|
||||
openfpga_arch_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_arch/k4_N4_40nm_powergate_frame_openfpga.xml
|
||||
openfpga_sim_setting_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_simulation_settings/auto_sim_openfpga.xml
|
||||
external_fabric_key_file=
|
||||
|
||||
[ARCHITECTURES]
|
||||
arch0=${PATH:OPENFPGA_PATH}/openfpga_flow/vpr_arch/k4_N4_tileable_40nm.xml
|
||||
|
||||
[BENCHMARKS]
|
||||
bench0=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and2/and2.v
|
||||
|
||||
[SYNTHESIS_PARAM]
|
||||
bench0_top = and2
|
||||
bench0_chan_width = 300
|
||||
|
||||
[SCRIPT_PARAM_MIN_ROUTE_CHAN_WIDTH]
|
||||
end_flow_with_test=
|
Loading…
Reference in New Issue