2
\$\begingroup\$

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);
\$\endgroup\$
  • \$\begingroup\$ We need to see the declarations for the various signals. Obviously, you missed a type conversion somewhere along the way. \$\endgroup\$ – Dave Tweed Mar 16 '16 at 2:21
  • \$\begingroup\$ What about temp_byte? \$\endgroup\$ – Dave Tweed Mar 16 '16 at 2:32
  • \$\begingroup\$ @DaveTweed That's signed(7 downto 0) but how can I change the signal type in a individual process. The signal temp_byte is also been used in other processes so I don't know how to deal with it. \$\endgroup\$ – EEEidolt Mar 16 '16 at 2:37
4
\$\begingroup\$

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.

\$\endgroup\$
  • \$\begingroup\$ How should I keep the byte at the centre? I want each new coming byte goes to the centre so when it's compared to be the maximum I can directly output the bytes stored in the shift register 【(3 bit) maximum(3bit)】 the out put is the maximum bit with 3 bits on either side. \$\endgroup\$ – EEEidolt Mar 16 '16 at 21:35
  • \$\begingroup\$ @EEEidolt I have extended my answer to describe the basic idea. If you have a question about the given code, you can ask it here in the comments. But, if you have a question on how to proceed further, please ask a new question. I will not extend my answer again, I will only correct it if needed. \$\endgroup\$ – Martin Zabel Mar 17 '16 at 7:56
  • \$\begingroup\$ Thank you but what I'm thinking is if the the new bytes coming in from the left side( 7 down to 0), they would be shift out of the register at the beginning when no data is in the register. Therefore I'm wondering if I can change the sentence temp_shift_register(7 downto 0) <= new byte from memory; to temp_shift_register(55 downto 48)........? \$\endgroup\$ – EEEidolt Mar 17 '16 at 17:17
  • \$\begingroup\$ That makes no sense to me. In my code, I have used the same shift direction as in your code. A new byte is placed in position 7 downto 0. At the next clock edge, it is shifted to 15 downto 8. Then to 23 downto 16 and so on until 55 downto 48. Then it is shifted out. Just setup a testbench and try it out :-) \$\endgroup\$ – Martin Zabel Mar 17 '16 at 20:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.