Эмулятор троичного процессора

Эмулятор троичного процессора

Сообщение nezabudka » 23 янв 2017, 19:58

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

Возможно полностью с нуля, самим написать даже спецификацию
трайта. Например у меня в набросках трайт имеет не сбалансированную
как в сетунь систему и состоит из 4 тритов, а трит эмулируется
двух битовым полем в структуре.
0 == 00
1 == 01
2 == 10
3 == 11 //остается неисользованным.

0 == 0000
1 == 0001
2 == 0002
3 == 0010
4 == 0011
5 == 0012 и т.д.
Для хоста размер структуры трайта будет ровнятся 1 байту. А максимально
доступная память для самого эмулятора при этом получится 3**4 + 1 = 82 адресса.
Для начала хватит а в дальнейшем если будет интерес можно расширить
до 2 трайтов тоесть до 8 тритов. И тем самым мы как бы инкапсулируем
бит. С таким прогрессивным порядком системная шина и регистры очень хорошо
будут масштабироваться.

Вот пример простой структуры с возможным сумматором.
Повторюсь это всего лишь наброски так сказать вектор
движения.
[spoiler]
Код: выделить все
#include <stdio.h>
#include <errno.h>
#include <stdint.h>
#include <string.h>
#include <stdlib.h>

/* определим структуру минимального блока памяти
 * с которым оперирует этот процессор размером в  1 байт == 1 трайт
 * один бит не используется, единица адресации 1 трайт.
 * спецификацию напишу позже; */

typedef struct tryte_t {
   uint8_t one:2, two:2, three:2, four:2;
} Tryte_t;

Tryte_t summ(Tryte_t, Tryte_t, Tryte_t *);

int main(int argc, char *argv[]) {
//   Tryte_t *mem;
   Tryte_t r0 = {2, 2, 2, 2};
   Tryte_t r1 = {2, 2, 2, 2};
   Tryte_t rf = {0, 0, 0, 0}; // регистр флагов

   r0 = summ(r0, r1, &rf);
   printf("%d%d%d%d\n", r0.four, r0.three, r0.two, r0.one);
   printf("%d\n", rf.one);

   // выделяем доступную память примерно 13Кб;
   // нет пока разделения между секциями;
//   mem = (Tryte *)malloc(sizeof(Tryte) + 1);
   // определяем регистры;
//   Tryte r0;
//   Tryte r1;
//   Tryte r2;
   // загружаем двоичную программу в память.
//   FILE *prog;
//   prog = fopen(argv[1], "r");
//   if(!prog) {
//      perror("can't open programm file");
//      return(1);
//   }
//   fwrite(&mem, sizeof(mem), 1, prog);
//   printf("%d %d %d %d\n", mem.one, mem.two, mem.three, mem.four);
   return 0;
}


Tryte_t summ(Tryte_t reg0, Tryte_t reg1, Tryte_t *flag) { //сумматор двух регистров
   int sum = reg0.one + reg1.one;
   switch(sum) {
      case 4:
         reg0.one = 1;
         sum = 1;
         break;
      case 3:
         reg0.one = 0;
         sum = 1;
         break;
      case 2:
         reg0.one = 2;
         sum = 0;
         break;
      case 1:
         reg0.one = 1;
         sum = 0;
         break;
      case 0:
         reg0.one = 0;
         sum = 0;
         break;
      default:
         perror("kernel_panic");
         exit(EXIT_FAILURE);
   }
   sum += (reg0.two + reg1.two);
   switch(sum) {
      case 5:
         reg0.two = 2;
         sum = 1;
         break;
      case 4:
         reg0.two = 1;
         sum = 1;
         break;
      case 3:
         reg0.two = 0;
         sum = 1;
         break;
      case 2:
         reg0.two = 2;
         sum = 0;
         break;
      case 1:
         reg0.two = 1;
         sum = 0;
         break;
      case 0:
         reg0.two = 0;
         sum = 0;
         break;
      default:
         perror("kernel_panic");
         exit(EXIT_FAILURE);
   }
   sum += (reg0.three + reg1.three);
   switch(sum) {
      case 5:
         reg0.three = 2;
         sum = 1;
         break;
      case 4:
         reg0.three = 1;
         sum = 1;
         break;
      case 3:
         reg0.three = 0;
         sum = 1;
         break;
      case 2:
         reg0.three = 2;
         sum = 0;
         break;
      case 1:
         reg0.three = 1;
         sum = 0;
         break;
      case 0:
         reg0.three = 0;
         sum = 0;
         break;
      default:
         perror("kernel_panic");
         exit(EXIT_FAILURE);
   }
   sum += (reg0.four + reg1.four);
   switch(sum) {
      case 5:
         reg0.four = 2;
         sum = 1;
         break;
      case 4:
         reg0.four = 1;
         sum = 1;
         break;
      case 3:
         reg0.four = 0;
         sum = 1;
         break;
      case 2:
         reg0.four = 2;
         sum = 0;
         break;
      case 1:
         reg0.four = 1;
         sum = 0;
         break;
      case 0:
         reg0.four = 0;
         sum = 0;
         break;
      default:
         perror("kernel_panic");
         exit(EXIT_FAILURE);
   }
//   printf("%d%d%d%d\n", reg0.four, reg0.three, reg0.two, reg0.one);
   if(sum == 1) {
      flag->one = sum;
      reg0.one = reg0.two;
      reg0.two = reg0.three;
      reg0.three = reg0.four;
      reg0.four = sum;
   }
   return reg0;
}
[/spoiler]
https://github.com/olecya/trinc_4003
Например есть идея эмулировать системную шину с помощью
omp дирректив и пустить каждое поле по параллельной нити.
Даже если хостовый процессор поддерживает один поток,
будут все равно задействованы 4 псевдо потока и в финале
пришедший первый будет ждать окончания других нитей
все равно как пайп.

