在线咨询
eetop公众号 创芯大讲堂 创芯人才网
切换到宽版

EETOP 创芯网论坛 (原名:电子顶级开发网)

手机号码,快捷登录

手机号码,快捷登录

找回密码

  登录   注册  

快捷导航
搜帖子
查看: 4006|回复: 4

[求助] 一个关于SRAM设计的问题,希望大神们不吝赐教哈

[复制链接]
发表于 2013-8-6 00:45:28 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?注册

x
SRAM_2_Dimensional.rar (2.8 KB, 下载次数: 16 ) 我想设计一个16路数据并行读写的双口SRAM(1024*32bit),在同一时刻有16路数据并行写入SRAM,下一时钟从SRAM中同时读出16路数据,我现在的想法是将SRAM1024个存储空间分为16块即列数(每块64*32bit),每块有一路读写地址分别与其相连,现在比较迷惑的是SRAM存储空间的表示,之前看过SRAM的程序大都是表示成寄存器组的形式,我在Quartus II中将SRAM表示成
reg[31:0]RAM_col[3:0][63:0],不知道这样可不可以,编译语法没有错误,但是仿真结果不对,有几路有输出结果,其他没有,不知道是什么原因,我检查了下逻辑没有错误,为什么几路有,另外几路没有呢?我觉得程序不复杂,可是编译时间感觉比较长,不知道怎么回事?


还有一个问题就是刚一开始我对SRAM存储的声明是这样的reg[31:0]RAM_col_0[63:0],..........reg[31:0]RAM_col_15[63:0],一共16个,然后根据地址译码生成的列数和行数,根据每路地址的列数先判断是16块中的哪一块,再根据行数判断是64个存储空间中的哪一个,通过case语句实现,case语句下有16条语句(根据列数),这样的话一共32个case语句(读写各16路地址线),发现执行的时间更长,差不多有10分钟,所以才改成上面SRAM的声明,这是怎么回事,编译时间好长啊


求解,附代码,期待大神不吝赐教!先谢谢了
发表于 2013-8-6 12:46:53 | 显示全部楼层
回复 1# jinglong_zhou

可能是自动映射出了问题,每一个FPGA公司支持的自动RAM映射的coding style是有限的,一定要和他们的匹配,才能自动映射到FPGA内部的RAM.
发表于 2013-8-8 18:00:24 | 显示全部楼层
或者换个思路,为啥一定要定义这么复杂的数组呢,直接例化小块的SRAM也可以啊,使用generate生成,代码风格也很简洁。
我发段代码,也是双口RAM的。



  1.    
  2. ram_2p_inst u_ram_2p_inst0
  3. (
  4.     .clka       (aclk               ),
  5.     .clkb       (aclk               ),
  6.     .addra      (ram_waddr          ),
  7.     .addrb      (ram_raddr          ),
  8.     .dina       (ram_wdata[31:0]    ),
  9.     .doutb      (ram_rdata[31:0]    ),
  10.     .ena        (1'b1               ),
  11.     .enb        (1'b1               ),
  12.     .wea        (|ram_we[3:0]       )
  13. );

  14. ram_2p_inst u_ram_2p_inst1
  15. (
  16.     .clka       (aclk               ),
  17.     .clkb       (aclk               ),
  18.     .addra      (ram_waddr          ),
  19.     .addrb      (ram_raddr          ),
  20.     .dina       (ram_wdata[63:32]   ),
  21.     .doutb      (ram_rdata[63:32]   ),
  22.     .ena        (1'b1               ),
  23.     .enb        (1'b1               ),
  24.     .wea        (|ram_we[7:4]       )
  25. );

  26. ram_2p_inst u_ram_2p_inst2
  27. (
  28.     .clka       (aclk               ),
  29.     .clkb       (aclk               ),
  30.     .addra      (ram_waddr          ),
  31.     .addrb      (ram_raddr          ),
  32.     .dina       (ram_wdata[95:64]   ),
  33.     .doutb      (ram_rdata[95:64]   ),
  34.     .ena        (1'b1               ),
  35.     .enb        (1'b1               ),
  36.     .wea        (|ram_we[11:8]      )
  37. );

  38. ram_2p_inst u_ram_2p_inst3
  39. (
  40.     .clka       (aclk               ),
  41.     .clkb       (aclk               ),
  42.     .addra      (ram_waddr          ),
  43.     .addrb      (ram_raddr          ),
  44.     .dina       (ram_wdata[127:96]  ),
  45.     .doutb      (ram_rdata[127:96]  ),
  46.     .ena        (1'b1               ),
  47.     .enb        (1'b1               ),
  48.     .wea        (|ram_we[15:12]     )
  49. );




  50. module ram_2p_inst
  51. #(
  52. parameter WD        = 32,               // Width of ram
  53. parameter PW        = 12,                // Pointer Width: This RAM is indexed by sequence number (12 bits)
  54. parameter DP        = (1 << PW)         // Depth: max of 4K sequence numbers
  55. )
  56. (
  57.     clka,
  58.     clkb,   
  59.     addra,
  60.     addrb,
  61.     dina,
  62.     doutb,
  63.     ena,
  64.     enb,
  65.     wea
  66. );

  67. // -----------------------------------------------------------------------------
  68. // IO Declarations
  69. // -----------------------------------------------------------------------------
  70. input               clka;
  71. input               clkb;
  72. input   [PW-1:0]    addra;
  73. input   [PW-1:0]    addrb;
  74. input   [WD-1:0]    dina;
  75. input               ena;
  76. input               enb;
  77. input               wea;

  78. output  [WD-1:0]    doutb;

  79. reg         [WD-1:0]    mem [0:DP-1];
  80. reg         [WD-1:0]    doutb;
  81. integer                 i;

  82. // Writes
  83. always @(posedge clka)
  84. begin
  85.     if (wea)
  86.         mem[addra]      <= #(`TP) dina;
  87. // synopsys translate_off
  88.     if ((addra >= DP) & (DP > 0))
  89.         $display("%t: Memory (%m) write address error. Address is %x, Max is %x, DP = 0x%x, PW = 0x%x", $time, addra, DP-1,DP,PW);
  90. // synopsys translate_on
  91. end

  92. // Reads
  93. always @(posedge clkb)
  94. begin
  95.     doutb           <= #(`TP) mem[addrb];
  96. // synopsys translate_off
  97.     if ((addrb >= DP) & (DP > 0))
  98.         $display("%t: Memory (%m) read address error. Address is %x, Max is %x, DP = 0x%x, PW = 0x%x", $time, addrb, DP-1,DP,PW);
  99. // synopsys translate_on
  100. end





复制代码
 楼主| 发表于 2013-8-9 15:41:21 | 显示全部楼层
回复 4# eaglelsb

谢谢你的建议和提供的代码,在昨天我用altera的RAM IP实现了并行读写的功能,但是我还是很想自己设计出来, 我会好好研究学习一下你给我发的代码,谢谢哈
发表于 2014-10-23 13:31:57 | 显示全部楼层
who know it?
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

站长推荐 上一条 /2 下一条


小黑屋| 手机版| 关于我们| 联系我们| 在线咨询| 隐私声明| EETOP 创芯网
( 京ICP备:10050787号 京公网安备:11010502037710 )

GMT+8, 2024-11-22 04:16 , Processed in 0.022048 second(s), 10 queries , Gzip On, Redis On.

eetop公众号 创芯大讲堂 创芯人才网
快速回复 返回顶部 返回列表