The Designer's Guide Community Forum
https://designers-guide.org/forum/YaBB.pl
Design Languages >> Verilog-AMS >> NAND gate, multiple input module, gate cap?
https://designers-guide.org/forum/YaBB.pl?num=1172627649

Message started by altaj on Feb 27th, 2007, 5:54pm

Title: NAND gate, multiple input module, gate cap?
Post by altaj on Feb 27th, 2007, 5:54pm

Hi all,
I'm new to writing verilog-A modules.  I need some help (or a pointer to what book to buy to help!).  
I am setting up a verilog-A library to handle logic.  I have made an inverter module that models gate capatitance nicely.  I want to do the same for the multiple input gates, and retain the usefulness of the module for any number of inputs.  I have the module working with an appropriate cap on the first input of a 2 input nand, but can't figure out how to make the the cap 'increment' (for lack of a better word) to appear on all inputs.   Any pointers to material on this subject, or any help at all would be appreciated.   My code is below: first the model statment, then the module.  Please note that I found a bug in the spice engine that we use, and there is a hack in the code to workaround this until the software vendor fixes it.  The module is otherwise from eda-stds.org/verilog-ams/ more or less in tact, except for the Cap that I added.
Thanks for taking the time to read all of this!
John

*model statment
* nand2a
.model NAND2A_VLG VLG MODULE = nandg
+ vth = 1.4
+ tdelay = 2p
+ trise = 1p
+ tfall = 1p
+C_IN = 17e-15
+size = 2
*

// Now the module
////////////////////////////////////////////////////////////////////////
// NAND gate
//
module nandg (in,out);

parameter real size      = 2 from [2:inf),
               vout_high = 3.3,
               vout_low  = 0 from (-inf:vout_high),
               vth       = 1.4,
               tdelay    = 5n from [0:inf),
               trise     = 10n from [0:inf),
               tfall     = 12n from [0:inf);               input [0:size-1] in;
output           out;
voltage          in, out;

integer in_state[0:size-1];
integer out_state;
integer i;
real    vout;

// electrical gnd;
// ground gnd;
parameter real       C_IN     = 0 from [0:inf);
capacitor #(.c(C_IN))  cin(in[i]);
 
analog
begin
  @(initial_step)
    for(i=0; i<size; i=i+1) in_state[i] = 0;

  generate i (0, size-1)
  begin
    @(cross(V(in[i]) - vth))
    begin
      // Hack to workaround spice problem
      for(i=0; i<size; i=i+1) in_state[i] = V(in[i]) > vth;  
      // Hack to workaround spice problem End
      out_state   = 1;
      for (i=0; i<size; i=i+1) begin
        if (!(out_state && in_state[i])) out_state = 0;
      end
      if (out_state) vout = vout_low;          // Inversion
      else           vout = vout_high;
    end
  end

  V(out) <+ transition(vout,tdelay,trise,tfall);
end
endmodule
//
////////////////////////////////////////////////////////////////////////

Title: Re: NAND gate, multiple input module, gate cap?
Post by Geoffrey_Coram on Feb 28th, 2007, 4:22am

Why are "in" and "out" voltages, rather than electrical?

I think, though I haven't worked much with generates, that you could put the capacitors in explicitly by equations, and do this in the generate block:

