FPGA学习FIFO轮询

FIFO轮询检测

功能需求

需求

模块图

模块

时序图

时序

代码

fifo_polling.v

module fifo_polling (
    input wire fifo1_clk,
    input wire fifo2_clk,
    input wire fifo3_clk,
    input wire fifo4_clk,
    input wire [31:0]fifo1_data,
    input wire [31:0]fifo2_data,
    input wire [31:0]fifo3_data,
    input wire [31:0]fifo4_data,
    input wire wrreq,
    input wire rst_n,
    input wire polling_rst_n,
    input wire polling_clk,
    output reg data_valid,
    output wire [63:0]up_data
);

wire [13:0]wrusedw_fifo1;

wire [13:0]wrusedw_fifo2;

wire [13:0]wrusedw_fifo3;

wire [13:0]wrusedw_fifo4;

reg [6:0]cnt_polling;
reg [3:0]cnt_state;
reg rdreq_fifo1;
reg rdreq_fifo2;
reg rdreq_fifo3;
reg rdreq_fifo4;

wire [63:0]fifo1_q;
wire [63:0]fifo2_q;
wire [63:0]fifo3_q;
wire [63:0]fifo4_q;

//轮询四个fifo 0:检测fifo1 2:检测fifo2 4:检测fifo3 6:检测fifo4
always @(posedge polling_clk or negedge polling_rst_n) begin
    if (~polling_rst_n) begin
        cnt_state <= 4'd0;
    end
    else if (cnt_state == 4'd8) begin
        cnt_state <= 4'd0;
    end
    else if (rdreq_fifo1||rdreq_fifo2||rdreq_fifo3||rdreq_fifo4) begin
        cnt_state <= cnt_state;//读数据时,轮询状态保持
    end
    else begin
        cnt_state <= cnt_state + 4'd1;
    end
end

always @(posedge polling_clk or negedge polling_rst_n) begin
    if (~polling_rst_n) begin
        rdreq_fifo1 <= 1'b0;
    end
    else if (rdreq_fifo1 == 1'd0) begin
        if (cnt_state == 4'd0 && wrusedw_fifo1 > 255) begin
            rdreq_fifo1 <= 1'd1;//低电平时,轮询状态到0且fifo1达到255的阈值,拉高电平。拉高后不在受wrusedw影响。
        end
        else begin
            rdreq_fifo1 <= rdreq_fifo1;
        end
    end
    else begin
        if (cnt_polling == 7'd127) begin//电平拉高127个周期后,读出1024个比特的数据后拉低。
            rdreq_fifo1 <= 1'd0;
        end
        else begin
            rdreq_fifo1 <= rdreq_fifo1;
        end
    end
end

always @(posedge polling_clk or negedge polling_rst_n) begin
    if (~polling_rst_n) begin
        rdreq_fifo2 <= 1'b0;
    end
    else if (rdreq_fifo2 == 1'd0) begin
        if (cnt_state == 4'd2 && wrusedw_fifo2 > 255) begin
            rdreq_fifo2 <= 1'd1;
        end
        else begin
            rdreq_fifo2 <= rdreq_fifo2;
        end
    end
    else begin
        if (cnt_polling == 7'd127) begin
            rdreq_fifo2 <= 1'd0;
        end
        else begin
            rdreq_fifo2 <= rdreq_fifo2;
        end
    end
end

always @(posedge polling_clk or negedge polling_rst_n) begin
    if (~polling_rst_n) begin
        rdreq_fifo3 <= 1'b0;
    end
    else if (rdreq_fifo3 == 1'd0) begin
        if (cnt_state == 4'd4 && wrusedw_fifo3 > 255) begin
            rdreq_fifo3 <= 1'd1;
        end
        else begin
            rdreq_fifo3 <= rdreq_fifo3;
        end
    end
    else begin
        if (cnt_polling == 7'd127) begin
            rdreq_fifo3 <= 1'd0;
        end
        else begin
            rdreq_fifo3 <= rdreq_fifo3;
        end
    end
end

always @(posedge polling_clk or negedge polling_rst_n) begin
    if (~polling_rst_n) begin
        rdreq_fifo4 <= 1'b0;
    end
    else if (rdreq_fifo4 == 1'd0) begin
        if (cnt_state == 4'd6 && wrusedw_fifo4 > 255) begin
            rdreq_fifo4 <= 1'd1;
        end
        else begin
            rdreq_fifo4 <= rdreq_fifo4;
        end
    end
    else begin
        if (cnt_polling == 7'd127) begin
            rdreq_fifo4 <= 1'd0;
        end
        else begin
            rdreq_fifo4 <= rdreq_fifo4;
        end
    end
end



always @(posedge polling_clk or negedge polling_rst_n) begin
    if (~polling_rst_n) begin
        cnt_polling <= 7'd0;
    end
    else if (rdreq_fifo1 || rdreq_fifo2 || rdreq_fifo3 || rdreq_fifo4) begin
        cnt_polling <= cnt_polling + 7'd1;//读使能拉高时计数。
    end
    else begin
        cnt_polling <= 7'd0;
    end
end

always @(posedge polling_clk or negedge polling_rst_n) begin
    if (~polling_rst_n) begin
        data_valid <= 1'd0;
    end
    else begin//综合四个读使能信号
        data_valid <= rdreq_fifo1 || rdreq_fifo2 || rdreq_fifo3 || rdreq_fifo4;
    end
end

reg rdreq_fifo1_r1;
reg rdreq_fifo2_r1;
reg rdreq_fifo3_r1;
reg rdreq_fifo4_r1;

always @(posedge polling_clk or negedge polling_rst_n) begin
    if (~polling_rst_n) begin
        rdreq_fifo1_r1 <= 1'd0;
    end
    else begin
        rdreq_fifo1_r1 <= rdreq_fifo1;
    end
end

always @(posedge polling_clk or negedge polling_rst_n) begin
    if (~polling_rst_n) begin
        rdreq_fifo2_r1 <= 1'd0;
    end
    else begin
        rdreq_fifo2_r1 <= rdreq_fifo2;
    end
end

always @(posedge polling_clk or negedge polling_rst_n) begin
    if (~polling_rst_n) begin
        rdreq_fifo3_r1 <= 1'd0;
    end
    else begin
        rdreq_fifo3_r1 <= rdreq_fifo3;
    end
end

always @(posedge polling_clk or negedge polling_rst_n) begin
    if (~polling_rst_n) begin
        rdreq_fifo4_r1 <= 1'd0;
    end
    else begin
        rdreq_fifo4_r1 <= rdreq_fifo4;
    end
end

assign up_data = (rdreq_fifo1_r1)?fifo1_q:
                 (rdreq_fifo2_r1)?fifo2_q:
                 (rdreq_fifo3_r1)?fifo3_q:
                 (rdreq_fifo4_r1)?fifo4_q:64'd0;


ip_fifo1	ip_fifo1_inst (
	.data ( fifo1_data ),
	.rdclk ( polling_clk ),
	.rdreq ( rdreq_fifo1 ),
	.wrclk ( fifo1_clk ),
	.wrreq ( wrreq ),
	.q ( fifo1_q ),
	.wrusedw ( wrusedw_fifo1 )
);

ip_fifo2	ip_fifo2_inst (
	.data ( fifo2_data ),
	.rdclk ( polling_clk ),
	.rdreq ( rdreq_fifo2 ),
	.wrclk ( fifo2_clk ),
	.wrreq ( wrreq ),
	.q ( fifo2_q ),
	.wrusedw ( wrusedw_fifo2 )
);

ip_fifo3	ip_fifo3_inst (
	.data ( fifo3_data ),
	.rdclk ( polling_clk),
	.rdreq ( rdreq_fifo3 ),
	.wrclk ( fifo3_clk ),
	.wrreq ( wrreq ),
	.q ( fifo3_q ),
	.wrusedw ( wrusedw_fifo3 )
);

ip_fifo4	ip_fifo4_inst (
	.data ( fifo4_data ),
	.rdclk ( polling_clk ),
	.rdreq ( rdreq_fifo4 ),
	.wrclk ( fifo4_clk ),
	.wrreq ( wrreq ),
	.q ( fifo4_q ),
	.wrusedw ( wrusedw_fifo4 )
);

endmodule

tb文件

`timescale 1ns/1ps

module fifo_tb ();
    
reg fifo1_clk;
reg fifo2_clk;
reg fifo3_clk;
reg fifo4_clk;
reg [31:0]fifo1_data;
reg [31:0]fifo2_data;
reg [31:0]fifo3_data;
reg [31:0]fifo4_data;
reg wrreq;
reg rst_n;
reg polling_rst_n;
reg polling_clk;
wire data_valid;
wire [63:0]up_data;

initial begin
    fifo1_clk = 1'd0;
    fifo2_clk = 1'd0;
    fifo3_clk = 1'd0;
    fifo4_clk = 1'd0;
    polling_clk = 1'd0;
    wrreq = 1'd1;
    rst_n = 1'd0;
    polling_rst_n= 1'd0;
    #2
    rst_n = 1'd1;
    polling_rst_n= 1'd1;
end

always #20 fifo1_clk = ~fifo1_clk;
always #15 fifo2_clk = ~fifo2_clk;
always #50 fifo3_clk = ~fifo3_clk;
always #100 fifo4_clk = ~fifo4_clk;
always #10 polling_clk = ~polling_clk;

always #20 fifo1_data = {$random} % 1024;
always #15 fifo2_data = {$random} % 1024;
always #50 fifo3_data = {$random} % 1024;
always #100 fifo4_data = {$random} % 1024;

fifo_polling fifo_polling_1 (
    .fifo1_clk(fifo1_clk),
    .fifo2_clk(fifo2_clk),
    .fifo3_clk(fifo3_clk),
    .fifo4_clk(fifo4_clk),
    .fifo1_data(fifo1_data),
    .fifo2_data(fifo2_data),
    .fifo3_data(fifo3_data),
    .fifo4_data(fifo4_data),
    .wrreq(wrreq),
    .rst_n(rst_n),
    .polling_rst_n(polling_rst_n),
    .polling_clk(polling_clk),
    .data_valid(data_valid),
    .up_data(up_data)
);

endmodule

仿真

在这里插入图片描述

在这里插入图片描述

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值