Code covered by the BSD License  

Highlights from
INTERFACE BETWEEN MATLAB AND CADENCE FOR MACRO-MODEL EXTRACTION

image thumbnail
from INTERFACE BETWEEN MATLAB AND CADENCE FOR MACRO-MODEL EXTRACTION by Philippe BENABES
launch cadence analog simulations from Matlab and extract a macromodel of linear analog functions

filepath_vhd=create_vhdl_model_cdn(vhdl_model_par,model_in_out,multi_in_out,filepath_vhd)
%---------------------------------------------------
% Ce programme est la propriete exclusive de SUPELEC
% Tout  usage  non  authorise  ou reproduction de ce
% programme est strictement defendu.
% Copyright  (c) 2010  SUPELEC  Departement SSE
% Tous droits reserves
%---------------------------------------------------
%
% fichier : create_vhdl_model_cdn.m
% auteur  : P.BENABES & C.TUGUI
% Copyright (c) 2010 SUPELEC
% Revision: 2.0  Date: 29/10/2010
%
%---------------------------------------------------
%
% DESCRIPTION DU MODULE :
%
%
% MODULES UTILISES :
%
%---------------------------------------------------
function filepath_vhd=create_vhdl_model_cdn(vhdl_model_par,model_in_out,multi_in_out,filepath_vhd)
% Create vhdl model starting from extracted characteristics

% Open or create the vhd and the pat file:

if isempty(filepath_vhd)
    filename = strcat('VHDL/Models/', vhdl_model_par.subcell, '_cdn.vhms');
    [file,path] = uiputfile('*.vhms', 'Extract VHDL-AMS Model -> write CADENCE .vhms', filename);
    if (file(1)~=0)&&(path(1)~=0)
        
        filepath_vhd=[path file];
        fid = fopen(filepath_vhd, 'w');
    else
        return
    end
else
    fid = fopen(filepath_vhd, 'w');
end

%Number of outputs
no=vhdl_model_par.numout;

%Create model .vhd file
% Write the first lines:
fprintf(fid, '%s\n', '---------------------------------------');
fprintf(fid, '%s\n', '-- Generated by SIMECT');
fprintf(fid, '%s', '-- Generated on: ');
fprintf(fid, '%s\n', datestr(now));
fprintf(fid, '%s\n', '---------------------------------------');
fprintf(fid, '%s\n', '');
fprintf(fid, '%s\n', 'library ieee, std;');
fprintf(fid, '%s\n', 'use ieee.std_logic_1164.all;');
fprintf(fid, '%s\n', 'USE ieee.electrical_systems.all;');
fprintf(fid, '%s\n', 'use ieee.math_real.all;');
fprintf(fid, '%s\n', 'use work.all;');
fprintf(fid, '%s\n', '');
fprintf(fid, 'ENTITY %s IS\n', vhdl_model_par.subcell);
fprintf(fid, '%s\n', '');

if vhdl_model_par.nlin
    
    
%     fprintf(fid, '%s\n', '  PORT    (TERMINAL P1, P2, N1, N2: ELECTRICAL);');
%     fprintf(fid, '%s\n', '');
%     fprintf(fid, 'END ENTITY %s;\n', vhdl_model_par.subcell);
%     fprintf(fid, '%s\n', '');
%     fprintf(fid, 'ARCHITECTURE behavioral OF %s IS\n', vhdl_model_par.subcell);
%     fprintf(fid, '%s\n', '');
%     
%     fprintf(fid, '%s', '  CONSTANT C0 : REAL := ');
%     fprintf(fid, '%f;\n', multi_in_out.dir_dc.c0);
%     % TBD: import all nonlinear coefficients from multi_in_out
%     
%     fprintf(fid, '%s\n', '');
%     fprintf(fid, '%s\n', '  QUANTITY Vin ACROSS Iin THROUGH ground TO P;');
%     fprintf(fid, '%s\n', '  QUANTITY Vout ACROSS Iout THROUGH ground TO N;');
%     
%     % Models
%     
%     % TBD: implement nonlinear behavior for VCVS CCVS CCCS VCCS
    
