數字asic流程實驗(三) Verilog編寫&前仿真


數字asic流程實驗(三) Verilog編寫&前仿真

1.Verilog編寫

本次實驗要實現的是一個三級抽取CIC濾波器,抽取系數為64。回顧上一章節中的CIC濾波器結構,可以發現其硬件實現是非常簡單的,積分器的部分通過加法器與D觸發器即可實現,降采樣通過分頻器實現,梳狀器的部分則通過減法器和觸發器實現。

img

編寫分頻器的verilog實現,其輸入信號為時鍾信號clk與復位信號rst_n,輸出信號為64倍分頻后的時鍾信號clk_div。

分頻器使用計數器實現。當復位信號為低時,計數器值復位為0,clk_div輸出為0;當復位信號為高時,計數器在時鍾clk的每個上升沿計數,當第32個上升時鍾沿到來時clk_div進行翻轉,由於計數器位數為5位,第32個上升時鍾沿到來的同時計數器也清零了,直到下一次的第32個上升時鍾沿再重復上述過程,故clk_div兩次翻轉的時間(一個周期)為64個clk周期,從而實現了64倍分頻。

分頻器的verilog代碼實現如下:

module divider(
    input clk,
    input rst_n,
    output reg clk_div
);

reg [4:0]count;

always @(posedge clk or negedge rst_n) begin
    if (rst_n == 0) begin
        count <= 5'd0;
        clk_div <= 1'b0;
    end
    else if (count < 31) begin
        count <= count + 1;
        clk_div <= clk_div;
    end
    else begin
        count <= count + 1;
        clk_div <= ~clk_div;
    end
end

endmodule

編寫CIC濾波器的verilog實現,其輸入信號為時鍾clk,復位信號rst_n以及調制器輸入信號in,輸出信號為量化值out。

由於積分運算會導致數據位寬變寬,需要通過公式計算

\[B_{out}=B_{in}+Nlog_2(RM) \]

公式中,\(B_{out}\)為輸出數據的位數,\(B_{in}\)為輸入數據的位數,\(N\)為濾波器級數,\(R\)為濾波器階數,\(M\)​​為降采樣系數。代入數據后可以計算得到所需要的位數為19位,因此設計寄存器位寬為19。

需要注意的是梳狀器作為降采樣部分的后級,所有的時鍾信號都需要使用分頻器64倍分頻后的時鍾clk_div。

CIC濾波器的verilog實現代碼如下:

module cic_filter(
    input clk,
    input rst_n,
    input in,
    output [18:0] out
);
    reg [18:0]out_reg;
    wire clk_div;
    reg [18:0]sum1,sum2,sum3;
    wire [18:0]sum1_nxt,sum2_nxt,sum3_nxt;

    // 積分器加法器部分
    assign sum1_nxt = sum1 + in;
    assign sum2_nxt = sum2 + sum1;
    assign sum3_nxt = sum3 + sum2;

    // 積分器D觸發器部分
    always @(posedge clk or negedge rst_n) begin
        if (rst_n == 0) begin
            sum1 <= 19'b0;
            sum2 <= 19'b0;
            sum3 <= 19'b0;
        end
        else begin
            sum1 <= sum1_nxt;
            sum2 <= sum2_nxt;
            sum3 <= sum3_nxt;
        end
    end

    // 調用分頻器
    divider div(
        .clk(clk),
        .rst_n(rst_n),
        .clk_div(clk_div)
    );

    reg [18:0]sub1,sub2,sub3;
    wire [18:0]sub1_nxt,sub2_nxt,sub3_nxt;

    // 梳狀器減法器部分
    assign sub1_nxt = sum3_nxt - sub1;
    assign sub2_nxt = sub1_nxt - sub2;
    assign sub3_nxt = sub2_nxt - sub3;

    // 梳狀器D觸發器部分
    always @(posedge clk_div or negedge rst_n) begin
        if (rst_n == 0) begin
            sub1 <= 19'b0;
            sub2 <= 19'b0;
            sub3 <= 19'b0;
        end
        else begin
            sub1 <= sum3_nxt;
            sub2 <= sub1_nxt;
            sub3 <= sub2_nxt;
        end
    end

    // 輸出
    always @(posedge clk_div or negedge rst_n) begin
        if (rst_n == 0) begin
            out_reg <= 0;
        end
        else begin
            out_reg <= sub3_nxt;
        end
    end

    assign out = out_reg;

