module fifo (clk, rstp, din, writep, readp, dout, emptyp, fullp);
input clk; input rstp; //复位信号 input [15:0] din; input readp; //读信号 input writep; //写信号 output [15:0] dout; output emptyp; //空标志 output fullp; //满标志 parameter DEPTH = 2, MAX_COUNT = 2‘b11; //定义地址最大值 reg emptyp; reg fullp; reg [15:0] dout; reg [(DEPTH-1):0] tail; //定义读指针 reg [(DEPTH-1):0] head; //定义写指针 // 定义计数器 reg [(DEPTH-1):0] count; reg [15:0] fifomem[0:MAX_COUNT]; //定义fifomem存储器有4个16位的存储器
// dout被赋给tail指向的值 always @(posedge clk) begin if (rstp == 1) begin dout <= 16‘h0000; //复位信号有效置0 end else begin dout <= fifomem[tail]; //将fifomem中第tail个单元赋给dout end end always @(posedge clk) begin if (rstp == 1'b0 && writep == 1'b1 && fullp == 1'b0) begin fifomem[head] <= din; //写入 end end always @(posedge clk) begin if (rstp == 1'b1) begin head <= 2‘b00; //复位 end else begin if (writep == 1'b1 && fullp == 1'b0) begin head <= head + 1; end end end
always @(posedge clk) begin if (rstp == 1'b1) begin tail <= 2‘b00; //复位 end else begin if (readp == 1'b1 && emptyp == 1'b0) begin tail <= tail + 1; end end end always @(posedge clk) begin if (rstp == 1'b1) begin count <= 2'b00; end else begin case ({readp, writep}) 2'b00: count <= count; 2'b01: if (count != MAX_COUNT) count <= count + 1; //为写状态时计数器进行加法计数 2'b10: if (count != 2'b00) count <= count - 1; //为读状态计数器进行减法计数 2'b11: count <= count; endcase end end
always @(count) begin if (count == 2'b00) emptyp <= 1‘b1; //count为0时emptyp赋为1 else emptyp <= 1'b0; end
always @(count) begin if (count == MAX_COUNT) fullp <= 1‘b1; //计数到最大时fullp赋为1 else fullp <= 1'b0; end
endmodule
//测试代码:
module test_fifo;
reg clk; reg rstp; reg [15:0] din; reg readp; reg writep; wire [15:0] dout; wire emptyp; wire fullp;
reg [15:0] value; fifo U1 (.clk(clk),.rstp(rstp),.din(din),.readp(readp),.writep(writep),.dout(dout), .emptyp(emptyp),.fullp(fullp));
task read_word; begin @(negedge clk); readp = 1; @(posedge clk) #5; readp = 0; end endtask
task write_word; input [15:0] value; begin @(negedge clk); din = value; writep = 1; @(posedge clk); #5; din = 16'hzzzz; writep = 0; end endtask
initial begin clk = 0; forever begin #10 clk = 1; #10 clk = 0; end end
initial begin test1; end
task test1; begin din = 16'hzzzz; writep = 0; readp = 0; rstp = 1; #50 rstp = 0; #50; write_word (16'h1111); write_word (16'h2222); write_word (16‘h3333); //写入3个数据 read_word; read_word; //读两个 write_word (16‘h4444); //在写一个数据 repeat (6) begin read_word; end
write_word (16'h0001); write_word (16'h0002); write_word (16'h0003); write_word (16'h0004); write_word (16'h0005); write_word (16'h0006); write_word (16'h0007); write_word (16'h0008); repeat (6) begin read_word; end end endtask
endmodule
|
|