Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
11 years ago

procedure call problem

Hi,

I am having problems using procedures in my simulation. I create the procedure between architecture and begin. I then call the procedure concurrently in the body of the architecture. As I understand it when I call the procedure like this then then it will be evaluated when any of the input signals change, a bit like a process with a sensitivity list. When I simulate however it seems to only evaluate once.

Here is a cut down of the code I am using:


ARCHITECTURE logic OF test_procedure IS
    PROCEDURE read_stuff (  SIGNAL clk_i    : IN std_logic;
                            SIGNAL reset_i  : IN std_Logic;
                            SIGNAL empty    : IN std_logic;
                            SIGNAL rdreq    : OUT std_logic) IS
        TYPE state_machine IS
        (
            check_empty,
            clear_rdreq
        );
        VARIABLE state : state_machine;
    BEGIN
        IF(reset_i = '1') THEN
            state := check_empty;
            rdreq <= '0';
        ELSIF(clk_i = '1' AND clk_i'EVENT) THEN
            CASE state IS
                WHEN check_empty =>
                    IF(empty = '0') THEN
                        rdreq <= '1';
                        state := clear_rdreq;
                    END IF;
                WHEN clear_rdreq =>
                    rdreq <= '0';
                    state := check_empty;
            END CASE;
        END IF;
    END PROCEDURE;
    
    SIGNAL clk             : std_logic;
    SIGNAL reset           : std_logic;
    SIGNAL empty_signal    : std_logic;
    SIGNAL rdreq_signal    : std_logic;
BEGIN
    call_read_stuff : read_stuff
        (    
            clk_i    => clk,
            reset_i  => reset,
            empty    => empty_signal,
            rdreq    => rdreq_signal 
        );
END ARCHITECTURE;

The aim of the procedure is to read data from a fifo when it is not empty. I know I can do this with a process but I am trying to create a smaller reusable chunk that I can call in a generate as I have a few fifos that I want to pull data out of. This is for simulation only im not trying to create rtl from this.

When I run my simulation the rdreq signal gets set when the empty flag goes low, however rdreq stays high, it doesnt seem to change to the second state and clear the rdreq signal and transition back to evaluate empty again. I also tried to do the same without using the state machine but had no more luck.

Any suggestions would be appreciated.

Thanks

James

12 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    So from this im guessing that when I call the procedure concurrently, every time the inputs change and the procedure gets re-evaluated the variable is getting re-initialised. in the case of the state machine this is meaning that it keeps getting re-initialised to check_empty so the state machine isnt transitioning and in my second procedure rdreq_ip is always being re-intialised to 0 and is never able to clear rdreq.

    --- Quote End ---

    Its all a question of scope. Calling a procedure the way you have done, or any code outside a process, implicitly declares a process.

    Procedures and functions are supposed to be re-useble, but self contained bits of code.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    Its all a question of scope. Calling a procedure the way you have done, or any code outside a process, implicitly declares a process.

    Procedures and functions are supposed to be re-useble, but self contained bits of code.

    --- Quote End ---

    But procedure does not behave like equivalent replacement with process. In this example if you replace the procedure with equivalent process then it works with process but not with procedure.

    try and replace the procedure with this code:

    
    process(reset,clk)
    	 	   
    	TYPE state_machine IS (check_empty, clear_rdreq);
            VARIABLE state : state_machine;
        BEGIN
            IF(reset = '1') THEN
                state := check_empty;
                rdreq_signal <= '0';
            ELSIF(clk = '1' AND clk'EVENT) THEN
                CASE state IS
                    WHEN check_empty =>
                        IF(empty_signal = '0') THEN
                            rdreq_signal <= '1';
                            state := clear_rdreq;
                        END IF;
                    WHEN clear_rdreq =>
                        rdreq_signal <= '0';
                        state := check_empty;
                END CASE;
            END IF;
        END PROCESS;