The Designer's Guide Community
Forum
Welcome, Guest. Please Login or Register. Please follow the Forum guidelines.
Jul 16th, 2024, 4:01pm
Pages: 1
Send Topic Print
NAND gate, multiple input module, gate cap? (Read 9113 times)
altaj
Junior Member
**
Offline



Posts: 11

NAND gate, multiple input module, gate cap?
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
//
////////////////////////////////////////////////////////////////////////
Back to top
 
 
View Profile   IP Logged
Geoffrey_Coram
Senior Fellow
******
Offline



Posts: 1999
Massachusetts, USA
Re: NAND gate, multiple input module, gate cap?
Reply #1 - 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] );
Back to top
 
 

If at first you do succeed, STOP, raise your standards, and stop wasting your time.
View Profile WWW   IP Logged
Ken Kundert
Global Moderator
*****
Offline



Posts: 2386
Silicon Valley
Re: NAND gate, multiple input module, gate cap?
Reply #2 - 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[i]) <+ C_IN*ddt(V(in[i])); 


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

-Ken
Back to top
 
« Last Edit: Feb 28th, 2007, 1:28pm by Ken Kundert »  
View Profile WWW   IP Logged
altaj
Junior Member
**
Offline



Posts: 11

Re: NAND gate, multiple input module, gate cap?
Reply #3 - 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
//
////////////////////////////////////////////////////////////////////////
Back to top
 
 
View Profile   IP Logged
Ken Kundert
Global Moderator
*****
Offline



Posts: 2386
Silicon Valley
Re: NAND gate, multiple input module, gate cap?
Reply #4 - 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
Back to top
 
 
View Profile WWW   IP Logged
altaj
Junior Member
**
Offline



Posts: 11

Re: NAND gate, multiple input module, gate cap?
Reply #5 - 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
Back to top
 
 
View Profile   IP Logged
Geoffrey_Coram
Senior Fellow
******
Offline



Posts: 1999
Massachusetts, USA
Re: NAND gate, multiple input module, gate cap?
Reply #6 - 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.
Back to top
 
 

If at first you do succeed, STOP, raise your standards, and stop wasting your time.
View Profile WWW   IP Logged
altaj
Junior Member
**
Offline



Posts: 11

Re: NAND gate, multiple input module, gate cap?
Reply #7 - 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
//
////////////////////////////////////////////////////////////////////////
Back to top
 
 
View Profile   IP Logged
Geoffrey_Coram
Senior Fellow
******
Offline



Posts: 1999
Massachusetts, USA
Re: NAND gate, multiple input module, gate cap?
Reply #8 - 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

Back to top
 
 

If at first you do succeed, STOP, raise your standards, and stop wasting your time.
View Profile WWW   IP Logged
altaj
Junior Member
**
Offline



Posts: 11

Re: NAND gate, multiple input module, gate cap?
Reply #9 - 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
Back to top
 
 
View Profile   IP Logged
Geoffrey_Coram
Senior Fellow
******
Offline



Posts: 1999
Massachusetts, USA
Re: NAND gate, multiple input module, gate cap?
Reply #10 - Mar 2nd, 2007, 12:04pm
 
Indeed!
Back to top
 
 

If at first you do succeed, STOP, raise your standards, and stop wasting your time.
View Profile WWW   IP Logged
altaj
Junior Member
**
Offline



Posts: 11

Re: NAND gate, multiple input module, gate cap?
Reply #11 - 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
//
////////////////////////////////////////////////////////////////////////
Back to top
 
« Last Edit: Mar 2nd, 2007, 4:15pm by altaj »  
View Profile   IP Logged
Geoffrey_Coram
Senior Fellow
******
Offline



Posts: 1999
Massachusetts, USA
Re: NAND gate, multiple input module, gate cap?
Reply #12 - 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.
Back to top
 
 

If at first you do succeed, STOP, raise your standards, and stop wasting your time.
View Profile WWW   IP Logged
Pages: 1
Send Topic Print
Copyright 2002-2024 Designer’s Guide Consulting, Inc. Designer’s Guide® is a registered trademark of Designer’s Guide Consulting, Inc. All rights reserved. Send comments or questions to editor@designers-guide.org. Consider submitting a paper or model.