FPGA时序技巧

热度101票  浏览816次 【共0条评论】【我要评论 时间:2018年8月15日 09:21

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

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

对本篇资讯内容的质量打分:
当前平均分:-0.35 (52次打分)
【已经有49人表态】
8票
感动
11票
路过
2票
高兴
7票
难过
5票
搞笑
2票
愤怒
7票
无聊
7票
同情
上一篇 下一篇
查看全部回复【已有0位网友发表了看法】