VexRiscv (RISC-V) の Murax SoC に自作ペリフェラルを追加してみた

(更新

Added a PWM output control to VexRiscv (RISC-V) Murax Soc.

先日、VexRiscv Murax SoC を TinyFPGA-BX で動かす修正を御紹介しましたが、今回は自分で書いた小さな小さなペリフェラル(PWM 出力)を APB3 バス経由で Murax SoC に繋いでみました。

SpinalHDL によるコードは非常にシンプルで明解です。じゃん。

package flogics.vexriscv.pwm

import spinal.core._
import spinal.lib._
import spinal.lib.bus.amba3.apb.{Apb3, Apb3Config, Apb3SlaveFactory}

class Pwm(size: Int) extends Component {
  val io = new Bundle {
    val width = in UInt (size bits)
    val output = out Bool
  }

  val ct = Counter(size bits)

  ct.increment()
  io.output := ct.value < io.width
}

class Apb3PwmCtrl(size: Int) extends Component {
  val io = new Bundle {
    val apb = slave(
      Apb3(
        addressWidth = 4,
        dataWidth = 32
      )
    )
    val output = out Bool
  }

  val pwm = new Pwm(size)
  io.output := pwm.io.output

  val busCtrl = Apb3SlaveFactory(io.apb)
  busCtrl.driveAndRead(pwm.io.width, address = 0)
}

今回は、FPGA の入力クロック 16MHz を 8ビットのカウンタで分周しますので、PWM のレートは 16e6 / (1 << 8) = 62.5 kHz になります。ファームウェアによる bit-banging では難しい実装になるかと思います。

あとは、これを Murax SoC の中に APB3 経由で繋ぐだけです。詳しくは、以下の GitHub リポジトリを御覧ください。(ソースコード: src/main/scala/vexriscv/flogics/Murax.scala

なお、PWM を制御するコードを埋め込んだファームウェアはここにあります。

C言語のプログラムによる制御部分は、こんな感じです。

void main() {
    // ...
    PWM->WIDTH = 0; // Initialize PWM
    // ...
}

void irqCallback() {
    // ...
    volatile int rx = (UART->DATA) & 0xFF;
    UART->DATA = rx;
    if (rx >= '0' && rx <= '9')
        PWM->WIDTH = (rx - '0') * (255 / 9); // Assign PWM width
}

つまり、UART の受信文字が数字であるとき、その値に応じて PWM の幅(0〜255)を指定している訳ですね。

ようやく、自分が HDL で書いた(小さな小さな)ペリフェラルに標準的なバスを繋ぎ、さらに C 言語で書いたプログラムを FPGA 上の RISC-V で動かすことで、ペリフェラルの制御ができました。SpinalHDL を勉強し始めてから 3ヶ月ということで、ちょっと感激です。でも、頭の柔らかい学生さんや若手技術者なら、もっと簡単に習得できるのではないかと思います。

私は組込ソフト屋なのでソフト設計のほうはなんてことはないのですが、必要に応じて独自のペリフェラルやインターフェイスを設計して動かすことができる、というのは組込設計の応用が広がりそうです。

最後に動かしているところをビデオに納めましたので、御笑納ください。

https://www.youtube.com/watch?v=yb-KG3U9vzU

今日はここまで!

お問い合わせはお気軽に

お問い合わせを頂いた後、継続して営業活動をしたり、ニュースレター等をお送りしたりすることはございません。
御返答は 24時間以内(営業時間中)とさせて頂いております。必ず返信致しますが、時々アドレス誤りと思われる返信エラーがございます。返答が届かない場合、大変お手数ではございますが別のメールアドレスで督促頂けますと幸いです。