OpenCores
URL https://opencores.org/ocsvn/thor/thor/trunk

Subversion Repositories thor

[/] [thor/] [trunk/] [FT64/] [rtl/] [common/] [cam.v] - Blame information for rev 43

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 43 robfinch
// ============================================================================
2
//        __
3
//   \\__/ o\    (C) 2017-2018  Robert Finch, Waterloo
4
//    \  __ /    All rights reserved.
5
//     \/_//     robfinch<remove>@finitron.ca
6
//       ||
7
//
8
//      cam.v
9
//  CAM primitives
10
//              
11
//
12
// This source file is free software: you can redistribute it and/or modify 
13
// it under the terms of the GNU Lesser General Public License as published 
14
// by the Free Software Foundation, either version 3 of the License, or     
15
// (at your option) any later version.                                      
16
//                                                                          
17
// This source file is distributed in the hope that it will be useful,      
18
// but WITHOUT ANY WARRANTY; without even the implied warranty of           
19
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            
20
// GNU General Public License for more details.                             
21
//                                                                          
22
// You should have received a copy of the GNU General Public License        
23
// along with this program.  If not, see <http://www.gnu.org/licenses/>.    
24
//                                                                          
25
//
26
// The cam is implemented as two memories. The first memory is the data memory
27
// which is used to store the data as per usual. The second memory is a bitmap
28
// of which memory locations the data is stored in.
29
// Because two memories are used writing is a two step process. First the
30
// bit of where the old data is stored must be updated by clearing it for old
31
// data. Next the bitmap of the data storage is set for the new data.
32
// ============================================================================
33
//
34
//`define DUAL_READ     1'b1
35
 
36
module cam6x32(clk, we, wr_addr, din, cmp_din, match_addr, match);
37
input clk;
38
input we;
39
input [4:0] wr_addr;
40
input [5:0] din;
41
input [5:0] cmp_din;
42
output [31:0] match_addr;
43
output match;
44
 
45
(* RAM_STYLE="DISTRIBUTED" *)
46
reg [31:0] bmem [0:63];
47
reg [5:0] dmem [0:31];
48
reg [5:0] din2;
49
 
50
integer n;
51
initial begin
52
    for (n = 0; n < 64; n = n + 1)
53
        bmem[n] = 0;
54
    for (n = 0; n < 32; n = n + 1)
55
        dmem[n] = 0;
56
end
57
 
58
reg we2;
59
wire [5:0] madr = (we2 & ~we) ? din2 : we ? dmem[wr_addr] : cmp_din;
60
 
61
always @(posedge clk)
62
begin
63
    din2 <= din;
64
    we2 <= we;
65
    if (we & ~we2)
