FIR 例とシステム検証 - 2020.2 日本語

Vivado Design Suite ユーザー ガイド: System Generator を使用したモデル ベースの DSP デザイン (UG897)

Document ID
UG897
Release Date
2020-11-18
Version
2020.2 日本語

この例では、MCode ブロックを使用して FIR をモデリングする方法と、MCode ブロックでシステム検証を実行する方法を示します。

図 1. FIR 例

この例には、FIR ブロックが 2 つ含まれています。これらのブロックは MCode ブロックで定義されており、どちらも合成可能です。次に、これら 2 つのブロックを定義する 2 つの関数を示します。

function y = simple_fir(x, lat, coefs, len, c_nbits, c_binpt, o_nbits, o_binpt)
  coef_prec = {xlSigned, c_nbits, c_binpt, xlRound, xlWrap};
  out_prec = {xlSigned, o_nbits, o_binpt};
  
  coefs_xfix = xfix(coef_prec, coefs);
  persistent coef_vec, coef_vec = xl_state(coefs_xfix, coef_prec);
  persistent x_line, x_line = xl_state(zeros(1, len-1), x);
  persistent p, p = xl_state(zeros(1, lat), out_prec, lat);
  
  sum = x * coef_vec(0);
  for idx = 1:len-1
    sum = sum + x_line(idx-1) * coef_vec(idx);
    sum = xfix(out_prec, sum);
  end
  y = p.back;
  p.push_front_pop_back(sum);
  x_line.push_front_pop_back(x);
function y = fir_transpose(x, lat, coefs, len, c_nbits, c_binpt, o_nbits, o_binpt)
  coef_prec = {xlSigned, c_nbits, c_binpt, xlRound, xlWrap};
  out_prec = {xlSigned, o_nbits, o_binpt};
  coefs_xfix = xfix(coef_prec, coefs);
  persistent coef_vec, coef_vec = xl_state(coefs_xfix, coef_prec);
  persistent reg_line, reg_line = xl_state(zeros(1, len), out_prec);
  if lat <= 0
    error('latency must be at least 1');
  end
  lat = lat - 1;
  persistent dly, 
  if lat <= 0
    y = reg_line.back;
  else
    dly = xl_state(zeros(1, lat), out_prec, lat);
    y = dly.back;
    dly.push_front_pop_back(reg_line.back);
  end
  for idx = len-1:-1:1
    reg_line(idx) = reg_line(idx - 1) + coef_vec(len - idx - 1) * x;
  end
  reg_line(0) = coef_vec(len - 1) * x;

パラメーターは、次のように設定されます。

図 2. パラメーター

2 つのブロックの機能が同一であることを検証するため、MCode ブロックをもう 1 つ使用して 2 つのブロックの出力を比較します。2 つの出力が等しくない場合は、エラー チェック ブロックによりエラーがレポートされます。エラー チェックは、次の関数により実行されます。

function eq = error_ne(a, b, report, mod)
  persistent cnt, cnt = xl_state(0, {xlUnsigned, 16, 0});
  switch mod
    case 1
      eq = a==b;
    case 2
      eq = isnan(a) || isnan(b) || a == b;
    case 3
      eq = ~isnan(a) && ~isnan(b) && a == b;
    otherwise
      eq = false;
    error(['wrong value of mode ', num2str(mod)]);
  end
  if report
    if ~eq
      error(['two inputs are not equal at time ', num2str(cnt)]);
    end
  end
  cnt = cnt + 1;

このブロックは、次のように設定されます。

図 3. ブロックの設定