LoginSignup
4
5

More than 5 years have passed since last update.

面倒な処理はPythonにおまかせ

Posted at

はじめに

私の前後が、PythonからHDLを生成したり、Pythonから直接ゲートを合成したり、と((((;゚Д゚))))ガクガクブルブルですが、これは、至って気楽な記事です。

SystemVerilogって、ハードウェアを記述するためだけのものではないですよね? というか、社会人になって以来、HDLは使えど、ハードウェアを合成したことないです。もっぱらSystemVerilogでプログラムしたりするだけなのですが、ライブラリが少ないので(検証用のライブラリはとっても豊富ですけどね)、効率が悪いのが難点です。それ、普通の言語だったら、ライブラリで一発なのに。。。と言ったものでも、自分で書かないといけないのは結構ストレスですよね。

そういう時は、みんな大好きPythonに接続して、なるべく少ない記述で済ましてまいましょう、というものです。

流れ

SystemVerilogのDPIを使います。何かの本(SystemVerilog設計スタートアップ?)でDPIは、Cだけではなく、色んな言語に繋がる予定、とのことですが、現時点では、DPI-Cだけしかないので、DPI-C経由で、SystemVerilogとPythonを接続することになります。

SystemVerilog - (DPI) - C - Python

という流れです。

今回、2次方程式の係数をSystemVerilogから、Pythonに渡して、解をSystemVerilogに返す、という流れにしたいと思います。

Python

2次方程式は、SymPyに解いてもらいます。

two_order_eq_py.py
import sympy

def calc_two_order_eq(a, b, c):
  x = sympy.symbols('x')
  f = a*x**2 + b*x + c
  solve = sympy.solve(f, x)
  return solve

C

数年ぶりのCなので、あまりいい感じじゃない気がします。もっと、汎用的に作れると思うのですが。。。

two_order_eq.c
#include <stdio.h>
#include <stdlib.h>
#include <Python.h>
#include <svdpi.h>

void two_order_eq(double* ary, double* answer) {
  PyObject *pName, *pModule, *pFunc;
  PyObject *pArgs, *pValue;
  int i, order=2;

  Py_Initialize();
  pName = PyString_FromString("two_order_eq_py");       
  pModule = PyImport_Import(pName);                                   
  pFunc = PyObject_GetAttrString(pModule, "calc_two_order_eq");

  pArgs = PyTuple_New(order+1);             // Pythonに渡す引数toupleを生成
  for (i=0; i<order+1; i++) {
    pValue = PyFloat_FromDouble(ary[i]);
    PyTuple_SetItem(pArgs, i, pValue);
  }

  pValue = PyObject_CallObject(pFunc, pArgs);    // Pythonの関数を実行

  for (i=0; i<order; i++) {          // Pythonの結果を回収。
    answer[i] = PyFloat_AsDouble(PyList_GetItem(pValue, i));
  }

  Py_Finalize();
}

SVのコード

two_order_eq.sv
module top();
real ary[3];
real answer[2];

import "DPI-C" function void two_order_eq(input real ary[3], output real answer[2]);

initial begin
  ary = {1, -1, -6};
  two_order_eq(ary, answer);
  $display("Answer is %f, %f", answer[0], answer[1]);
  $finish;
end
endmodule

Make

お高いシミュレータであれば、SVのコードとCのコードをシミュレータに渡してやれば、一気にコンパイルして実行してくれます。
お高いやつじゃない場合は、*.oを作って、-sv_libで渡してやればいいんですかね?

実は。。。

もっと、いいサンプルが、https://github.com/rfukatani/pylink にあります。ΔΣ変調をPythonの部分で書いているようです。これを見ると、Matlabなくてもあるところまでいけるね、って感じがします。

ともあれ、これで、面倒な処理をPythonに投げることができるので、生産性が大きく向上します。SVのコードをどれだけ削減できるか、というのが、僕にとっては幸せへの第一歩です。

4
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
5