Реализация кэш

您所在的位置:网站首页 cacheline Реализация кэш

Реализация кэш

2023-04-21 01:12| 来源: 网络整理| 查看: 265

Введение

Существенную часть кристалла современных ЦП занимает кэш-память. Дальнейшее увеличение кэш-памяти без изменения технологических норм приведет к соответствующему увеличению кристалла. Одним из способов увеличения объема хранимой информации в кэше без увеличения объёма самого кэша является использование алгоритмов компрессии. Среди них выделяются алгоритмы Base+Delta и Base-Delta-Immediate. Данная статья посвящена реализации первого алгоритма

Описание Base+Delta 

Кэш-память состоит из кэш-строк фиксированного объема. 

Кэш-строку разделяют на несколько сегментов. Нулевой сегмент называют базой. При равенстве старших бит сегментов между собой возможно сжатие с помощью разности сегмента и базы, что и называется дельтой. В зависимости от размеров базы и дельт разделяют несколько режимов

B8-∆1 (Base = 8 Byte, ∆ = 1 Byte)B8-∆2B8-∆4B4-∆1B4-∆2B2-∆1

Ниже представлены примеры компрессии 32-ух байтовых кэш-строк

Декомпрессия происходит с помощью суммы базы и дельт. В данном примере осуществляется компрессия в режиме B4-∆1. Исходная строка, равная 32-ум байтам, сжимается до 12-ти байт

Данный алгоритм компрессии обоснован, во-первых, регулярностью расположения данных в памяти и, во-вторых, малым динамическим диапазоном значений в кэш-памяти. Объем сегментов отличается в зависимости от типа сжимаемых данных. Он может быть равен 2, 4 и 8 байтам. Использование только одного фиксированного объема сегментов может существенно повлиять на степень компрессии в худшую сторону. Например, для массива указателей объемом 4 байта оптимально использовать 4-ех байтовые сегменты, а для массива 2-ух байтовых целых чисел - сегменты объемом по 2 байта

Значением базы всегда выбирается нулевой сегмент, так как поиск минимального значения базы потребует сложной логики, что существенно скажется на латентности компрессии. Более того, по заявлениям разработчиков алгоритма степень компрессии не увеличится значительно, если реализовать логику поиска базы

Кэш-память

Кэш-память имеет 16 кэш-строк объемом 64 байта, что позволяет хранить 1КБ данных без компрессии. У каждой кэш-строки помимо данных имеется бит достоверности, определяющий актуальность и достоверность данных, 8-ми байтовое поле тега, хранящий адрес младшего слова в памяти, 8 невидимых байт, о предназначении которых будет упомянуто в последующих разделах, и 3 младших бита, в которых хранится код компрессии

Каждая кэш-строка имеет вход, куда подаются данные, которые можно записать, если активен управляющий сигнал WE (Write Enable). Имеется асинхронный сброс, контролируемый сигналом reset. При сбросе все биты строки заполняются нулями. Выходные данные проходят через буферы трех состояний, контролируемые сигналом OE (Output Enable). На выходе появляются данные только при активности данного сигнала. Описание кэш-строки представлено ниже

