SystemVerilog|パラレルシリアル変換回路

Systemverilog
田中太郎
田中太郎

パラシリ変換回路を作ります

サンプルコード

initの立ち上がりで入力されたパラレルデータをシリアルデータに変換します

sample.sv
module sample #(
    parameter BW = 10
)(
    input clk,
    input rst_n,
    input init, // initが立ち上がるとパラシリ変換を始める
    input [BW-1:0] din, // 入力のシリアルデータ
    output logic valid, // doutが有効のとき1
    output logic dout // 出力のパラレルデータ
);
    // initの立ち上がりを検知するために、initをFFでたたきます
    logic init_delay;
    always_ff @(posedge clk, negedge rst_n) begin
        if (!rst_n) begin
            init_delay <= '0;
        end
        else begin
            init_delay <= init;
        end
    end

    logic [$clog2(BW):0] cnt; // $clog2でBWに適したビット幅のカウンタを作成
    always_ff @(posedge clk, negedge rst_n) begin
        if (!rst_n) begin
            cnt <= BW - 1'b1;
        end
        else begin
            if (~init_delay && init) begin
                cnt <= '0;
            end
            else if (cnt < BW - 1) begin
                cnt <= cnt + 1'b1;
            end
        end
    end

    // 出力が有効のときはvalidが1になる
    always_ff @(posedge clk, negedge rst_n) begin
        if (!rst_n) begin
            valid <= 1'b0;
        end
        else begin
            if (cnt < BW - 1) begin
                valid <= 1'b1;
            end
            else begin
                valid <= 1'b0;
            end
        end
    end

    // 入力のパラレルデータをシリアルデータに変換する
    always_ff @(posedge clk, negedge rst_n) begin
        if (!rst_n) begin
            dout <= '0;
        end
        else begin
            dout <= din[cnt];
        end
    end
endmodule

テストベンチを作成して動作を確認します

テストベンチ

tb.sv
module tb;
    initial begin
        $dumpfile("wave.vcd"); // 波形を取得するおまじない
        $dumpvars(0, tb);
    end

    bit clk = 0;
    always #5 clk = ~clk; // クロックを生成

    localparam BW = 8;
    bit rst_n = 0;
    bit init = 0;
    bit [BW-1:0] din = 8'b01010101; // 入力データ
    initial begin // テストシーケンス。リセットを解除してinitを1にする。
        #20;
        rst_n = 1;
        #20;
        init = 1;
        #100;
        $finish;
    end

    bit valid;
    bit dout;
    sample #( // RTLをインスタンス
        .BW(BW)
    ) u_sample(
        .clk(clk),
        .rst_n(rst_n),
        .init(init),
        .din(din),
        .valid(valid),
        .dout(dout)
    );

    // 出力データを表示
    always_ff @(posedge clk iff valid) $display("%d", dout);
endmodule
出力
1
0
1
0
1
0
1
波形

まとめ

パラシリ変換回路を作成しました

コメント

タイトルとURLをコピーしました