• 牛客刷题<23>ROM的简单实现


    题目:ROM的简单实现_牛客题霸_牛客网

    知识点:要实现ROM,首先要声明数据的存储空间,例如:[3:0] rom [7:0];变量名称rom之前的[3:0]表示每个数据具有多少位,指位宽;变量名称rom之后的[7:0]表示需要多少个数据,指深度,注意这里深度为8,应该是使用[7:0],而不是[2:0];

    声明存储变量之后,需要对rom进行初始化,写入数据,然后将输入地址作为rom的索引值,将索引值对应的数据输出。

    初始化完成之后的rom的形式如下,内部存在地址和数据的对应关系,通过输入相应的地址,可以得到相应的输出数据

     

    1. `timescale 1ns/1ns
    2. module rom(
    3. input clk,
    4. input rst_n,
    5. input [7:0]addr,
    6. output [3:0]data
    7. );
    8. reg [3:0] rom_data [7:0] ;
    9. assign data = rom_data[addr];
    10. //保持ROM中的数据不变
    11. always@(posedge clk or negedge rst_n)
    12. if(!rst_n)begin
    13. rom_data[0] <= 4'd0;
    14. rom_data[1] <= 4'd2;
    15. rom_data[2] <= 4'd4;
    16. rom_data[3] <= 4'd6;
    17. rom_data[4] <= 4'd8;
    18. rom_data[5] <= 4'd10;
    19. rom_data[6] <= 4'd12;
    20. rom_data[7] <= 4'd14;
    21. end
    22. else begin
    23. rom_data[0] <= 4'd0;
    24. rom_data[1] <= 4'd2;
    25. rom_data[2] <= 4'd4;
    26. rom_data[3] <= 4'd6;
    27. rom_data[4] <= 4'd8;
    28. rom_data[5] <= 4'd10;
    29. rom_data[6] <= 4'd12;
    30. rom_data[7] <= 4'd14;
    31. end
    32. endmodule

    对于一个ROM,既要有数据位宽,也要有数据深度,例如

    reg [3:0] rom  [7:0]

    表示,由8个,位宽为4bits的连续地址组成一个名为rom的区域

    初始化就简单了,直接时序逻辑对rom的不同地址赋值

    由addr提取rom的数据时,应注意使用时序逻辑,因为data随着addr的变化立即发生变化,且是wire

    解法二:

    思路:

        1,声明ROM存储器,可以理解为一个数组

        2,对ROM进行初始化赋值,在initial 块内,因赋值有规律,可以用for循环实现

        3,根据传入的地址值,决定从rom中取第几个数

    1. `timescale 1ns/1ns
    2. module rom(
    3. input clk,
    4. input rst_n,
    5. input [7:0]addr,
    6. output [3:0]data
    7. );
    8. reg [3:0] rom_data [7:0] ;
    9. reg [3:0] data_1;
    10. assign data=data_1;
    11. integer i;
    12. always@(*)begin //由于输出要求实时性,所以不能采用时序逻辑,而是组合逻辑
    13. if(!rst_n)begin
    14. data_1 <= 4'b0;
    15. for(i=0;i<8;i=i+1)
    16. begin
    17. rom_data[i] = i << 1; //初始化的位置放置在了复位的阶段
    18. end
    19. end
    20. else begin
    21. case(addr)
    22. 8'd0:data_1 <= rom_data[0];
    23. 8'd1:data_1 <= rom_data[1];
    24. 8'd2:data_1 <= rom_data[2];
    25. 8'd3:data_1 <= rom_data[3];
    26. 8'd4:data_1 <= rom_data[4];
    27. 8'd5:data_1 <= rom_data[5];
    28. 8'd6:data_1 <= rom_data[6];
    29. 8'd7:data_1 <= rom_data[7];
    30. default: data_1 <= 4'b0;
    31. endcase
    32. end
    33. end
    34. endmodule

    解法三:很简单,利用for循环

    1. `timescale 1ns/1ns
    2. module rom(
    3. input clk,
    4. input rst_n,
    5. input [7:0]addr,
    6. output [3:0]data
    7. );
    8. parameter DEPTH = 8;
    9. integer i;
    10. reg [3:0] rom [7:0];
    11. always@(posedge clk or negedge rst_n)begin
    12. if(!rst_n)begin
    13. for(i=0;i<DEPTH-1;i++)begin
    14. rom[i] <= i*2;
    15. end
    16. end
    17. end
    18. assign data = rom[addr];
    19. endmodule

    解法四:注意:条件是上升沿或下降沿或复位低电平有效,没有下降沿代码无法通过

    1. `timescale 1ns/1ns
    2. module rom(
    3. input clk,
    4. input rst_n,
    5. input [7:0]addr,
    6. output [3:0]data
    7. );
    8. reg [3:0] p=0;
    9. always@(posedge clk or negedge clk or negedge rst_n)begin
    10. if(!rst_n)
    11. p<=0;
    12. else begin
    13. p<= addr*2;
    14. end
    15. end
    16. assign data=p;
    17. endmodule

  • 相关阅读:
    Python接口自动化测试之post请求详解
    Apache Doris 系列: 基础篇-Routine Load
    MyBatisPlus(六)字段映射 @TableField
    Altium Designer 19.1.18 - 画多边形铜皮挖空时,针对光标胡乱捕获的解决方法
    渐进式web全栈:blazor web app
    Maven的安装与配置与使用
    交换机和路由器技术-25-OSPF多区域配置
    vim学习手册
    新建SpringCloud电商前端Vant项目
    【博主推荐】SpringBoot API接口对数据库增删改查,路由,TOKEN,WebSocket完整版(附源码)
  • 原文地址:https://blog.csdn.net/mxh3600/article/details/126594379