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