endmodule

編寫testbench用於仿真,文件1k1000mv.txt中存儲了一段∑-Δ調制器對一個周期的正弦波采樣后輸出的碼流,通過系統任務$readmemb將其讀入聲明好的存儲器mem中,並將數據按次序以1位碼流的形式進行輸出到CIC濾波器的輸入端口in,此外在testbench中設置時鍾信號clk周期為156.25ns,復位信號rst_n在仿真開始500ns后由低電平變為高電平。

testbench的verilog實現代碼如下:

`timescale 1ns/1ns
`define period 78.125

module testbench;
    // input
    reg clk,rst_n,in;
    // output
    wire [18:0]out;

    // 設置時鍾周期為156.25ns
    always #`period clk <= ~clk;

    // 初始化
    initial begin
        rst_n <= 1'b0;
        clk <= 1'b0;
        #500;
        rst_n <= 1'b1;
    end

    integer i;
    
    // 定義存儲器mem
    reg mem[0:3000000];
    
    // 將1k1000mv.txt文件讀入mem
    initial $readmemb("1k1000mv.txt",mem);

    // 將mem中數據次序輸出到in
    always @(posedge clk or negedge rst_n) begin
        if(rst_n == 0) begin
            i = 0;
            in <= 0;
        end
        else begin
            in <= mem[i];
            i = i + 1;
        end
    end

    // 調用cic濾波器
    cic_filter cic(
        .clk(clk),
        .rst_n(rst_n),
        .in(in),
        .out(out)
    );

endmodule

2.使用Modelsim進行前仿真

1.打開Modelsim,File---->New---->Project.. 建立新工程,命名為CICFilter,並設置工程路徑

image-20210725233419104

image-20210725233501108

2.將編寫好的verilog文件、1k1000mv.txt全部放到工程路徑下

image-20210725233920361

3.在Modelsim的Project標簽頁中右鍵,點擊Add to Project ---> Existing File... 選擇工程路徑下的verilog文件,Add file as type選為Verilog。將三個verilog文件全部添加進工程。

image-20210725234008270

image-20210725234106291

4.在Modelsim的Project標簽頁中右鍵,點擊Compile ---> Compile All,編譯全部verilog文件

image-20210725234402384

5.若編譯成功,下方Transcript窗口會輸出編譯成功的信息。若提示失敗則根據報錯信息修改verilog並再次編譯。

image-20210725234430925

6.點擊Simulate--->Start Simulation... 在彈出的窗口中,點擊work左側的小加號展開,在展開的欄目中點擊選中testbench,進入仿真環境。

image-20210725235317595

image-20210725235658477

image-20210725235807772

7.在仿真環境中①為Instance窗口,所有例化的模塊都會顯示在其中;②為Objects窗口,選中①中的模塊后,該窗口會對應顯示模塊中的信號,寄存器,存儲器等;③為Wave窗口,用於顯示仿真波形。在Instance窗口中點擊testbench,在Objects窗口中選中out並右鍵,Add to ---> Wave ---> Selected Signals,將out信號加入Wave窗口

image-20210726001011513

image-20210726001311351

image-20210726001515795

8.以同樣的方式將in信號也添加進Wave窗口

image-20210726001613423

9.修改右上角仿真時間,設置為1ms,再點擊其右側的run圖標

image-20210726001704257

10.此時Wave窗口應出現綠色波形,點擊左側小放大鏡自動縮放波形時間軸

image-20210726001842261

11.在Wave窗口中右鍵out信號,Format ---> Analog(automatic)

image-20210726001951100

12.可以看到一個周期正弦波信號

image-20210726002135940

13.多次點擊run圖標運行仿真,可以看到多個周期的正弦波

image-20210726002235341

14.使用左側放大鏡功能調整波形橫軸分度,可以看到在out值大的部分(波峰),in信號是以1為主的碼流,在out值小的部分(波谷),in信號是以0為主的碼流,和上一章節的調制器輸出與CIC濾波器輸出的關系是一致的。

image-20210726002725726

image-20210726002648841

至此完成了CIC濾波器的Verilog編寫及前仿真的實驗流程。

3.參考資料

https://blog.csdn.net/FPGADesigner/article/details/80885415

《數字集成電路設計入門--從HDL到版圖》 於敦山 北大微電子學系


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM