- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic to the Top
- Bookmark
- Subscribe
- Printer Friendly Page
PicoBlaze - beginners question on interrupt
- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Highlight
- Email to a Friend
- Report Inappropriate Content
02-05-2012 09:55 PM
Got my first PicoBlaze design / program running ... extended it with an external 1 kHz interrupt and this causes me now some headaches.
The interrupt is recognized and serviced by the PicoBlaze, however as long as the extint signal is high, the interrupt is serviced continuously instead of only once. So I've an level serviced extint instead of an edged triggered ext int.
( see attachment ).
This is my VHDL interrupt_control process.
interrupt_control: process(clk)
begin
if clk'event and clk='1' then
if interrupt_ack='1' then
interrupt <= '0';
elsif extint = '1' then interrupt <= '1';
else interrupt <= interrupt;
end if;
end if;
end process interrupt_control;
My question : how do I get this edged trigger instead of level triggered ?
Again, I'm a PicoBlaze starter and hope somebody can help me out.
Kind regards, Jan - Netherlands
Re: PicoBlaze - beginners question on interrupt
- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Highlight
- Email to a Friend
- Report Inappropriate Content
02-05-2012 10:47 PM
If PicoBlaze is level sensitive, you should detect rising edges of extint in your process.
In Verilog, I would do something (untested) like this:
reg [1:0] extint_sr;
always @(posedge clk)
begin
// Use a shift register to detect state transitions
extint_sr <= {extint_sr[0], extint};
// If a rising edge, assert an interrupt
if (extint_sr == 2'b01)
interrupt <= 1;
else if (interrupt_ack == 1)
interrupt <= 0;
end
Re: PicoBlaze - beginners question on interrupt
- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Highlight
- Email to a Friend
- Report Inappropriate Content
02-06-2012 01:55 PM
Thanks Joelby for your swift response ... thanks for your suggestion ... will try to incorporate in VHDL in my design.
Rgds. Jan
Re: PicoBlaze - beginners question on interrupt
- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Highlight
- Email to a Friend
- Report Inappropriate Content
02-06-2012 10:55 PM
Hi,
you can use the debounce circuit from the ISE language templates (VHDL -> Synthesis Constructs -> Coding Examples -> Misc).
This creates a synchronized one shot of your input signal.
Have a nice synthesis
Eilert
Re: PicoBlaze - beginners question on interrupt
- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Highlight
- Email to a Friend
- Report Inappropriate Content
02-07-2012 12:46 AM
used the shift register approach and this did the job :
risefall: process(clk)
begin
if (clk'event and clk = '1') then
shift(0) <= extint;
shift(1) <= shift(0);
rise <= not shift(1) and shift(0);
fall <= shift(1) and not shift(0);
end if;
end process;
the rise signal is connected to the interrupt of the PicoBlaze and performing according my expectation ... :manhappy:
Re: PicoBlaze - beginners question on interrupt
[ Edited ]- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Highlight
- Email to a Friend
- Report Inappropriate Content
02-07-2012 06:16 AM - edited 02-07-2012 06:17 AM
Just to make sure anyone reading this thread implements interrupts correctly I will make some comments below and also recommend a good read of the descriptions provided in the documentation (e.g. pages 4- to 44 of ‘KCPSM6_User_Guide_30Sept11.pdf’).
As Jan has shown above, the interrupt input to PicoBlaze is level sensitive (active High). Interrupts need to be enabled within the program for PicoBlaze to react and clearly Jan must have used the ‘ENABLE INTERRUPT’ instruction to do that. However, we must remember that when PicoBlaze responded to the interrupt input (i.e. the point at which it issued the ‘interrupt_ack’ pulse) and started to execute the interrupt service routine it automatically disabled further interrupts. The interrupt service routine needed to end with a ‘RETURNI ENABLE’ instruction in order that PicoBlaze could again react to a High level on the interrupt input. Hence the reason we see spaces between the ‘int_ack’ pulses in Jan’s first waveform diagram.
In Jan’s case, each time PicoBlaze completed an interrupt service routine it immediately reacted to the High level that was still being applied to the interrupt input. For some applications this could be the desired behaviour but it was not what Jan was looking for in this design. The ‘solution’ described for Jan’s case was to detect the rising edge of the ‘extint’ signal that was remaining High for a long time and produce a ‘rise’ signal that was a single cycle clock pulse occurring only when the ‘extint’ signal went from Low to High. As you can see, it worked but I feel that Jan was lucky that it did!
Jan indicated that he connected the ‘rise’ signal directly to the PicoBlaze interrupt. If this was indeed what Jan did then the design will almost certainly be unreliable and should be modified. As documented, PicoBlaze samples the interrupt input every other clock cycle (on the rising edge of clock that ‘address’ changes). This means that if you only apply an interrupt pulse that is High for one clock cycle then it may be missed completely (50% of the time if it occurs randomly). If only a short pulse is to be applied to the interrupt input, then it should be a minimum of two clock cycles wide which is still easy to implement.
Although short pulses can be applied to the interrupt input, this method also has the potential to be unreliable depending on the application. The point to remember is that PicoBlaze will not always be ready to respond to an interrupt. As I mentioned previously, PicoBlaze automatically disables interrupts whilst it is busy servicing an interrupt, so if a pulse occurred during that time it would be ignored altogether. There can also be times when you deliberately disable interrupts using the ‘DISABLE INTERRUPT’ and ‘ENABLE INTERRUPT’ instructions and again there would be the potential to miss a short pulse.
Therefore, the better solution is to use one circuit to generate a pulse that indicates that an interrupt is required and then use a circuit that drives the interrupt input to PicoBlaze High until it is acknowledged by PicoBlaze with the ‘interrupt_ack’ signal. In this way any interrupts that occur whilst PicoBlaze is otherwise busy are not missed and will be serviced as soon as interrupts are enabled again. So in this case we would have something like this....
interrupt_control: process(clk)
begin
if clk'event and clk='1' then
-- Detect rising edge and generate a pulse
extint_delay <= extint;
if (extint = '1' and extint_delay = '0') then
interrupt_event <= '1';
else
interrupt _event <= '0';
end if;
-- Drive interrupt until acknowledged by PicoBlaze
if interrupt_ack = '1' then
interrupt <= '0';
else
if interrupt = '1' then
interrupt <= '1';
else
interrupt <= interrupt;
end if;
end if;
end if;
end process interrupt_control;
By the way, even the code I have shown above is not completely bullet proof. Can anyone spot the weakness and suggest an improvement? :smileywink:
Principal Engineer, Xilinx UK
Re: PicoBlaze - beginners question on interrupt
[ Edited ]- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Highlight
- Email to a Friend
- Report Inappropriate Content
02-07-2012 07:57 AM - edited 02-07-2012 07:58 AM
Joffie,
As Ken Chapman explained, your logic does not keep the interrupt input to PicoBlaze asserted until the interrupt has been acknowledged, and so there is considerable probability that interrupts will be lost, or even a deadlock condition might occur.
Try implementing joelby's code, which includes both edge detection and sticky-interrupt-request-until-acknowledged.
I would have recommended using Ken Chapman's code, but he has already confessed that it has a bug. :)
-- Bob Elkind
README for newbies is here: http://forums.xilinx.com/t5/New-Users-Forum/README-first-Help-for-new-users/td-p/219369
Summary:
1. Read the manual or user guide. Have you read the manual? Can you find the manual?
2. Search the forums (and search the web) for similar topics.
3. Do not post the same question on multiple forums.
4. Do not post a new topic or question on someone else's thread, start a new thread!
5. Students: Copying code is not the same as learning to design.
6 "It does not work" is not a question which can be answered. Provide useful details (with webpage, datasheet links, please).
7. You are not charged extra fees for comments in your code.
8. I am not paid for forum posts. If I write a good post, then I have been good for nothing.
Re: PicoBlaze - beginners question on interrupt
- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Highlight
- Email to a Friend
- Report Inappropriate Content
02-07-2012 08:14 AM
I'm not completely sure what the weakness is, unless it's that
if interrupt = '1' then
should be
if interrupt_event = '1' then
Unless I'm missing something because it's 2:30am.
If you cared about servicing the correct number of interrupts (and your interrupt handler occasionally, but not always, took a long time to run) you could increment a counter each time a rising edge was detected and decrement it when it was acknowledged, but that's probably a rather silly idea unless you were using it as a real-time clock.
Re: PicoBlaze - beginners question on interrupt
- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Highlight
- Email to a Friend
- Report Inappropriate Content
02-07-2012 09:40 AM
Joelby,
Once you stop, you just can't start.
-- Bob Elkind
README for newbies is here: http://forums.xilinx.com/t5/New-Users-Forum/README-first-Help-for-new-users/td-p/219369
Summary:
1. Read the manual or user guide. Have you read the manual? Can you find the manual?
2. Search the forums (and search the web) for similar topics.
3. Do not post the same question on multiple forums.
4. Do not post a new topic or question on someone else's thread, start a new thread!
5. Students: Copying code is not the same as learning to design.
6 "It does not work" is not a question which can be answered. Provide useful details (with webpage, datasheet links, please).
7. You are not charged extra fees for comments in your code.
8. I am not paid for forum posts. If I write a good post, then I have been good for nothing.
Re: PicoBlaze - beginners question on interrupt
- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Highlight
- Email to a Friend
- Report Inappropriate Content
02-08-2012 06:09 AM
Ok, I made myself look stupid more than normal that time so please allow me to redeem myself with some better code.
interrupt_control: process(clk)
begin
if clk'event and clk='1' then
-- Detect rising edge and generate a pulse
extint_delay <= extint;
if (extint = '1' and extint_delay = '0') then
interrupt_event <= '1';
else
interrupt_event <= '0';
end if;
-- Drive interrupt until acknowledged by PicoBlaze
if interrupt_event = '1' then
interrupt <= '1';
else
if interrupt_ack = '1' then
interrupt <= '0';
else
interrupt <= interrupt;
end if;
end if;
end if;
end process interrupt_control;
I just wish I could function during daylight as well as 'joelby' does at 2:30am. In other words, I've just defined the same basic functionality as 'joelby' presented earlier but took far more lines of code to describe it! Furthermore he spots the potential weakness as well.
A BIG THANK YOU to all the experts that contribute to the PicoBlaze forum; you make my life much easier.
Principal Engineer, Xilinx UK











