Waseem Abbas
Waseem Abbas

Reputation: 5

Out come of vhdl code not as expected

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;

Upvotes: 0

Views: 110

Answers (1)

Morten Zilmer
Morten Zilmer

Reputation: 15924

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));

Upvotes: 1

Related Questions