Programmable Devices
CPLDs, FPGAs, SoC FPGAs, Configuration, and Transceivers
Announcements
FPGA community forums and blogs on community.intel.com are migrating to the new Altera Community and are read-only. For urgent support needs during this transition, please visit the FPGA Design Resources page or contact an Altera Authorized Distributor.
21615 Discussions

Multicycle custom instruction repeated calls, hangs, signals

Altera_Forum
Honored Contributor II
2,118 Views

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
0 Kudos
12 Replies
Altera_Forum
Honored Contributor II
1,261 Views

I have litte, very little experience in Nios II but I tell you what I learn with trial and error method. When you place a Nios processor in SOPC builder you have an CPU ID option. Click on it. The USB Blaster don't establish a good link with your processor without this. 

 

Place a system ID component in SOPC builder. With this you avoid the sys ID mismatch but ignore the timestamp mismatch ID when you download the firmware ( unless you have a timer component for timestamp activities ). 

 

I see you vhdl code. I assume it is not a testbench, so why do u use metavalue U?: 

 

RESULT <= (others => 'U'); -- *** 

DONE <= 'U'; -- *** 

 

this is intended only for simulation. It has no sense in synthesis. Assign ( others => '0' ) or something like that to RESULT when reset take place.
0 Kudos
Altera_Forum
Honored Contributor II
1,261 Views

First of all, thank you for your answer. 

 

 

--- Quote Start ---  

I have litte, very little experience in Nios II but I tell you what I learn with trial and error method. When you place a Nios processor in SOPC builder you have an CPU ID option. Click on it. The USB Blaster don't establish a good link with your processor without this. 

 

Place a system ID component in SOPC builder. With this you avoid the sys ID mismatch but ignore the timestamp mismatch ID when you download the firmware ( unless you have a timer component for timestamp activities ). 

 

--- Quote End ---  

 

 

I forget to say that I use Qsys. 

Anyway, I have the system id component. As I wrote, the system in Qsys is the one (perfectly working) of the 'count_binary' example. This example is part of the Altera HW dev tutorial. 

I've only added the custom instruction. 

 

 

--- Quote Start ---  

 

I see you vhdl code. I assume it is not a testbench, so why do u use metavalue U?: 

 

RESULT <= (others => 'U'); -- *** 

DONE <= 'U'; -- *** 

 

this is intended only for simulation. It has no sense in synthesis. Assign ( others => '0' ) or something like that to RESULT when reset take place. 

 

--- Quote End ---  

 

 

Forget those U... only a result of despair...
0 Kudos
Altera_Forum
Honored Contributor II
1,261 Views

I'm pretty sure "DONE" needs to be asserted for a single clock only. 

 

The NIOS is probably hanging prior to issuing the next instruction because it's waiting for "DONE" to be de-asserted? 

 

I don't think you have to do anything special with "RESULT" when you clear the "DONE" bit (it can keep it's old contents).
0 Kudos
Altera_Forum
Honored Contributor II
1,261 Views

 

--- Quote Start ---  

I'm pretty sure "DONE" needs to be asserted for a single clock only. 

 

The NIOS is probably hanging prior to issuing the next instruction because it's waiting for "DONE" to be de-asserted? 

 

I don't think you have to do anything special with "RESULT" when you clear the "DONE" bit (it can keep it's old contents). 

--- Quote End ---  

 

 

Thank you for your answer. 

 

Where state = 2 I assign result and DONE <= '1'. 

Where state = 3 you can see DONE <= 'U', but the original code was DONE <= '0': the deassertion was realized there. 

In this way, DONE is asserted for one clock cycle. But the result was exactly the same. 

The c.i. call hang.
0 Kudos
Altera_Forum
Honored Contributor II
1,261 Views

Try finding your custom instruction on the RTL viewer. 

For combinatorial ones it shows quite cleary how they connect to the main cpu. 

 

Signaltap might also be informative. 

 

I'm not vhdl expert, but I'd have thought that you'd need to set DONE to zero in the reset clause - setting things to 'U' is probably only relevenant for simulation.
0 Kudos
Altera_Forum
Honored Contributor II
1,261 Views

 

--- Quote Start ---  

Thank you for your answer. 

 

Where state = 2 I assign result and DONE <= '1'. 

Where state = 3 you can see DONE <= 'U', but the original code was DONE <= '0': the deassertion was realized there. 

