The Designer's Guide Community Forum
https://designers-guide.org/forum/YaBB.pl
Design Languages >> Verilog-AMS >> VerilogA - Pulse generator with reset
https://designers-guide.org/forum/YaBB.pl?num=1525456310

Message started by Jacob E. F. Overgaard on May 4th, 2018, 10:51am

Title: VerilogA - Pulse generator with reset
Post by Jacob E. F. Overgaard on May 4th, 2018, 10:51am

Hello everyone.

I have been looking a little on various websites and on Designer's  Guide, but I remain unable to figure out how I deal with this issue.

I am making a set/reset pulse based on an incomming clocked signal (200 kHz at 50% duty cycle). I want to make a give set pulse (pulse width 15 ns) on rising edge and a corresponding reset pulse (pulse width 15 ns) on falling edge.

But I also want a disable input pin, that keeps set low and asserts reset.

My current implementation is shown below, and the basic behaviour works quite well. But I have remained unable to assert reset during disable = high.

Do you guys have any ideas as to how I manage this? Using @cross() in if statements doesn't work naturally, and using if statements in @cross() only checks during a transition.


Code:
// VerilogA for set/reset pulse-generator with external reset
`include "constants.vams"
`include "disciplines.vams"

module s144029_SET_RST(Clkin, Disable, RST, SET, Vdd, Vss);
input Clkin, Disable, Vdd, Vss;
output SET, RST;
electrical Clkin, Disable, SET, RST, Vdd, Vss;
parameter real pulsewidth = 15n;
parameter real tt = 10n;
real v_set, v_rst, tend;

analog begin
     @(cross(V(Clkin) - 2.5, +1)) begin
           v_set = V(Vdd);
           tend = $abstime + pulsewidth;
     end
     @(timer(tend)) v_set = V(Vss);
     V(SET) <+ transition(v_set, 0, tt);

     @(cross(V(Clkin) - 2.5, -1)) begin
           v_rst = V(Vdd);
           tend = $abstime + pulsewidth;
     end
     @(timer(tend)) v_rst = V(Vss);
     V(RST) <+ transition(v_rst, 0, tt);
end
endmodule


I hope my question is clear, otherwise I'd love to elaborate.

Best regards Jacob

Title: Re: VerilogA - Pulse generator with reset
Post by Ken Kundert on May 4th, 2018, 8:58pm

Jacob,
   One thing that seems strange to me is your use of tend. Specifically, if you have one tend variable, like you do, then it seems like you should have one timer block that resets both ouputs. Otherwise it seems like you should have two tend variables, one for each output.

Concerning your question about how to implement disable, I recommend that put a conditional around the statements that assign to v_set and v_rst. Something like this ...

Code:
@(cross(V(Clkin) - 2.5, +1)) begin
   if (V(disable) < 2.5)
       v_set = V(Vdd);
   else
       v_set = V(Vss);
   tend = $abstime + pulsewidth;
end

Or perhaps ...

Code:
@(cross(V(Clkin) - 2.5, +1)) begin
   v_set = V(disable) < 2.5 ? V(Vdd) : V(Vss);
   tend = $abstime + pulsewidth;
end


-Ken

Title: Re: VerilogA - Pulse generator with reset
Post by Jacob E. F. Overgaard on May 4th, 2018, 11:50pm

Hi Ken, thank you very much for your reply.

I do see what you mean with my variable tend, I didn't even think about it. Somehow it works as intended though, I am pretty amazed by that!

Regarding your suggestion for the implementatioon. I have tried that specific method, but the issue is it only asserts reset/set on edges and not at all times when disable is high.

One could imagine at gate level that the last gate on reset is an or-gate with two inputs. Where one of the inputs is some conditional logic that ensures the given pulsewidth, and the other input would simply just be Disable.

This way whenever Disable is high reset is asserted for all eternity.

Did this make sense?

Best regards Jacob

Title: Re: VerilogA - Pulse generator with reset
Post by Ken Kundert on May 5th, 2018, 12:00pm

In addition to what I have suggested so far. also get rid of the @timer blocks and replace with the following:

Code:
@(timer(tend) or cross(V(disable) - 2.5, +1)) begin
   v_set = V(Vss);
   v_rst = V(Vss);
end


-Ken

Title: Re: VerilogA - Pulse generator with reset
Post by Jacob E. F. Overgaard on May 5th, 2018, 12:15pm

Ah fantastic Ken, thank you very much.

I will try this shortly. :)

Boy does VerilogA contain so many new aspects...

Title: Re: VerilogA - Pulse generator with reset
Post by Jacob E. F. Overgaard on May 5th, 2018, 1:52pm

Okay, so I did find a solution to my explained issue above. Largely based on the helpful input of Ken.

Solution:


Code:
// VerilogA for set/reset pulse-generator with external reset

`include "constants.vams"
`include "disciplines.vams"

module s144029_SET_RST(Clkin, Disable, RST, SET, Vdd, Vss);
input Clkin, Disable, Vdd, Vss;
output SET, RST;
electrical Clkin, Disable, SET, RST, Vdd, Vss;
parameter real pulsewidth = 15n;
parameter real tt = 10n;
real v_set, v_rst, tendset, tendrst;

     analog begin
           @(cross(V(Clkin) - 2.5, +1)) begin
                 if (V(Disable) < 2.5)
                       v_set = V(Vdd);
               else
                       v_set = V(Vss);
                 tendset = $abstime + pulsewidth;
           end

           @(cross(V(Clkin) - 2.5, -1)) begin
                 v_rst = V(Vdd);
                 tendrst = $abstime + pulsewidth;
           end

           @(timer(tendset)) v_set = V(Vss);
           @(timer(tendrst)) v_rst = V(Vss);

           if (V(Disable) > 2.5) v_rst = V(Vdd);
           @(cross(V(Disable) - 2.5, -1))
                 v_rst = V(Vss);

           V(SET) <+ transition(v_set, 0, tt);
           V(RST) <+ transition(v_rst, 0, tt);
     end
endmodule

The Designer's Guide Community Forum » Powered by YaBB 2.2.2!
YaBB © 2000-2008. All Rights Reserved.