- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
Link Copied
12 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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...- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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).- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- 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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- 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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- 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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- 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..
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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!
Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page