-- Albert Coba 1727 -- Shawn Nematbakhsh 8551 -- cs161 proj2: Datapath: -- a MIPS control -- this file is the main control unit, it sends signals out to the datapath library IEEE; use IEEE.std_logic_1164.all; use IEEE.std_logic_arith.all; entity Control is port( rst : in std_logic; clk : in std_logic; --control signals -- mux select lines feeding ALU alu_src_A : out std_logic; alu_src_B : out std_logic_vector( 1 downto 0 ); -- ALU op sent to ALU control to generate alu control signals alu_op : out std_logic_vector( 1 downto 0 ); -- register to write to in RF reg_write : out std_logic; -- mux feeding write reg line reg_dst : out std_logic; -- source for pc, either +4 or some branch pc_source : out std_logic_vector( 1 downto 0 ); -- output from the or gate, combining PCWriteCond and PCWrite pc_load : out std_logic; -- instruction or data, feeds memory i_or_d : out std_logic; -- read/write from/to memory signals mem_read : out std_logic; mem_write : out std_logic; -- write data signal, asserted to write data to reg mem_to_reg : out std_logic; -- write data to IR signal IR_write : out std_logic; -- input to control ins_31_26 : in std_logic_vector( 5 downto 0 ); -- input to PC write logic alu_zero : in std_logic ); end Control; architecture bhv of Control is type state_type is(S0,S1,S2,S3,S4,S5,S6,S7,S8,S9); signal state,next_state :state_type; begin -- bhv process (clk,rst) begin -- keep returning to state0 on reset if (rst = '1') then state <= S0; -- go to next state on new cycle elsif (clk = '1' and clk'event) then state <= next_state; end if; end process; -- state definitions process(rst,ins_31_26,alu_zero,state) begin -- go to S0 on reset if(rst='1') then next_state <=S0; else case state is -- state 0 : instruction fetch when S0 => -- assert/deassert necessary controls alu_src_A <= '0'; alu_src_B <= "01"; alu_op <= "00"; reg_write <= '0'; reg_dst <= '0'; pc_source <= "00"; pc_load <= '1'; i_or_d <= '0'; mem_read <= '1'; mem_write <= '0'; mem_to_reg <= '0'; IR_write <= '1'; next_state<=S1; -- state1: instruction decode/reg fetch when S1 => alu_src_A <= '0'; alu_src_B <= "11"; alu_op <= "00"; reg_write <= '0'; reg_dst <= '0'; pc_source <= "00"; pc_load <= '0'; i_or_d <= '0'; mem_read <= '0'; mem_write <= '0'; mem_to_reg <= '0'; IR_write <= '0'; -- depending on opcode, go to different state case ins_31_26 is when "100011" => next_state<=S2; when "101011" => next_state <= S2; when "000100" => next_state <= S8; when "000010" => next_state <= S9; when others => next_state <= S6; end case; -- state 2: memory address computation when S2 => alu_src_A <= '1'; alu_src_B <= "10"; alu_op <= "00"; reg_write <= '0'; reg_dst <= '0'; pc_source <= "00"; pc_load <= '0'; i_or_d <= '0'; mem_read <= '0'; mem_write <= '0'; mem_to_reg <= '0'; IR_write <= '0'; case ins_31_26 is -- depending on opcode, go to different state when "100011" => next_state<=S3; when "101011" => next_state<=S5; when others => end case; -- state3: memory access when S3 => alu_src_A <= '0'; alu_src_B <= "00"; alu_op <= "00"; reg_write <= '0'; reg_dst <= '0'; pc_source <= "00"; pc_load <= '0'; i_or_d <= '1'; mem_read <= '1'; mem_write <= '0'; mem_to_reg <= '0'; IR_write <= '0'; next_state <= S4; -- state4: memory read completion when S4 => alu_src_A <= '0'; alu_src_B <= "00"; alu_op <= "00"; reg_write <= '1'; reg_dst <= '0'; pc_source <= "00"; pc_load <= '0'; i_or_d <= '0'; mem_read <= '0'; mem_write <= '0'; mem_to_reg <= '1'; IR_write <= '0'; next_state <= S0; -- state5: memory access when S5 => alu_src_A <= '0'; alu_src_B <= "00"; alu_op <= "00"; reg_write <= '0'; reg_dst <= '0'; pc_source <= "00"; pc_load <= '0'; i_or_d <= '1'; mem_read <= '0'; mem_write <= '1'; mem_to_reg <= '0'; IR_write <= '0'; next_state <= S0; -- state6: execution when S6 => alu_src_A <= '1'; alu_src_B <= "00"; alu_op <= "10"; reg_write <= '0'; reg_dst <= '0'; pc_source <= "00"; pc_load <= '0'; i_or_d <= '0'; mem_read <= '0'; mem_write <= '0'; mem_to_reg <= '0'; IR_write <= '0'; next_state <= S7; -- state7: r-type completion when S7 => alu_src_A <= '0'; alu_src_B <= "00"; alu_op <= "00"; reg_write <= '1'; reg_dst <= '1'; pc_source <= "00"; pc_load <= '0'; i_or_d <= '0'; mem_read <= '0'; mem_write <= '0'; mem_to_reg <= '0'; IR_write <= '0'; next_state <= S0; -- state8: branch completion when S8 => alu_src_A <= '1'; alu_src_B <= "00"; alu_op <= "01"; reg_write <= '0'; reg_dst <= '0'; pc_source <= "01"; pc_load <= alu_zero; i_or_d <= '0'; mem_read <= '0'; mem_write <= '0'; mem_to_reg <= '0'; IR_write <= '0'; next_state <= S0; -- state9: jump completion when S9 => alu_src_A <= '0'; alu_src_B <= "00"; alu_op <= "00"; reg_write <= '0'; reg_dst <= '0'; pc_source <= "10"; pc_load <= '1'; i_or_d <= '0'; mem_read <= '0'; mem_write <= '0'; mem_to_reg <= '0'; IR_write <= '0'; next_state<=S0; when others => end case; end if; end process; end bhv;