在线咨询
eetop公众号 创芯大讲堂 创芯人才网
切换到宽版

EETOP 创芯网论坛 (原名:电子顶级开发网)

手机号码,快捷登录

手机号码,快捷登录

找回密码

  登录   注册  

快捷导航
搜帖子
查看: 4540|回复: 15

关于同步fifo的怪事!!!!

[复制链接]
发表于 2007-1-16 08:53:14 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?注册

x
我用同步fifo程序是xinlinx的ipcore自动生成的4.0版本的程序,将它的verilog语言程序复制到modelsim下仿真,在输入时钟直接给出时可以读写!
     但是若用一个分频后的时钟作为它的输入时钟,就不能写入数据,我已经试了好几天还是不行,不知为什么??

完整的测试程序及原程序都在下面的回复中(附件中也是),请热心的大侠帮忙解惑,不胜感激!!

[ 本帖最后由 liumeco 于 2007-1-17 14:48 编辑 ]

新建文件夹.rar

3.78 KB, 下载次数: 13 , 下载积分: 资产 -2 信元, 下载支出 2 信元

同步fifo怪事

发表于 2007-1-16 13:05:33 | 显示全部楼层
你可以直接八程序贴在这里,下附件要扣money的
 楼主| 发表于 2007-1-16 14:52:10 | 显示全部楼层
测试程序:
module teetestt;
reg clk,rst,WR_EN,RD_EN;
reg [15:0] data;
wire clk_out,FULL,EMPTY,RD_ACK,WR_ACK,RD_ERR,WR_ERR;
wire [3:0] DATA_COUNT;
wire [15:0] DOUT;

always #50 clk= ~ clk;
initial
begin
rst=1;
WR_EN=0;
RD_EN=0;
clk=0;
data=16'b1010010011110101;
#100 rst=0;
#100 WR_EN=1;
#8000 WR_EN=0;
#100  RD_EN=1;
#2000 RD_EN=0;
end
always @(posedge clk)
  data={data[14:0],data[15]};
  
fdivision fdivision(.rst(rst),
                    .clk_in(clk),
                    .clk_out(clk_out)
                    );
SYNC_FIFO_V4_0 lhh(  .CLK(clk_out),
                .SINIT(rst),
                .DIN(data),   
                .WR_EN(WR_EN),
                .RD_EN(RD_EN),
                .DOUT(DOUT),
                .FULL(FULL),
                .EMPTY(EMPTY),
                .RD_ACK(RD_ACK),
                .WR_ACK(WR_ACK),
                .RD_ERR(RD_ERR),               
                .WR_ERR(WR_ERR),
                .DATA_COUNT(DATA_COUNT)
                 );
endmodule


分频程序***********************************
module fdivision(rst,clk_in,clk_out);
input clk_in,rst;
output clk_out;
reg clk_out;
reg [4:0]j;
initial
clk_out=0;
always @(posedge clk_in)
//clk_out<=!clk_out;
begin
if(rst)
begin
clk_out <= 0;
j <= 0;
end
else
begin
if(j==17)
begin
j <= 0;
clk_out <= ~clk_out;
end
else
j <= j+1;
end
end
endmodule

大家注意:这个分频器如果使用clk_out<=!clk_out;进行2分频就能写入数据,但是使用后面的程序则不行!为什么呢?后面的程序我单独做过测试,都是正确的阿

[ 本帖最后由 liumeco 于 2007-1-19 08:39 编辑 ]
 楼主| 发表于 2007-1-16 14:57:13 | 显示全部楼层
这是同步fifo的程序!

module SYNC_FIFO_V4_0 (  CLK,//Clock for read and write operations (rising edge)
                      SINIT, //Synchronous initialization of all FIFO functions, flags, and pointers
                      DIN,   //Data Input
                      WR_EN,
                      RD_EN,
                      DOUT,  //Data Output
                      FULL,
                      EMPTY,
                      RD_ACK,
                      WR_ACK,
                      RD_ERR,
                      WR_ERR,
                      DATA_COUNT
                       );

