本文实现可以综合的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 版权协议,转载请附上原文出处链接和本声明。