All pastes #396079 Raw Edit

Stuff

public text v1 · immutable
·published 2007-03-15 14:20 UTC
rendered paste body
--
--  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;