/**********************************************************************************
* Parameter Declarations
**********************************************************************************/
  parameter  c_dcount_width          =  4 ; //  width of the dcount . Adjustable by customer
  parameter  c_enable_rlocs          =  0; //
  parameter  c_has_dcount            =  1 ; //
  parameter  c_has_rd_ack            =  1; //
  parameter  c_has_rd_err            =  1; //
  parameter  c_has_wr_ack            =  1; //
  parameter  c_has_wr_err            =  1; //
  parameter  c_memory_type           =  1; //
  parameter  c_ports_differ          =  0; //
  parameter  c_rd_ack_low            =  0; //
  parameter  c_rd_err_low            =  0  ; //   
  parameter  c_read_data_width       =  16  ; //  
  parameter  c_read_depth            =  32  ; //
  parameter  c_write_data_width      =  16 ; //
  parameter  c_write_depth           =  32 ;  //
  parameter  c_wr_ack_low            =  0; //
  parameter  c_wr_err_low            =  0 ; //


parameter addr_max      = (c_write_depth == 16 ? 4:
                          (c_write_depth == 32 ? 5:
                          (c_write_depth == 64 ? 6 :
                          (c_write_depth == 128 ? 7 :
                          (c_write_depth == 256 ? 8 :
                          (c_write_depth == 512 ? 9 :
                          (c_write_depth == 1024 ? 10 :
                          (c_write_depth == 2048 ? 11 :
                          (c_write_depth == 4096 ? 12 :
                          (c_write_depth == 8192 ? 13 :
                          (c_write_depth == 16384 ? 14 :
                          (c_write_depth == 32768 ? 15 :
                          (c_write_depth == 65536 ? 16 : 6)))))))))))));
/***********************************************************************************
* Input and Output Declarations
***********************************************************************************/
input                       CLK;      // CLK Signal.
input                       SINIT;    // High Asserted Reset signal.
input [(c_write_data_width-1):0]      DIN;  // Data Into FIFO.
input                       WR_EN;    // Write into FIFO Signal.
input                       RD_EN;    // Read From FIFO Signal.
output [(c_read_data_width-1):0]      DOUT;   // FIFO Data out.
output                      FULL;     // FIFO Full indicating signal.
output                      EMPTY;    // FIFO Empty indicating signal.
output                      RD_ACK ;  // Read Acknowledge signal
output                      WR_ACK ;  // Write Acknowledge signal
output                      RD_ERR ; // Rejection of RD_EN active on prior clock edge
output                      WR_ERR ; // Rejection of WR_EN active on prior clock edge
output [(c_dcount_width-1):0]        DATA_COUNT ;
reg                FULL;
reg                EMPTY;
wire               RD_ACK_internal ;
wire               WR_ACK_internal ;
wire               RD_ERR_internal ;
wire               WR_ERR_internal ;
wire [(c_dcount_width-1):0] DATA_COUNT_int ;
reg  [(c_dcount_width-1):0] DATA_COUNT ;
integer k,j ;
reg                rd_ack_int ;
reg                rd_err_int ;
reg                wr_ack_int ;
reg                wr_err_int ;
integer            N ;
reg    [addr_max:0]       fcounter;    // counter indicates num of data in FIFO
reg    [addr_max:0]       fcounter_max ; // value of fcounter OR with MSB of fcounter      
reg    [(addr_max-1):0]   rd_ptr;      // current read pointer.
reg    [(addr_max-1):0]   wr_ptr;      // current write pointer.
wire   [(c_write_data_width-1):0]    memory_dataout; // Data Out from the  MemBlk
wire   [(c_write_data_width-1):0]    memory_datain ;  // Data into the  MemBlk
wire   write_allow = (WR_EN && (!FULL)) ;
wire   read_allow = (RD_EN && (!EMPTY)) ;
assign DOUT     = memory_dataout;  
assign memory_datain = DIN;
assign RD_ACK_internal = (c_rd_ack_low == 0 )  ? rd_ack_int : (!rd_ack_int) ;
assign WR_ACK_internal = (c_wr_ack_low == 0 )  ? wr_ack_int : (!wr_ack_int) ;
assign RD_ERR_internal = (c_rd_err_low == 0 )  ? rd_err_int : (!rd_err_int) ;
assign WR_ERR_internal = (c_wr_err_low == 0 )  ? wr_err_int : (!wr_err_int) ;
// assign DATA_COUNT = (c_has_dcount == 0 ) ? {c_dcount_width{1'bX}} : DATA_COUNT_int ;
assign RD_ACK     = (c_has_rd_ack == 0 ) ? 1'bX : RD_ACK_internal ;
assign WR_ACK     = (c_has_wr_ack == 0 ) ? 1'bX : WR_ACK_internal ;
assign RD_ERR     = (c_has_rd_err == 0 ) ? 1'bX : RD_ERR_internal ;
assign WR_ERR     = (c_has_wr_err == 0 ) ? 1'bX : WR_ERR_internal ;     

    MEM_BLK_V4_0 # (addr_max, c_write_data_width, c_write_depth)  memblk(.clk(CLK),
                                                                         .write_en(write_allow),
                                                                         .read_en(read_allow),
                                                                         .rd_addr(rd_ptr),
                                                                         .wr_addr(wr_ptr),
                                                                         .data_in(memory_datain),
                                                                         .data_out(memory_dataout),
                                                                         .rst(SINIT)
                                                                          ) ;
