The following steps need to be done for getting the gm/Id vs Id/(W/L) graphs in Cadence for a MOS transistor.
Create the schematic
The schematic is a simple transistor schematic. The schematic below shows an example:
The above schematic shows that the drain current(di), vgd, vbs, W and L are parameterized and they are sweeped in the simulation script (except vbs) to get the graphs for a wide range of conditions and check the variation of the graph for them.
Save Operating Point Info
Create a text file called
mysaves_t18.scs and add the following line in it:
Now add this file with path in ADE->Setup->Simulation Files->Definition Files
Note that the .m0 is only needed because this model is implemented as s Sub Circuit in the models file. If the model is not a subcircuit and something direct like a BSIM model then .m0 would not be needed.
Setup simulation in ADE
Setup the DC sweep simulation in ADE by DC sweeping di from a low value to a high value for a typical vgd, W and L. Set the sweep to be logarithmic with 50 points per decade. Also setup expressions to calculate
- gm/Id = gm/di expression: (getData("MNO_PSP.m0:gm" ?result "dc-dc")/IS("/V1/PLUS"))
- Id/(W/L) expression: (IS("/V1/PLUS")/(5e-6/180e-9))
Run the Simulation and see the results.
Create the Ocean Script
Save the Ocean Script from the ADE environment and modify it to look like the following:
; Select the waveform tool
ocnWaveformTool( 'wavescan )
; Select the simulator
simulator( 'spectre )
; Specify the Design Netlist
design( "/sim/mgupta/nch_char_1/spectre/schematic/netlist/netlist")
; Specify the Results Directory
resultsDir( "/sim/mgupta/nch_char_1/spectre/schematic" )
; Specify the model files set
modelFile(
'("/home/tekcad/cds4_4/lib/models.scs" "tt_res")
'("/home/tekcad/cds4_4/lib/models.scs" "tt_mim")
'("/home/tekcad/cds4_4/lib/models.scs" "tt")
)
; Specify the Definition file created to save the operating point
definitionFile(
"/home/mgupta/Cadence/mysaves_t18.scs"
)
; Convert the main run steps to a procedure 'mysim' and convert width, length, vgd, istart, istop
; etc as variables to be passed along with the filehandle where to write the results
procedure(mysim(istart istop length width vgd fileHandle)
analysis('dc ?param "di" ?start istart ?stop istop ?dec "50" )
desVar( "l" length )
desVar( "vgd" vgd )
desVar( "di" 5u )
desVar( "w" width )
save( 'i "/V1/PLUS" )
temp( 27 )
run()
gm_by_Ids = (getData("MN0_PSP.m0:gm" ?result "dc-dc") / IS("/V1/PLUS"))
id_by_w_l = IS("/V1/PLUS")*length/width
;Comment out the plot statement
;plot( gm_by_Ids ?expr '( "gm_by_Ids" ) )
; Write the results in the filehandle
ocnPrint( ?output fileHandle ?numberNotation 'engineering ?numSpaces 10 id_by_w_l gm_by_Ids)
)
; Create file for writing the results
resultFile = outfile( "./Curves/gmByIdCurves.csv" "w")
; Close the file
close(resultFile)
; Lists for iterating the simulation
length_list = list(180e-9 500e-9 1e-6 1.5e-6 2e-6 2.5e-6 3e-6 3.5e-6 4e-6 4.5e-6 5e-6 5.5e-6 6e-6 6.5e-6 7e-6 7.5e-6 8e-6 8.5e-6 9e-6 9.5e-6 10e-6)
;length_list = list(180e-9 500e-9)
width_list = list(2e-6 4e-6 6e-6 8e-6 10e-6 15e-6 20e-6)
;width_list = list(2e-6 4e-6)
vgd_list = list(0.3 0 -0.3 -0.6 -0.9)
;vgd_list = list(0.3 0)
min_IdbyWL = 1e-9
max_IdbyWL = 200e-6
; Loop through all the lists
foreach( vgd vgd_list
foreach( width width_list
foreach(length length_list
; Calculate istart, istop so that Id/(W/L) starts and stops the same for every W/L combination
istart = min_IdbyWL*width/length
istop = max_IdbyWL*width/length
; Write the data in a temp File
tempFile = outfile("./Curves/gmByIdtmp.out" "w")
mysim(istart istop length width vgd tempFile)
; Close the file
close(tempFile)
; Combine the data file and temp file to an intermediate file
; Create the intermediate file
system(sprintf(nil "pr -mr -t -s\\ %s %s > %s" "./Curves/gmByIdCurves.csv" "./Curves/gmByIdtmp.out" "./Curves/gmByIdinter.out"))
; remove the Curves data file
system(sprintf(nil "rm -rf ./Curves/gmByIdCurves.csv"))
; rename intermediate file to Curves file
system(sprintf(nil "mv ./Curves/gmByIdinter.out ./Curves/gmByIdCurves.csv"))
)
)
)
; Remove the temporary File
system(sprintf(nil "rm -rf ./Curves/gmByIdtmp.out"))
Save this ocean script (say 'gmByIdScript.ocn') and load it from the CIW window by typing:
This would start the simulations and at the end we would have the file gmByIdCurves.csv with all the simulation results.
Draw the Graph using MATLAB
Finally create the following script in MATLAB and name it
mergeGraphs.m and run it to create the graphs in a figure:
% Script to read gmbyId.txt and merge the readings to just 1 graph
% 1st column is taken as Current, 2nd column as Id/(W/L), 3rd column as
% gm/Id
% Remove the 1st 2 lines as the header lines
arr = textread('gmByIdCurves.csv','',-1,'headerlines',2,'headercolumns',0);
figure(1);
for count = 2:3:size(arr,2)
semilogx(arr([1:size(arr,1)],count),arr([1:size(arr,1)],count+1),'r');
hold on;
end
grid on;
xlabel('Id/(W/L)')
ylabel('gm/Id')
title('gm/Id vs Id/(W/L) for 2V NMOS TSMC 0.18\mum RF; 180nm \leq L \leq 10\mum, 2\mum \leq W \leq 20\mum, 0.3V \leq Vgd \leq -0.9V')
Drawing the Graph using gsl-shell
Use the following script. The script can be loaded in gsl-shell using the command dofile('script_path_and_name').
csv = require 'csv'
t=csv.read('MyScripts/gmByIdCurves.csv')
-- Convert it to a 2D numeric array since the csv is space separated and not "," separated
curves = {}
for i = 4,#t do
curves[#curves+1] = {}
for n in string.gmatch(t[i][1],"%S+") do
curves[#curves][#curves[#curves]+1] = tonumber(n)
end
end
-- Now all the data table is in Curves:
-- 1st column is drain current
-- 2nd column is Id/(W/L)
-- 3rd column is gm/Id
-- And it repeats
p = graph.plot()
for i = 2,#curves[1],3 do
-- Create the line here
ln = graph.path(math.log10(curves[1][i]),curves[1][i+1])
for j = 2,#curves do
ln:line_to(math.log10(curves[j][i]),curves[j][i+1])
end
p:addline(ln)
end
p:show()
Sample Graph
Shown below is a sample graph from the above steps:
NOTE This graph was taken with a linear sweep a better graph will result of the sweep is set to logarithmic especially with no discontinuity in the slope as it seems in this one.
References