nabbla (nabbla1) wrote,
nabbla
nabbla1

Весеннее обострение - 2

Что ж, обмозговали немного, как нам ускорить АЛУ, пора выполнять! Сначала самое простое и приятное - добавить новые выводы и проводки:


Если сравнивать с прошлой схемой, обнаружим:
- добавились входы SrcStall и SrcDiscard. То, что они отсутствовали на старой схеме, мне сейчас показалось было криминалом, но я так и не смог придумать сценария, когда это привело бы к проблеме, будь то ошибочное срабатывание байпаса или ошибочная задержка на один такт. Всё-таки, когда АЛУ всех останавливает, особенно интересных ситуаций не возникает :) А вот новой схеме, у меня такое чувство, без этих входов не обойтись!
- ушёл модуль EnableBypass, точнее, переехал внутрь ALUoutput, а в ALUcontrol перестала поступать шина SrcAddr - мы как бы разделили "зоны ответственности".
- добавились выходы DestStallReq, Busy и SBusy. Первый будет останавливать процессор, если нам нужен результат работы АЛУ, а оно ещё вкалывает. Два других будут вести в QuatCorePC, для корректной работы условных переходов, завязанных на АЛУ. Busy будет управлять работой JO / JNO, а SBusy (sign busy) - работой JL / JGE. Этот SBusy можно просто соединить с Busy, а можно ещё пожадничать - и выдавать на него единичку лишь на тех командах АЛУ, которые воздействуют на флаг знака.

Модуль ALUoutput мы уже переделали, из QuatCoreALUoutput в QuatCorePipelineALUoutput:


module QuatCorePipelineALUoutput (input clk, input [7:0] SrcAddr, input [16:0] Acc, input [15:0] C, input SrcDiscard, input SrcStall, input busy, output [15:0] Q, output isOFLO, output DestStallReq, output reg BypassEn = 1'b0);

assign isOFLO = (Acc[16] != Acc[15]);

wire [1:0] mode;
//00: Q = -32768
//01: Q = 32767
//10: Q = Acc[15:0]
//11: Q = C

assign mode[1] = SrcAddr[1] | ~isOFLO;
assign mode[0] = SrcAddr[1] & SrcAddr[0] | (~SrcAddr[1]) & Acc[15] & (~Acc[16]); 

assign Q = (mode == 2'b00)? 16'h8000 :
           (mode == 2'b01)? 16'h7FFF :
           (mode == 2'b10)? Acc [15:0]:
							C;

wire isOurAddr = (SrcAddr[7:3] == 5'b1000_0) & (~SrcDiscard) & (~SrcStall);
assign DestStallReq = isOurAddr & busy;

always @(posedge clk)
	BypassEn <= isOurAddr;

endmodule


Здесь можно увидеть логику формирования переполнения, а также как происходит насыщение результата, если выбрана команда Acc, а не UAC (Unsigned Acc - там аккумулятор берётся "как есть").

Ну и сразу внесём изменения в QuatCorePC:


В сравнении с прошлой схемой, здесь чуть переехал вход DestStall: раньше он шёл в нижний модуль, теперь туда он не идёт, взамен - в relJumpDecision. Так оно логичнее. Ну и сам этот модуль заметно "растолстел": в него добавились входы ALUbusy и ALUsbusy, а также выход SrcStallReq.

Вот его код:
module QuatCorePCpipelineRelJumpDecision (	input isNeg, input isOFLO, input iZ, input jZ, input kZ, input iEQk,
											input [7:0] DestAddr, input DestStall, input ALUbusy, input ALUsbusy,
											output DoJump, output SrcStallReq);

wire isOurOp = (DestAddr[7:5] == 3'b101)&DestAddr[3]&(~DestStall);

wire isLOOP = isOurOp & (~DestAddr[4]);

wire DoiLOOP 	= isLOOP & (DestAddr[1:0] == 2'b00) & (~iZ);
wire DojLOOP 	= isLOOP & (DestAddr[1:0] == 2'b01) & (~jZ);
wire DokLOOP 	= isLOOP & (DestAddr[1:0] == 2'b10) & (~kZ);
wire DoJik	= isLOOP & (DestAddr[1:0] == 2'b11) & (iEQk ^ DestAddr[2]);

wire isFlags 	= isOurOp & DestAddr[4];
wire DoJL	= isFlags & (~DestAddr[1]) & (isNeg ^ DestAddr[2]);
wire DoJO	= isFlags & DestAddr[1] & (isOFLO ^ DestAddr[2]);

assign DoJump = DoiLOOP | DojLOOP | DokLOOP | DoJik | DoJL | DoJO;

assign SrcStallReq = (isFlags & (~DestAddr[1]) & ALUsbusy) | (isFlags & DestAddr[1] & ALUbusy);

endmodule


Собственно, выражение для DoJump и не поменялось, но теперь формируется также выражение SrcStallReq, если мы выполняем JL/JGE и при этом АЛУ ещё работает над операцией, которая поменяет флаг знака, либо выполняем JO/JNO, и АЛУ ещё не завершило работу. Тогда счётчик инструкций (PC, Program Counter) остановится на то время, что SrcStallReq = 1, за это время результат может поменяться, можем передумать прыгать (или наоборот, решиться), неважно. Главное, что когда наконец-то установится SrcStallReq=0, решение уже будет правильным.


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

А ещё я страшный человек, абсолютно ненадёжный - куда-то посеял справку по 3-й форме, которую мне выдали в 2018 году, а теперь вдруг спохватились - ВЕРНИ ЕЁ НАЗАД! С тех пор я дважды переехал на работе, а ещё уеззжал на самоизоляцию и возвращался из неё, но справку вынь да положь.
Tags: ПЛИС, программки, работа, странные девайсы
Subscribe

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

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

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

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

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

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

  • Ковыряемся с сантехникой

    Наконец-то закрыл сколько-нибудь пристойно трубы, подводящие к смесителю, в квартире в Москве: А в воскресенье побывал на даче, там очередная…

  • Мартовское велосипедное

    Продолжаю кататься на работу и с работы на велосипеде, а также в РКК Энергию и на дачу. Хотя на две недели случился перерыв, очередная поломка,…

  • Обнаружение на новом GPU - первые 16 мс

    Закончилась симуляция. UFLO и OFLO ни разу не возникли, что не может не радовать. За это время мы дошли до строки 0x10F = 271. Поглядим дамп памяти:…

  • Post a new comment

    Error

    Anonymous comments are disabled in this journal

    default userpic

    Your IP address will be recorded 

  • 1 comment