--
-- Dalton Project
-- Roman Lysecky and Puneet Mehra
-- 07/14/98
-- Version 1.2
-- Notes: Only a subset of MIPS instructions have been implemented.
--	  Instruction do not follow the correct MIPS format.
--

--**************************************************************************--

library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.STD_LOGIC_ARITH.all;

--**************************************************************************--

entity MIPS is 
	port( clk : in STD_LOGIC;
	      rst : in STD_LOGIC;
              cs : in STD_LOGIC;
	      data : inout UNSIGNED(31 downto 0);
              addr : out UNSIGNED(22 downto 0);
              rd : out STD_LOGIC;
              wr : out STD_LOGIC;
	      rdy : in STD_LOGIC;
	      adr : out UNSIGNED(31 downto 0) );
end MIPS;

--**************************************************************************--

architecture BHV_MIPS of MIPS is

	--
	-- type declarations
	--
	subtype REG_TYPE is UNSIGNED(31 downto 0);
	type REG_FILE_TYPE is array(0 to 31) of REG_TYPE;
	type STATE_TYPE is ( IF_S, IF2_S, IF3_S, IDE_S, MEM_S, MEM_READ1_S,
			     MEM_READ2_S, WB_S );

	--
	-- constant declarations
	--
	constant Z_32 : UNSIGNED(31 downto 0) := 
		"ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ";

	constant Z_23 : UNSIGNED(22 downto 0) :=
		"ZZZZZZZZZZZZZZZZZZZZZZZ";

	constant C0_32 : UNSIGNED(31 downto 0) :=
		"00000000000000000000000000000000";

	constant C0_23 : UNSIGNED(22 downto 0) :=
		"00000000000000000000000";

	constant C1_32 : UNSIGNED(31 downto 0) :=
		"00000000000000000000000000000001";

	constant C1_23 : UNSIGNED(22 downto 0) :=
		"00000000000000000000001";

	constant C14_23 : UNSIGNED(22 downto 0) :=
		"00000000000000000001110";

	constant C4_32 : UNSIGNED(31 downto 0) :=
		"00000000000000000000000000000100";

	constant C2P1B_32 : UNSIGNED(31 downto 0) :=
		"10000000000000000000000000000000";

	constant LI      : UNSIGNED(3 downto 0) := "0000";
	constant MOV     : UNSIGNED(3 downto 0) := "0001";
	constant LOAD    : UNSIGNED(3 downto 0) := "0010";
	constant STORE   : UNSIGNED(3 downto 0) := "0011";
	constant GE      : UNSIGNED(3 downto 0) := "0100";
	constant JNZ     : UNSIGNED(3 downto 0) := "0101";
	constant ADD     : UNSIGNED(3 downto 0) := "0110";
	constant JMP     : UNSIGNED(3 downto 0) := "0111";
	constant NOP     : UNSIGNED(3 downto 0) := "1000";
	constant SHFL    : UNSIGNED(3 downto 0) := "1001";
	constant SHFR    : UNSIGNED(3 downto 0) := "1010";
	constant EQ	 : UNSIGNED(3 downto 0) := "1011";
	constant STOREI  : UNSIGNED(3 downto 0) := "1100";

	--
	-- signal declarations
	--
	signal state         : STATE_TYPE;
	signal reg_file      : REG_FILE_TYPE;
	signal pc_reg        : UNSIGNED(22 downto 0);
	signal inst_reg      : REG_TYPE;
	signal reg_write, mem_write, mem_read : STD_LOGIC;
	signal reg_data, mem_data : UNSIGNED(31 downto 0);
	signal mem_addr           : UNSIGNED(22 downto 0);	
	signal reg_num            : UNSIGNED(4 downto 0);
	signal init : STD_LOGIC;
