-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathlab1d_associative_array.sv
More file actions
343 lines (295 loc) · 18.8 KB
/
lab1d_associative_array.sv
File metadata and controls
343 lines (295 loc) · 18.8 KB
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
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
module associative_array_demo;
// ========================================
// ВАЖЛИВО: Icarus Verilog НЕ підтримує associative arrays!
// ========================================
// Цей код демонструє синтаксис SystemVerilog, але для запуску
// потрібен комерційний симулятор (Questa, VCS, Xcelium)
// ========================================
// Завдання 1: Створення асоціативного масиву
// ========================================
// Ключ: string (MAC-адреса)
// Значення: int (номер порту)
// int mac_table [string]; // НЕ працює в Icarus Verilog!
initial begin
$display("\n=== Associative Array Demo: MAC Address Table ===\n");
$display("УВАГА: Icarus Verilog НЕ підтримує associative arrays!");
$display("Нижче наведено теоретичний код та пояснення.\n");
$display("======================================================================");
$display("=== СИНТАКСИС ASSOCIATIVE ARRAY ===");
$display("======================================================================\n");
$display("1. ОГОЛОШЕННЯ:");
$display(" int mac_table [string]; // ключ: string, значення: int");
$display(" int data [int]; // ключ: int, значення: int");
$display(" string names [logic[7:0]]; // ключ: 8-bit, значення: string");
$display("\n2. ДОДАВАННЯ ЕЛЕМЕНТІВ:");
$display(" mac_table[\"AA:BB:CC:DD:EE:01\"] = 1;");
$display(" mac_table[\"AA:BB:CC:DD:EE:02\"] = 2;");
$display(" mac_table[\"AA:BB:CC:DD:EE:03\"] = 3;");
$display("\n3. ПЕРЕВІРКА ІСНУВАННЯ:");
$display(" if (mac_table.exists(\"AA:BB:CC:DD:EE:02\")) begin");
$display(" $display(\"Знайдено: порт %%0d\", mac_table[\"AA:BB:CC:DD:EE:02\"]);");
$display(" end");
$display("\n4. ВИДАЛЕННЯ:");
$display(" mac_table.delete(\"AA:BB:CC:DD:EE:01\");");
$display("\n5. ОНОВЛЕННЯ:");
$display(" mac_table[\"AA:BB:CC:DD:EE:05\"] = 10; // Змінює значення");
$display("\n6. ІТЕРАЦІЯ (first/next):");
$display(" string key;");
$display(" if (mac_table.first(key)) begin");
$display(" do begin");
$display(" $display(\"%%s → %%0d\", key, mac_table[key]);");
$display(" end while (mac_table.next(key));");
$display(" end");
$display("\n");
$display("======================================================================");
$display("=== ЗАВДАННЯ (ТЕОРЕТИЧНЕ ВИКОНАННЯ) ===");
$display("======================================================================\n");
$display("ЗАВДАННЯ 2: Додавання записів");
$display("─────────────────────────────────");
$display("mac_table[\"AA:BB:CC:DD:EE:01\"] = 1; ✓");
$display("mac_table[\"AA:BB:CC:DD:EE:02\"] = 2; ✓");
$display("mac_table[\"AA:BB:CC:DD:EE:03\"] = 3; ✓");
$display("mac_table[\"AA:BB:CC:DD:EE:04\"] = 9; ✓");
$display("mac_table[\"AA:BB:CC:DD:EE:05\"] = 7; ✓");
$display("mac_table[\"AA:BB:CC:DD:EE:06\"] = 8; ✓");
$display("\nРозмір таблиці: 6 записів (mac_table.num() = 6)");
$display("\n\nЗАВДАННЯ 3: Перевірка існування");
$display("─────────────────────────────────");
$display("Перевірка \"AA:BB:CC:DD:EE:02\":");
$display(" exists() = 1 (TRUE)");
$display(" ✓ MAC AA:BB:CC:DD:EE:02 ЗНАЙДЕНО → порт 2");
$display("\nПеревірка \"AA:BB:CC:DD:EE:11\":");
$display(" exists() = 0 (FALSE)");
$display(" ✗ MAC AA:BB:CC:DD:EE:11 НЕ ЗНАЙДЕНО (порт відсутній)");
$display("\n\nЗАВДАННЯ 4: Додавання нової адреси");
$display("─────────────────────────────────");
$display("mac_table[\"AA:BB:CC:DD:EE:10\"] = 5; ✓");
$display("Розмір таблиці: 7 записів");
$display("\n\nЗАВДАННЯ 5: Видалення запису");
$display("─────────────────────────────────");
$display("Перед видаленням:");
$display(" Розмір: 7 записів");
$display(" exists(\"AA:BB:CC:DD:EE:01\") = TRUE");
$display("\nmac_table.delete(\"AA:BB:CC:DD:EE:01\"); ✓");
$display("\nПісля видалення:");
$display(" Розмір: 6 записів");
$display(" exists(\"AA:BB:CC:DD:EE:01\") = FALSE");
$display("\n\nЗАВДАННЯ 6: Оновлення запису");
$display("─────────────────────────────────");
$display("Перед оновленням:");
$display(" AA:BB:CC:DD:EE:05 → порт 7");
$display("\nmac_table[\"AA:BB:CC:DD:EE:05\"] = 10; ✓");
$display("\nПісля оновлення:");
$display(" AA:BB:CC:DD:EE:05 → порт 10");
$display("\n\nЗАВДАННЯ 7: Перегляд усіх записів (first/next)");
$display("─────────────────────────────────");
$display("╔════════════════════════╦═══════════╗");
$display("║ MAC Address ║ Port ║");
$display("╠════════════════════════╬═══════════╣");
$display("║ AA:BB:CC:DD:EE:02 ║ 2 ║");
$display("║ AA:BB:CC:DD:EE:03 ║ 3 ║");
$display("║ AA:BB:CC:DD:EE:04 ║ 9 ║");
$display("║ AA:BB:CC:DD:EE:05 ║ 10 ║ ← оновлено");
$display("║ AA:BB:CC:DD:EE:06 ║ 8 ║");
$display("║ AA:BB:CC:DD:EE:10 ║ 5 ║ ← додано");
$display("╚════════════════════════╩═══════════╝");
$display(" ↑");
$display(" (AA:BB:CC:DD:EE:01 видалено)");
$display("\nЗагальна кількість: 6 записів");
$display("\n");
$display("======================================================================");
$display("=== МЕТОДИ ASSOCIATIVE ARRAY ===");
$display("======================================================================\n");
$display("┌────────────────────┬──────────────────────────────────────┐");
$display("│ Метод │ Опис │");
$display("├────────────────────┼──────────────────────────────────────┤");
$display("│ num() │ Кількість елементів │");
$display("│ exists(key) │ Перевірка існування ключа (1/0) │");
$display("│ first(key) │ Перший ключ, ініціалізує ітерацію │");
$display("│ last(key) │ Останній ключ │");
$display("│ next(key) │ Наступний ключ │");
$display("│ prev(key) │ Попередній ключ │");
$display("│ delete(key) │ Видалення одного елемента │");
$display("│ delete() │ Видалення всіх елементів │");
$display("└────────────────────┴──────────────────────────────────────┘");
$display("\n");
$display("======================================================================");
$display("=== ПРИКЛАДИ ВИКОРИСТАННЯ ===");
$display("======================================================================\n");
$display("1. ПОШУК З ПЕРЕВІРКОЮ:");
$display(" ─────────────────────");
$display(" string mac = \"AA:BB:CC:DD:EE:02\";");
$display(" if (mac_table.exists(mac)) begin");
$display(" int port = mac_table[mac];");
$display(" $display(\"Знайдено: порт %%0d\", port);");
$display(" end else begin");
$display(" $display(\"MAC не знайдено\");");
$display(" end");
$display("\n2. ІТЕРАЦІЯ ВПЕРЕД (first → last):");
$display(" ──────────────────────────────────");
$display(" string key;");
$display(" if (mac_table.first(key)) begin");
$display(" do begin");
$display(" $display(\"%%s → %%0d\", key, mac_table[key]);");
$display(" end while (mac_table.next(key));");
$display(" end");
$display("\n3. ІТЕРАЦІЯ НАЗАД (last → first):");
$display(" ─────────────────────────────────");
$display(" string key;");
$display(" if (mac_table.last(key)) begin");
$display(" do begin");
$display(" $display(\"%%s → %%0d\", key, mac_table[key]);");
$display(" end while (mac_table.prev(key));");
$display(" end");
$display("\n4. ОЧИЩЕННЯ ТАБЛИЦІ:");
$display(" ────────────────────");
$display(" mac_table.delete(); // Видаляє всі елементи");
$display(" // або");
$display(" string key;");
$display(" if (mac_table.first(key)) begin");
$display(" do begin");
$display(" mac_table.delete(key);");
$display(" end while (mac_table.first(key));");
$display(" end");
$display("\n5. ПІДРАХУНОК ЕЛЕМЕНТІВ:");
$display(" ────────────────────────");
$display(" int count = mac_table.num();");
$display(" $display(\"Таблиця містить %%0d записів\", count);");
$display("\n");
$display("======================================================================");
$display("=== ТИПИ КЛЮЧІВ ===");
$display("======================================================================\n");
$display("Associative array може використовувати різні типи ключів:\n");
$display("• INTEGER:");
$display(" int data [int];");
$display(" data[42] = 100;");
$display(" data[-5] = 200;");
$display("\n• STRING:");
$display(" int ports [string];");
$display(" ports[\"router1\"] = 10;");
$display(" ports[\"switch2\"] = 20;");
$display("\n• BIT VECTOR:");
$display(" string names [logic[7:0]];");
$display(" names[8'hFF] = \"broadcast\";");
$display(" names[8'h00] = \"null\";");
$display("\n• ENUM:");
$display(" typedef enum {RED, GREEN, BLUE} color_t;");
$display(" int values [color_t];");
$display(" values[RED] = 0xFF0000;");
$display(" values[GREEN] = 0x00FF00;");
$display("\n• STRUCT (unpacked):");
$display(" typedef struct {int x; int y;} point_t;");
$display(" string labels [point_t];");
$display(" point_t p = '{10, 20};");
$display(" labels[p] = \"start\";");
$display("\n");
$display("======================================================================");
$display("=== ПОРІВНЯННЯ ТИПІВ МАСИВІВ ===");
$display("======================================================================\n");
$display("┌─────────────────┬──────────────┬──────────────┬──────────────┐");
$display("│ │ Associative │ Dynamic │ Unpacked │");
$display("├─────────────────┼──────────────┼──────────────┼──────────────┤");
$display("│ Розмір │ Динамічний │ Динамічний │ Фіксований │");
$display("│ Тип індексу │ Будь-який │ Integer │ Integer │");
$display("│ Порядок │ Hash table │ Послідовний │ Послідовний │");
$display("│ Пошук │ O(1) │ O(1) │ O(1) │");
$display("│ Пам'ять │ Тільки викор.│ Весь розмір │ Весь розмір │");
$display("│ Методи │ exists, etc. │ size, new │ Немає │");
$display("│ Синтез │ НІ │ НІ │ НІ │");
$display("└─────────────────┴──────────────┴──────────────┴──────────────┘");
$display("\n");
$display("======================================================================");
$display("=== ПРАКТИЧНІ ПРИКЛАДИ ===");
$display("======================================================================\n");
$display("1. ETHERNET SWITCH MAC TABLE:");
$display(" ───────────────────────────");
$display(" int mac_table [string];");
$display(" mac_table[\"00:11:22:33:44:55\"] = 1; // MAC → port");
$display(" ");
$display(" // Пошук порту для MAC");
$display(" string src_mac = get_packet_mac();");
$display(" if (mac_table.exists(src_mac))");
$display(" forward_to_port(mac_table[src_mac]);");
$display(" else");
$display(" flood_all_ports();");
$display("\n2. CACHE SIMULATOR:");
$display(" ──────────────────");
$display(" logic [31:0] cache [logic[31:0]]; // address → data");
$display(" ");
$display(" // Запис");
$display(" cache[32'h1000] = 32'hDEADBEEF;");
$display(" ");
$display(" // Читання з перевіркою");
$display(" if (cache.exists(addr))");
$display(" data = cache[addr]; // Cache hit");
$display(" else");
$display(" data = read_memory(addr); // Cache miss");
$display("\n3. SCOREBOARD:");
$display(" ─────────────");
$display(" typedef struct {");
$display(" int data;");
$display(" bit valid;");
$display(" } transaction_t;");
$display(" ");
$display(" transaction_t scoreboard [int]; // ID → transaction");
$display(" ");
$display(" // Додавання транзакції");
$display(" scoreboard[txn_id] = '{100, 1};");
$display(" ");
$display(" // Порівняння");
$display(" if (scoreboard.exists(txn_id))");
$display(" compare(actual, scoreboard[txn_id]);");
$display("\n4. SPARSE MEMORY MODEL:");
$display(" ──────────────────────");
$display(" logic [7:0] memory [logic[31:0]]; // 4GB address space");
$display(" ");
$display(" // Займає пам'ять тільки для записаних адрес!");
$display(" memory[32'h0000_1000] = 8'hAA;");
$display(" memory[32'hFFFF_FFFF] = 8'hBB;");
$display(" ");
$display(" // Використано лише 2 байти, а не 4GB!");
$display(" $display(\"Used memory: %%0d bytes\", memory.num());");
$display("\n");
$display("======================================================================");
$display("=== ЯК ЗАПУСТИТИ ЦЕЙ КОД ===");
$display("======================================================================\n");
$display("Associative arrays підтримуються в:");
$display("");
$display("✓ Questa/ModelSim (Mentor Graphics):");
$display(" vsim -c -do \"run -all\" associative_array_demo");
$display("");
$display("✓ VCS (Synopsys):");
$display(" vcs -sverilog associative_array_demo.sv");
$display(" ./simv");
$display("");
$display("✓ Xcelium (Cadence):");
$display(" xrun -sv associative_array_demo.sv");
$display("");
$display("✗ Icarus Verilog:");
$display(" НЕ ПІДТРИМУЄТЬСЯ (як ви бачите зараз)");
$display("");
$display("✓ Verilator:");
$display(" Часткова підтримка (тільки для lint)");
$display("\n");
$display("======================================================================");
$display("=== ВИСНОВКИ ===");
$display("======================================================================\n");
$display("✓ Associative array - потужний інструмент для тестбенчів");
$display("✓ Швидкий пошук O(1) завдяки hash table");
$display("✓ Економія пам'яті - тільки використані ключі");
$display("✓ Гнучкість - будь-який тип ключа");
$display("✓ Зручні методи: exists(), first(), next(), delete()");
$display("");
$display("✗ НЕ синтезується в апаратуру");
$display("✗ Тільки для верифікації");
$display("✗ Потребує комерційний симулятор");
$display("\n");
$display("Використовуйте associative arrays для:");
$display(" • Lookup tables з динамічним розміром");
$display(" • Sparse memory models");
$display(" • Scoreboards та checkers");
$display(" • MAC/routing tables");
$display(" • Cache simulators");
$display("\n======================================================================\n");
end
endmodule