[SOLVED] verilog event disable

Status
Not open for further replies.

it_boy

Full Member level 3
Joined
Jul 18, 2002
Messages
173
Helped
6
Reputation
12
Reaction score
2
Trophy points
1,298
Activity points
1,261
I am trying to generate a pulse at every rising edge of "inp" signal. I am using event to do the same.
Problem occurs whenever event triggers during the delay of the pulse_width.
Named block gets disabled, but never event does not trigger.
Have a look at attached file to see what I mean.

Can someone help me understand why the event does not trigger during the second event? or why inp_pulse always stays high?

Code:
  always @(posedge inp) begin
    disable pulse_gen;
    -> inp_rise;
  end
  
  always @(inp_rise) begin: pulse_gen
    inp_pulse = 1'b1;
    #pulse_width;
    inp_pulse = 1'b0;
  end

 

I suggest you use temporary registers for values swap.
.

:i also suggest pasting the entire program with declarations so we can use them in our tools.
:
well, I am not debugging but rather providing my code for you., which I hope serves you purposes.
:
comments, modification requiremnts are welcome.
.
.


Code Verilog - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
module redge(d,clk,rst,rising,ax,bx,nx);
    input d,clk,rst;
    output rising,ax,bx,nx;
//    reg q,w;
    reg rising;
    reg ax,bx,nx;
 
 
always @(posedge clk ) begin
   ax= d; // to juz store input, shift-in reg
   bx<= ax;
   if(rst) begin
       rising<=0;
       nx<=0;
   end else  if ( ax==1 & bx==0 ) begin // falling edge
             rising <= 1'b1;
             nx<= rising;
             rising<=~nx;
   end  else
   rising=0;
// end
 end
endmodule

:
 

I can explain why the simulator behaves the way it does.

Remember that the always construct

always statement;

is a process that executes a statement, and when it is done, it executes the statement again in an infinite loop.

People sometimes think that when they see

always @(event) statement;

it means execute the statement at every event. It does not mean that. The event control is just part of the statement. The statement has to complete before it starts executing the whole thing over again.

A begin/end block is just a compound statement made up of a serial sequence of other statements. When you use the disable block statement in your example, that causes the block to jump to its end. However your next statement is to trigger inp_rise. This is technically a race condition, but most simulators will trigger the event first, then go back to the top of the loop and wait for another @(posedge inp). At that point, the simulator will switch to the other always block and repeat it loop waiting for another inp_rise, which has already been triggered and missed.

One way to avoid this race is to delay the trigger. You could easily do this if you were using SystemVerilog, but if you have to stick with Verilog, you can use a toggle as I have attached here:

Code:
module top;
   reg inp_pulse,inp_rise=0;
   reg inp;
   parameter pulse_width = 50;

   always begin : pulse_gen
      @(inp_rise)
    inp_pulse = 1;
      #pulse_width 
    inp_pulse = 0;
   end
   always @(posedge inp) begin
      disable pulse_gen;
      inp_rise <= ! inp_rise;
   end
   
   initial begin
      inp = 0;
      #10 inp = 1;
      #10 inp = 0;
      #100;
      #10 inp = 1;
      #10 inp = 0;

      #10;
      #10 inp = 1;
      #10 inp = 0;
      #50;
      #10 inp = 1;
      #10 inp = 0;
   end // initial begin
endmodule // top

You can find other modeling suggestion by searching for "Verilog re-triggerable one-shot"
 
Last edited:
@graphene:
Thanks for your reply, I currently dont have clock or other signals that you have mentioned.
Will try out your code sometime.

@dave_59.
Thanks a lot for the explanation. Understood the problem with my always statement.
Your piece of code solved my problem. Will look for "Verilog re-triggerable one-shot" that you indicated.
 
Status
Not open for further replies.
Cookies are required to use this site. You must accept them to continue using the site. Learn more…