module cacheline(input tri [643:0] d, input tri clk, reset, we, oe, output tri [643:0] q); logic [643:0] d1; always_ff @(posedge clk, posedge reset) begin if (reset) d1 = q[991:960]) & (q[159:128] >= q[991:960]) & (q[223:192] >= q[991:960]) & (q[287:256] >= q[991:960]) & (q[351:320] >= q[991:960]) & (q[415:384] >= q[991:960]) & (q[479:448] >= q[991:960]) & (q[543:512] >= q[991:960]) & (q[607:576] >= q[991:960]) & (q[671:640] >= q[991:960]) & (q[735:704] >= q[991:960]) & (q[799:768] >= q[991:960]) & (q[863:832] >= q[991:960]) & (q[927:896] >= q[991:960])); assign cmpr[1] = ((q[15:0] >= q[1007:992]) & (q[47:32] >= q[1007:992]) & (q[79:64] >= q[1007:992]) & (q[111:96] >= q[1007:992]) & (q[143:128] >= q[1007:992]) & (q[175:160] >= q[1007:992]) & (q[207:192] >= q[1007:992]) & (q[239:224] >= q[1007:992]) & (q[271:256] >= q[1007:992]) & (q[303:288] >= q[1007:992]) & (q[335:320] >= q[1007:992]) & (q[367:352] >= q[1007:992]) & (q[399:384] >= q[1007:992]) & (q[431:416] >= q[1007:992]) & (q[463:448]>= q[1007:992]) & (q[495:480] >= q[1007:992]) & (q[527:512] >= q[1007:992]) & (q[559:544] >= q[1007:992]) & (q[591:576] >= q[1007:992]) & (q[623:608] >= q[1007:992]) & (q[655:640] >= q[1007:992]) & (q[687:672] >= q[1007:992]) & (q[719:704] >= q[1007:992]) &(q[751:736] >= q[1007:992]) & (q[783:768] >= q[1007:992]) & (q[815:800] >= q[1007:992]) & (q[847:832] >= q[1007:992]) & (q[879:864] >= q[1007:992]) & (q[911:896] >= q[1007:992]) & (q[943:928] >= q[1007:992]) & (q[975:960] >= q[1007:992])); assign cmpr[2] = ((q[7:0] >= q[1015:1008]) & (q[23:16] >= q[1015:1008]) & (q[39:32] >= q[1015:1008]) & (q[55:48] >= q[1015:1008]) & (q[71:64] >= q[1015:1008]) &(q[87:80] >= q[1015:1008]) & (q[103:96] >= q[1015:1008]) & (q[119:112] >= q[1015:1008]) & (q[135:128] >= q[1015:1008]) & (q[151:144] >= q[1015:1008]) & (q[167:160] >= q[1015:1008]) & (q[183:176] >= q[1015:1008]) & (q[199:192] >= q[1015:1008]) & (q[215:208] >= q[1015:1008]) & (q[231:224] >= q[1015:1008]) & (q[247:240] >= q[1015:1008]) & (q[263:256] >= q[1015:1008]) & (q[279:272] >= q[1015:1008]) &(q[295:288] >= q[1015:1008]) & (q[311:304] >= q[1015:1008]) & (q[327:320] >= q[1015:1008]) & (q[343:336] >= q[1015:1008]) & (q[359:352] >= q[1015:1008]) & (q[375:368] >= q[1015:1008]) & (q[391:384] >= q[1015:1008]) & (q[407:400] >= q[1015:1008]) & (q[423:416] >= q[1015:1008]) & (q[439:432] >= q[1015:1008]) & (q[455:448] >= q[1015:1008]) & (q[471:464] >= q[1015:1008]) & (q[487:480] >= q[1015:1008]) & (q[503:496] >= q[1015:1008]) & (q[519:512] >= q[1015:1008]) & (q[535:528] >= q[1015:1008]) & (q[551:544] >= q[1015:1008]) & (q[567:560] >= q[1015:1008]) & (q[583:576] >= q[1015:1008]) & (q[599:592] >= q[1015:1008]) & (q[615:608] >= q[1015:1008]) & (q[631:624] >= q[1015:1008]) & (q[647:640] >= q[1015:1008]) & (q[663:656] >= q[1015:1008]) & (q[679:672] >= q[1015:1008]) & (q[695:688] >= q[1015:1008]) & (q[711:704] >= q[1015:1008]) & (q[727:720] >= q[1015:1008]) & (q[743:736]>= q[1015:1008]) & (q[759:752] >= q[1015:1008]) & (q[775:768] >= q[1015:1008]) & (q[791:784] >= q[1015:1008]) & (q[807:800] >= q[1015:1008]) & (q[823:816] >= q[1015:1008]) & (q[839:832] >= q[1015:1008]) & (q[855:848] >= q[1015:1008]) & (q[871:864] >= q[1015:1008]) & (q[887:880] >= q[1015:1008]) & (q[903:896] >= q[1015:1008]) & (q[919:912] >= q[1015:1008]) & (q[935:928] >= q[1015:1008]) & (q[951:944] >= q[1015:1008]) & (q[967:960] >= q[1015:1008]) & (q[983:976] >= q[1015:1008]) & (q[999:992] >= q[1015:1008])); assign bd[0] = ((q[63:8] == q[127:72]) & (q[127:72] == q[191:136]) & (q[191:136]== q[255:200]) & (q[388:328] == q[447:392]) & (q[447:392] == q[511:456]) & (q[511:456] == q[575:520]) & (q[575:520] == q[639:584]) & (q[639:584] == q[703:648]) & (q[703:648] == q[767:712]) & (q[767:712] == q[831:776]) & (q[831:776] == q[895:840]) & (q[895:840] == q[959:904]) & (q[959:904] == q[1023:968])) & cmpr[0]; assign bd[1] = ((q[63:16] == q[127:80]) & (q[127:80] == q[191:144]) & (q[191:144] == q[255:208]) & (q[255:208] == q[319:272]) & (q[319:272] == q[383:336]) & (q[383:336] == q[447:400]) & (q[447:400] == q[511:464]) & (q[511:464] == q[575:528]) & (q[575:528] == q[639:592]) & (q[639:592] == q[703:656]) & (q[703:656] == q[767:720]) & (q[767:720] == q[831:784]) & (q[831:784] == q[895:848]) & (q[895:848] == q[959:912]) & (q[959:912] == q[1023:976])) & cmpr[0]; assign bd[2] = ((q[63:32] == q[127:96]) & (q[127:96] == q[191:160]) & (q[191:160] == q[255:224]) & (q[255:224] == q[319:288]) & (q[319:288] == q[383:352]) & (q[383:352] == q[447:416]) & (q[447:416] == q[511:480]) & (q[511:480] == q[575:544]) & (q[575:544] == q[639:608]) & (q[639:608] == q[703:672]) & (q[703:672] == q[767:736]) & (q[767:736] == q[831:800]) & (q[831:800] == q[895:864]) & (q[895:864] == q[959:928]) & (q[959:928] == q[1023:992])) & cmpr[0]; assign bd[3] = ((q[31:8] == q[63:40]) & (q[63:40] == q[95:72]) & (q[95:72] == q[127:104]) & (q[127:104] == q[159:136]) & (q[159:136] == q[191:168]) & (q[191:168] == q[223:200]) & (q[223:200] == q[255:232]) & (q[255:232] == q[287:264]) & (q[287:264] == q[319:296]) & (q[319:296] == q[351:328]) & (q[351:328] == q[383:360]) & (q[383:360] == q[415:392]) & (q[415:392] == q[447:424]) & (q[447:424] == q[479:456]) & (q[479:456] == q[511:488]) & (q[511:488] == q[543:520]) & (q[543:520] == q[575:552]) & (q[575:552] == q[607:584]) & (q[607:584] == q[639:616]) & (q[639:616] == q[671:648]) & (q[671:648] == q[703:680]) & (q[703:680] == q[735:712]) & (q[735:712] == q[767:744]) & (q[767:744] == q[799:776]) & (q[799:776] == q[831:808]) & (q[831:808] == q[863:840]) & (q[863:840] == q[895:872]) & (q[895:872] == q[927:904]) & (q[927:904] == q[959:936]) & (q[959:936] == q[991:968]) & (q[991:968] == q[1023:1000])) & cmpr[1]; assign bd[4] = ((q[31:16] == q[63:48]) & (q[63:48] == q[95:80]) & (q[95:80] == q[127:112]) & (q[127:112] == q[159:144]) & (q[159:144] == q[191:176]) & (q[191:176] == q[223:208]) & (q[223:208] == q[255:240]) & (q[255:240] == q[287:272]) & (q[287:272] == q[319:304]) & (q[319:304] == q[351:336]) & (q[351:336] == q[383:368]) & (q[383:368] == q[415:400]) & (q[415:400] == q[447:432]) & (q[447:432] == q[479:464]) & (q[479:464] == q[511:496]) & (q[511:496] == q[543:528]) & (q[543:528] == q[575:560]) & (q[575:560] == q[607:592]) & (q[607:592] == q[639:624]) & (q[639:624] == q[671:656]) & (q[671:656] == q[703:688]) & (q[703:688] == q[735:720]) & (q[735:720] == q[767:752]) & (q[767:752] == q[799:784]) & (q[799:784] == q[831:816]) & (q[831:816] == q[863:848]) & (q[863:848] == q[895:880]) & (q[895:880]== q[927:912]) & (q[927:912] == q[959:944]) & (q[959:944] == q[991:976]) & (q[991:976] == q[1023:1008])) & cmpr[1]; assign bd[5] = ((q[15:8] == q[31:24]) & (q[31:24] == q[47:40]) & (q[47:40] == q[63:56]) & (q[63:56] == q[79:72]) & (q[79:72] == q[95:88]) & (q[95:88] == q[111:104]) & (q[111:104] == q[127:120]) & (q[127:120] == q[143:136]) & (q[143:136] == q[159:152]) & (q[159:152] == q[175:168]) & (q[175:168] == q[191:184]) & (q[191:184] == q[207:200]) & (q[207:200] == q[223:216]) & (q[223:216] == q[239:232]) & (q[239:232] == q[255:248]) & (q[255:248] == q[271:264]) & (q[271:264] == q[287:280]) & (q[287:280] == q[303:296]) & (q[303:296] == q[319:312]) & (q[319:312] == q[335:328]) & (q[335:328] == q[351:344]) & (q[351:344] == q[367:360]) & (q[367:360] == q[383:376]) & (q[383:376] == q[399:392]) & (q[399:392] == q[415:408]) & (q[415:408] == q[431:424]) & (q[431:424] == q[447:440]) & (q[447:440] == q[463:456]) & (q[463:456] == q[479:472]) & (q[479:472] == q[495:488]) & (q[495:488] == q[511:504]) & (q[511:504] == q[527:520]) & (q[527:520] == q[543:536]) & (q[543:536] == q[559:552]) & (q[559:552] == q[575:568]) & (q[575:568] == q[591:584]) & (q[591:584] == q[607:600]) & (q[607:600] == q[623:616]) & (q[623:616] == q[639:632]) & (q[639:632] == q[655:648]) & (q[655:648] == q[671:664]) & (q[671:664] == q[687:680]) & (q[687:680] == q[703:696]) & (q[703:696] == q[719:712]) & (q[719:712]== q[735:728]) & (q[735:728] == q[751:744]) & (q[751:744] == q[767:760]) & (q[767:760] == q[783:776]) & (q[783:776] == q[799:792]) & (q[799:792] == q[815:808])& (q[815:808] == q[831:824]) & (q[831:824] == q[847:840]) & (q[847:840] == q[863:856]) & (q[863:856] == q[879:872]) & (q[879:872] == q[895:888]) & (q[895:888] == q[911:904]) & (q[911:904] == q[927:920]) & (q[927:920] == q[943:936]) & (q[943:936] == q[959:952]) & (q[959:952] == q[975:968]) & (q[975:968] == q[991:984]) & (q[991:984] == q[1007:1000]) & (q[1007:1000] == q[1023:1016])) & cmpr[2]; assign bd[6] = ~(bd[0] | bd[1] | bd[2] | bd[3] | bd[4] | bd[5]); priority_select preget(.a(bd), .y(y)); getcode get(.a(y), .code(code), .con(con)); ttongle doubleclockmode(.clk(clk), .reset(reset), .con(con), .t(t)); always_comb begin if (con) begin case (y) 7'b0000001: cq = {1'b1, q[1087:1024], q[1023:960], 8'b0, (q[903:896] - q[967:960]), (q[839:832] - q[967:960]), (q[775:768] - q[967:960]), (q[711:704] - q[967:960]), (q[647:640] - q[967:960]), (q[583:576] - q[967:960]), (q[519:512] - q[967:960]), (q[455:448] - q[967:960]), (q[391:384] - q[967:960]), (q[327:320] - q[967:960]), (q[263:256] - q[967:960]), (q[199:192] - q[967:960]), (q[135:128] - q[967:960]), (q[71:64] - q[967:960]), (q[7:0] - q[967:960]), 384'b0, code}; //b8-1 7'b0000010: cq = {1'b1, q[1087:1024], q[1023:960], 16'b0, (q[911:896] - q[975:960]), (q[847:832] - q[975:960]), (q[783:768] - q[975:960]), (q[719:704] - q[975:960]), (q[655:640] - q[975:960]), (q[591:576] - q[975:960]), (q[527:512] - q[975:960]), (q[463:448] - q[975:960]), (q[399:384] - q[975:960]), (q[335:320] - q[975:960]), (q[271:256] - q[975:960]), (q[207:192] - q[975:960]), (q[143:128] - q[975:960]), (q[79:64] - q[975:960]), (q[15:0] - q[975:960]), 256'b0, code}; //b8-2 7'b0000100: cq = {1'b1, q[1087:1024], q[1023:960], 32'b0, (q[927:897] - q[991:960]), (q[863:832] - q[991:960]), (q[799:768] - q[991:960]), (q[735:704] - q[991:960]), (q[671:640] - q[991:960]), (q[607:576] - q[991:960]), (q[543:512] - q[991:960]), (q[479:448] - q[991:960]), (q[415:384] - q[991:960]), (q[351:320] - q[991:960]), (q[287:256] - q[991:960]), (q[223:192] - q[991:960]), (q[159:128] - q[991:960]), (q[95:64] - q[991:960]), (q[31:0] - q[991:960]), code}; //b8-4 7'b0001000: cq = {1'b1, q[1087:1024], q[1023:992], 8'b0, (q[967:960] - q[999:992]), (q[935:928] - q[999:992]), (q[903:896] - q[999:992]), (q[871:864] - q[999:992]), (q[839:832] - q[999:992]), (q[807:800] - q[999:992]), (q[775:768] - q[999:992]), (q[743:736] - q[999:992]), (q[711:704] - q[999:992]), (q[679:672] - q[999:992]), (q[647:640] - q[999:992]), (q[615:608] - q[999:992]), (q[583:576] - q[999:992]), (q[551:544] - q[999:992]), (q[519:512] - q[999:992]), (q[487:480] - q[999:992]), (q[455:448] - q[999:992]), (q[423:416] - q[999:992]), (q[391:384] - q[999:992]), (q[359:352] - q[999:992]), (q[327:320] - q[999:992]), (q[295:288] - q[999:992]), (q[263:256] - q[999:992]), (q[231:224] - q[999:992]), (q[199:192] - q[999:992]), (q[167:160] - q[999:992]), (q[135:128] - q[999:992]), (q[103:96] - q[999:992]), (q[71:64] - q[999:992]), (q[39:32] - q[999:992]), (q[7:0] - q[999:992]), 288'b0, code}; 7'b0010000: cq = {1'b1, q[1087:1024], q[1023:992], 16'b0, (q[975:960] - q[1007:992]), (q[943:928] - q[1007:992]), (q[911:896] - q[1007:992]), (q[879:864] - q[1007:992]), (q[847:832] - q[1007:992]), (q[815:800] - q[1007:992]), (q[783:768] - q[1007:992]), (q[751:736] - q[1007:992]), (q[719:704] - q[1007:992]), (q[687:672] - q[1007:992]),(q[655:640] - q[1007:992]), (q[623:608] - q[1007:992]), (q[591:576] - q[1007:992]), (q[559:544] - q[1007:992]), (q[527:512] - q[1007:992]), (q[495:480] - q[1007:992]), (q[463:448] - q[1007:992]), (q[431:416] - q[1007:992]), (q[399:384] - q[1007:992]), (q[367:352] - q[1007:992]), (q[335:320] - q[1007:992]), (q[303:288] - q[1007:992]), (q[271:256] - q[1007:992]), (q[239:224] - q[1007:992]), (q[207:192] - q[1007:992]), (q[175:160] - q[1007:992]), (q[143:128] - q[1007:992]), (q[111:96] - q[1007:992]), (q[79:64] - q[1007:992]), (q[47:32] - q[1007:992]), (q[15:0] - q[1007:992]), 32'b0, code}; 7'b0100000: cq = {1'b1, q[1087:1024], q[1023:1008], 8'b0, (q[999:992] - q[1015:1008]), (q[983:978] - q[1015:1008]), (q[967:960] - q[1015:1008]), (q[951:944] - q[1015:1008]), (q[935:928] - q[1015:1008]), (q[919:912] - q[1015:1008]), (q[903:896] - q[1015:1008]), (q[887:880] - q[1015:1008]), (q[871:864] - q[1015:1008]), (q[855:848] - q[1015:1008]), (q[839:832] - q[1015:1008]), (q[823:816] - q[1015:1008]), (q[807:800] - q[1015:1008]), (q[791:784] - q[1015:1008]), (q[775:768] - q[1015:1008]), (q[759:752] - q[1015:1008]), (q[743:736] - q[1015:1008]), (q[727:720] - q[1015:1008]), (q[711:704] - q[1015:1008]), (q[695:688] - q[1015:1008]), (q[679:672] - q[1015:1008]), (q[663:656] - q[1015:1008]), (q[647:640] - q[1015:1008]), (q[631:624] - q[1015:1008]), (q[615:608] - q[1015:1008]), (q[599:592] - q[1015:1008]), (q[583:576] - q[1015:1008]), (q[567:560] - q[1015:1008]), (q[551:544] - q[1015:1008]), (q[535:528] - q[1015:1008]), (q[519:512] - q[1015:1008]), (q[503:496] - q[1015:1008]), (q[487:480] - q[1015:1008]), (q[471:464] - q[1015:1008]), (q[455:448] - q[1015:1008]), (q[439:432] - q[1015:1008]), (q[423:416] - q[1015:1008]), (q[407:400] - q[1015:1008]), (q[391:384] - q[1015:1008]), (q[375:368] - q[1015:1008]), (q[359:352] - q[1015:1008]), (q[343:336] - q[1015:1008]), (q[327:320] - q[1015:1008]), (q[311:304] - q[1015:1008]), (q[295:288] - q[1015:1008]), (q[279:272] - q[1015:1008]), (q[263:256] - q[1015:1008]), (q[247:240] - q[1015:1008]), (q[231:224] - q[1015:1008]), (q[215:208] - q[1015:1008]), (q[199:192] - q[1015:1008]), (q[183:176] - q[1015:1008]), (q[167:160] - q[1015:1008]), (q[151:144] - q[1015:1008]), (q[135:128] - q[1015:1008]), (q[119:112] - q[1015:1008]), (q[103:96] - q[1015:1008]), (q[87:80] - q[1015:1008]), (q[71:64] - q[1015:1008]), (q[55:48] - q[1015:1008]), (q[39:32] - q[1015:1008]), (q[23:16] - q[1015:1008]), (q[7:0] - q[1015:1008]), 48'b0, code}; 7'b1000000: cq = reset ? 644'b0 : {1'b1, q[1087:512], 64'b0, code}; default: cq = 644'bz; endcase way = q[1031:1028]; end else begin if (t) begin cq = {1'b1, q[1087:512], 64'b0, code}; way = q[1031:1028]; end else begin cq = {1'b1, q[1087:1024], q[511:0], code}; way = q[1031:1028] - 1'b1; end end end endmoduleТранзакция с кэш-памятью

