Electronic – shift register problem in VHDL

debuggingshift-registervhdl

I'm designing a 56 bit shift register to store the bits coming in.

In my system, 8 bit data is keep coming in from a generator and I need to output the maximum value detected with 3 bytes either side of it.I want the data stored in a 56 bit wide shift register to give a out put that consists of the maximum and the other 7 bytes as shown in the graph.

The system compare each byte coming in with a temporary maximum value and it will give a 56 bit output each time when a new maximum value is detected.

I just wondering how can I keep the new coming in data at the centre so once the new-coming-in data is found to be greater than the temporary maximum I'm able to out put the whole 56-bit serial signal.

I tried to write something but Modelsim gave me this

Target type ieee.std_logic_1164.STD_LOGIC_VECTOR in signal assignment is different from expression type ieee.NUMERIC_STD.SIGNED. for temp_shift_register(31downto 24)…..

shift : process (clk)
begin
  if rising_edge(clk) and begin_req ='1' then 
    for i in 55 downto 8 loop 
      temp_shift_register(i) <= temp_shift_register(i-8); 
    end loop;
    temp_shift_register(31 downto 24) <= temp_byte; 
  else null;
  end if;
end process;

enter image description here

The signal declarations are:

signal temp_shift_register : std_logic_vector (55 downto 0):= "00000000000000000000000000000000000000000000000000000000";
signal perm_shift_register : std_logic_vector (55 downto 0):= "00000000000000000000000000000000000000000000000000000000";
signal temp_byte : signed (7 downto 0);

Best Answer

As the array types signed and std_logic_vector have the same element type you can convert between both types the following way:

signal x : std_logic_vector(7 downto 0); -- 8 bit for example
signal y : signed(7 downto 0);

y <= signed(x);

and back

signal y : signed(7 downto 0);
signal z : std_logic_vector(7 downto 0); -- 8 bit for example

z <= std_logic_vector(y);

Of course, you can also use variables instead of signals (using the := assignment).

So for your shift register you will need:

temp_shift_register(31 downto 24) <= std_logic_vector(temp_byte);

Further remarks

This line is not required:

  else null;

You are missing to shift in new values at the position temp_shift_register(7 downto 0).

Instead of the for ... end loop; you can just assign all bits at once:

temp_shift_register(55 downto 8) <= temp_shift_register(47 downto 0);

How to proceed

Taking your other question into account, the basic idea is to have a second 56-bit wide result register which stores the current maximum and the values (bytes) beside it:

signal result_register : std_logic_vector(55 downto 0) := (others => '0');

Then you will have to:

  • Shift the new values from memory into the shift register at the lower bits.
  • Compare the middle byte of the shift register with the middle byte of the result register. If the former is greater, then copy the shift register into the result register.

The code would look like this:

process (clk) is
begin
  if rising_edge(clk) then
    -- shift register
    temp_shift_register(55 downto 8) <= temp_shift_register(47 downto 0);
    temp_shift_register(7 downto 0)  <= new_byte_from_memory;

    -- check for new maximum
    if signed(temp_shift_register(31 downto 24)) > signed(result_register(31 downto 24))  then
      result_register <= temp_shift_register;
    end if;
  end if;
end process;

You will have to extend the code at least 1) to reset both registers, and 2) shift the register only when new data from memory is available.

Related Topic