begin

	process(clk, rst, cs, init)

		variable reg_data1, 
			 reg_data2, add_result : UNSIGNED(31 downto 0);

	begin

		if( rst = '1' ) then

			state <= IF_S;
			data <= Z_32;
			addr <= Z_23;
			rd <= 'Z';
			wr <= 'Z';
			init <= '0';
			pc_reg <= C0_23;	
			reg_file(0) <= C0_32;
			reg_data1 := C0_32;	
			reg_data2 := C0_32;
			add_result := C0_32;
			adr <= add_result;	

		elsif( cs = '0' ) then

			state <= IF_S;
			data <= Z_32;
			addr <= Z_23;
			rd <= 'Z';
			wr <= 'Z';
			init <= '1';
			adr <= add_result;	

		elsif( cs = '1' and init = '1' ) then

			--
			-- capture state
			--
			data <= Z_32;
			addr <= C0_23;
			rd <= '0';
			wr <= '0';
			init <= '0';
			state <= IF_S;
			adr <= add_result;	
	
		elsif( clk'event and clk = '1' ) then

			-- 
			-- steady state
			--

			data <= Z_32;
			addr <= Z_23;
			rd <= '0';
			wr <= '0';
			adr <= add_result;	
		
			case( state )  is
	
				when IF_S =>
		
					reg_write <= '0';
					mem_write <= '0';
					mem_read <= '0';

					if( rdy = '1' ) then

						addr <= pc_reg;
						data <= Z_32;
						rd <= '1';
						state <= IF2_S;
					else

						state <= IF_S;
					end if;
				
				when IF2_S =>
	
					reg_write <= '0';
					mem_write <= '0';
					mem_read <= '0';

					state <= IF3_S;

				when IF3_S =>

					reg_write <= '0';
					mem_write <= '0';
					mem_read <= '0';

					if( rdy = '1' ) then

						inst_reg <= data;
						pc_reg <= pc_reg + C1_23;
						state <= IDE_S;
					else

						state <= IF3_S;
					end if;

				when IDE_S =>

					reg_write <= '0';
					mem_write <= '0';
					mem_read <= '0';

					case( inst_reg(31 downto 28) ) is
			
					when LI =>

						reg_write <= '1';
						mem_write <= '0';
						mem_read <= '0';
						reg_data <= "000000000" 
                                                            & inst_reg(22 downto 0);
						reg_num <= inst_reg(27 downto 23);
						state <= MEM_S;

					when MOV =>
							
						reg_write <= '1';
						mem_write <= '0';
						mem_read <= '0';
						reg_data <= reg_file(
						        conv_integer(inst_reg(22 downto 18)));
						reg_num <= inst_reg(27 downto 23);
						state <= MEM_S;

					when LOAD =>

						reg_write <= '1';
						mem_write <= '0';
						mem_read <= '1';
						reg_num <= inst_reg(27 downto 23);
						mem_addr <= inst_reg(22 downto 0);
						state <= MEM_S;
	
					when STORE =>

						reg_write <= '0';
						mem_write <= '1';
						mem_read <= '0';
						mem_addr <= inst_reg(22 downto 0);
						mem_data <= reg_file(
							conv_integer(inst_reg(27 downto 23)));
						state <= MEM_S;

					when STOREI =>

						reg_write <= '0';
						mem_write <= '1';
						mem_read <= '0';
						mem_addr <= reg_file(conv_integer
						    (inst_reg(22 downto 18)))
						    (22 downto 0);
						mem_data <= reg_file(
							conv_integer(inst_reg(27 downto 23)));
						state <= MEM_S;

					when GE =>

						reg_write <= '1';
						mem_write <= '0';
						mem_read <= '0';
						reg_num <= inst_reg(27 downto 23);
						if(reg_file(conv_integer
						   (inst_reg(22 downto 18))) >= reg_file(
						   conv_integer(inst_reg(17 downto 13)))) then

							reg_data <= C1_32;
						else

							reg_data <= C0_32;
						end if;
						state <= MEM_S;

					when EQ =>

						reg_write <= '1';
						mem_write <= '0';
						mem_read <= '0';
						reg_num <= inst_reg(27 downto 23);
						if(reg_file(conv_integer
						   (inst_reg(22 downto 18))) = reg_file(
						   conv_integer(inst_reg(17 downto 13)))) then

							reg_data <= C1_32;
						else

							reg_data <= C0_32;
						end if;
						state <= MEM_S;

					when JNZ =>

						reg_write <= '0';
						mem_write <= '0';
						mem_read <= '0';
						if( reg_file(conv_integer(
						    inst_reg(27 downto 23))) /= C0_23 ) then

							pc_reg <= inst_reg(22 downto 0);
						end if;
						state <= MEM_S;

					when ADD =>

						reg_write <= '1';
						mem_write <= '0';
						mem_read <= '0';
						reg_num <= inst_reg(27 downto 23);
						reg_data1 := reg_file(
							     conv_integer(inst_reg(22 downto 18)));
						reg_data2 := reg_file(
							     conv_integer(inst_reg(17 downto 13)));

						add_result := reg_data1 + reg_data2;
						reg_data <= add_result;

--reg_file(
--							conv_integer(inst_reg(22 downto 18)))
--						        + reg_file(conv_integer
--							(inst_reg(17 downto 13)));
						state <= MEM_S;
						
					when JMP =>

						reg_write <= '0';
						mem_write <= '0';
						mem_read <= '0';
						pc_reg <= inst_reg(22 downto 0);
						state <= MEM_S;

					when NOP =>
		
						reg_write <= '0';
						mem_write <= '0';
						mem_read <= '0';
						state <= MEM_S;

					when SHFL =>

						reg_write <= '1';
						mem_write <= '0';
						mem_read <= '0';
						reg_num <= inst_reg(27 downto 23);
						reg_data <= SHL(reg_file(
						    conv_integer(inst_reg(27 downto 23))), 
						    inst_reg(22 downto 18));
						state <= MEM_S;

					when SHFR =>

						reg_write <= '1';
						mem_write <= '0';
						mem_read <= '0';
						reg_num <= inst_reg(27 downto 23);
						reg_data <= SHR(reg_file(
						    conv_integer(inst_reg(27 downto 23))), 
						    inst_reg(22 downto 18));
						state <= MEM_S;

					when others =>
			
						null;
					end case;
								
				when MEM_S =>
		
					if(rdy='1' and mem_read = '1') then

						data <= Z_32;
						addr <= mem_addr;
						rd <= '1';
						mem_read <= '0';
						mem_write <= '0';
						state <= MEM_READ1_S;
	
					elsif(rdy='1' and mem_write='1') then

						data <= mem_data;
						addr <= mem_addr;
						wr <= '1';
						mem_read <= '0';
						mem_write <= '0';
						state <= WB_S;

					elsif( rdy = '1' ) then

						state <= WB_S;
					else
						
						state <= MEM_S;
					end if;

				when MEM_READ1_S =>
		
					state <= MEM_READ2_S;	

				when MEM_READ2_S =>

					if( rdy = '1' ) then

						reg_data <= data;
						state <= WB_S;
					else

						state <= MEM_READ2_S;
					end if;
					
				when WB_S =>

					if( reg_write = '1' ) then

						reg_file(conv_integer(reg_num))
						    <= reg_data;
						reg_write <= '0';
					end if;
					
					state <= IF_S;

				when others =>

					state <= IF_S;
			end case;
		end if;
	end process;
end BHV_MIPS;

--**************************************************************************--

configuration CFG_MIPS of MIPS is
	for BHV_MIPS
	end for;
end CFG_MIPS;

--**************************************************************************--

-- end of file --





<div align="center"><br /><script type="text/javascript"><!--
google_ad_client = "pub-7293844627074885";
//468x60, Created at 07. 11. 25
google_ad_slot = "8619794253";
google_ad_width = 468;
google_ad_height = 60;
//--></script>
<script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script><br />&nbsp;</div>