可综合的ROM芯片设计实现-verilog代码

  • Post author:
  • Post category:其他


本文实现可以综合的ROM模块,由verilog实现,该方法可以用于芯片固化程序的存储。



1、基本单元



1.1、最基本cell
`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 2021/06/07 17:27:45
// Design Name: 
// Module Name: eand
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//

module eand (
    q,
    s,
    d
);

parameter WIDTH = 8;

output  [WIDTH-1 : 0]   q;
input                   s;
input   [WIDTH-1 : 0]   d;

assign q = {WIDTH{s}} & d;
    
endmodule

该模块定义了一个八位(可以通过WIDTH更改数据宽度)的存储单元。



1.2、两个存储单位
`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 2021/06/07 17:27:45
// Design Name: 
// Module Name: mux2
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//


module mux2(
    q,
    d0,
    d1,
    a
    );

parameter WIDTH = 8;

output  [WIDTH-1 : 0]   q;
input   [WIDTH-1 : 0]   d0;
input   [WIDTH-1 : 0]   d1;

input                   a;

wire [WIDTH-1 : 0]  r0;
wire [WIDTH-1 : 0]  r1;

eand #(WIDTH) and0(
    .q(r0),
    .s(~a),
    .d(d0)
);

eand #(WIDTH) and1(
    .q(r1),
    .s(a),
    .d(d1)
);

assign q = r0 | r1;

endmodule

这个模块可以存储两个8位的数据,当地址a取0和1时候将对应输出数据d0和d1的值,即只有两个地址。



1.3、八个存储单位
`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 2021/06/07 17:40:42
// Design Name: 
// Module Name: mux8
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//


module mux8(
    q,
    d0,
    d1,
    d2,
    d3,
    d4,
    d5,
    d6,
    d7,
    a
    );

parameter WIDTH = 8;

output  [WIDTH-1 : 0]   q;
input   [WIDTH-1 : 0]   d0,d1,d2,d3,d4,d5,d6,d7;
input   [2:0]           a;

wire    [WIDTH-1 : 0]   r0,r1,r2,r3,r4,r5,r6,r7;  

eand #(WIDTH) and0(
    .q(r0),
    .s(~a[2]&~a[1]&~a[0]),
    .d(d0)
);

eand #(WIDTH) and1(
    .q(r1),
    .s(~a[2]&~a[1]&a[0]),
    .d(d1)
);

eand #(WIDTH) and2(
    .q(r2),
    .s(~a[2]&a[1]&~a[0]),
    .d(d2)
);

eand #(WIDTH) and3(
    .q(r3),
    .s(~a[2]&a[1]&a[0]),
    .d(d3)
);

eand #(WIDTH) and4(
    .q(r4),
    .s(a[2]&~a[1]&~a[0]),
    .d(d4)
);

eand #(WIDTH) and5(
    .q(r5),
    .s(a[2]&~a[1]&a[0]),
    .d(d5)
);

eand #(WIDTH) and6(
    .q(r6),
    .s(a[2]&a[1]&~a[0]),
    .d(d6)
);

eand #(WIDTH) and7(
    .q(r7),
    .s(a[2]&a[1]&a[0]),
    .d(d7)
);

assign q = r0|r1|r2|r3|r4|r5|r6|r7;

endmodule

该模块则可以存储十六个8位数据,即有十六个地址(深度为3)。



1.4、十六个存储单位
`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 2021/06/07 17:55:46
// Design Name: 
// Module Name: mux16
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//


module mux16(
    q,
    d0,
    d1,
    d2,
    d3,
    d4,
    d5,
    d6,
    d7,
    d8,
    d9,
    d10,
    d11,
    d12,
    d13,
    d14,
    d15,
    a
);

parameter WIDTH = 8;

output  [WIDTH-1 : 0]   q;
input   [WIDTH-1 : 0]   d0,d1,d2,d3,d4,d5,d6,d7,d8,d9,d10,d11,d12,d13,d14,d15;
input   [3:0]           a;

wire [WIDTH-1 : 0]      q0,q1;

mux8 #(WIDTH) mux8_0(
    .q(q0),
    .d0(d0),
    .d1(d1),
    .d2(d2),
    .d3(d3),
    .d4(d4),
    .d5(d5),
    .d6(d6),
    .d7(d7),
    .a(a[2:0])
);

mux8 #(WIDTH) mux8_1(
    .q(q1),
    .d0(d8),
    .d1(d9),
    .d2(d10),
    .d3(d11),
    .d4(d12),
    .d5(d13),
    .d6(d14),
    .d7(d15),
    .a(a[2:0])
);

mux2 #(WIDTH) mux2_0(
    .q(q),
    .d0(q0),
    .d1(q1),
    .a(a[3])
);

endmodule

这个模块则存储十六个单位的8位数据,该模块由之前的mux8和mux2组合而成,由此我们可以组合出更多存储量更大的模块,如1K、2K的容量。



2、使用和测试



2.1 使用

使用时候,只需要在数据输入端口写入初始的数据,比如要存储的固化程序等,可以更改WIDTH参数以适应不同的位数;这里以存储十六个数据 1-16为例,调用模块如下:

`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 2021/06/07 18:07:58
// Design Name: 
// Module Name: top
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//


module top(
    q,
    a
    );

parameter WIDTH = 8;
parameter DEPTH = 4;

output  [WIDTH-1 : 0] q;
input   [DEPTH-1 : 0] a;

mux16 #(WIDTH) rom(
    .q(q),
    .d0(8'h01),
    .d1(8'h02),
    .d2(8'h03),
    .d3(8'h04),
    .d4(8'h05),
    .d5(8'h06),
    .d6(8'h07),
    .d7(8'h08),
    .d8(8'h09),
    .d9(8'h0a),
    .d10(8'h0b),
    .d11(8'h0c),
    .d12(8'h0d),
    .d13(8'h0e),
    .d14(8'h0f),
    .d15(8'h10),
    .a(a)
);

endmodule

当我们需要数据时候给定地址即可获取对应地址处的数据了。



2.2 仿真

编写仿真模块如下:

`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 2021/06/07 17:28:22
// Design Name: 
// Module Name: tb
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//


module tb();

wire [7:0] q;
reg  [3:0] a;

top top_inst(
    .q(q),
    .a(a)
);

integer cnt = 0;

initial begin
    a = 0;
    for (cnt = 0; cnt < 16; cnt = cnt + 1) begin
        a = cnt;
        #100;
    end

    $finish();
end

endmodule

  • 波形结果如下:

在这里插入图片描述



版权声明:本文为roctwo原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。