VHDL FSM Moving Average

vhdl

I'm trying to write a VHDL moving average (evenly weighted) module that uses FSMD(ata). From what I understand, the states needed would be something like fetch, divide, output. Below is the process I wrote, but I feel like my logic is a bit off. Note that the data I'm averaging is just a constant array of 8 bit numbers, so I figured it should be fine to use a non-causal design.

The data has 64 entries, and at the moment the window for the average is 4.

process (clk,rst) is

    variable temp : integer range 0 to 1020;
    begin
        if rst = '1' then
            count  <= 0;
            n_state <= s0;
        elsif (clk'event and clk = '1') then
            c_state <= n_state;
            case c_state is
                when s0 =>
                    for i in 0 to (len) loop
                        temp := temp + pattern(count+i);
                    end loop;
                    n_state <= s1;
                when s1 =>
                    temp := temp/4;
                    n_state <= s2;
                when s2 =>
                    data <= std_logic_vector(to_unsigned(pattern(count),8));
                    data_avg <= std_logic_vector(to_unsigned(temp,8));
                    n_state <= s0;
                    count <= count+1;
                end case;
        end if;
    end process;

How wrong does this look?

Best Answer

A few problems I can see right away:

  1. You don't [re-]initialize temp anywhere.
  2. You don't have any limit checks for count (is it a subtype or just a natural/integer? What happens with pattern(count+i) when you approach the limit? How do you roll over?)
  3. Your for-loop is 0 to len - are you sure you didn't mean 0 to (len - 1)?
  4. Since your entire state decode process is clocked, you don't really need n_state at all. Note that you're not even initializing c_state (but you're still decoding it). Either make your state decode a separate combinational process or just get rid of n_state and assign to c_state directly.

Otherwise, it depends on your design goals. If you don't care about throughput but need to run at a very high clock rate, you might want to perform your addition sequentially instead of in parallel, for example.

Related Topic