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:
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:
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:
You've still got a problem. Quote:
|
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:
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. |