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

...
Google Search
Forth-FAQ Spy Grafic

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




Начать новую тему Ответить на тему  [ Сообщений: 2 ] 
Автор Сообщение
 Заголовок сообщения: EQUINOX: версия 1Е16 схема на VHDL
СообщениеДобавлено: Ср май 12, 2010 20:30 
Не в сети
Administrator
Administrator
Аватара пользователя

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

Код:
-- EQUINOX Version 13-MAY-2010

LIBRARY IEEE;
USE IEEE.std_logic_1164.all;
USE IEEE.std_logic_unsigned.all;

entity Equinox is

GENERIC ( widthdat : integer := 16;
      WidthAdr : integer := 16);

   Port(
   clk   : in std_logic;
   reset   : in std_logic := '1';
   ena   : in std_logic := '1';
   di   : in std_logic_vector (WidthDat-1 downto 0);

   adr   : out std_logic_vector (WidthAdr-1 downto 0);
   do   : out std_logic_vector (WidthDat-1 downto 0);
   
   PortIn   : in std_logic_vector (WidthDat-1 downto 0);
   
   Cmd   : out std_logic_vector (3 downto 0);
   CmdPref   : out std_logic_vector (3 downto 0);
   
   wait_all: in std_logic_vector (4 downto 0) := (others => '0');
   wait_rd : in std_logic_vector (4 downto 0) := (3 => '1',others => '0');
   wait_wr : in std_logic_vector (4 downto 0) := (1 => '1',others => '0');
   
   ready   : in std_logic := '1';
   rdy2Out   : out std_logic;

   cs_RAM,wr_RAM,rd_RAM : out std_logic;
   PortRead,PortWrite    : out std_logic;
--   RAM_wren    : out std_logic
   
   int         : in std_logic :='0';
   iVector      : in std_logic_vector (WidthAdr-1 downto 0) := (4 => '1', others => '0');
   intack      : out std_logic
   
   );
   
END Equinox;
   
ARCHITECTURE RTL OF Equinox IS

   type wait_mashine is (workS, readyS, readySrr, readySwr, resetS, waitS);

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";

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 jmp : std_logic_vector (3 downto 0) := "0100";
constant dup : std_logic_vector (3 downto 0) := "0101";
constant swap: std_logic_vector (3 downto 0) := "0110";
constant drop: std_logic_vector (3 downto 0) := "0111";

constant pris : std_logic_vector (3 downto 0) := "1000";
constant razi : std_logic_vector (3 downto 0) := "1001";
constant toR  : std_logic_vector (3 downto 0) := "1010";
constant fromR: std_logic_vector (3 downto 0) := "1011";

constant move : std_logic_vector (3 downto 0) := "1100";
constant nnext: std_logic_vector (3 downto 0) := "1101";
constant res14: std_logic_vector (3 downto 0) := "1110";
constant res15: std_logic_vector (3 downto 0) := "1111";
   
   signal waitM   : wait_mashine;
   
   signal cmdr      : std_logic_vector (WidthDat-1 downto 0);
   signal NEWcmdr   : std_logic_vector (WidthDat-1 downto 0);
   signal zero      : std_logic_vector (WidthDat-1 downto 0);
   signal CMD4shr   : std_logic_vector (WidthDat-1 downto 0);
   signal CMD8shr   : std_logic_vector (WidthDat-1 downto 0);
   
   signal alu1_resT     : std_logic_vector (WidthDat-1 downto 0);
   signal alu1_resB     : std_logic_vector (WidthDat-1 downto 0);
   signal alu2_resT     : std_logic_vector (WidthDat-1 downto 0);
   signal alu2_resB     : std_logic_vector (WidthDat-1 downto 0);
   signal alu3_resT     : std_logic_vector (WidthDat-1 downto 0);
   signal alu3_resB     : std_logic_vector (WidthDat-1 downto 0);      
   
   signal WaitCT    : std_logic_vector (4 downto 0);
   signal NEWwaitCT: std_logic_vector (4 downto 0);
   signal CmdS      : std_logic_vector (3 downto 0);

   signal Xready   : std_logic;
   signal newXready: std_logic;
   signal Trigg   : std_logic;
   signal NewTrigg   : std_logic;

   signal oldWrRAM : std_logic;
   signal oldRdRAM : std_logic;
   signal oldCsRAM : std_logic;
   
   signal PC      : std_logic_vector (WidthAdr-1 downto 0);
   signal newPC   : std_logic_vector (WidthAdr-1 downto 0);
   
   signal TR      : std_logic_vector (WidthAdr-1 downto 0);
   signal newTR   : std_logic_vector (WidthAdr-1 downto 0);
   
   signal csRAM,wrRAM,rdRAM   : std_logic;
   
   signal test_rom   : std_logic_vector (WidthDat-1 downto 0);
