--
-- File: c:\my designs\try1\SRC\stack.VHD
-- created by Design Wizard: 02/10/07 12:27:09
--
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity MyIP is
port
(
-- DO NOT EDIT BELOW THIS LINE ---------------------
-- Bus protocol ports, do not add or delete.
FSL_Clk : in std_logic;
FSL_Rst : in std_logic;
FSL_S_Clk : out std_logic;
FSL_S_Read : out std_logic;
FSL_S_Data : in std_logic_vector(0 to 31);
FSL_S_Control : in std_logic;
FSL_S_Exists : in std_logic;
FSL_M_Clk : out std_logic;
FSL_M_Write : out std_logic;
FSL_M_Data : out std_logic_vector(0 to 31);
FSL_M_Control : out std_logic;
FSL_M_Full : in std_logic
-- DO NOT EDIT ABOVE THIS LINE ---------------------
);
attribute SIGIS : string;
attribute SIGIS of FSL_Clk : signal is "Clk";
attribute SIGIS of FSL_S_Clk : signal is "Clk";
attribute SIGIS of FSL_M_Clk : signal is "Clk";
end MyIP;
------------------------------------------------------------------------------
-- Architecture Section
------------------------------------------------------------------------------
-- In this section, we povide an example implementation of ENITY MyIP
-- that does the following:
--
-- 1. Read all inputs
-- 2. Add each input to the contents of register 'sum' which
-- acts as an accumulator
-- 3. After all the inputs have been read, write out the
-- content of 'sum' into the output FSL bus NUMBER_OF_OUTPUT_WORDS times
--
-- You will need to modify this example or implement a new architecture for
-- ENTITY MyIP to implement your coprocessor
architecture EXAMPLE of MyIP is
-- Total number of input data.
constant NUMBER_OF_INPUT_WORDS : natural := 3;
-- Total number of output data
constant NUMBER_OF_OUTPUT_WORDS : natural := 1;
type STATE_TYPE is (Idle, Idle2, Read_Opcode, Read_Operands, Load_From_Stack1, Load_From_Stack2, Store_Into_Stack, Load_Constants, GetLocsArgs, DoBinOps, Pop, Write_Outputs);
signal state : STATE_TYPE;
-- Accumulator to hold sum of inputs read at any point in time
signal sum : std_logic_vector(0 to 31);
signal op : std_logic_vector(0 to 31);
-- Counters to store the number inputs read & outputs written
signal nr_of_reads : natural range 0 to NUMBER_OF_INPUT_WORDS - 1;
signal nr_of_writes : natural range 0 to NUMBER_OF_OUTPUT_WORDS - 1;
-- Stack definition starts =======================
-- The Stack
constant MAXSTACK:INTEGER := 32; -- the max stack file length
type stack_file is array (MAXSTACK-1 downto 0) of std_logic_vector(0 to 31); -- 256 entry stack.
signal stack : stack_file;
-- Stack variables and pointers
--signal sp : std_logic_vector ( 0 to 5-1 ) := (others=>'0') ; -- the stack pointer
signal sp: std_logic_vector ( 0 to 5-1 ) := (others=>'0') ;
signal localsStart : std_logic_vector ( 0 to 5-1 ) := (others=>'0') ;
signal argsStart : std_logic_vector ( 0 to 5-1 ) := (others=>'0') ;
signal base : std_logic_vector ( 0 to 5 - 1 ) := (others => '0');
signal offset : std_logic_vector ( 0 to 5 - 1 ) := (others=>'0');
signal a : std_logic_vector(0 to 31);
signal b : std_logic_vector(0 to 31);
type StackState is (CTRL, DATA, ARGSDATA, LDLOCS);
signal nextState : StackState := CTRL; -- first to start with: Ctrl signal.
-- Stack definition ends =========================
--type bstore is array (127 downto 0) of STD_LOGIC_VECTOR (31 downto 0);
--signal bs : bstore;
signal temp1: Integer range 0 to 127 :=31;
signal bsp,temp,temp2,temp3:INTEGER range 0 to 127 := 0;-- bsp points to t next empty place
signal bsempty: STD_LOGIC := '1';
signal empty: STD_LOGIC:= '1';
signal halffull: STD_LOGIC:= '0';
signal spillover: STD_LOGIC:= '0';
signal fillover: STD_LOGIC:= '0';
signal insidepush : STD_LOGIC :='0';
--signal rear: Integer range -1 to 31 := 0;
signal rear: std_logic_vector ( 0 to 5-1 ) := (others=>'0') ;
signal full: std_logic :='0';
type BIG_STATE_TYPE is(STACK_ONLY,SPILLING,STACK_AND_BS,FILLING);
signal bstate:BIG_STATE_TYPE:=STACK_ONLY ;
-- <<enter your statements here>>
begin
-- CAUTION:
-- The sequence in which data are read in and written out should be
-- consistant with the sequence they are written and read in the
-- driver's MyIP.c file
FSL_S_Read <= FSL_S_Exists when state = Read_Opcode or state = Read_Operands else '0';
FSL_M_Write <= not FSL_M_Full when state = Write_Outputs else '0';
FSL_M_Data <= sum;
process (bsp)
begin
if(bsp=0)then
bsempty<='1';
else
bsempty<='0';
end if;
end process;
The_SW_accelerator : process (FSL_Clk) is
variable transfer1,transfer2,dummyinpush,dummyinpop, dummyinspill, dummyinfill : INTEGER range 0 to 127 :=0;
variable newsp, newrear,dummy : std_logic_vector ( 0 to 5-1 ) := (others=>'0') ;
--variable newsp,newrear : std_logic_vector ( 0 to 5-1 ) := (others=>'0') ;
begin -- process The_SW_accelerator
--if FSL_Clk'event and FSL_Clk = '1' then -- Rising clock edge
if(not ((sp=rear) or (sp=rear-1))) then
a <= stack((CONV_INTEGER(sp) +31) mod 32);
b <= stack((CONV_INTEGER(sp) + 30) mod 32);
end if;
if FSL_Rst = '1' then -- Synchronous reset (active high)
-- CAUTION: make sure your reset polarity is consistant with the
-- system reset polarity
state <= Idle;
nr_of_reads <= 0;
nr_of_writes <= 0;
sum <= (others => '0');
else
case state is
when Idle =>
if (FSL_S_Exists = '1') then
sum <= (others => '0');
state <= Read_Opcode;
end if;
when Idle2 =>
when Read_Opcode =>
if(FSL_S_Exists = '1') then
op <= FSL_S_Data;
if(unsigned(FSL_S_Data) = 3) then -- pop
state <= Pop;
elsif (unsigned(FSL_S_Data) = 4 ) then -- Stack add
state <= DoBinOps;
elsif (unsigned(FSL_S_Data) = 5) then -- stack sub
state <= DoBinOps;
elsif (unsigned(FSL_S_Data) >= 16 and unsigned(FSL_S_Data) <= 24) then -- ldc.i4's
state <= Load_Constants;
elsif (unsigned(FSL_S_Data) >= 32 and unsigned(FSL_S_Data) <= 35) then -- ldloc's
base <= localsStart;
offset <= FSL_S_Data(27 to 31);
state <= Load_From_Stack1;
elsif (unsigned(FSL_S_Data) = 36 ) then --ldloc.s
base <= localsStart;
state <= Read_Operands;
elsif (unsigned(FSL_S_Data) >= 37 and unsigned(FSL_S_Data) <= 40) then -- ldargs's
base <= argsStart;
offset <= FSL_S_Data(27 to 31) - 37;
state <= Load_From_Stack1;
elsif (unsigned(FSL_S_Data) = 41) then -- ldarg.s
base <= argsStart;
state <= Read_Operands;
elsif (unsigned(FSL_S_Data) >= 42 and unsigned(FSL_S_Data) <= 45 ) then -- stloc's
-- sp <= sp - 1;
-- stack(conv_integer(localsStart) + conv_integer(FSL_S_Data(27 to 31) - 42)) <= a; -- a contains the TOS always
base <= localsStart;
offset <= FSL_S_Data(27 to 31) - 42;
state <= Store_Into_Stack;
elsif (unsigned(FSL_S_Data) = 46) then-- stloc.s
base <= localsStart;
state <= Read_Operands;
elsif (unsigned(FSL_S_Data) = 47) then -- starg.s
base <= argsStart;
state <= Read_Operands;
elsif (unsigned(FSL_S_Data) = 25) then -- ldc.i4.s;
state <= Read_Operands;
elsif (unsigned(FSL_S_Data) = 48) then -- CGT
dummy :=sp;
sp<=dummy-1;
state <= idle;
if ( signed(b) > signed(a) ) then
stack(conv_integer(sp - 2)) <= "00000000000000000000000000000001";
else
stack(conv_integer(sp - 2)) <= "00000000000000000000000000000000";
end if;
elsif (unsigned(FSL_S_Data) = 49) then -- CEQ
dummy :=sp;
sp<=dummy-1;
state <= idle;
if( b = a) then
stack(conv_integer(sp - 2)) <= "00000000000000000000000000000001";
else
stack(conv_integer(sp - 2)) <= "00000000000000000000000000000000";
end if;
elsif (unsigned(FSL_S_Data) = 50) then -- CLT
dummy :=sp;
sp<=dummy-1;
state <= idle;
if(signed(b) < signed(a)) then
stack(conv_integer(sp - 2)) <= "00000000000000000000000000000001";
else
stack(conv_integer(sp - 2)) <= "00000000000000000000000000000000";
end if;
elsif (unsigned(FSL_S_Data) = 51) then -- BEQ
dummy :=sp;
sp<=dummy-2;
if(signed(b) = signed(a)) then
sum <= "00000000000000000000000000000001";
else
sum <= (others => '0');
end if;
state <= Write_Outputs;
elsif (unsigned(FSL_S_Data) = 52) then -- BGE
dummy :=sp;
sp<=dummy-2;
if(signed(b) >= signed(a)) then
sum <= "00000000000000000000000000000001";
else
sum <= "00000000000000000000000000000000";
end if;
state <= Write_Outputs;
elsif (unsigned(FSL_S_Data) = 53) then -- BGT
dummy :=sp;
sp<=dummy-2;
if(signed(b) > signed(a)) then
sum <= "00000000000000000000000000000001";
else
sum <= "00000000000000000000000000000000";
end if;
state <= Write_Outputs;
elsif (unsigned(FSL_S_Data) = 54) then -- BLE
dummy :=sp;
sp<=dummy-2;
if(signed(b) <= signed(a)) then
sum <= "00000000000000000000000000000001";
else
sum <= "00000000000000000000000000000000";
end if;
state <= Write_Outputs;
elsif (unsigned(FSL_S_Data) = 55) then -- BLT
dummy :=sp;
sp<=dummy-2;
if(signed(b) < signed(a)) then
sum <= "00000000000000000000000000000001";
else
sum <= "00000000000000000000000000000000";
end if;
state <= Write_Outputs;
elsif (unsigned(FSL_S_Data) = 57) then -- DUP
stack (conv_integer(sp)) <= a;
dummy :=sp;
sp<=dummy+1;
state <= idle;
elsif (unsigned(FSL_S_Data) = 58) then -- And
state <= DoBinOps;
elsif (unsigned(FSL_S_Data) = 59) then -- OR
state <= DoBinOps;
elsif (unsigned(FSL_S_Data)= 60) then -- Xor
state <= DoBinOps;
elsif (unsigned(FSL_S_Data) = 61) then -- Not
stack (conv_integer(sp - 1)) <= not a;
state <= idle;
elsif (unsigned(FSL_S_Data) = 62) then -- Neg
stack (conv_integer(sp - 1)) <= 0 - a;
state <= idle;
elsif (unsigned(FSL_S_Data) >= 1073741824) then
state <= GetLocsArgs;
else
state <= Read_Operands;
end if;
end if;
when Read_Operands =>
if (FSL_S_Exists = '1') then
if (unsigned(op) = 2 or unsigned(op) = 25) then --push and ldc.i4.s
insidepush<='1';
stack(conv_integer(sp)) <= FSL_S_Data;
--sp <= sp + 1;
--stack(sp) <= indata;
newsp :=conv_std_logic_vector((conv_integer(sp) + 1)mod 32, 5);
sp <= newsp;
--check if full
if(newsp = (conv_integer(newrear)+31) mod 32)then
full<='1';
bstate<=SPILLING;
else
full<='0';
end if;
--check if empty
if(newsp = newrear)then
empty<='1';
bstate<=FILLING;
else
empty<='0';
end if;
if(newsp = (conv_integer(newrear)+31) mod 32)then
sum<=conv_std_logic_vector(100,32);
state <= Idle2;
else
sum <= conv_std_logic_vector(conv_integer(sp) + 1, 32);
state <= Idle;
end if;
elsif (unsigned(op) = 36) then -- ldloc.s
offset <= FSL_S_Data(27 to 31);
state <= Load_From_Stack1;
elsif (unsigned(op) = 41) then --ldarg.s
offset <= FSL_S_Data(27 to 31);
state <= Load_From_Stack1;
elsif (unsigned(op) = 46) then -- stloc.s
offset <= FSL_S_Data(27 to 31);
-- stack(conv_integer(localsStart) + conv_integer(FSL_S_Data(27 to 31))) <= a; -- a contains the TOS always
state <= Store_Into_Stack;
elsif (unsigned(op) = 47) then -- starg.s
offset <= FSL_S_Data(27 to 31);
-- stack(conv_integer(argsStart) + conv_integer(FSL_S_Data(27 to 31))) <= a; -- a contains the TOS always
state <= Store_Into_Stack;
else
sum <= "00011010001010101010101010101010";
state <= idle;
end if;
end if;
when DoBinOps =>
dummy :=sp;
sp<=dummy-1;
state <= Idle;
if(unsigned(op) = 4) then --add
stack(conv_integer(sp - 2)) <= a + b;
elsif(unsigned(op) = 5) then--sub
stack(conv_integer(sp-2)) <= b - a;
elsif(unsigned(op) = 58) then --and
stack (conv_integer(sp - 2)) <= a and b;
elsif(unsigned(op) = 59) then -- or
stack (conv_integer(sp - 2)) <= a or b;
elsif(unsigned(op) = 60) then --
stack (conv_integer(sp - 2)) <= a xor b;
end if;
when Load_Constants =>
stack(conv_integer(sp)) <= op and "00000000000000000000000000001111";
dummy :=sp;
sp<=dummy+1;
state <= idle;
when Pop =>
sum <= stack((conv_integer(sp)+31)mod 32);
--end if;
newsp :=conv_std_logic_vector((conv_integer(sp)+31)mod 32, 5);
sp <= newsp;
--check if empty
if(newsp= newrear)then
empty<='1';
bstate<=FILLING;
else
empty<='0';
end if;
--check if full
if(newsp = (conv_integer(newrear) +31)mod 32)then
full<='1';
bstate<=SPILLING;
else
full<='0';
end if;
if(newsp= newrear)then
sum <= conv_std_logic_vector(99999,32);
state <= idle2;
else
sum <= stack(conv_integer(sp - 1));
state <= Write_Outputs;
end if;
when Load_From_Stack1 =>
a <= stack (conv_integer(base + offset));
state <= Load_From_Stack2;
when Load_From_Stack2 =>
stack(conv_integer(sp)) <= a;
dummy :=sp;
sp<=dummy+1;
state <= idle;
when Store_Into_Stack =>
stack(conv_integer(base+offset)) <= a; -- a is TOS
dummy :=sp;
sp<=dummy-1;
state <= idle;
when GetLocsArgs=>
localsStart <= op(27 to 31);
argsStart <= op(19 to 23);
state <= idle;
when Write_Outputs =>
state <= idle;
end case;
end if;
--end if;
-- FSM For Spill fill handler
-- process (FSL_Clk)
--variable transfer1,transfer2,dummyinpush,dummyinpop, dummyinspill, dummyinfill : INTEGER range 0 to 127 :=0;
-- begin
case bstate is
when SPILLING=>
fillover<='0';
if (transfer1 < 16)then
if (not(((conv_integer(rear)+1) mod 32)= sp)) then
dummyinspill := transfer1 + 1;
transfer1 := dummyinspill;
dummyinspill := conv_integer(rear);
sum <= stack(dummyinspill);
if(full='1')then
full<='0';
end if;
newrear:= conv_std_logic_vector((dummyinspill+1)mod 32,5);
rear <= newrear;
dummyinspill := bsp + 1;
bsp <= dummyinspill;
else
transfer1:=16;
spillover<='1';
end if;
else
spillover <= '1';
transfer1 := 0;
end if;
-- push condition
--end push
--pop condition
-- end pop
if ((spillover='1') and not(newsp=newrear))then
--spillover<='1';
bstate<=STACK_AND_BS;
if(state=idle2)then
state<=Idle;
end if;
--spillover<='0';
end if;
-- end case SPILLING
--case FILLING
when FILLING=>
spillover<='0';
transfer1 := 0;
if ((transfer2 < 16)) then
if (not(bsp=0)) then
transfer2 := dummyinfill;
dummyinfill := bsp - 1;
bsp <= dummyinfill;
newrear := conv_std_logic_vector((conv_integer(rear)+31)mod 32,5);
stack(conv_integer(newrear))<= FSL_S_Data;
if(empty='1')then
empty<='0';
end if;
rear <= newrear;
else
transfer2:=16;
fillover<='1';
end if;
else
fillover <= '1';
transfer2 := 0;
end if;
-- push condition
-- FILLING --> STACK_AND_BS transition : filling over and BS is not empty
if((fillover='1')and (bsempty='0')and not(newsp=(conv_integer(newrear)+31)mod 32))then
if(state=Idle2)then
state<=Write_Outputs;
end if;
bstate<=STACK_AND_BS;
--fillover<='0';
empty<='0';
end if;
-- FILLING --> STACK_ONLY transition : filling over and BS is empty
if((bsempty='1')and(fillover='1') and not(newsp=(conv_integer(newrear)+31)mod 32))then
if(state=Idle2)then
state<=Write_Outputs;
end if;
bstate<=STACK_ONLY;
--fillover<='0';
empty<='0';
end if;
-- FILLING --> SPILLING transition : filling over and stack is empty
if((fillover='1') and (newsp=conv_std_logic_vector((conv_integer(newrear)+31)mod 32, 5))) then
--fillover<='0';
if(state=Idle2)then
state<=Write_Outputs;
end if;
bstate<=SPILLING;
end if;
-- end case FILLING
-- case STACK_ONLY
when STACK_ONLY=>
transfer1 := 0;
spillover<='0';
fillover <='0';
-- push condition
-- end pop
-- end case STACK_ONLY
-- case STACK_AND_BS
when STACK_AND_BS=>
transfer1 := 0;
spillover<='0';
fillover <='0';
-- end push
-- end case STACK_AND_BS
end case;
--end process;
end process The_SW_accelerator;
-- FSM for spill fill handler ends here
end architecture EXAMPLE;