1

I am new to vhdl and I have a question that I could not find an answer to.

I am trying to implement some algorithm that operates on a vector 1024 bits long. So I have to read data from a file and insert them in this temp_vector(1023 downto 0).

The file contains many inputs and for each one the algorithm operates on the output of the previous one. The problem is that the length of this input data is not constant, but each input length varies from 0 to 16000.

In each cycle I can only read 64 bits from my testbench and insert them. At specific moments I also have to append sequences of bits of variable length to the already inserted data. I use the integer bit_position to keep track of the last position of temp_vector I inserted data in, and the integer data_in_length to tell me the actual length of the data that I read in each cycle.

After temp_vector is full or I finished inserting all the input, I stop reading and the algorithm operates on temp_vector and then the reading from the file resumes.

I get correct results in simulations. The problem I have is with FPGA and ASIC synthesis. It has to do with the varying length of the input data. I came up with two approaches in order to read the file and insert the data to temp_vector. First

temp_vector_proc : process(clk, rst_n)
begin
      if rst_n = '0' then
        state  <=  RESET;
      elsif clk'event and clk = '1' then
        case state is
          when RESET =>
            state  <=  TAKING_DATA;
            enable_calculations <= '0';
            bit_position <= 0;
            temp_vector <= (others => '0');

          when TAKING_DATA =>
            if take_data = '1' then
              for i in 0 to 63 loop
                temp_vector(i+bit_position) <= data_in_keyak(i);
              end loop;
              bit_position <= bit_position +data_in_length;
            end if;
          when ...
          .....
        end case;
      end if; -- end rst_n = '0'
  end process temp_vector_proc;

And second

  when TAKING_DATA =>
     if take_data = '1' then
       temp_vector(63+ bit_position downto bit_position) <= data_in(63 downto 0);
       bit_position <= bit_position +data_in_length;
     end if;
  when ...
     .....
end case;

The second approach is working in FPGA but it is taking a lot of time and consuming too many Logic Elements and for design compiler it is returning an error that the range has to be constant.

The first one is also working in FPGA and returning no error in ASIC ( Design compiler), but for the ASIC it runs forever (I let it run overnight). It was stuck at beginning Pass 1 Mapping of the entity that contains the first code.

I hope I explained my problem enough and I would really appreciate some thoughts on how to implement it in a more efficient way.

I do not think I can go with generics because the file is read and operated on in one go, so the lengths are changing during the simulation. I also though about shifting but since the shifting value would be changing each time, i guess that it would still consume a lot of time/area.

Finally could my whole approach be wrong? I mean is it possible that for FPGA and especially for ASIC I need to be working on specific input sizes? That would mean that I should try to write and synthesize code that does not work for all of my file, but for some of its inputs with some specified size only.

Thanks a lot in advance for your time.

thodmir
  • 11
  • 1
  • Some random thoughts : Need declarations ... for temp_vector, (OK found that), data_in_length, etc. It's not really clear what you're doing but it seems to me if data_in_length /= 64 then neither of these does the right thing. If you need to replace a variable part of a 64 bit chunk, you can do that by ANDing with a variable mask and ORing with its complement. Synthesis of variable sized hardware is clearly impossible. And finally, it may be that ASIC synth tools are more restrictive in understanding VHDL than FPGA tools. –  Nov 12 '15 at 18:54
  • I read in each cycle 64 bits, but since the length of the input is not fixed, I use the integer data_in_length to tell me how long in bits is the input. It is an input from the test bench. If the data I still have to input in my temp_vector are more than or equal to 64 bits long then data_in_length = 64, if it is less then data_in_length = something less than 64 (the length of the remaining data). It is used to modify the bit_position, which is the last position of temp_vector that I put data in, so I know where to continue inserting the next time. – thodmir Nov 12 '15 at 19:18
  • OK so you can use `data_in_length` to generate a mask for incomplete 64-bit words, e.g. to set the remaining bits to 0 instead of garbage. –  Nov 12 '15 at 19:25
  • The problem is not the garbage, I set the extra(garbage) bits to 0 from my testbench. data_in_length tells me how many of the input bits are useful. When I insert the bits from the input to temp_vector I always input the 64 even if some of them are extra zeros. I use the bit_position <= bit_position + data_in_length to know where I last put something useful in temp_vector. The sim is correct but the way I thought is not efficient for synthesis and the area I get is too high. I am looking for thoughts for a more efficient/synthesis friendly way to insert inputs of unknown length to temp_vector – thodmir Nov 13 '15 at 12:07
  • Without a self-contained complete compilable example to illustrate the specific problem, all we can do is guess. –  Nov 13 '15 at 12:14
  • The hardware you are inferring is large. What's the range of the number of inputs and are there a fixed number of lengths (and if so how many)? It tells us how many clocks there are to play in. There can be time and space trade offs by describing hardware. Is the throughput assembling the 1024 bit value critical? You could pre-pack the significant number of 64 bit segments in your file and pre-clear the target value or target clear the remaining segments - format the data for simpler hardware. (Think hardware). –  Nov 16 '15 at 17:00

0 Answers0