--   signal di   : std_logic_vector (WidthDat-1 downto 0);

   signal mul_res   : std_logic_vector (WidthDat+WidthDat-1 downto 0);
   
   signal RStcmd    : std_logic_vector (1 downto 0);
   signal RStDi   : std_logic_vector (WidthDat-1 downto 0);
   signal RStDo   : std_logic_vector (WidthDat-1 downto 0);
   signal DStcmd    : std_logic_vector (1 downto 0);
   signal DStDi   : std_logic_vector (WidthDat-1 downto 0);
   signal DStDo   : std_logic_vector (WidthDat-1 downto 0);
   
   signal enaout   : std_logic;
   signal intack1,intack2   : std_logic;
   signal interupt   : std_logic;
   
COMPONENT Stack IS

GENERIC ( widthdat : integer := 16;
      depth : integer := 8
      );
      Port (
         clk   : in std_logic;
         di   : in std_logic_vector (widthdat-1 downto 0);
         doo   : out std_logic_vector (widthdat-1 downto 0);
         
         cmd   : in std_logic_vector (1 downto 0);
         ena   : in std_logic
      );

END COMPONENT;

BEGIN

Data_Stack: Stack
   GENERIC MAP ( widthdat => widthdat, depth => 8 )
   PORT MAP (clk => clk,di => DStDo, doo => DStDi, cmd => DStcmd, ena => enaout);

Return_Stack: Stack
   GENERIC MAP ( widthdat => widthdat, depth => 8 )
   PORT MAP (clk => clk,di => RStDo, doo => RStDi, cmd => RStcmd, ena => enaout);

