Shaos wrote: 08 Jul 2018 01:56
Троичный счётчик вроде считает - интересный момент, что каждый новый троичный разряд счётчика добавляет только 2 макроячейки, что несколько неожиданно, т.к. я рассчитвал на 4 потому что в каждом разряде у нас по 2 блока MEM
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ternary.all;
entity main is
Port ( clk : in bit;
res : in bit;
a : in FakeTrit;
b : in FakeTrit;
c : in FakeTrit;
s1 : out FakeTrit;
s2 : out FakeTrit;
s3 : out FakeTrit;
led : out bit);
end main;
architecture Behavioral of main is
signal a1,b1,c1,ss0,ss1,ss2,ss3,ss4 : FakeTrit;
signal pclk,pclk1,nclk,nclk1,res0,res1,m1,m2,m3,m4,h1,h2,h3,h4,g1,g2,g3 : FakeTrit;
signal tmp_clk_std, tmp_iclk_std : STD_LOGIC;
signal tmp_clk : BIT;
COMPONENT Clock_Divider
PORT(
clk : IN std_logic;
reset : IN std_logic;
clock_out : OUT std_logic
);
END COMPONENT;
COMPONENT Half_Adder
Port ( a : in FakeTrit;
b : in FakeTrit;
s : out FakeTrit;
c : out FakeTrit
);
END COMPONENT;
FUNCTION io_invert(T: FakeTrit) RETURN FakeTrit IS
begin
case T is
when N =>
return P;
when O =>
return X;
when P =>
return N;
when others =>
return O;
end case;
end;
begin
a1 <= io_invert(a);
b1 <= io_invert(b);
c1 <= io_invert(c);
tmp_iclk_std <= to_stdulogic(clk);
div1: Clock_Divider port map( clk => tmp_iclk_std, reset => '0', clock_out => tmp_clk_std );
tmp_clk <= to_bit(tmp_clk_std);
res0(0) <= '0';
res0(1) <= res;
res1 <= res0;
clk1: ternary_clock port map( B_C => tmp_clk, T_C => ss0 );
mux1: ternary_mux port map( T_S => ss0, T_N => O, T_O => O, T_P => P, T_C => pclk );
mux2: ternary_mux port map( T_S => res1, T_N => pclk, T_O => N, T_P => N, T_C => pclk1 );
mux3: ternary_mux port map( T_S => ss0, T_N => N, T_O => O, T_P => O, T_C => nclk );
mux4: ternary_mux port map( T_S => res1, T_N => nclk, T_O => P, T_P => P, T_C => nclk1 );
mem1: ternary_mem port map( T_S => pclk1, T_N => O, T_P => ss1, T_Q => m1 );
ha1: Half_Adder port map( a => P, b => m1, s => h1, c => g1 );
mem2: ternary_mem port map( T_S => nclk1, T_N => h1, T_P => O, T_Q => ss1 );
mem3: ternary_mem port map( T_S => pclk1, T_N => O, T_P => ss2, T_Q => m2 );
ha2: Half_Adder port map( a => g1, b => m2, s => h2, c => g2 );
mem4: ternary_mem port map( T_S => nclk1, T_N => h2, T_P => O, T_Q => ss2 );
mem5: ternary_mem port map( T_S => pclk1, T_N => O, T_P => ss3, T_Q => m3 );
ha3: Half_Adder port map( a => g2, b => m3, s => h3, c => g3 );
mem6: ternary_mem port map( T_S => nclk1, T_N => h3, T_P => O, T_Q => ss3 );
s1 <= io_invert(ss1);
s2 <= io_invert(ss2);
s3 <= io_invert(ss3);
led <= to_bit(tmp_clk_std);
end Behavioral;
use ternary.all;
entity Half_Adder is
Port ( a : in FakeTrit;
b : in FakeTrit;
s : out FakeTrit;
c : out FakeTrit
);
end Half_Adder;
architecture Behavioral of Half_Adder is
signal r1,r2,r3,r4,r5,r6 : FakeTrit;
begin
process (a,b)
begin
r1 <= mux(a,P,N,O);
r2 <= mux(a,O,P,N);
r3 <= mux(b,r1,a,r2);
r4 <= e12(a,N,O);
r5 <= e21(a,O,P);
r6 <= mux(b,r4,O,r5);
s <= r3;
c <= r6;
end process;
end Behavioral;
NET "clk" LOC = "P38" | IOSTANDARD = LVTTL ;
NET "res" LOC = "P143" | IOSTANDARD = LVTTL ;
NET "a<0>" LOC = "P140" | IOSTANDARD = LVTTL ;
NET "a<1>" LOC = "P142" | IOSTANDARD = LVTTL ;
NET "b<0>" LOC = "P138" | IOSTANDARD = LVTTL ;
NET "b<1>" LOC = "P139" | IOSTANDARD = LVTTL ;
NET "c<0>" LOC = "P136" | IOSTANDARD = LVTTL ;
NET "c<1>" LOC = "P137" | IOSTANDARD = LVTTL ;
NET "s3<0>" LOC = "P82" | IOSTANDARD = LVTTL ;
NET "s3<1>" LOC = "P83" | IOSTANDARD = LVTTL ;
NET "s2<0>" LOC = "P85" | IOSTANDARD = LVTTL ;
NET "s2<1>" LOC = "P86" | IOSTANDARD = LVTTL ;
NET "s1<0>" LOC = "P87" | IOSTANDARD = LVTTL ;
NET "s1<1>" LOC = "P88" | IOSTANDARD = LVTTL ;
NET "led" LOC = "P92" | IOSTANDARD = LVTTL ;
Плюс ещё использовался модуль делителя частоты, что я приводил чуть выше, но в данном случае я делю на 460800, чтобы счётчик считал секунды (тактовая частота при преобразовании в троичную синхру делится на 4).
P.S. На этом этапе VHDL код постепенно начинает превращаться в месиво - думаю пора браться за автоматизацию...
На видео запечетлено, как оно после сброса кнопкой (вход res) считает от OOO (0) до PPP (+13) и далее NNN (-13) и вверх до OOO (0) с периодом в 1 секунду (частоту двоичного такта, которая выше в 4 раза, можно пронаблюдать на бортовом красном светодиодике)
Через почти что 7 лет дошли руки посимулировать это дело в ghdl, который входит в состав пакетов дебияна - правда пришлось поправить кое-что кое-где - приаттачиваю картинку и архив с поправленными исходникми:
Screenshot from 2025-03-17 23-47-41.png
You do not have the required permissions to view the files attached to this post.
Я тут за главного - если что шлите мыло на me собака shaos точка net
use work.ternary.all;
entity main is
port ( a1: out FakeTrit;
a2: out FakeTrit;
a3: out FakeTrit
);
end main;
architecture behaviour of main
is
component test3
Port ( clk : in bit;
res : in bit;
s1 : out FakeTrit;
s2 : out FakeTrit;
s3 : out FakeTrit
);
end component;
constant clk_period : time := 10 ns;
signal iclk : bit := '1';
signal ires : bit := '1';
begin
test: test3 port map( clk => iclk, res => ires, s1 => a1, s2 => a2, s3 => a3 );
-- Clock process definition
clk_process: process
begin
iclk <= '0';
wait for clk_period/2;
iclk <= '1';
wait for clk_period/2;
end process;
end behaviour;
Последовательность команд для запуска через ghdl (тоже есть в архиве):
ghdl -a ternary.vhd
ghdl -a half_adder.vhd
ghdl -a ternary_clock.vhd
ghdl -a test3.vhd
ghdl -a test3a.vhd
ghdl -e main
ghdl -r main --wave=wave.ghw --stop-time=1000ns
gtkwave wave.ghw &
#ghdl -r main --fst=wave.fst --stop-time=1000ns
#ghdl -r main --vcd=wave.vcd --stop-time=1000ns
Надо научиться цеплять объектники генерируемые ghdl в свои программы - чтобы тестбенчи не на VHDL писать, а прямо на сях, как в вериляторе...
P.S. Про ghdl я немножко писал в декабре 2013 года вот тут
P.P.S. Обновил архив выше, а также перезалил поправленное в репу...
Я тут за главного - если что шлите мыло на me собака shaos точка net
Shaos wrote: 17 Mar 2025 23:55
Надо научиться цеплять объектники генерируемые ghdl в свои программы - чтобы тестбенчи не на VHDL писать, а прямо на сях, как в вериляторе...
Начал разбираться - оказывается vpi-интерфейс не только ghdl поддерживает
askfind wrote: 19 Mar 2025 01:28
Переключатели с 3 положениями. Специально покупал для ввода трита.
Ну тогда и светодиоды надо красно-зелёные в одном корпусе
Эхо конференции
Бурцев Алексей Анатольевич, доклад «Опыт создания и развития ДССП для троичной машины»
Докладчик рассказал, что у «Сетунь-70» лампочки на панели были сделаны с цветной кодировкой: « Знаете! Когда запускали тесты для машины панель машины светилась как гирлянда. Красная лампа - это «+1», синий цвет или зелёный - это «-1», а 0 - лампочка погашена. Был шуршащий шум от считывания перфоленты».
.
Vladimir V., [08.02.2025 16:31]
Подготовка к Лабораторной работе №2
Индикация трита.
В троичной цифровой машине "СЕТУНЬ" использовались две неоновые лампочки одного цвета.
Для индикации трита
Эмуляция троичных цифровых элементов "СЕТУНЬ". Троичных счётчик и отображение
Цвета трита:
- Красный RED '+1'
- светодиоды погашены "0"
- Синий BLUE '-1'
Vladimir V., [08.02.2025 16:32]
Угадал в своём макете отображение тритов. Сделал как «отцы основатели» троичности…
Рассматривая солнечный спект, красный и синий цвета максимально разнесены друг от друга на шкале длины волн спектра.
Как запомнить? Красный: Солнце, горячий. Вверху. "+1" Синий: Море, холодный. Внизу. "-1"
"Ученье свет, а неученье — тьма. Дело мастера боится, и коль крестьянин не умеет сохою владеть — хлеб не родится." (С)
А мы в своё время решили как в биржевых котировках сделать - зелёный это положительный тренд, а красный - отрицательный…
По поводу четвёртого состояния:
Shaos wrote: 09 Apr 2009 13:32
Внутри троичный сигнал будет состоять из двух двоичных:
00 - O (zero)
10 - N (negative)
01 - P (positive)
11 - X (exception or fatal error)
Тут я вдруг осознал, что 11 нельзя использовать в качестве маркера ошибки прям везде т.к. в реальном FPGA по ходу движения сигналов могут быть (будут) гонки и в каких-то переходных ситуациях может так оказаться, что на обоих сигналах временно будет присутствовать 1 (на одном он скажем переключается в 0, а на другом только что переключился из 0 в 1) - поэтому если и проверять на валидность таким образом, то только после защёлок (в моём случае ТОЛЬКО после троичного блока MEM)...
Я тут за главного - если что шлите мыло на me собака shaos точка net
Shaos wrote: 17 Mar 2025 23:55
Надо научиться цеплять объектники генерируемые ghdl в свои программы - чтобы тестбенчи не на VHDL писать, а прямо на сях, как в вериляторе...
Начал разбираться - оказывается vpi-интерфейс не только ghdl поддерживает