Search code examples
embeddedvhdlfpgahardware

VHDL decimation(?) of data in specific way


My VHDL code doesn't behave as i expected.

What i want: i have 32 bit input data stream, and decimated 32 bit data output in some specific order.

Let's say each 32 bit data split into two 16 bit data.

  • first case: every second 16 bit of 32 bit data present on output;
  • second case: every fourth 16 bit of 32 bit data present on output;
  • third case fourth 16 bit of 32 bit data present on output and so on.

Like in the picture:pic1

Here is first case of implementation:

process (CLK_IN, RST_IN)
begin
    if (RST_IN = '1') then
        rx_data_half_a <= (others => '0');
    elsif rising_edge(CLK_IN) then
        rx_data_half_a <= DATA_IN(15 downto 0);
    end if;
end process;

process (CLK_IN, RST_IN)
begin
    if (RST_IN = '1') then
        rx_data_half_a0 <= (others => '0');
        rx_data_half_a1 <= (others => '0');
    elsif rising_edge(CLK_IN) then
        rx_data_half_a0 <= rx_data_half_a;
        rx_data_half_a1 <= rx_data_half_a0; 
        rx_data_half_a2 <= rx_data_half_a1; 
        DATA_OUT <= rx_data_half_a0 & rx_data_half_a;
    end if;
end process;

And the testbench is looking like that: sim

Instead of 00002222 44446666 ...

I get: 00002222 22224444 44446666 ...

I already do this job using memory (just counting specific addresses) but i dont' want to use it. I think there's much easiest way to implement this.

It is possible to do with registers without reducing the frequency? Can you give me some advise?


Solution

  • You need a minimal state machine (eg: a counter) to track the input and update the data registers at the appropriate time. You logic is running every clock cycle and has no idea it needs to "skip" any of the incoming samples.

    Since you are decimating, it is not possible to do this in registers or in memory without "reducing the frequency" in that you will have half (or 1/4 or whatever your decimation ratio is set to) as many output elements as input elements. If you use a memory you could burst at the full rate for a while, but you will still have to pause periodically and "re-fill" the buffer.