利用RAM实现a,b两路数据延迟
时间:10-02
整理:3721RD
点击:
想利用RAM块实现a,b两路数据的延迟,其中a,b都是32位,速率为61.44Mb/s ,要求a路延迟16个数据时钟周期,b路延迟8个数据周期
请各位帮忙瞧一瞧代码哪里有问题?我怎么也查不出问题来,也没有报错就是仿真得出的结果不对!
`timescale 1ns / 1ps
//利用RAM实现两路数据的延迟,其中a,b都是32位,速率为61.44Mb/s ,要求a路延迟16个数据时钟周期,b路延迟8个数据周期
module bram_delay(clk_122p88MHz,a,b,a_delay,b_delay);
input clk_122p88MHz;
input [31:0] a;
input [31:0] b;
output [31:0] a_delay;
output [31:0] b_delay;
reg [31:0] a_delay;
reg [31:0] b_delay;
wire[5:0] addra,addrb;
wire[31:0] douta,doutb;
reg[5:0] addra1=0;
reg[5:0] addra2=0;
reg[5:0] addrb1=32;
reg[5:0] addrb2=32;
reg wea=0;
reg web=0;
reg flag=0;
always@(posedge clk_122p88MHz)
begin
flag<= !flag;
if(flag ==1'b1)
begin
a_delay<=a_delay;
b_delay<=b_delay;
wea<=1'b1;
web<=1'b1;
addra2<=addra2;
addrb2<=addrb2;
if(addra1==31)
addra1<=0;
else
addra1<=addra1+1'b1;
if(addrb1==63)
addrb1<=32;
else
addrb1<=addrb1+1'b1;
end
else
begin
wea<=1'b0;
web<=1'b0;
a_delay<=douta;
b_delay<=doutb;
addra1<=addra1;
addrb1<=addrb1;
if(addra1<=15) //控制A路延迟的时间
addra2<=addra1+16;
else
addra2<=addra1-16;
if(addrb1<=39) //控制B路延迟的时间
addrb2<=addrb1+8;//...
else
addrb2<=addrb1-8;
end
end
assign addra=!flag?addra1:addra2;
assign addrb=!flag?addrb1:addrb2;
bram_16 bram_16 (
.clka(clk_122p88MHz), // input clka
.wea(wea), // input [0 : 0] wea
.addra(addra), // input [3 : 0] addra
.dina(a), // input [31 : 0] dina
.douta(douta), // output [31 : 0] douta
.clkb(clk_122p88MHz), // input clkb
.web(web), // input [0 : 0] web
.addrb(addrb), // input [3 : 0] addrb
.dinb(b), // input [31 : 0] dinb
.doutb(doutb) // output [31 : 0] doutb
);
endmodule
利用块RAM实现数据延迟的一些问题:http://bbs.eetop.cn/viewthread.php?tid=431323
请各位帮忙瞧一瞧代码哪里有问题?我怎么也查不出问题来,也没有报错就是仿真得出的结果不对!
`timescale 1ns / 1ps
//利用RAM实现两路数据的延迟,其中a,b都是32位,速率为61.44Mb/s ,要求a路延迟16个数据时钟周期,b路延迟8个数据周期
module bram_delay(clk_122p88MHz,a,b,a_delay,b_delay);
input clk_122p88MHz;
input [31:0] a;
input [31:0] b;
output [31:0] a_delay;
output [31:0] b_delay;
reg [31:0] a_delay;
reg [31:0] b_delay;
wire[5:0] addra,addrb;
wire[31:0] douta,doutb;
reg[5:0] addra1=0;
reg[5:0] addra2=0;
reg[5:0] addrb1=32;
reg[5:0] addrb2=32;
reg wea=0;
reg web=0;
reg flag=0;
always@(posedge clk_122p88MHz)
begin
flag<= !flag;
if(flag ==1'b1)
begin
a_delay<=a_delay;
b_delay<=b_delay;
wea<=1'b1;
web<=1'b1;
addra2<=addra2;
addrb2<=addrb2;
if(addra1==31)
addra1<=0;
else
addra1<=addra1+1'b1;
if(addrb1==63)
addrb1<=32;
else
addrb1<=addrb1+1'b1;
end
else
begin
wea<=1'b0;
web<=1'b0;
a_delay<=douta;
b_delay<=doutb;
addra1<=addra1;
addrb1<=addrb1;
if(addra1<=15) //控制A路延迟的时间
addra2<=addra1+16;
else
addra2<=addra1-16;
if(addrb1<=39) //控制B路延迟的时间
addrb2<=addrb1+8;//...
else
addrb2<=addrb1-8;
end
end
assign addra=!flag?addra1:addra2;
assign addrb=!flag?addrb1:addrb2;
bram_16 bram_16 (
.clka(clk_122p88MHz), // input clka
.wea(wea), // input [0 : 0] wea
.addra(addra), // input [3 : 0] addra
.dina(a), // input [31 : 0] dina
.douta(douta), // output [31 : 0] douta
.clkb(clk_122p88MHz), // input clkb
.web(web), // input [0 : 0] web
.addrb(addrb), // input [3 : 0] addrb
.dinb(b), // input [31 : 0] dinb
.doutb(doutb) // output [31 : 0] doutb
);
endmodule
延迟很容易做呢,
1.使用一位使能位(记作a)当作数据输入,用一个16位(或者8位)把使能位延迟16(8)个时钟周期(记作b),然后用fifo做延迟输出可以,写使能是a,读使能是b,但 fifo的大小要大于延迟长度。
2.使用16组(8组)寄存器 将数据缓存16(8)个时钟也可以
双口RAM,有点复杂,暂时你的代码是不对的
可以参考一下这个代码
- `timescale 1ns / 1ps
- //////////////////////////////////////////////////////////////////////////////////
- // Company:
- // Engineer:
- //
- // Create Date: 20:51:45 12/15/2013
- // Design Name:
- // Module Name: bram_delay
- // Project Name:
- // Target Devices:
- // Tool versions:
- // Description:
- //
- // Dependencies:
- //
- // Revision:
- // Revision 0.01 - File Created
- // Additional Comments:
- //
- //////////////////////////////////////////////////////////////////////////////////
- module bram_delay(
- input wire clk,
- input wire rst_n,
- input wire[31:0] a_in,
- input wire[31:0] b_in,
- output reg[31:0] a_delay,
- output reg[31:0] b_delay);
- /*************************************************************************/
- parameter DEL = 1;
- /*************************************************************************/
- wire[5:0] a_addr;
- wire[5:0] b_addr;
- wire[31:0] douta;
- wire[31:0] doutb;
- reg[5:0] a_addr1 = 6'd0;
- reg[5:0] a_addr2 = 6'd0;
- reg[5:0] b_addr1 = 6'd32;
- reg[5:0] b_addr2 = 6'd32;
- reg wea = 1'b0;
- reg web = 1'b0;
- reg flag = 1'b0;
-
- /**************************************************************************/
- always @ ( posedge clk)
- begin
- if( rst_n == 1'b0 )
- begin
- a_delay <= 32'b0;
- b_delay <= 32'b0;
- end
- else begin
- flag <= #DEL !flag;
- if( flag == 1'b1)
- begin
- a_delay <= #DEL a_delay;
- b_delay <= #DEL b_delay;
- wea <= #DEL 1'b1;
- web <= #DEL 1'b1;
- a_addr2 <= #DEL a_addr2;
- b_addr2 <= #DEL b_addr2;
- if( a_addr1 == 6'd31)
- a_addr1 <= #DEL 6'd0;
- else
- a_addr1 <= #DEL a_addr1 + 6'b1;
- if( b_addr1 == 6'd63)
- b_addr1 <= #DEL 6'd0;
- else
- b_addr1 <= #DEL b_addr1 + 6'b1;
- end
- else
- begin
- a_delay <= #DEL douta;
- b_delay <= #DEL doutb;
- wea <= #DEL 1'b0;
- web <= #DEL 1'b0;
- a_addr1 <= #DEL a_addr1;
- b_addr1 <= #DEL b_addr1;
- if( a_addr1 <= 6'd15)
- a_addr2 <= #DEL a_addr1 + 6'd16;
- else
- a_addr2 <= #DEL a_addr1 - 6'd16;
- if( b_addr1 <= 6'd39)
- b_addr2 <= #DEL b_addr1 + 6'd24;
- else
- b_addr2 <= #DEL b_addr1 - 6'd8;
- end
- end
- end
- /*************************************************************************/
- assign a_addr = !flag ? a_addr1 : a_addr2;
- assign b_addr = !flag ? b_addr1 : b_addr2;
- /**************************************************************************/
- bram_16 dut (
- .clka(clk), // input clka
- .wea(wea), // input [0 : 0] wea
- .addra(a_addr), // input [5 : 0] addra
- .dina(a_in), // input [15 : 0] dina
- .douta(douta), // output [15 : 0] douta
- .clkb(clk), // input clkb
- .web(web), // input [0 : 0] web
- .addrb(b_addr), // input [5 : 0] addrb
- .dinb(b_in), // input [15 : 0] dinb
- .doutb(doutb) // output [15 : 0] doutb
- );
- endmodule
利用块RAM实现数据延迟的一些问题:http://bbs.eetop.cn/viewthread.php?tid=431323
现在的程序相当于是在程序第一个clk_122p88MHz上升沿处理 if(flag ==1'b1) 后的程序,第二个clk_122p88MHz上升沿处理else后的程序。还有一个错误是程序没有初始化存储器 a_delay和b_delay;
设计fpga程序,首先要画出时序逻辑图,然后根据逻辑图来编写程序,这样编写完程序后就可以有目的的验证,不要先动手编程序,要不然还要从头开始设计。