Forth и другие саморасширяющиеся системы программирования Locations of visitors to this page
Текущее время: Пт апр 19, 2024 03:10

...
Google Search
Forth-FAQ Spy Grafic

Часовой пояс: UTC + 3 часа [ Летнее время ]




Начать новую тему Ответить на тему  [ Сообщений: 137 ]  На страницу Пред.  1, 2, 3, 4, 5 ... 10  След.
Автор Сообщение
 Заголовок сообщения: Re: VHDL: процессор за час
СообщениеДобавлено: Пт фев 04, 2011 20:00 
Не в сети
Administrator
Administrator
Аватара пользователя

Зарегистрирован: Вт май 02, 2006 13:19
Сообщения: 3565
Откуда: St.Petersburg
Благодарил (а): 4 раз.
Поблагодарили: 72 раз.
После исправления компилируется четырехкомандный процессор ;))

179 LCELLs, 160 тригеров, частота 227MHz на втором циклоне,

_________________
С уважением, WingLion
Forth-CPU . RuF09WE
Мой Форт
Отсутствие бана это не заслуга юзера, а недоработка модератора (с)


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения: Re: VHDL: процессор за час
СообщениеДобавлено: Пт фев 04, 2011 20:06 
Не в сети
Administrator
Administrator
Аватара пользователя

Зарегистрирован: Вт май 02, 2006 13:19
Сообщения: 3565
Откуда: St.Petersburg
Благодарил (а): 4 раз.
Поблагодарили: 72 раз.
Надо по идее, еще и симулировать его...

Поэтому кодирование функции отложу и займусь симуляцей.


А пока последние версии исходникoв:

Главный файл CPU2011.vhd:
Код:
LIBRARY IEEE;
USE IEEE.std_logic_1164.all;
USE IEEE.std_logic_unsigned.all;
USE WORK.CPUpack.all;

entity CPU2011 is

   Port(
      clk : in std_logic;
      reset : in std_logic;
      addr : out word;
      iData : in word;
      oData : out word
   );
END CPU2011;
   
architecture rtl of CPU2011 is
   signal new_CPU,CPU : CPU_t;
begin

   new_CPU <= Logic_kernel(CPU,iData);

   process (reset,clk) begin
      if reset = '0' then
         CPU.pc <= (others =>'0');
         CPU.cmd <= (others =>'0');
      elsif clk'event and clk='1' then
         CPU <= new_CPU;
      end if;
      
   Addr <= Logic_kernel(CPU,iData).addr;
   oData <= Logic_kernel(CPU,iData).oData;

   end process;

end;


36 строк весь процессор! ;)

Пакет для него CPUpack.vhd:

Код:
LIBRARY IEEE;
USE IEEE.std_logic_1164.all;
USE IEEE.std_logic_unsigned.all;


package CPUpack is

constant width : natural :=16;
constant depth : natural :=8;

   subtype word is std_logic_vector (width-1 downto 0);
   
   type stk is array (depth-3 downto 0) of word;
   
   type stack_t is record
      top    : word;
      subtop    : word;
      regs    : stk;
   end record;
   
   type mem_t is (Mread,Mwrite,Mnop);
   
   type cpu_t is record
      cmd : word;
      pc   : word;
      data_stack : stack_t;
      return_stack : stack_t;
      addr : word;
      oData : word;
      mem : mem_t;
   end record;


constant zero : word := (others => '0');
constant nop : std_logic_vector (3 downto 0)   := "0000";
constant lit : std_logic_vector (3 downto 0)   := "0001";
constant call : std_logic_vector (3 downto 0)   := "0010";
constant ret : std_logic_vector (3 downto 0)   := "0011";

   function PUSH2STACK(stack : stack_t;data : word) return stack_t;
   function POP4STACK(stack :stack_t) return stack_t;
   
   function logic_kernel(CPU : cpu_t; data : word) return cpu_t;
   

end;

