Автор |
Сообщение |
|
|
Заголовок сообщения: |
|
|
|
Вчерашний код процессора отредактирован (новая версия - два поста выше).
Добавлены:
1. автомат ожидания - вставляет нужное количество тактов в циклы чтения памяти (минимум - два такта).
2. схема быстрого исполнения для команд, не требующих обащения к памяти - исполняются за один такт без тактов ожидания.
3. коды команд приведены в соответствие со списком в начале исходника
4. удалены левые коментарии
Вчерашний код процессора отредактирован (новая версия - два поста выше).
Добавлены:
1. автомат ожидания - вставляет нужное количество тактов в циклы чтения памяти (минимум - два такта).
2. схема быстрого исполнения для команд, не требующих обащения к памяти - исполняются за один такт без тактов ожидания.
3. коды команд приведены в соответствие со списком в начале исходника
4. удалены левые коментарии
|
|
|
|
Добавлено: Пн апр 12, 2010 20:51 |
|
|
|
|
|
Заголовок сообщения: |
|
|
|
Немного поигрался с компилятором...
EP2C20F484C7 -- 16 bit вариант - 180MHz - 710 LCELLs
EP2C20F484C7 -- 32 bit вариант - 148MHz - 1383 LCELLs
EP2AGX45CU17C4 -- 16 bit вариант - 418MHz - 318 ALUTs
EP2AGX45DF25C4 -- 32 bit вариант - 362MHz - 739 ALUTs
Добавка через день (компилировано на работе, на лицензионном квартусе)
EP3SE50F484C2 - 16 бит - 393ALUTs - 470MHz
EP4CGX22CF19C6 - 16 bit - 732LCELLs - 277MHz
EP3C16Q240C8 - 16 bit - 730LCELLs - 198MHz
Немного поигрался с компилятором...
EP2C20F484C7 -- 16 bit вариант - 180MHz - 710 LCELLs
EP2C20F484C7 -- 32 bit вариант - 148MHz - 1383 LCELLs
EP2AGX45CU17C4 -- 16 bit вариант - 418MHz - 318 ALUTs
EP2AGX45DF25C4 -- 32 bit вариант - 362MHz - 739 ALUTs
Добавка через день (компилировано на работе, на лицензионном квартусе)
EP3SE50F484C2 - 16 бит - 393ALUTs - 470MHz
EP4CGX22CF19C6 - 16 bit - 732LCELLs - 277MHz
EP3C16Q240C8 - 16 bit - 730LCELLs - 198MHz
|
|
|
|
Добавлено: Вс апр 11, 2010 18:28 |
|
|
|
|
|
Заголовок сообщения: |
|
|
|
Прикидка на VHDL, которая у меня получилась:
Код: -- version of 12 april 2010 LIBRARY IEEE; USE IEEE.std_logic_1164.all; USE IEEE.std_logic_unsigned.all;
--Minimal instruction Forth Computer -- --MIFC16 -- --0 NOP выборка следующей команды (нет операции) --1 ?BRANCH (IFNZ) переход, если на стеке не ноль --2 LIT загрузка непосредственного литерала на стек ( --> data ) --3 @ извлечь данное по адресу из стека ( addr --> data=mem[addr]) --4 ! сохранить даное в памяти по адресу ( data, addr --> ) --5 CALL вызов попрограммы ( вызов адресного интерпретатора) --6 RET возврат из подпрограммы --7 DUP дублирование данного с вершины стека ( d --> d d) --8 DROP удаление данного с вершины стека ( d --> ) --9 SWAP перестановка двух элементов на вершине стека ( d1 d2 --> d2 d1) --10 OVER копирование второго элемента стека ( d1 d2 --> d2 d1 d2) --11 AR> переместить данное со стека данных на стек возвратов ( adr --> ) --12 A>R переместить данное со стека возвратов на стек данных ( --> adr) --13 NAND поразрядное логическое "И-НЕ" двух верхних элементов стека ( d1 d1 --> d1 nand d2) --: NOT DUP NAND ; поразрядное логическое инвертирование верхнего элемента стека (d --> not d) --: OR NOT SWAP NOT NAND ; поразрядное логическое "ИЛИ" двух верхних элементов стека ( d1 d1 --> d1 or d2 ) --: AND NAND DUP NAND ; поразрядное логическое "И" ( d1 d1 --> d1 and d2 ) --: XOR OVER OVER NAND DUP >R NAND SWAP R> NAND NAND ; поразрядное "Исключающее ИЛИ" ( d1 d1 --> d1 xor d2) --14 ADD сложить два верхних элемента стека (d1 d1 --> d1+d2) --15 2/ разделить верхний элемент стека на 2 ( d --> d/2) --: 2* DUP ADD ;
entity mifc16 is GENERIC ( widtX : integer :=16 );
Port( clk : in std_logic; ready : in std_logic := '1'; reset : in std_logic := '1'; di : in std_logic_vector (WidtX-1 downto 0); adr : out std_logic_vector (WidtX-1 downto 0); do : out std_logic_vector (WidtX-1 downto 0); test_Cmd : out std_logic_vector (3 downto 0); test_Trigg : out std_logic; test_DStDo : out std_logic_vector (WidtX-1 downto 0); test_RStDo : out std_logic_vector (WidtX-1 downto 0); cs_RAM,wr_RAM,rd_RAM,Out_ena : out std_logic
);
END mifc16; ARCHITECTURE RTL OF mifc16 IS
type wait_mashine is (Work1, Wait1, Wait2); subtype T_data is std_logic_vector (WidtX-1 downto 0); signal RStcmd : std_logic_vector (1 downto 0); signal RStDi : T_data; -- std_logic_vector (WidtX-1 downto 0); signal RStDo : T_data; -- std_logic_vector (WidtX-1 downto 0); signal DStcmd : std_logic_vector (1 downto 0); signal DStDi : T_data; -- std_logic_vector (WidtX-1 downto 0); signal DStDo : T_data; -- std_logic_vector (WidtX-1 downto 0);
constant STnop : std_logic_vector (1 downto 0) := "00"; constant STpush : std_logic_vector (1 downto 0) := "01"; constant STpop : std_logic_vector (1 downto 0) := "10"; constant STswap : std_logic_vector (1 downto 0) := "11";
signal STM : wait_mashine; signal ENA : std_logic; signal stw : std_logic_vector (3 downto 0); signal rst1 : std_logic;
signal cmdS : std_logic_vector (3 downto 0); signal cmdr : T_data; signal NEWcmdr : T_data; signal zero : T_data; signal CMD4shr : T_data;
signal WrRAM : std_logic; signal RdRAM : std_logic; signal CsRAM : std_logic; signal PC : T_data; -- std_logic_vector (WidtX-1 downto 0); signal newPC : T_data; -- std_logic_vector (WidtX-1 downto 0); signal TR : T_data; -- std_logic_vector (WidtX-1 downto 0); signal newTR : T_data; -- std_logic_vector (WidtX-1 downto 0); signal alux : T_data; -- std_logic_vector (WidtX-1 downto 0); signal mul_res : std_logic_vector (WidtX+WidtX-1 downto 0); signal Trigg,NewTrigg : std_logic;
-- внутренний WAIT - '0' - команда исполняется за один такт, иначе - не меньше 3-х signal IntWait : std_logic; COMPONENT Stack IS GENERIC ( WidtX : integer :=16; depth : integer :=3); Port ( clk : in std_logic; cmd : in std_logic_vector (1 downto 0); di : in std_logic_vector (widtX-1 downto 0); do : out std_logic_vector (widtX-1 downto 0); ena : in std_logic ); END COMPONENT; BEGIN
stack_dd: stack GENERIC MAP ( widtX => WidtX, depth => 8 ) PORT MAP (clk,DSTcmd,DSTdo,DSTdi,ENA); stack_rr: stack GENERIC MAP ( widtX => WidtX, depth => 8 ) PORT MAP (clk,RSTcmd,RSTdo,RSTdi,ENA);
zero <= (others => '0'); -- command register 4-bit shifted CMD4shr(widtX-5 downto 0) <= (cmdr(widtX-1 downto 4)); CMD4shr(widtX-1 downto widtX-4)<=zero(widtX-1 downto widtX-4);
-- REGISTERS and RESET SHEME process (clk,ena) begin if (CLK'event and CLK='1' and ENA='1' ) then if rst1 = '0' then cmdr <= zero; PC <= zero; TR <= newTR; Trigg <= '0'; else cmdr <= NEWcmdr; PC <= newPC; TR <= newTR; Trigg <= NewTrigg; end if; end if; end process;
-- !!! WAIT MACHINE !!! process (clk,STM) begin if (CLK'event and CLK='1' ) then if reset = '0' then STM <= Work1; ENA <= '1'; stw <= (others => '0'); rst1 <= '0'; else rst1 <= '1'; case STM is when Work1 => if (IntWait = '1') then STM <= Wait1; ENA <= '0'; stw <= zero (3 downto 0) + 1; else STM <= Work1; ENA <= '1'; stw <= zero (3 downto 0); end if; when Wait1 => if (stw = 1) then stw <= zero (3 downto 0) + 1; else stw <= stw - 1; end if; ENA <= '0'; if ((stw = 1) and ready = '1') then STM <= Wait2; else STM <= Wait1; end if; when Wait2 => STM <= Work1; ENA <= '1'; stw <= (others => '0'); end case; end if; end if; end process; CmdS <= cmdr (3 downto 0);
-- MAIN COMMAND CASE process (NEWcmdr(3 downto 0)) begin case conv_integer(NEWcmdr(3 downto 0)) is when 0 => IntWait <= '1'; when 1 => IntWait <= '1'; when 2 => IntWait <= '1'; when 5 => IntWait <= '1'; when 3 => intWait <= Trigg; when 4 => intWait <= Trigg; when others => IntWait <= '0'; end case; end process;
process (cmdr (3 downto 0)) begin case conv_integer(cmdr (1 downto 0)) is when 1 => alux <= TR nand DSTdi; when 2 => alux <= TR + DSTdi; when 3 => alux <= TR(WidtX-1)&TR(WidtX-1 downto 1); when others => alux <= TR; end case; case conv_integer(cmdr (3 downto 0)) is -- NOP when 0 => NEWcmdr <= di; newPC <= PC + 1; RStcmd <= STnop; NewTrigg <= '0'; RStdo <= RStdi; newTR <= TR; DStcmd <= STnop; DStdo <= DStdi; CsRAM <= '0'; WrRAM <= '1'; RdRAM <= '0'; -- LIT when 1 => NEWcmdr <= cmd4shr; newPC <= PC + 1; RStcmd <= STnop; NewTrigg <= '0'; DStdo <= TR; newTR <= di; DStcmd <= STpush; RStdo <= RStdi; CsRAM <= '0'; WrRAM <= '1'; RdRAM <= '0'; -- CALL when 2 => NEWcmdr <= cmd4shr; NewTrigg <= '0'; newPC <= di; RStDo <= PC + 1; RStcmd <= STpush; newTR <= TR; DStcmd <= STnop; DStdo <= DStdi; CsRAM <= '0'; WrRAM <= '1'; RdRAM <= '0'; -- @ when 3 => newTrigg <= not Trigg; if Trigg = '0' then CsRAM <= '1'; WrRAM <= '1'; RdRAM <= '1'; NEWcmdr <= cmdr; RStcmd <= STpush; newPC <= TR; RStdo <= PC; newTR <= DStdi; DStcmd <= STpop; DStdo <= DStdi; else CsRAM <= '0'; WrRAM <= '1'; RdRAM <= '0'; NEWcmdr <= cmd4shr; RStcmd <= STpop; newPC <= RSTdi; RStdo <= RStdi; newTR <= di; DStcmd <= STpush; DStdo <= TR; end if; -- ! when 4 => newTrigg <= not Trigg; if Trigg = '0' then CsRAM <= '1'; WrRAM <= '1'; RdRAM <= '1'; NEWcmdr <= cmdr; RStcmd <= STpush; newPC <= TR; RStdo <= PC; DStcmd <= STpop; newTR <= DStdi; DStcmd <= STpop; DStdo <= DStdi; else CsRAM <= '0'; WrRAM <= '0'; RdRAM <= '1'; NEWcmdr <= cmd4shr; RStcmd <= STpop; newPC <= RSTdi; RStdo <= RStdi; DStcmd <= STpop; newTR <= DStdi; DStcmd <= STpop; DStdo <= DStdi; end if; -- ?BRANCH when 5 => NEWcmdr <= cmd4shr; RStdo <= RStdi; NewTrigg <= '0'; newTR <= TR; DStcmd <= STnop; DStdo <= DStdi; CsRAM <= '0'; WrRAM <= '1'; RdRAM <= '0'; if (TR = 0) then newPC <= PC + 1; RStcmd <= STnop; else newPC <= di; RStcmd <= STnop; end if; -- RET when 6 => NEWcmdr <= cmd4shr; NewTrigg <= '0'; newPC <= RStDi; RStcmd <= STpop; RStdo <= RStdi; newTR <= TR; DStcmd <= STnop; DStdo <= DStdi; CsRAM <= '1'; WrRAM <= '1'; RdRAM <= '1'; -- DUP when 7 => NEWcmdr <= cmd4shr; RStcmd <= STnop; newPC <= PC; CsRAM <= '1'; WrRAM <= '1'; RdRAM <= '1'; NewTrigg <= '0'; RStdo <= RStdi; newTR <= TR; DStcmd <= STpush; DStdo <= TR; -- DROP when 8 => NEWcmdr <= cmd4shr; RStcmd <= STnop; newPC <= PC; CsRAM <= '1'; WrRAM <= '1'; RdRAM <= '1'; NewTrigg <= '0'; RStdo <= RStdi; newTR <= DSTdi; DStcmd <= STpop; DStdo <= TR; -- SWAP when 9 => NEWcmdr <= cmd4shr; RStcmd <= STnop; newPC <= PC; CsRAM <= '1'; WrRAM <= '1'; RdRAM <= '1'; NewTrigg <= '0'; RStdo <= RStdi; -- swap* newTR <= DSTdi; DStcmd <= STswap; DStdo <= TR; -- OVER when 10 => NEWcmdr <= cmd4shr; RStcmd <= STnop; newPC <= PC; CsRAM <= '1'; WrRAM <= '1'; RdRAM <= '1'; NewTrigg <= '0'; RStdo <= RStdi; -- dup* newTR <= DSTdi; DStcmd <= STpush; DStdo <= TR; -- R> when 11 => NEWcmdr <= cmd4shr; RStcmd <= STpop; newPC <= PC; CsRAM <= '1'; WrRAM <= '1'; RdRAM <= '1'; NewTrigg <= '0'; RStdo <= RStdi; newTR <= RStdi; DStcmd <= STpush; DStdo <= TR; -- >R when 12 => NEWcmdr <= cmd4shr; RStcmd <= STpush; newPC <= PC; CsRAM <= '1'; WrRAM <= '1'; RdRAM <= '1'; NewTrigg <= '0'; RStdo <= TR; newTR <= DStdi; DStcmd <= STpop; DStdo <= DStdi; -- NAND when 13 => CsRAM <= '1'; WrRAM <= '1'; RdRAM <= '1'; NEWcmdr <= cmd4shr; RStcmd <= STnop; newPC <= PC; NewTrigg <= '0'; RStdo <= RStdi; newTR <= alux; -- TR nand DSTdi; DStcmd <= STpush; DStdo <= TR; -- ADD when 14 => CsRAM <= '1'; WrRAM <= '1'; RdRAM <= '1'; NewTrigg <= '0'; NEWcmdr <= cmd4shr; RStcmd <= STnop; newPC <= PC; RStdo <= RStdi; -- dup* newTR <= alux; -- TR + DSTdi; DStcmd <= STpush; DStdo <= TR; -- 2/ when 15 => CsRAM <= '1'; WrRAM <= '1'; RdRAM <= '1'; NewTrigg <= '0'; NEWcmdr <= cmd4shr; RStcmd <= STnop; newPC <= PC; RStdo <= RStdi; newTR <= alux; -- TR(WidtX-1)&TR(WidtX-1 downto 1); DStcmd <= STpush; DStdo <= TR;
when others => NEWcmdr <= cmd4shr; RStcmd <= STnop; newPC <= PC; CsRAM <= '1'; WrRAM <= '1'; RdRAM <= '1'; NewTrigg <= '0'; RStdo <= RStdi; DStdo <= DStdi; DStcmd <= STnop; DStdo <= DStdi; newTR <= TR;
end case; end process;
do <= TR; adr <= PC; test_cmd <= CmdS; Out_ena <= ENA; cs_RAM <= csRAM or ENA; rd_RAM <= rdRAM or ENA; wr_RAM <= wrRAM or ENA; test_Trigg <= Trigg; test_RStDo <= RSTdo; test_DStDo <= DSTdo;
END RTL;
--
LIBRARY IEEE; USE IEEE.std_logic_1164.all; USE IEEE.std_logic_unsigned.all;
ENTITY stack IS
GENERIC ( WidtX : integer := 16; depth : integer := 3 ); Port ( clk : in std_logic; cmd : in std_logic_vector (1 downto 0); di : in std_logic_vector (WidtX-1 downto 0); do : out std_logic_vector (WidtX-1 downto 0); ena : in std_logic );
END stack;
ARCHITECTURE SRTL OF stack IS attribute altera_attribute : string; attribute altera_attribute of SRTL: architecture is "-name AUTO_SHIFT_REGISTER_RECOGNITION OFF";
TYPE Tstack IS array (depth-1 downto 0) OF std_logic_vector (WidtX-1 downto 0);
constant nop : std_logic_vector (1 downto 0) := "00"; constant push : std_logic_vector (1 downto 0) := "01"; constant pop : std_logic_vector (1 downto 0) := "10"; constant swap : std_logic_vector (1 downto 0) := "11"; signal st : Tstack; BEGIN
process (clk,cmd) begin if (clk'event and clk='1' and ena = '1') then case cmd is when nop => st <= st; when pop => st(depth-2 downto 0) <= st(depth-1 downto 1); st(depth-1) <= (others => '0'); when push => st(depth-1 downto 1) <= st(depth-2 downto 0); st(0) <= di; when swap => st(depth-1 downto 1) <= st(depth-1 downto 1); st(0) <= di; end case; end if; end process; do <= st(0); END ARCHITECTURE;
На CYCLONE-II эта штучка вытягивает до 180MHz
При условии, что обращение к внутренней памяти занимает 3 такта - получается 60MIPS
Прикидка на VHDL, которая у меня получилась:
[code] -- version of 12 april 2010 LIBRARY IEEE; USE IEEE.std_logic_1164.all; USE IEEE.std_logic_unsigned.all;
--Minimal instruction Forth Computer -- --MIFC16 -- --0 NOP выборка следующей команды (нет операции) --1 ?BRANCH (IFNZ) переход, если на стеке не ноль --2 LIT загрузка непосредственного литерала на стек ( --> data ) --3 @ извлечь данное по адресу из стека ( addr --> data=mem[addr]) --4 ! сохранить даное в памяти по адресу ( data, addr --> ) --5 CALL вызов попрограммы ( вызов адресного интерпретатора) --6 RET возврат из подпрограммы --7 DUP дублирование данного с вершины стека ( d --> d d) --8 DROP удаление данного с вершины стека ( d --> ) --9 SWAP перестановка двух элементов на вершине стека ( d1 d2 --> d2 d1) --10 OVER копирование второго элемента стека ( d1 d2 --> d2 d1 d2) --11 AR> переместить данное со стека данных на стек возвратов ( adr --> ) --12 A>R переместить данное со стека возвратов на стек данных ( --> adr) --13 NAND поразрядное логическое "И-НЕ" двух верхних элементов стека ( d1 d1 --> d1 nand d2) --: NOT DUP NAND ; поразрядное логическое инвертирование верхнего элемента стека (d --> not d) --: OR NOT SWAP NOT NAND ; поразрядное логическое "ИЛИ" двух верхних элементов стека ( d1 d1 --> d1 or d2 ) --: AND NAND DUP NAND ; поразрядное логическое "И" ( d1 d1 --> d1 and d2 ) --: XOR OVER OVER NAND DUP >R NAND SWAP R> NAND NAND ; поразрядное "Исключающее ИЛИ" ( d1 d1 --> d1 xor d2) --14 ADD сложить два верхних элемента стека (d1 d1 --> d1+d2) --15 2/ разделить верхний элемент стека на 2 ( d --> d/2) --: 2* DUP ADD ;
entity mifc16 is GENERIC ( widtX : integer :=16 );
Port( clk : in std_logic; ready : in std_logic := '1'; reset : in std_logic := '1'; di : in std_logic_vector (WidtX-1 downto 0); adr : out std_logic_vector (WidtX-1 downto 0); do : out std_logic_vector (WidtX-1 downto 0); test_Cmd : out std_logic_vector (3 downto 0); test_Trigg : out std_logic; test_DStDo : out std_logic_vector (WidtX-1 downto 0); test_RStDo : out std_logic_vector (WidtX-1 downto 0); cs_RAM,wr_RAM,rd_RAM,Out_ena : out std_logic
);
END mifc16; ARCHITECTURE RTL OF mifc16 IS
type wait_mashine is (Work1, Wait1, Wait2); subtype T_data is std_logic_vector (WidtX-1 downto 0); signal RStcmd : std_logic_vector (1 downto 0); signal RStDi : T_data; -- std_logic_vector (WidtX-1 downto 0); signal RStDo : T_data; -- std_logic_vector (WidtX-1 downto 0); signal DStcmd : std_logic_vector (1 downto 0); signal DStDi : T_data; -- std_logic_vector (WidtX-1 downto 0); signal DStDo : T_data; -- std_logic_vector (WidtX-1 downto 0);
constant STnop : std_logic_vector (1 downto 0) := "00"; constant STpush : std_logic_vector (1 downto 0) := "01"; constant STpop : std_logic_vector (1 downto 0) := "10"; constant STswap : std_logic_vector (1 downto 0) := "11";
signal STM : wait_mashine; signal ENA : std_logic; signal stw : std_logic_vector (3 downto 0); signal rst1 : std_logic;
signal cmdS : std_logic_vector (3 downto 0); signal cmdr : T_data; signal NEWcmdr : T_data; signal zero : T_data; signal CMD4shr : T_data;
signal WrRAM : std_logic; signal RdRAM : std_logic; signal CsRAM : std_logic; signal PC : T_data; -- std_logic_vector (WidtX-1 downto 0); signal newPC : T_data; -- std_logic_vector (WidtX-1 downto 0); signal TR : T_data; -- std_logic_vector (WidtX-1 downto 0); signal newTR : T_data; -- std_logic_vector (WidtX-1 downto 0); signal alux : T_data; -- std_logic_vector (WidtX-1 downto 0); signal mul_res : std_logic_vector (WidtX+WidtX-1 downto 0); signal Trigg,NewTrigg : std_logic;
-- внутренний WAIT - '0' - команда исполняется за один такт, иначе - не меньше 3-х signal IntWait : std_logic; COMPONENT Stack IS GENERIC ( WidtX : integer :=16; depth : integer :=3); Port ( clk : in std_logic; cmd : in std_logic_vector (1 downto 0); di : in std_logic_vector (widtX-1 downto 0); do : out std_logic_vector (widtX-1 downto 0); ena : in std_logic ); END COMPONENT; BEGIN
stack_dd: stack GENERIC MAP ( widtX => WidtX, depth => 8 ) PORT MAP (clk,DSTcmd,DSTdo,DSTdi,ENA); stack_rr: stack GENERIC MAP ( widtX => WidtX, depth => 8 ) PORT MAP (clk,RSTcmd,RSTdo,RSTdi,ENA);
zero <= (others => '0'); -- command register 4-bit shifted CMD4shr(widtX-5 downto 0) <= (cmdr(widtX-1 downto 4)); CMD4shr(widtX-1 downto widtX-4)<=zero(widtX-1 downto widtX-4);
-- REGISTERS and RESET SHEME process (clk,ena) begin if (CLK'event and CLK='1' and ENA='1' ) then if rst1 = '0' then cmdr <= zero; PC <= zero; TR <= newTR; Trigg <= '0'; else cmdr <= NEWcmdr; PC <= newPC; TR <= newTR; Trigg <= NewTrigg; end if; end if; end process;
-- !!! WAIT MACHINE !!! process (clk,STM) begin if (CLK'event and CLK='1' ) then if reset = '0' then STM <= Work1; ENA <= '1'; stw <= (others => '0'); rst1 <= '0'; else rst1 <= '1'; case STM is when Work1 => if (IntWait = '1') then STM <= Wait1; ENA <= '0'; stw <= zero (3 downto 0) + 1; else STM <= Work1; ENA <= '1'; stw <= zero (3 downto 0); end if; when Wait1 => if (stw = 1) then stw <= zero (3 downto 0) + 1; else stw <= stw - 1; end if; ENA <= '0'; if ((stw = 1) and ready = '1') then STM <= Wait2; else STM <= Wait1; end if; when Wait2 => STM <= Work1; ENA <= '1'; stw <= (others => '0'); end case; end if; end if; end process; CmdS <= cmdr (3 downto 0);
-- MAIN COMMAND CASE process (NEWcmdr(3 downto 0)) begin case conv_integer(NEWcmdr(3 downto 0)) is when 0 => IntWait <= '1'; when 1 => IntWait <= '1'; when 2 => IntWait <= '1'; when 5 => IntWait <= '1'; when 3 => intWait <= Trigg; when 4 => intWait <= Trigg; when others => IntWait <= '0'; end case; end process;
process (cmdr (3 downto 0)) begin case conv_integer(cmdr (1 downto 0)) is when 1 => alux <= TR nand DSTdi; when 2 => alux <= TR + DSTdi; when 3 => alux <= TR(WidtX-1)&TR(WidtX-1 downto 1); when others => alux <= TR; end case; case conv_integer(cmdr (3 downto 0)) is -- NOP when 0 => NEWcmdr <= di; newPC <= PC + 1; RStcmd <= STnop; NewTrigg <= '0'; RStdo <= RStdi; newTR <= TR; DStcmd <= STnop; DStdo <= DStdi; CsRAM <= '0'; WrRAM <= '1'; RdRAM <= '0'; -- LIT when 1 => NEWcmdr <= cmd4shr; newPC <= PC + 1; RStcmd <= STnop; NewTrigg <= '0'; DStdo <= TR; newTR <= di; DStcmd <= STpush; RStdo <= RStdi; CsRAM <= '0'; WrRAM <= '1'; RdRAM <= '0'; -- CALL when 2 => NEWcmdr <= cmd4shr; NewTrigg <= '0'; newPC <= di; RStDo <= PC + 1; RStcmd <= STpush; newTR <= TR; DStcmd <= STnop; DStdo <= DStdi; CsRAM <= '0'; WrRAM <= '1'; RdRAM <= '0'; -- @ when 3 => newTrigg <= not Trigg; if Trigg = '0' then CsRAM <= '1'; WrRAM <= '1'; RdRAM <= '1'; NEWcmdr <= cmdr; RStcmd <= STpush; newPC <= TR; RStdo <= PC; newTR <= DStdi; DStcmd <= STpop; DStdo <= DStdi; else CsRAM <= '0'; WrRAM <= '1'; RdRAM <= '0'; NEWcmdr <= cmd4shr; RStcmd <= STpop; newPC <= RSTdi; RStdo <= RStdi; newTR <= di; DStcmd <= STpush; DStdo <= TR; end if; -- ! when 4 => newTrigg <= not Trigg; if Trigg = '0' then CsRAM <= '1'; WrRAM <= '1'; RdRAM <= '1'; NEWcmdr <= cmdr; RStcmd <= STpush; newPC <= TR; RStdo <= PC; DStcmd <= STpop; newTR <= DStdi; DStcmd <= STpop; DStdo <= DStdi; else CsRAM <= '0'; WrRAM <= '0'; RdRAM <= '1'; NEWcmdr <= cmd4shr; RStcmd <= STpop; newPC <= RSTdi; RStdo <= RStdi; DStcmd <= STpop; newTR <= DStdi; DStcmd <= STpop; DStdo <= DStdi; end if; -- ?BRANCH when 5 => NEWcmdr <= cmd4shr; RStdo <= RStdi; NewTrigg <= '0'; newTR <= TR; DStcmd <= STnop; DStdo <= DStdi; CsRAM <= '0'; WrRAM <= '1'; RdRAM <= '0'; if (TR = 0) then newPC <= PC + 1; RStcmd <= STnop; else newPC <= di; RStcmd <= STnop; end if; -- RET when 6 => NEWcmdr <= cmd4shr; NewTrigg <= '0'; newPC <= RStDi; RStcmd <= STpop; RStdo <= RStdi; newTR <= TR; DStcmd <= STnop; DStdo <= DStdi; CsRAM <= '1'; WrRAM <= '1'; RdRAM <= '1'; -- DUP when 7 => NEWcmdr <= cmd4shr; RStcmd <= STnop; newPC <= PC; CsRAM <= '1'; WrRAM <= '1'; RdRAM <= '1'; NewTrigg <= '0'; RStdo <= RStdi; newTR <= TR; DStcmd <= STpush; DStdo <= TR; -- DROP when 8 => NEWcmdr <= cmd4shr; RStcmd <= STnop; newPC <= PC; CsRAM <= '1'; WrRAM <= '1'; RdRAM <= '1'; NewTrigg <= '0'; RStdo <= RStdi; newTR <= DSTdi; DStcmd <= STpop; DStdo <= TR; -- SWAP when 9 => NEWcmdr <= cmd4shr; RStcmd <= STnop; newPC <= PC; CsRAM <= '1'; WrRAM <= '1'; RdRAM <= '1'; NewTrigg <= '0'; RStdo <= RStdi; -- swap* newTR <= DSTdi; DStcmd <= STswap; DStdo <= TR; -- OVER when 10 => NEWcmdr <= cmd4shr; RStcmd <= STnop; newPC <= PC; CsRAM <= '1'; WrRAM <= '1'; RdRAM <= '1'; NewTrigg <= '0'; RStdo <= RStdi; -- dup* newTR <= DSTdi; DStcmd <= STpush; DStdo <= TR; -- R> when 11 => NEWcmdr <= cmd4shr; RStcmd <= STpop; newPC <= PC; CsRAM <= '1'; WrRAM <= '1'; RdRAM <= '1'; NewTrigg <= '0'; RStdo <= RStdi; newTR <= RStdi; DStcmd <= STpush; DStdo <= TR; -- >R when 12 => NEWcmdr <= cmd4shr; RStcmd <= STpush; newPC <= PC; CsRAM <= '1'; WrRAM <= '1'; RdRAM <= '1'; NewTrigg <= '0'; RStdo <= TR; newTR <= DStdi; DStcmd <= STpop; DStdo <= DStdi; -- NAND when 13 => CsRAM <= '1'; WrRAM <= '1'; RdRAM <= '1'; NEWcmdr <= cmd4shr; RStcmd <= STnop; newPC <= PC; NewTrigg <= '0'; RStdo <= RStdi; newTR <= alux; -- TR nand DSTdi; DStcmd <= STpush; DStdo <= TR; -- ADD when 14 => CsRAM <= '1'; WrRAM <= '1'; RdRAM <= '1'; NewTrigg <= '0'; NEWcmdr <= cmd4shr; RStcmd <= STnop; newPC <= PC; RStdo <= RStdi; -- dup* newTR <= alux; -- TR + DSTdi; DStcmd <= STpush; DStdo <= TR; -- 2/ when 15 => CsRAM <= '1'; WrRAM <= '1'; RdRAM <= '1'; NewTrigg <= '0'; NEWcmdr <= cmd4shr; RStcmd <= STnop; newPC <= PC; RStdo <= RStdi; newTR <= alux; -- TR(WidtX-1)&TR(WidtX-1 downto 1); DStcmd <= STpush; DStdo <= TR;
when others => NEWcmdr <= cmd4shr; RStcmd <= STnop; newPC <= PC; CsRAM <= '1'; WrRAM <= '1'; RdRAM <= '1'; NewTrigg <= '0'; RStdo <= RStdi; DStdo <= DStdi; DStcmd <= STnop; DStdo <= DStdi; newTR <= TR;
end case; end process;
do <= TR; adr <= PC; test_cmd <= CmdS; Out_ena <= ENA; cs_RAM <= csRAM or ENA; rd_RAM <= rdRAM or ENA; wr_RAM <= wrRAM or ENA; test_Trigg <= Trigg; test_RStDo <= RSTdo; test_DStDo <= DSTdo;
END RTL;
--
LIBRARY IEEE; USE IEEE.std_logic_1164.all; USE IEEE.std_logic_unsigned.all;
ENTITY stack IS
GENERIC ( WidtX : integer := 16; depth : integer := 3 ); Port ( clk : in std_logic; cmd : in std_logic_vector (1 downto 0); di : in std_logic_vector (WidtX-1 downto 0); do : out std_logic_vector (WidtX-1 downto 0); ena : in std_logic );
END stack;
ARCHITECTURE SRTL OF stack IS attribute altera_attribute : string; attribute altera_attribute of SRTL: architecture is "-name AUTO_SHIFT_REGISTER_RECOGNITION OFF";
TYPE Tstack IS array (depth-1 downto 0) OF std_logic_vector (WidtX-1 downto 0);
constant nop : std_logic_vector (1 downto 0) := "00"; constant push : std_logic_vector (1 downto 0) := "01"; constant pop : std_logic_vector (1 downto 0) := "10"; constant swap : std_logic_vector (1 downto 0) := "11"; signal st : Tstack; BEGIN
process (clk,cmd) begin if (clk'event and clk='1' and ena = '1') then case cmd is when nop => st <= st; when pop => st(depth-2 downto 0) <= st(depth-1 downto 1); st(depth-1) <= (others => '0'); when push => st(depth-1 downto 1) <= st(depth-2 downto 0); st(0) <= di; when swap => st(depth-1 downto 1) <= st(depth-1 downto 1); st(0) <= di; end case; end if; end process; do <= st(0); END ARCHITECTURE; [/code]
На CYCLONE-II эта штучка вытягивает до 180MHz
При условии, что обращение к внутренней памяти занимает 3 такта - получается 60MIPS
|
|
|
|
Добавлено: Вс апр 11, 2010 17:49 |
|
|
|
|
|
Заголовок сообщения: |
|
|
|
А что с командным конвейером? Какая ширина команд? Я тут уже готов на VHDL прикинуть.
А что с командным конвейером? Какая ширина команд? Я тут уже готов на VHDL прикинуть.
|
|
|
|
Добавлено: Вс апр 11, 2010 16:52 |
|
|
|
|
|
Заголовок сообщения: |
|
|
|
вопрос писал(а): это плохо для призводительности, если не сделать какую-либо более хитрую оптимизацию
Интересное это дело! - Оптимизировать шкуру неубитого медведя!..
[quote="вопрос"]это плохо для призводительности, если не сделать какую-либо более хитрую оптимизацию[/quote]
Интересное это дело! - Оптимизировать шкуру неубитого медведя!.. :))
|
|
|
|
Добавлено: Сб апр 10, 2010 15:20 |
|
|
|
|
|
Заголовок сообщения: |
|
|
|
наименее редко используемые операции, чтобы потом по возможности вынести ==
наиболее часто вынести
[b]наименее редко[/b] используемые операции, чтобы потом по возможности [b]вынести[/b] ==
[b]наиболее часто вынести[/b]
|
|
|
|
Добавлено: Сб апр 10, 2010 14:02 |
|
|
|
|
|
Заголовок сообщения: |
|
|
|
Хищник писал(а): PC и embedded программы достаточно существенно отличаются
я это понимаю, поэтому и спрашивал статистику посмотреть, на которую ссылался Хищник
Более того, то, что у меня есть собиралось совсем для другой вещи - я смотрел наименее редко используемые операции, чтобы потом по возможности вынести их из ядра во внешние библиотеки.
[quote="Хищник"]PC и embedded программы достаточно существенно отличаются[/quote]
я это понимаю, поэтому и спрашивал статистику посмотреть, на которую ссылался Хищник ;)
Более того, то, что у меня есть собиралось совсем для другой вещи - я смотрел наименее редко используемые операции, чтобы потом по возможности вынести их из ядра во внешние библиотеки.
|
|
|
|
Добавлено: Сб апр 10, 2010 13:55 |
|
|
|
|
|
Заголовок сообщения: |
|
|
|
вопрос писал(а): это плохо для призводительности, если не сделать какую-либо более хитрую оптимизацию
А какую же оптимизацию тут еще можно сделать, если объем операций может быть обусловлен требованиями ТЗ? Если надо посчитать c = a + b, то это будет a @ + b @ + c !. При этом a b c представляют собой литералы - адреса переменных.
[quote="вопрос"]это плохо для призводительности, если не сделать какую-либо более хитрую оптимизацию[/quote]
А какую же оптимизацию тут еще можно сделать, если объем операций может быть обусловлен требованиями ТЗ? Если надо посчитать c = a + b, то это будет a @ + b @ + c !. При этом a b c представляют собой литералы - адреса переменных.
|
|
|
|
Добавлено: Сб апр 10, 2010 13:40 |
|
|
|
|
|
Заголовок сообщения: |
|
|
|
mOleg писал(а): всеравно картина по частоте использования есть. видно, что чаще всего литералы встречаются, потом DUP DROP SWAP @ + OVER ! и удивительно часто NOOP
PC и embedded программы достаточно существенно отличаются. Для embedded характерен больший удельный вес операций работы с памятью и портами, потому что монитор и файловая система как-то нечасто встречаются в таких системах. И если для PC нет-нет да и проскакивает DUP . , то для embedded такая отладочная печать может быть либо невозможна (по причине отсутствия устройства, поддерживающего символьный вывод), либо малоосмысленна (экран 16x2, который мгновенно забьется этой отладочной печатью).
[quote="mOleg"]всеравно картина по частоте использования есть. видно, что чаще всего литералы встречаются, потом DUP DROP SWAP @ + OVER ! и удивительно часто NOOP[/quote]
PC и embedded программы достаточно существенно отличаются. Для embedded характерен больший удельный вес операций работы с памятью и портами, потому что монитор и файловая система как-то нечасто встречаются в таких системах. И если для PC нет-нет да и проскакивает DUP . , то для embedded такая отладочная печать может быть либо невозможна (по причине отсутствия устройства, поддерживающего символьный вывод), либо малоосмысленна (экран 16x2, который мгновенно забьется этой отладочной печатью).
|
|
|
|
Добавлено: Сб апр 10, 2010 13:37 |
|
|
|
|
|
Заголовок сообщения: |
|
|
|
mOleg писал(а): Хищник писал(а): Где форк и где ПЛИС? всеравно картина по частоте использования есть. видно, что чаще всего литералы встречаются
это плохо для призводительности, если не сделать какую-либо более хитрую оптимизацию
[quote="mOleg"][quote="Хищник"]Где форк и где ПЛИС?[/quote] всеравно картина по частоте использования есть. видно, что чаще всего литералы встречаются[/quote]
это плохо для призводительности, если не сделать какую-либо более хитрую оптимизацию
|
|
|
|
Добавлено: Сб апр 10, 2010 13:23 |
|
|
|
|
|
Заголовок сообщения: |
|
|
|
Хищник писал(а): rupor "Тиграаааааааааа!".....
хм, а он сюда заглядывает?
[quote="Хищник"]rupor "Тиграаааааааааа!".....[/quote]
хм, а он сюда заглядывает? :shuffle;
|
|
|
|
Добавлено: Сб апр 10, 2010 12:45 |
|
|
|
|
|
Заголовок сообщения: |
|
|
|
Хищник писал(а): Где форк и где ПЛИС?
всеравно картина по частоте использования есть.
видно, что чаще всего литералы встречаются, потом DUP DROP SWAP @ + OVER ! и удивительно часто NOOP
[quote="Хищник"]Где форк и где ПЛИС?[/quote]
всеравно картина по частоте использования есть.
видно, что чаще всего литералы встречаются, потом DUP DROP SWAP @ + OVER ! и удивительно часто NOOP
|
|
|
|
Добавлено: Сб апр 10, 2010 11:43 |
|
|
|
|
|
Заголовок сообщения: |
|
|
|
mOleg писал(а): вот статистика по частоте использования слов в ядре форка, т.е. речь не о примитивах, а вообще о любом слове, которое искалось и компилировалось во время сборки ядра:
Где форк и где ПЛИС?
[quote="mOleg"]вот статистика по частоте использования слов в ядре форка, т.е. речь не о примитивах, а вообще о любом слове, которое искалось и компилировалось во время сборки ядра: [/quote]
Где форк и где ПЛИС?
|
|
|
|
Добавлено: Сб апр 10, 2010 11:34 |
|
|
|
|
|
Заголовок сообщения: |
|
|
|
Хищник писал(а): mOleg писал(а): очень хотелось бы увидеть результирующую статистику (в смысле, по примитивам) "Тиграаааааааааа!"..... вот статистика по частоте использования слов в ядре форка, т.е. речь не о примитивах, а вообще о любом слове, которое искалось и компилировалось во время сборки ядра: 117 DUP 073 0 072 DROP 067 SWAP 067 A@ 066 @ 065 + 064 OVER 055 A! 054 - 054 L> 052 >L 044 THROW 038 NOOP 035 ! 035 DDROP 034 HERE 034 L@ 034 COMPILE, 032 COUNT 032 = 024 FALSE 023 TYPE 020 R> 020 DDUP 019 TRUE 019 NIP 019 TUCK 019 >STDERR 018 GET-CURRENT 017 LDROP 017 CATCH 017 +! 016 >R
[quote="Хищник"]mOleg писал(а): очень хотелось бы увидеть результирующую статистику (в смысле, по примитивам) "Тиграаааааааааа!".....[/quote] вот статистика по частоте использования слов в ядре форка, т.е. речь не о примитивах, а вообще о любом слове, которое искалось и компилировалось во время сборки ядра:
[pre]117 DUP 073 0 072 DROP 067 SWAP 067 A@ 066 @ 065 + 064 OVER 055 A! 054 - 054 L> 052 >L 044 THROW 038 NOOP 035 ! 035 DDROP 034 HERE 034 L@ 034 COMPILE, 032 COUNT 032 = 024 FALSE 023 TYPE 020 R> 020 DDUP 019 TRUE 019 NIP 019 TUCK 019 >STDERR 018 GET-CURRENT 017 LDROP 017 CATCH 017 +! 016 >R[/pre]
|
|
|
|
Добавлено: Сб апр 10, 2010 10:34 |
|
|
|
|
|
Заголовок сообщения: |
|
|
|
WingLion писал(а): Но, это еще вопрос, надо ли так делать?.. И даст ли оно реальный выигрыш?
Я тут на днях именно так и сделал. То есть JMP по сути есть EXECUTE, и все команды перехода (jmp/if/call) берут адрес со стека. Хотя можно адрес и после команды тянуть, тоже вариант.
[quote="WingLion"]Но, это еще вопрос, надо ли так делать?.. И даст ли оно реальный выигрыш?[/quote]
Я тут на днях именно так и сделал. То есть JMP по сути есть EXECUTE, и все команды перехода (jmp/if/call) берут адрес со стека. Хотя можно адрес и после команды тянуть, тоже вариант.
|
|
|
|
Добавлено: Сб апр 10, 2010 00:04 |
|
|
|
|