你的位置:EETOP 赛灵思(Xilinx) 社区 >> >> 全部 >> 详细内容

FPGA时序技巧

发布者:jackzhang 时间:2018-08-15 09:21:10

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

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

最新课程

  • 深入浅出玩儿转FPGA

    本视频基于Xilinx公司的Artix-7FPGA器件以及各种丰富的入门和进阶外设,提供了一些典型的工程实例,帮助读者从FPGA基础知识、逻辑设计概念

  • 从零开始大战FPGA基础篇

    本课程为“从零开始大战FPGA”系列课程的基础篇。课程通俗易懂、逻辑性强、示例丰富,课程中尤其强调在设计过程中对“时序”和“逻辑”的把控,以及硬件描述语言与硬件电路相对应的“

  • Verilog基础及典型数字

    课程中首先会给大家讲解在企业中一般数字电路从算法到流片这整个过程中会涉及到哪些流程,都分别使用什么工具,以及其中每个流程都分别做了