Forum Discussion

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

Multicycle custom instruction repeated calls, hangs, signals

Hello,

I have some problems with a multicycle custom instruction.

I'm using a Terasic DE1 board with Quartus II 13.01 64 bit on Ubuntu 12.04.

I've started with the NIOS II system for "count_binary" example. It works, more or less. Sometimes I get errors of mismatch ID or timestamps that I must solve with deleting Run environment of, at worst, reprogramming the FPGA. (Is it normal..??)

Starting from this system, I've eliminated the PIO that is used to display the counter by boards leds. Still ok.

At this point I've added this custom instruction (it's only and example, I know it's stupid):


library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity dci4 is
    port (
        CLK:        in        std_logic;
        CLK_EN:    in     std_logic;
        RESET:    in        std_logic;
        START:    in        std_logic;
        DATAA:    in        std_logic_vector(31 downto 0);
        DATAB:    in        std_logic_vector(31 downto 0);
        RESULT:    out    std_logic_vector(31 downto 0);
        DONE:        out    std_logic
    );
end dci4;
architecture Behavior of dci4 is
begin
    process(CLK)
        variable IDATAA:    integer;
        variable IDATAB:    integer;
        variable STATE:     integer;
    begin
        if (rising_edge(CLK)) then
            if (RESET = '1') then
                RESULT <= (others => '0'); 
                DONE <= '0'; 
                IDATAA := 0;
                IDATAB := 0;
                STATE := 0;
            elsif (CLK_EN = '1') then
                case STATE is
                    when 0 =>
                        if (START = '1') then
                            STATE := 1;
                        else
                            STATE := 0;
                        end if;
                    when 1 =>
                        IDATAA :=  to_integer(unsigned(DATAA));
                        IDATAB :=  to_integer(unsigned(DATAB));
                        STATE := 2;
                    when 2 =>
                        IDATAA := IDATAA +1;
                        IDATAB := IDATAB -1;
                        if (IDATAB = 0) then
                            RESULT <= std_logic_vector(to_unsigned(IDATAA, RESULT'length));
                            DONE <= '1';
                            STATE := 3;
                        end if;
                    when 3 =>
                        DONE <= '0'; 
                        RESULT <= (others => '0');  
                        STATE := 0;
                    when others =>
                        STATE := 0;
                end case;
            end if;
        end if;
    end process;
end Behavior;

Problems starts here: the c.i. seems to hang and nothing is returned.

Any suggestion is HIGHLY welcome.

Are START, RESULT and DONE correctly managed? Am I doing something really stupid (consider that ModelSim simulation on the above code give correct results).

Thanks

12 Replies

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

    For what it's worth, after you stop using 'U' as dsl described, your custom instruction VHDL that you pasted is fine.

    Whatever hang you're seeing is not caused by the VHDL you pasted, and it is something else.

    If you're not able to figure it out, my suggestion would be to post a .zip of a simplified project (NIOS+Onchip SRAM+your custom instruction) that others can compile and run.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    I've solved.

    The problem was a timer component, in Qsys, set to 1 nanosecond resolution.... DE1 has a 50MHz clock.

    Changing the resolution to 20 ns makes all things work as expected.

    Thanks all!