Merge pull request #292 from lnis-uofu/dff_techmap
Verilog testbench generator now accepts pin constraints on non-clock global ports
This commit is contained in:
commit
0e65442afd
|
@ -38,6 +38,17 @@ std::string PinConstraints::net(const PinConstraintId& pin_constraint_id) const
|
|||
return pin_constraint_nets_[pin_constraint_id];
|
||||
}
|
||||
|
||||
std::string PinConstraints::pin_net(const openfpga::BasicPort& pin) const {
|
||||
std::string constrained_net_name;
|
||||
for (const PinConstraintId& pin_constraint : pin_constraints()) {
|
||||
if (pin == pin_constraint_pins_[pin_constraint]) {
|
||||
constrained_net_name = net(pin_constraint);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return constrained_net_name;
|
||||
}
|
||||
|
||||
bool PinConstraints::empty() const {
|
||||
return 0 == pin_constraint_ids_.size();
|
||||
}
|
||||
|
|
|
@ -52,6 +52,11 @@ class PinConstraints {
|
|||
/* Get the net to be constrained */
|
||||
std::string net(const PinConstraintId& pin_constraint_id) const;
|
||||
|
||||
/* Find the net that is constrained on a pin
|
||||
* TODO: this function will only return the first net found in the constraint list
|
||||
*/
|
||||
std::string pin_net(const openfpga::BasicPort& pin) const;
|
||||
|
||||
/* Check if there are any pin constraints */
|
||||
bool empty() const;
|
||||
|
||||
|
|
|
@ -135,13 +135,7 @@ int print_verilog_preconfig_top_module_connect_global_ports(std::fstream &fp,
|
|||
BasicPort module_clock_pin(module_global_port.get_name(), module_global_port.pins()[pin_id], module_global_port.pins()[pin_id]);
|
||||
|
||||
/* If the clock port name is in the pin constraints, we should wire it to the constrained pin */
|
||||
std::string constrained_net_name;
|
||||
for (const PinConstraintId& pin_constraint : pin_constraints.pin_constraints()) {
|
||||
if (module_clock_pin == pin_constraints.pin(pin_constraint)) {
|
||||
constrained_net_name = pin_constraints.net(pin_constraint);
|
||||
break;
|
||||
}
|
||||
}
|
||||
std::string constrained_net_name = pin_constraints.pin_net(module_clock_pin);
|
||||
|
||||
/* If constrained to an open net or there is no clock in the benchmark, we assign it to a default value */
|
||||
if ( (std::string(PIN_CONSTRAINT_OPEN_NET) == constrained_net_name)
|
||||
|
@ -173,8 +167,27 @@ int print_verilog_preconfig_top_module_connect_global_ports(std::fstream &fp,
|
|||
}
|
||||
|
||||
/* For other ports, give an default value */
|
||||
std::vector<size_t> default_values(module_global_port.get_width(), fabric_global_ports.global_port_default_value(global_port_id));
|
||||
print_verilog_wire_constant_values(fp, module_global_port, default_values);
|
||||
for (size_t pin_id = 0; pin_id < module_global_port.pins().size(); ++pin_id) {
|
||||
BasicPort module_global_pin(module_global_port.get_name(),
|
||||
module_global_port.pins()[pin_id],
|
||||
module_global_port.pins()[pin_id]);
|
||||
|
||||
/* If the global port name is in the pin constraints, we should wire it to the constrained pin */
|
||||
std::string constrained_net_name = pin_constraints.pin_net(module_global_pin);
|
||||
|
||||
/* - If constrained to a given net in the benchmark, we connect the global pin to the net
|
||||
* - If constrained to an open net in the benchmark, we assign it to a default value
|
||||
*/
|
||||
if ( (std::string(PIN_CONSTRAINT_OPEN_NET) != constrained_net_name)
|
||||
&& (!constrained_net_name.empty())) {
|
||||
BasicPort benchmark_pin(constrained_net_name + std::string(FORMAL_VERIFICATION_TOP_MODULE_PORT_POSTFIX), 1);
|
||||
print_verilog_wire_connection(fp, module_global_pin, benchmark_pin, false);
|
||||
} else {
|
||||
VTR_ASSERT_SAFE(std::string(PIN_CONSTRAINT_OPEN_NET) == constrained_net_name);
|
||||
std::vector<size_t> default_values(module_global_pin.get_width(), fabric_global_ports.global_port_default_value(global_port_id));
|
||||
print_verilog_wire_constant_values(fp, module_global_pin, default_values);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
print_verilog_comment(fp, std::string("----- End Connect Global ports of FPGA top module -----"));
|
||||
|
|
|
@ -258,21 +258,17 @@ void print_verilog_top_testbench_config_protocol_port(std::fstream& fp,
|
|||
}
|
||||
|
||||
/********************************************************************
|
||||
* Wire the global ports of FPGA fabric to local wires
|
||||
* Wire the global clock ports of FPGA fabric to local wires
|
||||
*******************************************************************/
|
||||
static
|
||||
void print_verilog_top_testbench_global_ports_stimuli(std::fstream& fp,
|
||||
const ModuleManager& module_manager,
|
||||
const ModuleId& top_module,
|
||||
const FabricGlobalPortInfo& fabric_global_port_info,
|
||||
const SimulationSetting& simulation_parameters,
|
||||
const bool& active_global_prog_reset,
|
||||
const bool& active_global_prog_set) {
|
||||
void print_verilog_top_testbench_global_clock_ports_stimuli(std::fstream& fp,
|
||||
const ModuleManager& module_manager,
|
||||
const ModuleId& top_module,
|
||||
const FabricGlobalPortInfo& fabric_global_port_info,
|
||||
const SimulationSetting& simulation_parameters) {
|
||||
/* Validate the file stream */
|
||||
valid_file_stream(fp);
|
||||
|
||||
print_verilog_comment(fp, std::string("----- Begin connecting global ports of FPGA fabric to stimuli -----"));
|
||||
|
||||
/* Connect global clock ports to operating or programming clock signal */
|
||||
for (const FabricGlobalPortId& fabric_global_port : fabric_global_port_info.global_ports()) {
|
||||
if (false == fabric_global_port_info.global_port_is_clock(fabric_global_port)) {
|
||||
|
@ -317,6 +313,18 @@ void print_verilog_top_testbench_global_ports_stimuli(std::fstream& fp,
|
|||
1 == fabric_global_port_info.global_port_default_value(fabric_global_port));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
* Wire the global config done ports of FPGA fabric to local wires
|
||||
*******************************************************************/
|
||||
static
|
||||
void print_verilog_top_testbench_global_config_done_ports_stimuli(std::fstream& fp,
|
||||
const ModuleManager& module_manager,
|
||||
const ModuleId& top_module,
|
||||
const FabricGlobalPortInfo& fabric_global_port_info) {
|
||||
/* Validate the file stream */
|
||||
valid_file_stream(fp);
|
||||
|
||||
/* Connect global configuration done ports to configuration done signal */
|
||||
for (const FabricGlobalPortId& fabric_global_port : fabric_global_port_info.global_ports()) {
|
||||
|
@ -341,6 +349,20 @@ void print_verilog_top_testbench_global_ports_stimuli(std::fstream& fp,
|
|||
stimuli_config_done_port,
|
||||
1 == fabric_global_port_info.global_port_default_value(fabric_global_port));
|
||||
}
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
* Wire the global reset ports of FPGA fabric to local wires
|
||||
*******************************************************************/
|
||||
static
|
||||
void print_verilog_top_testbench_global_reset_ports_stimuli(std::fstream& fp,
|
||||
const ModuleManager& module_manager,
|
||||
const ModuleId& top_module,
|
||||
const PinConstraints& pin_constraints,
|
||||
const FabricGlobalPortInfo& fabric_global_port_info,
|
||||
const bool& active_global_prog_reset) {
|
||||
/* Validate the file stream */
|
||||
valid_file_stream(fp);
|
||||
|
||||
/* Connect global reset ports to operating or programming reset signal */
|
||||
for (const FabricGlobalPortId& fabric_global_port : fabric_global_port_info.global_ports()) {
|
||||
|
@ -373,20 +395,58 @@ void print_verilog_top_testbench_global_ports_stimuli(std::fstream& fp,
|
|||
stimuli_reset_port.set_name(std::string(TOP_TB_RESET_PORT_NAME));
|
||||
stimuli_reset_port.set_width(1);
|
||||
}
|
||||
/* Wire the port to the input stimuli:
|
||||
* The wiring will be inverted if the default value of the global port is 1
|
||||
* Otherwise, the wiring will not be inverted!
|
||||
*/
|
||||
if (true == activate) {
|
||||
print_verilog_wire_connection(fp, module_manager.module_port(top_module, module_global_port),
|
||||
stimuli_reset_port,
|
||||
1 == fabric_global_port_info.global_port_default_value(fabric_global_port));
|
||||
} else {
|
||||
VTR_ASSERT_SAFE(false == activate);
|
||||
print_verilog_wire_constant_values(fp, module_manager.module_port(top_module, module_global_port),
|
||||
std::vector<size_t>(1, fabric_global_port_info.global_port_default_value(fabric_global_port)));
|
||||
|
||||
BasicPort module_global_port_info = module_manager.module_port(top_module, module_global_port);
|
||||
|
||||
for (size_t pin_id = 0; pin_id < module_global_port_info.pins().size(); ++pin_id) {
|
||||
BasicPort module_global_pin(module_global_port_info.get_name(),
|
||||
module_global_port_info.pins()[pin_id],
|
||||
module_global_port_info.pins()[pin_id]);
|
||||
|
||||
/* Regular reset port can be mapped by a net from user design */
|
||||
if (false == fabric_global_port_info.global_port_is_prog(fabric_global_port)) {
|
||||
/* If the global port name is in the pin constraints, we should wire it to the constrained pin */
|
||||
std::string constrained_net_name = pin_constraints.pin_net(module_global_pin);
|
||||
|
||||
/* - If constrained to a given net in the benchmark, we connect the global pin to the net */
|
||||
if ( (std::string(PIN_CONSTRAINT_OPEN_NET) != constrained_net_name)
|
||||
&& (!constrained_net_name.empty())) {
|
||||
BasicPort benchmark_pin(constrained_net_name, 1);
|
||||
print_verilog_wire_connection(fp, module_global_pin,
|
||||
benchmark_pin,
|
||||
false);
|
||||
continue; /* Finish the net assignment for this reset pin */
|
||||
}
|
||||
}
|
||||
|
||||
/* Wire the port to the input stimuli:
|
||||
* The wiring will be inverted if the default value of the global port is 1
|
||||
* Otherwise, the wiring will not be inverted!
|
||||
*/
|
||||
if (true == activate) {
|
||||
print_verilog_wire_connection(fp, module_global_pin,
|
||||
stimuli_reset_port,
|
||||
1 == fabric_global_port_info.global_port_default_value(fabric_global_port));
|
||||
} else {
|
||||
VTR_ASSERT_SAFE(false == activate);
|
||||
print_verilog_wire_constant_values(fp, module_global_pin,
|
||||
std::vector<size_t>(1, fabric_global_port_info.global_port_default_value(fabric_global_port)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
* Wire the global set ports of FPGA fabric to local wires
|
||||
*******************************************************************/
|
||||
static
|
||||
void print_verilog_top_testbench_global_set_ports_stimuli(std::fstream& fp,
|
||||
const ModuleManager& module_manager,
|
||||
const ModuleId& top_module,
|
||||
const FabricGlobalPortInfo& fabric_global_port_info,
|
||||
const bool& active_global_prog_set) {
|
||||
/* Validate the file stream */
|
||||
valid_file_stream(fp);
|
||||
|
||||
/* Connect global set ports to operating or programming set signal */
|
||||
for (const FabricGlobalPortId& fabric_global_port : fabric_global_port_info.global_ports()) {
|
||||
|
@ -438,6 +498,18 @@ void print_verilog_top_testbench_global_ports_stimuli(std::fstream& fp,
|
|||
std::vector<size_t>(1, fabric_global_port_info.global_port_default_value(fabric_global_port)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
* Wire the regular global ports of FPGA fabric to local wires
|
||||
*******************************************************************/
|
||||
static
|
||||
void print_verilog_top_testbench_regular_global_ports_stimuli(std::fstream& fp,
|
||||
const ModuleManager& module_manager,
|
||||
const ModuleId& top_module,
|
||||
const FabricGlobalPortInfo& fabric_global_port_info) {
|
||||
/* Validate the file stream */
|
||||
valid_file_stream(fp);
|
||||
|
||||
/* For the rest of global ports, wire them to constant signals */
|
||||
for (const FabricGlobalPortId& fabric_global_port : fabric_global_port_info.global_ports()) {
|
||||
|
@ -478,6 +550,55 @@ void print_verilog_top_testbench_global_ports_stimuli(std::fstream& fp,
|
|||
std::vector<size_t> default_values(module_port.get_width(), fabric_global_port_info.global_port_default_value(fabric_global_port));
|
||||
print_verilog_wire_constant_values(fp, module_port, default_values);
|
||||
}
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
* Wire the global ports of FPGA fabric to local wires
|
||||
*******************************************************************/
|
||||
static
|
||||
void print_verilog_top_testbench_global_ports_stimuli(std::fstream& fp,
|
||||
const ModuleManager& module_manager,
|
||||
const ModuleId& top_module,
|
||||
const PinConstraints& pin_constraints,
|
||||
const FabricGlobalPortInfo& fabric_global_port_info,
|
||||
const SimulationSetting& simulation_parameters,
|
||||
const bool& active_global_prog_reset,
|
||||
const bool& active_global_prog_set) {
|
||||
/* Validate the file stream */
|
||||
valid_file_stream(fp);
|
||||
|
||||
print_verilog_comment(fp, std::string("----- Begin connecting global ports of FPGA fabric to stimuli -----"));
|
||||
|
||||
print_verilog_top_testbench_global_clock_ports_stimuli(fp,
|
||||
module_manager,
|
||||
top_module,
|
||||
fabric_global_port_info,
|
||||
simulation_parameters);
|
||||
|
||||
print_verilog_top_testbench_global_config_done_ports_stimuli(fp,
|
||||
module_manager,
|
||||
top_module,
|
||||
fabric_global_port_info);
|
||||
|
||||
|
||||
print_verilog_top_testbench_global_reset_ports_stimuli(fp,
|
||||
module_manager,
|
||||
top_module,
|
||||
pin_constraints,
|
||||
fabric_global_port_info,
|
||||
active_global_prog_reset);
|
||||
|
||||
print_verilog_top_testbench_global_set_ports_stimuli(fp,
|
||||
module_manager,
|
||||
top_module,
|
||||
fabric_global_port_info,
|
||||
active_global_prog_set);
|
||||
|
||||
|
||||
print_verilog_top_testbench_regular_global_ports_stimuli(fp,
|
||||
module_manager,
|
||||
top_module,
|
||||
fabric_global_port_info);
|
||||
|
||||
print_verilog_comment(fp, std::string("----- End connecting global ports of FPGA fabric to stimuli -----"));
|
||||
}
|
||||
|
@ -1994,6 +2115,7 @@ void print_verilog_top_testbench(const ModuleManager& module_manager,
|
|||
/* Generate stimuli for global ports or connect them to existed signals */
|
||||
print_verilog_top_testbench_global_ports_stimuli(fp,
|
||||
module_manager, top_module,
|
||||
pin_constraints,
|
||||
global_ports,
|
||||
simulation_parameters,
|
||||
active_global_prog_reset,
|
||||
|
|
|
@ -55,7 +55,7 @@ write_fabric_verilog --file ./SRC --explicit_port_mapping --include_timing --pri
|
|||
# - Enable top-level testbench which is a full verification including programming circuit and core logic of FPGA
|
||||
# - Enable pre-configured top-level testbench which is a fast verification skipping programming phase
|
||||
# - Simulation ini file is optional and is needed only when you need to interface different HDL simulators using openfpga flow-run scripts
|
||||
write_verilog_testbench --file ./SRC --reference_benchmark_file_path ${REFERENCE_VERILOG_TESTBENCH} --print_top_testbench --print_preconfig_top_testbench --print_simulation_ini ./SimulationDeck/simulation_deck.ini --include_signal_init --support_icarus_simulator
|
||||
write_verilog_testbench --file ./SRC --reference_benchmark_file_path ${REFERENCE_VERILOG_TESTBENCH} --print_top_testbench --print_preconfig_top_testbench --print_simulation_ini ./SimulationDeck/simulation_deck.ini --include_signal_init --support_icarus_simulator --pin_constraints_file ${OPENFPGA_PIN_CONSTRAINTS_FILE}
|
||||
|
||||
# Write the SDC files for PnR backend
|
||||
# - Turn on every options here
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
<pin_constraints>
|
||||
<!-- For a given .blif file, we want to assign
|
||||
- the reset signal to the op_reset[0] port of the FPGA fabric
|
||||
-->
|
||||
<set_io pin="op_reset[0]" net="reset"/>
|
||||
</pin_constraints>
|
||||
|
|
@ -19,6 +19,7 @@ fpga_flow=yosys_vpr
|
|||
openfpga_shell_template=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_shell_scripts/example_without_ace_script.openfpga
|
||||
openfpga_arch_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_arch/k4_frac_N4_fracff_40nm_cc_openfpga.xml
|
||||
openfpga_sim_setting_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_simulation_settings/fixed_sim_openfpga.xml
|
||||
openfpga_pin_constraints_file=${PATH:OPENFPGA_PATH}/openfpga_flow/tasks/basic_tests/k4_series/k4n4_fracff/config/pin_constraints.xml
|
||||
# Yosys script parameters
|
||||
yosys_cell_sim_verilog=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_yosys_techlib/openfpga_dff_sim.v
|
||||
yosys_dff_map_verilog=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_yosys_techlib/openfpga_dff_map.v
|
||||
|
|
Loading…
Reference in New Issue