微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > FPGA,CPLD和ASIC > 利用RAM实现a,b两路数据延迟

利用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

延迟很容易做呢,
1.使用一位使能位(记作a)当作数据输入,用一个16位(或者8位)把使能位延迟16(8)个时钟周期(记作b),然后用fifo做延迟输出可以,写使能是a,读使能是b,但 fifo的大小要大于延迟长度。
2.使用16组(8组)寄存器 将数据缓存16(8)个时钟也可以
双口RAM,有点复杂,暂时你的代码是不对的

可以参考一下这个代码

  1. `timescale 1ns / 1ps
  2. //////////////////////////////////////////////////////////////////////////////////
  3. // Company:
  4. // Engineer:
  5. //
  6. // Create Date:    20:51:45 12/15/2013
  7. // Design Name:
  8. // Module Name:    bram_delay
  9. // Project Name:
  10. // Target Devices:
  11. // Tool versions:
  12. // Description:
  13. //
  14. // Dependencies:
  15. //
  16. // Revision:
  17. // Revision 0.01 - File Created
  18. // Additional Comments:
  19. //
  20. //////////////////////////////////////////////////////////////////////////////////
  21. module bram_delay(
  22.     input wire clk,
  23.          input wire rst_n,
  24.          input wire[31:0] a_in,
  25.          input wire[31:0] b_in,
  26.          output reg[31:0] a_delay,
  27.          output reg[31:0] b_delay);
  28. /*************************************************************************/   
  29.          parameter DEL = 1;
  30. /*************************************************************************/
  31.     wire[5:0] a_addr;
  32.     wire[5:0] b_addr;
  33.          wire[31:0] douta;
  34.          wire[31:0] doutb;
  35.          reg[5:0] a_addr1 = 6'd0;
  36.          reg[5:0] a_addr2 = 6'd0;
  37.          reg[5:0] b_addr1 = 6'd32;
  38.          reg[5:0] b_addr2 = 6'd32;
  39.          reg wea = 1'b0;
  40.          reg web = 1'b0;
  41.          reg flag = 1'b0;
  42.          
  43. /**************************************************************************/
  44.     always @ ( posedge clk)
  45.              begin
  46.                       if( rst_n == 1'b0 )
  47.                                     begin
  48.                                              a_delay <= 32'b0;
  49.                                                   b_delay <= 32'b0;
  50.                                          end
  51.                                 else begin
  52.                       flag <= #DEL !flag;
  53.                                 if( flag == 1'b1)
  54.                                     begin
  55.                                              a_delay <= #DEL a_delay;
  56.                                                   b_delay <= #DEL b_delay;
  57.                                                   wea <= #DEL 1'b1;
  58.                                                   web <= #DEL 1'b1;
  59.                                                   a_addr2 <= #DEL a_addr2;
  60.                                                   b_addr2 <= #DEL b_addr2;
  61.                                                   if( a_addr1 == 6'd31)
  62.                                                       a_addr1 <= #DEL 6'd0;
  63.                                                   else
  64.                                                       a_addr1 <= #DEL a_addr1 + 6'b1;
  65.                                                   if( b_addr1 == 6'd63)
  66.                                                       b_addr1 <= #DEL 6'd0;
  67.                                                   else
  68.                                                       b_addr1 <= #DEL b_addr1 + 6'b1;
  69.                 end
  70.             else
  71.                           begin
  72.                               a_delay <= #DEL douta;
  73.                                         b_delay <= #DEL doutb;
  74.                                         wea <= #DEL 1'b0;
  75.                                         web <= #DEL 1'b0;
  76.                                         a_addr1 <= #DEL a_addr1;
  77.                                         b_addr1 <= #DEL b_addr1;
  78.                                         if( a_addr1 <= 6'd15)
  79.                                             a_addr2 <= #DEL a_addr1 + 6'd16;
  80.                                         else
  81.                                             a_addr2 <= #DEL a_addr1 - 6'd16;
  82.                                         if( b_addr1 <= 6'd39)
  83.                                             b_addr2 <= #DEL b_addr1 + 6'd24;
  84.                                         else
  85.                                             b_addr2 <= #DEL b_addr1 - 6'd8;
  86.                 end
  87.                                 end
  88.         end
  89. /*************************************************************************/

  90.     assign a_addr = !flag ? a_addr1 : a_addr2;
  91.          assign b_addr = !flag ? b_addr1 : b_addr2;
  92. /**************************************************************************/
  93.   bram_16 dut (
  94.   .clka(clk), // input clka
  95.   .wea(wea), // input [0 : 0] wea
  96.   .addra(a_addr), // input [5 : 0] addra
  97.   .dina(a_in), // input [15 : 0] dina
  98.   .douta(douta), // output [15 : 0] douta
  99.   .clkb(clk), // input clkb
  100.   .web(web), // input [0 : 0] web
  101.   .addrb(b_addr), // input [5 : 0] addrb
  102.   .dinb(b_in), // input [15 : 0] dinb
  103.   .doutb(doutb) // output [15 : 0] doutb
  104.    );                     

  105. endmodule

复制代码


利用块RAM实现数据延迟的一些问题:http://bbs.eetop.cn/viewthread.php?tid=431323

现在的程序相当于是在程序第一个clk_122p88MHz上升沿处理    if(flag ==1'b1)  后的程序,第二个clk_122p88MHz上升沿处理else后的程序。还有一个错误是程序没有初始化存储器 a_delay和b_delay;
   
    设计fpga程序,首先要画出时序逻辑图,然后根据逻辑图来编写程序,这样编写完程序后就可以有目的的验证,不要先动手编程序,要不然还要从头开始设计。
   

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top