С пословной адресацией (64 бит) требуется 8 слов для заполнения кэш-строки объемом 64 байт. Отсюда следует, что 3 младших бита поля тега (адрес младшего слова в памяти) должны быть равны 0. А в теге запроса младшие три бита будут обеспечивать выбор слова в кэш-строке. Для выбора самой кэш-строки (адрес кэш-памяти) нужно считать следующие 4 бита (так как кэш-строк 16 = 2^4) тега запроса (при чтении), либо тега в буфере чтения (при записи)

Когда включена компрессия, каждая кэш-строка может содержать 8, либо 16 слов. Тогда младшие 4 бита поля тега будут равны 0. Младшие 4 бита тега запроса будут обеспечивать выбор слова из кэш-памяти. Следующие 4 бита в теге запроса или в поле тега буфера чтения будут обеспечивать выбор кэш-строки

Запись в кэш-память осуществляется только через компрессор, даже если компрессия отключена.

Операция чтения (RD активен) происходит следующим образом. По тегу запроса известно, в какой кэш-строке находятся данные. Затем поле тега передается и бит достоверности вместе с тегом запроса, а также вместе с сигналом CON передаются в фильтр запросов. Там происходит сравнение старших бит поля тега и старших бит тега запроса. Младшие 3 или 4 бита (в зависимости от сигнала CON) не сравниваются по той причине, что у тега запроса они служат для выбора слова. Если равенство устанавливается, а также бит достоверности равен 1, то сигнал кэш-попадание устанавливается в 0. В противном случае данный сигнал устанавливается в 1. 

