用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后變數的聲明有順序要求,任務使能語句中參數列表順序應與之一直。新的波形圖: