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
以上的代码不是完整的代码。只是提供一些思路。
本视频基于Xilinx公司的Artix-7FPGA器件以及各种丰富的入门和进阶外设,提供了一些典型的工程实例,帮助读者从FPGA基础知识、逻辑设计概念
本课程为“从零开始大战FPGA”系列课程的基础篇。课程通俗易懂、逻辑性强、示例丰富,课程中尤其强调在设计过程中对“时序”和“逻辑”的把控,以及硬件描述语言与硬件电路相对应的“
课程中首先会给大家讲解在企业中一般数字电路从算法到流片这整个过程中会涉及到哪些流程,都分别使用什么工具,以及其中每个流程都分别做了
@2003-2020 中国电子顶级开发网