Кое-что бесит.

May 20, 2018 13:57

Дожив до седых волос, сделав множество работоспособных и ещё больше неработоспособных электронных штук, понял, что в моих познаниях есть некий пробел, заполненный ненадёжным туманом очень общих слов: я не знаю, как на самом деле работают микропроцессоры. Т.е. я умею ими пользоваться, я понимаю различия между архитектурами и семействами, я знаю, для чего нужно АЛУ, кэш и т.п., но я не имею ни малейшего представления о том, как оно на самом деле всё устроено. Т.е. я понимаю, что на функциональных схемах обозначают эти квадратики, но вот что у них внутри - ?..

И это беспокойное сомнение свербит мне мозг.

Полез читать и разбираться.

Начал с динозавра (стадию релейных рыб и ламповых земноводных решил пропустить) - АЛУ 74181, достославный чип, подливший бензина в пламя компьютерной революции. Почитал даташиты, заказал (ещё не получил) КМОП-версию для экспериментов. Чтобы было что пощупать, пока микросхемы в пути, написал VHDL-модель, буквально передрав схему из документации:

----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity alu74181 is
Port ( m : in STD_LOGIC;
cn : in STD_LOGIC;
s : in STD_LOGIC_VECTOR (3 downto 0);
neg_a : in STD_LOGIC_VECTOR (3 downto 0);
neg_b : in STD_LOGIC_VECTOR (3 downto 0);
neg_g : out STD_LOGIC;
neg_p : out STD_LOGIC;
Cn4 : out STD_LOGIC;
neg_f : out STD_LOGIC_VECTOR (3 downto 0);
pb,gb : out STD_LOGIC_VECTOR (3 downto 0);
a_eq_b : out STD_LOGIC);
end alu74181;

architecture Behavioral of alu74181 is
signal g, -- GENERATE
p, -- PROPAGATE
f : std_logic_vector (3 downto 0);
signal a,b: std_logic_vector (3 downto 0);
signal nm, temp_ng, temp_cn4, temp_p : std_logic;
begin
a <= neg_a;
b <= neg_b;
nm <= not m;

g(3) <= not ( (b(3) and s(3) and a(3)) or (a(3) and s(2) and (not b(3))) ); -- Generate
g(2) <= not ( (b(2) and s(3) and a(2)) or (a(2) and s(2) and (not b(2))) ); -- Generate
g(1) <= not ( (b(1) and s(3) and a(1)) or (a(1) and s(2) and (not b(1))) ); -- Generate
g(0) <= not ( (b(0) and s(3) and a(0)) or (a(0) and s(2) and (not b(0))) ); -- Generate

p(3) <= not ( (not b(3) and s(1) ) or (s(0) and b(3)) or a(3)); -- Propagate
p(2) <= not ( (not b(2) and s(1) ) or (s(0) and b(2)) or a(2)); -- Propagate
p(1) <= not ( (not b(1) and s(1) ) or (s(0) and b(1)) or a(1)); -- Propagate
p(0) <= not ( (not b(0) and s(1) ) or (s(0) and b(0)) or a(0)); -- Propagate

pb <= p;
gb <= g;

temp_p <= (g(3) and g(2) and g(1) and g(0));
neg_p <= not temp_p;
temp_ng <= not (
p(3) or
(g(3) and p(2)) or
(g(3) and g(2) and p(1)) or
(g(3) and g(2) and g(1) and p(0))
);
neg_g <= temp_ng;
temp_cn4 <= not (temp_p and cn);
cn4 <= (not temp_cn4) or (not temp_ng);

f(3) <= (g(3) and (not p(3))) xor
(not (
(g(2) and g(1) and g(0) and cn and nm) or
(g(2) and g(1) and p(0) and nm) or
(g(2) and p(1) and nm) or
(p(2) and nm)
)
);

f(2) <= (g(2) and (not p(2))) xor
(not (
(g(1) and g(0) and cn and nm) or
(g(1) and p(0) and nm) or
(p(1) and nm)
)
);

f(1) <= (g(1) and (not p(1))) xor
(not (
(g(0) and cn and nm) or
(p(0) and nm)
)
);

f(0) <= (g(0) and (not p(0))) xor
(not (cn and nm));

neg_f <= f;
a_eq_b <= (f(3) and f(2) and f(1) and f(0));

end Behavioral;
----------------------------------------------------------------------------------

Написал тестбенч для некоторых функций (всё решил не проверять, ибо не могу придумать никакого практического применения выражениям типа (A + /B) plus AB). И эта штука в самом деле умеет складывать, вычитать, сравнивать... поразительно. Т.е. вроде ничего странного - но всё равно удивляет.

Набросал так же модель 4-битного компаратора 7585 (и сделал из неё 32-битную версию) и каскадного быстрого сумматора вообще на отдельных вентилях. Всё работает: битики сравнения выставляются, сумма-разность вычисляется. Фантастика!

Почитал ещё, как в самом деле устроена кэш-память. Модель ещё не делал, т.к. пока не всё ясно.

Параллельно читаю про RISC-V.
Почитал, что-как народ делает.
Посмотрел картинки самопальных компьютеров, в т.ч. смелую попытку собрать RISC-V на рассыпухе (чувак зашёл очень бодро - но закончил примерно там же, где и начал).
Понял, что все они дураки, а я один умный и весь в белом - думаю, а не попробовать ли и мне? Ведь нет лучшего способа для того, чтобы в чём-то разобраться, чем сделать это самому. Причём не на ПЛИС. Во всяком случае, не на высокоуровневом HDL, прячущем все детали реализации под кодом - это было бы удобно, но всё равно непонятно: к примеру, тот же АЛУ, будучи написанным как блок switch/case, остаётся всё таким же таинственным квадратиком.

Уже понятно, что чудовище будет огромное (сотни микросхем), медленное (вряд ли тактовую частоту получится поднять выше 5 МГц) и дорогое: один лишь только блок регистров (только детальки к нему!) обойдётся рублей эдак тыщи в три-четыре. А это ведь только часть. Хоть и весьма значительная, но не единственная. Потребуется много-много мультиплексоров и дешифраторов, отдельных вентилей и триггеров, компараторов, сумматоров и т.п., и т.д. Плюс всякая экзотика и эзотерика, снятая с производства - и если АЛУ ещё можно легко повторить на отдельных вентилях (и получится даже лучше, чем оригинал), то content-addressable memory повторить хоть и в принципе возможно, но лучше всё-таки найти чипы, оставшиеся от золотой эпохи цифровой электроники.

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

мысли, археология, worklog

Previous post Next post
Up