Designing a 32-bit MIPS single cycle processor to implement R-type and I-type formats. Each component of the processor was created using Quartus II VHDL software. The processor consisted of a PC, instruction memory, multiplexers, registers, ALUs, data memory, a sign extender, a shift left 2, and control units for## the ALU and the processor. Each component was emulated and tested for functionality. Once all components were confirmed to function properly, the processor was assembled using a Quartus II block schematic that was made up of block symbols of each component of the full data path. The assembled processor was compiled successfully and verified to work properly.
Using Altera Quartus to design a 32-bit MIPS single cycle processor. The processor is built to implement R-type and I-type formats for MIPS commands. The full data path consists of a PC, instruction memory, registers, ALUs, multiplexers, data memory, a sign extender, a shift left 2, and controls for the ALU and processor. Each component was designed using Quartus II VHDL and emulated with timing simulations to test for functionality.
The VHDL for each component was written to emulate the component’s functionality to assemble the circuit for the processor. The components were tested using timing simulations to verify the functionality of each component. The assembled processor was built using an Altera Quartus block diagram. The schematic was compiled and tested.
Figure 1. Full Data Path of MIPS Processor.
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.STD_LOGIC_UNSIGNED.all;
entity MUX is
port(A, B : IN STD_LOGIC_VECTOR (31 downto 0);
S : IN STD_LOGIC;
R : OUT STD_LOGIC_VECTOR (31 downto 0));
end MUX;
architecture behavior of MUX IS
begin
process(A, B, S)
begin
if S = '0' then
R <= A;
else
R <= B;
end if;
end process;
end behavior;
Figure 2. VHDL and Timing Simulation of 2-1 Multiplexers.
library IEEE;
use IEEE.STD_LOGIC_1164.all;
entity mux5 IS
port(A, B : IN STD_LOGIC_VECTOR(4 downto 0);
S : IN STD_LOGIC;
R : OUT STD_LOGIC_VECTOR(4 downto 0));
end mux5;
architecture behavior of mux5 IS
begin
with s select
R <= A when '0',
B when '1';
end behavior;
Figure 3. VHDL and Timing Simulation of a 5 Multiplexer
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity SHIFT_LEFT2 IS
port(A : IN STD_LOGIC_VECTOR (31 downto 0);
B : OUT STD_LOGIC_VECTOR (31 downto 0));
end SHIFT_LEFT2;
architecture behavior of SHIFT_LEFT2 IS
begin
B <= A(29 downto 0) & "00";
end behavior;
Figure 4. VHDL and Timing Simulation of Shift Left 2.
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity Sign_extend IS
port(A : IN STD_LOGIC_VECTOR (15 downto 0);
R : OUT STD_LOGIC_VECTOR (31 downto 0));
end Sign_extend;
architecture behavior of Sign_extend IS
begin
R <= (X"0000" & A) WHEN A(15) = '0' ELSE
(X"ffff" & A);
end behavior;
Figure 5. VHDL and Timing Simulation for Sign Extender.
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
use IEEE.NUMERIC_STD.ALL;
entity REGFILE IS
port(
clock : IN STD_LOGIC_VECTOR (4 DOWNTO 0);
read_reg1 : IN STD_LOGIC_VECTOR (4 DOWNTO 0);
read_reg2 : IN STD_LOGIC_VECTOR (4 DOWNTO 0);
write_reg : IN STD_LOGIC_VECTOR (4 DOWNTO 0);
write_data : IN STD_LOGIC_VECTOR (31 DOWNTO 0);
reg_write : IN STD_LOGIC;
read_data1 : OUT STD_LOGIC_VECTOR (31 DOWNTO 0);
read_data2 : OUT STD_LOGIC_VECTOR (31 DOWNTO 0));
end REGFILE;
architecture behavior of REGFILE IS
TYPE reg_file_type IS array(0 to 3) OF STD_LOGIC_VECTOR (31 DOWNTO 0);
signal array_reg : reg_file_type := (X"00000000",
X"11111111",
X"22222222",
X"33333333");
begin
process(clock, reg_write) THEN
begin
if RISING_EDGE(clock) THEN
if (reg_write = '1') THEN
array_reg (TO_INTEGER(UNSIGNED(write_reg))) <= write_data;
end if;
end if;
end process;
read_data1 <= array_reg (TO_INTEGER(UNSIGNED(read_reg1)));
read_data2 <= array_reg (TO_INTEGER(UNSIGNED(read_reg2)));
end behavior;
Figure 6. VHDL and Timing Simulation of Register File.
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity ALU_CONTROL IS
port(INPUT : IN STD_LOGIC_VECTOR(5 DOWNTO 0);
OPCODE : IN STD_LOGIC_VECTOR(1 DOWNTO 0);
OUTPUT : OUT STD_LOGIC_VECTOR(3 DOWNTO 0));
end ALU_CONTROL;
architecture behavior of ALU_CONTROL IS
begin
process(OPCODE, INPUT)
begin
case(OPCODE) IS
WHEN "00" => OUTPUT <= "1000"; --ADD COMMAND
WHEN "01" => OUTPUT <= "0110"; --SUB COMMAND
WHEN "10" => CASE (INPUT) IS --R TYPE COMMANDS
WHEN "100000" => OUTPUT <= "1000";
WHEN "100010" => OUTPUT <= "0110";
WHEN "100100" => OUTPUT <= "0010";
WHEN "100101" => OUTPUT <= "0100";
WHEN "101010" => OUTPUT <= "1001";
WHEN OTHERS => OUTPUT <= "0000";
END CASE;
WHEN OTHERS => OUTPUT <= "1000";
END CASE;
END PROCESS;
END behavior;
Figure 7. VHDL and Timing Simulation of ALU Control Unit.
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
use IEEE.NUMERIC_STD.ALL;
entity IM IS
port(CLOCK : IN STD_LOGIC;
READADD : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
INSTOUT : OUT STD_LOGIC_VECTOR(31 DOWNTO 0));
end IM;
architecture behavioral of IM IS
type RAM_IM IS ARRAY(0 TO 3) OF STD_LOGIC_VECTOR(31 DOWNTO 0);
SIGNAL InstMem : RAM_IM := (X"01285024", --AND t2, t1, t0
X"018B6825", --OR t%, t4, t3
X"01285020", --AND t2, t1, t0
X"2108000A"); --addi t0, t0, l0
begin
process(CLOCK)
begin
if RISING_EDGE(CLOCK) THEN
INSTOUT <= INSTMEM((TO_INTEGER(UNSIGNED(READADD))));
end if;
end process;
end behavioral;
Figure 8. VHDL and Timing Simulation for Instruction Memory.
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
use IEEE.NUMERIC_STD.ALL;
entity PC IS
port(CLOCK : IN STD_LOGIC;
PCADD : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
IMADD : OUT STD_LOGIC_VECTOR(31 DOWNTO 0));
end PC;
architecture behavioral of PC IS
signal X : STD_LOGIC := '0';
begin
process(CLOCK, PCADD, X)
begin
if RISING_EDGE(CLOCK) THEN
if X = '0' THEN
IMADD <= X"00000000";
X <= '1';
ELSEIF (X = '1') THEN
IMADD <= PCADD;
END IF;
end if;
end process;
end behavioral;
Figure 9. VHDL and Timing Simulation for PC.
library IEEE;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity DM IS
port(clock : IN STD_LOGIC;
address : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
write_data : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
mem_read : IN STD_LOGIC;
mem_write : IN STD_LOGIC;
read_data : OUT STD_LOGIC_VECTOR(31 DOWNTO 0));
end DM;
architecture behavioral of DM IS
type RAM_DM IS array(0 to 4 -1) of STD_LOGIC_VECTOR(31 DOWNTO 0);
signal DM : RAM_DM := (X"00000000",
X"00000001",
X"00000005"
X"00000000");
begin
process(mem_write, mem_read, clock)
begin
if RISING_EDGE(clock) THEN
if(mem_write = '1') THEN
DM((TO_INTEGER(UNSIGNED(address)))) <= write_data;
end if;
end if;
end process;
end behavioral;
Figure 10. VHDL and Timing Simulation for Data Memory.
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity ALU IS
Port(A, B : in STD_LOGIC_VECTOR (31 downto 0);
OPCODE : in STD_LOGIC_VECTOR (3 downto 0);
R : out STD_LOGIC_VECTOR (31 downto 0));
Zero : out stdlogic
end ALU;
architecture behavior of ALU IS
begin
process (A, B, OPCODE) IS
begin
case OPCODE IS
-- Logical Operations
when "0000" =>
R <= NOT(A);
when "0001" =>
R <= NOT(B);
when "0010" =>
R <= A AND B;
when "0011" =>
R <= A NAND B;
when "0100" =>
R <= A OR B;
when "0101" =>
R <= A NOR B;
when "0110" =>
R <= A XOR B;
when "0111" =>
R <= A XNOR B;
-- Arithmetic Operations
when "1000" =>
R <= A + B;
when "1001" =>
if A < B then
R <= "00000000000000000000000000000001";
else
R <= "00000000000000000000000000000000";
end if;
when "1010" =>
R <= A + "00000000000000000000000000000001";
when "1011" =>
R <= A - "00000000000000000000000000000001";
when "1100" =>
R <= B + "00000000000000000000000000000001";
when "1101" =>
R <= B - "00000000000000000000000000000001";
when "1110" =>
R <= NOT(A) + "00000000000000000000000000000001";
when "1111" =>
R <= NOT(B) + "00000000000000000000000000000001";
end case;
end process;
end behavior;
Figure 11. VHDL and Timing Simulation of ALU.
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.NUMERIC_STD.all;
entity Main_Control IS
port( OPCODE : IN STD_LOGIC_VECTOR(5 DOWNTO 0);
REGDEST : OUT STD_LOGIC;
MEMREAD : OUT STD_LOGIC;
MEMWRITE : OUT STD_LOGIC;
MEMTOREG : OUT STD_LOGIC;
ALUOP : OUT STD_LOGIC_VECTOR(1 DOWNTO 0);
ALUSRC : OUT STD_LOGIC;
BRANCH : OUT STD_LOGIC;
REGWRITE : OUT STD_LOGIC);
end Main_Control;
architecture behavioral of Main_Control IS
begin
process(OPCODE)
begin
REGWRITE <= '0';
case OPCODE IS
WHEN "000000" => -- ALL R-TYPE
REGDEST <= '0';
MEMREAD <= '0';
MEMWRITE <= '0';
MEMTOREG <= '0';
ALUOP <= "10";
ALUSRC <= '0';
REGWRITE <= '1' AFTER 10ns;
BRANCH <= '0';
WHEN "100011" => -- FOR LW INTRUCTIONS
REGDEST <= '0';
MEMREAD <= '1';
MEMWRITE <= '0';
MEMTOREG <= '1';
ALUOP <= "00";
ALUSRC <= '1';
REGWRITE <= '1' AFTER 10ns;
BRANCH <= '0';
WHEN "101011" => --FOR SW INSTRUCTIONS
REGDEST <= '1';
MEMREAD <= '0';
MEMWRITE <= '1';
MEMTOREG <= '0';
ALUOP <= "00";
ALUSRC <= '1';
REGWRITE <= '0' AFTER 10ns;
BRANCH <= '0';
WHEN "000100" => --FOR BEQ INSTRUCTIONS
REGDEST <= '0';
MEMREAD <= '0';
MEMWRITE <= '0';
MEMTOREG <= '0';
ALUOP <= "10";
ALUSRC <= '0';
REGWRITE <= '0' AFTER 10ns;
BRANCH <= '1';
WHEN OTHERS => NULL;
REGDEST <= '0';
MEMREAD <= '0';
MEMWRITE <= '0';
MEMTOREG <= '0';
ALUOP <= "00";
ALUSRC <= '0';
REGWRITE <= '0';
BRANCH <= '0';
END CASE;
END PROCESS;
end behavioral;
Figure 12. VHDL and Timing Simulation for Main Control Unit.
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity adder IS
port(A, B : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
R : OUT STD_LOGIC_VECTOR(31 DOWNTO 0));
end adder;
architecture behavior of adder IS
begin
R <= A + B;
end behavior;
Figure 13. VHDL and Timing Simulation for Adder.
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity add4 IS
port(A : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
R : OUT STD_LOGIC_VECTOR(31 DOWNTO 0));
end add4;
architecture add4 IS
begin
R <= A + "X0100";
end behavior;
Figure 14. VHDL and Timing Simulation for Add4.
Figure 15. Assembled 32-bit MIPS Single Cycle Processor.
The timing simulations for all the components for the 32-bit MIPS single cycle processor was verified to be operating correctly and producing the expected output. The assembled circuit for the processor was compiled successfully and was verified to be operating correctly.
The project was overall successful. The components of the processor worked individually and together with the assembled processor circuit. This was the result of the course goal of learning computer architecture and analyzing/designing simple computers.
None.