• Skip to main content
  • Skip to search
  • Skip to footer
Cadence Home
  • This search text may be transcribed, used, stored, or accessed by our third-party service providers per our Cookie Policy and Privacy Policy.

  1. Community Forums
  2. Custom IC Design
  3. Fatal error found by spectre during topology check.

Stats

  • Locked Locked
  • Replies 9
  • Subscribers 125
  • Views 13300
  • Members are here 0
This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Fatal error found by spectre during topology check.

Aswathyn
Aswathyn over 3 years ago

I am trying to build verilogA code of MTJ in cadence. I got the following error. I am new to cadence . please help me to eliminate the error . 

Fatal error found by spectre during topology check.
FATAL: The following branches form a loop of rigid branches (shorts) when added to the circuit:
I1:mz_flow (from net012 to 0)
I1:my_flow (from net14 to 0)
I1:mx_flow (from net13 to 0)

the schematic used is given below

  • Cancel
  • Andrew Beckett
    Andrew Beckett over 3 years ago

    There's no chance of debugging this without seeing:

    1. The Verilog-A code for MTJ . I assume this is a "Magnetic Tunnel Junction" but that's a bit of a guess; you might want to expand when using unusual acronyms. That said, even knowing that wouldn't help without seeing the code
    2. What's inside the Initial block too - is that Verilog-A?

    It suggests that both have a voltage source (or a current probe) and for each of the mx, my,mz pins and hence you've got two voltage sources in parallel, which leads to something that cannot be solved (it's impossible to solve the simultaneous equations when you have two ideal voltage sources cannot be in parallel).

    Regards,

    Andrew

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
  • Aswathyn
    Aswathyn over 3 years ago in reply to Andrew Beckett

    Fullscreen initial (1).txt Download
    // VerilogA for Betty_Jan2018, Initial, veriloga
    
    `include "constants.vams"
    `include "disciplines.vams"
    
    module Initial(x,y,z);
    
    //VerilogA code to set the initial state of magnetization vector:
    electrical x,y,z;
    integer seed;
    real RandomTheta, volume, std_dev;
    parameter real kb = 1.38e-16 from (-inf:inf);//Boltzmann’s constant
    parameter T = 300 from (-inf:inf);//Temperature
    parameter real Ms = 1050 from (0:inf);
    parameter real Hk = 250 from (0:inf);
    parameter real length = 60e-7 from (0:inf);
    parameter real width = 60e-7 from (0:inf);
    parameter real thickness = 1e-7 from (0:inf);
    analog begin
    volume = length*width*thickness;
    std_dev=sqrt(kb*T/(Ms*volume*Hk));//standard deviation of theta
    if(analysis("ic"))
    begin
    //This defines the initial conditions for the magnetization vector
    //fixed
    /*V(x) <+ 0;
    V(y) <+ 0.3;
    V(z) <+ sqrt(1 - 0.3*0.3);*/
    //random
    seed=4;
    RandomTheta=$rdist_normal(seed, 0, std_dev);
    V(x) <+ 0.2;//0;
    V(y) <+ 0.45;//sin(RandomTheta);
    V(z) <+ 0.65;//cos(RandomTheta);
    end
    else if(analysis("tran")) begin
    end
    end
    endmodule
    
    

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
  • Aswathyn
    Aswathyn over 3 years ago in reply to Aswathyn

    Fullscreen mtj_model (1).txt Download
    // VerilogA for Betty_Jan2018, MTJ, veriloga
    
    `include "constants.vams"
    `include "disciplines.vams"
    
    module MTJ_Model(pos, neutral, neg, mx, my, mz);
    //terminal definitions
    inout pos,neutral,neg, mx, my, mz;
    electrical pos,neutral,neg;
    electrical mx, my, mz;
    branch (pos, neutral) top;
    branch (neutral, neg) bott;
    // variables
    real top_res0, top_res, bott_res0, bott_res, net_torque,polarization_top, polarization_bott, top_efficiency, bottom_efficiency,
    volume, rpar_top, rpar_bott, RandomGaussian, Hfluctuation;
    integer seed;
    // LLG equation coefficients
    real h1, h2, h3, k1, k2, k3, s1, s2, s3;
    // model parameters
    parameter integer use_as_dmtj = 1 from (-2:2);
    parameter real plank_constant = 1.054e-27 from (-inf:inf);
    parameter real electron_charge = 1.602e-19 from (-inf:inf);
    parameter real gyromagnetic_ratio = 1.7608e7 from (-inf:inf);
    parameter real alpha = 0.002 from (0:inf);
    parameter real Ms = 1050 from (0:inf);
    parameter real Hk = 250 from (0:inf);
    parameter real Vh = 0.5 from (0:inf);
    parameter real Rp = 1500 from (0:inf);
    parameter real tmr = 2 from (0:inf);
    parameter real length = 60e-7 /*60e-7*/ from (0:inf);
    parameter real width = 60e-7 from (0:inf);
    parameter real thickness = 1e-7 from (0:inf);
    parameter real tox = 1.2e-9 from (0:inf);
    parameter real kb = 1.38e-16 from (-inf:inf);//Boltzmann’s constant
    parameter T = 300 from (-inf:inf);//Temperature
    parameter real PI = 3.14 from (0:inf);
    // model analog block
    analog begin
    volume = length*width*thickness;
    k1 = -1*gyromagnetic_ratio/(1 + pow(alpha,2));
    k2 = -1*gyromagnetic_ratio*alpha/(1 + pow(alpha,2));
    k3 = gyromagnetic_ratio*plank_constant/(2*electron_charge*Ms*volume);
    //conventional STT source (PL with easy axis parallel to FL)
    s1 = 0;
    s2 = 0;
    s3 = 1;
    rpar_top = 2*Rp*(tmr + 1 + V(top)*V(top)/(Vh*Vh))/(tmr + 2*(1 + (V(top)*V(top))/(Vh*Vh)));
    rpar_bott = 2*Rp*(tmr + 1 + V(bott)*V(bott)/(Vh*Vh))/(tmr + 2*(1 + (V(bott)*V(bott))/(Vh*Vh)));
    
    polarization_top = sqrt(tmr/(tmr + 2*(1 +V(top)*V(top)/(Vh*Vh))));
    polarization_bott = sqrt(tmr/(tmr + 2*(1 + V(bott)*V(bott)/(Vh*Vh))));
    top_efficiency = polarization_top/(2*(1 + pow(polarization_top,2)*V(mz)));
    bottom_efficiency = polarization_bott/(2*(1 + pow(polarization_bott,2)*V(mz)));
    top_res = rpar_top/(1 + polarization_top*polarization_top*V(mz));
    bott_res = 0;
    net_torque = I(top)*top_efficiency;
    //Heff=Heff+Hfluctuation
    seed=25;
    RandomGaussian=$rdist_normal(seed, 0, 1);
    Hfluctuation=sqrt(2*alpha*kb*T/(gyromagnetic_ratio*Ms*volume))*RandomGaussian;
    h1= -4*PI*Ms*V(mx)+Hfluctuation;
    h2 = 0+Hfluctuation;
    h3 = Hk*V(mz)+Hfluctuation;
    if(analysis("ic"))
    begin
    end
    else if(analysis("tran")) begin
    V(mx):
    ddt(V(mx)) == k1*(h3*V(my) - h2*V(mz)) + k2*(-h1*V(my)*V(my)- h1*V(mz)*V(mz) + h2*V(mx)*V(my) + h3*V(mx)*V(mz))+k3*net_torque*(-s1*V(my)*V(my) -s1*V(mz)*V(mz) + s2*V(mx)*V(my)+ s3*V(mx)*V(mz));
    V(my):
    ddt(V(my)) == k1*(h1*V(mz) - h3*V(mx))+ k2*(h1*V(mx)*V(my)- h2*V(mx)*V(mx) - h2*V(mz)*V(mz) + h3*V(my)*V(mz)) +k3*net_torque*(s1*V(mx)*V(my) - s2*V(mx)*V(mx) - s2*V(mz)*V(mz)+ s3*V(my)*V(mz));
    V(mz):
    ddt(V(mz)) == k1*(h2*V(mx) -h1*V(my))+ k2*(h1*V(mx)*V(mz)+ h2*V(my)*V(mz) -h3*V(mx)*V(mx) - h3*V(my)*V(my))+k3*net_torque*(s1*V(mx)*V(mz) + s2*V(my)*V(mz) - s3*V(mx)*V(mx)- s3*V(my)*V(my));
    end
    V(top) <+ I(top)*top_res;
    V(bott) <+ I(bott)*bott_res;
    end
    
    endmodule
    

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
  • Aswathyn
    Aswathyn over 3 years ago

    Please find the attached verilogA code of two modules and help me to solve the error

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
  • Andrew Beckett
    Andrew Beckett over 3 years ago in reply to Aswathyn

    OK, the issue is that you have indirect branch assignments in the MTJ_model block:

    V(mx):
    ddt(V(mx)) == k1*(h3*V(my) - h2*V(mz)) + k2*(-h1*V(my)*V(my)- h1*V(mz)*V(mz) + h2*V(mx)*V(my) + h3*V(mx)*V(mz))+k3*net_torque*(-s1*V(my)*V(my) -s1*V(mz)*V(mz) + s2*V(mx)*V(my)+ s3*V(mx)*V(mz));

    (similar expressions for my and mz), and then the Initial block has some voltage sources:

    V(x) <+ 0.2;//0;

    These are in conditional blocks based on the analysis (which is a dubious modelling practice and potentially dangerous because the behaviour might be different). The indirect branch assignments will be creating voltage sources on mx, my and mz - and so the simulator sees these as potentially in parallel. In practice, because of the condition they are not in parallel - the Initial module only has the sources when in the "ic" analysis, and the MTJ module only has the sources when in the "tran" analysis. So you could workaround this by changing the analog begin in the Initial module to:

    (* no_rigid_switch_branch *) analog begin

    which turns off the check for switch branches (this is sort of a multi-module switch branch).

    However I would question whether this is a particularly good way of implementing the model. You might want to look at this again and decide whether there is a better way of setting up the initial conditions. Maybe have the indirect branch assignments there all the time, and use initial conditions in the simulator (which are handled via a 1ohm resistor to avoid the rigid loops) rather than using this Initial block?

    Regards,

    Andrew

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
  • Aswathyn
    Aswathyn over 3 years ago in reply to Andrew Beckett

    sir, when i tried as per your suggestion by putting the code before analog begin the error report got is attached . please find the attachment error_2.docx

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
  • Andrew Beckett
    Andrew Beckett over 3 years ago in reply to Aswathyn

    I checked in the same version of Spectre that you're using, and don't see that error. The error you're seeing is exactly what would happen if you have two voltage sources in parallel (the loop of rigid branches that the check normally performs, and that this attribute is disabling). With the attribute on the analog line, no check for a loop of rigid branches is performed, and so parallel voltage sources will lead to a singularity and that's what you're seeing.

    I suspect you've changed the conditions in the code so that there is a time when both sources are enabled. For me (because the Initial block as them enabled during the "ic" analysis, and MTJ block has them in "tran" analysis) they are never in parallel at the same time.

    Did you change something else as well? Maybe by mistake?

    Andrew 

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
  • Aswathyn
    Aswathyn over 3 years ago in reply to Andrew Beckett

    yes sir, i made a small mistake in code. when i remove that transient working. but the output of MTJ is shown  as 

    in the graph. it is only 100mv. normally around 1v should be there to indicate high state. any information regarding this . 

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
  • Andrew Beckett
    Andrew Beckett over 3 years ago in reply to Aswathyn

    Sorry, I can't debug your code for you - I don't know what it's supposed to be doing, and my quick tests showed different (and rather strange behaviour) - the model looks pretty unstable to me.

    Andrew

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel

Community Guidelines

The Cadence Design Communities support Cadence users and technologists interacting to exchange ideas, news, technical information, and best practices to solve problems and get the most from Cadence technology. The community is open to everyone, and to provide the most value, we require participants to follow our Community Guidelines that facilitate a quality exchange of ideas and information. By accessing, contributing, using or downloading any materials from the site, you agree to be bound by the full Community Guidelines.

© 2025 Cadence Design Systems, Inc. All Rights Reserved.

  • Terms of Use
  • Privacy
  • Cookie Policy
  • US Trademarks
  • Do Not Sell or Share My Personal Information