0

I'm trying to create a ROM where a number of values is stored and, after receiving a clock pulse, one of its values is read and then sent to the output while the counter that keeps track of the current position in the ROM is increased by 1. The problem that i found is that the ROM value is not retrieved as it should be in the first clock event.

Entity code

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity memoria is
    Port ( clock, reset :in STD_LOGIC;
              valor : out  STD_LOGIC_VECTOR(7 downto 0);
           vazia : out  STD_LOGIC);
end memoria;

architecture Behavioral of memoria is

    type ROM is array (0 to 4) of STD_LOGIC_VECTOR(7 downto 0); --Read only memory

    constant mem : ROM := (b"00000000", b"00000001", b"00000010", b"00000011", b"11111111"); --"11111111" is the stop value
    signal mem_value : STD_LOGIC_VECTOR(7 downto 0);

begin
    process(clock, reset)
        variable counter : integer := 0;
    begin

        if reset = '1' then
            valor <= "11111111";
            vazia <= '1';

        elsif clock'event and clock = '1' then
            mem_value <= mem(counter);  --gets the current memory value

            if mem_value = "11111111" then --checks if the value read is the stop one
                vazia <= '1';
            else
                vazia <= '0';
            end if;

            valor <= mem_value;             --sends the memory value read to the output
            if counter < 4 then
                counter := counter + 1; --increases counter by one
            end if;
        else
            valor <= "11111111";
            vazia <= '0';
        end if;
    end process;
end Behavioral;

Test Bench

ENTITY memoria_tb IS
END memoria_tb;

ARCHITECTURE behavior OF memoria_tb IS 

   --Inputs
   signal clock : std_logic;-- := '0';
    signal reset : std_logic := '0';

    --Outputs
   signal valor : std_logic_vector(7 downto 0);
   signal vazia : std_logic;

   -- Clock period definitions
   constant clock_period : time := 10 ns;

BEGIN

    -- Instantiate the Unit Under Test (UUT)
   uut: entity work.memoria PORT MAP (
          clock => clock,
             reset => reset,
          valor => valor,
          vazia => vazia
        );

   -- Clock process definitions
   clock_process :process
   begin
        clock <= '0';
        wait for clock_period/2;
        clock <= '1';
        wait for clock_period/2;
   end process;  
END;

Image of the error enter image description here

I would like to know how to get the first ROM value in the first clock pulse instead of UUUUUUUU. Thanks for the help.

Dave
  • 5,108
  • 16
  • 30
  • 40

1 Answers1

0

The problem was that the outputs should always be assigned after the process as noted in this post https://forums.xilinx.com/t5/General-Technical-Discussion/Counter-implementation-in-vhdl/td-p/570433.

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity memoria is
    Port ( clock, reset :in STD_LOGIC;
              valor : out  STD_LOGIC_VECTOR(7 downto 0);
           vazia : out  STD_LOGIC);
end memoria;

architecture Behavioral of memoria is

    type ROM is array (0 to 4) of STD_LOGIC_VECTOR(7 downto 0); --Read only memory

    constant mem : ROM := (b"00000000", b"00000001", b"00000010", b"00000011", b"11111111"); --"11111111" is the stop value
    signal mem_value : STD_LOGIC_VECTOR(7 downto 0);
    signal empty : STD_LOGIC;

begin
    process(clock, reset)
        variable counter : integer := 0;
    begin

        if reset = '1' then
            mem_value <= "11111111";
            empty <= '1';

        elsif clock'event and clock = '1' then
            mem_value <= mem(counter);  --gets the current memory value

            if mem_value = "11111111" then --checks if the value read is the stop one
                empty <= '1';
            else
                empty <= '0';
            end if;


            if counter < 4 then
                counter := counter + 1; --increases counter by one
            end if;
        else
            mem_value <= "11111111";
            empty <= '0';
        end if;
    end process;

    valor <= mem_value;             --sends the memory value read to the output
    vazia <= empty;
end Behavioral;
  • I don't think that the if statement `if mem_value = "11111111" then` will be evaluated the way you expect, i-e at the first clock cycle, `mem_value` is undefined. Also, you must remove the else statement which creates latch. – grorel May 28 '18 at 09:13
  • you can take a look at this post for more informations : https://stackoverflow.com/a/15499109/1182849 – grorel May 28 '18 at 09:14