nabbla (nabbla1) wrote,
nabbla
nabbla1

Categories:

QuatCoreImmTable - по-простому

Описанный вчера алгоритм пока не реализовал, больно он мудрёный, для начала "подготовил для него почву", т.е реализовал пока самый дурацкий алгоритм, и хочу убедиться, что весь код генерируется верно, хоть и не очень эффективно. А именно, сейчас генерится такой вот модуль:

//таблица непосредственных значений, сгенерированная под конкретный исполняемый код
module QuatCoreImmTable (input [7:0] SrcAddr, output [15:0] Q);
	wire[5:0] adr = SrcAddr[5:0];
	assign Q = 
		(adr==5'h00)?	16'h005D:
		(adr==5'h01)?	16'h0018:
		(adr==5'h02)?	16'h0000:
		(adr==5'h03)?	16'h0003:
		(adr==5'h04)?	16'h0001:
		(adr==5'h05)?	16'h0019:
		(adr==5'h06)?	16'h0017:
		(adr==5'h07)?	16'h00F0:
		(adr==5'h08)?	16'h001A:
		(adr==5'h09)?	16'h001C:
		(adr==5'h0A)?	16'h001E:
		(adr==5'h0B)?	16'h0031:
		(adr==5'h0C)?	16'h00C7:
		(adr==5'h0D)?	16'h2B02:
		(adr==5'h0E)?	16'h0016:
		(adr==5'h0F)?	16'h00F2:
		(adr==5'h10)?	16'h4000:
		(adr==5'h11)?	16'h00CD:
		(adr==5'h12)?	16'h0013:
		(adr==5'h13)?	16'h54FE:
		(adr==5'h14)?	16'hAA80:
		(adr==5'h15)?	16'h00EC:
		(adr==5'h16)?	16'h00CB:
		(adr==5'h17)?	16'h00EE:
		(adr==5'h18)?	16'h001B:
				16'hxxxx;
endmodule


То есть, мы просто выкладываем значения одно за другим, вместо того, чтобы долго и упорно придумывать их расположение в доступных 128 ячейках. Хорошо хоть, программе хватает ума понять, что из 7 бит SrcAddr, "отданных" под непосредственные значения, достаточно взять 5, что несколько снизит расходы логических элементов.

И как ни странно, такое безобразие синтезируется в 32 ЛЭ - не шибко хорошо, но и не шибко плохо, жить можно...


Странная вещь: в порядке эксперимента я "ручками" вбил следующие значения:

module QuatCoreImmTable (input [7:0] SrcAddr, output [15:0] Q);
	wire[5:0] adr = SrcAddr[5:0];
	assign Q = 
		(adr==5'h00)?	16'bxxxx_xxxx_0101_1101:
		(adr==5'h01)?	16'bxxxx_xxxx_0001_1000:
		(adr==5'h02)?	16'b0000_0000_0000_0000:
		(adr==5'h03)?	16'bxxxx_xxxx_xxx0_0011:
		(adr==5'h04)?	16'b0000_0000_0000_0001:
		(adr==5'h05)?	16'bxxxx_xxxx_xxx1_1001:
		(adr==5'h06)?	16'bxxxx_xxxx_xxx1_0111:
		(adr==5'h07)?	16'bxxxx_xxxx_1111_0000:
		(adr==5'h08)?	16'bxxxx_xxxx_0001_1010:
		(adr==5'h09)?	16'bxxxx_xxxx_0001_1100:
		(adr==5'h0A)?	16'bxxxx_xxxx_0001_1110:
		(adr==5'h0B)?	16'bxxxx_xxxx_0011_0001:
		(adr==5'h0C)?	16'bxxxx_xxxx_1100_0111:
		(adr==5'h0D)?	16'b0010_1011_0000_0010:
		(adr==5'h0E)?	16'bxxxx_xxxx_xxx1_0110:
		(adr==5'h0F)?	16'bxxxx_xxxx_1111_0010:
		(adr==5'h10)?	16'b0100_0000_0000_0000:
		(adr==5'h11)?	16'bxxxx_xxxx_1100_1101:
		(adr==5'h12)?	16'bxxxx_xxxx_xxx1_0011:
		(adr==5'h13)?	16'bxxxx_xxxx_xxx1_1011:
		(adr==5'h14)?	16'bxxxx_xxxx_1110_1110:
		(adr==5'h15)?	16'bxxxx_xxxx_1100_1011:
		(adr==5'h16)?	16'bxxxx_xxxx_1110_1100:
		(adr==5'h17)?	16'b1010_1010_1000_0000:
		(adr==5'h18)?	16'b0101_0100_1111_1110:
				16'hxxxx;			
endmodule


То есть, в явном виде отметил те биты, которые нам "безразличны". Надеялся, что при синтезе Квартус упростит логику, но не тут-то было: размер модуля ВОЗРОС до 46 ЛЭ (!!!). В общем-то, подобное я наблюдал и ранее: Квартус очень странно воспринимает эти don't care, не припомню, когда их применение позволяло действительно уменьшить размеры модулей.

Посмотрим на фрагмент листинга программы, которую мы сейчас компилировали:

main proc
00  FD00              SP      Stack
AffineAlgorithm     proc
    Associate4Points    proc
        FindMDD3    proc
01  DD01                  Y       Points2D
02  F002                  [SP+1]  0   ;максимальная отдалённость, инициализируем нулём
03  A103                  j       3
04  A204      @@j_loop:   k       1   ;также от 0 до 3, чтобы все расстояния просуммировать
05  FC02                  [SP]    0   ;здесь будет храниться текущий максимум
06  A003      @@k_loop:   i       3   ;от 0 до 1, т.е значения X и Y
07  80DA      @@i_loop:   Acc     [Y+2j+k]    ;загрузили одно значение
08  83D9                  SUB     [Y+2i+k]    ;вычитаем второе
09  9C80                  SQRD2   Acc         ;возводим в квадрат
0A  82FC                  ADD     [SP]        ;прибавляем к пред. значению
0B  FC80                  [SP]    Acc
0C  A805                  iLOOP   @@i_loop        ;теперь то же самое для второй координаты
0D  AA06                  kLOOP   @@k_loop
0E  83F0                  SUB     [SP+1]  ;можно и "пожертвовать" значением в Acc,
0F  B804                  JL      @@skip
10  F0FC                  [SP+1]  [SP]    ;двухпортовая память-это зашибись!
11  CDA1                  X       j
12  A907          @@skip: jLOOP   @@j_loop
13  A0CD                  i       X
14  CD01                  X       Points2D
15  ED01                  Z       Points2D
16  F3B3                  CALL        SwapPoints  ;потёрли текущий максимум (лежал в [SP])-и хрен с ним
        FindMDD3    endp


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

Теперь надо в QuatCore заменить старый модуль QuatCoreImm заменить на новый QuatCoreImmTable, и попробовать снова запустить эту программу на симуляции. Вот как выглядит сейчас QuatCore без периферии, одно "ядро":



Вот и сменился самый "долгоживущий" модуль... Остальные-то тоже, как видно по названиям, менялись уже несколько раз. Когда от 4 МГц переходил к 25 МГц, все модули, рассчитанные на конвейер, получили приставку Fast, кроме ПЗУ кода, который почему-то получил окончание wStall. Модуль обращения к памяти обрёл "версию 3", т.к в первой версии был один мультиплексор базового адреса, во второй версии их стало два (один для формирования эффективного адреса, второй - для выбора одного из регистров на выход шины данных), в третьей - добавились "защёлки" для повышения тактовой частоты до 25 МГц и хитрости с остановкой конвейера.

Счётчик инструкций получил "приставку" Ultimate буквально неделю назад, когда ему подсократили размер сумматора для относительных прыжков, а верхние биты заменили реверсивным счётчиком.

Запускаем синтез. Вся эта штуковина упихивается в 550 ЛЭ, тогда как со старым модулем QuatCoreImm упихивались в 507 ЛЭ. Не очень хорошо, но по крайней мере фиттер не ругался и управился с работой очень быстро, и по таймингам всё хорошо, мы явно сейчас работали не с критическим путём :)

Запустим симуляцию.


И работу QuatCoreImmTable можно наблюдать "воочию", сравнивая, какие даются "команды" (SrcAddr) и какие значения в итоге появляются на шине данных. Всё в точности как в этой таблице.


Какая-то прямо Agile-методология получается - ломать, но аккуратно, чтобы в течение недели восстановить функционирование, но уже с дополнительными "пряниками" :)

Но сразу возникает желание отложить экономию 40 ЛЭ на потом, как бы запомнить, что "здесь можно сделать существенно лучше", а пока взяться за программу обработки видео в реальном времени.

Вообще, даже сейчас обмен вышел довольно выгодный: мы поменяли 10 слов кода и данных = 160 бит, на лишние 31 ЛЭ (до всей эпопеи с переделкой счётчика инструкций и таблицы непосредственных команд, ядро занимало 519 ЛЭ, а сейчас 550). Но можно-то вообще шикарно, и даже понятно, как :)
Poll #2103007 Суперский алгоритм составления таблицы QuatCoreImmTable

Стоит ли его реализовывать прямо сейчас?

Да
0(0.0%)
Нет
0(0.0%)
Tags: ПЛИС, программки, работа, странные девайсы
Subscribe

Recent Posts from This Journal

  • Нахождение двух самых отдалённых точек

    Пока компьютер долго и упорно мучал симуляцию, я пытался написать на ассемблере алгоритм захвата на ближней дистанции. А сейчас на этом коде можно…

  • Слишком общительный счётчик

    Вчера я чуть поторопился отсинтезировать проект,параметры не поменял: RomWidth = 8 вместо 7, RamWidth = 9 вместо 8, и ещё EnableByteAccess=1, чтобы…

  • Балансируем конвейер QuatCore

    В пятницу у нас всё замечательно сработало на симуляции, первые 16 миллисекунд полёт нормальный. А вот прошить весь проект на ПЛИС и попробовать "в…

  • Post a new comment

    Error

    Anonymous comments are disabled in this journal

    default userpic

    Your IP address will be recorded 

  • 0 comments