Product Documentation
Real Number Modeling Guide
Product Version 22.09, September 2022

Wreal Connections to the Electrical Domain

In connections between wreal and electrical, the E2R, R2E_2, and ER_bidir connect modules (CM) are inserted automatically, if needed, during the elaboration process.

The current connect modules are shown below. The source file can be found in the Xcelium release in <install_path>/tools/affirma_ams/etc/connect_lib/. The Real to Electrical (R2E) CM implementation is relatively straightforward. The newly introduced X and Z states are taken into account. The input wreal value is assigned to a voltage source with serial resistance. Transition operators help to avoid abrupt changes in the behavior that might convergence issues in the analog solver.

// R2E_2.vams - Efficient Verilog-AMS discrete wreal to
// electrical connection module

`include "disciplines.vams"
`timescale 1ns / 1ps

connectmodule R2E_2 (Din, Aout);
  input Din;
  wreal Din;                        // input wreal
  \logic Din;
  output Aout;
  electrical Aout;               // output electrical

  parameter real vss=0             from (-inf:inf); // Voltage of negative supply
  parameter real vsup=1.8          from (0:inf);    // supply voltage based on vss
  parameter real vdelta=vsup/64    from (0:vsup];   // voltage delta
  parameter real vx=vss            from [0:vsup];   // X output voltage
  parameter real tr=10p            from (0:inf);    // risetime of analog output
  parameter real tf=tr             from (0:inf);    // falltime of analog output
  parameter real ttol_t=(tr+tf)/20 from (0:inf);    // time tol of transition
  parameter real tdelay=0          from [0:1m);     // delay time of analog output
  parameter real rout=200          from (0:inf);    // output resistance
  parameter real rx=rout           from (0:inf);    // X output resistance
  parameter real rz=10M            from (0:inf);    // Z output resistance
  parameter integer currentmode=0  from [-1:1];     // 0:voltage 1:forward -1:backward
  parameter real idelta=10u        from (0:inf);    // current delta
  parameter real ix=0              from [0:inf);    // X output current
  parameter real i0=0              from [0:inf);    // 0 output current
  parameter integer clamp=0        from [0:1];      // 0: disable, 1: enable clamp
  parameter real dvclamp=vsup/20   from (0:vsup/2); // clamp zoon from supply
  parameter integer idealmode=0    from [0:1];      // ideal supply mode
  parameter real vdd=vss+vsup;               // internal parameter: vss+vsup
  parameter real vdd10=vdd+vsup*10;          // internal parameter: vdd+vsup*10
  parameter real vss10=vss-vsup*10;          // internal parameter: vss-vsup*10
  parameter integer debug=0        from [0:1];     // 1: enable debug features
  parameter real vinlimit=vsup*4/3 from [0:inf);  // input signal limit

  real RealN, Rstate;
  real RealA;                          //analog value converted from wreal
  real VprevA;                         //voltage at previous analog-step
  real Rout;                           //impedence converted from wreal driver
  wreal R_val;
  reg sie;