package body CPUpack is

   function PUSH2STACK(stack : stack_t; data: word) return stack_t is
      variable new_stack : stack_t;
   begin
      new_stack.top := data;
      new_stack.subtop := stack.top;
      new_stack.regs(depth-3) := stack.subtop;
      for i in depth-4 downto 0 loop
         new_stack.regs(i) := stack.regs(i+1);
      end loop;
      return new_stack;
   end;
   
   function POP4STACK(stack : stack_t) return stack_t is
      variable new_stack : stack_t;
   begin
      new_stack.top := stack.subtop;
      new_stack.subtop := stack.regs(depth-3);
      for i in depth-3 downto 1 loop
         new_stack.regs(i) := stack.regs(i-1);
      end loop;
      new_stack.regs(0) := zero;
   
      return new_stack;
   end;
   

function logic_kernel(CPU : cpu_t; data : word) return cpu_t is
   variable new_CPU : cpu_t;
   variable sh_cmd : word;
begin
      new_CPU :=CPU;
      sh_cmd := CPU.cmd(width-5 downto 0)&nop;
      -- по умолчанию регистр команды сдвигается на четыре бита
      new_CPU.cmd := sh_cmd;
      -- по умолчанию на адрес подается содержимое PC
      new_CPU.addr := CPU.pc;

      case CPU.cmd(width-1 downto width-4) is
         when nop =>
            new_CPU.pc := CPU.pc+1;
            new_CPU.cmd := Data;
         when lit =>
            -- счетчик команды увеличивается на единицу
            new_CPU.pc := CPU.pc+1;
            -- считанный литерал заталкиваем в стек данных
            new_CPU.data_stack := PUSH2STACK(CPU.data_stack,Data);
         when call =>
            -- загружаем новое значение для PC
            new_CPU.pc := Data;
            -- старое заталкиваем в стек возвратов
            new_CPU.return_stack := PUSH2STACK(CPU.return_stack,CPU.pc+1);
         when ret =>
            -- возвращаем адрес
            new_CPU.pc := CPU.return_stack.top;
            -- и выталкиваем его из стека возвратов
            new_CPU.return_stack := POP4STACK(CPU.return_stack);

            
         when others => null;
         
      end case;

      
      
   return new_CPU;
end;

end;

_________________
С уважением, WingLion
Forth-CPU . RuF09WE
Мой Форт
Отсутствие бана это не заслуга юзера, а недоработка модератора (с)


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения: Re: VHDL: процессор за час
СообщениеДобавлено: Пт фев 04, 2011 20:39 
Не в сети
Administrator
Administrator
Аватара пользователя

Зарегистрирован: Вт май 02, 2006 13:19
Сообщения: 3565
Откуда: St.Petersburg
Благодарил (а): 4 раз.
Поблагодарили: 72 раз.
Симуляция прошла успешно для команд
NOP,LIT,CALL и RET

можно кодить дальше.

На очереди команды ?branch, @, !, NEXT

_________________
С уважением, WingLion
Forth-CPU . RuF09WE
Мой Форт
Отсутствие бана это не заслуга юзера, а недоработка модератора (с)


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения: Re: VHDL: процессор за час
СообщениеДобавлено: Пт фев 04, 2011 21:15 
Не в сети

