@+id/proelbtn

nop, nop, nop, nop...

Verilog HDLで簡単な論理回路を組む。

Verilog HDLは簡単っぽさそうですがそれでも慣れるために練習。

回路の仕様

KEY[3]のネガティブエッジで、カウンタがインクリメントされ、RESETのネガティブエッジでカウンタがリセットされる。

カウンタが0の時、LED[3:0]にはSW[8:5] AND SW[3:0]が代入される。 カウンタが1の時、LED[3:0]にはSW[8:5] OR SW[3:0]が代入される。 カウンタが2の時、LED[3:0]にはSW[8:5] XOR SW[3:0]が代入される。 カウンタが3の時、LED[3:0]にはSW[3:0]をビット反転させたものが代入される。

コード

module logical_sample (RESET, KEY, SW, LED);
    input RESET;
    input[3:0] KEY;
    input[9:0] SW;
    output[9:0] LED;
    
    reg[3:0] val;
    reg[1:0] counter;

    always @(negedge KEY[3] or negedge RESET)
        begin
            if(RESET == 1'b0) counter <= 2'b00;
            else
                begin
                    counter <= counter + 1;
                end
                
            case (counter)
                2'b00: val = SW[8:5] & SW[3:0];
                2'b01: val = SW[8:5] | SW[3:0];
                2'b10: val = SW[8:5] ^ SW[3:0];
                2'b11: val = ~SW[3:0];
            endcase
        end
        
    assign LED[6:5] = counter;
    assign LED[3:0] = val;
endmodule

各部分の説明

1行目

module logical_sample (RESET, KEY, SW, LED);

moduleの宣言です。きっとトップレベルのモジュールは評価ボードのペリフェラルFPGA内のポートの架け橋にしたほうがよさそうなので、評価ボード上にあるRESETスイッチやKEYなどといったものを宣言しています。

2~5行目

 input RESET;
    input[3:0] KEY;
    input[9:0] SW;
    output[9:0] LED;

評価ボード上にある入出力のポートと1対1で対応できるように型を宣言しておきます。

6~7行目

 reg[3:0] val;
    reg[1:0] counter;

内部で保持しておきたい値の宣言です。内部で保持する値はreg宣言しておいてます。

8~24行目

 always @(negedge KEY[3] or negedge RESET)
        begin
            if(RESET == 1'b0) counter <= 2'b00;
            else
                begin
                    counter <= counter + 1;
                end
                
            case (counter)
                2'b00: val = SW[8:5] & SW[3:0];
                2'b01: val = SW[8:5] | SW[3:0];
                2'b10: val = SW[8:5] ^ SW[3:0];
                2'b11: val = ~SW[3:0];
            endcase
        end

ここが処理の大部分を占めていますね。always @(cond) begin ~ endでcondが成立するときに~の部分の処理を実行します。今回はKEY[3]がH->L、もしくはRESETがH->Lの時に実行されます。ポジティブエッジにしたいならnegedgeの代わりにL->HにすればOKです。

そして処理の中身です。RESETがLならcounterに0を代入して、そうでないならcounterをインクリメントします。2'b00というのは2bitで値が2進数で00という意味です。8bitで値が16進数でAFならば8'hAFとなります。まぁ、適宜調べてください。リファレンスじゃないので、、、

そして、その値を見てそれぞれの計算結果をvalに代入します。

26~27行目

 assign LED[6:5] = counter;
    assign LED[3:0] = val;

LED[6:5]とcounterを紐付けます。代入と言うより、wireとoutputを紐付ける処理な気がする。

動いてる感じ