Можно написать транслятор программы из консоли линукс,
а можно будет запускать программу уже из двоичного файла
с отдельным от эмулятора кросскомпилятором.
Здесь получается большая свобода для мысли и маневров.
Предлагаю, если и не присоединится то хотябы принять участие
в обсуждении. Это всего лишь мысли вслух которые могут развеяться
за неимением интереса так же быстро как и возникли.
"I invented the term Object-Oriented and I can tell you I did not have C++ in mind." - Alan Kay
Аватар пользователя
nezabudka
Местный говорун
Местный говорун
 
Автор темы
Сообщений: 613
Фото: 180
Стаж: 3 года 5 месяцев 6 дней
Откуда: Ростов на Дону
Благодарил (а): 286 раз.
Поблагодарили: 145 раз.

Эмулятор троичного процессора

Спонсор

Спонсор
 

Re: Эмулятор троичного процессора

Сообщение Olej » 23 янв 2017, 22:16

nezabudka писал(а):

Недавно познакомилась поверхностно с некоторыми статьями
по работе с троичным компьютером сетунь.

Это было ... давно.
И вряд ли будет иметь какое-то осмысленное продолжение.
Но было и очень много любопытных вещей и проектов...

истории отечественных IT

Изображение
Это вот на картинке образец тех систем, которые своими потребностями двигали вперёд развитие IT
(Это загоризонтная РЛС под Чернобылем, система класса "Днепр", за рубежом известная как "Русский Дятел", потому что на определённых частотах КВ радиодиапазона её работа слышалась как стук. 2-я и последняя в природе из таких систем была в Николаеве ... но "нэзалэжные" её разобрали и сдали на металлолом в первейшие годы нэзалежности, сейчас и следа не осталось на месте где такое чудо стояло.
На сегодня такие конструкции смотрятся как из "Сталкер" Стругацких - артефакты неизвестной ушедшей цивилизации, которые невозможно ни осмыслить их предназначение, ни создать что-то подобное.)
Olej
 
Стаж: 48 лет 8 месяцев 23 дня

Re: Эмулятор троичного процессора

Сообщение nezabudka » 31 янв 2017, 19:39

Добавила еще 3 функции - меньше, равно и вычитание. В функции вычетания задействованна функция "меньше"
sed '175,$!d' cpu.c
[spoiler]
Код: выделить все
unsigned short less(Tryte_t dig0, Tryte_t dig1) { // <
        if(dig0.three < dig1.three)
                return 1;
        else if(dig0.three == dig1.three) {
                if(dig0.two < dig1.two)
                        return 1;
                else if(dig0.two == dig1.two) {
                        if(dig0.one < dig1.one)
                                return 1;
                        else if(dig0.one == dig1.one) {
                                if(dig0.ou < dig1.ou)
                                        return 1;
                        }
                }
        }
        return 0;
}

unsigned short equal(Tryte_t dig0, Tryte_t dig1) { // ==
        if(dig0.ou == dig1.ou && dig0.one == dig1.one && dig0.two == dig1.two && dig0.three == dig1.three)
                return 1;
        else
                return 0;
}


Tryte_t sub(Tryte_t reg0, Tryte_t reg1) { // -
        unsigned short sub = 0;
        if(less(reg0, reg1)) {
                Tryte_t temp;
                memcpy(&temp, &reg0, 1);
                memcpy(&reg0, &reg1, 1);
                memcpy(&reg1, &temp, 1);
                rf.one = 1;
        } else 
                rf.one = 0;
        if(reg0.ou < reg1.ou) {
                sub = 3;
                reg1.one += 1;
        }
        reg0.ou = reg0.ou + sub - reg1.ou;
        sub = 0;

        if(reg0.one < reg1.one) {
                sub = 3;
                reg1.two += 1;
        }
        reg0.one = reg0.one + sub - reg1.one;
        sub = 0;

        if(reg0.two < reg1.two) {
                sub = 3;
                reg1.three += 1;
        }
        reg0.two = reg0.two + sub - reg1.two;
        sub = 0;

        reg0.three = reg0.three - reg1.three;
        return reg0;
}
[/spoiler]
"I invented the term Object-Oriented and I can tell you I did not have C++ in mind." - Alan Kay
Аватар пользователя
nezabudka
Местный говорун
Местный говорун
 
Автор темы
Сообщений: 613
Фото: 180
Стаж: 3 года 5 месяцев 6 дней
Откуда: Ростов на Дону
Благодарил (а): 286 раз.
Поблагодарили: 145 раз.


Вернуться в C/C++

Кто сейчас на форуме

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 0

cron