Когда компрессия включена, но для строки нет режимов компрессии, отсеиваются запросы в первые 4 слова

Схема фильтра запросов описана ниже

module requestfilter(input tri [643:0] d, input tri [63:0] tag, input tri con, input tri [3:0] wordaddr, output logic cachemiss); tri filter; tri [63:0] tageq; tri [63:0] deq; tri code110; assign tageq = con ? {tag[63:4], 4'b0} : {tag[63:3], 3'b0}; assign deq = con ? {d[642:583], 4'b0} : {d[642:582], 3'b0}; assign code110 = con ? ((d[2:0] == 3'b110) & (wordaddr < 4'b0111)) : 1'b0; assign filter = code110 ? 1'b1 : 1'b0; always_comb begin if(d[643] & (tageq == deq)) cachemiss = 1'b0 | filter; else cachemiss = 1'b1; end endmodule

Данные с кэш-памяти попадают в декомпрессор. Декомпрессия происходит путем сложения базы и дельт. Если компрессия отключена, либо для строки нет режима компрессии, то данные кэш-строки выводятся без декомпрессии. Декомпрессор реализован с помощью сумматоров, работающих параллельно. Декомпрессор представлен ниже

module decompressor(input tri [578:0] d, input tri clk, reset, output logic [1023:0] q); always_comb begin case (d[2:0]) 3'b000: q = {d[578:515], (d[506:499] + d[578:515]), (d[498:491] + d[578:515]), (d[490:483] + d[578:515]), (d[482:475] + d[578:515]), (d[474:467] + d[578:515]), (d[466:459] + d[578:515]), (d[458:451] + d[578:515]), (d[450:443] + d[578:515]), (d[442:435] + d[578:515]), (d[434:427] + d[578:515]), (d[426:419] + d[578:515]), (d[418:411] + d[578:515]), (d[410:403] + d[578:515]), (d[402:395] + d[578:515]), (d[394:387] + d[578:515])}; 3'b001: q = {d[578:515], (d[498:483] + d[578:515]), (d[482:467] + d[578:515]), (d[466:451] + d[578:515]), (d[450:435] + d[578:515]), (d[434:419] + d[578:515]), (d[418:403] + d[578:515]), (d[402:387] + d[578:515]), (d[386:371] + d[578:515]), (d[370:355] + d[578:515]), (d[354:339] + d[578:515]), (d[338:323] + d[578:515]), (d[322:307] + d[578:515]), (d[306:291] + d[578:515]), (d[290:275] + d[578:515]), (d[274:259] + d[578:515])}; 3'b010: q = {d[578:515], (d[482:451] + d[578:515]), (d[450:419] + d[578:515]), (d[418:387] + d[578:515]), (d[386:355] + d[578:515]), (d[354:323] + d[578:515]), (d[322:291] + d[578:515]), (d[290:259] + d[578:515]), (d[258:227] + d[578:515]), (d[226:195] + d[578:515]), (d[194:163] + d[578:515]), (d[162:131] + d[578:515]), (d[130:99] + d[578:515]), (d[98:67] + d[578:515]), (d[66:35] + d[578:515]), (d[34:3] + d[578:515])}; 3'b011: q = {d[578:547], (d[538:531] + d[578:547]), (d[530:523] + d[578:547]), (d[522:515] + d[578:547]), (d[514:507] + d[578:547]), (d[506:499] + d[578:547]), (d[498:491] + d[578:547]), (d[490:483] + d[578:547]), (d[482:475] + d[578:547]), (d[450:443] + d[578:547]), (d[442:435] + d[578:547]), (d[434:427] + d[578:547]), (d[426:419] + d[578:547]), (d[418:411] + d[578:547]), (d[410:403] + d[578:547]), (d[402:395] + d[578:547]), (d[394:387] + d[578:547]), (d[386:379] + d[578:547]), (d[378:371] + d[578:547]), (d[370:363] + d[578:547]), (d[362:355] +d[578:547]), (d[354:347] + d[578:547]), (d[346:339] + d[578:547]), (d[338:331] +d [578:547]), (d[330:323] + d[578:547]), (d[322:315] + d[578:547]), (d[314:307] + d[578:547]), (d[306:299] + d[578:547]), (d[298:291] + d[578:547])}; 3'b100: q = {d[578:547], (d[530:515] + d[578:547]), (d[514:499] + d[578:547]), (d[498:483] + d[578:547]), (d[482:467] + d[578:547]), (d[466:451] + d[578:547]), (d[450:435] + d[578:547]), (d[434:419] + d[578:547]), (d[418:403] + d[578:547]), (d[402:387] + d[578:547]), (d[386:371] + d[578:547]), (d[370:355] + d[578:547]), (d[354:339] + d[578:547]), (d[338:323] + d[578:547]), (d[322:307] + d[578:547]), (d[306:291] + d[578:547]), (d[290:275] + d[578:547]), (d[274:259] + d[578:547]), (d[258:243] + d[578:547]), (d[242:227] + d[578:547]), (d[226:211] + d[578:547]), (d[210:195] + d[578:547]), (d[194:179] + d[578:547]), (d[178:163] + d[578:547]), (d[162:147] + d[578:547]), (d[146:131] + d[578:547]), (d[130:115] + d[578:547]), (d[114:99] + d[578:547]), (d[98:83] + d[578:547]), (d[82:67] + d[578:547]), (d[66:51] + d[578:547]), (d[50:35] + d[578:547])}; 3'b101: q = {d[578:563], (d[554:547] + d[578:563]), (d[546:539] + d[578:563]), (d[538:531] + d[578:563]), (d[530:523] + d[578:563]), (d[522:515] + d[578:563]), (d[514:507] + d[578:563]), (d[506:499] + d[578:563]), (d[498:491] + d[578:563]), (d[490:483] + d[578:563]), (d[482:475] + d[578:563]), (d[474:467] + d[578:563]), (d[466:459] + d[578:563]), (d[458:451] + d[578:563]), (d[450:443] + d[578:563]), (d[442:435] + d[578:563]), (d[434:427] + d[578:563]), (d[426:419] + d[578:563]), (d[418:411] + d[578:563]), (d[410:403] + d[578:563]), (d[402:395] + d[578:563]), (d[394:387] + d[578:563]), (d[386:379] + d[578:563]), (d[378:371] +d[578:563]), (d[370:363] + d[578:563]), (d[362:355] + d[578:563]), (d[354:347] +d[578:563]), (d[346:339] + d[578:563]), (d[338:331] + d[578:563]), (d[330:323]+ d[578:563]), (d[322:315] + d[578:563]), (d[314:307] + d[578:563]), (d[306:299]+ d[578:563]), (d[298:291] + d[578:563]), (d[290:283] + d[578:563]), (d[282:275] + d[578:563]), (d[274:267] + d[578:563]), (d[266:259] + d[578:563]), (d[258:251] + d[578:563]), (d[250:243] + d[578:563]), (d[242:235] + d[578:563]), (d[234:227] + d[578:563]), (d[226:219] + d[578:563]), (d[218:211] + d[578:563]), (d[210:203] + d[578:563]), (d[202:195] + d[578:563]), (d[194:187] + d[578:563]), (d[186:179] + d[578:563]), (d[178:171] + d[578:563]), (d[170:163] + d[578:563]), (d[162:155] + d[578:563]), (d[154:147] + d[578:563]), (d[146:139] + d[578:563]), (d[138:131] + d[578:563]), (d[130:123] + d[578:563]), (d[122:115] + d[578:563]), (d[114:107] + d[578:563]), (d[106:99] + d[578:563]), (d[98:91] + d[578:563]), (d[90:83] + d[578:563]), (d[82:75] + d[578:563]), (d[74:67] + d[578:563]), (d[66:59]+ d[578:563]), (d[58:51] + d[578:563])}; 3'b110: q = {d[578:3], 448'b0}; default: q = 1024'bz; endcase end endmodule

