move check codes on power gate ports to libarchopenfpga

Try to report errors to users as early as possible
This commit is contained in:
tangxifan 2020-07-22 18:47:12 -06:00
parent 97cca72590
commit f573fa3ee0
5 changed files with 172 additions and 74 deletions

View File

@ -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) {

View File

@ -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"
@ -159,7 +161,6 @@ int print_spice_powergated_inverter_subckt(std::fstream& fp,
*/
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);
std::vector<CircuitPortId> global_ports = circuit_lib.model_global_ports_by_type(circuit_model, CIRCUIT_MODEL_PORT_INPUT, true, true);
/* Make sure:
* There is only 1 input port and 1 output port,
@ -170,54 +171,10 @@ int print_spice_powergated_inverter_subckt(std::fstream& fp,
/* 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 */
size_t num_err = 0;
/* We need at least one global port */
if (2 != global_ports.size()) {
VTR_LOGF_ERROR(__FILE__, __LINE__,
"Expect two global ports (a pair of EN/Enb) for Inverter/buffer 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 */
for (const auto& port : global_ports) {
if (false == circuit_lib.port_is_config_enable(port)) {
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());
num_err++;
}
}
/* Report errors if there are any */
if (0 < num_err) {
exit(1);
}
/* Try to find a pair of Enable and ENb ports from the global ports */
VTR_ASSERT(2 == global_ports.size());
CircuitPortId en_port = CircuitPortId::INVALID();
CircuitPortId enb_port = CircuitPortId::INVALID();
for (const auto& port : global_ports) {
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 inverter/buffer circuit model '%s' is power-gated!\n",
circuit_lib.model_name(circuit_model).c_str());
exit(1);
}
if (false == circuit_lib.valid_circuit_port_id(enb_port)) {
VTR_LOGF_ERROR(__FILE__, __LINE__,
"Fail to find an inverted enable port for the inverter/buffer circuit model '%s' is power-gated!\n",
circuit_lib.model_name(circuit_model).c_str());
exit(1);
}
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) {

View File

@ -48,6 +48,10 @@ void print_verilog_power_gated_invbuf_body(std::fstream& fp,
fp << "\talways @(" << std::endl;
/* Power-gate port first*/
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;
}
/* Skip first comma to dump*/
if (0 < &power_gate_port - &power_gate_ports[0]) {
fp << ",";
@ -61,6 +65,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&&";
@ -161,30 +169,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));

View File

@ -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 (0 == 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 (1 == circuit_lib.port_default_value(port)) {
enb_port = port;
break;
}
}
return enb_port;
}
} /* end namespace openfpga */

View File

@ -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