Veriloggenって何だろう(6)Case

Verilog HDL を生成するための記述を python で行うことで FPGA 回路の生成を楽にする為のライブラリー Veriloggen を使ってみたいと思います。
今回は単純なCASE文の書き方です。

Case文の記述

Veriloggenを使用したcase文の記述は、条件を簡潔にできるので、非常に読みやすい記述が可能です。
例えば、条件の変数が0の時に、outに0b1111110を出力するというのは
veriloggen.When(0)(out(0b1111110))
となります。
このような条件をリストに羅列してveriloggen.Caseに与えます。

Case文使用の例

クロックをカウントして0~9までの数を繰り返し、セブンセグメントLEDに対応する数字を表示する時のLEDの組み合わせをcase文で作るときの例を書いてみます。

import veriloggen as vg

def Num2led(m,clk,rst,number):
    '''
    モジュールmにnumberに応じたLEDをONにするcase文を追加する
    '''
    out = m.TmpReg(7, initval=0)

    seq = vg.TmpSeq(m,clk)
    #7segment LED a,b,c,d,e,f,g
    decCond = []
    decCond.append( vg.When(0)(out(0b1111110)) )
    decCond.append( vg.When(1)(out(0b0110000)) )
    decCond.append( vg.When(2)(out(0b11001101)) )
    decCond.append( vg.When(3)(out(0b11110001)) )
    decCond.append( vg.When(4)(out(0b01110011)) )
    decCond.append( vg.When(5)(out(0b10110011)) )
    decCond.append( vg.When(6)(out(0b10111011)) )
    decCond.append( vg.When(7)(out(0b11100000)) )
    decCond.append( vg.When(8)(out(0b11111111)) )
    decCond.append( vg.When(9)(out(0b11111011)) )
    decCond.append( vg.When()(out(0b0000000)) )

    seq.add(vg.Case(number)(*decCond))
    
    return out

def mkSevenSeg():
    '''
    クロックをカウントし、0~9までのnumberを繰り返し、セブンセグメントLEDに数字を表示する信号を生成
    '''
    m = vg.Module('SevenSeg')
    clk = m.Input('CLK')
    rst = m.Input('RST')
    ledout = m.Output('LED',7)
    
    count = m.TmpReg(width = 4,initval = 0)

    seq = vg.TmpSeq(m,clk,rst)
    seq.add(count.inc())
    seq.add(vg.If(count>=9)(count(0)))
    seq.make_always()
    
    sled = Num2led(m,clk,rst,count)
    ledout.assign(sled)

    return m

生成されるVerilog HDL とシミュレーション結果

テストベンチを作成してVerilog HDLを生成し、シミュレーションした結果は次の様になりました。

module SevenSeg
(
  input CLK,
  input RST,
  output [7-1:0] LED
);

  reg [4-1:0] _tmp_0;

  always @(posedge CLK) begin
    if(RST) begin
      _tmp_0 <= 0;
    end else begin
      _tmp_0 <= _tmp_0 + 1;
      if(_tmp_0 >= 9) begin
        _tmp_0 <= 0;
      end 
    end
  end

  reg [7-1:0] _tmp_1;
  assign LED = _tmp_1;

  always @(posedge CLK) begin
    case(_tmp_0)
      0: begin
        _tmp_1 <= 126;
      end
      1: begin
        _tmp_1 <= 48;
      end
      2: begin
        _tmp_1 <= 205;
      end
      3: begin
        _tmp_1 <= 241;
      end
      4: begin
        _tmp_1 <= 115;
      end
      5: begin
        _tmp_1 <= 179;
      end
      6: begin
        _tmp_1 <= 187;
      end
      7: begin
        _tmp_1 <= 224;
      end
      8: begin
        _tmp_1 <= 255;
      end
      9: begin
        _tmp_1 <= 251;
      end
      default: begin
        _tmp_1 <= 0;
      end
    endcase
  end

endmodule

f:id:feynman911:20181105143452j:plain