--   mul_res <= TR * RSTdi;

   -- ALU for commands DUP#
   process (CMDr,clk) begin
      
      case conv_integer(CMDr(7 downto 4)) is
      -- 5 x command
         when 0 =>
            -- DUP 5, 0,
            alu1_resB <= TR; --  DUP
            alu1_resT <= TR; --  DUP
            PortRead <= '0';
         when 1 =>
            -- OVER 5, 1,
            alu1_resB <= TR; --  DUP
            alu1_resT <= DStdi; --  DUP
            PortRead <= '0';
         when 3 =>
            -- TRUE = ZERO???
            alu1_resB <= TR; --  DUP
            alu1_resT <= zero; --  DUP
            PortRead <= '0';
         when 2 =>
            -- FALSE
            alu1_resB <= TR; --  DUP
            alu1_resT <= (others => '1'); --  DUP
            PortRead <= '0';
         when 4 =>
            -- ONE
            alu1_resB <= TR; --  DUP
            alu1_resT <= (0 => '1',others => '0'); --  DUP
            PortRead <= '0';
         when others =>
            -- RESERVED DUP
            alu1_resB <= TR; --   DUP
            alu1_resT <= PortIn; --   DUP
            
            if conv_integer(CMDr(3 downto 0)) = 5 then
               PortRead <= '1';
            else
               PortRead <= '0';
            end if;
      end case;
      
   end process;   
   
   -- ALU for commands SWAP#
   process (CMDr,clk) begin
      
      case conv_integer(CMDr(7 downto 4)) is
      -- 6 x command
         when 0 =>
            -- SWAP 6, 0,
            alu2_resB <= TR; --  SWAP
            alu2_resT <= DStdi; --  SWAP
         when 1 =>
            -- INC 6, 1,
            alu2_resB <= DStdi; --  SWAP
            alu2_resT <= TR+1; --  SWAP
         when 2 =>
            -- DEC 6, 2,
            alu2_resB <= DStdi; --  SWAP
            alu2_resT <= TR-1; --  SWAP
         when 3 =>
            -- MUL 6, 3,
            alu2_resB <= mul_res(WidthDat+WidthDat-1 downto WidthDat);
            alu2_resT <= mul_res(WidthDat-1 downto 0);
         when 4 =>
            -- BSWAP 6, 4,
            alu2_resB <= DStdi;
            alu2_resT(7 downto 0) <= TR(widthDat-1 downto 8);
            alu2_resT(widthDat-1 downto 8) <= TR(7 downto 0);
         when 5 =>
            -- LOGC - 6, 5, -  Logic Convert
            alu2_resB <= DStdi;
            IF (conv_integer(TR) = 0) THEN
               alu2_resT <= (others => '1'); --  FALSE
            ELSE
               alu2_resT <= (others => '0'); --  TRUE
            END IF;
         when 6 =>
            alu2_resB <= DStdi;
            ALU2_resT <= (TR(0)&TR(widthDat-1 downto 1));
         when others =>
            -- RESERVED SWAP
            alu2_resB <= TR; --   SWAP
            alu2_resT <= DStdi; --   SWAP
      end case;
      
   end process;
   
   -- ALU for commands DROP#
   process (CMDr,clk) begin
      
      case conv_integer(CMDr(7 downto 4)) is
      -- 7 x command
         when 0 =>
            -- DROP 7, 0,
            alu3_resB <= DStdi; --  DROP
            alu3_resT <= DStdi; --  DROP
            PortWrite <= '0';
         when 1 =>
            -- ADD 7, 1,
            alu3_resB <= DStdi; --  DROP
            alu3_resT <= DStdi+TR; --  DROP
            PortWrite <= '0';
         when 2 =>
            -- SUB 7, 2,
            alu3_resB <= DStdi; --  DROP
            alu3_resT <= DStdi-TR; --  DROP
            PortWrite <= '0';
         when 3 =>
            -- AND 7, 3,
            alu3_resB <= DStdi; --  DROP
            alu3_resT <= DStdi and TR; --  DROP
            PortWrite <= '0';
         when 4 =>
            -- OR 7, 4,
            alu3_resB <= DStdi; --  DROP
            alu3_resT <= DStdi or TR; --  DROP
            PortWrite <= '0';
         when 5 =>
            -- XOR 7, 5,
            alu3_resB <= DStdi; --  DROP
            alu3_resT <= DStdi xor TR; --  DROP            
            PortWrite <= '0';
         when others =>
            -- RESERVED DROP
            alu3_resB <= DStdi; --   DROP
            alu3_resT <= DStdi; --   DROP
            if conv_integer(CMDr(3 downto 0)) = 7 then
               PortWrite <= '1';
            else
               PortWrite <= '0';
            end if;
      end case;
      
   end process;

   zero <= (others => '0');
   -- command register 4-bit shifted
   CMD4shr(widthdat-5 downto 0) <= (cmdr(widthdat-1 downto 4));
   CMD4shr(widthdat-1 downto widthdat-4)<=zero(widthdat-1 downto widthdat-4);
   -- command register 8-bit shifted
   CMD8shr(widthdat-9 downto 0) <= (cmdr(widthdat-1 downto 8));
   CMD8shr(widthdat-1 downto widthdat-8)<=zero(widthdat-1 downto widthdat-8);

   process(clk) begin
      if clk'event and clk = '1' then
         mul_res <= TR * RSTdi;
         if reset = '0' then
            waitM <= resetS;
            csRAM <= '1'; rdRAM <= '1'; wrRAM <= '1';
            waitCT <= wait_all;
         else
               case waitM is
                  when workS =>
                     csRAM <= '1'; rdRAM <= '1'; wrRAM <= '1';
                     case conv_integer(newTrigg&newCMDr(3 downto 0)) is
                        when 3 => waitM <= workS; rdy2Out <= '1';
                        when 5 => waitM <= workS; rdy2Out <= '1';
                        when 6 => waitM <= workS; rdy2Out <= '1';
                        when 7 => waitM <= workS; rdy2Out <= '1';
                        when 8 => waitM <= workS; rdy2Out <= '1';
                        when 9 => waitM <= workS; rdy2Out <= '1';
                        when 10 => waitM <= workS; rdy2Out <= '1';
                        when 11 => waitM <= workS; rdy2Out <= '1';
                        when 13 => waitM <= workS; rdy2Out <= '1';
                        when 14 => waitM <= workS; rdy2Out <= '1';
                        when 15 => waitM <= workS; rdy2Out <= '1';
                        when 24 => waitM <= readySrr; rdy2Out <= '0';
                        when 25 => waitM <= readySwr; rdy2Out <= '0';
                        when 12 => waitM <= readyS; rdy2Out <= '0';
                        when 28 => waitM <= readySwr; rdy2Out <= '0';
                        when 29 => waitM <= readySrr;  rdy2Out <= '0';
                        when others => waitM <= readyS; rdy2Out <= '0';
                     end case;
                     waitCT <= wait_all;
                  when readyS => waitM <= waitS;
                     -- read command/immediate cycle
                     csRAM <= '0'; WaitCT <= wait_all;
                     rdRAM <= '0'; wrRAM <= '1';
                  when readySrr => waitM <= waitS;
                     -- read memory cycle
                     rdRAM <= '0'; csRAM <= '0'; WaitCT <= wait_rd;
                  when readySwr => waitM <= waitS;
                     -- write memory cycle
                     wrRAM <= '0'; csRAM <= '0'; WaitCT <= wait_wr;
                  when waitS =>
                     if (conv_integer(WaitCT) = 0) then
                        WaitCT <= (others => '0');
                     else
                        WaitCT <= (WaitCT - 1);
                     end if;
                     
                     csRAM <= csRAM;
                     rdRAM <= rdRAM;
                     wrRAM <= wrRAM;
                     if (ready = '1' and (conv_integer(WaitCT) = 0)) then
                        waitM <= workS;
                     else
                        waitM <= waitS;
                     end if;
                  when resetS => waitM <= readyS;
                     csRAM <= '1';
                     waitCT <= wait_all;
                  when others => waitM <= workS;
                     csRAM <= '1';
                     waitCT <= wait_all;
               end case;
         end if;
         
      end if;
   end process;

   -- MAIN REGISTERS AND TRIGERS
   process (clk,ena) begin
      if (CLK'event and CLK='1' and ENA='1' and (waitM = workS)) then
         if reset = '0' then
            cmdr <= zero;
            PC <= zero;
            TR <= newTR;
            Trigg <= '0';
            intack <= '0';
            interupt <= '0';
         else
            interupt <= (int or interupt) and not intack1;
            cmdr <= NEWcmdr;
            PC <= newPC;
            TR <= newTR;
            Trigg <= NewTrigg;
            intack2 <= intack1;
            intack <= intack1;
         end if;
      end if;
   end process;
   
   CmdS <= cmdr (3 downto 0);

   -- Ccommands Decoder
   process (CmdS) begin
   
      case conv_integer(CmdS) is
         -- STnop
         when 0 =>
            
            NewTrigg <= '0';
            newTR <= TR; DStcmd <= STnop; DStdo <= DStdi;
            if interupt = '1' then
               -- call iVector
               intack1 <= '1';
               NEWcmdr <= (others => '0'); newPC <= iVector;
               RStcmd <= STpush; RStdo <= PC;
            else
               -- Load new commands
               intack1 <= '0';
               NEWcmdr <= di; newPC <= PC + 1; RStcmd <= STnop;
               RStdo <= RStdi;            
            end if;
         -- lit
         when 1 => NEWcmdr <= cmd4shr;  newPC <= PC + 1; RStcmd <= STnop;
            NewTrigg <= '0'; DStdo <= TR; newTR <= di; DStcmd <= STpush; RStdo <= RStdi;
            intack1 <= '0';
         -- call
         when 2 => NEWcmdr <= cmd4shr; NewTrigg <= '0';
            newPC <= di; RStDo <= PC + 1; RStcmd <= STpush;
            newTR <= TR; DStcmd <= STnop; DStdo <= DStdi;
            intack1 <= '0';
         -- ret
         when 3 => NEWcmdr <= cmd4shr;  NewTrigg <= '0';
            newPC <= RStDi; RStcmd <= STpop;
            RStdo <= RStdi; newTR <= TR; DStcmd <= STnop; DStdo <= DStdi;
            intack1 <= '0';
         -- if
         when 4 => NEWcmdr <= cmd4shr; RStdo <= RStdi;
            NewTrigg <= '0'; newTR <= TR; DStcmd <= STnop; DStdo <= DStdi;
            if (TR = 0) then
               newPC <= PC + 1; RStcmd <= STnop;
            else
               newPC <= di; RStcmd <= STnop;
            end if;
            intack1 <= '0';
         -- arifmetic,logic and stack commands
         when 5 => NEWcmdr <= cmd8shr; RStcmd <= STnop; newPC <= PC;
            NewTrigg <= '0'; RStdo <= RStdi;
            -- dup*
            newTR <= alu1_resT;
            DStcmd <= STpush;
            DStdo <= alu1_resB;
            intack1 <= '0';
         -- arifmetic,logic and stack commands
         when 6 => NEWcmdr <= cmd8shr; RStcmd <= STnop; newPC <= PC;
            NewTrigg <= '0'; RStdo <= RStdi;
            -- swap*
            newTR <= alu2_resT;
            DStcmd <= STswap;
            DStdo <= alu2_resB;
            intack1 <= '0';
         -- arifmetic,logic and stack commands
         when 7 => NEWcmdr <= cmd8shr; RStcmd <= STnop; newPC <= PC;
            NewTrigg <= '0'; RStdo <= RStdi;
            newTR <= alu3_resT;
            DStcmd <= STpop;
            DStdo <= alu3_resB;
            intack1 <= '0';
         -- @
         when 8 =>
            intack1 <= '0';
            NewTrigg <= not Trigg;
            if Trigg = '0' then
               NEWcmdr <= cmdr;
               RStcmd <= STpush; newPC <= TR; RStdo <= PC;
               newTR <= DStdi; DStcmd <= STpop; DStdo <= DStdi;
            else
               NEWcmdr <= cmd4shr;
               RStcmd <= STpop;    newPC <= RSTdi; RStdo <= RStdi;
               newTR <= di;    DStcmd <= STpush; DStdo <= TR;
            end if;
         -- !
         when 9 =>
            intack1 <= '0';
            NewTrigg <= not Trigg;
            if Trigg = '0' then
               NEWcmdr <= cmdr;
               RStcmd <= STpush; newPC <= TR; RStdo <= PC;
               DStcmd <= STpop;    newTR <= DStdi; DStcmd <= STpop; DStdo <= DStdi;
            else
               NEWcmdr <= cmd4shr;
               RStcmd <= STpop; newPC <= RSTdi; RStdo <= RStdi;
               DStcmd <= STpop; newTR <= DStdi; DStcmd <= STpop; DStdo <= DStdi;
            end if;
         -- >R
         when 10 => NEWcmdr <= cmd4shr; RStcmd <= STpush; newPC <= PC;
            NewTrigg <= '0'; RStdo <= TR; newTR <= DStdi; DStcmd <= STpop;
            DStdo <= DStdi;
            intack1 <= '0';
         -- R>
         when 11 => NEWcmdr <= cmd4shr; RStcmd <= STpop; newPC <= PC;
            NewTrigg <= '0'; RStdo <= RStdi; newTR <= RStdi; DStcmd <= STpush; DStdo <= TR;
            intack1 <= '0';
         -- move
         when 12 =>
            intack1 <= '0';
            NewTrigg <= not Trigg;
            if Trigg = '0' then
               newTR <= di;
               RStcmd <= STswap; RStdo <= PC + 1; newPC <= RStdi;
               newTR <= di;    DStdo <= TR - 1; DStcmd <= STpush;
               NEWcmdr <= cmdr; -- CMD not changed
            else
               newTR <= DStdi;
               RStcmd <= STswap; RStdo <= PC + 1; newPC <= RStdi;
               newTR <= DStdi; DStdo <= DStdi;  DStcmd <= STpop;
               if (conv_integer(DStdi) = 0) then
                  NEWcmdr <= cmd4shr; -- next CMD
               else
                  NEWcmdr <= cmdr; -- CMD not changed
               end if;                  
            end if;

         -- next = ret+call
         when 13 =>
            intack1 <= '0';
            NewTrigg <= not Trigg;
            if Trigg = '0' then
               -- ret
               newPC <= RStDi; RStcmd <= STpop; RStdo <= RStdi;
               newTR <= TR; DStcmd <= STnop; DStdo <= DStdi;
               NEWcmdr <= cmdr;
            else
               -- call
               newPC <= di; RStDo <= PC + 1; RStcmd <= STpush;
               newTR <= TR; DStcmd <= STnop; DStdo <= DStdi;
               NEWcmdr <= cmd4shr;
            end if;
            
--         when 14 =>
--         when 15 =>
         when others => NEWcmdr <= cmd4shr; RStcmd <= STnop; newPC <= PC;
            NewTrigg <= '0'; RStdo <= RStdi; DStdo <= DStdi; DStcmd <= STnop; DStdo <= DStdi;
            newTR <= TR;
            intack1 <= '0';
      end case;
   
   end process;
   
   do <= TR;
   adr <= PC;
   
   cmd <= CmdS;
   cmdPref <= cmdr (7 downto 4);
   cs_RAM <= csRAM;
   rd_RAM <= rdRAM;
   wr_RAM <= wrRAM;
   
   process (waitM) begin
      if waitM = workS then
         enaout <= '1';
      else
         enaout <= '0';
      end if;
      
--      RAM_wren <= (not wrRAM) and reset;
      
   end process;

END ARCHITECTURE;


-- VHDL Lcell Cashe Stack in RAM

LIBRARY IEEE;
USE IEEE.std_logic_1164.all;
USE IEEE.std_logic_unsigned.all;

ENTITY   Stack IS

GENERIC ( widthdat : integer := 16;
      depth : integer := 8
      );
      Port (
         clk   : in std_logic;
         di   : in std_logic_vector (widthdat-1 downto 0);
         doo   : out std_logic_vector (widthdat-1 downto 0);
         
         cmd   : in std_logic_vector (1 downto 0);
         ena   : in std_logic
      );

END Stack;

ARCHITECTURE RTL OF Stack IS
   
   subtype words is std_logic_vector (widthdat-1 downto 0);
   type T_memory is array(2**depth-1 downto 0) of words;
   
attribute altera_attribute : string;
attribute altera_attribute of RTL: architecture is "-name AUTO_SHIFT_REGISTER_RECOGNITION OFF";   

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 do : std_logic_vector (widthdat-1 downto 0);

   signal TOP : std_logic_vector (widthdat-1 downto 0);
   signal BOT : std_logic_vector (widthdat-1 downto 0);
   
   signal REG0 : std_logic_vector (widthdat-1 downto 0);
   signal REG1 : std_logic_vector (widthdat-1 downto 0);
   signal REG2 : std_logic_vector (widthdat-1 downto 0);
   signal REG3 : std_logic_vector (widthdat-1 downto 0);
   
   signal ADR      : natural range 0 to 2**depth-1;
   signal ADR_WR   : natural range 0 to 2**depth-1;
   signal ADR_RD   : natural range 0 to 2**depth-1;
   signal radr   : natural range 0 to 2**depth-1;
   
   signal ramq      : words;
   
   signal adr_rd0   : std_logic_vector (1 downto 0);
   signal adr_rd1   : std_logic_vector (1 downto 0);
   signal adr_rd2   : std_logic_vector (1 downto 0);
   
   signal push_s   : std_logic;
   
   signal RAM : T_memory;

   signal wr0,wr1,wr2,wr3 : std_logic;
   signal wr0t,wr1t,wr2t,wr3t : std_logic;
   signal wr0x,wr1x,wr2x,wr3x : std_logic;
   
function last2bits (adr : natural)  return natural is
   variable adr_4,tmp : natural;
   
begin
   adr_4 := adr/4;
   tmp := adr - (adr_4)*4;
   return tmp;
end last2bits;

BEGIN

   process (clk,ena,cmd) begin
      if (clk'event and clk='1' and ena='1') then
         case  cmd is
            when nop => TOP <= TOP; BOT <= BOT; ADR <= ADR;
            when push => TOP <= Di; BOT <= TOP; if adr = -1 then adr <= adr; else ADR <= ADR+1; end if;
            when pop => TOP <= BOT; BOT <= Do;  if adr = 0 then adr <= adr; else adr <= adr-1; end if;
            when swap => TOP <= di; BOT <= BOT; ADR <= ADR;
            when others => TOP <= TOP; BOT <= BOT;
         end case;

         case cmd is
            when nop =>    if adr = 2**depth-1 then adr_wr <= 2**depth-1; else adr_wr<=adr+1; end if;
            when push =>   if adr = 2**depth-1 or adr = 2**depth-2 then adr_wr <= 2**depth-1; else adr_wr<=adr+2; end if;
            when pop =>    adr_wr <= adr;
            when swap =>   if adr = 2**depth-1 then adr_wr <= 2**depth-1; else adr_wr<=adr+1; end if;
            when others => if adr = 2**depth-1 then adr_wr <= 2**depth-1; else adr_wr<=adr+1; end if;
         end case;         
         
         adr_rd1 <= "00" + last2bits(adr_rd);
         adr_rd2 <= adr_rd1;
      end if;
   end process;
   
   process (cmd) begin
      case cmd is
         when nop => if adr > 2 then adr_rd <= adr-2; else adr_rd<=0; end if;
         when push => if adr > 1 then adr_rd <= adr-1; else adr_rd<=0; end if;
         when pop => if adr > 3 then adr_rd <= adr-3; else adr_rd<=0; end if;
         when swap => if adr > 2 then adr_rd <= adr-2; else adr_rd<=0; end if;
         when others => if adr > 2 then adr_rd <= adr-2; else adr_rd<=0; end if;
      end case;   

      if cmd = push  then push_s <=ena; else push_s <='0'; end if;
   end process;
   


   doo <= top;
   
   process (adr_wr) begin
      if last2bits(adr_wr) = 0 and push_s ='1' then wr0 <='1'; else wr0<='0'; end if;
      if last2bits(adr_wr) = 1 and push_s ='1' then wr1 <='1'; else wr1<='0'; end if;
      if last2bits(adr_wr) = 2 and push_s ='1' then wr2 <='1'; else wr2<='0'; end if;
      if last2bits(adr_wr) = 3 and push_s ='1' then wr3 <='1'; else wr3<='0'; end if;
   end process;
   
   process (clk,ena) begin
      if (clk'event and clk='1' and ena='1') then
         wr0t <= wr0; if wr0 = '1' then reg0 <= bot; elsif wr0x = '1' and wr0t = '0' then reg0 <= ramq; end if;
         wr1t <= wr1; if wr1 = '1' then reg1 <= bot; elsif wr1x = '1' and wr1t = '0' then reg1 <= ramq; end if;
         wr2t <= wr2; if wr2 = '1' then reg2 <= bot; elsif wr2x = '1' and wr2t = '0' then reg2 <= ramq; end if;
         wr3t <= wr3; if wr3 = '1' then reg3 <= bot; elsif wr3x = '1' and wr3t = '0' then reg3 <= ramq; end if;
      end if;
   end process;
   
   process (adr) begin
      case last2bits(adr) is
         when 0 => do <= reg0;
         when 1 => do <= reg1;
         when 2 => do <= reg2;
         when 3 => do <= reg3;
         when others => null;
      end case;
   end process;

   process (adr_rd2) begin
      if adr_rd2 = "00" then wr0x <= '1'; else wr0x <= '0'; end if;
      if adr_rd2 = "01" then wr1x <= '1'; else wr1x <= '0'; end if;
      if adr_rd2 = "10" then wr2x <= '1'; else wr2x <= '0'; end if;
      if adr_rd2 = "11" then wr3x <= '1'; else wr3x <= '0'; end if;
   end process;

   -- RAM
   process(clk)
   begin
   if(rising_edge(clk)) then
      if(push_s = '1') then
         ram(adr_wr) <= bot;
      end if;
      radr <= adr_rd;
      ramq <= ram(radr);
   end if;
   end process;

END ARCHITECTURE;



Компилируется для EP2C20F484C7 с частотой более 140MHz.

Проверен в работе в реальной ПЛИС на частоте 100MHz.
занимает ~950LCELL + 8Kbit встроенной памяти. (~5% от EP2C20)

исправления, добавленные 13 мая:
1. введено (немаскируемое) прерывание с внешним вектором.
2. добавлены команды ввода и вывода в порты (префиксные команды из групп DUP* и DROP*) количество портов сильно ограничено, но номер порта задается в самой команде.

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


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения: Re: EQUINOX: версия 1Е16 схема на VHDL
СообщениеДобавлено: Чт май 13, 2010 21:24 
Не в сети
Administrator
Administrator
Аватара пользователя

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

1. введено (немаскируемое) прерывание с внешним вектором.
прерывание срабатывает по положительному импульсу на входе int. импульс должен длиться не более чем до появления высокого уровня на выходе intack. В противном случае может возникнуть повторное срабатывание прерывания. Выход из прерывания по команде RET

2. добавлены команды ввода и вывода в порты (префиксные команды из групп DUP* и DROP*) количество портов сильно ограничено, но номер порта задается в самой команде. Номер порта присутствует на выходе CmdPref, чтение из порта по сигналу PortRead, запись в порт по сигналу PortWrite. Чтение/запись - синхронные по clk.
Если номер в CmdPref соответствует арифметическо-логической команде. сигналы чтения/записи в порт не формируются, и операция ввода/вывода с портом не производится.

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


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 2 ] 

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


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

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


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

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