一.非阻塞赋值延时打拍
always @ (posedge clk) begin
d1 <= d;
d2 <= d1;
.......
dout <= dn;
end
本质上就是对数据进行多级寄存器缓存,延迟时间以clk的一个周期为单位,消耗的就是寄存器。比较适合延迟固定周期以及延迟周期比较短的情况。
缺点:延迟时间不方便控制,不适合延迟时间比较长的情况。
二、移位寄存器延时
reg [data_width*delay_width-1:00]
data_r=0;
always @ (posedge clk)
begin
data_r <= {data_r[data_width*(delay_width-1)-1:0],data_in};
end
assign data_out=data_r[camera_trig_delay_time];
这种方法利用的是移位寄存器的方法,用的是SLICEM资源。SLICEM可以在不使用触发器的条件下配置为32位移位寄存器(注意:只能左移)。这样,每个LUT可以将串行数据延迟1到32个时钟周期。移位输入D(LUT DI1脚)和移位输出Q31(LUT MC31脚)可以进行级联,以形成更大的移位寄存器,达到更大的延迟效果。这种方法延迟的时间可配置性也比较高。
缺点:占用的资源比较多。尤其当延迟的数量级较大时,拼接的位移寄器是有个数限制的,如下图则是当延迟时间设置比较久的时候vivado报错的截图。
三、计数器实现任意周期延时
这种资源消耗率较低,延迟周期也比较灵活。
parameter delay_per = 8'h4;//延时周期数
reg flag;
reg [7:0] delay_count;
always @(posedge clk or negedge rst_n) begin
if(!rst_n) begin
flag <= 0;
end
else if(in1)begin
flag <= 1;
end
else if(delay_count == delay_per)begin
flag <= 0;
end
end
always @(posedge clk or negedge rst_n) begin
if(!rst_n)begin
delay_count <= 0;
out1 <= 0;
end
else if(delay_count == delay_per && flag == 1'b1)begin
delay_count <= 0;
out1 <= 1;
end
else if(flag == 1'b1)begin
delay_count <= delay_count + 1'b1;
out1 <= 0;
end
else begin
delay_count <= 0;
out1 <= 0;
end
end
这种实现方式比较多,这里摘录了网上的代码。这种方法下,延迟的时间必须小于信号的间隔。因为如果延迟时间大于了信号间隔,就会丢掉信号。
缺点:.延迟时间必须小于信号间隔。
四、大容量存储
对于比较大时间的延迟,可以用RAM或者fifo或者DDR这种存储介质进行缓存延迟文章来源:https://www.toymoban.com/news/detail-512184.html
文章来源地址https://www.toymoban.com/news/detail-512184.html
到了这里,关于FPGA中数据延迟方案汇总的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!