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

システムバス(Lattice ice40)につなぐ

More than 1 year has passed since last update.

文章を書くときは vim を使っている。30 年前はマイフェス(MIFES)と ATOK だった。OS は MS-DOS 3.1。未だに、出版社に原稿をあげるときも TeX だったりする。ほぼテキストなので文章は使いまわせる。Lattice のシステムバスにつなぐという話はインタフェースの 2018 年1月号に書いている。その記事を元に構成しなおそう。

ターゲットは Lattice iCE40 だ。iCE40 は内部にシステムバスと呼ばれるものを持っている。非常に簡単なバスでアクセスは比較的簡単だ。雑誌の記事では全ソース載せられてない。200 行を超えるので、ここでも一部としよう。

なお全文は gist にデバッグの生々しいコメントアウトも含めてあげてある。

read_spi_data16
   def read_spi_data16(self):
        debug_v:uint3 = 0

        debug_v = 4
        #self.debug.wr(4)

        self.write_data(0x06, 0x18)
        self.write_data(0x0A, 0xC0)
        self.write_data(0x0D, 0xFF)

        while True:
            irq_status = self.read_data(0x06)
            irq_trdy = (irq_status >> 4) & 1
            if irq_trdy == 1 :
                self.write_data(0x06, 0x10)
                break
        self.write_data(0x0D, 0xFF)
        #self.debug.wr(5)

        debug_v = 1

        while True:
            irq_status = self.read_data(0x06)
            irq_rrdy = (irq_status >> 3) & 1
            debug_v = 7 ^ debug_v
        #    self.debug.wr(debug_v)
            if irq_rrdy == 1:
                self.write_data(0x06, 0x08)
                break
        data0 = self.read_data(0x0E) << 8
        debug_v = 2
        #self.debug.wr(2)

        while True:
            irq_status = self.read_data(0x06)
            irq_rrdy = (irq_status >> 3) & 1
            if irq_rrdy == 1:
                debug_v = 4 ^ debug_v
                #self.debug.wr(debug_v)
                self.write_data(0x06, 0x08)
                break
        data1 = self.read_data(0x0E)
        #self.debug.wr(1)

        self.write_data(0x0A, 0x80)
        return (data0 | data1)

メソッド read_spi_data16 は PmodALS からデータを読み込むプログラムだ。write_data や read_data が実際にシステムバスと通信をしている。

write_data
    def write_data(self, addr:uint8, data:uint8):
        self.rw(1)
        self.addr(addr)
        self.data_out(data)
        clkfence()
        self.stb(1)
        clkfence()
        wait_value(1, self.ack)
        clkfence()
        self.stb(0)
read_data
    def read_data(self, addr:uint8):
        data:uint8 = 0
        self.rw(0)
        self.addr(addr)
        clkfence()
        self.stb(1)
        clkfence()
        wait_value(1, self.ack)
        data = self.data_in.rd()
        clkfence()
        self.stb(0)
        return data

clkfence という特別な関数が順序性の追い越しをしないように制御している。

image.png

Polyphony は将来的にもう少しこの辺を便利にしようかとも思っている。ただ、クロックという考え方と、コンパイラがパイプラインを生成するという発想は、著しく相性が悪いことはわかっている。この部分のブレイクスルーがあると次の世代の HLS に行きつくのかもしれない。

image.png
開発の過程では Arty Z7 をデジアナの代わりに。

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