ferrandi / PandA-bambu

PandA-bambu public repository

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Documentation on memory architecture

TheZoq2 opened this issue · comments

Hi. I'm still playing around with bambu and have run into a question that I haven't found an answer for in the documentation.

I wanted to try synthesising a correlation circuit like this:

constexpr std::size_t SAMPLE_COUNT = 500;
constexpr int8_t MAX_CORRELATION_SAMPLES = 50;

using Sample = int16_t;
using SampleArray = std::array<Sample, SAMPLE_COUNT>;

// int8_t do_correlation(SampleArray& left_samples, SampleArray& right_samples) {
int8_t do_correlation(SampleArray& left_samples, SampleArray& right_samples) {
    int32_t best_sum = std::numeric_limits<int32_t>::min();
    int8_t best_offset = MAX_CORRELATION_SAMPLES+1;
    for (int8_t offset = -MAX_CORRELATION_SAMPLES; offset < MAX_CORRELATION_SAMPLES; offset++) {
        int32_t sum = 0;
        for(std::size_t i = MAX_CORRELATION_SAMPLES; i < SAMPLE_COUNT-MAX_CORRELATION_SAMPLES; i++) {
            int32_t l = left_samples[i];
            int32_t r = right_samples[i-offset];
            sum += l * r;
        }
        if(abs(sum) > best_sum) {
            best_sum = abs(sum);
            best_offset = offset;
        }
    }


    return best_offset;
}

building it with bambu main.cpp --print-dot --compiler=I386_CLANG11 --std=c++17 gives me an entity with the following signature:

module _Z14do_correlationRSt5arrayIsLj500EES1_(
    clock,
    reset,
    start_port,
    left_samples,
    right_samples,
    M_Rdata_ram,
    M_DataRdy,
    done_port,
    return_port,
    Mout_oe_ram,
    Mout_we_ram,
    Mout_addr_ram,
    Mout_Wdata_ram,
    Mout_data_ram_size
);
  // IN
  input clock;
  input reset;
  input start_port;
  input [31:0] left_samples;
  input [31:0] right_samples;
  input [31:0] M_Rdata_ram;
  input [1:0] M_DataRdy;
  // OUT
  output done_port;
  output [7:0] return_port;
  output [1:0] Mout_oe_ram;
  output [1:0] Mout_we_ram;
  output [63:0] Mout_addr_ram;
  output [31:0] Mout_Wdata_ram;
  output [9:0] Mout_data_ram_size;

however, I am not sure how to work with this. For example, how do I know where
in the memory to store the 2 arrays? Passing left_samples and right_samples
seems to have little effect, and from looking at the access pattern of the
addresses, it looks like this is generating 2 separate memories. The steps in
addresses between accesses are 0x200000002.

Is this explained ins some documentation somewhere that I missed? Or is this
just the wrong way to use the tool?

Dear Frans,
the two memories you see are generated because of the default Bambu setup.
You can find predefined experimental setups passing --help to the bambu executable: there you should be able to read implied options for the default setup BAMBU-BALANCED-MP. In particular, the -MP means Multi Port memory and the default setup implies two memory channels, thus the generated design will feature two parallel memories.
If you need to have a single memory I suggest you try out other experimental setups without the -MP suffix, or you can just specify type and number of memory channels through --channels-number and --channels-type options (which are described in the help).

Hi, thanks for the reply! I'm still curious about how to instantiate the module, in particular, what values do I pass to left_samples and right_samples? Are they the addresses of the two arrays in memory? If I wanted set values for those two arrays externally, would I need to write to the same memories that I "connect" to the bambu module?

Hi, this is all correct. Pointer/reference parameters are fed into the generated module as memory addresses pointing to the external memory location where each object is allocated. If you need to initialize these objects before the computation begins you need to write the values at the memory location pointed by the addresses you are passing to the generated module.

Great, thanks!