ZYBOでシンセサイザー作成(4)パラシリ変換 IP の作成


今回は、前回の記事で作成した正弦波生成 IP(sin_gen)の出力をパラシリ変換して、オーディオコーデック(SSM2603)で受け取れるデータ形式にします。

環境

  • パソコン:Windows10 64 bit
    • Vivado 2020.2 をインストール
    • Xilinx Vitis 2020.2 をインストール
  • ボード:Zybo Z7-20

パラシリ変換 IP の作成

Vivadoでパラシリ変換 IP のpara2serialを製作していきます。作成の仕方は前回のIPの作成とほとんど同じです。

パラシリ変換 IP について

コーデックへのデータの与え方はいくつかありますが、今回は図1の方法でシリアル変換します。コーデックから図1のBCLKとPBLRCの波形がくるので、これらに同期させて、PBDATに波形を送ります。

図1:コーデックへのデータの与え方(SSM2603のデータシートから引用)
図1:コーデックへのデータの与え方(SSM2603のデータシートから引用)

パラシリ変換 IPのフォルダの用意

前回と同じように以下のようにフォルダとファイルを配置していきます。para2serial.svはGitHubの「4th」フォルダにあります。

ip_repo_synth
└── para2serial
    └── HDL
        └── para2serial.sv

para2serial.svの内容を以下に示します。para2serial.svの内容については別の記事でしたいと思います。

para2serial.sv

module para2serial(
    input logic clk96M,
    input logic reset,
    input logic bclk,
    input logic pblrc,
    input logic [15:0] din_L,
    input logic [15:0] din_R,
    output logic pbdat
    );
    
    logic [1:0] cnt4;
    logic load;
    logic shift;
    logic [31:0] sreg_ff;
    
    // cnt4
    always_ff @(posedge clk96M) begin
        if(reset)
            cnt4 <= 2'd0;
        else if(bclk)
            cnt4 <= cnt4 + 2'd1;
        else
            cnt4 <= 2'd0;
    end
                  
    // shift register
    assign shift = (cnt4==2'd3);
    assign load = shift & pblrc;
    
    always_ff @ (posedge clk96M) begin
        if(reset)
            sreg_ff <= 32'd0;
        else if(load)
            sreg_ff <= {din_L, din_R};
        else if(shift)
            sreg_ff <= {sreg_ff[31:0], 1'b0};
    end

assign pbdat = sreg_ff[31];      
    
endmodule

VivadoでIPの製作

プロジェクトを以下のようにして作成します。

  • 作業フォルダ:para2serial
  • プロジェクト名:para2serial

このプロジェクトでIPの製作を行い、IPのシミュレーションも行います。

プロジェクトができたら、前回のVivadoでIPの製作の手順通りに途中まで進めて、IP編集用のVivado画面を起動します。

前回は編集用のVivado画面でいろいろとやりましたが、今回は「Package IP」タブ →「Review and Package」の「Package IP」を押すだけでいいです(図3)。

図2:「Package IP」を押す
図2:「Package IP」を押す

以上でIPが作成され、元のVivadoプロジェクト画面に戻ります。

パラシリ変換 IP のシミュレーション

パラシリ変換 IPであるpara2serialのシミュレーションをしていきます。

IP インテグレータで回路作成

IPインテグレータで回路を作っていきます。

  1. 「IP INTEGRATOR」→「Create Block Design」で「Diagram」を作成する。
  2. 「PROJECT MANAGER」→「Settings」で「Settings」画面を開き、「Project Settings」→「IP」→「Repository」の「+」で「sin_gen」IPを追加して、「OK」を押す(図3)。

    図3:プロジェクトにIPを追加する
    図3:プロジェクトにIPを追加する

  3. 「Add IP」で「sin_gen_v1_0」と「para2serial_v1_0」を追加する。

  4. 図4のようにして、回路を作成する。

図4:作成する回路
図4:作成する回路

回路ができたら、「Validate Design」をして、回路のチェックを行います。また、「Create HDL Wrapper」でラッパーを作成します。ラッパーの作成では「Copy generated wrapper to allow user edits」を選択します。

テストベンチの追加

テストベンチsim_para2serial.svを前回の記事のテストベンチの追加と同じように追加します。sim_para2serial.svはGitHubにあり、内容は以下です。(2021/5/29 追記:PBLRCの周期が96kHzだったため、48kHzになるようにテストベンチを修正しました)。sim_para2serial.svの説明についても別の記事で書こうと思います。

sim_para2serial.sv

`timescale 1ps / 1ps

module sim_para2serial;

localparam [63:0] STEP = 10416;
localparam [63:0] CLKNUM = 960000*4;

logic clk96M;
logic [14:0] freq;
logic reset;
logic bclk;
logic pbdat;
logic pblrc;

logic [1:0] cnt4;
logic [8:0] cnt500;

design_1_wrapper design_1_wrapper(
    .bclk(bclk),
    .clk96M (clk96M),
    .freq (freq),
    .pbdat (pbdat),
    .pblrc (pblrc),
    .reset (reset)
    );

// clk96M
always begin
    clk96M = 0; #(STEP/2);
    clk96M = 1; #(STEP/2);
end     

// cnt4
always_ff @(posedge clk96M) begin
    if(reset)
        cnt4 <= 2'd0;
    else
        cnt4 <= cnt4 + 2'd1;
end

// cnt500
always_ff @(posedge clk96M) begin
    if(reset)
        cnt500 <= 9'd0;
    else if(cnt4==2'd2)
        if(cnt500==9'd499)
            cnt500 <= 9'd0;
        else
            cnt500 <= cnt500 + 9'd1;
end

// pblrc
always_ff @(posedge clk96M) begin
    if(reset)
        pblrc <= 1'b0; 
    else if(cnt500==9'd499 | cnt500==9'd498)
        pblrc <= 1'b1;
    else
        pblrc <= 1'b0;
end

// bclk
always_ff @(posedge clk96M) begin
    if(reset)
        bclk <= 1'b0;
    else if(cnt4==2'd3)
        bclk <= ~bclk;
end

initial begin
    reset = 0;
    freq = 15'd440;
    #(STEP*600);
    reset = 1;
    #(STEP*20);
    reset = 0;
    #(STEP*CLKNUM);
    freq = 15'd600;
    #(STEP*CLKNUM);
    $stop;
end

endmodule

シミュレーションの実行

シミュレーションを実行すると、図6のようになっています。

図6:シミュレーションの結果
図6:シミュレーションの結果

PBDATが図1のデータ形式通りになっていることが確認できると思います。

おわりに

今回でパラシリ変換 IP を作成して、シミュレーションができました。次回はいよいよ音を出力したいと思います。

参考文献

[1] SSM2603のデータシート
[2] 小林 優、「FPGAプログラミング大全 Xilinx編 第2版」、秀和システム、2021.

お問い合わせフォーム プライバシーポリシー

© 2021 Setoti All rights reserved.