add local encoder support in bitstream generation refactoring
This commit is contained in:
parent
97193794c4
commit
c38513c838
|
@ -192,6 +192,14 @@ size_t MuxGraph::num_memory_bits_at_level(const size_t& level) const {
|
|||
return mem_lookup_[level].size();
|
||||
}
|
||||
|
||||
/* Return memory id at level */
|
||||
std::vector<MuxMemId> MuxGraph::memories_at_level(const size_t& level) const {
|
||||
/* need to check if the graph is valid or not */
|
||||
VTR_ASSERT_SAFE(valid_level(level));
|
||||
VTR_ASSERT_SAFE(valid_mux_graph());
|
||||
return mem_lookup_[level];
|
||||
}
|
||||
|
||||
/* Find the number of nodes at a given level in the MUX graph */
|
||||
size_t MuxGraph::num_nodes_at_level(const size_t& level) const {
|
||||
/* validate the level numbers */
|
||||
|
@ -533,10 +541,10 @@ MuxNodeId MuxGraph::node_id(const size_t& node_level, const size_t& node_index_a
|
|||
}
|
||||
|
||||
/* Decode memory bits based on an input id and an output id */
|
||||
std::vector<bool> MuxGraph::decode_memory_bits(const MuxInputId& input_id,
|
||||
const MuxOutputId& output_id) const {
|
||||
vtr::vector<MuxMemId, bool> MuxGraph::decode_memory_bits(const MuxInputId& input_id,
|
||||
const MuxOutputId& output_id) const {
|
||||
/* initialize the memory bits: TODO: support default value */
|
||||
std::vector<bool> mem_bits(mem_ids_.size(), false);
|
||||
vtr::vector<MuxMemId, bool> mem_bits(mem_ids_.size(), false);
|
||||
|
||||
/* valid the input and output */
|
||||
VTR_ASSERT_SAFE(valid_input_id(input_id));
|
||||
|
@ -575,9 +583,9 @@ std::vector<bool> MuxGraph::decode_memory_bits(const MuxInputId& input_id,
|
|||
MuxMemId mem = edge_mem_ids_[edge];
|
||||
VTR_ASSERT_SAFE (valid_mem_id(mem));
|
||||
if (true == edge_inv_mem_[edge]) {
|
||||
mem_bits[size_t(mem)] = false;
|
||||
mem_bits[mem] = false;
|
||||
} else {
|
||||
mem_bits[size_t(mem)] = true;
|
||||
mem_bits[mem] = true;
|
||||
}
|
||||
|
||||
/* each edge must have 1 fan-out */
|
||||
|
|
|
@ -83,6 +83,8 @@ class MuxGraph {
|
|||
size_t num_memory_bits() const;
|
||||
/* Find the number of SRAMs at a level in the MUX graph */
|
||||
size_t num_memory_bits_at_level(const size_t& level) const;
|
||||
/* Return memory id at level */
|
||||
std::vector<MuxMemId> memories_at_level(const size_t& level) const;
|
||||
/* Find the number of nodes at a given level in the MUX graph */
|
||||
size_t num_nodes_at_level(const size_t& level) const;
|
||||
/* Find the level of a node */
|
||||
|
@ -122,8 +124,8 @@ class MuxGraph {
|
|||
* This function will start from the input node
|
||||
* and do a forward propagation until reaching the output node
|
||||
*/
|
||||
std::vector<bool> decode_memory_bits(const MuxInputId& input_id,
|
||||
const MuxOutputId& output_id) const;
|
||||
vtr::vector<MuxMemId, bool> decode_memory_bits(const MuxInputId& input_id,
|
||||
const MuxOutputId& output_id) const;
|
||||
/* Find the input node that the memory bits will route an output node to
|
||||
* This function backward propagate from the output node to an input node
|
||||
* assuming the memory bits are applied
|
||||
|
|
|
@ -3,9 +3,12 @@
|
|||
* which are based on different technology
|
||||
*******************************************************************/
|
||||
#include "vtr_assert.h"
|
||||
#include "vtr_vector.h"
|
||||
|
||||
#include "mux_utils.h"
|
||||
#include "decoder_library_utils.h"
|
||||
#include "fpga_x2p_types.h"
|
||||
#include "fpga_x2p_utils.h"
|
||||
|
||||
#include "build_mux_bitstream.h"
|
||||
|
||||
|
@ -74,7 +77,53 @@ std::vector<bool> build_cmos_mux_bitstream(const CircuitLibrary& circuit_lib,
|
|||
VTR_ASSERT(1 == mux_graph.outputs().size());
|
||||
|
||||
/* Generate the memory bits */
|
||||
return mux_graph.decode_memory_bits(MuxInputId(datapath_id), mux_graph.output_id(mux_graph.outputs()[0]));
|
||||
vtr::vector<MuxMemId, bool> raw_bitstream = mux_graph.decode_memory_bits(MuxInputId(datapath_id), mux_graph.output_id(mux_graph.outputs()[0]));
|
||||
|
||||
std::vector<bool> mux_bitstream;
|
||||
for (const bool& bit : mux_bitstream) {
|
||||
mux_bitstream.push_back(bit);
|
||||
}
|
||||
|
||||
/* Consider local encoder support, we need further encode the bitstream */
|
||||
if (false == circuit_lib.mux_use_local_encoder(mux_model)) {
|
||||
return mux_bitstream;
|
||||
}
|
||||
|
||||
/* Clear the mux_bitstream, we need to apply encoding */
|
||||
mux_bitstream.clear();
|
||||
|
||||
/* Encode the memory bits level by level,
|
||||
* One local encoder is used for each level of multiplexers
|
||||
*/
|
||||
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
|
||||
*/
|
||||
std::vector<size_t> encoder_data;
|
||||
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]]) {
|
||||
encoder_data.push_back(mem_index);
|
||||
}
|
||||
}
|
||||
/* There should be at most one '1' */
|
||||
VTR_ASSERT( (0 == encoder_data.size()) || (1 == encoder_data.size()));
|
||||
/* Convert to encoded bits */
|
||||
std::vector<size_t> encoder_addr;
|
||||
if (0 == encoder_data.size()) {
|
||||
encoder_addr = my_itobin_vec(0, find_mux_local_decoder_addr_size(mux_graph.memories_at_level(level).size()));
|
||||
} else {
|
||||
VTR_ASSERT(1 == encoder_data.size());
|
||||
encoder_addr = my_itobin_vec(encoder_data[0], find_mux_local_decoder_addr_size(mux_graph.memories_at_level(level).size()));
|
||||
}
|
||||
/* Build final mux bitstream */
|
||||
for (const size_t& bit : encoder_addr) {
|
||||
mux_bitstream.push_back((bool)bit);
|
||||
}
|
||||
}
|
||||
|
||||
return mux_bitstream;
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
|
|
Loading…
Reference in New Issue