
Здесь "голое ядро" QuatCore, без прочей периферии в лице SRAM, SPI, UART и LCD.
Эта "схема" синтезируется в 949 ЛЭ, что уже потихоньку начинает напрягать. На той ПЛИС, что сейчас у меня на макетке, 5576ХС4Т, имеется 9984 ЛЭ, так что я менее 10% занял, но я-то мечтаю в 5576ХС6Т поместиться (у неё нормирована стойкость к ТЗЧ, в отличие от ХС4Т, где это нужно ставить схему защиты от тиристорного эффекта и доказывать её работоспособность), а там их всего 2880, а ведь мне ещё нужен контроллер МКО (Mil-Std 1553), да и видеопроцессора нужно два, и ещё не все алгоритмы "зашиты" в память, когда к двум алгоритмам обработки изображения добавится два математических алгоритма, ширина регистров QuatCore несколько подрастёт... Но кажется, что всё складывается, возможно даже с запасом.
Максимально допустимая частота 26,39 МГц, критический путь проходит через недра QuatCore, что вполне ожидаемо - я его и "разгонял" до 25 МГц, разбивал комбинаторные пути, пока не добился этого результата, и дальше не пошёл.
Мультиплексор шины данных в очередной раз пришлось подрихтовать, добавить новый вход GPU.
Так он сейчас выглядит:
module QuatCoreSrcMux (input [7:0] SRAM, input [15:0] MEM, input [15:0] ALU, input [15:0] IMM, input [15:0] PC, input [15:0] IO, input [15:0] GPU, input [7:0] SrcAddr, input clk, input stall, output [15:0] Q); parameter DoLatch = 1'b1; parameter EnableIO = 1'b0; parameter EnableSRAM = 1'b0; parameter EnableGPU = 1'b1; reg [15:0] rQ; wire [15:0] combQ; assign combQ = (~SrcAddr[7])? IMM : SrcAddr[6]? MEM : SrcAddr[5]? PC : (~SrcAddr[4])|(~(EnableIO|EnableSRAM))? ((SrcAddr[3]&EnableGPU)? GPU : ALU) : (SrcAddr[3]&EnableSRAM)|(~EnableIO)? SRAM : IO; always @(posedge clk) if (~stall) rQ <= combQ; assign Q = DoLatch? rQ : combQ; endmodule
Самый большой куш по-прежнему принадлежит модулю IMM: целых 128 адресов по SrcAddr, 0xxx_xxxx, остаётся 128 адресов.
Следующий по счёту модуль внутренней памяти MEM: 64 адреса, 11xx_xxxx. Остаётся 64 адреса.
Их делим ещё пополам, одна половина достаётся счётчику инструкций PC, 101x_xxxx. Остаётся ещё 32 адреса.
Раньше ещё половину от остатка, 16 адресов, брало арифметическо-логическое устройство ALU, 1000_xxxx. Но сейчас, если мы задействуем вход от видеопроцессора, GPU, то откусываем ещё от ALU, оно получает лишь 8 адресов, 1000_0xxx, а другие 8 адресов получает GPU: 1000_1xxx.
И ещё по 8 адресов получают IO (1001_0xxx) и SRAM (1001_1xxx), в итоге всё наше небольшое адресное пространство "внутренней шины QuatCore" оказывается распределённым.
Я поставил параметры, которые должны отключить неиспользуемые входы, и рано или поздно постараюсь во всех модулях их задействовать, чтобы и декодирующая логика могла упрощаться, если мы заранее знаем, что каких-то устройств у нас не будет. Впрочем, много на этом сэкономить всё равно не получится, декодирующая логика довольно "дешёвая", разве что мультиплексор немножко упростится.
Ладно, пока всё хорошо :) Бывали у меня случаи, когда "на ровном месте" Fitter начинал бунтовать - Can't find fit, а стоит его перенастроить на более агрессивную "прокладку путей" - начинают тайминги валиться. Но здесь всё нормально, что и ожидалось - видеопроцессор от QuatCore хорошо "развязаны" буферами, сами буферы очень быстродействующие (у них отдельно получались частоты в 120 МГц и выше, на нашем-то тормозном хламе :)), поэтому фиттеру простор для фантазии, куда сунуть QuatCore, куда сунуть GPU, а соединения между регистрами буферов можно через половину кристалла протащить - работать будет!
Пора тестировать всё целиком - программу видеообработки на только что "собранном" для неё железе :) Чего-то страшно...