[Engine] Support programming shift register clock in XML syntax
This commit is contained in:
parent
fa57117f50
commit
7b010ba0f4
|
@ -949,7 +949,6 @@ bool CircuitLibrary::port_is_config_enable(const CircuitPortId& circuit_port_id)
|
||||||
return port_is_config_enable_[circuit_port_id];
|
return port_is_config_enable_[circuit_port_id];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Return a flag if the port is used during programming a FPGA in a circuit model */
|
/* Return a flag if the port is used during programming a FPGA in a circuit model */
|
||||||
bool CircuitLibrary::port_is_prog(const CircuitPortId& circuit_port_id) const {
|
bool CircuitLibrary::port_is_prog(const CircuitPortId& circuit_port_id) const {
|
||||||
/* validate the circuit_port_id */
|
/* validate the circuit_port_id */
|
||||||
|
@ -957,6 +956,13 @@ bool CircuitLibrary::port_is_prog(const CircuitPortId& circuit_port_id) const {
|
||||||
return port_is_prog_[circuit_port_id];
|
return port_is_prog_[circuit_port_id];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Return a flag if the port is used by shift register in a circuit model */
|
||||||
|
bool CircuitLibrary::port_is_shift_register(const CircuitPortId& circuit_port_id) const {
|
||||||
|
/* validate the circuit_port_id */
|
||||||
|
VTR_ASSERT(valid_circuit_port_id(circuit_port_id));
|
||||||
|
return port_is_shift_register_[circuit_port_id];
|
||||||
|
}
|
||||||
|
|
||||||
/* Return which level the output port locates at a LUT multiplexing structure */
|
/* Return which level the output port locates at a LUT multiplexing structure */
|
||||||
size_t CircuitLibrary::port_lut_frac_level(const CircuitPortId& circuit_port_id) const {
|
size_t CircuitLibrary::port_lut_frac_level(const CircuitPortId& circuit_port_id) const {
|
||||||
/* validate the circuit_port_id */
|
/* validate the circuit_port_id */
|
||||||
|
@ -1401,6 +1407,7 @@ CircuitPortId CircuitLibrary::add_model_port(const CircuitModelId& model_id,
|
||||||
port_is_set_.push_back(false);
|
port_is_set_.push_back(false);
|
||||||
port_is_config_enable_.push_back(false);
|
port_is_config_enable_.push_back(false);
|
||||||
port_is_prog_.push_back(false);
|
port_is_prog_.push_back(false);
|
||||||
|
port_is_shift_register_.push_back(false);
|
||||||
port_tri_state_model_names_.emplace_back();
|
port_tri_state_model_names_.emplace_back();
|
||||||
port_tri_state_model_ids_.push_back(CircuitModelId::INVALID());
|
port_tri_state_model_ids_.push_back(CircuitModelId::INVALID());
|
||||||
port_inv_model_names_.emplace_back();
|
port_inv_model_names_.emplace_back();
|
||||||
|
@ -1538,6 +1545,15 @@ void CircuitLibrary::set_port_is_prog(const CircuitPortId& circuit_port_id,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Set the is_prog for a port of a circuit model */
|
||||||
|
void CircuitLibrary::set_port_is_shift_register(const CircuitPortId& circuit_port_id,
|
||||||
|
const bool& is_shift_register) {
|
||||||
|
/* validate the circuit_port_id */
|
||||||
|
VTR_ASSERT(valid_circuit_port_id(circuit_port_id));
|
||||||
|
port_is_shift_register_[circuit_port_id] = is_shift_register;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/* Set the model_name for a port of a circuit model */
|
/* Set the model_name for a port of a circuit model */
|
||||||
void CircuitLibrary::set_port_tri_state_model_name(const CircuitPortId& circuit_port_id,
|
void CircuitLibrary::set_port_tri_state_model_name(const CircuitPortId& circuit_port_id,
|
||||||
const std::string& model_name) {
|
const std::string& model_name) {
|
||||||
|
|
|
@ -288,6 +288,7 @@ class CircuitLibrary {
|
||||||
bool port_is_set(const CircuitPortId& circuit_port_id) const;
|
bool port_is_set(const CircuitPortId& circuit_port_id) const;
|
||||||
bool port_is_config_enable(const CircuitPortId& circuit_port_id) const;
|
bool port_is_config_enable(const CircuitPortId& circuit_port_id) const;
|
||||||
bool port_is_prog(const CircuitPortId& circuit_port_id) const;
|
bool port_is_prog(const CircuitPortId& circuit_port_id) const;
|
||||||
|
bool port_is_shift_register(const CircuitPortId& circuit_port_id) const;
|
||||||
size_t port_lut_frac_level(const CircuitPortId& circuit_port_id) const;
|
size_t port_lut_frac_level(const CircuitPortId& circuit_port_id) const;
|
||||||
bool port_is_harden_lut_port(const CircuitPortId& circuit_port_id) const;
|
bool port_is_harden_lut_port(const CircuitPortId& circuit_port_id) const;
|
||||||
std::vector<size_t> port_lut_output_mask(const CircuitPortId& circuit_port_id) const;
|
std::vector<size_t> port_lut_output_mask(const CircuitPortId& circuit_port_id) const;
|
||||||
|
@ -372,6 +373,8 @@ class CircuitLibrary {
|
||||||
const bool& is_config_enable);
|
const bool& is_config_enable);
|
||||||
void set_port_is_prog(const CircuitPortId& circuit_port_id,
|
void set_port_is_prog(const CircuitPortId& circuit_port_id,
|
||||||
const bool& is_prog);
|
const bool& is_prog);
|
||||||
|
void set_port_is_shift_register(const CircuitPortId& circuit_port_id,
|
||||||
|
const bool& is_shift_register);
|
||||||
void set_port_tri_state_model_name(const CircuitPortId& circuit_port_id,
|
void set_port_tri_state_model_name(const CircuitPortId& circuit_port_id,
|
||||||
const std::string& model_name);
|
const std::string& model_name);
|
||||||
void set_port_tri_state_model_id(const CircuitPortId& circuit_port_id,
|
void set_port_tri_state_model_id(const CircuitPortId& circuit_port_id,
|
||||||
|
@ -560,6 +563,7 @@ class CircuitLibrary {
|
||||||
vtr::vector<CircuitPortId, bool> port_is_set_;
|
vtr::vector<CircuitPortId, bool> port_is_set_;
|
||||||
vtr::vector<CircuitPortId, bool> port_is_config_enable_;
|
vtr::vector<CircuitPortId, bool> port_is_config_enable_;
|
||||||
vtr::vector<CircuitPortId, bool> port_is_prog_;
|
vtr::vector<CircuitPortId, bool> port_is_prog_;
|
||||||
|
vtr::vector<CircuitPortId, bool> port_is_shift_register_;
|
||||||
vtr::vector<CircuitPortId, std::string> port_tri_state_model_names_;
|
vtr::vector<CircuitPortId, std::string> port_tri_state_model_names_;
|
||||||
vtr::vector<CircuitPortId, CircuitModelId> port_tri_state_model_ids_;
|
vtr::vector<CircuitPortId, CircuitModelId> port_tri_state_model_ids_;
|
||||||
vtr::vector<CircuitPortId, std::string> port_inv_model_names_;
|
vtr::vector<CircuitPortId, std::string> port_inv_model_names_;
|
||||||
|
|
|
@ -484,6 +484,9 @@ void read_xml_circuit_port(pugi::xml_node& xml_port,
|
||||||
/* Identify if the port is in programming purpose, by default it is NOT */
|
/* Identify if the port is in programming purpose, by default it is NOT */
|
||||||
circuit_lib.set_port_is_prog(port, get_attribute(xml_port, "is_prog", loc_data, pugiutil::ReqOpt::OPTIONAL).as_bool(false));
|
circuit_lib.set_port_is_prog(port, get_attribute(xml_port, "is_prog", loc_data, pugiutil::ReqOpt::OPTIONAL).as_bool(false));
|
||||||
|
|
||||||
|
/* Identify if the port is in shift register purpose, by default it is NOT */
|
||||||
|
circuit_lib.set_port_is_shift_register(port, get_attribute(xml_port, "is_shift_register", loc_data, pugiutil::ReqOpt::OPTIONAL).as_bool(false));
|
||||||
|
|
||||||
/* Identify if the port is to enable programming for FPGAs, by default it is NOT */
|
/* Identify if the port is to enable programming for FPGAs, by default it is NOT */
|
||||||
circuit_lib.set_port_is_config_enable(port, get_attribute(xml_port, "is_config_enable", loc_data, pugiutil::ReqOpt::OPTIONAL).as_bool(false));
|
circuit_lib.set_port_is_config_enable(port, get_attribute(xml_port, "is_config_enable", loc_data, pugiutil::ReqOpt::OPTIONAL).as_bool(false));
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,7 @@ e_sim_accuracy_type string_to_sim_accuracy_type(const std::string& type_string)
|
||||||
}
|
}
|
||||||
|
|
||||||
/********************************************************************
|
/********************************************************************
|
||||||
* Parse XML codes of a <clock> line to an object of simulation setting
|
* Parse XML codes of a <clock> line under <operating> to an object of simulation setting
|
||||||
*******************************************************************/
|
*******************************************************************/
|
||||||
static
|
static
|
||||||
void read_xml_operating_clock_override_setting(pugi::xml_node& xml_clock_override_setting,
|
void read_xml_operating_clock_override_setting(pugi::xml_node& xml_clock_override_setting,
|
||||||
|
@ -62,6 +62,40 @@ void read_xml_operating_clock_override_setting(pugi::xml_node& xml_clock_overrid
|
||||||
sim_setting.set_clock_frequency(clock_id, get_attribute(xml_clock_override_setting, "frequency", loc_data).as_float(0.));
|
sim_setting.set_clock_frequency(clock_id, get_attribute(xml_clock_override_setting, "frequency", loc_data).as_float(0.));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/********************************************************************
|
||||||
|
* Parse XML codes of a <clock> line under <programming> to an object of simulation setting
|
||||||
|
*******************************************************************/
|
||||||
|
static
|
||||||
|
void read_xml_programming_clock_override_setting(pugi::xml_node& xml_clock_override_setting,
|
||||||
|
const pugiutil::loc_data& loc_data,
|
||||||
|
openfpga::SimulationSetting& sim_setting) {
|
||||||
|
std::string clock_name = get_attribute(xml_clock_override_setting, "name", loc_data).as_string();
|
||||||
|
|
||||||
|
/* Create a new clock override object in the sim_setting object with the given name */
|
||||||
|
SimulationClockId clock_id = sim_setting.create_clock(clock_name);
|
||||||
|
|
||||||
|
/* Report if the clock creation failed, this is due to a conflicts in naming*/
|
||||||
|
if (false == sim_setting.valid_clock_id(clock_id)) {
|
||||||
|
archfpga_throw(loc_data.filename_c_str(), loc_data.line(xml_clock_override_setting),
|
||||||
|
"Fail to create simulation clock '%s', it may share the same name as other simulation clock definition!\n",
|
||||||
|
clock_name.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Parse port information */
|
||||||
|
openfpga::PortParser clock_port_parser(get_attribute(xml_clock_override_setting, "port", loc_data).as_string());
|
||||||
|
sim_setting.set_clock_port(clock_id, clock_port_parser.port());
|
||||||
|
|
||||||
|
/* Parse frequency information */
|
||||||
|
std::string clock_freq_str = get_attribute(xml_clock_override_setting, "frequency", loc_data).as_string();
|
||||||
|
if (std::string("auto") != clock_freq_str) {
|
||||||
|
sim_setting.set_clock_frequency(clock_id, get_attribute(xml_clock_override_setting, "frequency", loc_data).as_float(0.));
|
||||||
|
}
|
||||||
|
|
||||||
|
sim_setting.set_clock_is_programming(clock_id, true);
|
||||||
|
|
||||||
|
sim_setting.set_clock_is_shift_register(clock_id, get_attribute(xml_clock_override_setting, "is_shift_register", loc_data).as_bool(false));
|
||||||
|
}
|
||||||
|
|
||||||
/********************************************************************
|
/********************************************************************
|
||||||
* Parse XML codes of a <clock_setting> to an object of simulation setting
|
* Parse XML codes of a <clock_setting> to an object of simulation setting
|
||||||
*******************************************************************/
|
*******************************************************************/
|
||||||
|
@ -102,6 +136,15 @@ void read_xml_clock_setting(pugi::xml_node& xml_clock_setting,
|
||||||
pugi::xml_node xml_programming_clock_setting = get_single_child(xml_clock_setting, "programming", loc_data);
|
pugi::xml_node xml_programming_clock_setting = get_single_child(xml_clock_setting, "programming", loc_data);
|
||||||
|
|
||||||
sim_setting.set_programming_clock_frequency(get_attribute(xml_programming_clock_setting, "frequency", loc_data).as_float(0.));
|
sim_setting.set_programming_clock_frequency(get_attribute(xml_programming_clock_setting, "frequency", loc_data).as_float(0.));
|
||||||
|
|
||||||
|
/* Iterate over multiple operating clock settings and parse one by one */
|
||||||
|
for (pugi::xml_node xml_clock : xml_programming_clock_setting.children()) {
|
||||||
|
/* Error out if the XML child has an invalid name! */
|
||||||
|
if (xml_clock.name() != std::string("clock")) {
|
||||||
|
bad_tag(xml_clock, loc_data, xml_programming_clock_setting, {"clock"});
|
||||||
|
}
|
||||||
|
read_xml_programming_clock_override_setting(xml_clock, loc_data, sim_setting);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/********************************************************************
|
/********************************************************************
|
||||||
|
|
|
@ -16,6 +16,36 @@ SimulationSetting::simulation_clock_range SimulationSetting::clocks() const {
|
||||||
return vtr::make_range(clock_ids_.begin(), clock_ids_.end());
|
return vtr::make_range(clock_ids_.begin(), clock_ids_.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<SimulationClockId> SimulationSetting::operating_clocks() const {
|
||||||
|
std::vector<SimulationClockId> op_clks;
|
||||||
|
for (const SimulationClockId& clk : clocks()) {
|
||||||
|
if (!clock_is_programming(clk)) {
|
||||||
|
op_clks.push_back(clk);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return op_clks;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<SimulationClockId> SimulationSetting::programming_clocks() const {
|
||||||
|
std::vector<SimulationClockId> prog_clks;
|
||||||
|
for (const SimulationClockId& clk : clocks()) {
|
||||||
|
if (clock_is_programming(clk)) {
|
||||||
|
prog_clks.push_back(clk);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return prog_clks;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<SimulationClockId> SimulationSetting::programming_shift_register_clocks() const {
|
||||||
|
std::vector<SimulationClockId> prog_clks;
|
||||||
|
for (const SimulationClockId& clk : clocks()) {
|
||||||
|
if (clock_is_programming(clk) && clock_is_shift_register(clk)) {
|
||||||
|
prog_clks.push_back(clk);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return prog_clks;
|
||||||
|
}
|
||||||
|
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
* Constructors
|
* Constructors
|
||||||
***********************************************************************/
|
***********************************************************************/
|
||||||
|
@ -53,6 +83,16 @@ float SimulationSetting::clock_frequency(const SimulationClockId& clock_id) cons
|
||||||
return clock_frequencies_[clock_id];
|
return clock_frequencies_[clock_id];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool SimulationSetting::clock_is_programming(const SimulationClockId& clock_id) const {
|
||||||
|
VTR_ASSERT(valid_clock_id(clock_id));
|
||||||
|
return clock_is_programming_[clock_id];
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SimulationSetting::clock_is_shift_register(const SimulationClockId& clock_id) const {
|
||||||
|
VTR_ASSERT(valid_clock_id(clock_id));
|
||||||
|
return clock_is_shift_register_[clock_id];
|
||||||
|
}
|
||||||
|
|
||||||
bool SimulationSetting::auto_select_num_clock_cycles() const {
|
bool SimulationSetting::auto_select_num_clock_cycles() const {
|
||||||
return 0 == num_clock_cycles_;
|
return 0 == num_clock_cycles_;
|
||||||
}
|
}
|
||||||
|
@ -157,6 +197,8 @@ SimulationClockId SimulationSetting::create_clock(const std::string& name) {
|
||||||
clock_names_.push_back(name);
|
clock_names_.push_back(name);
|
||||||
clock_ports_.emplace_back();
|
clock_ports_.emplace_back();
|
||||||
clock_frequencies_.push_back(0.);
|
clock_frequencies_.push_back(0.);
|
||||||
|
clock_is_programming_.push_back(false);
|
||||||
|
clock_is_shift_register_.push_back(false);
|
||||||
|
|
||||||
/* Register in the name-to-id map */
|
/* Register in the name-to-id map */
|
||||||
clock_name2ids_[name] = clock_id;
|
clock_name2ids_[name] = clock_id;
|
||||||
|
@ -176,6 +218,18 @@ void SimulationSetting::set_clock_frequency(const SimulationClockId& clock_id,
|
||||||
clock_frequencies_[clock_id] = frequency;
|
clock_frequencies_[clock_id] = frequency;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SimulationSetting::set_clock_is_programming(const SimulationClockId& clock_id,
|
||||||
|
const float& is_prog) {
|
||||||
|
VTR_ASSERT(valid_clock_id(clock_id));
|
||||||
|
clock_is_programming_[clock_id] = is_prog;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SimulationSetting::set_clock_is_shift_register(const SimulationClockId& clock_id,
|
||||||
|
const float& is_sr) {
|
||||||
|
VTR_ASSERT(valid_clock_id(clock_id));
|
||||||
|
clock_is_shift_register_[clock_id] = is_sr;
|
||||||
|
}
|
||||||
|
|
||||||
void SimulationSetting::set_num_clock_cycles(const size_t& num_clk_cycles) {
|
void SimulationSetting::set_num_clock_cycles(const size_t& num_clk_cycles) {
|
||||||
num_clock_cycles_ = num_clk_cycles;
|
num_clock_cycles_ = num_clk_cycles;
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,6 +62,9 @@ class SimulationSetting {
|
||||||
SimulationSetting();
|
SimulationSetting();
|
||||||
public: /* Accessors: aggregates */
|
public: /* Accessors: aggregates */
|
||||||
simulation_clock_range clocks() const;
|
simulation_clock_range clocks() const;
|
||||||
|
std::vector<SimulationClockId> operating_clocks() const;
|
||||||
|
std::vector<SimulationClockId> programming_clocks() const;
|
||||||
|
std::vector<SimulationClockId> programming_shift_register_clocks() const;
|
||||||
public: /* Public Accessors */
|
public: /* Public Accessors */
|
||||||
float default_operating_clock_frequency() const;
|
float default_operating_clock_frequency() const;
|
||||||
float programming_clock_frequency() const;
|
float programming_clock_frequency() const;
|
||||||
|
@ -69,6 +72,8 @@ class SimulationSetting {
|
||||||
std::string clock_name(const SimulationClockId& clock_id) const;
|
std::string clock_name(const SimulationClockId& clock_id) const;
|
||||||
BasicPort clock_port(const SimulationClockId& clock_id) const;
|
BasicPort clock_port(const SimulationClockId& clock_id) const;
|
||||||
float clock_frequency(const SimulationClockId& clock_id) const;
|
float clock_frequency(const SimulationClockId& clock_id) const;
|
||||||
|
bool clock_is_programming(const SimulationClockId& clock_id) const;
|
||||||
|
bool clock_is_shift_register(const SimulationClockId& clock_id) const;
|
||||||
bool auto_select_num_clock_cycles() const;
|
bool auto_select_num_clock_cycles() const;
|
||||||
size_t num_clock_cycles() const;
|
size_t num_clock_cycles() const;
|
||||||
float operating_clock_frequency_slack() const;
|
float operating_clock_frequency_slack() const;
|
||||||
|
@ -102,6 +107,10 @@ class SimulationSetting {
|
||||||
const BasicPort& port);
|
const BasicPort& port);
|
||||||
void set_clock_frequency(const SimulationClockId& clock_id,
|
void set_clock_frequency(const SimulationClockId& clock_id,
|
||||||
const float& frequency);
|
const float& frequency);
|
||||||
|
void set_clock_is_programming(const SimulationClockId& clock_id,
|
||||||
|
const float& is_prog);
|
||||||
|
void set_clock_is_shift_register(const SimulationClockId& clock_id,
|
||||||
|
const float& is_sr);
|
||||||
void set_num_clock_cycles(const size_t& num_clk_cycles);
|
void set_num_clock_cycles(const size_t& num_clk_cycles);
|
||||||
void set_operating_clock_frequency_slack(const float& op_clk_freq_slack);
|
void set_operating_clock_frequency_slack(const float& op_clk_freq_slack);
|
||||||
void set_simulation_temperature(const float& sim_temp);
|
void set_simulation_temperature(const float& sim_temp);
|
||||||
|
@ -150,6 +159,8 @@ class SimulationSetting {
|
||||||
vtr::vector<SimulationClockId, std::string> clock_names_;
|
vtr::vector<SimulationClockId, std::string> clock_names_;
|
||||||
vtr::vector<SimulationClockId, BasicPort> clock_ports_;
|
vtr::vector<SimulationClockId, BasicPort> clock_ports_;
|
||||||
vtr::vector<SimulationClockId, float> clock_frequencies_;
|
vtr::vector<SimulationClockId, float> clock_frequencies_;
|
||||||
|
vtr::vector<SimulationClockId, bool> clock_is_programming_;
|
||||||
|
vtr::vector<SimulationClockId, bool> clock_is_shift_register_;
|
||||||
|
|
||||||
/* Fast name-to-id lookup */
|
/* Fast name-to-id lookup */
|
||||||
std::map<std::string, SimulationClockId> clock_name2ids_;
|
std::map<std::string, SimulationClockId> clock_name2ids_;
|
||||||
|
|
|
@ -220,6 +220,10 @@ void write_xml_circuit_port(std::fstream& fp,
|
||||||
write_xml_attribute(fp, "is_prog", "true");
|
write_xml_attribute(fp, "is_prog", "true");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (true == circuit_lib.port_is_shift_register(port)) {
|
||||||
|
write_xml_attribute(fp, "is_shift_register", "true");
|
||||||
|
}
|
||||||
|
|
||||||
if (true == circuit_lib.port_is_config_enable(port)) {
|
if (true == circuit_lib.port_is_config_enable(port)) {
|
||||||
write_xml_attribute(fp, "is_config_enable", "true");
|
write_xml_attribute(fp, "is_config_enable", "true");
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,7 +41,7 @@ void write_xml_clock_setting(std::fstream& fp,
|
||||||
fp << ">" << "\n";
|
fp << ">" << "\n";
|
||||||
|
|
||||||
/* Output clock information one by one */
|
/* Output clock information one by one */
|
||||||
for (const SimulationClockId& clock_id : sim_setting.clocks()) {
|
for (const SimulationClockId& clock_id : sim_setting.operating_clocks()) {
|
||||||
fp << "\t\t\t" << "<clock";
|
fp << "\t\t\t" << "<clock";
|
||||||
write_xml_attribute(fp, "name", sim_setting.clock_name(clock_id).c_str());
|
write_xml_attribute(fp, "name", sim_setting.clock_name(clock_id).c_str());
|
||||||
write_xml_attribute(fp, "port", generate_xml_port_name(sim_setting.clock_port(clock_id)).c_str());
|
write_xml_attribute(fp, "port", generate_xml_port_name(sim_setting.clock_port(clock_id)).c_str());
|
||||||
|
@ -52,9 +52,22 @@ void write_xml_clock_setting(std::fstream& fp,
|
||||||
fp << "\t\t" << "</operating";
|
fp << "\t\t" << "</operating";
|
||||||
fp << ">" << "\n";
|
fp << ">" << "\n";
|
||||||
|
|
||||||
fp << "\t\t" << "<operating";
|
fp << "\t\t" << "<programming";
|
||||||
write_xml_attribute(fp, "frequency", sim_setting.programming_clock_frequency());
|
write_xml_attribute(fp, "frequency", sim_setting.programming_clock_frequency());
|
||||||
fp << "/>" << "\n";
|
fp << ">" << "\n";
|
||||||
|
|
||||||
|
/* Output clock information one by one */
|
||||||
|
for (const SimulationClockId& clock_id : sim_setting.programming_clocks()) {
|
||||||
|
fp << "\t\t\t" << "<clock";
|
||||||
|
write_xml_attribute(fp, "name", sim_setting.clock_name(clock_id).c_str());
|
||||||
|
write_xml_attribute(fp, "port", generate_xml_port_name(sim_setting.clock_port(clock_id)).c_str());
|
||||||
|
write_xml_attribute(fp, "frequency", std::to_string(sim_setting.clock_frequency(clock_id)).c_str());
|
||||||
|
write_xml_attribute(fp, "is_shift_register", std::to_string(sim_setting.clock_is_shift_register(clock_id)).c_str());
|
||||||
|
fp << ">" << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
fp << "\t\t" << "</programming";
|
||||||
|
fp << ">" << "\n";
|
||||||
|
|
||||||
fp << "\t" << "</clock_setting>" << "\n";
|
fp << "\t" << "</clock_setting>" << "\n";
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,6 +50,11 @@ bool FabricGlobalPortInfo::global_port_is_prog(const FabricGlobalPortId& global_
|
||||||
return global_port_is_prog_[global_port_id];
|
return global_port_is_prog_[global_port_id];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool FabricGlobalPortInfo::global_port_is_shift_register(const FabricGlobalPortId& global_port_id) const {
|
||||||
|
VTR_ASSERT(valid_global_port_id(global_port_id));
|
||||||
|
return global_port_is_shift_register_[global_port_id];
|
||||||
|
}
|
||||||
|
|
||||||
bool FabricGlobalPortInfo::global_port_is_config_enable(const FabricGlobalPortId& global_port_id) const {
|
bool FabricGlobalPortInfo::global_port_is_config_enable(const FabricGlobalPortId& global_port_id) const {
|
||||||
VTR_ASSERT(valid_global_port_id(global_port_id));
|
VTR_ASSERT(valid_global_port_id(global_port_id));
|
||||||
return global_port_is_config_enable_[global_port_id];
|
return global_port_is_config_enable_[global_port_id];
|
||||||
|
@ -77,6 +82,7 @@ FabricGlobalPortId FabricGlobalPortInfo::create_global_port(const ModulePortId&
|
||||||
global_port_is_set_.push_back(false);
|
global_port_is_set_.push_back(false);
|
||||||
global_port_is_reset_.push_back(false);
|
global_port_is_reset_.push_back(false);
|
||||||
global_port_is_prog_.push_back(false);
|
global_port_is_prog_.push_back(false);
|
||||||
|
global_port_is_shift_register_.push_back(false);
|
||||||
global_port_is_io_.push_back(false);
|
global_port_is_io_.push_back(false);
|
||||||
global_port_is_config_enable_.push_back(false);
|
global_port_is_config_enable_.push_back(false);
|
||||||
global_port_default_values_.push_back(0);
|
global_port_default_values_.push_back(0);
|
||||||
|
@ -108,6 +114,12 @@ void FabricGlobalPortInfo::set_global_port_is_prog(const FabricGlobalPortId& glo
|
||||||
global_port_is_prog_[global_port_id] = is_prog;
|
global_port_is_prog_[global_port_id] = is_prog;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FabricGlobalPortInfo::set_global_port_is_shift_register(const FabricGlobalPortId& global_port_id,
|
||||||
|
const bool& is_shift_register) {
|
||||||
|
VTR_ASSERT(valid_global_port_id(global_port_id));
|
||||||
|
global_port_is_shift_register_[global_port_id] = is_shift_register;
|
||||||
|
}
|
||||||
|
|
||||||
void FabricGlobalPortInfo::set_global_port_is_config_enable(const FabricGlobalPortId& global_port_id,
|
void FabricGlobalPortInfo::set_global_port_is_config_enable(const FabricGlobalPortId& global_port_id,
|
||||||
const bool& is_config_enable) {
|
const bool& is_config_enable) {
|
||||||
VTR_ASSERT(valid_global_port_id(global_port_id));
|
VTR_ASSERT(valid_global_port_id(global_port_id));
|
||||||
|
|
|
@ -36,6 +36,7 @@ class FabricGlobalPortInfo {
|
||||||
bool global_port_is_set(const FabricGlobalPortId& global_port_id) const;
|
bool global_port_is_set(const FabricGlobalPortId& global_port_id) const;
|
||||||
bool global_port_is_reset(const FabricGlobalPortId& global_port_id) const;
|
bool global_port_is_reset(const FabricGlobalPortId& global_port_id) const;
|
||||||
bool global_port_is_prog(const FabricGlobalPortId& global_port_id) const;
|
bool global_port_is_prog(const FabricGlobalPortId& global_port_id) const;
|
||||||
|
bool global_port_is_shift_register(const FabricGlobalPortId& global_port_id) const;
|
||||||
bool global_port_is_config_enable(const FabricGlobalPortId& global_port_id) const;
|
bool global_port_is_config_enable(const FabricGlobalPortId& global_port_id) const;
|
||||||
bool global_port_is_io(const FabricGlobalPortId& global_port_id) const;
|
bool global_port_is_io(const FabricGlobalPortId& global_port_id) const;
|
||||||
size_t global_port_default_value(const FabricGlobalPortId& global_port_id) const;
|
size_t global_port_default_value(const FabricGlobalPortId& global_port_id) const;
|
||||||
|
@ -52,6 +53,8 @@ class FabricGlobalPortInfo {
|
||||||
const bool& is_reset);
|
const bool& is_reset);
|
||||||
void set_global_port_is_prog(const FabricGlobalPortId& global_port_id,
|
void set_global_port_is_prog(const FabricGlobalPortId& global_port_id,
|
||||||
const bool& is_prog);
|
const bool& is_prog);
|
||||||
|
void set_global_port_is_shift_register(const FabricGlobalPortId& global_port_id,
|
||||||
|
const bool& is_shift_register);
|
||||||
void set_global_port_is_config_enable(const FabricGlobalPortId& global_port_id,
|
void set_global_port_is_config_enable(const FabricGlobalPortId& global_port_id,
|
||||||
const bool& is_config_enable);
|
const bool& is_config_enable);
|
||||||
void set_global_port_is_io(const FabricGlobalPortId& global_port_id,
|
void set_global_port_is_io(const FabricGlobalPortId& global_port_id,
|
||||||
|
@ -68,6 +71,7 @@ class FabricGlobalPortInfo {
|
||||||
vtr::vector<FabricGlobalPortId, bool> global_port_is_reset_;
|
vtr::vector<FabricGlobalPortId, bool> global_port_is_reset_;
|
||||||
vtr::vector<FabricGlobalPortId, bool> global_port_is_set_;
|
vtr::vector<FabricGlobalPortId, bool> global_port_is_set_;
|
||||||
vtr::vector<FabricGlobalPortId, bool> global_port_is_prog_;
|
vtr::vector<FabricGlobalPortId, bool> global_port_is_prog_;
|
||||||
|
vtr::vector<FabricGlobalPortId, bool> global_port_is_shift_register_;
|
||||||
vtr::vector<FabricGlobalPortId, bool> global_port_is_config_enable_;
|
vtr::vector<FabricGlobalPortId, bool> global_port_is_config_enable_;
|
||||||
vtr::vector<FabricGlobalPortId, bool> global_port_is_io_;
|
vtr::vector<FabricGlobalPortId, bool> global_port_is_io_;
|
||||||
vtr::vector<FabricGlobalPortId, size_t> global_port_default_values_;
|
vtr::vector<FabricGlobalPortId, size_t> global_port_default_values_;
|
||||||
|
|
|
@ -97,7 +97,7 @@ void print_pnr_sdc_global_clock_ports(std::fstream& fp,
|
||||||
/* Should try to find a port defintion from simulation parameters
|
/* Should try to find a port defintion from simulation parameters
|
||||||
* If found, it means that we need to use special clock name!
|
* If found, it means that we need to use special clock name!
|
||||||
*/
|
*/
|
||||||
for (const SimulationClockId& sim_clock : sim_setting.clocks()) {
|
for (const SimulationClockId& sim_clock : sim_setting.operating_clocks()) {
|
||||||
if (port_to_constrain == sim_setting.clock_port(sim_clock)) {
|
if (port_to_constrain == sim_setting.clock_port(sim_clock)) {
|
||||||
clock_period = 1./sim_setting.clock_frequency(sim_clock);
|
clock_period = 1./sim_setting.clock_frequency(sim_clock);
|
||||||
}
|
}
|
||||||
|
|
|
@ -515,7 +515,7 @@ void print_verilog_testbench_clock_stimuli(std::fstream& fp,
|
||||||
/* Skip all the unrelated pin constraints */
|
/* Skip all the unrelated pin constraints */
|
||||||
VTR_ASSERT(clock_port.get_name() == pin_constraints.net(pin_constraint));
|
VTR_ASSERT(clock_port.get_name() == pin_constraints.net(pin_constraint));
|
||||||
/* Try to find which clock source is considered in simulation settings for this pin */
|
/* Try to find which clock source is considered in simulation settings for this pin */
|
||||||
for (const SimulationClockId& sim_clock_id : simulation_parameters.clocks()) {
|
for (const SimulationClockId& sim_clock_id : simulation_parameters.operating_clocks()) {
|
||||||
if (pin_constraints.pin(pin_constraint) == simulation_parameters.clock_port(sim_clock_id)) {
|
if (pin_constraints.pin(pin_constraint) == simulation_parameters.clock_port(sim_clock_id)) {
|
||||||
clk_freq_to_use = (0.5 / simulation_parameters.clock_frequency(sim_clock_id)) / VERILOG_SIM_TIMESCALE;
|
clk_freq_to_use = (0.5 / simulation_parameters.clock_frequency(sim_clock_id)) / VERILOG_SIM_TIMESCALE;
|
||||||
}
|
}
|
||||||
|
|
|
@ -290,7 +290,7 @@ void print_verilog_top_testbench_global_clock_ports_stimuli(std::fstream& fp,
|
||||||
/* Should try to find a port defintion from simulation parameters
|
/* Should try to find a port defintion from simulation parameters
|
||||||
* If found, it means that we need to use special clock name!
|
* If found, it means that we need to use special clock name!
|
||||||
*/
|
*/
|
||||||
for (const SimulationClockId& sim_clock : simulation_parameters.clocks()) {
|
for (const SimulationClockId& sim_clock : simulation_parameters.operating_clocks()) {
|
||||||
if (global_port_to_connect == simulation_parameters.clock_port(sim_clock)) {
|
if (global_port_to_connect == simulation_parameters.clock_port(sim_clock)) {
|
||||||
stimuli_clock_port.set_name(generate_top_testbench_clock_name(std::string(TOP_TB_OP_CLOCK_PORT_PREFIX), simulation_parameters.clock_name(sim_clock)));
|
stimuli_clock_port.set_name(generate_top_testbench_clock_name(std::string(TOP_TB_OP_CLOCK_PORT_PREFIX), simulation_parameters.clock_name(sim_clock)));
|
||||||
}
|
}
|
||||||
|
@ -640,7 +640,7 @@ void print_verilog_top_testbench_benchmark_clock_ports(std::fstream& fp,
|
||||||
/* Skip all the unrelated pin constraints */
|
/* Skip all the unrelated pin constraints */
|
||||||
VTR_ASSERT(clock_port_name == pin_constraints.net(pin_constraint));
|
VTR_ASSERT(clock_port_name == pin_constraints.net(pin_constraint));
|
||||||
/* Try to find which clock source is considered in simulation settings for this pin */
|
/* Try to find which clock source is considered in simulation settings for this pin */
|
||||||
for (const SimulationClockId& sim_clock_id : simulation_parameters.clocks()) {
|
for (const SimulationClockId& sim_clock_id : simulation_parameters.operating_clocks()) {
|
||||||
if (pin_constraints.pin(pin_constraint) == simulation_parameters.clock_port(sim_clock_id)) {
|
if (pin_constraints.pin(pin_constraint) == simulation_parameters.clock_port(sim_clock_id)) {
|
||||||
std::string sim_clock_port_name = generate_top_testbench_clock_name(std::string(TOP_TB_OP_CLOCK_PORT_PREFIX), simulation_parameters.clock_name(sim_clock_id));
|
std::string sim_clock_port_name = generate_top_testbench_clock_name(std::string(TOP_TB_OP_CLOCK_PORT_PREFIX), simulation_parameters.clock_name(sim_clock_id));
|
||||||
clock_source_to_connect = BasicPort(sim_clock_port_name, 1);
|
clock_source_to_connect = BasicPort(sim_clock_port_name, 1);
|
||||||
|
@ -742,7 +742,7 @@ void print_verilog_top_testbench_ports(std::fstream& fp,
|
||||||
fp << generate_verilog_port(VERILOG_PORT_REG, prog_clock_register_port) << ";" << std::endl;
|
fp << generate_verilog_port(VERILOG_PORT_REG, prog_clock_register_port) << ";" << std::endl;
|
||||||
|
|
||||||
/* Multiple operating clocks based on the simulation settings */
|
/* Multiple operating clocks based on the simulation settings */
|
||||||
for (const SimulationClockId& sim_clock : simulation_parameters.clocks()) {
|
for (const SimulationClockId& sim_clock : simulation_parameters.operating_clocks()) {
|
||||||
std::string sim_clock_port_name = generate_top_testbench_clock_name(std::string(TOP_TB_OP_CLOCK_PORT_PREFIX), simulation_parameters.clock_name(sim_clock));
|
std::string sim_clock_port_name = generate_top_testbench_clock_name(std::string(TOP_TB_OP_CLOCK_PORT_PREFIX), simulation_parameters.clock_name(sim_clock));
|
||||||
BasicPort sim_clock_port(sim_clock_port_name, 1);
|
BasicPort sim_clock_port(sim_clock_port_name, 1);
|
||||||
fp << generate_verilog_port(VERILOG_PORT_WIRE, sim_clock_port) << ";" << std::endl;
|
fp << generate_verilog_port(VERILOG_PORT_WIRE, sim_clock_port) << ";" << std::endl;
|
||||||
|
@ -1010,7 +1010,7 @@ void print_verilog_top_testbench_generic_stimulus(std::fstream& fp,
|
||||||
fp << std::endl;
|
fp << std::endl;
|
||||||
|
|
||||||
/* Generate stimuli waveform for multiple user-defined operating clock signals */
|
/* Generate stimuli waveform for multiple user-defined operating clock signals */
|
||||||
for (const SimulationClockId& sim_clock : simulation_parameters.clocks()) {
|
for (const SimulationClockId& sim_clock : simulation_parameters.operating_clocks()) {
|
||||||
print_verilog_comment(fp, "----- Begin raw operating clock signal '" + simulation_parameters.clock_name(sim_clock) + "' generation -----");
|
print_verilog_comment(fp, "----- Begin raw operating clock signal '" + simulation_parameters.clock_name(sim_clock) + "' generation -----");
|
||||||
std::string sim_clock_port_name = generate_top_testbench_clock_name(std::string(TOP_TB_OP_CLOCK_PORT_PREFIX), simulation_parameters.clock_name(sim_clock));
|
std::string sim_clock_port_name = generate_top_testbench_clock_name(std::string(TOP_TB_OP_CLOCK_PORT_PREFIX), simulation_parameters.clock_name(sim_clock));
|
||||||
BasicPort sim_clock_port(sim_clock_port_name, 1);
|
BasicPort sim_clock_port(sim_clock_port_name, 1);
|
||||||
|
@ -1935,7 +1935,7 @@ int print_verilog_full_testbench(const ModuleManager& module_manager,
|
||||||
float prog_clock_period = (1./simulation_parameters.programming_clock_frequency());
|
float prog_clock_period = (1./simulation_parameters.programming_clock_frequency());
|
||||||
float default_op_clock_period = (1./simulation_parameters.default_operating_clock_frequency());
|
float default_op_clock_period = (1./simulation_parameters.default_operating_clock_frequency());
|
||||||
float max_op_clock_period = 0.;
|
float max_op_clock_period = 0.;
|
||||||
for (const SimulationClockId& clock_id : simulation_parameters.clocks()) {
|
for (const SimulationClockId& clock_id : simulation_parameters.operating_clocks()) {
|
||||||
max_op_clock_period = std::max(max_op_clock_period, (float)(1./simulation_parameters.clock_frequency(clock_id)));
|
max_op_clock_period = std::max(max_op_clock_period, (float)(1./simulation_parameters.clock_frequency(clock_id)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,41 @@
|
||||||
|
<!-- Simulation Setting for OpenFPGA framework
|
||||||
|
This file will use automatic inference for any settings
|
||||||
|
including:
|
||||||
|
- auto select the number of simulation cycles
|
||||||
|
- auto select the simulation clock frequency from VPR results
|
||||||
|
-->
|
||||||
|
<openfpga_simulation_setting>
|
||||||
|
<clock_setting>
|
||||||
|
<operating frequency="auto" num_cycles="auto" slack="0.2"/>
|
||||||
|
<programming frequency="100e6">
|
||||||
|
<clock name="shift_register_clk" port="sr_clk[0:0]" frequency="auto" is_shift_register="true"/>
|
||||||
|
</programming>
|
||||||
|
</clock_setting>
|
||||||
|
<simulator_option>
|
||||||
|
<operating_condition temperature="25"/>
|
||||||
|
<output_log verbose="false" captab="false"/>
|
||||||
|
<accuracy type="abs" value="1e-13"/>
|
||||||
|
<runtime fast_simulation="true"/>
|
||||||
|
</simulator_option>
|
||||||
|
<monte_carlo num_simulation_points="2"/>
|
||||||
|
<measurement_setting>
|
||||||
|
<slew>
|
||||||
|
<rise upper_thres_pct="0.95" lower_thres_pct="0.05"/>
|
||||||
|
<fall upper_thres_pct="0.05" lower_thres_pct="0.95"/>
|
||||||
|
</slew>
|
||||||
|
<delay>
|
||||||
|
<rise input_thres_pct="0.5" output_thres_pct="0.5"/>
|
||||||
|
<fall input_thres_pct="0.5" output_thres_pct="0.5"/>
|
||||||
|
</delay>
|
||||||
|
</measurement_setting>
|
||||||
|
<stimulus>
|
||||||
|
<clock>
|
||||||
|
<rise slew_type="abs" slew_time="20e-12" />
|
||||||
|
<fall slew_type="abs" slew_time="20e-12" />
|
||||||
|
</clock>
|
||||||
|
<input>
|
||||||
|
<rise slew_type="abs" slew_time="25e-12" />
|
||||||
|
<fall slew_type="abs" slew_time="25e-12" />
|
||||||
|
</input>
|
||||||
|
</stimulus>
|
||||||
|
</openfpga_simulation_setting>
|
Loading…
Reference in New Issue