Последняя на данный момент версия 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*) количество портов сильно ограничено, но номер порта задается в самой команде.