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

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

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

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

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

 

`timescale 1ns/1ns
module rom(
	input clk,
	input rst_n,
	input [7:0]addr,
	
	output [3:0]data
);
    reg [3:0] rom_data [7:0] ;
    assign data = rom_data[addr];
    //保持ROM中的数据不变
    always@(posedge clk or negedge rst_n)
        if(!rst_n)begin
            rom_data[0] <= 4'd0;
            rom_data[1] <= 4'd2;
            rom_data[2] <= 4'd4;
            rom_data[3] <= 4'd6;
            rom_data[4] <= 4'd8;
            rom_data[5] <= 4'd10;
            rom_data[6] <= 4'd12;
            rom_data[7] <= 4'd14;
        end
    else begin
            rom_data[0] <= 4'd0;
            rom_data[1] <= 4'd2;
            rom_data[2] <= 4'd4;
            rom_data[3] <= 4'd6;
            rom_data[4] <= 4'd8;
            rom_data[5] <= 4'd10;
            rom_data[6] <= 4'd12;
            rom_data[7] <= 4'd14;
    end
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中取第几个数

`timescale 1ns/1ns
module rom(
	input clk,
	input rst_n,
	input [7:0]addr,
	
	output [3:0]data
);
    reg [3:0] rom_data [7:0] ;
        reg [3:0] data_1;
        assign data=data_1;
        integer i;
    always@(*)begin   //由于输出要求实时性,所以不能采用时序逻辑,而是组合逻辑
        if(!rst_n)begin
            data_1 <= 4'b0;
            for(i=0;i<8;i=i+1)
                begin
                    rom_data[i] = i << 1;  //初始化的位置放置在了复位的阶段
                end
        end
        else begin
            case(addr)
                8'd0:data_1 <= rom_data[0];
                8'd1:data_1 <= rom_data[1];
                8'd2:data_1 <= rom_data[2];
                8'd3:data_1 <= rom_data[3];
                8'd4:data_1 <= rom_data[4];
                8'd5:data_1 <= rom_data[5];
                8'd6:data_1 <= rom_data[6];
                8'd7:data_1 <= rom_data[7];
                default: data_1 <= 4'b0;
            endcase
        end
    end
endmodule

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

`timescale 1ns/1ns
module rom(
	input clk,
	input rst_n,
	input [7:0]addr,
	
	output [3:0]data
);
    parameter DEPTH = 8;
    integer i;
    reg [3:0] rom [7:0];
    
    always@(posedge clk or negedge rst_n)begin
        if(!rst_n)begin
            for(i=0;i<DEPTH-1;i++)begin
                rom[i] <= i*2;
            end
        end
    end
    assign data = rom[addr];
endmodule

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

`timescale 1ns/1ns
module rom(
	input clk,
	input rst_n,
	input [7:0]addr,
	
	output [3:0]data
);
    reg [3:0] p=0;
    always@(posedge clk or negedge clk or negedge rst_n)begin
        if(!rst_n)
            p<=0;
        else begin
            p<= addr*2;
        end
    end
    assign data=p;
endmodule

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值