[OpenFPGA Tool] Add edge triggered attribute to circuit library definition. Better support for using CCFF in frame-based protocol
This commit is contained in:
parent
8e4e66038a
commit
064678fe32
|
@ -942,6 +942,12 @@ bool CircuitLibrary::port_is_config_enable(const CircuitPortId& circuit_port_id)
|
|||
return port_is_config_enable_[circuit_port_id];
|
||||
}
|
||||
|
||||
bool CircuitLibrary::port_is_edge_triggered(const CircuitPortId& circuit_port_id) const {
|
||||
/* validate the circuit_port_id */
|
||||
VTR_ASSERT(valid_circuit_port_id(circuit_port_id));
|
||||
return port_is_edge_triggered_[circuit_port_id];
|
||||
}
|
||||
|
||||
/* 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 {
|
||||
/* validate the circuit_port_id */
|
||||
|
@ -1493,6 +1499,15 @@ void CircuitLibrary::set_port_is_config_enable(const CircuitPortId& circuit_port
|
|||
return;
|
||||
}
|
||||
|
||||
/* Set the is_edge_triggered for a port of a circuit model */
|
||||
void CircuitLibrary::set_port_is_edge_triggered(const CircuitPortId& circuit_port_id,
|
||||
const bool& is_edge_triggered) {
|
||||
/* validate the circuit_port_id */
|
||||
VTR_ASSERT(valid_circuit_port_id(circuit_port_id));
|
||||
port_is_edge_triggered_[circuit_port_id] = is_edge_triggered;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Set the is_prog for a port of a circuit model */
|
||||
void CircuitLibrary::set_port_is_prog(const CircuitPortId& circuit_port_id,
|
||||
const bool& is_prog) {
|
||||
|
|
|
@ -91,15 +91,16 @@
|
|||
* 9. port_is_reset: specify if this port is a reset signal which needs special pulse widths in testbenches
|
||||
* 10. port_is_set: specify if this port is a set signal which needs special pulse widths in testbenches
|
||||
* 11. port_is_config_enable: specify if this port is a config_enable signal which needs special pulse widths in testbenches
|
||||
* 12. port_is_prog: specify if this port is for FPGA programming use which needs special pulse widths in testbenches
|
||||
* 13. port_tri_state_model_name: the name of circuit model linked to tri-state the port
|
||||
* 14. port_tri_state_model_ids_: the Id of circuit model linked to tri-state the port
|
||||
* 15. port_inv_model_names_: the name of inverter circuit model linked to the port
|
||||
* 16. port_inv_model_ids_: the Id of inverter circuit model linked to the port
|
||||
* 17. port_tri_state_map_: only applicable to inputs of LUTs, the tri-state map applied to each pin of this port
|
||||
* 18. port_lut_frac_level_: only applicable to outputs of LUTs, indicate which level of outputs inside LUT multiplexing structure will be used
|
||||
* 19. port_lut_output_mask_: only applicable to outputs of LUTs, indicate which output at an internal level of LUT multiplexing structure will be used
|
||||
* 20. port_sram_orgz_: only applicable to SRAM ports, indicate how the SRAMs will be organized, either memory decoders or scan-chains
|
||||
* 12. port_is_edge_triggered: specify if this port is triggerd by edges like the clock signal of a D-type flip-flop
|
||||
* 13. port_is_prog: specify if this port is for FPGA programming use which needs special pulse widths in testbenches
|
||||
* 14. port_tri_state_model_name: the name of circuit model linked to tri-state the port
|
||||
* 15. port_tri_state_model_ids_: the Id of circuit model linked to tri-state the port
|
||||
* 16. port_inv_model_names_: the name of inverter circuit model linked to the port
|
||||
* 17. port_inv_model_ids_: the Id of inverter circuit model linked to the port
|
||||
* 18. port_tri_state_map_: only applicable to inputs of LUTs, the tri-state map applied to each pin of this port
|
||||
* 19. port_lut_frac_level_: only applicable to outputs of LUTs, indicate which level of outputs inside LUT multiplexing structure will be used
|
||||
* 20. port_lut_output_mask_: only applicable to outputs of LUTs, indicate which output at an internal level of LUT multiplexing structure will be used
|
||||
* 21. port_sram_orgz_: only applicable to SRAM ports, indicate how the SRAMs will be organized, either memory decoders or scan-chains
|
||||
*
|
||||
* ------ Delay information ------
|
||||
* 1. delay_types_: type of pin-to-pin delay, either rising_edge of falling_edge
|
||||
|
@ -284,6 +285,7 @@ class CircuitLibrary {
|
|||
bool port_is_reset(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_edge_triggered(const CircuitPortId& circuit_port_id) const;
|
||||
bool port_is_prog(const CircuitPortId& circuit_port_id) const;
|
||||
size_t port_lut_frac_level(const CircuitPortId& circuit_port_id) const;
|
||||
std::vector<size_t> port_lut_output_mask(const CircuitPortId& circuit_port_id) const;
|
||||
|
@ -364,6 +366,8 @@ class CircuitLibrary {
|
|||
const bool& is_set);
|
||||
void set_port_is_config_enable(const CircuitPortId& circuit_port_id,
|
||||
const bool& is_config_enable);
|
||||
void set_port_is_edge_triggered(const CircuitPortId& circuit_port_id,
|
||||
const bool& is_edge_triggered);
|
||||
void set_port_is_prog(const CircuitPortId& circuit_port_id,
|
||||
const bool& is_prog);
|
||||
void set_port_tri_state_model_name(const CircuitPortId& circuit_port_id,
|
||||
|
@ -550,6 +554,7 @@ class CircuitLibrary {
|
|||
vtr::vector<CircuitPortId, bool> port_is_reset_;
|
||||
vtr::vector<CircuitPortId, bool> port_is_set_;
|
||||
vtr::vector<CircuitPortId, bool> port_is_config_enable_;
|
||||
vtr::vector<CircuitPortId, bool> port_is_edge_triggered_;
|
||||
vtr::vector<CircuitPortId, bool> port_is_prog_;
|
||||
vtr::vector<CircuitPortId, std::string> port_tri_state_model_names_;
|
||||
vtr::vector<CircuitPortId, CircuitModelId> port_tri_state_model_ids_;
|
||||
|
|
|
@ -564,6 +564,9 @@ void read_xml_circuit_port(pugi::xml_node& xml_port,
|
|||
/* 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));
|
||||
|
||||
/* Identify if the port is to triggered by edges, by default it is NOT */
|
||||
circuit_lib.set_port_is_edge_triggered(port, get_attribute(xml_port, "is_edge_triggered", loc_data, pugiutil::ReqOpt::OPTIONAL).as_bool(false));
|
||||
|
||||
/* Find the name of circuit model that this port is linked to */
|
||||
circuit_lib.set_port_tri_state_model_name(port, get_attribute(xml_port, "circuit_model_name", loc_data, pugiutil::ReqOpt::OPTIONAL).as_string());
|
||||
|
||||
|
|
|
@ -207,6 +207,10 @@ void write_xml_circuit_port(std::fstream& fp,
|
|||
write_xml_attribute(fp, "is_config_enable", "true");
|
||||
}
|
||||
|
||||
if (true == circuit_lib.port_is_edge_triggered(port)) {
|
||||
write_xml_attribute(fp, "is_edge_triggered", "true");
|
||||
}
|
||||
|
||||
/* Output the name of circuit model that this port is linked to */
|
||||
if (!circuit_lib.port_tri_state_model_name(port).empty()) {
|
||||
write_xml_attribute(fp, "circuit_model_name", circuit_lib.port_tri_state_model_name(port).c_str());
|
||||
|
|
|
@ -97,7 +97,7 @@ int write_verilog_testbench(OpenfpgaContext& openfpga_ctx,
|
|||
openfpga_ctx.vpr_netlist_annotation(),
|
||||
openfpga_ctx.arch().circuit_lib,
|
||||
openfpga_ctx.simulation_setting(),
|
||||
openfpga_ctx.arch().config_protocol.type(),
|
||||
openfpga_ctx.arch().config_protocol,
|
||||
options);
|
||||
|
||||
/* TODO: should identify the error code from internal function execution */
|
||||
|
|
|
@ -156,7 +156,7 @@ void fpga_verilog_testbench(const ModuleManager &module_manager,
|
|||
const VprNetlistAnnotation &netlist_annotation,
|
||||
const CircuitLibrary &circuit_lib,
|
||||
const SimulationSetting &simulation_setting,
|
||||
const e_config_protocol_type &config_protocol_type,
|
||||
const ConfigProtocol &config_protocol,
|
||||
const VerilogTestbenchOption &options) {
|
||||
|
||||
vtr::ScopedStartFinishTimer timer("Write Verilog testbenches for FPGA fabric\n");
|
||||
|
@ -205,7 +205,7 @@ void fpga_verilog_testbench(const ModuleManager &module_manager,
|
|||
std::string top_testbench_file_path = src_dir_path + netlist_name + std::string(AUTOCHECK_TOP_TESTBENCH_VERILOG_FILE_POSTFIX);
|
||||
print_verilog_top_testbench(module_manager,
|
||||
bitstream_manager, fabric_bitstream,
|
||||
config_protocol_type,
|
||||
config_protocol,
|
||||
circuit_lib, global_ports,
|
||||
atom_ctx, place_ctx, io_location_map,
|
||||
netlist_annotation,
|
||||
|
@ -225,7 +225,7 @@ void fpga_verilog_testbench(const ModuleManager &module_manager,
|
|||
src_dir_path,
|
||||
atom_ctx, place_ctx, io_location_map,
|
||||
module_manager,
|
||||
config_protocol_type,
|
||||
config_protocol.type(),
|
||||
bitstream_manager.num_bits(),
|
||||
simulation_setting.num_clock_cycles(),
|
||||
simulation_setting.programming_clock_frequency(),
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include "mux_library.h"
|
||||
#include "decoder_library.h"
|
||||
#include "circuit_library.h"
|
||||
#include "config_protocol.h"
|
||||
#include "vpr_context.h"
|
||||
#include "vpr_device_annotation.h"
|
||||
#include "device_rr_gsb.h"
|
||||
|
@ -49,7 +50,7 @@ void fpga_verilog_testbench(const ModuleManager& module_manager,
|
|||
const VprNetlistAnnotation& netlist_annotation,
|
||||
const CircuitLibrary& circuit_lib,
|
||||
const SimulationSetting& simulation_parameters,
|
||||
const e_config_protocol_type& config_protocol_type,
|
||||
const ConfigProtocol& config_protocol,
|
||||
const VerilogTestbenchOption& options);
|
||||
|
||||
|
||||
|
|
|
@ -153,6 +153,8 @@ void print_verilog_top_testbench_memory_bank_port(std::fstream& fp,
|
|||
*******************************************************************/
|
||||
static
|
||||
void print_verilog_top_testbench_frame_decoder_port(std::fstream& fp,
|
||||
const ConfigProtocol& config_protocol,
|
||||
const CircuitLibrary& circuit_lib,
|
||||
const ModuleManager& module_manager,
|
||||
const ModuleId& top_module) {
|
||||
/* Validate the file stream */
|
||||
|
@ -174,15 +176,32 @@ void print_verilog_top_testbench_frame_decoder_port(std::fstream& fp,
|
|||
fp << generate_verilog_port(VERILOG_PORT_REG, din_port) << ";" << std::endl;
|
||||
|
||||
/* Wire the INVERTED configuration done signal to the enable signal !!! */
|
||||
print_verilog_comment(fp, std::string("---- Wire enable port of frame-based decoder to inverted configuration done signal -----"));
|
||||
ModulePortId en_port_id = module_manager.find_module_port(top_module,
|
||||
std::string(DECODER_ENABLE_PORT_NAME));
|
||||
BasicPort en_port = module_manager.module_port(top_module, en_port_id);
|
||||
BasicPort config_done_port(std::string(TOP_TB_CONFIG_DONE_PORT_NAME), 1);
|
||||
|
||||
fp << generate_verilog_port(VERILOG_PORT_WIRE, en_port) << ";" << std::endl;
|
||||
print_verilog_wire_connection(fp, en_port, config_done_port, true);
|
||||
/* Find the circuit model of configurable memory
|
||||
* Spot its BL port and generate stimuli based on BL port's attribute:
|
||||
* - If the BL port is triggered by edge, use the inverted programming clock signal
|
||||
* - If the BL port is a regular port, use the inverted configuration done signal
|
||||
*/
|
||||
const CircuitModelId& mem_model = config_protocol.memory_model();
|
||||
VTR_ASSERT(true == circuit_lib.valid_model_id(mem_model));
|
||||
std::vector<CircuitPortId> mem_model_bl_ports = circuit_lib.model_ports_by_type(mem_model, CIRCUIT_MODEL_PORT_BL);
|
||||
VTR_ASSERT(1 == mem_model_bl_ports.size());
|
||||
|
||||
if (true == circuit_lib.port_is_edge_triggered(mem_model_bl_ports[0])) {
|
||||
VTR_ASSERT_SAFE(false == circuit_lib.port_is_edge_triggered(mem_model_bl_ports[0]));
|
||||
BasicPort prog_clock_port(std::string(TOP_TB_PROG_CLOCK_PORT_NAME), 1);
|
||||
print_verilog_comment(fp, std::string("---- Wire enable port of frame-based decoder to inverted programming clock signal -----"));
|
||||
fp << generate_verilog_port(VERILOG_PORT_WIRE, en_port) << ";" << std::endl;
|
||||
print_verilog_wire_connection(fp, en_port, prog_clock_port, true);
|
||||
} else {
|
||||
BasicPort config_done_port(std::string(TOP_TB_CONFIG_DONE_PORT_NAME), 1);
|
||||
print_verilog_comment(fp, std::string("---- Wire enable port of frame-based decoder to inverted configuration done signal -----"));
|
||||
fp << generate_verilog_port(VERILOG_PORT_WIRE, en_port) << ";" << std::endl;
|
||||
print_verilog_wire_connection(fp, en_port, config_done_port, true);
|
||||
}
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
|
@ -190,10 +209,11 @@ void print_verilog_top_testbench_frame_decoder_port(std::fstream& fp,
|
|||
*******************************************************************/
|
||||
static
|
||||
void print_verilog_top_testbench_config_protocol_port(std::fstream& fp,
|
||||
const e_config_protocol_type& sram_orgz_type,
|
||||
const ConfigProtocol& config_protocol,
|
||||
const CircuitLibrary& circuit_lib,
|
||||
const ModuleManager& module_manager,
|
||||
const ModuleId& top_module) {
|
||||
switch(sram_orgz_type) {
|
||||
switch(config_protocol.type()) {
|
||||
case CONFIG_MEM_STANDALONE:
|
||||
print_verilog_top_testbench_flatten_memory_port(fp, module_manager, top_module);
|
||||
break;
|
||||
|
@ -204,7 +224,8 @@ void print_verilog_top_testbench_config_protocol_port(std::fstream& fp,
|
|||
print_verilog_top_testbench_memory_bank_port(fp, module_manager, top_module);
|
||||
break;
|
||||
case CONFIG_MEM_FRAME_BASED:
|
||||
print_verilog_top_testbench_frame_decoder_port(fp, module_manager, top_module);
|
||||
print_verilog_top_testbench_frame_decoder_port(fp, config_protocol, circuit_lib,
|
||||
module_manager, top_module);
|
||||
break;
|
||||
default:
|
||||
VTR_LOGF_ERROR(__FILE__, __LINE__,
|
||||
|
@ -435,7 +456,8 @@ void print_verilog_top_testbench_ports(std::fstream& fp,
|
|||
const AtomContext& atom_ctx,
|
||||
const VprNetlistAnnotation& netlist_annotation,
|
||||
const std::vector<std::string>& clock_port_names,
|
||||
const e_config_protocol_type& sram_orgz_type,
|
||||
const ConfigProtocol& config_protocol,
|
||||
const CircuitLibrary& circuit_lib,
|
||||
const std::string& circuit_name){
|
||||
/* Validate the file stream */
|
||||
valid_file_stream(fp);
|
||||
|
@ -509,7 +531,7 @@ void print_verilog_top_testbench_ports(std::fstream& fp,
|
|||
fp << generate_verilog_port(VERILOG_PORT_REG, set_port) << ";" << std::endl;
|
||||
|
||||
/* Configuration ports depend on the organization of SRAMs */
|
||||
print_verilog_top_testbench_config_protocol_port(fp, sram_orgz_type,
|
||||
print_verilog_top_testbench_config_protocol_port(fp, config_protocol, circuit_lib,
|
||||
module_manager, top_module);
|
||||
|
||||
/* Create a clock port if the benchmark have one but not in the default name!
|
||||
|
@ -1459,7 +1481,7 @@ void print_verilog_top_testbench_bitstream(std::fstream& fp,
|
|||
void print_verilog_top_testbench(const ModuleManager& module_manager,
|
||||
const BitstreamManager& bitstream_manager,
|
||||
const FabricBitstream& fabric_bitstream,
|
||||
const e_config_protocol_type& sram_orgz_type,
|
||||
const ConfigProtocol& config_protocol,
|
||||
const CircuitLibrary& circuit_lib,
|
||||
const std::vector<CircuitPortId>& global_ports,
|
||||
const AtomContext& atom_ctx,
|
||||
|
@ -1498,13 +1520,14 @@ void print_verilog_top_testbench(const ModuleManager& module_manager,
|
|||
/* Start of testbench */
|
||||
print_verilog_top_testbench_ports(fp, module_manager, top_module,
|
||||
atom_ctx, netlist_annotation, clock_port_names,
|
||||
sram_orgz_type, circuit_name);
|
||||
config_protocol, circuit_lib,
|
||||
circuit_name);
|
||||
|
||||
/* Find the clock period */
|
||||
float prog_clock_period = (1./simulation_parameters.programming_clock_frequency());
|
||||
float op_clock_period = (1./simulation_parameters.operating_clock_frequency());
|
||||
/* Estimate the number of configuration clock cycles */
|
||||
size_t num_config_clock_cycles = calculate_num_config_clock_cycles(sram_orgz_type,
|
||||
size_t num_config_clock_cycles = calculate_num_config_clock_cycles(config_protocol.type(),
|
||||
fast_configuration,
|
||||
bitstream_manager,
|
||||
fabric_bitstream);
|
||||
|
@ -1543,11 +1566,11 @@ void print_verilog_top_testbench(const ModuleManager& module_manager,
|
|||
|
||||
/* Print tasks used for loading bitstreams */
|
||||
print_verilog_top_testbench_load_bitstream_task(fp,
|
||||
sram_orgz_type,
|
||||
config_protocol.type(),
|
||||
module_manager, top_module);
|
||||
|
||||
/* load bitstream to FPGA fabric in a configuration phase */
|
||||
print_verilog_top_testbench_bitstream(fp, sram_orgz_type,
|
||||
print_verilog_top_testbench_bitstream(fp, config_protocol.type(),
|
||||
fast_configuration,
|
||||
module_manager, top_module,
|
||||
bitstream_manager, fabric_bitstream);
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include "bitstream_manager.h"
|
||||
#include "fabric_bitstream.h"
|
||||
#include "circuit_library.h"
|
||||
#include "config_protocol.h"
|
||||
#include "vpr_context.h"
|
||||
#include "io_location_map.h"
|
||||
#include "vpr_netlist_annotation.h"
|
||||
|
@ -25,7 +26,7 @@ namespace openfpga {
|
|||
void print_verilog_top_testbench(const ModuleManager& module_manager,
|
||||
const BitstreamManager& bitstream_manager,
|
||||
const FabricBitstream& fabric_bitstream,
|
||||
const e_config_protocol_type& sram_orgz_type,
|
||||
const ConfigProtocol& config_protocol,
|
||||
const CircuitLibrary& circuit_lib,
|
||||
const std::vector<CircuitPortId>& global_ports,
|
||||
const AtomContext& atom_ctx,
|
||||
|
|
Loading…
Reference in New Issue