Затем, имея адрес слова, схема WSU (Word Select UnIt) выводит одно из слов памяти на выход. Её описание представлено ниже

module wordselectunit(input tri [1023:0] d, input tri [3:0] addr, output logic [63:0] q); always_comb begin case(addr) 4'b1111: q = d[1023:960]; 4'b1110: q = d[959:896]; 4'b1101: q = d[895:832]; 4'b1100: q = d[831:768]; 4'b1011: q = d[767:704]; 4'b1010: q = d[703:640]; 4'b1001: q = d[639:576]; 4'b1000: q = d[575:512]; 4'b0111: q = d[511:448]; 4'b0110: q = d[447:384]; 4'b0101: q = d[383:320]; 4'b0100: q = d[319:256]; 4'b0011: q = d[255:192]; 4'b0010: q = d[191:128]; 4'b0001: q = d[127:64]; 4'b0000: q = d[63:0]; default: q = 64'bz; endcase end endmodule

Обращение к кэш-памяти происходит стандартным образом за тем исключением, что есть схема декомпрессии. Со сжатыми кэш-строками мы работаем также, как если бы мы работали с настоящими 128-ми байтовыми кэш-строками. Данная реализация алгоритма Base+Delta не меняет принципов ассоциативности кэш-памяти.

Конечная схема

