[Tool] Remove the limitation on requiring Qb ports for CCFF
This commit is contained in:
parent
2aab8bf910
commit
ba0120bd76
|
@ -302,7 +302,7 @@ size_t check_ccff_circuit_model_ports(const CircuitLibrary& circuit_lib,
|
|||
/* Check if we have output */
|
||||
num_err += check_one_circuit_model_port_type_and_size_required(circuit_lib, circuit_model,
|
||||
CIRCUIT_MODEL_PORT_OUTPUT,
|
||||
2, 1, false);
|
||||
1, 1, false);
|
||||
|
||||
return num_err;
|
||||
}
|
||||
|
|
|
@ -152,10 +152,6 @@ BitstreamManager build_device_bitstream(const VprContext& vpr_ctx,
|
|||
/* Bitstream manager to be built */
|
||||
BitstreamManager bitstream_manager;
|
||||
|
||||
/* Assign the SRAM model applied to the FPGA fabric */
|
||||
CircuitModelId sram_model = openfpga_ctx.arch().config_protocol.memory_model();
|
||||
VTR_ASSERT(true == openfpga_ctx.arch().circuit_lib.valid_model_id(sram_model));
|
||||
|
||||
/* Create the top-level block for bitstream
|
||||
* This is related to the top-level module of fpga
|
||||
*/
|
||||
|
|
|
@ -181,6 +181,7 @@ void fpga_verilog_testbench(const ModuleManager &module_manager,
|
|||
if (true == options.print_formal_verification_top_netlist()) {
|
||||
std::string formal_verification_top_netlist_file_path = src_dir_path + netlist_name + std::string(FORMAL_VERIFICATION_VERILOG_FILE_POSTFIX);
|
||||
print_verilog_preconfig_top_module(module_manager, bitstream_manager,
|
||||
config_protocol,
|
||||
circuit_lib, global_ports,
|
||||
atom_ctx, place_ctx, io_location_map,
|
||||
netlist_annotation,
|
||||
|
|
|
@ -189,7 +189,8 @@ namespace openfpga
|
|||
static void print_verilog_preconfig_top_module_assign_bitstream(std::fstream &fp,
|
||||
const ModuleManager &module_manager,
|
||||
const ModuleId &top_module,
|
||||
const BitstreamManager &bitstream_manager)
|
||||
const BitstreamManager &bitstream_manager,
|
||||
const bool& output_datab_bits)
|
||||
{
|
||||
/* Validate the file stream */
|
||||
valid_file_stream(fp);
|
||||
|
@ -231,44 +232,46 @@ namespace openfpga
|
|||
print_verilog_wire_constant_values(fp, config_data_port, config_data_values);
|
||||
}
|
||||
|
||||
fp << "initial begin" << std::endl;
|
||||
if (true == output_datab_bits) {
|
||||
fp << "initial begin" << std::endl;
|
||||
|
||||
for (const ConfigBlockId &config_block_id : bitstream_manager.blocks())
|
||||
{
|
||||
/* We only cares blocks with configuration bits */
|
||||
if (0 == bitstream_manager.block_bits(config_block_id).size())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
/* Build the hierarchical path of the configuration bit in modules */
|
||||
std::vector<ConfigBlockId> block_hierarchy = find_bitstream_manager_block_hierarchy(bitstream_manager, config_block_id);
|
||||
/* Drop the first block, which is the top module, it should be replaced by the instance name here */
|
||||
/* Ensure that this is the module we want to drop! */
|
||||
VTR_ASSERT(0 == module_manager.module_name(top_module).compare(bitstream_manager.block_name(block_hierarchy[0])));
|
||||
block_hierarchy.erase(block_hierarchy.begin());
|
||||
/* Build the full hierarchy path */
|
||||
std::string bit_hierarchy_path(FORMAL_VERIFICATION_TOP_MODULE_UUT_NAME);
|
||||
for (const ConfigBlockId &temp_block : block_hierarchy)
|
||||
for (const ConfigBlockId &config_block_id : bitstream_manager.blocks())
|
||||
{
|
||||
/* We only cares blocks with configuration bits */
|
||||
if (0 == bitstream_manager.block_bits(config_block_id).size())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
/* Build the hierarchical path of the configuration bit in modules */
|
||||
std::vector<ConfigBlockId> block_hierarchy = find_bitstream_manager_block_hierarchy(bitstream_manager, config_block_id);
|
||||
/* Drop the first block, which is the top module, it should be replaced by the instance name here */
|
||||
/* Ensure that this is the module we want to drop! */
|
||||
VTR_ASSERT(0 == module_manager.module_name(top_module).compare(bitstream_manager.block_name(block_hierarchy[0])));
|
||||
block_hierarchy.erase(block_hierarchy.begin());
|
||||
/* Build the full hierarchy path */
|
||||
std::string bit_hierarchy_path(FORMAL_VERIFICATION_TOP_MODULE_UUT_NAME);
|
||||
for (const ConfigBlockId &temp_block : block_hierarchy)
|
||||
{
|
||||
bit_hierarchy_path += std::string(".");
|
||||
bit_hierarchy_path += bitstream_manager.block_name(temp_block);
|
||||
}
|
||||
bit_hierarchy_path += std::string(".");
|
||||
bit_hierarchy_path += bitstream_manager.block_name(temp_block);
|
||||
}
|
||||
bit_hierarchy_path += std::string(".");
|
||||
|
||||
/* Find the bit index in the parent block */
|
||||
BasicPort config_datab_port(bit_hierarchy_path + generate_configurable_memory_inverted_data_out_name(),
|
||||
bitstream_manager.block_bits(config_block_id).size());
|
||||
/* Find the bit index in the parent block */
|
||||
BasicPort config_datab_port(bit_hierarchy_path + generate_configurable_memory_inverted_data_out_name(),
|
||||
bitstream_manager.block_bits(config_block_id).size());
|
||||
|
||||
std::vector<size_t> config_datab_values;
|
||||
for (const ConfigBitId config_bit : bitstream_manager.block_bits(config_block_id))
|
||||
{
|
||||
config_datab_values.push_back(!bitstream_manager.bit_value(config_bit));
|
||||
std::vector<size_t> config_datab_values;
|
||||
for (const ConfigBitId config_bit : bitstream_manager.block_bits(config_block_id))
|
||||
{
|
||||
config_datab_values.push_back(!bitstream_manager.bit_value(config_bit));
|
||||
}
|
||||
print_verilog_force_wire_constant_values(fp, config_datab_port, config_datab_values);
|
||||
}
|
||||
print_verilog_force_wire_constant_values(fp, config_datab_port, config_datab_values);
|
||||
|
||||
fp << "end" << std::endl;
|
||||
}
|
||||
|
||||
fp << "end" << std::endl;
|
||||
|
||||
print_verilog_comment(fp, std::string("----- End assign bitstream to configuration memories -----"));
|
||||
}
|
||||
|
||||
|
@ -279,7 +282,8 @@ namespace openfpga
|
|||
static void print_verilog_preconfig_top_module_deposit_bitstream(std::fstream &fp,
|
||||
const ModuleManager &module_manager,
|
||||
const ModuleId &top_module,
|
||||
const BitstreamManager &bitstream_manager)
|
||||
const BitstreamManager &bitstream_manager,
|
||||
const bool& output_datab_bits)
|
||||
{
|
||||
/* Validate the file stream */
|
||||
valid_file_stream(fp);
|
||||
|
@ -314,9 +318,6 @@ namespace openfpga
|
|||
BasicPort config_data_port(bit_hierarchy_path + generate_configurable_memory_data_out_name(),
|
||||
bitstream_manager.block_bits(config_block_id).size());
|
||||
|
||||
BasicPort config_datab_port(bit_hierarchy_path + generate_configurable_memory_inverted_data_out_name(),
|
||||
bitstream_manager.block_bits(config_block_id).size());
|
||||
|
||||
/* Wire it to the configuration bit: access both data out and data outb ports */
|
||||
std::vector<size_t> config_data_values;
|
||||
for (const ConfigBitId config_bit : bitstream_manager.block_bits(config_block_id))
|
||||
|
@ -325,6 +326,15 @@ namespace openfpga
|
|||
}
|
||||
print_verilog_deposit_wire_constant_values(fp, config_data_port, config_data_values);
|
||||
|
||||
/* Skip datab ports if specified */
|
||||
if (false == output_datab_bits) {
|
||||
continue;
|
||||
}
|
||||
|
||||
BasicPort config_datab_port(bit_hierarchy_path + generate_configurable_memory_inverted_data_out_name(),
|
||||
bitstream_manager.block_bits(config_block_id).size());
|
||||
|
||||
|
||||
std::vector<size_t> config_datab_values;
|
||||
for (const ConfigBitId config_bit : bitstream_manager.block_bits(config_block_id))
|
||||
{
|
||||
|
@ -347,19 +357,37 @@ namespace openfpga
|
|||
static void print_verilog_preconfig_top_module_load_bitstream(std::fstream &fp,
|
||||
const ModuleManager &module_manager,
|
||||
const ModuleId &top_module,
|
||||
const CircuitLibrary& circuit_lib,
|
||||
const CircuitModelId& mem_model,
|
||||
const BitstreamManager &bitstream_manager)
|
||||
{
|
||||
|
||||
/* Skip the datab port if there is only 1 output port in memory model
|
||||
* Currently, it assumes that the data output port is always defined while datab is optional
|
||||
* If we see only 1 port, we assume datab is not defined by default.
|
||||
* TODO: this switch could be smarter: it should identify if only data or datab
|
||||
* ports are defined.
|
||||
*/
|
||||
bool output_datab_bits = true;
|
||||
if (1 == circuit_lib.model_ports_by_type(mem_model, CIRCUIT_MODEL_PORT_OUTPUT).size()) {
|
||||
output_datab_bits = false;
|
||||
}
|
||||
|
||||
print_verilog_comment(fp, std::string("----- Begin load bitstream to configuration memories -----"));
|
||||
|
||||
print_verilog_preprocessing_flag(fp, std::string(ICARUS_SIMULATOR_FLAG));
|
||||
|
||||
/* Use assign syntax for Icarus simulator */
|
||||
print_verilog_preconfig_top_module_assign_bitstream(fp, module_manager, top_module, bitstream_manager);
|
||||
print_verilog_preconfig_top_module_assign_bitstream(fp, module_manager, top_module,
|
||||
bitstream_manager,
|
||||
output_datab_bits);
|
||||
|
||||
fp << "`else" << std::endl;
|
||||
|
||||
/* Use assign syntax for Icarus simulator */
|
||||
print_verilog_preconfig_top_module_deposit_bitstream(fp, module_manager, top_module, bitstream_manager);
|
||||
print_verilog_preconfig_top_module_deposit_bitstream(fp, module_manager, top_module,
|
||||
bitstream_manager,
|
||||
output_datab_bits);
|
||||
|
||||
print_verilog_endif(fp);
|
||||
|
||||
|
@ -400,6 +428,7 @@ namespace openfpga
|
|||
*******************************************************************/
|
||||
void print_verilog_preconfig_top_module(const ModuleManager &module_manager,
|
||||
const BitstreamManager &bitstream_manager,
|
||||
const ConfigProtocol &config_protocol,
|
||||
const CircuitLibrary &circuit_lib,
|
||||
const std::vector<CircuitPortId> &global_ports,
|
||||
const AtomContext &atom_ctx,
|
||||
|
@ -457,8 +486,13 @@ namespace openfpga
|
|||
std::string(FORMAL_VERIFICATION_TOP_MODULE_PORT_POSTFIX),
|
||||
(size_t)VERILOG_DEFAULT_SIGNAL_INIT_VALUE);
|
||||
|
||||
/* Assign the SRAM model applied to the FPGA fabric */
|
||||
CircuitModelId sram_model = config_protocol.memory_model();
|
||||
VTR_ASSERT(true == circuit_lib.valid_model_id(sram_model));
|
||||
|
||||
/* Assign FPGA internal SRAM/Memory ports to bitstream values */
|
||||
print_verilog_preconfig_top_module_load_bitstream(fp, module_manager, top_module,
|
||||
circuit_lib, sram_model,
|
||||
bitstream_manager);
|
||||
|
||||
/* Testbench ends*/
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include "module_manager.h"
|
||||
#include "bitstream_manager.h"
|
||||
#include "io_location_map.h"
|
||||
#include "config_protocol.h"
|
||||
#include "vpr_netlist_annotation.h"
|
||||
|
||||
/********************************************************************
|
||||
|
@ -22,6 +23,7 @@ namespace openfpga {
|
|||
|
||||
void print_verilog_preconfig_top_module(const ModuleManager& module_manager,
|
||||
const BitstreamManager& bitstream_manager,
|
||||
const ConfigProtocol &config_protocol,
|
||||
const CircuitLibrary& circuit_lib,
|
||||
const std::vector<CircuitPortId>& global_ports,
|
||||
const AtomContext& atom_ctx,
|
||||
|
|
|
@ -776,7 +776,7 @@ void add_module_nets_between_logic_and_memory_sram_bus(ModuleManager& module_man
|
|||
|
||||
/* Do wiring only when we have sramb ports */
|
||||
if ( (false == logic_module_sramb_port_ids.empty())
|
||||
|| (ModulePortId::INVALID() == mem_module_sramb_port_id) ) {
|
||||
&& (ModulePortId::INVALID() != mem_module_sramb_port_id) ) {
|
||||
add_module_nets_between_logic_and_memory_sram_ports(module_manager, parent_module,
|
||||
logic_module, logic_instance_id,
|
||||
memory_module, memory_instance_id,
|
||||
|
|
Loading…
Reference in New Issue