Sign In

Don't have a Xilinx account yet?

  • Choose to receive important news and product information
  • Gain access to special content
  • Personalize your web experience on Xilinx.com

Create Account

Username

Password

Forgot your password?
XClose Panel
Xilinx Home
Reply
Visitor
joffie32
Posts: 3
Registered: ‎02-05-2012
0

PicoBlaze - beginners question on interrupt

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



picoblaze-interrupt.JPG
Expert Contributor
joelby
Posts: 1,055
Registered: ‎10-05-2010

Re: PicoBlaze - beginners question on interrupt

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

 

Visitor
joffie32
Posts: 3
Registered: ‎02-05-2012
0

Re: PicoBlaze - beginners question on interrupt

Thanks Joelby for your swift response ... thanks for your suggestion ... will try to incorporate in VHDL in my design. 

 

Rgds. Jan 

Expert Contributor
eilert
Posts: 2,055
Registered: ‎08-14-2007
0

Re: PicoBlaze - beginners question on interrupt

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

Visitor
joffie32
Posts: 3
Registered: ‎02-05-2012
0

Re: PicoBlaze - beginners question on interrupt

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:

 

 

picoblaze-interrupt-ok.JPG
Xilinx Employee
chapman
Posts: 411
Registered: ‎09-05-2007
0

Re: PicoBlaze - beginners question on interrupt

[ Edited ]

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:

Ken Chapman
Principal Engineer, Xilinx UK
Expert Contributor
eteam00
Posts: 7,505
Registered: ‎07-21-2009
0

Re: PicoBlaze - beginners question on interrupt

[ Edited ]

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

SIGNATURE:
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.
Expert Contributor
joelby
Posts: 1,055
Registered: ‎10-05-2010
0

Re: PicoBlaze - beginners question on interrupt

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.

 

Expert Contributor
eteam00
Posts: 7,505
Registered: ‎07-21-2009
0

Re: PicoBlaze - beginners question on interrupt

Joelby,

 

Once you stop, you just can't start.

 

-- Bob Elkind

SIGNATURE:
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.
Xilinx Employee
chapman
Posts: 411
Registered: ‎09-05-2007
0

Re: PicoBlaze - beginners question on interrupt

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. 

Ken Chapman
Principal Engineer, Xilinx UK