查看: 3961|回复: 1

【小脚丫Step FPGA】同步真双口RAM模块----微风细雨

[复制链接]
  • TA的每日心情
    郁闷
    2017-12-4 18:33
  • 签到天数: 94 天

    连续签到: 1 天

    [LV.6]常住居民II

    发表于 2015-12-15 17:09:18 | 显示全部楼层 |阅读模式
    分享到:
    写本帖的原因有两个,一是分享FPGA学习心得,二是验证寄存器二维数组(即HDL描述的RAM/ROM)可以在两个always过程块中被调用。
    同步真双口RAM包含两个独立的访问端口,允许两个寄存器同时操作。功能如下:
    • 当读操作和写操作在同一个端口发生时,要写入存储器的新数据被读取出来;
    • 当读操作和写操作发生在不同的端口,但使用相同的地址时。存储器中的旧数据被读取出来,需要附件的旁路逻辑恢复数据;
    • 通过两个端口想同一个地址写数据将导致无法预料的行为发生。。。。
    在实现过程中,EDA软件会自行编译选择相应的分布式存储设备。在Quatus中被识别为M4K内部同步嵌入式存储模块,在ISE/Vivado中识别为Block RAM,Diamond中则识别为EBR(内嵌块RAM)。
    1. module dual_port_ram_true
    2.         #(
    3.                 parameter DATA_WIDTH = 8,
    4.                                         ADDR_WIDTH = 10
    5.         )
    6.         (
    7.                 input wire clk,
    8.                 input wire we_a,we_b,
    9.                 input wire [ADDR_WIDTH-1:0] addr_a,addr_b,
    10.                 input wire [DATA_WIDTH-1:0] d_a,d_b,
    11.                 output wire [DATA_WIDTH-1:0] q_a,q_b
    12.         );
    13.         //signal declaration
    14.         reg [DATA_WIDTH-1:0] ram [2**ADDR_WIDTH-1:0];
    15.         reg [DATA_WIDTH-1:0] data_a_reg,data_b_reg;
    16.        
    17.         //body
    18.         //port a
    19.         always@(posedge clk)begin
    20.                 if(we_a)begin
    21.                         ram[addr_a] <= d_a;
    22.                         data_a_reg <= d_a;
    23.                 end
    24.                 else
    25.                                 data_a_reg <= ram[addr_a];
    26.         end
    27.        
    28.         //port b
    29.         always@(posedge clk)begin
    30.                 if(we_b)begin
    31.                         ram[addr_b] <= d_b;
    32.                         data_b_reg <= d_b;
    33.                 end
    34.                 else
    35.                                 data_b_reg <= ram[addr_b];
    36.         end
    37.        
    38.         //output
    39.         assign q_a = data_a_reg;
    40.         assign q_b = data_b_reg;
    41.        
    42. endmodule
    复制代码
    代码解析:
    由于代码中利用读数据寄存器,且在过程块中使用非阻塞赋值,因此在同一时刻,不同端口对同一地址分别进行读写操作时,读操作的结果是之前的旧数据。
    可以用下面的数据交换来理解:
    1. always@(posedge clk)begin
    2.       a <= b;
    3.       b <= a;
    4. end
    复制代码
    在同一个时钟上升沿,既要对a进行写入b的值,又要将a的值读出来写到b中。





    回复

    使用道具 举报

  • TA的每日心情
    无聊
    2016-8-26 11:56
  • 签到天数: 2 天

    连续签到: 1 天

    [LV.1]初来乍到

    发表于 2016-8-25 14:51:59 | 显示全部楼层
    你好。这个板子在哪里可以买到呢?
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

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



    手机版|小黑屋|与非网

    GMT+8, 2024-4-26 22:14 , Processed in 0.112813 second(s), 16 queries , MemCache On.

    ICP经营许可证 苏B2-20140176  苏ICP备14012660号-2   苏州灵动帧格网络科技有限公司 版权所有.

    苏公网安备 32059002001037号

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.