Перейти к содержанию
    

Койяанискаци - ТТЛ-процессор с душой акына

Сегодня, на свежую голову, пришла одна любопытная мысль…

Процессоры i8085 и i8086 имеют мультиплексированную шину адреса и данных, предназначенную для работы с соответствующими ИМС.

Тут подумалось, что везде совмещали именно D0-D7 и A0-A7…
А что, если совместить D0-D7 с A8-A15, так как старшая часть адреса меняется относительно реже младшей?
То есть, сделать ход конём в рамках конкретной реализации, чтобы сэкономить на тактах: Использовать мелкий внешний регистровый файл, который мог бы переключаясь сам выдавать старшие биты адреса…

Вот на этом моменте выясняется, что вся проблема реализации в том, что она затачивается под конкретную шинную архитектуру.

Мне нужно разработать сухое ядро, которое уже будет обвешиваться всяческими контроллерами шин.

ЯДРО

  1. Должно обрабатывать поток машинного кода в формальном виде, как маршрутизатор
  2. Должно подключаться к регистровому файлу любого исполнения: Монолитное внутреннее или внешним кэшем
  3. Должно только вырабатывать управляющие сигналы для работы всех узлов, входящих в состав процессора

Тем самым, параметр разрядности не должен иметь никакого значения (чем-то напоминает процессорную секцию), как и архитектурное исполнение (Гарвардское или Принстонское).

На данный момент у меня более-менее разработан и отлажен лишь контроллер шины:

Спойлер
module bus_control
(input	wire	clk		// Clock
,input	wire	rst		// Reset
,input	wire	bus_save	// Machine Cycle: Write/Read
,input	wire	bus_ready	// External Ready Signal
//////////////////////////////////
,output reg	bus_read	// External Out for Read
,output reg	bus_write	// External Out for Write
//////////////////////////////////
,output	reg	bus_measure	// Machine Cycle Enable
,output	reg	bus_translate	// Data translation or z-state Data-bus
,output	reg	bus_receive	// Data receiving
,output	reg	bus_lock	// Enable changes for new address
);
	//////////////////////////
	always @*
	begin
		bus_translate = bus_write | (bus_save & ~bus_measure);
		bus_receive = bus_read & ~bus_ready & ~bus_measure;
		bus_lock = bus_read ~| bus_write;
	end
	//////////////////////////
	always @(posedge clk)
		if(~rst)
		begin
			bus_read <= 1'b0;
			bus_write <= 1'b0;
			bus_measure <= 1'b0;
		end else begin
			bus_read <= bus_measure ~| bus_save;
			bus_write <= ~bus_measure & bus_save;
			bus_measure <= ~bus_measure & (bus_read | bus_write) & ~bus_ready;
		end
endmodule

Здесь:

  • bus_measure - сигнал о разрешении выполнения текущего машинного цикла
  • bus_lock - сигнал о разрешении переключения шины адреса

Эти сигналы введены относительно недавно и отвечают за задержки всего остального. Иначе говоря, этот модуль получился основным задающим и остановить его нельзя: Только притормозить.

Думаю, именно «bus_measure» должен, в принципе, управлять Ядром в плане скорости, как я понимаю…
То есть, по «bus_lock» отдельные исполняющие (Регистровый Файл, Вычислитель Эффективного Адреса и Управление УВВ) архитектуры должны выполнять свой цикл…

Вот здесь, как ведущий инженер-конструктор проекта, я чувствую себя никак!
У меня нет базовых представлений о маршрутизации.

Дешифратор команд также более-менее закончил:

Спойлер
module	command_decoder
(input	wire	[7:0]	operation	// Instruction
//////////////////////////////////////////
,output	reg		command_hlt	//   00
,output	reg		command_bcd	// 01::99
,output	reg		command_alu	// 0A::9F
,output	reg		command_reg	// A0..A9 / B0..B9 / C0..C9 / D0..D9
,output	reg		command_arg	// AA..AD / BA..BD / CA..CD / DA..DD	
,output	reg		command_cnd	// AE..AF / BE..BF / CE..CF / DE..DF
,output	reg		command_int	// E0..FF
);
	reg		hi_reg, lo_reg;
	reg		hi_bcd, lo_bcd;

	always	@(operation)
	begin
		hi_reg = operation[7] & ^operation[6:5];
		lo_reg = operation[3] & ^operation[2:1];
		hi_bcd = operation[7] ~& |operation[6:5];
		lo_bcd = operation[3] ~& |operation[2:1];
	end
		//
	always	@*
	begin
		command_hlt = ~|operation[7:0];
		command_bcd = hi_bcd & lo_bcd & |operation[7:0];
		command_alu = hi_bcd & operation[3] & |operation[2:1];
		command_reg = hi_reg & lo_bcd;
		command_arg = hi_reg & lo_reg;
		command_cnd = hi_reg & &operation[3:1];
		command_int = &operation[7:5];
	end
endmodule

Вот на этих трёх узлах (включая вычислитель эффективного адреса, описанный выше) сейчас всё держится и работает (прежде всего, отладчик-дизассемблер на System Verilog).

Изменено пользователем Alikberov

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

16 часов назад, xvr сказал:

У автора 'концептуальный' процессор - главное что бы в HEX всё было красиво, работать ему (процессору) не обязательно 🙂

Ну этого уже достаточно, чтобы направить в Сколково на грант по импортозамещению))) Думаю можно на этом еще и бабла нехило срубить,ИМХО...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 час назад, mantech сказал:

Думаю можно на этом еще и бабла нехило срубить,ИМХО...

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вроде бы и отладки не требует такой модуль: И так всё очевидно, понятно…

module	bcd_accumulator
(input	wire		clk		// Clock (positive edge)
,input	wire		bcd_en		// Enable BCD accumulation
,input	wire		bcd_clr		// Clear BCD accumulator
,input	wire	[7:0]	operation	// Operation code (BCD only)
,output	reg	[15:0]	bcd_output	// Full binary summ from BCD
,output	reg		bcd_exist	// Flag of BCD
);
	wire	[3:0]	nibble;

	assign	nibble = &operation[3:0] ? operation[7:4] : operation[3:0];

	always	@(posedge clk)
	begin
		if(bcd_clr)
		begin
			bcd_output <= 16'd0;
			bcd_exist <= 1'd0;
		end else
		if(bcd_en)
		begin
			bcd_output <= (((bcd_output << 2) + bcd_output) << 1) + {12'd0, nibble};
			bcd_exist <= |nibble | bcd_exist;
		end
	end
endmodule

Здесь можно отметить одно важное нововведение: Триггер «bcd_exist»…
Сам аккумулятор вектора его не имеет и при указании смещения 65536 оно, естественно, переполняется и становится нулевым.
Это - опасная недокументированная ситуация, которая может выработать маргинал!

Например:

  • «10» - указатель «[D1+0]»
  • «10 10» - маргинал #1
  • «10 10 10» - маргинальный указатель «1#[D1+0]»
  • «16» - указатель «[D1+6]»
  • «16 15» - указатель «[D1+65]»
  • «16 15 15» - указатель «[D1+655]»
  • «16 15 15 13» - указатель «[D1+6553]»
  • «16 15 15 13 16» - указатель «[D1+0]», так как 65536 уже 17-битная величина 0x10000
  • «16 15 15 13 16 10» - побочный маргинал #1: Это уже из разряда эзотерического кодирования «из ряда вон!» - «маргиналище: маргинальный маргинал!»
  • «16 15 15 13 16 10 11» - маргинальный указатель «1#[D1+1]» (концептуальная недопустимость!)

Теперь флаг «bcd_exist» будет сигнализировать о наличии в смещении самой ненулевой тетрады, что никак не зависит от переполнения: маргинал посреди указателя не сможет образоваться.

Важная модификация: Здесь тетрада «nibble» может использовать как младшие биты кода операции (работает на префиксах и командах REG), так и старшие биты (специально для инструкции FOR/MOV).

  • «AA A1 3F» - команда «MOV A1,A3»
  • «AA A1 A2 3F» - команда «MOV A12,A3»
  • «AA A1 3F 4F» - команда «MOV A1,A34»
  • «AA A1 A2 3F 4F» - команда «MOV A12,A34»
  • «AA A1 A2 A3 A4 A5 6F 7F 8F 9F 0F» - команда «MOV A12345,A67890»

В таких ситуациях, так как MOV - не операция АЛУ и может без вреда исполняться много раз, то принято решение ввести такой механизм. Для чего этот модуль должен сам уметь ориентироваться

Изменено пользователем Alikberov
Важная доработка модуля

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

 

https://github.com/leijurv/Logisim-RISC-V/

может я это уже постил, извиняйте.
но вот есть такое. логисим этот "ис коропкм" у меня не заработал, но что-то типа 15 минут понадобилось.

(может их несколько таких проектов - что то мне кажется, что я у себя пускал похаотичнее гейты были)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

18 часов назад, yes сказал:

https://github.com/leijurv/Logisim-RISC-V/

может я это уже постил, извиняйте.
но вот есть такое. логисим этот "ис коропкм" у меня не заработал, но что-то типа 15 минут понадобилось.

(может их несколько таких проектов - что то мне кажется, что я у себя пускал похаотичнее гейты были)

Это всё понятно, так как тоже в Logisim в 2019 году и сделал рабочий прототип своего процессора.
Сначала Гарвардский, что совсем легко. Потом неделями отлаживал Принстонский, так как пришлось более чётко расписать всё по тактам.

Но, так уж сложилось, что о RISC'ах я ещё узнал из статьи «RISC - Путь в будущее» журнала РАДИО (ссылка).
Однако, как воспитанный на CISC'ах, консервативно занимаюсь именно этим.

К тому же, сам дизайн этого устройства я начинал как шуточную пародию на RISC, типа:

  • А пускай код A1 и выбирает регистр A1 на схеме
  • А пускай код CF инвертирует флаг CF
  • А пускай код BC означает операнды A,B для АЛУ-операций
  • А главное, чтобы код 00 был командой Останова HLT (как Zero-Terminated String)

То есть, каждый код делал только одно незаконченное действие и для выполнения одной эффективной операции требовалось как минимум три команды.

Но, по мере доработок и наработок, развития JavaScript-эмулятора, оказалось, что теперь можно получить вполне серьёзную модель полноценного процессора…
И который год никак не могу его охватить концептуально весь, что не позволяет даже на высоком уровне JavaScript описать эмуляцию на 100%.

Его легко эмулировать на i8080 (ссылка запуска) или z80, что позволит исполнять код даже на ZX-Spectrum.

Кто работает под Linux, может попробовать эмулятор на Bash'е (пока всё ещё не дописал, но отладчик с ассемблером имеется), который писался под Raspberry Pi для управления периферией.

 

BashEmu.zip

Изменено пользователем Alikberov
Перезагрузил файл эмулятора на Bash

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

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

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...