Verilog語法_1(reg、wire、always語法)

September 16, 2016
作者:dengshuai_super
出處:http://blog.csdn.net/dengshuai_super/article/details/52557422
聲明:轉載請註明作者及出處。


可綜合文件放到design文件夾下,testbench文件放到sim文件夾下(文件夾名可自定義)

//ex_module.v
module ex_module(
                input   wire                 sclk,
                input   wire             rst_n,
                input   wire  [7:0]  d,//聲明模塊的時候,輸入一定是wire變量
                output  reg   [7:0]  q//聲明模塊的時候,輸出可以是wire變量也可以是reg;reg變量必須在always塊裏面賦值
);//接口列表
//異步的D觸發器
always @(posedge sclk or negedge rst_n)    //括號裏面是敏感列表,可以包括電平觸發或者沿觸發
                                  //寄存器發生變化或翻轉就是由CLK(讓D觸發器翻轉)或CLR(復位端讓寄存器清零)
        if(rst_n == 1'b0) //if後面的括號裏是條件表,這裏是組合邏輯。"=="聲明一個比較器,"1"指的是1比特、""用來區分阿拉伯數字和進制,"b"代表的進制binary,“0”是一個比特的0
              q<=8'h00;            //10'b00000_00000  10'd10  10'hff,沿觸發的邏輯裏邊一定都用<=非阻塞賦值。
        else
              q<=d;

////同步
//always @(posedge sclk)//同步的時候sclk在上升沿的時候,檢測到低電平;異步的時候,當rst_n出現下降沿的時候,寄存器復位
//        if(rst_n == 1'b0)
//              q<=8'h00;
//        else
//              q<=d;

endmodule

//ex_wire.v
module ex_wire(
    input  wire sel,
    input  wire a,
    input  wire b,
    output wire c
);//always 對reg賦值,assign語句(連續賦值)對wire賦值
//wire 變量一定用assign連續賦值語句賦值,而且必須是用阻塞賦值
assign c=(sel == 1'b1)?a:b;//(條件)?條件爲1:條件爲0
/*
            if(sel == 1'b1)
                c =a;
            else
              c =b;
*/
endmodule

//ex_cnt.v
module ex_cnt(
        input wire sclk,//模擬晶振產生時鐘震盪
        input wire rst_n,//模擬外部復位電平testbench
      output wire [9:0] cnt
);
reg [9:0] cnt_r;//定義一個寄存器變量"r"代表reg

always @ (posedge sclk or negedge rst_n)
            if(rst_n == 1'b0)
                    cnt_r <= 10'd0;//"'d0"直接返回32位的0,截取低10位給cnt_r,1023+1=1024
            else
                cnt_r <= cnt_r + 1'b1;//0---1023-0---1023
assign cnt =cnt_r;          
//仿真工具modelsim    
//鏈接:http://pan.baidu.com/s/1qW5IhhM 密碼:n28z          
endmodule



//請參考verilog數據常量
//數字表達式:<位寬><進制><數字>
//'b:二進制    //eg.4'b1110  表示4位二進制數1110
//'h:十六進制 //eg  8'hef、4’ha等
//'d:十進制    //eg   2'd3、4‘d15(不能寫16,4位寬最大15)等
//
//所以10’d0表示10位寬的數值0,0000000000
//加入10‘d15,則表示十進制15 ,0000001111

//tb_ex_cnt.v

//聲明延時單位,1ns指的是單位,100ps(0.1ns)指的是時標的精度。
//例如:#10.11--->10.10(最後的10ps精度被忽略)
`timescale 1ns/100ps   

module tb_ex_cnt;//這是完整的頂層,沒有輸入輸出接口
            reg  tb_sclk,tb_rst_n;
            wire [9:0]  tb_cnt;

            initial//一上電只被執行一次,在initial這個塊裏面只能被寄存器變量賦值
            begin//在testbench裏面begin、and是順序執行的;在可綜合模塊裏面begin、and就是一個括號
                    tb_sclk <=0;
                    tb_rst_n<=0;//它倆有先後順序,先是tb_sclk被賦值然後再是tb_rst_n被賦值。但是之間的延遲是0。
                    #200.1
                    tb_rst_n<=1;
            end
always #10 tb_sclk <= ~tb_sclk;//例如初始狀態是0,過了10ns變成1,又保持10ns變成0,周而復始的進行翻轉。於是產生了時鐘和復位信號

//例化的方法
//原始模塊名字 例化的名字(可以自定義)
ex_cnt ex_cnt_inst(
        .sclk  (tb_sclk),//模擬晶振產生時鐘震盪
        .rst_n (tb_rst_n),//模擬外部復位電平testbench;例化模塊的時候如果原始模塊是輸入信號,那麼括號內可以是wire變量也可以是reg變量
      .cnt   (tb_cnt) //例化模塊的時候如果原始模塊是輸出信號,那麼括號內必須是wire變量(正好和可綜合模塊相反)
);
endmodule

例化時,變量的賦值應該遵循下圖(按照自己理解畫的,不一定正確,歡迎指正):
Design中的模塊輸出的時候可以作爲寄存器,它相當於把輸出寄存器的Q端直接連接到輸出口了,就把中間那根線給省略了;
Testbench中輸出變量必須是wire類型,因爲芯片畫PCB時,輸出的管腳都用線連。
這裏寫圖片描述

打開ModelSim--->File--->new--->Project--->Project Name:ex_cnt(自定義,別寫中文);路徑:D:\VivadoProjects\FPGA_From_e_to_c\ex_1\sim(根據你文件的路徑寫)
--->在Project標籤頁下右鍵--->Add to Project--->Existing File--->將ex_cnt.v,tb_ex_cnt.v加進來--->Compile All--->數據編譯到Library標籤頁的work下
--->右鍵tb_ex_cnt--->Simulation without Optimization--->右鍵ex_cnt_inst,Add Wave--->

如圖所示:
這裏寫圖片描述

在Wave 頁面下,如果左側信號欄變量名帶路徑,可以在Tools--->Window Preferences--->Display Signal Path改爲1即可。
然後在Wave頁面設置運行時間:這裏設置100us--->點擊Run--->在左側右擊變量--->Radix--->選擇顯示的進制。

Verilog中wire與reg類型的區別:
http://blog.csdn.net/changhaizhang/article/details/6933806


來源:
https://ke.qq.com/user/index/index.html#cid=66019&term_id=100056181

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章