//debug feature variabless:
 real (*integer mn_browser_default="1"; integer mn_broswer_description=
     "Number of d2a events of any logic toggling from the digital port"; *)
   num_d2a_events=0;
 real (*integer mn_browser_default="1"; integer mn_broswer_description=
     "Number of a2d events of any logic toggling to the digital port"; *)
   num_a2d_events=0;    
 reg   (*integer mn_browser_default="1"; integer mn_broswer_description=
     "Flag to 1 once the analog port signal voltage has exceeded vinlimit, vsup*4/3 by default"; *)
   vin_exceeded_limit = 0;
 real num_d2a_x_events=0;     // Number of d2a events of logic X
 real num_d2a_z_events=0;     // Number of d2a events of logic Z

  initial begin
    if (Din === `wrealXState)
      begin RealN = currentmode ? (currentmode*ix) : vx; Rstate = rx; end
    else if (Din === `wrealZState)
      begin RealN = currentmode ? (currentmode*i0) : vss; Rstate = rz; end
    else
      begin RealN = Din; Rstate = rout; end
    sie = $SIE_input(Din, R_val);
  end

  always begin
    if (Din === `wrealXState) begin
        if (debug) begin num_d2a_events=num_d2a_events+1; num_d2a_x_events=num_d2a_x_events+1; end
        RealN = currentmode ? (currentmode*ix) : vx; Rstate = rx; end
    else if (Din === `wrealZState) begin
        if (debug) begin num_d2a_events=num_d2a_events+1; num_d2a_z_events=num_d2a_z_events+1; end
        Rstate = rz;            //in voltage mode, Z means float, so Rout is rz
        if (currentmode) RealN = currentmode*i0;  //in current mode, Z means open circuit, so I=i0
      end
    else begin

      Rstate = rout;
      if ( currentmode && abs(Din-RealN) >= idelta ) begin
            RealN = currentmode*Din; if (debug) num_d2a_events=num_d2a_events+1; end
      else if ( currentmode==0 && abs(Din-RealN) >= vdelta ) begin
            RealN = Din; if (debug) num_d2a_events=num_d2a_events+1; end
    end
    @(Din);
  end

  assign Din = $drs_driver(Din);
  analog initial VprevA = vss;
  analog begin
    RealA = transition(RealN, tdelay, tr, tf, ttol_t);
    Rout = transition(Rstate, tdelay, tr, tf, ttol_t);
    if (currentmode) begin
      if (RealA > 0) begin
        if (clamp) begin
          if (V(Aout) > vdd - dvclamp) begin
            if (VprevA < vdd - dvclamp)
              $display("Warning: AMS IE %M at %g: wreal Din=%g is causing V(Aout)=%g being clamped near vdd. Please check for any mismatch between the electrical circuit and the R2E",
                $abstime, RealN, V(Aout));
            VprevA = V(Aout);
            RealA = RealA * (vdd - V(Aout)) / dvclamp;
          end
        end else begin

          if (V(Aout) > vdd10 ) begin
            if (VprevA < vdd10 )
              $display("Warning: AMS IE %M at %g: wreal Din=%g is causing V(Aout)=%g being 10x vsup above vdd. Please check for any mismatch between the electrical circuit and the 2E",
                $abstime, RealN, V(Aout));
            VprevA = V(Aout);
          end
        end
      end else begin

        if (clamp) begin
          if ( V(Aout) < vss + dvclamp ) begin
            if ( VprevA > vss + dvclamp )
              $display("Warning: AMS IE %M at %g: wreal Din=%g is causing V(Aout)=%g being clamped near vss. Please check for any mismatch between the electrical circuit and the R2E",
               $abstime, RealN, V(Aout));
            VprevA = V(Aout);
            RealA = RealA * (V(Aout) - vss) / dvclamp;
          end
        end else begin

          if ( V(Aout) < vss10 ) begin
            if ( VprevA > vss10 )
              $display("Warning: AMS IE %M at %g: wreal Din=%g is causing V(Aout)=%g being 10x vsup below vss. Please check for any mismatch between the electrical circuit and the R2E",
               $abstime, RealN, V(Aout));
            VprevA = V(Aout);
          end
        end
      end

      I(Aout) <+ -RealA + V(Aout)/rz;
    end else if (idealmode) begin
      V(Aout) <+ RealA;
    end else begin
      I(Aout) <+ (V(Aout) - RealA) / Rout;
    end
  end
endmodule

In contrast to the R2E, the E2R (Electrical to Real) operation is not so obvious because the continuous analog value needs to be translated into an event-based wreal signal. For this purpose, a new system function, absdelta is available, which creates events based on input value changes. The absdelta function generates events for the following times and conditions:

(absdelta ( expr, delta [ , time_tol [ , expr_tol ]]):

In the CM below, the absdelta function issues an event and updates the wreal value whenever V(Ain) changes more than the value vdelta.

// E2R.vams - basic Verilog-AMS electrical to discrete wreal connection module
// last revised:  08/01/06, jhou
//
// REVISION HISTORY:
// Created:  08/01/06, jhou

`include "disciplines.vams"
`timescale 1ns / 100ps

connectmodule E2R (Ain, Dout);
input Ain;
electrical Ain;   //input electrical
output Dout;
wreal Dout;   //output wreal
\logic Dout;   //discrete domain

parameter real vdelta=1.8/64 from (0:inf);
// voltage delta
parameter real vtol=vdelta/4 from (0:vdelta);
// voltage tolerance
parameter real ttol=10p from (0:1m];
// time tolerance

real Dreg;      //real register for A to D wreal conversion
assign Dout = Dreg;
//discretize V(Ain) triggered by absdelta function
  always @(absdelta(V(Ain), vdelta, ttol, vtol))
  Dreg = V(Ain);
endmodule

The proper setting of the CM parameters is critical for correct simulation results. While the supply voltage level mainly influences the electrical to logic connection thresholds, the E2R settings can be totally independent of the supply voltage. For example, if an electrical 5mV bias voltage is passed into a wreal block, a good setting for a vdelta parameter might be 100uV, independent of what the supply voltage is.

Also, consider the default resistance in the R2E CM. If a wreal net is connected to an electrical part that consumes significant current (for example, power net) the 200-Ohm default resistance of the R2E CM might have an unwanted influence on the signal level.

The following example shows a simple connection between electrical and wreal. The E2R connect module is inserted automatically. The connect rule definition at the end of the file defines the parameters for the connect modules.

// run with:
// xrun cm.vams cm.scs -clean -amsconnrules e2r_only
//   -discipline logic
`include "disciplines.vams"
`timescale 1ns / 1ps

module top();
  wreal real_wire;
  source I1 (real_wire);
  sink I3 (real_wire);
endmodule

module source(r);
  output r;
  electrical r;
  analog begin
    V(r) <+ sin($abstime * 1E4);
    $bound_step(1e-5); // limit the step size
  end
endmodule // source

module sink(r);
  input r;
  wreal r;
  always @(r) begin
    $display(" real value = %f", r);
  end
endmodule

connectrules e2r_only;
  connect E2R
    #( .vdelta(0.1), .vtol(0.001), .ttol(1n));
  Endconnectrules

And, the analog.scs file contains the following statements:

simulator lang=spectre
tran1 tran stop=1ms




 ⠀
X