search
尋找貓咪~QQ 地點 桃園市桃園區 Taoyuan , Taoyuan

【精品博文】學習FPGA第一天

用case語句實現一個計數器

module ex_case(

input wire rst_n,

input wire sclk,

output reg o_dv, //標誌數據有效

output reg [7:0] o_data, //用於數據輸入

input wire [9:0] i_data,

input wire [7:0] i_addr

);

reg [2:0] cnt_7;

//不同功能的寄存器分開always塊來寫,這樣代碼的可維護性和可讀性強.

always @(posedge sclk or negedge rst_n)

if(rst_n == 1'b0)

cnt_7 <= 3'd0;

else

cnt_7 <= cnt_7 + 1'b1; //溢出,低三位重新為0

if(rst_n == 1'b0)begin

o_data<=8'd0;

o_dv<=1'b0; //如果不賦初值,複位會接在o_dv使能端。

end

else begin

case(cnt_7)

3'd0:begin

o_data<=3'd7; //當cnt_7等於3'd0時,執行此條語句。如果:后多條語句,加beginend

o_dv<=1'b1;

end

3'd1:begin

o_data<=3'd0; //case endcase 比if else 快.相當於解碼器

o_dv<=1'b0;

end

3'd2:begin

o_data<=3'd5;

o_dv<=1'b1;

end

default:begin

o_data<=3'd0;

o_dv<=1'b0;

end //case語句一定要有default

endcase //case語句只能在always塊里,也是并行語句,滿足case條件執行

end

endmodule

//在消除鎖存器,鎖存器在FPGA里不能用,延時無法時序分析,而且FPGA每一次綜合布線是不固定的。 只有在電平觸發時,case沒有寫全才會有鎖存器出現。

//1、敏感列表寫全,case條件,在賦值語句右邊的變數也要加入敏感列表裡.

//2、所有條件分支寫全

//always @(cnt_7)

// case(cnt_7)

//3'd0:begin

// o_data<=3d'7;

//o_dv<=1'b1;

// end

// 3'd1:begin

// o_data<=3d'0;

// o_dv<=1'b0;

// end

// 3'd2:begin

// o_data<=3d'5;

// o_dv<=1'b1;

// end

// default:begin

// o_data<=3d'0;

// end

// endcase

testbench:

`timescale 1ns/1ns

module tb_ex_case;

reg sclk,rst_n;

wire [7:0] data;

wire dv;

reg [7:0] i_addr;

reg [9:0] i_data;

initial begin

sclk =0;

rst_n =0;

#200

rst_n =1;//不用設置位寬,tb因為不可綜合

end

initial begin

#500

send(255);

end

always #10 sclk <= ~sclk;

ex_case ex_case_inst(

.rst_n (rst_n),

.sclk (sclk),

.o_dv (dv),

.o_data (data),

.i_data (i_data),

.i_addr (i_addr)

);

task send_data(len); //任務的聲明,過程描述

integer len,i;

//變數聲明區,在可綜合模塊不用integer 它指32位整型

begin

for(i=0;i<len;i=i+1)begin //循環語句

@(posedge sclk);

i_addr<=i[7:0];

i_data<=i[7:0];

end

i_addr<=0;

i_data<=0;

end

endtask

endmodule

sclk和rst_n信號線都為金線,延時很短,而其它埠多為銅線,一般不用posedge、negedge來寫。

在modelsim模擬時提示「len」信號already declared in this scope ,

task send_data(len); //任務的聲明,過程描述

integer len,i;

於是交換順序無報錯:integer len,i;

task send_data(len);

可能是modelsim有要求,在塊裡邊出現之前,必須先做聲明。(已經弄明白了task聲明的要求)

測試后發現寫的程序有問題,i_data和i_addr的波形圖有問題:

將len加入波形,發現它一直是1,考慮到時位寬問題沒有處理好,task send_data(len) len默認為1bit,代碼改為:

task后變數的聲明有順序要求,任務使能語句中參數列表順序應與之一直。新的波形圖:



熱門推薦

本文由 yidianzixun 提供 原文連結

寵物協尋 相信 終究能找到回家的路
寫了7763篇文章,獲得2次喜歡
留言回覆
回覆
精彩推薦