add local encoder support in bitstream generation refactoring

This commit is contained in:
tangxifan 2019-10-24 22:49:24 -06:00
parent 97193794c4
commit c38513c838
3 changed files with 67 additions and 8 deletions

View File

@ -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 */

View File

@ -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

View File

@ -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;
}
/********************************************************************