Зарегистрирован: Вт май 09, 2006 12:31
Сообщения: 3438
Благодарил (а): 5 раз.
Поблагодарили: 16 раз.
Раньше компилятор 7 лет делали (фортран) теперь процессор за час. Интересно, если дальше такими темпами, что будет получаться за день через 100 лет? Фирма IBM в оперативной памяти с симуляцией персонала? :( :(


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения: Re: VHDL: процессор за час
СообщениеДобавлено: Пт фев 04, 2011 21:26 
Не в сети
Administrator
Administrator
Аватара пользователя

Зарегистрирован: Вт май 02, 2006 13:19
Сообщения: 3565
Откуда: St.Petersburg
Благодарил (а): 4 раз.
Поблагодарили: 72 раз.
А почему так грустно? Радоваться этому надо! ;)

прогресс шагает семимильными шагами.
Вон, уже и чипы пошли с 256 гигабитами внутре.

_________________
С уважением, WingLion
Forth-CPU . RuF09WE
Мой Форт
Отсутствие бана это не заслуга юзера, а недоработка модератора (с)


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения: Re: VHDL: процессор за час
СообщениеДобавлено: Пт фев 04, 2011 21:40 
Не в сети
Administrator
Administrator
Аватара пользователя

Зарегистрирован: Вт май 02, 2006 13:19
Сообщения: 3565
Откуда: St.Petersburg
Благодарил (а): 4 раз.
Поблагодарили: 72 раз.
последний вариант главной функции ядра:

Код:
function logic_kernel(CPU : cpu_t; data : word) return cpu_t is
   variable new_CPU : cpu_t;
   variable sh_cmd : word;
begin
      new_CPU :=CPU;
      sh_cmd := CPU.cmd(width-5 downto 0)&nop;
      -- по умолчанию регистр команды сдвигается на четыре бита
      new_CPU.cmd := sh_cmd;
      -- по умолчанию на адрес подается содержимое PC
      new_CPU.addr := CPU.pc;
      -- по умолчанию команда памяти - nop!
      new_CPU.mem := Mnop;
      
      new_CPU.oData := CPU.data_stack.top;

      case CPU.cmd(width-1 downto width-4) is
         when nop =>
            new_CPU.pc := CPU.pc+1;
            new_CPU.cmd := Data;
            new_CPU.mem := Mread;
         when lit =>
            -- счетчик команды увеличивается на единицу
            new_CPU.pc := CPU.pc+1;
            -- считанный литерал заталкиваем в стек данных
            new_CPU.data_stack := PUSH2STACK(CPU.data_stack,Data);
            new_CPU.mem := Mread;
         when call =>
            -- загружаем новое значение для PC
            new_CPU.pc := Data;
            -- старое заталкиваем в стек возвратов
            new_CPU.return_stack := PUSH2STACK(CPU.return_stack,CPU.pc+1);
            new_CPU.mem := Mread;
         when ret =>
            -- возвращаем адрес
            new_CPU.pc := CPU.return_stack.top;
            -- и выталкиваем его из стека возвратов
            new_CPU.return_stack := POP4STACK(CPU.return_stack);
         when branch =>
            new_CPU.mem := Mread;
            -- а вот и if!
            if  not (CPU.data_stack.top = 0) then
               new_CPU.pc := Data; -- если на стеке не ноль - перейти
            else
               new_CPU.pc := CPU.pc+1; -- если ноль следущая команда
            end if;
            -- а команда в четверке за if-ом будет исполняться в любом случае
            -- и она должна зануляться принудительно, если не нужно что-то сделать типа DROP
         when razim =>
            -- адрес со стека подать на шину адреса
            new_CPU.Addr := CPU.data_stack.top;
            -- результат считать в стек данных
            new_CPU.data_stack.top := Data;
            new_CPU.mem := Mread;
         when prisv => null;
            -- на адрес подать вершину стека данных
            new_CPU.Addr := CPU.data_stack.top;
            -- на данные подвершину
            new_CPU.oData := CPU.data_stack.subtop;
            -- и надо бы подать команду памяти на запись
            new_CPU.mem := Mwrite;
            -- а заодно и в иных местах определить, что делать памяти
         when c_next => null;
            -- на адрес подается вершина стека возвратов
            new_CPU.addr := CPU.return_stack.top;
            -- сама вершина модифицируется на следущщий адрес
            new_CPU.return_stack.top := CPU.return_stack.top+1;
            -- а считанное данное помещяется в PC
            new_CPU.pc := Data;
            -- память, ясное дело, читается
            new_CPU.mem := Mread;

         when others => null;
         
      end case;

   return new_CPU;
end;

_________________
С уважением, WingLion
Forth-CPU . RuF09WE
Мой Форт
Отсутствие бана это не заслуга юзера, а недоработка модератора (с)


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения: Re: VHDL: процессор за час
СообщениеДобавлено: Пт фев 04, 2011 21:42 
Не в сети
Administrator
Administrator
Аватара пользователя

Зарегистрирован: Вт май 02, 2006 13:19
Сообщения: 3565
Откуда: St.Petersburg
Благодарил (а): 4 раз.
Поблагодарили: 72 раз.
осталось 8 команд на арифметико-логические функции и манипуляции со стеками:

DUP,DROP,SWAP,R>,>R,ADD, NAND,2/

_________________
С уважением, WingLion
Forth-CPU . RuF09WE
Мой Форт
Отсутствие бана это не заслуга юзера, а недоработка модератора (с)


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения: Re: VHDL: процессор за час
СообщениеДобавлено: Пт фев 04, 2011 22:48 
Не в сети
Administrator
Administrator
Аватара пользователя

Зарегистрирован: Вт май 02, 2006 13:19
Сообщения: 3565
Откуда: St.Petersburg
Благодарил (а): 4 раз.
Поблагодарили: 72 раз.
Собственно, вот и результат.

16 команд работают в симуляторе, процессор занимает ~750 ячеек и в циклоне-2 показывает частоту 178MHz

последняя версия, проверенная в симуляторе:

файл CPUpack.vhd
Код:
LIBRARY IEEE;
USE IEEE.std_logic_1164.all;
USE IEEE.std_logic_unsigned.all;


package CPUpack is

constant width : natural :=16;
constant depth : natural :=8;

   subtype word is std_logic_vector (width-1 downto 0);
   
   type stk is array (depth-3 downto 0) of word;
   
   type stack_t is record
      top    : word;
      subtop    : word;
      regs    : stk;
   end record;
   
   type mem_t is (Mread,Mwrite,Mnop);
   
   type cpu_t is record
      cmd : word;
      pc   : word;
      data_stack : stack_t;
      return_stack : stack_t;
      addr : word;
      oData : word;
      mem : mem_t;
   end record;


constant zero : word := (others => '0');
-- тут фактически назначаются коды системы команд
constant nop    : std_logic_vector (3 downto 0)   := "0000";
constant lit    : std_logic_vector (3 downto 0)   := "0001";
constant call    : std_logic_vector (3 downto 0)   := "0010";
constant ret    : std_logic_vector (3 downto 0)   := "0011";
constant branch : std_logic_vector (3 downto 0)   := "0100";
constant razim    : std_logic_vector (3 downto 0)   := "0101";
constant prisv    : std_logic_vector (3 downto 0)   := "0110";
constant c_next : std_logic_vector (3 downto 0)   := "0111";

constant dup    : std_logic_vector (3 downto 0)   := "1000";
constant drop    : std_logic_vector (3 downto 0)   := "1001";
constant swap    : std_logic_vector (3 downto 0)   := "1010";
constant toR    : std_logic_vector (3 downto 0)   := "1011";
constant fromR   : std_logic_vector (3 downto 0)   := "1100";
constant c_add   : std_logic_vector (3 downto 0)   := "1101";
constant c_nand   : std_logic_vector (3 downto 0)   := "1110";
constant c2div   : std_logic_vector (3 downto 0)   := "1111";

-- NOP,LIT,CALL,RET,?BRANCH,@,!,NEXT,DUP,DROP,SWAP,R>,>R,ADD, NAND,2/




   function PUSH2STACK(stack : stack_t;data : word) return stack_t;
   function POP4STACK(stack :stack_t) return stack_t;
   
   function logic_kernel(CPU : cpu_t; data : word) return cpu_t;
   

end;

package body CPUpack is

   function PUSH2STACK(stack : stack_t; data: word) return stack_t is
      variable new_stack : stack_t;
   begin
      new_stack.top := data;
      new_stack.subtop := stack.top;
      new_stack.regs(depth-3) := stack.subtop;
      for i in depth-4 downto 0 loop
         new_stack.regs(i) := stack.regs(i+1);
      end loop;
      return new_stack;
   end;
   
   function POP4STACK(stack : stack_t) return stack_t is
      variable new_stack : stack_t;
   begin
      new_stack.top := stack.subtop;
      new_stack.subtop := stack.regs(depth-3);
      for i in depth-3 downto 1 loop
         new_stack.regs(i) := stack.regs(i-1);
      end loop;
      new_stack.regs(0) := zero;
   
      return new_stack;
   end;
   

function logic_kernel(CPU : cpu_t; data : word) return cpu_t is
   variable new_CPU : cpu_t;
   variable sh_cmd : word;
   variable tmp : word;
begin
      new_CPU :=CPU;
      sh_cmd := CPU.cmd(width-5 downto 0)&nop;
      -- по умолчанию регистр команды сдвигается на четыре бита
      new_CPU.cmd := sh_cmd;
      -- по умолчанию на адрес подается содержимое PC
      new_CPU.addr := CPU.pc;
      -- по умолчанию команда памяти - nop!
      new_CPU.mem := Mnop;
      
      new_CPU.oData := CPU.data_stack.top;

      case CPU.cmd(width-1 downto width-4) is
         when nop =>
            new_CPU.pc := CPU.pc+1;
            new_CPU.cmd := Data;
            new_CPU.mem := Mread;
         when lit =>
            -- счетчик команды увеличивается на единицу
            new_CPU.pc := CPU.pc+1;
            -- считанный литерал заталкиваем в стек данных
            new_CPU.data_stack := PUSH2STACK(CPU.data_stack,Data);
            new_CPU.mem := Mread;
         when call =>
            -- загружаем новое значение для PC
            new_CPU.pc := Data;
            -- старое заталкиваем в стек возвратов
            new_CPU.return_stack := PUSH2STACK(CPU.return_stack,CPU.pc+1);
            new_CPU.mem := Mread;
         when ret =>
            -- возвращаем адрес
            new_CPU.pc := CPU.return_stack.top;
            -- и выталкиваем его из стека возвратов
            new_CPU.return_stack := POP4STACK(CPU.return_stack);
         when branch =>
            new_CPU.mem := Mread;
            -- а вот и if!
            if  not (CPU.data_stack.top = 0) then
               new_CPU.pc := Data; -- если на стеке не ноль - перейти
            else
               new_CPU.pc := CPU.pc+1; -- если ноль следущая команда
            end if;
            -- а команда в четверке за if-ом будет исполняться в любом случае
            -- и она должна зануляться принудительно, если не нужно что-то сделать типа DROP
         when razim =>
            -- адрес со стека подать на шину адреса
            new_CPU.Addr := CPU.data_stack.top;
            -- результат считать в стек данных
            new_CPU.data_stack.top := Data;
            new_CPU.mem := Mread;
         when prisv => null;
            -- на адрес подать вершину стека данных
            new_CPU.Addr := CPU.data_stack.top;
            -- на данные подвершину
            new_CPU.oData := CPU.data_stack.subtop;
            -- и надо бы подать команду памяти на запись
            new_CPU.mem := Mwrite;
            -- а заодно и в иных местах определить, что делать памяти
         when c_next => null;
            -- на адрес подается вершина стека возвратов
            new_CPU.addr := CPU.return_stack.top;
            -- сама вершина модифицируется на следущщий адрес
            new_CPU.return_stack.top := CPU.return_stack.top+1;
            -- а считанное данное помещяется в PC
            new_CPU.pc := Data;
            -- память, ясное дело, читается
            new_CPU.mem := Mread;
         when dup =>
            -- просто втолкнуть в стек  даных копию вершины
            new_CPU.data_stack := PUSH2STACK(CPU.data_stack,CPU.data_stack.top);
            
         when drop => null;
            -- просто вытолкнуть вершину из стека данных
            new_CPU.data_stack := POP4STACK(CPU.data_stack);
         when swap => null;
            -- переставить местами вершину и подвершину
            -- задействовать временную переменную
            tmp := new_CPU.data_stack.top;
            new_CPU.data_stack.top := CPU.data_stack.subtop;
            new_CPU.data_stack.subtop := tmp;
            
         when toR => null;
            -- переместить вершину стека данных на ввершину стека возвратов
            new_CPU.return_stack := PUSH2STACK(CPU.return_stack,CPU.data_stack.top);
            new_CPU.data_stack := POP4STACK(CPU.data_stack);

         when fromR => null;
            -- переместить вершину стека возвратор на ввершину стека данных
            new_CPU.data_stack := PUSH2STACK(CPU.data_stack,CPU.return_stack.top);
            new_CPU.return_stack := POP4STACK(CPU.return_stack);
            
         when c_add => null;
            tmp := CPU.data_stack.top + CPU.data_stack.subtop;
            -- во первых POP из стека данных
            new_CPU.data_stack := POP4STACK(CPU.data_stack);
            -- и заменить вершину на результат операции +
            new_CPU.data_stack.top := tmp;
            
         when c_nand => null;
            tmp := not(CPU.data_stack.top and CPU.data_stack.subtop);
            -- теперь POP из стека данных
            new_CPU.data_stack := POP4STACK(CPU.data_stack);
            -- и заменить вершину на результат операции NAND
            new_CPU.data_stack.top := tmp;
         when c2div => null;
            -- арифметический сдвиг вправо
            tmp := CPU.data_stack.top(width-1)&CPU.data_stack.top(width-1 downto 1);
            -- и заменить вершину на результат операции 2/
            new_CPU.data_stack.top := tmp;

         when others => null;
         
      end case;

      
      
   return new_CPU;
end;

end;


и файл CPU2011.vhd

Код:
LIBRARY IEEE;
USE IEEE.std_logic_1164.all;
USE IEEE.std_logic_unsigned.all;
USE WORK.CPUpack.all;

entity CPU2011 is

   Port(
      clk : in std_logic;
      reset : in std_logic;
      addr : out word;
      iData : in word;
      MRD,MWR,MCS : out std_logic;
      test_cmd : out std_logic_vector(3 downto 0);
      test_top : out word;
      test_subtop : out word;
      test_rst_top : out word;

      oData : out word
   );
END CPU2011;
   
architecture rtl of CPU2011 is
   signal new_CPU,CPU : CPU_t;
begin

   new_CPU <= Logic_kernel(CPU,iData);

   process (reset,clk) begin
      if reset = '0' then
         CPU.pc <= (others =>'0');
         CPU.cmd <= (others =>'0');
         CPU.mem <= Mnop;
      elsif clk'event and clk='1' then
         CPU <= new_CPU;
      end if;
      
   Addr <= new_CPU.addr;
   oData <= new_CPU.oData;
   
   case new_CPU.mem is
      when Mread => MRD <= clk;MWR <= '1';MCS  <=clk;
      when Mwrite => MRD <= '1';MWR <= clk;MCS  <=clk;
      when others => MRD <= '1';MWR <= '1';MCS  <='1';
   end case;

   end process;

      test_cmd <= CPU.cmd(width-1 downto width-4);
      test_top <= CPU.data_stack.top;
      test_subtop <= CPU.data_stack.subtop;
      test_rst_top <= CPU.return_stack.top;

end;

_________________
С уважением, WingLion
Forth-CPU . RuF09WE
Мой Форт
Отсутствие бана это не заслуга юзера, а недоработка модератора (с)


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения: Re: VHDL: процессор за час
СообщениеДобавлено: Сб фев 05, 2011 01:05 
Не в сети
Administrator
Administrator
Аватара пользователя

Зарегистрирован: Вт май 02, 2006 13:19
Сообщения: 3565
Откуда: St.Petersburg
Благодарил (а): 4 раз.
Поблагодарили: 72 раз.
ИзображениеИзображениеИзображениеИзображениеИзображение

_________________
С уважением, WingLion
Forth-CPU . RuF09WE
Мой Форт
Отсутствие бана это не заслуга юзера, а недоработка модератора (с)


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения: Re: VHDL: процессор за час
СообщениеДобавлено: Сб фев 05, 2011 13:53 
Не в сети
Аватара пользователя

Зарегистрирован: Пт дек 26, 2008 21:16
Сообщения: 412
Откуда: Великий Новгород
Благодарил (а): 9 раз.
Поблагодарили: 4 раз.
Итого сколько все же времени потрачено на разработку :?:


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения: Re: VHDL: процессор за час
СообщениеДобавлено: Сб фев 05, 2011 14:01 
Не в сети
Administrator
Administrator
Аватара пользователя

Зарегистрирован: Вт май 02, 2006 13:19
Сообщения: 3565
Откуда: St.Petersburg
Благодарил (а): 4 раз.
Поблагодарили: 72 раз.
с 18.10 до 22.48 - 4 часа 38 мин.
Ну, и к этим часам надо бы добавить -1996+2011 = 15 лет занятий ПЛИС-ами.

_________________
С уважением, WingLion
Forth-CPU . RuF09WE
Мой Форт
Отсутствие бана это не заслуга юзера, а недоработка модератора (с)


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения: Re: VHDL: процессор за час
СообщениеДобавлено: Сб фев 05, 2011 14:20 
Не в сети
Administrator
Administrator
Аватара пользователя

Зарегистрирован: Вт май 02, 2006 13:19
Сообщения: 3565
Откуда: St.Petersburg
Благодарил (а): 4 раз.
Поблагодарили: 72 раз.
Теперь надо бы поговорить о скорости процессора.

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

Чтобы проверить реальную рабочую частоту надо подключить к процессору внешнюю память и прогнать тесты или проверить на реальном железе.

Вот, этой проверкой (в симуляторе!) я сейчас и займусь.

Для начала, добавляю в пакет новый тип - память:

И 'рисую' в главном файле двухпортовую память для процессора. Двух - для того, чтобы через второй порт можно было записать в память нужные данные непосредственно в процессе симуляции и проверить таким образом все команды, а компилятор будет считать, что в памяти может лежать что угодно, и не станет ее оптимизировать, как это может быть, если просто задать в памяти конкретные значения и не давать возможности ее менять извне.

Код:
   type memory_t is array (mem_size-1 downto 0) of word;


Тут же в пакете пишу фунцию инициализации памяти:

Код:
function mem_init(attr : natural) return mem_type;


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

все таки написал тело функции инициализации в трех вариантах
нулями, единицами и короткой тест-программой.

Код:
function mem_init(attr : natural) return mem_type is
   variable mem : mem_type;
begin
   
   -- если ноль - инициализировать как есть - нулями
   -- иначе - инвертировать - единицами
   if attr = 1 then
      mem := not mem;
   end if;
   
   -- инициализация для теста
   -- используются те же константы что и в главном case
   if attr = 2 then
      mem(0) := nop&nop&nop&nop;
      -- загрузить четыре литерала
      mem(1) := lit&lit&;lit&lit;
      mem(3) := vv(32);
      mem(4) := vv(64);
      mem(5) := vv(128);
      mem(6) := vv(256);
      
      -- сложить попарно, попутно проверяя передачу на стек возвратов и обратно
      mem(7) := add&toR&add&fromR;
      -- сделать nand и зациклить call-ом на ноль
      mem(8) := c_nand&call&nop&nop;
      mem(9) := vv(0);
      -- все остальное остается нулями само
   end if;
   
   return mem;
end;


компилирую, исправляю ошибки...

сама память в главном файле еще не объвлена

_________________
С уважением, WingLion
Forth-CPU . RuF09WE
Мой Форт
Отсутствие бана это не заслуга юзера, а недоработка модератора (с)


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения: Re: VHDL: процессор за час
СообщениеДобавлено: Сб фев 05, 2011 15:02 
Не в сети
Administrator
Administrator
Аватара пользователя

Зарегистрирован: Вт май 02, 2006 13:19
Сообщения: 3565
Откуда: St.Petersburg
Благодарил (а): 4 раз.
Поблагодарили: 72 раз.
Объявляю порты, сигналы, память и описываю ее в отдельном process.


Код:
   -- сигналы для записи данных в память процесора извне
   ram_wr   : in std_logic := '0';
   ram_addr : in word;
   ram_data : in word;



Код:
   -- сигналы для памяти
   signal ram : memory_t;
   signal new_CPU_addr : natural;
   signal new_CPU_oData : word;


Код:
   process(clk) begin
   if clk'event and clk='1' then
      new_CPU_addr <= conv_integer(new_CPU.addr);
      new_CPU_oData <= new_CPU.oData;
      
      if (ram_wr = '1') then
         ram(conv_integer(ram_addr)) <= ram_data;
      elsif (new_CPU.mem = Mwrite) then
         ram(conv_integer(new_CPU_addr)) <= new_CPU_oData;
      end if;
      
      ram_q <= ram(conv_integer(new_CPU_addr));
   end if;
   end process;


компилирую

_________________
С уважением, WingLion
Forth-CPU . RuF09WE
Мой Форт
Отсутствие бана это не заслуга юзера, а недоработка модератора (с)


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения: Re: VHDL: процессор за час
СообщениеДобавлено: Сб фев 05, 2011 15:18 
Не в сети
Administrator
Administrator
Аватара пользователя

Зарегистрирован: Вт май 02, 2006 13:19
Сообщения: 3565
Откуда: St.Petersburg
Благодарил (а): 4 раз.
Поблагодарили: 72 раз.
Исправляю ошибки, компилирую.

Память к процессору еще не подключена и не инициализирована,

Записываю контрольные результаты без памяти:

184MHz, 743 LCELL, 288 тригеров

Подключаю память:

в строчке

Код:
new_CPU <= Logic_kernel(CPU,iData);


меняю iData на mem_q
адреса и остальные сигналы к памяти уже подключены ранее. компилятор их соптимизировал, пока выход памяти висел в воздухе.

Компилирую

_________________
С уважением, WingLion
Forth-CPU . RuF09WE
Мой Форт
Отсутствие бана это не заслуга юзера, а недоработка модератора (с)


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения: Re: VHDL: процессор за час
СообщениеДобавлено: Сб фев 05, 2011 15:28 
Не в сети
Administrator
Administrator
Аватара пользователя

Зарегистрирован: Вт май 02, 2006 13:19
Сообщения: 3565
Откуда: St.Petersburg
Благодарил (а): 4 раз.
Поблагодарили: 72 раз.
Итак, компиляция прошла.

Результат - частота упала до 130MHz, объем по ячейкам и тригерам немного подрос - 805 и 318. И занято 128 килобит внутренней памяти.
Больше ему не подключаю, потому что целевая ПЛИС EP2C20F484C7, которая на моем ките стоит.

Теперь делаю инициализацию памяти, компилирую и иду в симулятор

для инициализации в объявлении памяти добавляю фунцию инициализации:

Код:
   signal ram : memory_t := mem_init(2);

_________________
С уважением, WingLion
Forth-CPU . RuF09WE
Мой Форт
Отсутствие бана это не заслуга юзера, а недоработка модератора (с)


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 137 ]  На страницу Пред.  1, 2, 3, 4, 5 ... 10  След.

Часовой пояс: UTC + 3 часа [ Летнее время ]


Кто сейчас на конференции

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


Вы не можете начинать темы
Вы можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
phpBB сборка от FladeX // Русская поддержка phpBB