Вся система выглядит следующим образом

module cachewithcompression(input tri [1087:0] readbuffer, input tri [63:0] tag, input tri con, clk, reset, rd, output tri [63:0] q, output tri cachehit); tri [643:0] cq; tri [643:0] cqic; tri [1023:0] pdq, dq; tri [3:0] addr; tri cachemiss; tri [3:0] wordaddr; tri [3:0] addrread, addrwrite; tri [643:0] wsuq; msbitoutput msbitoutput(.word(tag[3:0]), .s(con), .outputword(wordaddr)); mux2_4 conmux(.a(tag[6:3]), .b(tag[7:4]), .s(con), .c(addrread)); mux2_4 addrselect(.a(addrwrite), .b(addrread), .s(rd), .c(addr)); compressor compressor(.d(readbuffer), .con(con), .clk(clk), .reset(reset), .cq(cq), .way(addrwrite)); cache cache(.d(cq), .addr(addr), .clk(clk), .reset(reset), .rd(rd), .q(cqic)); requestfilter requestfilter(.d(cqic), .tag(tag), .wordaddr(wordaddr), .con(con), .cachemiss(cachemiss)); decompressor decompressor(.d(cqic), .clk(clk), .reset(reset), .q(pdq)); bufferd bufd(.d(pdq), .clk(clk), .reset(reset), .q(dq)); wordselectunit wsu(.d(dq), .addr(wordaddr), .q(wsuq)); assign cachehit = ~cachemiss & rd; assign q = cachehit ? wsuq : 64'bz; endmodule

Здесь, помимо описанных модулей, есть ещё несколько мультиплексоров, обеспечивающих выбор правильного адреса для кэш-памяти. Стоит ещё отметить, что данные выводятся только при кэш-попадании. Значение кэш-попадания основано на инвертированном значении кэш-промаха и сигнала RD. То есть даже если кэш-попадание есть в принципе есть, считывание не произойдет, если используется операция записи

Полезные ссылки

В статье, как вы увидели, отсутствуют тесты. Их вы можете посмотреть у авторов-разработчиков

О таких алгоритмах я узнал от других разработчиков, статью которых прикрепляю

Залил на github



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3