void init_dislin(Dislin& g) {

	g.metafl ("cons");
	g.scrmod ("revers");
	g.disini ();
	g.pagera ();
	g.complx ();
	g.axspos (450, 1800);
	g.axslen (2200, 1200);

	g.name   ("X-axis", "x");
	g.name   ("Y-axis", "y");

	g.labdig (-1, "x");
	g.ticks  (9, "x");
	g.ticks  (10, "y");

	g.titlin ("Energy over generations", 1);
	g.titlin ("Energy", 3);

	int ic = g.intrgb (0.95,0.95,0.95);
	g.axsbgd (ic);

	//g.graf   (0.0, 360.0, 0.0, 90.0, -1.0, 1.0, -1.0, 0.5);
	g.setrgb (0.7, 0.7, 0.7);
	g.grid   (1, 1);

	g.color  ("fore");
	g.height (50);
	g.title  ();
}
Exemple #2
0
void myplot (int id)
{ string ctitle;
  int isel;
  double xa, xe, xorg, xstp, ya, ye, yorg, ystp;

  if (id != id_but) return;    /* Dummy statement */

  xa = -180.;
  xe = 180.;
  xorg = -180.;
  xstp = 60.;

  ya =  -90.; 
  ye =  90.;
  yorg =  -90.;
  ystp = 30.;

  isel = g.gwglis (id_lis);
  g.setxid (id_draw, "widget");
  g.metafl ("xwin");
  g.disini ();
  g.erase  ();
  g.hwfont ();

  if (isel >=4 && isel <= 7) 
    g.noclip ();
  else if (isel == 2)
  { ya = -85;
    ye = 85;
    yorg = -60;
  }
  else if (isel >= 8 && isel <= 10)
  { ya = 0;
    ye = 90;
    yorg = 0;
  }

  g.labdig (-1, "xy");
  g.name ("Longitude", "x");
  g.name ("Latitude", "y");

  g.projct (cl2[isel-1].c_str ());
  g.htitle (50);
  ctitle = cl1[isel-1];
  ctitle += " Projection";

  g.titlin (ctitle. c_str (), 3);
  g.grafmp (xa, xe, xorg, xstp, ya, ye, yorg, ystp);
  g.title  ();
  g.gridmp (1,1);
  g.color  ("green");
  g.world  ();
  g.errmod ("protocol", "off");
  g.disfin ();
}
int main( int argc, char *argv[], char *env[] )
{
  Verilated::commandArgs( argc, argv );
  top = new Vbldc_mcasic_enc;
  top->clk = 0;
  top->eval();

  Dislin g;

  g.itmstr( "Yes!", 1 );  

  g.metafl( "CONS" );
  g.setpag( "da4l" ); // Page format

  static const double power_supply_voltage = 12.0; // [V]
  
  // TODO: Need to account for rounded off encoder counts in HDL.
  static const int rotor_pole_pair_cnt = 6;
  static const int enc_lpr = 334; // [lines/rev]
  
  top->period = ( enc_lpr << 2 ) / rotor_pole_pair_cnt;
  printf( "Electrical commutation period: %d eu\n", top->period );

  static const double sqrt3 = sqrt( 3.0 );
  static const double enc_res = 2.0 * M_PI / (double)( enc_lpr << 2 ); // [rad/eu]
  printf( "Encoder resolution: %.6f rad/eu.\n", enc_res );
  
  static const double dt = 1 / 50E6; // [sec]
  static const double tmax = 0.2; // [sec]
  static const int step_max = tmax / dt + 1;
  printf( "Step max: %d\n", step_max );

  static double A[step_max];
  static double B[step_max];
  
  // Keep these out of the stack by making them static.
  static double t[step_max]; // [sec]
  static double stator_phase[step_max];
  static double rotor_phase[step_max];
  static double mtr_phase[step_max];
  static double mtr_vel[step_max];
  
  static double winding_voltage[3][step_max];
  
  top->clk = 0;
  top->pwm = 1024;
  top->A = 0;
  top->B = 0;
  top->eval();

  typedef struct
  {
    int A;
    int B;
  } quad_state_t;
  static const quad_state_t quad_state_arr[] =
  {
   // A, B
    { 0, 0 },
    { 1, 0 },
    { 1, 1 },
    { 0, 1 },
  };
  static const int quad_state_cnt
    = sizeof( quad_state_arr ) / sizeof( quad_state_arr[0] );
  static int quad_state_idx = 0;
  static double enc_line_phase = 0.0; // [rad] Position of last quadrature state change.
  
  A[0] = quad_state_arr[quad_state_idx].A;
  B[0] = quad_state_arr[quad_state_idx].B; 
  
  t[0] = 0.0;
  stator_phase[0] = 0.0;
  rotor_phase[0] = 0.0;
  mtr_phase[0] = 0.0;
  mtr_vel[0] = 0.0;

  // bldc_mcasic_enc( clk, rst, pwm, offset, period, A, B, out );
  
  // First order digital low-pass butterworth filter with cut-off frequency of 100 Hz and sampling frequency of 50 MHz.
  static const double Abutter = 0.999987433708342;
  static const double Bbutter = 1.777142009174172E-05;
  static const double Cbutter = 0.707102338331525;
  static const double Dbutter = 6.283145829092713E-06;
  
  static int step_cnt;
  for ( step_cnt = 1; step_cnt < step_max; ++step_cnt )
  {    
    t[step_cnt] = t[step_cnt-1] + dt; // [sec]
    mtr_vel[step_cnt] = 10; // [rad/sec]
    mtr_phase[step_cnt] = mtr_phase[step_cnt-1] + mtr_vel[step_cnt-1] * dt; // [rad]
    
    stator_phase[step_cnt] = 0.0;
    rotor_phase[step_cnt] = 0.0;
    
    // Simulate encoder.
    if ( mtr_phase[step_cnt] >= enc_line_phase + enc_res )
    {
      quad_state_idx = ( quad_state_idx + 1 ) % quad_state_cnt;
      enc_line_phase += enc_res; // Update the location of the last quadrature state change.
    }
    else if ( mtr_phase[step_cnt] <= enc_line_phase - enc_res )
    {
      quad_state_idx = ( quad_state_idx - 1 ) % quad_state_cnt;
      enc_line_phase -= enc_res; // Update the location of the last quadrature state change.
    }

    if ( abs( mtr_phase[step_cnt] - enc_line_phase ) >= enc_res )
    {
      printf( "Error: Multiple quadrature states in a single timestep."
        "  Timestep: %.6f sec, velocity: %.3f rad/sec\n",
        dt, mtr_vel[step_cnt] );
      break;
    }

    top->A = quad_state_arr[quad_state_idx].A;
    top->B = quad_state_arr[quad_state_idx].B;
    A[step_cnt] = top->A;
    B[step_cnt] = top->B;
    
    top->clk = 1;
    top->eval();
    top->clk = 0;
    top->eval();
    
    static double xpwm[3] = { 0.0, 0.0, 0.0 };
    int i;
    for ( i = 0; i < 3; ++i )
    {
      winding_voltage[i][step_cnt] = Cbutter * xpwm[i] + Dbutter * power_supply_voltage * top->out[i];
      xpwm[i] = Abutter * xpwm[i] + Bbutter * power_supply_voltage * top->out[i];
    }
    //printf( "xpwm[2]: %.6f, out[2]: %d\n", xpwm[2], top->out[2] );
  }

  g.disini(); // Initializes DISLIN
  g.pagera();
  g.hwfont();
  //g.axspos( 450, 1800 );
  //g.axslen( 2200, 1200);

  g.name( "Time (sec)", "x" );
  g.name( "Phase (rad)", "y" );

  g.labdig( -1, "x" );
  g.ticks( 5, "xy" );

  g.titlin( "BLDC MCASIC ENC", 1 );
  //g.titlin ("SIN(X), COS(X)", 3);

  /*
  GRAF plots a two-dimensional axis system.

  The call is:	CALL GRAF (XA, XE, XOR, XSTP, YA, YE, YOR, YSTP)	level 1
  or:	void graf (float xa, float xe, float xor, float xstp, float ya, float ye, float yor, float ystp);

  XA, XE	are the lower and upper limits of the X-axis.
  XOR, XSTP	are the first X-axis label and the step between labels.
  YA, YE	are the lower and upper limits of the Y-axis.
  YOR, YSTP	are the first Y-axis label and the step between labels.
  */
  //g.graf( -2.0 * M_PI, ( (double)period_cnt + 1.0 ) * 2.0 * M_PI, 0.0, 90.0, -150, 150, -150, 50 );
  g.graf( 0.0, tmax, 0.0, 1.0, -10.0, 10.0, -10, 1.0 );
  g.title();

  g.color( "red" );
  g.curve( t, stator_phase, step_max );
  g.color( "green" );
  g.curve( t, rotor_phase, step_max );
  g.color( "blue" );
  g.curve( t, mtr_phase, step_max );

  g.color( "fore" );
  //g.dash(); // Sets dashed line style.
  g.xaxgit(); // Plots the line y = 0.
  g.endgrf();
  
  // Encoder window.
  g.opnwin(2);
  
  g.name( "Time (sec)", "x" );
  g.name( "Encoder", "y" );

  g.labdig( -1, "x" );
  g.ticks( 5, "xy" );
  
  g.graf( 0.0, tmax, 0.0, 1.0, -1.0, 2.0, -1.0, 0.5 );
  g.title();

  g.color( "red" );
  g.curve( t, A, step_max );
  g.color( "green" );
  g.curve( t, B, step_max );

  g.color( "fore" );
  g.endgrf();
  
  // Phase voltage window
  g.opnwin(3);
  
  g.name( "Time (sec)", "x" );
  g.name( "Voltage (V)", "y" );

  g.labdig( -1, "x" );
  g.ticks( 5, "xy" );
  
  g.graf( 0.0, tmax, 0.0, 1.0, -1.0, power_supply_voltage + 1.0, -1.0, 0.5 );
  g.title();

  g.color( "red" );
  g.curve( t, winding_voltage[0], step_max );
  g.color( "green" );
  g.curve( t, winding_voltage[1], step_max );
  g.color( "blue" );
  g.curve( t, winding_voltage[2], step_max );

  g.color( "fore" );
  g.endgrf();
  
  g.disfin(); // Terminates DISLIN
  
  delete top;
  exit( 0 );
}
Exemple #4
0
int main( int argc, char *argv[], char *env[] )
{
  Verilated::commandArgs( argc, argv );
  top = new Vsine3;
  top->clk = 0;
  top->eval();

  Dislin g;

  g.itmstr( "Yes!", 1 );  

  g.metafl( "CONS" );
  g.setpag( "da4l" );

  top->period = 64;
  const int period_cnt = 2; // [periods]
  const int res = 100; // [samples/period]
  const int sample_cnt = period_cnt * res; // [samples]
  const double dx = 2.0 * M_PI / (double)res;
  double x[3][sample_cnt]; // [radians]
  double y[3][sample_cnt];

  int n;
  for ( n = 0; n < sample_cnt; ++n )
  {
    x[0][n] = (double)n * dx; // [radians]
    x[1][n] = x[0][n]; // [radians]
    x[2][n] = x[0][n]; // [radians]

    top->in0 = (int)round( x[0][n] * (double)top->period / 2.0 / M_PI );
    top->in1 = (int)round( ( x[1][n] - 2.0 * M_PI / 3.0 ) * (double)top->period / 2.0 / M_PI );
    top->in2 = (int)round( ( x[2][n] + 2.0 * M_PI / 3.0 ) * (double)top->period / 2.0 / M_PI );

    top->eval();

    y[0][n] = ( (double)(signed char)top->out0 );
    y[1][n] = ( (double)(signed char)top->out1 );
    y[2][n] = ( (double)(signed char)top->out2 );

    //printf( "n: %d, in0: %d, out0: %d\n",
    //  n, top->in0, (signed char)top->out0 );
  }

  g.disini();
  g.pagera();
  g.hwfont();
  g.axspos( 450, 1800 );
  g.axslen( 2200, 1200) ;

  g.name( "Phase (radians)", "x" );
  g.name( "Sine (8 bit)", "y" );

  g.labdig( -1, "x" );
  g.ticks( 10, "xy" );

  g.titlin( "Sine simulation", 1 );
  //g.titlin ("SIN(X), COS(X)", 3);

  g.graf( -2.0 * M_PI, ( (double)period_cnt + 1.0 ) * 2.0 * M_PI, 0.0, 90.0, -150, 150, -150, 50 );
  g.title();

  g.color( "red" );
  g.curve( x[0], y[0], sample_cnt );
  g.color( "green" );
  g.curve( x[1], y[1], sample_cnt );
  g.color( "blue" );
  g.curve( x[2], y[2], sample_cnt );

  g.color( "fore" );
  g.dash();
  g.xaxgit();
  g.disfin();

  delete top;
  exit( 0 );
}