In this way, DONE is asserted for one clock cycle. But the result was exactly the same. 

The c.i. call hang. 

--- Quote End ---  

 

 

I guess I misunderstood your notation and problem description. I had understood that when you placed the '***' next to the state=3 deassertion, that when you removed that line you got the hang. I hadn't understood that this line had been there in both broken cases. 

Anyway, yes you should look at SignalTap as dsl mentioned and confirm your waveforms match Figure 1-6 of the user guide. 

 

Beyond that, your code is kind of simple so it might be something unrelated. Regarding your mistmatched system ID or timestamp, no it is not normal. It is the tools telling you that you aren't running on the same FPGA design that the software is compiled to expect. For example, maybe your are running on an FPGA that doesn't even have your custom instruction present and hangs for that reason. Furthermore, your 'DONE' bit is being set conditional on the value of 'DATAB', so depending on what your software is supplying, your instruction might take a REALLY long time to execute and simply appear to be hung when it is in fact operating normally.
0 Kudos
Altera_Forum
Honored Contributor II
1,261 Views

The sopc builder software used to cache the timestamp (or similar) from the board instead of re-reading it. 

Quite possibly something similar still happens. 

 

It is a shame that the Altera eample about using custom intructions just tells you how to click the buttons to add/remove the ones they supply. 

The source for one that implements add would be more useful! 

 

I wrote a combinatorial one that uses the 5 bit rB field to choose between various bit and byte reversals.
0 Kudos
Altera_Forum
Honored Contributor II
1,261 Views

 

--- Quote Start ---  

I guess I misunderstood your notation and problem description. I had understood that when you placed the '***' next to the state=3 deassertion, that when you removed that line you got the hang. I hadn't understood that this line had been there in both broken cases. 

Anyway, yes you should look at SignalTap as dsl mentioned and confirm your waveforms match Figure 1-6 of the user guide. 

 

Beyond that, your code is kind of simple so it might be something unrelated. Regarding your mistmatched system ID or timestamp, no it is not normal. It is the tools telling you that you aren't running on the same FPGA design that the software is compiled to expect. For example, maybe your are running on an FPGA that doesn't even have your custom instruction present and hangs for that reason. Furthermore, your 'DONE' bit is being set conditional on the value of 'DATAB', so depending on what your software is supplying, your instruction might take a REALLY long time to execute and simply appear to be hung when it is in fact operating normally. 

--- Quote End ---  

 

 

Thank you Ted for your suggestions. 

I will check SignalTap; at the moment i don't ever know what it is. 

Regarding problems of id and timestamp mismatch, I'm really puzzled because this problem appears sometimes also in base (untouched) example: from time to time you have to reprogram fpga or delete run configuration. Even in an example that should work perfectly: I follow exactly the tutorial to build the core and the Eclipse project. 

A long run time due to operands is not the case: in my example datab is 10, so the c.i. must complete in approx 10 clock cycles.
0 Kudos
Altera_Forum
Honored Contributor II
1,261 Views

 

--- Quote Start ---  

The sopc builder software used to cache the timestamp (or similar) from the board instead of re-reading it. 

Quite possibly something similar still happens. 

 

It is a shame that the Altera eample about using custom intructions just tells you how to click the buttons to add/remove the ones they supply. 

The source for one that implements add would be more useful! 

 

I wrote a combinatorial one that uses the 5 bit rB field to choose between various bit and byte reversals. 

--- Quote End ---  

 

 

Thank you, dsl. 

I use Qsys in QuartusII 13.0.1: I don't know if such a problem affects even this software. I will check. 

These problems are, for sure, my fault. But, quite frankly, Altera documentations on c.i. seems not to be very useful. If I solve this issue I must implement a c.i. that use conduit interface: I haven't found anything useful on documentation about that. Boh..
0 Kudos
Altera_Forum
Honored Contributor II
1,261 Views

I think you should be setting DONE to '0' not 'U'. 

Under simulation 'U' is probably different from both '0' and '1', on real silicon it will either be '0' or '1'. 

So quite likely the value doesn't change - and you need it to be 0. 

If it has a fixed value of '1' then the instruction would terminate immediately - which is one thing you are seeing.
0 Kudos
Altera_Forum
Honored Contributor II
1,261 Views

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.
0 Kudos
Altera_Forum
Honored Contributor II
1,261 Views

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!
0 Kudos
Reply