/***********************************************************************************
* Initialize the outputs for simulation purposes
***********************************************************************************/
    initial begin
        wr_ack_int = 0 ;
        rd_ack_int = 0 ;
        rd_err_int = 0 ;
        wr_err_int = 0 ;
        
        FULL = 0 ;
        EMPTY = 1 ;  
        for (k = 0; k < c_dcount_width; k = k + 1)
            DATA_COUNT[k] = 0 ;
    end
// DATA_COUNT assignment
always @(fcounter_max)
begin
  if  ((c_has_dcount == 1) && (c_dcount_width <= addr_max ) )
  begin
    for (j=(addr_max - c_dcount_width); j<addr_max; j=j+1 )
     DATA_COUNT[j-(addr_max - c_dcount_width)] = fcounter_max[j];
  end
end
always @(fcounter)
begin
  if ((c_has_dcount == 1) && (c_dcount_width ==  addr_max + 1 ))  
     DATA_COUNT = fcounter;
end

/***********************************************************************************
* Handshaking signals
***********************************************************************************/
// Read Ack logic
always @(posedge CLK )
begin
    if (SINIT)
        rd_ack_int <= 0 ;
    else
        rd_ack_int <= RD_EN && (! EMPTY);
end
// Write Ack logic
always @(posedge CLK )
begin
    if (SINIT)   
       wr_ack_int <= 0 ;
    else
       wr_ack_int <= WR_EN && (! FULL );
end
// Read Error handshake signal logic
always @(posedge CLK )
begin
    if (SINIT)
       rd_err_int <= 0 ;
    else
       rd_err_int <= RD_EN &&  EMPTY;
end
// Write Error handshake signal logic
always @(posedge CLK )
begin
    if (SINIT)
       wr_err_int <= 0 ;
    else   
       wr_err_int <= WR_EN &&  FULL;
end
always @(fcounter)
begin
for (N = 0 ; N<= addr_max ; N = N + 1)
    fcounter_max[N] = fcounter[addr_max] || fcounter[N] ;

end

