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;
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);
1 Answer 1
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.
-
\$\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– EEEidolt2016年03月16日 21:35:46 +00:00Commented Mar 16, 2016 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– Martin Zabel2016年03月17日 07:56:21 +00:00Commented Mar 17, 2016 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;
totemp_shift_register(55 downto 48)........
? \$\endgroup\$EEEidolt– EEEidolt2016年03月17日 17:17:52 +00:00Commented Mar 17, 2016 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– Martin Zabel2016年03月17日 20:15:59 +00:00Commented Mar 17, 2016 at 20:15
temp_byte
? \$\endgroup\$