LUTRAM Support (#1595)

* BRAM preload data - generic way to extract data from design

* Add docs and support special __layout__ case

* Add test

* Fix warning

* Change none-fabric to non-fabric

* LUTRAM Support Phase 1

* Add Test

* Add more protocol checking to enable LUTRAM feature

* Move the config setting under config protocol

* Revert any changes

---------

Co-authored-by: chungshien-chai <chungshien.chai@gmail.com>
This commit is contained in:
chungshien 2024-04-19 14:46:38 -07:00 committed by GitHub
parent e2673f10af
commit dd577e37e0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
19 changed files with 462 additions and 25 deletions

View File

@ -7,6 +7,17 @@ Configuration protocol is the circuitry designed to program an FPGA.
As an interface, configuration protocol could be really different in FPGAs, depending on the application context.
OpenFPGA supports versatile configuration protocol, providing different trade-offs between speed and area.
Under configuration protocol, if the configuration is QL Memory Bank with flatten BL/WL protocol, there might be
optional configuration setting call <ql_memory_bank_config_setting>.
In QL Memory Bank configuration protocol, configuration bits are organized as BitLine (BL) x WordLine (WL)
By default, OpenFPGA will keep BL and WL in square shape if possible where BL might be one bit longer than WL in some cases
For example:
- If the configuration bits of a PB is 9 bits, then BL=3 and WL=3
- If the configuration bits of a PB is 11 bits, then BL=4 and WL=3 (where there is one extra bit as phantom bit)
- If the configuration bits of a PB is 14 bits, then BL=4 and WL=4 (where there is two extra bits as phantom bits)
This QL Memory Bank configuration setting allow OpenFPGA to use a fixed WL size, instead of default approach
Template
~~~~~~~~
@ -14,6 +25,9 @@ Template
<configuration_protocol>
<organization type="<string>" circuit_model_name="<string>" num_regions="<int>"/>
<ql_memory_bank_config_setting>
<pb_type name="<string>" num_wl="<int>"/>
</ql_memory_bank_config_setting>
</configuration_protocol>
.. option:: type="scan_chain|memory_bank|standalone|frame_based|ql_memory_bank"
@ -54,6 +68,29 @@ Template
.. note:: For ``ql_memory_bank`` configuration protocol when BL/WL protocol ``shift_register`` is selected, different configuration regions **cannot** share any WLs on the same row! In such case, the default fabric key may not work. Strongly recommend to craft your own fabric key based on your configuration region plannning!
.. option:: name="<string>"
Specify the name of PB type, for example: clb, dsp, bram and etc
.. option:: num_wl="<int>"
Fix the size of WL
For example:
Considered that the configuration bits of a PB is 400 bits.
If num_wl is not defined, then
- BL will be 20 [=ceiling(square_root(400))]
- WL will be 20 [=ceiling(400/20)]
If num_wl is defined as 10, then
- WL will be fixed as 10
- BL will be 40 [=ceiling(400/10)]
If num_wl is defined as 32, then
- WL will be fixed as 32
- BL will be 13 [=ceiling(400/32)]
- There will be 16 bits [=(32x13)-400] as phantom bits.
Configuration Chain Example
~~~~~~~~~~~~~~~~~~~~~~~~~~~

View File

@ -116,6 +116,11 @@ CircuitModelId ConfigProtocol::wl_memory_model() const {
size_t ConfigProtocol::wl_num_banks() const { return wl_num_banks_; }
const QLMemoryBankConfigSetting* ConfigProtocol::ql_memory_bank_config_setting()
const {
return &ql_memory_bank_config_setting_;
}
/************************************************************************
* Public Mutators
***********************************************************************/
@ -256,6 +261,10 @@ void ConfigProtocol::set_wl_num_banks(const size_t& num_banks) {
wl_num_banks_ = num_banks;
}
QLMemoryBankConfigSetting* ConfigProtocol::get_ql_memory_bank_config_setting() {
return &ql_memory_bank_config_setting_;
}
/************************************************************************
* Private Validators
***********************************************************************/

View File

@ -7,6 +7,7 @@
#include "circuit_library_fwd.h"
#include "circuit_types.h"
#include "openfpga_port.h"
#include "ql_memory_bank_config_setting.h"
/* Data type to define the protocol through which BL/WL can be manipulated */
enum e_blwl_protocol_type {
@ -54,6 +55,9 @@ class ConfigProtocol {
CircuitModelId wl_memory_model() const;
size_t wl_num_banks() const;
/* QL Memory Bank Config Setting */
const QLMemoryBankConfigSetting* ql_memory_bank_config_setting() const;
public: /* Public Mutators */
void set_type(const e_config_protocol_type& type);
void set_memory_model_name(const std::string& memory_model_name);
@ -76,6 +80,9 @@ class ConfigProtocol {
void set_wl_memory_model(const CircuitModelId& memory_model);
void set_wl_num_banks(const size_t& num_banks);
/* QL Memory Bank Config Setting */
QLMemoryBankConfigSetting* get_ql_memory_bank_config_setting();
public: /* Public validators */
/* Check if internal data has any conflicts to each other. Return number of
* errors detected */
@ -131,6 +138,9 @@ class ConfigProtocol {
std::string wl_memory_model_name_;
CircuitModelId wl_memory_model_;
size_t wl_num_banks_;
/* QL Memory Bank Config Setting */
QLMemoryBankConfigSetting ql_memory_bank_config_setting_;
};
#endif

View File

@ -0,0 +1,34 @@
#include "ql_memory_bank_config_setting.h"
#include "openfpga_tokenizer.h"
#include "vtr_assert.h"
#include "vtr_log.h"
/************************************************************************
* Member functions for class QLMemoryBankConfigSetting
***********************************************************************/
/************************************************************************
* Constructors
***********************************************************************/
QLMemoryBankConfigSetting::QLMemoryBankConfigSetting() {}
/************************************************************************
* Public Accessors
***********************************************************************/
QLMemoryBankPBSetting QLMemoryBankConfigSetting::pb_setting(
const std::string& name) const {
if (settings_.find(name) != settings_.end()) {
return settings_.at(name);
}
return QLMemoryBankPBSetting();
}
/************************************************************************
* Public Mutators
***********************************************************************/
void QLMemoryBankConfigSetting::add_pb_setting(const std::string& name,
uint32_t num_wl) {
VTR_ASSERT(settings_.find(name) == settings_.end());
settings_[name] = QLMemoryBankPBSetting(num_wl);
}

View File

@ -0,0 +1,29 @@
#ifndef QL_MEMORY_BANK_CONFIG_SETTING_H
#define QL_MEMORY_BANK_CONFIG_SETTING_H
#include <map>
#include <string>
struct QLMemoryBankPBSetting {
QLMemoryBankPBSetting(uint32_t n = 0) : num_wl(n) {}
uint32_t num_wl = 0;
};
/********************************************************************
* A data structure to store QL Memory Bank configuration setting
*******************************************************************/
class QLMemoryBankConfigSetting {
public: /* Constructors */
QLMemoryBankConfigSetting();
public: /* Public Accessors */
QLMemoryBankPBSetting pb_setting(const std::string& name) const;
public: /* Public Mutators */
void add_pb_setting(const std::string& name, uint32_t num_wl);
private: /* Internal data */
std::map<std::string, QLMemoryBankPBSetting> settings_;
};
#endif

View File

@ -249,6 +249,32 @@ static void read_xml_config_organization(pugi::xml_node& xml_config_orgz,
}
}
/********************************************************************
* Parse XML codes about <ql_memory_bank_config_setting> to
*QLMemoryBankConfigSetting
*******************************************************************/
static void read_xml_ql_memory_bank_config_setting(
QLMemoryBankConfigSetting* setting, pugi::xml_node& Node,
const pugiutil::loc_data& loc_data) {
/* Parse configuration protocol root node */
pugi::xml_node config_setting =
get_single_child(Node, "ql_memory_bank_config_setting", loc_data,
pugiutil::ReqOpt::OPTIONAL);
if (config_setting) {
/* Add to ql_memory_bank_config_setting_ */
for (pugi::xml_node xml_child : config_setting.children()) {
if (xml_child.name() != std::string("pb_type")) {
bad_tag(xml_child, loc_data, config_setting, {"pb_type"});
}
const std::string& name_attr =
get_attribute(xml_child, "name", loc_data).as_string();
uint32_t num_wl = get_attribute(xml_child, "num_wl", loc_data).as_uint();
setting->add_pb_setting(name_attr, num_wl);
}
}
}
/********************************************************************
* Parse XML codes about <configuration_protocol> to an object of ConfigProtocol
*******************************************************************/
@ -264,5 +290,14 @@ ConfigProtocol read_xml_config_protocol(pugi::xml_node& Node,
get_single_child(xml_config, "organization", loc_data);
read_xml_config_organization(xml_config_orgz, loc_data, config_protocol);
/* Parse QL Memory Bank configuration setting */
if (config_protocol.type() == CONFIG_MEM_QL_MEMORY_BANK &&
config_protocol.bl_protocol_type() == BLWL_PROTOCOL_FLATTEN &&
config_protocol.wl_protocol_type() == BLWL_PROTOCOL_FLATTEN) {
read_xml_ql_memory_bank_config_setting(
config_protocol.get_ql_memory_bank_config_setting(), xml_config,
loc_data);
}
return config_protocol;
}

View File

@ -88,8 +88,9 @@ int build_device_module_graph(
module_manager, decoder_lib, vpr_device_ctx,
openfpga_ctx.vpr_device_annotation(), openfpga_ctx.arch().circuit_lib,
openfpga_ctx.mux_lib(), openfpga_ctx.arch().tile_annotations,
openfpga_ctx.arch().config_protocol.type(), sram_model, duplicate_grid_pin,
group_config_block, verbose);
openfpga_ctx.arch().config_protocol.type(), sram_model,
openfpga_ctx.arch().config_protocol.ql_memory_bank_config_setting(),
duplicate_grid_pin, group_config_block, verbose);
if (CMD_EXEC_FATAL_ERROR == status) {
return status;
}

View File

@ -1166,6 +1166,7 @@ static int build_physical_tile_module(
const e_config_protocol_type& sram_orgz_type,
const CircuitModelId& sram_model, t_physical_tile_type_ptr phy_block_type,
const TileAnnotation& tile_annotation, const e_side& border_side,
const QLMemoryBankConfigSetting* ql_memory_bank_config_setting,
const bool& duplicate_grid_pin, const bool& group_config_block,
const bool& verbose) {
int status = CMD_EXEC_SUCCESS;
@ -1334,9 +1335,10 @@ static int build_physical_tile_module(
module_manager, grid_module, circuit_lib, sram_model, sram_orgz_type,
config_child_type);
if (0 < module_num_config_bits) {
add_pb_sram_ports_to_module_manager(module_manager, grid_module,
circuit_lib, sram_model, sram_orgz_type,
module_num_config_bits);
add_pb_sram_ports_to_module_manager(
module_manager, grid_module, circuit_lib, sram_model, sram_orgz_type,
module_num_config_bits,
ql_memory_bank_config_setting->pb_setting(phy_block_type->name).num_wl);
}
/* Add module nets to connect memory cells inside
@ -1374,8 +1376,10 @@ int build_grid_modules(
const CircuitLibrary& circuit_lib, const MuxLibrary& mux_lib,
const TileAnnotation& tile_annotation,
const e_config_protocol_type& sram_orgz_type,
const CircuitModelId& sram_model, const bool& duplicate_grid_pin,
const bool& group_config_block, const bool& verbose) {
const CircuitModelId& sram_model,
const QLMemoryBankConfigSetting* ql_memory_bank_config_setting,
const bool& duplicate_grid_pin, const bool& group_config_block,
const bool& verbose) {
/* Start time count */
vtr::ScopedStartFinishTimer timer("Build grid modules");
@ -1431,7 +1435,8 @@ int build_grid_modules(
status = build_physical_tile_module(
module_manager, decoder_lib, device_annotation, circuit_lib,
sram_orgz_type, sram_model, &physical_tile, tile_annotation,
io_type_side, duplicate_grid_pin, group_config_block, verbose);
io_type_side, ql_memory_bank_config_setting, duplicate_grid_pin,
group_config_block, verbose);
if (status != CMD_EXEC_SUCCESS) {
return CMD_EXEC_FATAL_ERROR;
}
@ -1441,7 +1446,8 @@ int build_grid_modules(
status = build_physical_tile_module(
module_manager, decoder_lib, device_annotation, circuit_lib,
sram_orgz_type, sram_model, &physical_tile, tile_annotation, NUM_SIDES,
duplicate_grid_pin, group_config_block, verbose);
ql_memory_bank_config_setting, duplicate_grid_pin, group_config_block,
verbose);
if (status != CMD_EXEC_SUCCESS) {
return CMD_EXEC_FATAL_ERROR;
}

View File

@ -7,6 +7,7 @@
#include "decoder_library.h"
#include "module_manager.h"
#include "mux_library.h"
#include "ql_memory_bank_config_setting.h"
#include "tile_annotation.h"
#include "vpr_context.h"
#include "vpr_device_annotation.h"
@ -24,8 +25,10 @@ int build_grid_modules(
const CircuitLibrary& circuit_lib, const MuxLibrary& mux_lib,
const TileAnnotation& tile_annotation,
const e_config_protocol_type& sram_orgz_type,
const CircuitModelId& sram_model, const bool& duplicate_grid_pin,
const bool& group_config_block, const bool& verbose);
const CircuitModelId& sram_model,
const QLMemoryBankConfigSetting* ql_memory_bank_config_setting,
const bool& duplicate_grid_pin, const bool& group_config_block,
const bool& verbose);
} /* end namespace openfpga */

View File

@ -1110,14 +1110,14 @@ static void add_top_module_nets_cmos_memory_bank_config_bus(
/* Each memory bank has a unified number of BL/WLs */
size_t num_bls = 0;
for (const auto& curr_config_bits : num_config_bits) {
num_bls =
std::max(num_bls, find_memory_decoder_data_size(curr_config_bits.first));
num_bls = std::max(
num_bls, find_memory_decoder_data_size(curr_config_bits.first, 0, true));
}
size_t num_wls = 0;
for (const auto& curr_config_bits : num_config_bits) {
num_wls =
std::max(num_wls, find_memory_decoder_data_size(curr_config_bits.first));
num_wls = std::max(
num_wls, find_memory_decoder_data_size(curr_config_bits.first, 0, false));
}
/* Create separated memory bank circuitry, i.e., BL/WL decoders for each

View File

@ -77,7 +77,7 @@ size_t find_mux_local_decoder_addr_size(const size_t& data_size) {
***************************************************************************************/
size_t find_memory_decoder_addr_size(const size_t& num_mems) {
return find_mux_local_decoder_addr_size(
find_memory_decoder_data_size(num_mems));
find_memory_decoder_data_size(num_mems, 0, false));
}
/***************************************************************************************
@ -86,8 +86,18 @@ size_t find_memory_decoder_addr_size(const size_t& num_mems) {
*lines and word lines, the number of data lines will be a square root of the
*number of memory cells.
***************************************************************************************/
size_t find_memory_decoder_data_size(const size_t& num_mems) {
return (size_t)std::ceil(std::sqrt((float)num_mems));
size_t find_memory_decoder_data_size(const size_t& num_mems,
const size_t& defined_num_wl,
const bool is_bl) {
if (defined_num_wl == 0) {
return (size_t)std::ceil(std::sqrt((float)num_mems));
} else {
if (is_bl) {
return find_memory_wl_decoder_data_size(num_mems, defined_num_wl);
} else {
return defined_num_wl;
}
}
}
/***************************************************************************************

View File

@ -15,7 +15,9 @@ size_t find_mux_local_decoder_addr_size(const size_t& data_size);
size_t find_memory_decoder_addr_size(const size_t& num_mems);
size_t find_memory_decoder_data_size(const size_t& num_mems);
size_t find_memory_decoder_data_size(const size_t& num_mems,
const size_t& defined_num_wl,
const bool is_bl);
size_t find_memory_wl_decoder_data_size(const size_t& num_mems,
const size_t& num_bls);

View File

@ -436,7 +436,8 @@ size_t generate_sram_port_size(const e_config_protocol_type sram_orgz_type,
* - QL Memory decoders: Apply square root as BL/WLs will be grouped
********************************************************************/
size_t generate_pb_sram_port_size(const e_config_protocol_type sram_orgz_type,
const size_t& num_config_bits) {
const size_t& num_config_bits,
const size_t& defined_num_wl) {
size_t sram_port_size = num_config_bits;
switch (sram_orgz_type) {
@ -447,7 +448,8 @@ size_t generate_pb_sram_port_size(const e_config_protocol_type sram_orgz_type,
sram_port_size = 1;
break;
case CONFIG_MEM_QL_MEMORY_BANK:
sram_port_size = find_memory_decoder_data_size(num_config_bits);
sram_port_size =
find_memory_decoder_data_size(num_config_bits, defined_num_wl, true);
break;
case CONFIG_MEM_MEMORY_BANK:
break;

View File

@ -42,7 +42,8 @@ size_t generate_sram_port_size(const e_config_protocol_type sram_orgz_type,
const size_t& num_config_bits);
size_t generate_pb_sram_port_size(const e_config_protocol_type sram_orgz_type,
const size_t& num_config_bits);
const size_t& num_config_bits,
const size_t& defined_num_wl);
/**
* @brief Compute the number of configurable children to be skipped for a given

View File

@ -419,11 +419,16 @@ void add_sram_ports_to_module_manager(
void add_pb_sram_ports_to_module_manager(
ModuleManager& module_manager, const ModuleId& module_id,
const CircuitLibrary& circuit_lib, const CircuitModelId& sram_model,
const e_config_protocol_type sram_orgz_type, const size_t& num_config_bits) {
const e_config_protocol_type sram_orgz_type, const size_t& num_config_bits,
const uint32_t defined_num_wl) {
if (defined_num_wl) {
// Only support defined_num_wl if the configuration mode is QL Memory Bank
VTR_ASSERT(sram_orgz_type == CONFIG_MEM_QL_MEMORY_BANK);
}
std::vector<std::string> sram_port_names =
generate_sram_port_names(circuit_lib, sram_model, sram_orgz_type);
size_t sram_port_size =
generate_pb_sram_port_size(sram_orgz_type, num_config_bits);
generate_pb_sram_port_size(sram_orgz_type, num_config_bits, defined_num_wl);
/* Add ports to the module manager */
switch (sram_orgz_type) {

View File

@ -74,7 +74,8 @@ void add_sram_ports_to_module_manager(
void add_pb_sram_ports_to_module_manager(
ModuleManager& module_manager, const ModuleId& module_id,
const CircuitLibrary& circuit_lib, const CircuitModelId& sram_model,
const e_config_protocol_type sram_orgz_type, const size_t& num_config_bits);
const e_config_protocol_type sram_orgz_type, const size_t& num_config_bits,
const uint32_t defined_num_wl = 0);
void add_primitive_pb_type_ports_to_module_manager(
ModuleManager& module_manager, const ModuleId& module_id,

View File

@ -0,0 +1,206 @@
<?xml version="1.0"?>
<!-- Architecture annotation for OpenFPGA framework
This annotation supports the k6_N10_40nm.xml
- General purpose logic block
- K = 6, N = 10, I = 40
- Single mode
- Routing architecture
- L = 4, fc_in = 0.15, fc_out = 0.1
-->
<openfpga_architecture>
<technology_library>
<device_library>
<device_model name="logic" type="transistor">
<lib type="industry" corner="TOP_TT" ref="M" path="${OPENFPGA_PATH}/openfpga_flow/tech/PTM_45nm/45nm.pm"/>
<design vdd="0.9" pn_ratio="2"/>
<pmos name="pch" chan_length="40e-9" min_width="140e-9" variation="logic_transistor_var"/>
<nmos name="nch" chan_length="40e-9" min_width="140e-9" variation="logic_transistor_var"/>
</device_model>
<device_model name="io" type="transistor">
<lib type="academia" ref="M" path="${OPENFPGA_PATH}/openfpga_flow/tech/PTM_45nm/45nm.pm"/>
<design vdd="2.5" pn_ratio="3"/>
<pmos name="pch_25" chan_length="270e-9" min_width="320e-9" variation="io_transistor_var"/>
<nmos name="nch_25" chan_length="270e-9" min_width="320e-9" variation="io_transistor_var"/>
</device_model>
</device_library>
<variation_library>
<variation name="logic_transistor_var" abs_deviation="0.1" num_sigma="3"/>
<variation name="io_transistor_var" abs_deviation="0.1" num_sigma="3"/>
</variation_library>
</technology_library>
<circuit_library>
<circuit_model type="inv_buf" name="INVTX1" prefix="INVTX1" is_default="true">
<design_technology type="cmos" topology="inverter" size="1"/>
<device_technology device_model_name="logic"/>
<port type="input" prefix="in" size="1"/>
<port type="output" prefix="out" size="1"/>
<delay_matrix type="rise" in_port="in" out_port="out">
10e-12
</delay_matrix>
<delay_matrix type="fall" in_port="in" out_port="out">
10e-12
</delay_matrix>
</circuit_model>
<circuit_model type="inv_buf" name="buf4" prefix="buf4" is_default="false">
<design_technology type="cmos" topology="buffer" size="1" num_level="2" f_per_stage="4"/>
<device_technology device_model_name="logic"/>
<port type="input" prefix="in" size="1"/>
<port type="output" prefix="out" size="1"/>
<delay_matrix type="rise" in_port="in" out_port="out">
10e-12
</delay_matrix>
<delay_matrix type="fall" in_port="in" out_port="out">
10e-12
</delay_matrix>
</circuit_model>
<circuit_model type="inv_buf" name="tap_buf4" prefix="tap_buf4" is_default="false">
<design_technology type="cmos" topology="buffer" size="1" num_level="3" f_per_stage="4"/>
<device_technology device_model_name="logic"/>
<port type="input" prefix="in" size="1"/>
<port type="output" prefix="out" size="1"/>
<delay_matrix type="rise" in_port="in" out_port="out">
10e-12
</delay_matrix>
<delay_matrix type="fall" in_port="in" out_port="out">
10e-12
</delay_matrix>
</circuit_model>
<circuit_model type="pass_gate" name="TGATE" prefix="TGATE" is_default="true">
<design_technology type="cmos" topology="transmission_gate" nmos_size="1" pmos_size="2"/>
<device_technology device_model_name="logic"/>
<input_buffer exist="false"/>
<output_buffer exist="false"/>
<port type="input" prefix="in" size="1"/>
<port type="input" prefix="sel" size="1"/>
<port type="input" prefix="selb" size="1"/>
<port type="output" prefix="out" size="1"/>
<delay_matrix type="rise" in_port="in sel selb" out_port="out">
10e-12 5e-12 5e-12
</delay_matrix>
<delay_matrix type="fall" in_port="in sel selb" out_port="out">
10e-12 5e-12 5e-12
</delay_matrix>
</circuit_model>
<circuit_model type="chan_wire" name="chan_segment" prefix="track_seg" is_default="true">
<design_technology type="cmos"/>
<input_buffer exist="false"/>
<output_buffer exist="false"/>
<port type="input" prefix="in" size="1"/>
<port type="output" prefix="out" size="1"/>
<wire_param model_type="pi" R="101" C="22.5e-15" num_level="1"/>
<!-- model_type could be T, res_val and cap_val DON'T CARE -->
</circuit_model>
<circuit_model type="wire" name="direct_interc" prefix="direct_interc" is_default="true">
<design_technology type="cmos"/>
<input_buffer exist="false"/>
<output_buffer exist="false"/>
<port type="input" prefix="in" size="1"/>
<port type="output" prefix="out" size="1"/>
<wire_param model_type="pi" R="0" C="0" num_level="1"/>
<!-- model_type could be T, res_val cap_val should be defined -->
</circuit_model>
<circuit_model type="mux" name="mux_2level" prefix="mux_2level" dump_structural_verilog="true">
<design_technology type="cmos" structure="multi_level" num_level="2" add_const_input="true" const_input_val="1"/>
<input_buffer exist="true" circuit_model_name="INVTX1"/>
<output_buffer exist="true" circuit_model_name="INVTX1"/>
<pass_gate_logic circuit_model_name="TGATE"/>
<port type="input" prefix="in" size="1"/>
<port type="output" prefix="out" size="1"/>
<port type="sram" prefix="sram" size="1"/>
</circuit_model>
<circuit_model type="mux" name="mux_2level_tapbuf" prefix="mux_2level_tapbuf" dump_structural_verilog="true">
<design_technology type="cmos" structure="multi_level" num_level="2" add_const_input="true" const_input_val="1"/>
<input_buffer exist="true" circuit_model_name="INVTX1"/>
<output_buffer exist="true" circuit_model_name="tap_buf4"/>
<pass_gate_logic circuit_model_name="TGATE"/>
<port type="input" prefix="in" size="1"/>
<port type="output" prefix="out" size="1"/>
<port type="sram" prefix="sram" size="1"/>
</circuit_model>
<circuit_model type="mux" name="mux_1level_tapbuf" prefix="mux_1level_tapbuf" is_default="true" dump_structural_verilog="true">
<design_technology type="cmos" structure="one_level" add_const_input="true" const_input_val="1"/>
<input_buffer exist="true" circuit_model_name="INVTX1"/>
<output_buffer exist="true" circuit_model_name="tap_buf4"/>
<pass_gate_logic circuit_model_name="TGATE"/>
<port type="input" prefix="in" size="1"/>
<port type="output" prefix="out" size="1"/>
<port type="sram" prefix="sram" size="1"/>
</circuit_model>
<!--DFF subckt ports should be defined as <D> <Q> <CLK> <RESET> <SET> -->
<circuit_model type="ff" name="DFFSRQ" prefix="DFFSRQ" spice_netlist="${OPENFPGA_PATH}/openfpga_flow/openfpga_cell_library/spice/dff.sp" verilog_netlist="${OPENFPGA_PATH}/openfpga_flow/openfpga_cell_library/verilog/dff.v">
<design_technology type="cmos"/>
<input_buffer exist="true" circuit_model_name="INVTX1"/>
<output_buffer exist="true" circuit_model_name="INVTX1"/>
<port type="input" prefix="D" lib_name="D" size="1"/>
<port type="input" prefix="set" lib_name="SET" size="1" is_global="true" default_val="0" is_set="true"/>
<port type="input" prefix="reset" lib_name="RST" size="1" is_global="true" default_val="0" is_reset="true"/>
<port type="output" prefix="Q" lib_name="Q" size="1"/>
<port type="clock" prefix="clk" lib_name="CK" size="1" is_global="true" default_val="0"/>
</circuit_model>
<circuit_model type="lut" name="lut4" prefix="lut4" dump_structural_verilog="true">
<design_technology type="cmos"/>
<input_buffer exist="true" circuit_model_name="INVTX1"/>
<output_buffer exist="true" circuit_model_name="INVTX1"/>
<lut_input_inverter exist="true" circuit_model_name="INVTX1"/>
<lut_input_buffer exist="true" circuit_model_name="buf4"/>
<pass_gate_logic circuit_model_name="TGATE"/>
<port type="input" prefix="in" size="4"/>
<port type="output" prefix="out" size="1"/>
<port type="sram" prefix="sram" size="16"/>
</circuit_model>
<!--Scan-chain DFF subckt ports should be defined as <D> <Q> <Qb> <CLK> <RESET> <SET> -->
<circuit_model type="sram" name="SRAM" prefix="SRAM" spice_netlist="${OPENFPGA_PATH}/openfpga_flow/openfpga_cell_library/spice/sram.sp" verilog_netlist="${OPENFPGA_PATH}/openfpga_flow/openfpga_cell_library/verilog/sram.v">
<design_technology type="cmos"/>
<input_buffer exist="true" circuit_model_name="INVTX1"/>
<output_buffer exist="true" circuit_model_name="INVTX1"/>
<port type="bl" prefix="bl" lib_name="D" size="1"/>
<port type="wl" prefix="wl" lib_name="WE" size="1"/>
<port type="output" prefix="out" lib_name="Q" size="1"/>
<port type="output" prefix="outb" lib_name="QN" size="1"/>
</circuit_model>
<circuit_model type="iopad" name="GPIO" prefix="GPIO" spice_netlist="${OPENFPGA_PATH}/openfpga_flow/openfpga_cell_library/spice/gpio.sp" verilog_netlist="${OPENFPGA_PATH}/openfpga_flow/openfpga_cell_library/verilog/gpio.v">
<design_technology type="cmos"/>
<input_buffer exist="true" circuit_model_name="INVTX1"/>
<output_buffer exist="true" circuit_model_name="INVTX1"/>
<port type="inout" prefix="PAD" size="1" is_global="true" is_io="true" is_data_io="true"/>
<port type="sram" prefix="DIR" size="1" mode_select="true" circuit_model_name="SRAM" default_val="1"/>
<port type="input" prefix="outpad" lib_name="A" size="1"/>
<port type="output" prefix="inpad" lib_name="Y" size="1"/>
</circuit_model>
</circuit_library>
<configuration_protocol>
<organization type="ql_memory_bank" circuit_model_name="SRAM">
<bl protocol="flatten"/>
<wl protocol="flatten"/>
</organization>
<ql_memory_bank_config_setting>
<pb_type name="clb" num_wl="32"/>
</ql_memory_bank_config_setting>
</configuration_protocol>
<connection_block>
<switch name="ipin_cblock" circuit_model_name="mux_2level_tapbuf"/>
</connection_block>
<switch_block>
<switch name="0" circuit_model_name="mux_2level_tapbuf"/>
</switch_block>
<routing_segment>
<segment name="L4" circuit_model_name="chan_segment"/>
</routing_segment>
<pb_type_annotations>
<!-- physical pb_type binding in complex block IO -->
<pb_type name="io" physical_mode_name="physical" idle_mode_name="inpad"/>
<pb_type name="io[physical].iopad" circuit_model_name="GPIO" mode_bits="1"/>
<pb_type name="io[inpad].inpad" physical_pb_type_name="io[physical].iopad" mode_bits="1"/>
<pb_type name="io[outpad].outpad" physical_pb_type_name="io[physical].iopad" mode_bits="0"/>
<!-- End physical pb_type binding in complex block IO -->
<!-- physical pb_type binding in complex block CLB -->
<!-- physical mode will be the default mode if not specified -->
<pb_type name="clb">
<!-- Binding interconnect to circuit models as their physical implementation, if not defined, we use the default model -->
<interconnect name="crossbar" circuit_model_name="mux_2level"/>
</pb_type>
<pb_type name="clb.fle[n1_lut4].ble4.lut4" circuit_model_name="lut4"/>
<pb_type name="clb.fle[n1_lut4].ble4.ff" circuit_model_name="DFFSRQ"/>
<!-- End physical pb_type binding in complex block IO -->
</pb_type_annotations>
</openfpga_architecture>

View File

@ -78,6 +78,7 @@ run-task basic_tests/full_testbench/ql_memory_bank $@
run-task basic_tests/full_testbench/ql_memory_bank_use_wlr $@
run-task basic_tests/full_testbench/multi_region_ql_memory_bank $@
run-task basic_tests/full_testbench/ql_memory_bank_flatten $@
run-task basic_tests/full_testbench/ql_memory_bank_flatten_defined_wl $@
run-task basic_tests/full_testbench/ql_memory_bank_flatten_use_wlr $@
run-task basic_tests/full_testbench/ql_memory_bank_shift_register $@
run-task basic_tests/full_testbench/ql_memory_bank_shift_register_use_wlr $@

View File

@ -0,0 +1,45 @@
# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
# Configuration file for running experiments
# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
# timeout_each_job : FPGA Task script splits fpga flow into multiple jobs
# Each job execute fpga_flow script on combination of architecture & benchmark
# timeout_each_job is timeout for each job
# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
[GENERAL]
run_engine=openfpga_shell
power_tech_file = ${PATH:OPENFPGA_PATH}/openfpga_flow/tech/PTM_45nm/45nm.xml
power_analysis = true
spice_output=false
verilog_output=true
timeout_each_job = 20*60
fpga_flow=yosys_vpr
[OpenFPGA_SHELL]
openfpga_shell_template=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_shell_scripts/write_full_testbench_example_script.openfpga
openfpga_arch_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_arch/k4_N4_40nm_qlbankflatten_defined_wl_openfpga.xml
openfpga_sim_setting_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_simulation_settings/auto_sim_openfpga.xml
openfpga_vpr_device_layout=
openfpga_fast_configuration=
[ARCHITECTURES]
arch0=${PATH:OPENFPGA_PATH}/openfpga_flow/vpr_arch/k4_N4_tileable_40nm.xml
[BENCHMARKS]
bench0=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and2/and2.v
bench1=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/or2/or2.v
bench2=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and2_latch/and2_latch.v
[SYNTHESIS_PARAM]
bench_read_verilog_options_common = -nolatches
bench0_top = and2
bench0_chan_width = 300
bench1_top = or2
bench1_chan_width = 300
bench2_top = and2_latch
bench2_chan_width = 300
[SCRIPT_PARAM_MIN_ROUTE_CHAN_WIDTH]
end_flow_with_test=