else
    
    %Add supply, gnd and other terminals
    
    fprintf(fid, '%s','  PORT    (TERMINAL ');
    
    if vhdl_model_par.gen_sources
        if vhdl_model_par.gen_supply
            fprintf(fid, '%s',[strrep(vhdl_model_par.alim_Vname,'net_','') ',']);
        end
    end
    
    if ~isempty(vhdl_model_par.gnd)
        fprintf(fid, '%s',[strrep(vhdl_model_par.gnd,'net_','') ',']);
    end
    
    for i=1:size(vhdl_model_par.in_Vname,2)
        fprintf(fid, '%s',[strrep(vhdl_model_par.in_Vname{i},'net_','') ',']);
    end
    
    for i=1:size(vhdl_model_par.out_Vname,2)-1
        fprintf(fid, '%s',[strrep(vhdl_model_par.out_Vname{i},'net_','') ',']);
    end
    
    fprintf(fid, '%s\n',  [strrep(vhdl_model_par.out_Vname{size(vhdl_model_par.out_Vname,2)},'net_','') ': ELECTRICAL);']);
    
    fprintf(fid, '%s\n', '');
    fprintf(fid, 'END ENTITY %s;\n', vhdl_model_par.subcell);
    fprintf(fid, '%s\n', '');
    fprintf(fid, 'ARCHITECTURE behavioral OF %s IS\n', vhdl_model_par.subcell);
    fprintf(fid, '%s\n', '');
    
    
    
    
    
    

    % Copy the parameters:

    for i=1:no

            % TFD1
            model_in_out{i}.TF_dir1=decomp_write_tf_vhdl(1,fid,i,'TF_dir1',model_in_out{i}.Num_TF_dir1,model_in_out{i}.Den_TF_dir1,0);                    
            if vhdl_model_par.mode_diff_enabled_out
            % TFD2
            model_in_out{i}.TF_dir2=decomp_write_tf_vhdl(1,fid,i,'TF_dir2',model_in_out{i}.Num_TF_dir2,model_in_out{i}.Den_TF_dir2,0);
            end                   
            if vhdl_model_par.mode_diff_enabled
                % TFD3
                model_in_out{i}.TF_dir3=decomp_write_tf_vhdl(1,fid,i,'TF_dir3',model_in_out{i}.Num_TF_dir3,model_in_out{i}.Den_TF_dir3,0);
                if vhdl_model_par.mode_diff_enabled_out
                    % TFD4
                    model_in_out{i}.TF_dir4=decomp_write_tf_vhdl(1,fid,i,'TF_dir4',model_in_out{i}.Num_TF_dir4,model_in_out{i}.Den_TF_dir4,0);
                end
            end


            if vhdl_model_par.rev_trfunction                       
                    % TFR1
                    model_in_out{i}.TF_inv1=decomp_write_tf_vhdl(1,fid,i,'TF_inv1',model_in_out{i}.Num_TF_inv1,model_in_out{i}.Den_TF_inv1,0);
                if vhdl_model_par.mode_diff_enabled_out
                    % TFR2
                    model_in_out{i}.TF_inv2=decomp_write_tf_vhdl(1,fid,i,'TF_inv2',model_in_out{i}.Num_TF_inv2,model_in_out{i}.Den_TF_inv2,0);
                end    
                if vhdl_model_par.mode_diff_enabled
                   % TFR3
                     model_in_out{i}.TF_inv3=decomp_write_tf_vhdl(1,fid,i,'TF_inv3',model_in_out{i}.Num_TF_inv3,model_in_out{i}.Den_TF_inv3,0);
                    if vhdl_model_par.mode_diff_enabled_out
                        % TFR4
                        model_in_out{i}.TF_inv4=decomp_write_tf_vhdl(1,fid,i,'TF_inv4',model_in_out{i}.Num_TF_inv4,model_in_out{i}.Den_TF_inv4,0);
                    end
                end
            end

            % Zin1
            model_in_out{i}.Zin1=decomp_write_tf_vhdl(1,fid,i,'Zin1',model_in_out{i}.Num_Zin1,model_in_out{i}.Den_Zin1,vhdl_model_par.model_name(1)=='V');

            if vhdl_model_par.mode_diff_enabled
                % Zin2
                model_in_out{i}.Zin2=decomp_write_tf_vhdl(1,fid,i,'Zin2',model_in_out{i}.Num_Zin2,model_in_out{i}.Den_Zin2,vhdl_model_par.model_name(1)=='V');

                % Zin_diff1
                model_in_out{i}.Zin_diff1=decomp_write_tf_vhdl(1,fid,i,'Zin_diff1',model_in_out{i}.Num_Zin_diff1,model_in_out{i}.Den_Zin_diff1,vhdl_model_par.model_name(1)=='V');

                % Zin_diff2
                model_in_out{i}.Zin_diff2=decomp_write_tf_vhdl(1,fid,i,'Zin_diff2',model_in_out{i}.Num_Zin_diff2,model_in_out{i}.Den_Zin_diff2,vhdl_model_par.model_name(1)=='V');
            end

            % Zout1
            model_in_out{i}.Zout1=decomp_write_tf_vhdl(1,fid,i,'Zout1',model_in_out{i}.Num_Zout1,model_in_out{i}.Den_Zout1,vhdl_model_par.model_name(3)=='C');

            if vhdl_model_par.mode_diff_enabled_out
                % Zout2
                model_in_out{i}.Zout2=decomp_write_tf_vhdl(1,fid,i,'Zout2',model_in_out{i}.Num_Zout2,model_in_out{i}.Den_Zout2,vhdl_model_par.model_name(3)=='C');

                % Zout_diff1
                %model_in_out{i}.Zout_diff1=decomp_write_tf_vhdl(1,fid,i,'Zout_diff1',model_in_out{i}.Num_Zout_diff1,model_in_out{i}.Den_Zout_diff1,0);

                % Zout_diff2
                %model_in_out{i}.Zout_diff2=decomp_write_tf_vhdl(1,fid,i,'Zout_diff2',model_in_out{i}.Num_Zout_diff2,model_in_out{i}.Den_Zout_diff2,0);
            end


        % Offsets
        write_vhdl_real(fid, ['Out_' num2str(i) '_' 'OffIn11'],model_in_out{i}.OffIn11);
        write_vhdl_real(fid, ['Out_' num2str(i) '_' 'OffIn12'],model_in_out{i}.OffIn12);

        if vhdl_model_par.mode_diff_enabled
            write_vhdl_real(fid, ['Out_' num2str(i) '_' 'OffIn21'],model_in_out{i}.OffIn21);
            write_vhdl_real(fid, ['Out_' num2str(i) '_' 'OffIn22'],model_in_out{i}.OffIn22);
        end

            write_vhdl_real(fid, ['Out_' num2str(i) '_' 'OffOut11'],model_in_out{i}.OffOut11);
            write_vhdl_real(fid, ['Out_' num2str(i) '_' 'OffOut12'],model_in_out{i}.OffOut12);

        if vhdl_model_par.mode_diff_enabled_out
            write_vhdl_real(fid, ['Out_' num2str(i) '_' 'OffOut21'],model_in_out{i}.OffOut21);
            write_vhdl_real(fid, ['Out_' num2str(i) '_' 'OffOut22'],model_in_out{i}.OffOut22);
        end

    end
            
            
 

    fprintf(fid, '%s\n',[ '  QUANTITY Vin1 ACROSS Iin1 THROUGH ' strrep(vhdl_model_par.in_Vname{1},'net_','') ' TO ground; ']);
    if vhdl_model_par.mode_diff_enabled
        fprintf(fid, '%s\n',[ '  QUANTITY Vin2 ACROSS Iin2 THROUGH ' strrep(vhdl_model_par.in_Vname{2},'net_','') ' TO ground; ']);
    end

    for i=1:no           
        fprintf(fid, '%s\n',[ '  QUANTITY Vout1_' num2str(i) ' ACROSS Iout1_' num2str(i) ' THROUGH ' strrep(vhdl_model_par.out_Vname{2*i-1},'net_','') ' TO ground; ']);
        if vhdl_model_par.mode_diff_enabled_out
            fprintf(fid, '%s\n',[ '  QUANTITY Vout2_' num2str(i) ' ACROSS Iout2_' num2str(i) ' THROUGH ' strrep(vhdl_model_par.out_Vname{2*i},'net_','') ' TO ground; ']);
        end
    end

    if vhdl_model_par.model_name(1)=='V' % V in    
        fprintf(fid, '%s\n', '  QUANTITY deltaVin1: voltage;');
        if vhdl_model_par.mode_diff_enabled
            fprintf(fid, '%s\n', '  QUANTITY deltaVin2: voltage;');
        end               
    else
        fprintf(fid, '%s\n', '  QUANTITY deltaIin1: current;');
        if vhdl_model_par.mode_diff_enabled
            fprintf(fid, '%s\n', '  QUANTITY deltaIin2: current;');
        end
    end
    if vhdl_model_par.model_name(3)=='V' % V in             
        for i=1:no
            fprintf(fid, '%s\n', ['  QUANTITY deltaIout1_' num2str(i) ': current;']);
            if vhdl_model_par.mode_diff_enabled_out
                fprintf(fid, '%s\n', ['  QUANTITY deltaIout2_' num2str(i) ': current;']);
            end
        end
    else
         for i=1:no
            fprintf(fid, '%s\n', ['  QUANTITY deltaVout1_' num2str(i) ': voltage;']);
            if vhdl_model_par.mode_diff_enabled_out
                fprintf(fid, '%s\n', ['  QUANTITY deltaVout2_' num2str(i) ': voltage;']);
            end
         end
    end

    fprintf(fid, '%s\n', '');
    fprintf(fid, '%s\n', 'BEGIN');
    fprintf(fid, '%s\n', '');


    if vhdl_model_par.model_name(1)=='V' % V in                
        fprintf(fid, '%s\n', '  deltaVin1 == Vin1 - Out_1_OffIn11;');
        if vhdl_model_par.mode_diff_enabled
            fprintf(fid, '%s\n', '  deltaVin2 == Vin2 - Out_1_OffIn21;');
        end
    else
        fprintf(fid, '%s\n', '  deltaIin1 == Iin1 - Out_1_OffIn11;');
        if vhdl_model_par.mode_diff_enabled
            fprintf(fid, '%s\n', '  deltaIin2 == Iin2 - Out_1_OffIn21;');
        end
    end

    if vhdl_model_par.model_name(3)=='V' % V out                
        for i=1:no
            fprintf(fid, '%s\n', ['  deltaIout1_' num2str(i) ' == Iout1_' num2str(i) ' - Out_' num2str(i) '_' 'OffOut12;']);
            if vhdl_model_par.mode_diff_enabled_out
                fprintf(fid, '%s\n', ['  deltaIout2_' num2str(i) ' == Iout2_' num2str(i) ' - Out_' num2str(i) '_' 'OffOut22;']);
            end
        end
    else
        for i=1:no
            fprintf(fid, '%s\n', ['  deltaVout1_' num2str(i) ' == Vout1_' num2str(i) ' - Out_' num2str(i) '_' 'OffOut12;']);
            if vhdl_model_par.mode_diff_enabled_out
                fprintf(fid, '%s\n', ['  deltaVout2_' num2str(i) ' == Vout2_' num2str(i) ' - Out_' num2str(i) '_' 'OffOut22;']);
            end
        end
    end

    for i=1:no
        if vhdl_model_par.model_name(3)=='V' % V out                
            fprintf(fid, '%s\n',[ '  Vout1_' num2str(i) ' ==']);
        else
            fprintf(fid, '%s\n',[ '  Iout1_' num2str(i) ' ==']);
        end
        if vhdl_model_par.model_name(1)=='V' % V in                
            fprintf(fid, '%s\n',[ ' deltaVin1' vhdl_tr_decomp(1,i,model_in_out{i},'Num_TF_dir1','Den_TF_dir1') ]);
        else
            fprintf(fid, '%s\n',[ ' deltaIin1' vhdl_tr_decomp(1,i,model_in_out{i},'Num_TF_dir1','Den_TF_dir1') ]);
        end
        if vhdl_model_par.mode_diff_enabled
            if vhdl_model_par.model_name(1)=='V' % V in                
                fprintf(fid, '%s\n',[ ' + deltaVin2' vhdl_tr_decomp(1,i,model_in_out{i},'Num_TF_dir3','Den_TF_dir3') ]);
            else
                fprintf(fid, '%s\n',[ ' + deltaIin2' vhdl_tr_decomp(1,i,model_in_out{i},'Num_TF_dir3','Den_TF_dir3') ]);
            end
        end
        if vhdl_model_par.model_name(3)=='V' % V out                
            fprintf(fid, '%s\n',[ ' + deltaIout1_' num2str(i) vhdl_tr_decomp(1,i,model_in_out{i},'Num_Zout1','Den_Zout1') ]);
        else
            fprintf(fid, '%s\n',[ ' + deltaVout1_' num2str(i) vhdl_tr_decomp(1,i,model_in_out{i},'Den_Zout1','Num_Zout1') ]);
        end
        fprintf(fid, '%s\n',[ ' + Out_' num2str(i) '_' 'OffOut11;']);

        if vhdl_model_par.mode_diff_enabled_out

            if vhdl_model_par.model_name(3)=='V' % V out                
                fprintf(fid, '%s\n',[ '  Vout2_' num2str(i) ' ==']);
            else
                fprintf(fid, '%s\n',[ '  Iout2_' num2str(i) ' ==']);
            end
            if vhdl_model_par.model_name(1)=='V' % V in                
                fprintf(fid, '%s\n',[ ' deltaVin1' vhdl_tr_decomp(1,i,model_in_out{i},'Num_TF_dir2','Den_TF_dir2') ]);
            else
                fprintf(fid, '%s\n',[ ' deltaIin1' vhdl_tr_decomp(1,i,model_in_out{i},'Num_TF_dir2','Den_TF_dir2') ]);
            end
            if vhdl_model_par.mode_diff_enabled
                if vhdl_model_par.model_name(1)=='V' % V in                
                    fprintf(fid, '%s\n',[ ' + deltaVin2' vhdl_tr_decomp(1,i,model_in_out{i},'Num_TF_dir4','Den_TF_dir4') ]);
                else
                    fprintf(fid, '%s\n',[ ' + deltaIin2' vhdl_tr_decomp(1,i,model_in_out{i},'Num_TF_dir4','Den_TF_dir4') ]);
                end
            end
            if vhdl_model_par.model_name(3)=='V' % V out                
                fprintf(fid, '%s\n',[ ' + deltaIout2_' num2str(i) vhdl_tr_decomp(1,i,model_in_out{i},'Num_Zout2','Den_Zout2') ]);
            else
                fprintf(fid, '%s\n',[ ' + deltaVout2_' num2str(i) vhdl_tr_decomp(1,i,model_in_out{i},'Den_Zout2','Num_Zout2') ]);
            end
            fprintf(fid, '%s\n',[ ' + Out_' num2str(i) '_' 'OffOut21;']);

        end

     end

    if vhdl_model_par.model_name(1)=='V' % V in                
        fprintf(fid, '%s',[ '  Iin1 == deltaVin1' vhdl_tr_decomp(1,1,model_in_out{1},'Den_Zin1','Num_Zin1') ]);    
        if vhdl_model_par.mode_diff_enabled
            fprintf(fid, '%s',[ '+ deltaVin2' vhdl_tr_decomp(1,1,model_in_out{1},'Den_Zin_diff2','Num_Zin_diff2')]); 
        end
    else
        fprintf(fid, '%s',[ '  Vin1 == deltaIin1' vhdl_tr_decomp(1,1,model_in_out{1},'Num_Zin1','Den_Zin1') ]);    
        if vhdl_model_par.mode_diff_enabled
            fprintf(fid, '%s',[ '+ deltaIin2' vhdl_tr_decomp(1,1,model_in_out{1},'Num_Zin_diff1','Den_Zin_diff1')]); 
        end
    end
    if vhdl_model_par.rev_trfunction
        for i=1:no
            if vhdl_model_par.model_name(3)=='V' % V out                                       
                fprintf(fid, '%s',[ '+ deltaIout1_' num2str(i) vhdl_tr_decomp(1,i,model_in_out{i},'Num_TF_inv1','Den_TF_inv1') ]);
                if vhdl_model_par.mode_diff_enabled_out
                    fprintf(fid, '%s',[ '+ deltaIout2_' num2str(i) vhdl_tr_decomp(1,i,model_in_out{i},'Num_TF_inv2','Den_TF_inv2') ]);
                end
            else
                fprintf(fid, '%s',[ '+ deltaVout1_' num2str(i) vhdl_tr_decomp(1,i,model_in_out{i},'Num_TF_inv1','Den_TF_inv1') ]);
                if vhdl_model_par.mode_diff_enabled_out
                    fprintf(fid, '%s',[ '+ deltaVout2_' num2str(i) vhdl_tr_decomp(1,i,model_in_out{i},'Num_TF_inv2','Den_TF_inv2') ]);
                end
            end
        end      
    end
    fprintf(fid, '%s\n','+ Out_1_OffIn12;');

    if vhdl_model_par.mode_diff_enabled

        if vhdl_model_par.model_name(1)=='V' % V in                
            fprintf(fid, '%s',[ '  Iin2 == deltaVin2' vhdl_tr_decomp(1,1,model_in_out{1},'Den_Zin2','Num_Zin2') ]);    
            if vhdl_model_par.mode_diff_enabled
                fprintf(fid, '%s',[ '+ deltaVin1' vhdl_tr_decomp(1,1,model_in_out{1},'Den_Zin_diff1','Num_Zin_diff1')]); 
            end
        else
            fprintf(fid, '%s',[ '  Vin2 == deltaIin2' vhdl_tr_decomp(1,1,model_in_out{1},'Num_Zin2','Den_Zin2') ]);    
            if vhdl_model_par.mode_diff_enabled
                fprintf(fid, '%s',[ '+ deltaIin1' vhdl_tr_decomp(1,1,model_in_out{1},'Num_Zin_diff1','Den_Zin_diff1')]); 
            end
        end
        if vhdl_model_par.rev_trfunction
            for i=1:no
                if vhdl_model_par.model_name(3)=='V' % V out                                       
                    fprintf(fid, '%s',[ '+ deltaIout1_' num2str(i) vhdl_tr_decomp(1,i,model_in_out{i},'Num_TF_inv3','Den_TF_inv3') ]);
                    if vhdl_model_par.mode_diff_enabled_out
                        fprintf(fid, '%s',[ '+ deltaIout2_' num2str(i) vhdl_tr_decomp(1,i,model_in_out{i},'Num_TF_inv4','Den_TF_inv4') ]);
                    end
                else
                    fprintf(fid, '%s',[ '+ deltaVout1_' num2str(i) vhdl_tr_decomp(1,i,model_in_out{i},'Num_TF_inv3','Den_TF_inv3') ]);
                    if vhdl_model_par.mode_diff_enabled_out
                        fprintf(fid, '%s',[ '+ deltaVout2_' num2str(i) vhdl_tr_decomp(1,i,model_in_out{i},'Num_TF_inv4','Den_TF_inv4') ]);
                    end
                end
            end      
        end
        fprintf(fid, '%s\n','+ Out_1_OffIn22;');
    end


    fprintf(fid, '%s\n', '');
    fprintf(fid, '%s\n', 'END ARCHITECTURE behavioral;');
    fprintf(fid, '%s\n', '');
      
    
end

fclose(fid);

msgbox('Successfuly exported CADENCE VHDL-AMS model!','Export','help');
edit(filepath_vhd);


end

Contact us at files@mathworks.com