I(in[i]) <+ ddt( C_IN * V(in[i] );

Title: Re: NAND gate, multiple input module, gate cap?
Post by Ken Kundert on Feb 28th, 2007, 9:31am

It is odd that the same variable i is used as the index for both the for loops, and for the generate loop that contains them.

To add capacitors to every input, you should do it behaviorally by adding

Code:
   I(in) <+ C_IN*ddt(V(in[i]));

inside the generate statement. And if you do this, you will need to convert the ports from [i]voltage to electrical as Geoffrey suggests.

-Ken

Title: Re: NAND gate, multiple input module, gate cap?
Post by altaj on Feb 28th, 2007, 10:02am

Thanks so much for the replies.   I used voltage rather than electrical 'cause that's how I got it, and did not know better.  I had wondered about that distinction myself after reading the material I have here on the subject.   I see now that the behavioral line is the one to use.   I've seen that in the texts, but did not know which way to go.  
I've changed the parameters to electrical, and put the line in what I think is the generate statment (tried a couple different ways) but get the error"Error: Syntax error near ';'".  This is pointing to the ; at the end of the cap equation line.  Can you tell me what is incorrect?  Also, Is there a good reference on syntax for novices?

Here is the modified
code:
////////////////////////////////////////////////////////////////////////
// NAND gate
//
module nandg (in,out);

parameter real size      = 2 from [2:inf),
               vout_high = 3.3,
               vout_low  = 0 from (-inf:vout_high),
               vth       = 1.4,
                       tdelay    = 5n from [0:inf),
               trise     = 10n from [0:inf),
               tfall     = 12n from [0:inf);               input [0:size-1] in;
output           out;
electrical          in, out;

integer in_state[0:size-1];
integer out_state;
integer i;
real    vout;

parameter real       C_IN     = 0 from [0:inf);
 
analog
begin
  @(initial_step)
    for(i=0; i<size; i=i+1) in_state[i] = 0;

  generate i (0, size-1)
  I(in[i]) <+ C_IN*ddt(V(in[i]);
   
    begin
    @(cross(V(in[i]) - vth))
    begin
      // Hack to workaround spice problem
      for(i=0; i<size; i=i+1) in_state[i] = V(in[i]) > vth;  
      // Hack to workaround spice problem End
      out_state   = 1;
      for (i=0; i<size; i=i+1) begin
        if (!(out_state && in_state[i])) out_state = 0;
      end
      if (out_state) vout = vout_low;          // Inversion
      else           vout = vout_high;
    end
  end

  V(out) <+ transition(vout,tdelay,trise,tfall);
end
endmodule
//
////////////////////////////////////////////////////////////////////////

Title: Re: NAND gate, multiple input module, gate cap?
Post by Ken Kundert on Feb 28th, 2007, 1:29pm

parens are not balanced.

Also, you will need to do something about using i as the index variable for both the for loops and the generate.

-Ken

Title: Re: NAND gate, multiple input module, gate cap?
Post by altaj on Feb 28th, 2007, 3:30pm

oh duh, yeah.  Rookie mistake (()).
THANKS!   It seems to be working now  (I also added a second generate statment and used a different integer variable for the caps.).

Next is modeling the output with a transistion statment to control some resistance values.   I'm sure I'll be back when I get stuck!
Again, thanks for all of the help!
John

Title: Re: NAND gate, multiple input module, gate cap?
Post by Geoffrey_Coram on Mar 1st, 2007, 4:31am


altaj wrote on Feb 28th, 2007, 3:30pm:
THANKS!   It seems to be working now  (I also added a second generate statment and used a different integer variable for the caps.)


I'm not sure you got Ken's point.  You've got
 generate i (0, size-1)

so you should change your for loops to
for (j=0; j<size; j=j+1)

Also: you have
 generate
 I<+
 begin
whereas I'd expect you should have had
 generate
 begin
   I<+

that is, the capacitor contrib I<+ should be *inside* the begin/end for the generate.

Title: Re: NAND gate, multiple input module, gate cap?
Post by altaj on Mar 1st, 2007, 2:59pm

Okay, yes.  That makes sense to me.  I'm still reading and learning a lot as I go.   Please check me here, but I think I can eliminate the entire 'j' business, and just use the single 'i' to perform both the input checking and the creation of the caps?  (See code below, which seems to be working, but I can't be sure because...

...As an aside, just as I was thinking that this is starting to work, I see this really strange behavior in my sim output (inputs of the verilog gates not behaving as they should).  After many emails about 90 minutes in a phone conference with three people from our software vendor, I've been told that I have found a bug in their simulation engine, and that it will not handle vectors correctly.  I can either wait for the fix, or make a model for each size (# of inputs) nand gate.   Bummer.)


code:
////////////////////////////////////////////////////////////////////////
// NAND gate
//
module nandg (in,out);

parameter integer size   = 2 from [2:inf);
parameter real C_IN     = 0 from [0:inf),
               vout_high = 3.3,
               vout_low  = 0 from (-inf:vout_high),
               vth       = 1.4,
               tdelay    = 5n from [0:inf),
               trise     = 10n from [0:inf),
               tfall     = 12n from [0:inf);
              input [0:size-1] in;
output           out;
electrical   in, out;

integer in_state[0:size-1];
integer out_state;
integer i;
real vout;
 
analog
begin
  @(initial_step)
    for(i=0; i<size; i=i+1) in_state[i] = 0;
    generate i (0, size-1)  
    begin
    I(in[i]) <+ C_IN*ddt(V(in[i]));
    @(cross(V(in[i]) - vth))
    begin
      // Hack to workaround spice problem
      for(i=0; i<size; i=i+1) in_state[i] = V(in[i]) > vth;  
      // Hack to workaround spice problem End
      out_state   = 1;
      for (i=0; i<size; i=i+1) begin
        if (!(out_state && in_state[i])) out_state = 0;
      end
      if (out_state) vout = vout_low;          // Inversion
      else           vout = vout_high;
    end
  end

  V(out) <+ transition(vout,tdelay,trise,tfall);
end
endmodule
//
////////////////////////////////////////////////////////////////////////

Title: Re: NAND gate, multiple input module, gate cap?
Post by Geoffrey_Coram on Mar 2nd, 2007, 4:29am


altaj wrote on Mar 1st, 2007, 2:59pm:
Okay, yes.  That makes sense to me.  I'm still reading and learning a lot as I go.   Please check me here, but I think I can eliminate the entire 'j' business, and just use the single 'i' to perform both the input checking and the creation of the caps?


You've still got a problem.


Quote:
    for(i=0; i<size; i=i+1) in_state[i] = 0;    <-- this is OK
    generate i (0, size-1)                                    <-- this "i" conflicts with two for() loops later
    begin
    I(in[i]) <+ C_IN*ddt(V(in[i]));
    @(cross(V(in[i]) - vth))
    begin
      // Hack to workaround spice problem
      for(i=0; i<size; i=i+1) in_state[i] = V(in[i]) > vth;  <-- this is BAD, is the "i" for the generate or the for?
      // Hack to workaround spice problem End
      out_state   = 1;
      for (i=0; i<size; i=i+1) begin                                       <-- this is also BAD
        if (!(out_state && in_state[i])) out_state = 0;
      end
      if (out_state) vout = vout_low;          // Inversion
      else           vout = vout_high;
    end
  end


Title: Re: NAND gate, multiple input module, gate cap?
Post by altaj on Mar 2nd, 2007, 9:50am

Thanks.   It's easy to believe that my modifications and the hack from our software vendor are incorrect, but do you think original code that I got from eda.org might be flawed as well?   It seems to have some of the same 'i' conflicts that you point out.
It is at
http://www.eda.org/verilog-ams/htmlpages/sample_lib.dcm.html#Nand

Title: Re: NAND gate, multiple input module, gate cap?
Post by Geoffrey_Coram on Mar 2nd, 2007, 12:04pm

Indeed!

Title: Re: NAND gate, multiple input module, gate cap?
Post by altaj on Mar 2nd, 2007, 1:14pm

Geoffrey,
I untangled the loop problems you pointed out, and this code seems to work okay, anyway it behaves like a nand gate.  I hope I did not go to far adding new variables (j & k).  
Note that due to the software vendors bug, I have to use the explicit caps for now.  (They say their software does not "handle verctors correctly".)

ALso, a question:  I have put a resistor in to model the output resistance. It is working fine, but I don't know how to properly define the variable for sw.  Right now it shows up in simulation results the same as "in" and "out" do, and I would rather it did not.   I tried defining it as "real sw;" but I get an error, so I left it as electrical.  
Is everything defined as "electrical" automatically passed to spice as a voltage or current?  I assumed it would be limited to what was in the in and out declarations, but that does not seem to be the case.


code:
////////////////////////////////////////////////////////////////////////
// NAND gate
//
module nandg (in,out);

parameter integer size   = 2 from [2:inf);
parameter real C_IN      = 0 from [0:inf),
               RDSON      = 0 from [0:inf),
               vout_high = 3.3,
               vout_low  = 0 from (-inf:vout_high),
               vth       = 1.4,
               tdelay    = 0.1p from [0:inf),
               trise     = 0.1p from [0:inf),
               tfall     = 0.1p from [0:inf);  input [0:size-1] in;
output           out;
electrical   in, out, sw;

integer in_state[0:size-1];
integer out_state;
integer i,j,k;
real vout;
 
// implicit caps
 capacitor #(.c(C_IN))  cin0(in[0]);
 capacitor #(.c(C_IN))  cin1(in[1]);
 resistor #(.r(RDSON))  r1 (sw, out);
//V(p,n) <+ r*I(p, n);
//  

  analog
begin
  @(initial_step)
    for(i=0; i<size; i=i+1) in_state[i] = 0;
    generate i (0, size-1)  
    begin
//     I(in[i]) <+ C_IN*ddt(V(in[i]));
    @(cross(V(in[i]) - vth))
    begin
      // Hack to workaround spice problem
      for(j=0; j<size; j=j+1) in_state[j] = V(in[j]) > vth;  
      // Hack to workaround spice problem End
      out_state   = 1;
      for (k=0; k<size; k=k+1) begin
        if (!(out_state && in_state[k])) out_state = 0;
      end
      if (out_state) vout = vout_low;          // Inversion
      else           vout = vout_high;
    end
  end
  V(sw) <+ transition(vout,tdelay,trise,tfall);
end
endmodule
//
////////////////////////////////////////////////////////////////////////

Title: Re: NAND gate, multiple input module, gate cap?
Post by Geoffrey_Coram on Mar 5th, 2007, 5:43am


altaj wrote on Mar 2nd, 2007, 1:14pm:
ALso, a question:  I have put a resistor in to model the output resistance. It is working fine, but I don't know how to properly define the variable for sw.  Right now it shows up in simulation results the same as "in" and "out" do, and I would rather it did not.   I tried defining it as "real sw;" but I get an error, so I left it as electrical.  
Is everything defined as "electrical" automatically passed to spice as a voltage or current?  I assumed it would be limited to what was in the in and out declarations, but that does not seem to be the case.


That's simulator dependent, I think.  Some simulators treat a V-AMS module as a subckt, some as a built-in primitive (you don't see internal nodes of the diode when it has series resistance).

You could try doing the resistor with a contrib rather than an instantiated resistor:
I(sw,out) <+ V(sw,out) / RDSON;

You don't need both j and k, but it doesn't hurt.

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