pass current regression tests
This commit is contained in:
parent
55fbd72293
commit
7460dc8cab
|
@ -99,10 +99,18 @@ std::vector<bool> build_cmos_mux_bitstream(const CircuitLibrary& circuit_lib,
|
|||
*/
|
||||
for (const size_t& level : mux_graph.levels()) {
|
||||
/* The encoder will convert the path_id to a binary number
|
||||
* For example: when path_id=3 (use the 4th input), using a 4-input encoder
|
||||
* the sram_bits will be the 4-digit binary number of 3: 0100
|
||||
* For example: when path_id=3 (use the 4th input), using a 2-input encoder
|
||||
* the sram_bits will be the 2-digit binary number of 3: 10
|
||||
*/
|
||||
std::vector<size_t> encoder_data;
|
||||
|
||||
/* Exception: there is only 1 memory at this level, bitstream will not be changed!!! */
|
||||
if (1 == mux_graph.memories_at_level(level).size()) {
|
||||
mux_bitstream.push_back(raw_bitstream[mux_graph.memories_at_level(level)[0]]);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Otherwise: we follow a regular recipe */
|
||||
for (size_t mem_index = 0; mem_index < mux_graph.memories_at_level(level).size(); ++mem_index) {
|
||||
/* Conversion rule: true = 1, false = 0 */
|
||||
if (true == raw_bitstream[mux_graph.memories_at_level(level)[mem_index]]) {
|
||||
|
@ -121,7 +129,7 @@ std::vector<bool> build_cmos_mux_bitstream(const CircuitLibrary& circuit_lib,
|
|||
}
|
||||
/* Build final mux bitstream */
|
||||
for (const size_t& bit : encoder_addr) {
|
||||
mux_bitstream.push_back((bool)bit);
|
||||
mux_bitstream.push_back(1 == bit);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1004,6 +1004,7 @@ void build_mux_module_local_encoders_and_memory_nets(ModuleManager& module_manag
|
|||
|
||||
/* Local port to record the LSB and MSB of each level, here, we deposite (0, 0) */
|
||||
ModulePortId mux_module_sram_port_id = module_manager.find_module_port(mux_module, circuit_lib.port_lib_name(mux_sram_ports[0]));
|
||||
ModulePortId mux_module_sram_inv_port_id = module_manager.find_module_port(mux_module, circuit_lib.port_lib_name(mux_sram_ports[0]) + "_inv");
|
||||
BasicPort lvl_addr_port(circuit_lib.port_lib_name(mux_sram_ports[0]), 0);
|
||||
BasicPort lvl_data_port(decoder_data_port.get_name(), 0);
|
||||
BasicPort lvl_data_inv_port(decoder_data_inv_port.get_name(), 0);
|
||||
|
@ -1020,6 +1021,24 @@ void build_mux_module_local_encoders_and_memory_nets(ModuleManager& module_manag
|
|||
lvl_data_port.rotate(data_size);
|
||||
lvl_data_inv_port.rotate(data_size);
|
||||
|
||||
/* Exception: if the data size is one, we just need wires! */
|
||||
if (1 == data_size) {
|
||||
for (size_t pin_id = 0; pin_id < lvl_addr_port.pins().size(); ++pin_id) {
|
||||
MuxMemId mem_id = MuxMemId(mem_net_cnt);
|
||||
/* Set the module net source */
|
||||
module_manager.add_module_net_source(mux_module, mux_mem_nets[mem_id], mux_module, 0, mux_module_sram_port_id, lvl_addr_port.pins()[pin_id]);
|
||||
/* Update counter */
|
||||
mem_net_cnt++;
|
||||
|
||||
MuxMemId mem_inv_id = MuxMemId(mem_inv_net_cnt);
|
||||
/* Set the module net source */
|
||||
module_manager.add_module_net_source(mux_module, mux_mem_inv_nets[mem_inv_id], mux_module, 0, mux_module_sram_inv_port_id, lvl_addr_port.pins()[pin_id]);
|
||||
/* Update counter */
|
||||
mem_inv_net_cnt++;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
std::string decoder_module_name = generate_mux_local_decoder_subckt_name(addr_size, data_size);
|
||||
ModuleId decoder_module = module_manager.find_module(decoder_module_name);
|
||||
VTR_ASSERT(ModuleId::INVALID() != decoder_module);
|
||||
|
|
|
@ -82,8 +82,8 @@ void print_verilog_mux_local_decoder_module(std::fstream& fp,
|
|||
* data_inv = ~data_inv
|
||||
*/
|
||||
if (1 == data_size) {
|
||||
print_verilog_wire_connection(fp, addr_port, data_port, false);
|
||||
print_verilog_wire_connection(fp, data_inv_port, data_port, true);
|
||||
print_verilog_wire_connection(fp, data_port, addr_port, false);
|
||||
print_verilog_wire_connection(fp, data_inv_port, addr_port, true);
|
||||
print_verilog_comment(fp, std::string("----- END Verilog codes for Decoder convert " + std::to_string(addr_size) + "-bit addr to " + std::to_string(data_size) + "-bit data -----"));
|
||||
|
||||
/* Put an end to the Verilog module */
|
||||
|
|
|
@ -266,13 +266,101 @@ void print_verilog_preconfig_top_module_connect_ios(std::fstream& fp,
|
|||
|
||||
/********************************************************************
|
||||
* Impose the bitstream on the configuration memories
|
||||
* This function uses 'assign' syntax to impost the bitstream at mem port
|
||||
* while uses 'force' syntax to impost the bitstream at mem_inv port
|
||||
*******************************************************************/
|
||||
static
|
||||
void print_verilog_preconfig_top_module_load_bitstream(std::fstream& fp,
|
||||
const ModuleManager& module_manager,
|
||||
const ModuleId& top_module,
|
||||
const BitstreamManager& bitstream_manager) {
|
||||
print_verilog_comment(fp, std::string("----- Begin load bitstream to configuration memories -----"));
|
||||
void print_verilog_preconfig_top_module_assign_bitstream(std::fstream& fp,
|
||||
const ModuleManager& module_manager,
|
||||
const ModuleId& top_module,
|
||||
const BitstreamManager& bitstream_manager) {
|
||||
/* Validate the file stream */
|
||||
check_file_handler(fp);
|
||||
|
||||
print_verilog_comment(fp, std::string("----- Begin assign bitstream to configuration memories -----"));
|
||||
|
||||
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(".");
|
||||
|
||||
/* Find the bit index in the parent block */
|
||||
BasicPort config_data_port(bit_hierarchy_path + generate_configuration_chain_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)) {
|
||||
config_data_values.push_back(bitstream_manager.bit_value(config_bit));
|
||||
}
|
||||
print_verilog_wire_constant_values(fp, config_data_port, config_data_values);
|
||||
}
|
||||
|
||||
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) {
|
||||
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_configuration_chain_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));
|
||||
}
|
||||
print_verilog_force_wire_constant_values(fp, config_datab_port, config_datab_values);
|
||||
}
|
||||
|
||||
fp << "end" << std::endl;
|
||||
|
||||
print_verilog_comment(fp, std::string("----- End assign bitstream to configuration memories -----"));
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
* Impose the bitstream on the configuration memories
|
||||
* This function uses '$deposit' syntax to do so
|
||||
*******************************************************************/
|
||||
static
|
||||
void print_verilog_preconfig_top_module_deposit_bitstream(std::fstream& fp,
|
||||
const ModuleManager& module_manager,
|
||||
const ModuleId& top_module,
|
||||
const BitstreamManager& bitstream_manager) {
|
||||
/* Validate the file stream */
|
||||
check_file_handler(fp);
|
||||
|
||||
print_verilog_comment(fp, std::string("----- Begin deposit bitstream to configuration memories -----"));
|
||||
|
||||
fp << "initial begin" << std::endl;
|
||||
|
||||
for (const ConfigBlockId& config_block_id : bitstream_manager.blocks()) {
|
||||
|
@ -316,6 +404,35 @@ void print_verilog_preconfig_top_module_load_bitstream(std::fstream& fp,
|
|||
}
|
||||
|
||||
fp << "end" << std::endl;
|
||||
|
||||
print_verilog_comment(fp, std::string("----- End deposit bitstream to configuration memories -----"));
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
* Impose the bitstream on the configuration memories
|
||||
* We branch here for different simulators:
|
||||
* 1. iVerilog Icarus prefers using 'assign' syntax to force the values
|
||||
* 2. Mentor Modelsim prefers using '$deposit' syntax to do so
|
||||
*******************************************************************/
|
||||
static
|
||||
void print_verilog_preconfig_top_module_load_bitstream(std::fstream& fp,
|
||||
const ModuleManager& module_manager,
|
||||
const ModuleId& top_module,
|
||||
const BitstreamManager& bitstream_manager) {
|
||||
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);
|
||||
|
||||
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_endif(fp);
|
||||
|
||||
print_verilog_comment(fp, std::string("----- End load bitstream to configuration memories -----"));
|
||||
}
|
||||
|
||||
|
|
|
@ -682,6 +682,21 @@ void print_verilog_deposit_wire_constant_values(std::fstream& fp,
|
|||
fp << ");" << std::endl;
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
* Generate a wire connection, that assigns constant values to a
|
||||
* Verilog port
|
||||
*******************************************************************/
|
||||
void print_verilog_force_wire_constant_values(std::fstream& fp,
|
||||
const BasicPort& output_port,
|
||||
const std::vector<size_t>& const_values) {
|
||||
/* Make sure we have a valid file handler*/
|
||||
check_file_handler(fp);
|
||||
|
||||
fp << "\t";
|
||||
fp << "force ";
|
||||
fp << generate_verilog_port_constant_values(output_port, const_values);
|
||||
fp << ";" << std::endl;
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
* Generate a wire connection for two Verilog ports
|
||||
|
|
|
@ -92,6 +92,10 @@ void print_verilog_deposit_wire_constant_values(std::fstream& fp,
|
|||
const BasicPort& output_port,
|
||||
const std::vector<size_t>& const_values);
|
||||
|
||||
void print_verilog_force_wire_constant_values(std::fstream& fp,
|
||||
const BasicPort& output_port,
|
||||
const std::vector<size_t>& const_values);
|
||||
|
||||
void print_verilog_wire_connection(std::fstream& fp,
|
||||
const BasicPort& output_port,
|
||||
const BasicPort& input_port,
|
||||
|
|
Loading…
Reference in New Issue