-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathtrue_dual_port_ram.v
140 lines (127 loc) · 2.65 KB
/
true_dual_port_ram.v
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
/////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2013-2018 Efinix Inc. All rights reserved.
//
// True Dual Port RAM
//
//*******************************
// Revisions:
// 0.0 Initial rev
// 0.1 Added output register
// 1.0 Finalized RTL macro
//*******************************
module true_dual_port_ram
#(
parameter DATA_WIDTH = 8,
parameter ADDR_WIDTH = 9,
parameter WRITE_MODE_1 = "READ_FIRST", // WRITE_FIRST, READ_FIRST, NO_CHANGE
parameter WRITE_MODE_2 = "READ_FIRST",
parameter OUTPUT_REG_1 = "FALSE",
parameter OUTPUT_REG_2 = "FALSE",
parameter RAM_INIT_FILE = "ram_init_file.mem"
)
(
input we1, we2, clka, clkb,
input [DATA_WIDTH-1:0] din1, din2,
input [ADDR_WIDTH-1:0] addr1, addr2,
output[DATA_WIDTH-1:0] dout1, dout2
);
localparam MEMORY_DEPTH = 2**ADDR_WIDTH;
localparam MAX_DATA = (1<<ADDR_WIDTH)-1;
reg [DATA_WIDTH-1:0] ram [MEMORY_DEPTH-1:0];
reg [DATA_WIDTH-1:0] r_dout1_1P;
reg [DATA_WIDTH-1:0] r_dout2_1P;
reg [DATA_WIDTH-1:0] r_dout1_2P;
reg [DATA_WIDTH-1:0] r_dout2_2P;
integer i;
initial
begin
// // By default the Efinix memory will initialize to 0
if (RAM_INIT_FILE != "")
begin
$readmemh(RAM_INIT_FILE, ram);
end
end
generate
if (WRITE_MODE_1 == "WRITE_FIRST")
begin
always@(posedge clka)
begin
if (we1)
begin
ram[addr1] <= din1;
r_dout1_1P <= din1;
end
else
r_dout1_1P <= ram[addr1];
end
end
else if (WRITE_MODE_1 == "READ_FIRST")
begin
always@(posedge clka)
begin
if (we1)
ram[addr1] <= din1;
r_dout1_1P <= ram[addr1];
end
end
else if (WRITE_MODE_1 == "NO_CHANGE")
begin
always@(posedge clka)
begin
if (we1)
ram[addr1] <= din1;
else
r_dout1_1P <= ram[addr1];
end
end
if (WRITE_MODE_2 == "WRITE_FIRST")
begin
always@(posedge clkb)
begin
if (we2)
begin
ram[addr2] <= din2;
r_dout2_1P <= din2;
end
else
r_dout2_1P <= ram[addr2];
end
end
else if (WRITE_MODE_2 == "READ_FIRST")
begin
always@(posedge clkb)
begin
if (we2)
ram[addr2] <= din2;
r_dout2_1P <= ram[addr2];
end
end
else if (WRITE_MODE_2 == "NO_CHANGE")
begin
always@(posedge clkb)
begin
if (we2)
ram[addr2] <= din2;
else
r_dout2_1P <= ram[addr2];
end
end
if (OUTPUT_REG_1 == "TRUE")
begin
always@(posedge clka)
r_dout1_2P <= r_dout1_1P;
assign dout1 = r_dout1_2P;
end
else
assign dout1 = r_dout1_1P;
if (OUTPUT_REG_2 == "TRUE")
begin
always@(posedge clkb)
r_dout2_2P <= r_dout2_1P;
assign dout2 = r_dout2_2P;
end
else
assign dout2 = r_dout2_1P;
endgenerate
endmodule