// Read Counter
always @(posedge CLK )
begin
   if (SINIT)
      rd_ptr <= 0;
   else begin
      if (read_allow == 1'b1) begin
         if ( rd_ptr == (c_write_depth -1 ))  // Need to support any arbitrary depth
            rd_ptr <= 0 ;
         else
            rd_ptr <= rd_ptr + 1 ;
      end
   end
end
// Write Counter

always @(posedge CLK )
begin
   if (SINIT)
      wr_ptr <= 0;
   else begin
      if (write_allow == 1'b1) begin
         if  ( wr_ptr == (c_write_depth -1 )) // Need to support any arbitrary depth
             wr_ptr <= 0 ;
         else
             wr_ptr <= wr_ptr + 1 ;
      end
   end   
end
// Fifo Content Counter
always @(posedge CLK )
begin
   if (SINIT)
      fcounter <= 0;
   else begin
      case ({write_allow, read_allow})
         2'b00 : fcounter <= fcounter ;
         2'b01 : fcounter <= fcounter - 1 ;
         2'b10 : fcounter <= fcounter + 1 ;
         2'b11 : fcounter <= fcounter ;
      endcase
   end
end

always @(posedge CLK )
begin
  if (SINIT)
     EMPTY <= 1'b1;
  else begin
     if ( ( (fcounter==1) && RD_EN && (!WR_EN)) || ( (fcounter == 0) && (!WR_EN) ) )
          EMPTY <= 1'b1;

     else
          EMPTY <= 1'b0;
  end
end


/***********************************************************************************
* FULL Flag logic
**********************************************************************************/
always @(posedge CLK )
begin

  if (SINIT)

    FULL <= 1'b0;

  else begin

    if (((fcounter == c_write_depth) && (!RD_EN) ) || ((fcounter == c_write_depth-1) && WR_EN && (!RD_EN)))
      
       FULL <= 1'b1;

    else
   
       FULL <= 1'b0;
   
  end
end
      
endmodule


module MEM_BLK_V4_0( clk,
                     write_en,
                     read_en,
                     wr_addr,
                     rd_addr,
                     data_in,
                     data_out,
                     rst
                   );
parameter addr_value = 4  ;
parameter data_width = 16 ;
parameter mem_depth  = 16 ;

input                      clk;       // input clk.
input                      write_en;  // Write Signal to put datainto fifo.
input                      read_en ;
input  [(addr_value-1):0]  wr_addr;   // Write Address.
input  [(addr_value-1):0]  rd_addr;   // Read Address.
input  [(data_width-1):0]  data_in;   // DataIn in to Memory Block
input                      rst ;
output [(data_width-1):0]  data_out;  // Data Out from the Memory Block(FIFO)
reg    [(data_width-1):0]  data_out;  
reg    [(data_width-1):0]  FIFO[0mem_depth-1)];

initial begin
data_out = 0 ;
end
always @(posedge clk)
begin
   if (rst == 1'b1)
      data_out <= 0 ;
   else
      begin
        if (read_en == 1'b1)
          data_out  <= FIFO[rd_addr];
      end
end
always @(posedge clk)
begin
   if(write_en ==1'b1)
      FIFO[wr_addr] <= data_in;
end
endmodule
 楼主| 发表于 2007-1-16 14:58:08 | 显示全部楼层
程序已经全部贴上了,请各位执教!!
 楼主| 发表于 2007-1-17 14:50:48 | 显示全部楼层
则呢么没有人回复呢?难道大家没有遇到过类似的问题吗?
发表于 2007-1-17 23:53:54 | 显示全部楼层
写不进去是什么现象?有波形吗?
 楼主| 发表于 2007-1-18 08:38:14 | 显示全部楼层
就是fifo的计数器一直为0!说明没有数据进入fifo啊!
发表于 2007-1-18 18:25:01 | 显示全部楼层
贴了这么多程序怎么看啊,一步步检查吧,先确定分频后的时钟没有问题,看一下,在一步找呗,应该是程序有问题吧
 楼主| 发表于 2007-1-19 08:43:52 | 显示全部楼层
程序都没有问题的,有问题就是在衔接上,但是实在看不出来!!
能否有大侠帮忙跑一下啊!
贴上去的程序和附件中的一样,都是完整的,可以直接运行!!
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

站长推荐 上一条 /1 下一条

小黑屋| 手机版| 关于我们| 联系我们| 在线咨询| 隐私声明| EETOP 创芯网
( 京ICP备:10050787号 京公网安备:11010502037710 )

GMT+8, 2024-11-17 08:51 , Processed in 0.037795 second(s), 9 queries , Gzip On, Redis On.

eetop公众号 创芯大讲堂 创芯人才网
快速回复 返回顶部 返回列表