0

我自己写了一个FPGA 的 fifo总有问题,不知道什么原因?问问大家能否解决

我读写 fifo总有问题,不知道什么原因?问问大家能否解决
写入 1、2、3、4、5、6 的数据
读出时 0、1、2、3、4、5

写入的代码如下:

a_wrdata_r <= rxd_buff [wrdata_index + 1];
if(wrdata_index < 16)
begin
wrdata_index <= wrdata_index + 1;
a_wrreq_r <= 1;
end
else begin
wr_state <= 0;
wrdata_index <= 0;
a_wrreq_r <= 0;
rd_flag <= 1;
end

读出的代码如下

txd_buff [rddata_index+1] <= a_rdq;
if(rddata_index < 16)
begin
rddata_index <= rddata_index + 1;
a_rdreq_r <= 1;
end
else
begin
txd_buff [0] <= 'h13;
rd_state <= 0;
a_rdreq_r <= 0;
fifo_to_txd <= 1;
end
编辑 重设标签(回车键确认) 标为违禁 关闭 合并 删除
匿名用户

匿名

想向站长提问,微信扫码立刻加入! shawn的FPGA圈.png
0

指针问题应该是比较器没+1吧
可能是在同一个上升沿的时候,buffer指针还没有加完就读了,于是读错了

编辑 标为违禁 删除 链接 更多选项...
52fpga 头像

评论

verilog没有指针

xilinx_fpga 头像xilinx_fpga ( 2018-01-24 17:12:12 +0800 )编辑

在设计Fifo的时候,实际也是一块内存,加读写地址,习惯上把这个读写地址称为指针,其实也就是地址addr,在上面代码中是rdata_index.

52fpga 头像52fpga ( 2018-01-24 17:13:05 +0800 )编辑
0

仿真没有?做设计基本流程都不做只是给自己出难题。

编辑 标为违禁 删除 链接 更多选项...
shawn 头像

评论

没有做。。。。。。。。。

xilinx_fpga 头像xilinx_fpga ( 2018-01-24 17:17:46 +0800 )编辑

仿真试一下就能看出错在哪里了,或者你用逻辑分析仪抓一下也可以。

shawn 头像shawn ( 2018-01-24 17:18:21 +0800 )编辑

仿真试一下就能看出错在哪里了,或者你用逻辑分析仪抓一下也可以。

shawn 头像shawn ( 2018-01-24 17:18:31 +0800 )编辑
0

贴一段网上的异步FIFO代码给你,

module async_fifO(
       wclk,
       wr,
       wdat,
       wr_full,
       rclk,
       rd,
       rdat,
       rd_empty,
       resetb
);

parameter DW   = 16;
          AW   = 8;
          DP   = 1<<AW;

input           wclk;
input           wr;
input  [DW-1:0] wdat;
output          wr_full;
input           rclk;
input           rd;
output [DW-1:0] rdat;
output          rd_empty;
input           resetb;
parameter ck2q = 1;

//
//////////////////////////////////////////////////////
// dpram
wire wire_wr = wr && !wr_full;
wire wire_rd = rd && !rd_empty;

dpram    u_dpram(
        .wclk   ( wr_clk  ),
        .wr     ( wire_wr ),
        .waddr  ( waddr   ),
        .wdat   ( wdat    ),
        .rclk   ( rclk    ),
        .rd     ( wire_rd ),
        .raddr  ( raddr   ),
        .rdat   ( rdat    )
);


//
//////////////////////////////////////////////////////
// write address

//============waddr+1=========== 
reg  [AW:0  ] waddr;
wire [AW-1:0] waddr_p1 = waddr + 1'b1;
always@(posedge clkin or negedge resetb)begin
    if(!resetb)
        waddr <= #ck2q 0;
    else if(ie) begin
        waddr <= #ck2q waddrp1;
    end
end
//========bcd to gray reg========
wire [AW:0] waddr_g;
assign      waddr_g[AW]    = waddr_g[AW];
assign      waddr_g[AW-1:0]= waddr_g ^ waddr_g>>1;
reg  [AW:0] waddr_g_w0;
always@(posedge clkin or negedge resetb)begin
    if(!resetb)
        waddr_g_w0 <= #ck2q 0;
    else if(ie) begin
        waddr_g_w0 <= #ck2q waddr_g;
    end
end
//========waddr to rclk domain========
reg  [AW:0] waddr_g_r0,waddr_g_r1;
always@(posedge clkout or negedge resetb)begin
    if(!resetb)begin
        waddr_g_r0 <= #ck2q 0;
        waddr_g_r1 <= #ck2q 0;
    end
    else begin
        waddr_g_r0 <= waddr_g_w0;
        waddr_g_r1 <= waddr_g_r0;
    end
end
//=========gray to bcd========
reg [AW:0] waddr_r1;
integer j;
always@(waddr_g_r1)begin
        waddr_r1[AW] = waddr_g_r1[AW];
    for(j=AW-1;j>0;j=j-1)begin
        waddr_r1[j ] = waddr_g_r1[j ] ^ waddr_r1 [j+1];
    end
end


//
///////////////////////////////////////////////////////////////
//read address

//========raddr+1========
reg  [AW:0] raddr;
wire [AW:0] raddrp1 = raddr + 1'b1;
always@(posedge clkout or negedge resetb)begin
    if(!resetb)
        raddr <= #ck2q 0;
    else if(oe) begin
        raddr <= #ck2q raddrp1;
    end
end

//========bcd to gray reg========
wire [AW:0] raddr_g;
assign      raddr_g[AW    ] = raddr[AW];
assign      raddr_g[AW-1:0] = raddr^raddr>>1;
reg  [AW:0] raddr_g_r0;
always@(posedge clkout or negedge resetb)begin
    if(!resetb)
        raddr_g_r0 <= #ck2q 0;
    else if(oe) begin
        raddr_g_r0 <= #ck2q raddr_g;
    end
end
//========rd_addr to wr domain========
reg  [AW:0] raddr_g_w0,raddr_g_w1;
always@(posedge clkin or negedge resetb)begin
    if(!resetb)begin
        raddr_g_w0 <= #ck2q 0;
        raddr_g_w1 <= #ck2q 0;
    end
    else begin
        raddr_g_w0 <= #ck2q raddr_g_r0;
        raddr_g_w1 <= #ck2q raddr_g_w0;
    end
end
//========gray to bcd======== 
reg [AW:0] raddr_w1;
integer i;
always@(raddr_g_w1)begin
       raddr_w1[AW] = raddr_g_w1[AW];
    for(i=AW-1;i>0;i=i-1)begin
       raddr_w1[i ] = radr_g_w1[i ] ^ raddr_w1[i+1];
    end
end


//
///////////////////////////////////////////////////////////////////
//

//=======wr_full//rd_empty====
assign wr_full  = ( wire_ie && !(waddr[AW]&&raddr_w1[AW]) && (waddr[AW-1:0]==raddr_w1[AW-1:0]) );
assign rd_empty = (             (raddr[AW]&&waddr_r1[AW]) && (raddr[AW-1:0]==waddr_r1[AW-1:0]) );

endmodule
编辑 标为违禁 删除 链接 更多选项...
inner 头像
登录/注册后进行回答