加班猫

如果我那天发财了,我会告诉你,我比你强的地方就是,我知道你不知道,你知道的都是废话。

FPGA时序技巧

0
阅读(488) 评论(0)

   FPGA写代码写久了需要点技巧。程序健壮性,稳定性很需要考虑。

   比如说一个例子,把一个RAMA的数据写入另外一个RAMB中。

   新手肯定是读一个写一个。关键问题是,RAM的厂家的IP读数据过程是会有一个时钟或者2个时钟延时问题。所以很多人写的代码如下:

   always @(clk)

    begin

        case(ram_STATE)

           ramA_en_wraddr:

           ramA_en_delaytwo:

           ramB_en_wrout:

    end

       从RAMA到RAMB  搬移数据,花费的时间是4*地址 *clk时间,尤其是地址超过256长度,容易引起前端的ram的数据覆盖的问题。

       这个时候解决问题方式是把数据和地址分开不同模块写的。这个也是sdram操作核心思想之一。

      always @(clk)

     begin

           case(ram_STATE)

               ramA_en_wraddr:

     end      

     

     wire  rama_en;

    assign  ram_en =(ram_STATE == ramA_en_wraddr);

    ///// delaytwo time

    reg rama_en_delayone;

   reg  rama_en_delaytwo;

   always @(posedge clk)

  begin

    rama_en_delayone <= rama_en;

    rama_en_delaytwo <= rama_en_delayone ;

  end

    

   always @(posedge clk)

  begin

        if( rama_en_delaytwo)

            ramb_wrdata <= rama_rddata;

  end

   上面是数据是延时2个时钟之后的。地址也是必须延时2个时钟再给RAMB.


    reg[5:0] rama_addr_delayone;

   reg[5:0]  rama_addr_delaytwo;

   always @(posedge clk)

  begin

    rama_addr_delayone<= rama_addr;

    rama_addr_delaytwo<= rama_en_delayone ;

  end


 assign ramb_addr = (rama_en_delaytwo)?rama_addr_delaytwo:0};

   肯定有人觉得 这种ramb地址赋值方式,是没有时钟输出,会导致时序约束不好的。但是地址延时后,数据也是必须延时。

   //////延时数据 

   always @(posedge clk)

  begin

            rama_rddata_delay<= rama_rddata;

  end

   注意rama-en 也得延时三次

   always @(posedge clk)

  begin

         if( rama_en_delaythree)

            ramb_wrdata <= rama_rddata_delay;

  end

/////////////ramb地址赋值

   always @(posedge clk)

  begin

    if(rama_en_delaythree)

     ramb_addr <= rama_addr_delaytwo;

    else

     ramb_addr <= 0;

end


 以上的代码不是完整的代码。只是提供一些思路。