From c38513c838c1b1914a8c9600872dd7c624030adf Mon Sep 17 00:00:00 2001 From: tangxifan Date: Thu, 24 Oct 2019 22:49:24 -0600 Subject: [PATCH] add local encoder support in bitstream generation refactoring --- vpr7_x2p/vpr/SRC/device/mux_graph.cpp | 18 +++++-- vpr7_x2p/vpr/SRC/device/mux_graph.h | 6 ++- .../bitstream/build_mux_bitstream.cpp | 51 ++++++++++++++++++- 3 files changed, 67 insertions(+), 8 deletions(-) diff --git a/vpr7_x2p/vpr/SRC/device/mux_graph.cpp b/vpr7_x2p/vpr/SRC/device/mux_graph.cpp index 23230ae74..b54dcd0c2 100644 --- a/vpr7_x2p/vpr/SRC/device/mux_graph.cpp +++ b/vpr7_x2p/vpr/SRC/device/mux_graph.cpp @@ -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 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 MuxGraph::decode_memory_bits(const MuxInputId& input_id, - const MuxOutputId& output_id) const { +vtr::vector MuxGraph::decode_memory_bits(const MuxInputId& input_id, + const MuxOutputId& output_id) const { /* initialize the memory bits: TODO: support default value */ - std::vector mem_bits(mem_ids_.size(), false); + vtr::vector 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 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 */ diff --git a/vpr7_x2p/vpr/SRC/device/mux_graph.h b/vpr7_x2p/vpr/SRC/device/mux_graph.h index 18fc5464c..014e0a59b 100644 --- a/vpr7_x2p/vpr/SRC/device/mux_graph.h +++ b/vpr7_x2p/vpr/SRC/device/mux_graph.h @@ -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 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 decode_memory_bits(const MuxInputId& input_id, - const MuxOutputId& output_id) const; + vtr::vector 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 diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/bitstream/build_mux_bitstream.cpp b/vpr7_x2p/vpr/SRC/fpga_x2p/bitstream/build_mux_bitstream.cpp index b2dccc1eb..644fe730e 100644 --- a/vpr7_x2p/vpr/SRC/fpga_x2p/bitstream/build_mux_bitstream.cpp +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/bitstream/build_mux_bitstream.cpp @@ -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 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 raw_bitstream = mux_graph.decode_memory_bits(MuxInputId(datapath_id), mux_graph.output_id(mux_graph.outputs()[0])); + + std::vector 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 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 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; } /********************************************************************