move check codes on power gate ports to libarchopenfpga
Try to report errors to users as early as possible
This commit is contained in:
parent
97cca72590
commit
f573fa3ee0
|
@ -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) {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue