module ex_case(
input wire rst,
input wire sclk,
output reg o_dv, //表示有效
output reg [7:0] o_data, //寄存器——低电平把数据输入D端,高电平的时候保持数据
//数据输入
input wire [9:0] i_data,
input wire [7:0] i_addr
);
reg [2:0] cnt;
//不同功能的寄存器分开always块来写,这样代码的可维护性强,可读性强
always @ (posedge sclk or negedge rst) begin
if(rst == 1'b0)
cnt <= 3'b0;
else
cnt <= cnt + 1'b1;
end
always @ (posedge sclk or negedge rst) //异步复位
if(rst == 1'b0) begin
o_data <= 8'b0;
o_dv <= 1'b0; //如果后面需要用到O_dv,则需要对它进行赋初值
end
else begin
case(cnt) //case语句相当于编码器或译码器,if_else相当于选择器
3'd0: begin
o_data <= 3'd7;
o_dv <= 1'b1;
end
3'd1: begin
o_data <= 3'd0;
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
endcase
end
//消除锁存器latch:
//1.敏感列表写全,case条件,赋值语句的右边的变量加入到敏感列表里面
//2.所有条件分支写全
/* 组合逻辑写法
always @ (cnt) begin
case(cnt) //case语句相当于编码器或译码器,if_else相当于选择器
3'd0: begin
o_data <= 3'd7;
o_dv <= 1'b1;
end
3'd1: begin
o_data <= 3'd0;
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
endcase
end
*/
endmodule
FPGA应用:
- 接口
- 算法:图像、通信
- 集成产品
//testbench模块
`timescale 1ns/1ns
module tb_ex_case;
reg sclk,rst;
wire [7:0] data; //输出只能接wire变量
wire dv;
reg [7:0] i_addr;
reg [9:0] i_data;
initial begin
sclk = 0;
rst = 0;
#200
rst = 1;
end
initial begin
#500
send_data(255);
end
always #10 sclk <= ~sclk; //周期为20ns的时钟
ex_case tb_ex_case1 (
.rst(rst),
.sclk(sclk),
.o_dv(dv),
.o_data(data),
.i_addr(i_addr),
.i_data(i_data)
);
//做协议或者在testbench中产生数据,用task非常方便
//阻塞赋值——直接赋值,非阻塞赋值——延时一拍后赋值过去
task send_data (len); //任务声明
integer i; //变量声明区,默认32位
begin
for(i=0;i<=len;i=i+1) begin //循环语句
@(posedge sclk); //随着时钟节拍+1
i_addr <= i[7:0];
i_data <= i[7:0];
end
i_addr <= 0;
i_data <= 0;
end
endtask
endmodule