Help us understand the problem. What is going on with this article?

[新機能]パイプラインを使ったフィルター

More than 1 year has passed since last update.

スィングしなけれりゃ意味がない(It Don't Mean A Thing. If It Ain't Got That Swing)。最近ではめっきり聞かなくなったが、エラの歌はいつもスィングしている。いつまでもエラの時代じゃない。次の次の次の時代はエスペランザみたいな人が道なき道を作っていく。

そうしないと意味がないとまでは言わないが、FPGA で物を作るならパイプラインは必須だ。Polyphony でもついにパイプラインの機能が取り入れられた。まだ、準備段階にある機能だが github の devel から clone すれば、その機能を試すことが出来る。

ソースの例を示そう。

pipeline
 @rule(scheduling='pipeline')
    def proc(self):
        a0:uint18 = 0
        a1:uint18 = 0
        ...
        後略
        ...

実に単純だ。@rule というデコレータをつけるだけである。引数として設定されている scheduling='pipeline' でパイプライン化の指示をしていることになる。

これで数日に渡ったフィルタ・プログラムの完成である。全体像は次のようになる。

image.png

デザイナーはフィルター部分を独自に作れば様々な対応ができるだろう。参考までに UART と SPI を統合したフィルターのソースをつける。

filter.py
from polyphony import rule
import polyphony
from polyphony import is_worker_running
from polyphony.io import Port, Queue
from polyphony.typing import bit, int8, int16, int18
from polyphony.timing import clksleep, clkfence, wait_rising, wait_falling


@polyphony.module
class Filter:
    def __init__(self):
        self.uart = uart.Transmitter()
        self.spi_in = AD7091R_SPIC()
        self.q = Queue(int16, 'any', maxsize=10)
        self.append_worker(self.read_proc)
        self.append_worker(self.proc)

    def read_proc(self):
        while is_worker_running():
            #wait_rising(self.spi_in.data_ready)
            data = self.spi_in.dout.rd()
            self.q.wr(data)

    @rule(scheduling='pipeline')
    def proc(self):
        a0:int18 = 0
        a1:int18 = 0
        a2:int18 = 0
        a3:int18 = 0

        while is_worker_running():
            data:int16 = self.q.rd()
            a0 = a1 + data
            a1 = a2 + data
            a2 = a3 + data
            a3 =      data

            #print(data)
            self.uart.write_hex16(data)

@polyphony.testbench
def test(m):
    datas = (0xdead, 0xbeef, 0xffff, 0x0000, 0x800)
    for data in datas:
        m.din.wr(data)

    for i in range(5):
        print(m.q.rd())

    clksleep(10)

if __name__ == '__main__':
    filter = Filter()
    test(filter)
Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away