0

I want to take num as as an 8 bit input and then shift it on every rising edge of clock and out it on output "res". Code is shown below. But when simulated it does not give expected results.

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
use ieee.numeric_std.all;

entity shiftreg is
    port (
    num : in std_logic_vector (7 downto 0);
    clk : in std_logic; 
    res : out std_logic_vector (7 downto 0)
    );
end entity;

architecture behav of shiftreg is 
    signal temp_num : std_logic_vector (7 downto 0):= "00000000"; 
begin
    process(num) 
    begin
        if(num' event) then
            temp_num <= num;
            res<=temp_num; 
        end if;
    end process;

    process(clk) 
    begin
        if(rising_edge(clk)) then
            temp_num <= shr(temp_num,"01");
            res<=temp_num;
        end if;
    end process;
end behav;
Bill Lynch
  • 80,138
  • 16
  • 128
  • 173
Waseem Abbas
  • 5
  • 1
  • 3
  • 1
    You have multiple problems. First, you are driving `temp_num` and `res` from multiple processes, which will result in contention on those signals. Second, it appears that you may be attempting to use `temp_num` as a local variable, which it is not. See [How does signal assignment work in a process?](http://stackoverflow.com/questions/5060635/how-does-signal-assignment-work-in-a-process). More importantly, algorithmically, it's unclear exactly what you're trying to do. Are you trying to load `num` once and then rotate it several times? Are you trying to shift it serially? – fru1tbat Oct 23 '14 at 14:14
  • thanks for response, yes i'm trying to shift it serially. – Waseem Abbas Oct 23 '14 at 16:46

1 Answers1

1

The output res and signal temp_num are both driven from both of the processes, thus the simulator will do resolution, which is likely to result in X values for some or all bits.

In general, then signals and output is design modules should be driven from only a single process, since that is also what synthesis tools expect. For test benches, then there may be multiple drivers.

So if the intention is that any change in the num input should be reflected immediately to the res output, and any later rising edge of clk should result in right shift, then the two processes may be combined in a single process and assign to res like:

process (num, clk) is
begin
  if (num'event) then
    temp_num <= num;
  elsif (rising_edge(clk)) then
    temp_num <= shr(temp_num, "01");
  end if;
end process;
res <= temp_num;

This will work in simulation, but the 'event wont work in synthesis, since there is typically no hardware that can sense value changes like 'event, so the construction can't be mapped to hardware by synthesis.

So for a synthesizeable design, you may consider adding a load input:

load : in  std_logic;

And use this for load of the internal temp_num with a process like:

process (clk) is
begin
  if (rising_edge(clk)) then
    if load = '1' then
      temp_num <= num;
    else
      temp_num <= shr(temp_num, "01");
    end if;
  end if;
end process;
res <= temp_num;

Finally, you should consider removing the use ieee.std_logic_arith.all; and use ieee.std_logic_unsigned.all;, since these two packages are not standard VHDL packages, despite location in the IEEE library. Simply remove the two lines, and then use the shift_right function from the std_logic_unsigned like:

temp_num <= std_logic_vector(shift_right(unsigned(temp_num), 1));
Morten Zilmer
  • 15,586
  • 3
  • 30
  • 49