Search code examples
vhdlprocedure

VHDL procedure causes undefined signals where identical code outside procedure works fine


LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
use ieee.std_logic_unsigned.all;
USE ieee.numeric_std.ALL;

USE IEEE.STD_LOGIC_TEXTIO.ALL;
USE STD.TEXTIO.ALL;

entity theswings is

end theswings;

architecture Behavioral of theswings is
    signal a_signal_p: std_logic_vector(3 downto 0) := "0000";
    signal the_other: std_logic_vector(3 downto 0) := "0000";
    file da_goods: TEXT open read_mode is "C:\Users\~~~~\playground\goods";
    procedure read_slv(file F: text; value: inout std_logic_vector) is
                 -- no error checking of any sort is performed by this function
                 -- it assumes the file is a newline-separated list of strings
                 -- describing one std_logic_vector each
                 -- if EOF, then return "XXXXXXXX"
        variable tmp: line;
        variable tmpr: std_logic_vector(3 downto 0) := "1010";
    begin
        if endfile(F) then
                for i in tmpr'range loop
                    tmpr(i) := 'X';
                end loop;
        else
                readline(F, tmp);
                read(tmp, tmpr);
        end if;
    end read_slv;

begin
    process
        --variable invar, outvar: std_logic_vector(3 downto 0);
        --variable tmp: line;
        variable tmpr: std_logic_vector(3 downto 0);
        --variable str: string;
    begin
        wait for 50 ns;
--      while not endfile(da_goods) loop
--          readline(da_goods, tmp);
--          read(tmp, tmpr);
--          a_signal_p <= tmpr;
--          --a_signal_p <= invar;
--          the_other <= not tmpr;
--          --outvar := the_other;
--          --write(da_bads, the_other);
--          wait for 10 ns;
--      end loop;
        for i in 0 to 8 loop
            read_slv(da_goods, tmpr);
            a_signal_p <= tmpr;
            the_other <= not tmpr;
            wait for 10 ns;
        end loop;
        wait;
    end process;
END;

As you might guess, the commented out main loop works fine, whereas the for loop using the procedure doesn't work. (Specifically, after 50 ns of zeros, all signals go to "UUUU" instead of e.g. the "1010" one might expect from the procedure body.

Does anyone recognize the error I've made? I'm 98% sure it's a really stupid sort of problem that a noob like me wouldn't understand yet.


Solution

  • in your procedure declaration you mention the variable "value"

    procedure read_slv(file F: text; value: inout std_logic_vector) is
    

    you must assign "value" with "tmpr" within your procedure!

          ...
         if endfile(F) then
                for i in tmpr'range loop
                    tmpr(i) := 'X';
                end loop;
        else
                readline(F, tmp);
                read(tmp, tmpr);
        end if;
        value:=tmpr; -- assign result!
     end read_slv;
    

    as you already mentioned in the question... a pretty stupid mistake ;-)