66
        bmem[madr] <= bmem[madr] & ~(32'd1 << wr_addr);
67
    else if (we2 & ~we)
68
        bmem[madr] <= bmem[madr] | (32'd1 << wr_addr);
69
    if (we2 & ~we)
70
        dmem[wr_addr] <= din2;
71
end
72
 
73
assign match_addr = bmem[madr];
74
assign match = |match_addr;
75
 
76
endmodule
77
 
78
// Write six bits of data to one of 64 addresses
79
 
80
module cam6x64(rst, clk, we, wr_addr, din, cmp_din, match_addr, match);
81
input rst;
82
input clk;
83
input we;
84
input [5:0] wr_addr;
85
input [5:0] din;
86
input [5:0] cmp_din;
87
output [63:0] match_addr;
88
output match;
89
 
90
(* RAM_STYLE="DISTRIBUTED" *)
91
reg [63:0] bmem [0:63];
92
reg [5:0] dmem [0:63];
93
reg [5:0] din2;
94
 
95
integer n;
96
initial begin
97
    for (n = 0; n < 64; n = n + 1)
98
        bmem[n] = 0;
99
    for (n = 0; n < 64; n = n + 1)
100
        dmem[n] = 0;
101
end
102
 
103
reg we2;
104
wire [5:0] madr = (we2 & ~we) ? din2 : we ? dmem[wr_addr] : cmp_din;
105
 
106
always @(posedge clk)
107
    din2 <= din;
108
always @(posedge clk)
109
    we2 <= we;
110
 
111
// This looks like it might be updating the same address during we and we2 ubt
112
// bmem[adr] actually likely changes inbetween the write pulses due to an
113
// update of dmem[wr_addr].
114
always @(posedge clk)
115
if (rst) begin
116
    for (n = 0; n < 64; n = n + 1)
117
        bmem[n] <= 0;
118
end
119
else begin
120
    if (we & ~we2)
121
        bmem[madr] <= bmem[madr] & ~(64'd1 << wr_addr);
122
    else if (we2 & ~we)
123
        bmem[madr] <= bmem[madr] | (64'd1 << wr_addr);
124
end
125
 
126
always @(posedge clk)
127
if (rst) begin
128
    for (n = 0; n < 64; n = n + 1)
129
        dmem[n] <= 0;
130
end
131
else begin
132
    if (we2 & ~we)
133
        dmem[wr_addr] <= din2;
134
end
135
 
136
`ifdef DUAL_READ
137
assign match_addr = bmem[cmp_din];
138
`else
139
assign match_addr = bmem[madr];
140
`endif
141
assign match = |match_addr;
142
 
143
endmodule
144
 
145
// Write six bits of data to one of 64 addresses
146
 
147
module cam6x256(rst, clk, we, wr_addr, din, cmp_din, match_addr, match);
148
input rst;
149
input clk;
150
input we;
151
input [7:0] wr_addr;
152
input [5:0] din;
153
input [5:0] cmp_din;
154
output [255:0] match_addr;
155
output match;
156
 
157
reg [255:0] bmem [0:63];
158
reg [5:0] dmem [0:255];
159
reg [5:0] din2;
160
 
161
integer n;
162
initial begin
163
    for (n = 0; n < 64; n = n + 1)
164
        bmem[n] = 0;
165
    for (n = 0; n < 256; n = n + 1)
166
        dmem[n] = 0;
167
end
168
 
169
reg we2;
170
wire [5:0] madr = (we2 & ~we) ? din2 : we ? dmem[wr_addr] : cmp_din;
171
 
172
always @(posedge clk)
173
    din2 <= din;
174
always @(posedge clk)
175
    we2 <= we;
176
 
177
// This looks like it might be updating the same address during we and we2 ubt
178
// bmem[adr] actually likely changes inbetween the write pulses due to an
179
// update of dmem[wr_addr].
180
always @(posedge clk)
181
if (rst) begin
182
    for (n = 0; n < 64; n = n + 1)
183
        bmem[n] <= 0;
184
end
185
else begin
186
    if (we & ~we2)
187
        bmem[madr] <= bmem[madr] & ~(256'd1 << wr_addr);
188
    else if (we2 & ~we)
189
        bmem[madr] <= bmem[madr] | (256'd1 << wr_addr);
190
end
191
 
192
always @(posedge clk)
193
if (rst) begin
194
    for (n = 0; n < 256; n = n + 1)
195
        dmem[n] <= 0;
196
end
197
else begin
198
    if (we2 & ~we)
199
        dmem[wr_addr] <= din2;
200
end
201
 
202
assign match_addr = bmem[madr];
203
assign match = |match_addr;
204
 
205
endmodule
206
 
207
module cam36x32(clk, we, wr_addr, din, cmp_din, match_addr, match);
208
input clk;
209
input we;
210
input [4:0] wr_addr;
211
input [35:0] din;
212
input [35:0] cmp_din;
213
output [31:0] match_addr;
214
output match;
215
 
216
wire [31:0] match_addr0, match_addr1, match_addr2, match_addr3, match_addr4, match_addr5;
217
wire [31:0] match_addr = match_addr0 & match_addr1 & match_addr2 & match_addr3 & match_addr4 & match_addr5;
218
 
219
DSD9_cam6x32 u1 (clk, we, wr_addr, din[ 5: 0], cmp_din[ 5: 0], match_addr0);
220
DSD9_cam6x32 u2 (clk, we, wr_addr, din[11: 6], cmp_din[11: 6], match_addr1);
221
DSD9_cam6x32 u3 (clk, we, wr_addr, din[17:12], cmp_din[17:12], match_addr2);
222
DSD9_cam6x32 u4 (clk, we, wr_addr, din[23:18], cmp_din[23:18], match_addr3);
223
DSD9_cam6x32 u5 (clk, we, wr_addr, din[29:24], cmp_din[29:24], match_addr4);
224
DSD9_cam6x32 u6 (clk, we, wr_addr, din[35:30], cmp_din[35:30], match_addr5);
225
 
226
assign match = |match_addr;
227
 
228
endmodule
229
 
230
module cam36x64(rst, clk, we, wr_addr, din, cmp_din, match_addr, match);
231
input rst;
232
input clk;
233
input we;
234
input [5:0] wr_addr;
235
input [35:0] din;
236
input [35:0] cmp_din;
237
output [63:0] match_addr;
238
output match;
239
 
240
wire [63:0] match_addr0, match_addr1, match_addr2, match_addr3, match_addr4, match_addr5;
241
wire [63:0] match_addr = match_addr0 & match_addr1 & match_addr2 & match_addr3 & match_addr4 & match_addr5;
242
 
243
cam6x64 u1 (rst, clk, we, wr_addr, din[ 5: 0], cmp_din[ 5: 0], match_addr0);
244
cam6x64 u2 (rst, clk, we, wr_addr, din[11: 6], cmp_din[11: 6], match_addr1);
245
cam6x64 u3 (rst, clk, we, wr_addr, din[17:12], cmp_din[17:12], match_addr2);
246
cam6x64 u4 (rst, clk, we, wr_addr, din[23:18], cmp_din[23:18], match_addr3);
247
cam6x64 u5 (rst, clk, we, wr_addr, din[29:24], cmp_din[29:24], match_addr4);
248
cam6x64 u6 (rst, clk, we, wr_addr, din[35:30], cmp_din[35:30], match_addr5);
249
 
250
assign match = |match_addr;
251
 
252
endmodule

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.