You are on page 1of 7

DLX – MICROPROCESADOR (DATAPATH 3

)
RESUMEN JUAN PABLO GARCÍA
Ing. de Sistemas y Computación
Este informe describe los componentes básicos para la implementación de un Estudiante VII Semestre
microprocesador, basándose en el anterior taller (DATAPATH 2), se crearon Universidad Tecnológica de Pereira
nuevos módulos fueron y necesitaras varias modificaciones de módulos existente tamashii@gmail.com
para la implementación de este nuevo dispositivo (DATAPATH 3) que dispone
de un set de instrucciones más completo. Este taller será implementado en una JUAN PABLO GÓMEZ
FPGA. Ing. Sistemas y Computación
Estudiante VII Semestre
PALABRAS CLAVES: VHDL, FPGA, microprocesador, dispositivo, Universidad Tecnológica de Pereira
implementación, instrucciones. juanwalker@gmail.com

ABSTRACT
This report described the basic components for the implementation of a
microprocessor basing in lastest workshop DATAPATH 2, new modules are
created and may be changes in some existent modules for the implementation of
this new device (DATAPATH3) that develops a Set of more complete
instructions, and than finally will be implemented in the FPGA.

KEYWORDS: MIPS, VHDL, FPGA, MICROPROCESSOR

,.

1. INTRODUCCIÓN i_clk : in STD_LOGIC;
i_we : in STD_LOGIC;
Este tercer taller es la implementación final del o_dat : out STD_LOGIC_VECTOR (31 downto
procesador monociclo, fueron necesarios los 0));
conocimientos de las asignaturas de arquitectura de end DataMem;
computadores y de lab de arquitectura. El
comportamiento del datapath será descrito módulo por architecture Behavioral of DataMem is
módulo en el presente informe. Solo serán descritos
aquellos módulos del datapath 2 que fueron modificados, type RAM_type is array (0 to 511) of
y aquellos nuevos módulos. el cual, comparado con el std_logic_vector(31 downto 0);
DATAPATH2, contiene un set de instrucciones más signal RAM : RAM_type;
completo, con las cuales se puede implementar un signal addr_temp: STD_LOGIC_VECTOR (31 downto
programa para lenguaje ensamblador MIPS. 0);

begin
process (i_clk, i_addr)
2. CONTENIDO begin

1. Memoria de Datos addr_temp <= i_addr;
if (rising_edge(i_clk)) then
Descripción o_dat <= RAM(conv_integer(addr_temp(10
Es una memoria que permite almacenar downto 2)));
temporalmente datos, como si fuera una if (i_we = '1') then
memoria del sistema. RAM(conv_integer(addr_temp(10 downto 2)))
<= i_din;
Código end if;
end if;
entity DataMem is end process;
Port ( i_addr : in STD_LOGIC_VECTOR (31 downto
0); end Behavioral;
i_din : in STD_LOGIC_VECTOR (31 downto 0);
DLX–MICROPROCESADOR(DATAPATH 3) Noviembre/2006/6
2. Controlador de Program Counter: o_ext : out STD_LOGIC_VECTOR (31
downto 0));
Descripción end ext26b;

Recibe un tipo de salto y permite seleccionar architecture Behavioral of ext26b is
que señal recibe el program counter.
begin
Código process (i_dat)
begin
entity pccontrol is
Port ( i_pcsel : in STD_LOGIC_VECTOR (1 if (i_dat(25) = '1') then
downto 0); o_ext <= b"1111" & i_dat & b"00";
i_eq : in STD_LOGIC; else
o_pcsel : out STD_LOGIC_VECTOR (1 downto o_ext <= b"0000" & i_dat & b"00";
0)); end if;
end pccontrol;
end process;
architecture Behavioral of pccontrol is
end Behavioral;
begin
process (i_pcsel, i_eq) 4. Decodificador de Opcodes (modificado):
begin
Descripción
if (i_pcsel = "00") then -- cualquier instruccion
o_pcsel <= "00"; Permite controlar las diferentes señales del
elsif (i_pcsel = "01") then -- BEQ sistema dependiendo de la instrucción a la que
if (i_eq = '1') then es sometido.
o_pcsel <= "01";
else Código
o_pcsel <= "00";
end if; entity decopcode is
elsif (i_pcsel = "10") then -- J Port ( i_opcode : in std_logic_vector(5 downto 0);
o_pcsel <= "10"; i_funct : in std_logic_vector(5 downto 0);
elsif (i_pcsel = "11") then -- BNE o_aluctrl : out std_logic_vector(3 downto 0);
if (i_eq = '1') then o_alusrc : out std_logic;
o_pcsel <= "00"; o_regdest : out std_logic;
else o_regwr : out std_logic;
o_pcsel <= "11"; o_memwr : out std_logic;
end if; o_memtoreg : out std_logic;
end if; o_pcsrc : out std_logic_vector(1
downto 0)); -- 00 si contador regular, 01 si BEQ, 10 si J,
end process; 11 si reset.
end decopcode;
end Behavioral;
architecture Behavioral of decopcode is

3. Entendedor de Jump (de 26 bits a 32 bits): begin
process (i_opcode, i_funct)
Descripción begin
case i_opcode is
Recibe el numero de 26 bits de la instrucción J y when "000000" => -- tipo R
lo convierte a un numero de 32 bits . case i_funct is
when "000000" => o_aluctrl <= "1001"; -- SLL
Código when "000010" => o_aluctrl <= "1010"; -- SRL
when "100100" => o_aluctrl <= "0000"; -- AND
entity ext26b is when "100101" => o_aluctrl <= "0001"; -- OR
Port ( i_dat : in STD_LOGIC_VECTOR (25 when "100001" => o_aluctrl <= "0010"; --
downto 0); ADDU, era ADD (100000)

____________________________
DLX–MICROPROCESADOR(DATAPATH 3) Noviembre/2006/6
when "100011" => o_aluctrl <= "0110"; -- o_memtoreg <= '0';
SUBU, era SUB (100010) o_regwr <= '1';
when "101010" => o_aluctrl <= "0111"; -- SLT o_pcsrc <= "00";
when "100110" => o_aluctrl <= "1100"; -- XOR when "001110" => o_aluctrl <= "1100"; -- XORI
when others => o_aluctrl <= "0000"; o_alusrc <= '1';
end case; o_regdest <= '0';
o_alusrc <= '0'; o_memwr <= '0';
o_regdest <= '1'; o_memtoreg <= '0';
o_memwr <= '0'; o_regwr <= '1';
o_memtoreg <= '0'; o_pcsrc <= "00";
o_regwr <= '1'; when "100011" => o_aluctrl <= "1111"; -- LW
o_pcsrc <= "00"; o_alusrc <= '1';
when "000010" => o_aluctrl <= "0000"; -- J o_regdest <= '0';
o_alusrc <= '1'; o_memwr <= '0';
o_regdest <= '0'; o_memtoreg <= '1';
o_memwr <= '0'; o_regwr <= '1';
o_memtoreg <= '0'; o_pcsrc <= "00";
o_regwr <= '0'; when "101011" => o_aluctrl <= "1111"; -- SW
o_pcsrc <= "10"; o_alusrc <= '1';
when "000100" => o_aluctrl <= "0000"; -- BEQ o_regdest <= '0';
o_alusrc <= '1'; o_memwr <= '1';
o_regdest <= '0'; o_memtoreg <= '1';
o_memwr <= '0'; o_regwr <= '0';
o_memtoreg <= '0'; o_pcsrc <= "00";
o_regwr <= '0'; when others => o_aluctrl <= "0000"; --
o_pcsrc <= "01"; o_alusrc <= '1';
when "000101" => o_aluctrl <= "0000"; -- BNE o_regdest <= '0';
o_alusrc <= '1'; o_memwr <= '1';
o_regdest <= '0'; o_memtoreg <= '1';
o_memwr <= '0'; o_regwr <= '0';
o_memtoreg <= '0'; o_pcsrc <= "00";
o_regwr <= '0'; end case;
o_pcsrc <= "11"; end process;
when "001100" => o_aluctrl <= "0000"; -- ANDI
o_alusrc <= '1'; end Behavioral;
o_regdest <= '0';
o_memwr <= '0'; 5. ALU (Modificada):
o_memtoreg <= '0';
o_regwr <= '1'; Descripción
o_pcsrc <= "00";
when "001101" => o_aluctrl <= "0001"; -- ORI Este componente realiza los calculos lógicos que
o_alusrc <= '1'; se requieren por las operaciones soportadas por
o_regdest <= '0'; el sistema.
o_memwr <= '0';
o_memtoreg <= '0'; Código
o_regwr <= '1';
o_pcsrc <= "00"; entity alu32b is
when "001001" => o_aluctrl <= "0010"; -- ADDIU Port ( in_a : in std_logic_vector(31 downto 0);
o_alusrc <= '1'; in_b : in std_logic_vector(31 downto 0);
o_regdest <= '0'; in_s : in
o_memwr <= '0'; std_logic_vector(4 downto 0);
o_memtoreg <= '0'; in_funct : in std_logic_vector(3 downto 0);
o_regwr <= '1'; o_y : out std_logic_vector(31 downto 0);
o_pcsrc <= "00"; o_eq : out std_logic);
when "001010" => o_aluctrl <= "0111"; -- SLTI end alu32b;
o_alusrc <= '1';
o_regdest <= '0'; architecture Behavioral of alu32b is
o_memwr <= '0';

____________________________
DLX–MICROPROCESADOR(DATAPATH 3) Noviembre/2006/6
begin when "10101" => o_y <= in_b(10 downto
process (in_a, in_b, in_funct) 0) & "000000000000000000000";
begin when "10110" => o_y <= in_b(9 downto 0)
case in_funct is & "0000000000000000000000";
when "0000" => o_y <= in_a AND in_b; when "10111" => o_y <= in_b(8 downto 0)
when "0001" => o_y <= in_a OR in_b; & "00000000000000000000000";
when "0010" => o_y <= in_a + in_b; when "11000" => o_y <= in_b(7 downto 0)
when "0110" => o_y <= in_a - in_b; & "000000000000000000000000";
when "0111" => if (in_a < in_b) then when "11001" => o_y <= in_b(6 downto 0)
o_y <= (others => '1'); & "0000000000000000000000000";
else when "11010" => o_y <= in_b(5 downto 0)
o_y <= (others => '0'); & "00000000000000000000000000";
end if; when "11011" => o_y <= in_b(4 downto 0)
when "1100" => o_y <= in_a XOR in_b; & "000000000000000000000000000";
when "1001" => case in_s is when "11100" => o_y <= in_b(3 downto 0)
when "00000" => o_y <= in_b; & "0000000000000000000000000000";
when "00001" => o_y <= in_b(30 downto when "11101" => o_y <= in_b(2 downto 0)
0) & '0'; & "00000000000000000000000000000";
when "00010" => o_y <= in_b(29 downto when "11110" => o_y <= in_b(1 downto 0)
0) & "00"; & "000000000000000000000000000000";
when "00011" => o_y <= in_b(28 downto when "11111" => o_y <= in_b(0) &
0) & "000"; "0000000000000000000000000000000";
when "00100" => o_y <= in_b(27 downto when others => o_y <= in_b(0) &
0) & "0000"; "0000000000000000000000000000000";
when "00101" => o_y <= in_b(26 downto end case;
0) & "00000"; when "1010" => case in_s is
when "00110" => o_y <= in_b(25 downto when "00000" => o_y <= in_b;
0) & "000000"; when "00001" => o_y <= '0' & in_b(30
when "00111" => o_y <= in_b(24 downto downto 0);
0) & "0000000"; when "00010" => o_y <= "00" & in_b(29
when "01000" => o_y <= in_b(23 downto downto 0);
0) & "00000000"; when "00011" => o_y <= "000" & in_b(28
downto 0);
when "01001" => o_y <= in_b(22 downto when "00100" => o_y <= "0000" & in_b(27
0) & "000000000"; downto 0);
when "01010" => o_y <= in_b(21 downto
0) & "0000000000"; when "00101" => o_y <= "00000" &
when "01011" => o_y <= in_b(20 downto in_b(26 downto 0);
0) & "00000000000"; when "00110" => o_y <= "000000" &
when "01100" => o_y <= in_b(19 downto in_b(25 downto 0);
0) & "000000000000"; when "00111" => o_y <= "0000000" &
when "01101" => o_y <= in_b(18 downto in_b(24 downto 0);
0) & "0000000000000"; when "01000" => o_y <= "00000000" &
when "01110" => o_y <= in_b(17 downto in_b(23 downto 0);
0) & "00000000000000"; when "01001" => o_y <= "000000000" &
when "01111" => o_y <= in_b(16 downto in_b(22 downto 0);
0) & "000000000000000"; when "01010" => o_y <= "0000000000" &
when "10000" => o_y <= in_b(15 downto in_b(21 downto 0);
0) & "0000000000000000"; when "01011" => o_y <= "00000000000" &
when "10001" => o_y <= in_b(14 downto in_b(20 downto 0);
0) & "00000000000000000"; when "01100" => o_y <= "000000000000"
when "10010" => o_y <= in_b(13 downto & in_b(19 downto 0);
0) & "000000000000000000"; when "01101" => o_y <= "0000000000000"
when "10011" => o_y <= in_b(12 downto & in_b(18 downto 0);
0) & "0000000000000000000"; when "01110" => o_y <=
when "10100" => o_y <= in_b(11 downto "00000000000000" & in_b(17 downto 0);
0) & "00000000000000000000"; when "01111" => o_y <=
"000000000000000" & in_b(16 downto 0);

____________________________
DLX–MICROPROCESADOR(DATAPATH 3) Noviembre/2006/6
when "10000" => o_y <= Descripción
"0000000000000000" & in_b(15 downto 0);
when "10001" => o_y <= Es el modulo principal de todo el sistema .
"00000000000000000" & in_b(14 downto 0);
when "10010" => o_y <= Código
"000000000000000000" & in_b(13 downto 0);
when "10011" => o_y <= entity Datapath3 is
"0000000000000000000" & in_b(12 downto 0); Port ( i_clk : in std_logic;
when "10100" => o_y <= i_rst : in std_logic;
"00000000000000000000" & in_b(11 downto 0); i_we : in std_logic;
when "10101" => o_y <= i_sel : in std_logic_vector(1 downto
"000000000000000000000" & in_b(10 downto 0); 0);
when "10110" => o_y <= o_output: out std_logic_vector(7
"0000000000000000000000" & in_b(9 downto 0); downto 0);
when "10111" => o_y <= o_prueba: out std_logic_vector(3
"00000000000000000000000" & in_b(8 downto 0); downto 0));
when "11000" => o_y <= end Datapath3;
"000000000000000000000000" & in_b(7 downto
0); architecture Structural of Datapath3 is
when "11001" => o_y <=
"0000000000000000000000000" & in_b(6 downto component Datapath1 is
0); Port ( i_rst : in std_logic;
when "11010" => o_y <= i_clk : in std_logic;
"00000000000000000000000000" & in_b(5 downto i_en : in std_logic;
0); i_eq : in std_logic;
when "11011" => o_y <= i_pcsrc : in std_logic_vector(1 downto
"000000000000000000000000000" & in_b(4 0);
downto 0); i_offset : in std_logic_vector(25
when "11100" => o_y <= downto 0);
"0000000000000000000000000000" & in_b(3 o_data : out std_logic_vector(31 downto 0));
downto 0); end component;
when "11101" => o_y <=
"00000000000000000000000000000" & in_b(2 component Regfile is
downto 0); port(i_wd : in std_logic_vector(31 downto 0);
when "11110" => o_y <= -- Input Data
"000000000000000000000000000000" & in_b(1 i_ws : in std_logic_vector(4 downto 0);
downto 0); -- Input Address
when "11111" => o_y <= i_rs1 : in std_logic_vector(4 downto 0);
"0000000000000000000000000000000" & in_b(0); -- Output Address 1
when others => o_y <= i_rs2 : in std_logic_vector(4 downto 0);
"0000000000000000000000000000000" & in_b(0); -- Output Address 2
end case; i_we : in std_logic;
when "1111" => o_y <= in_a; -- Write Enable
when others => o_y <= (others => '1'); i_clk : in std_logic;
end case; -- Global Clk

if (in_a = in_b) then o_rd1 : out std_logic_vector(31 downto
o_eq <= '1'; 0); -- Output Data 1
else o_rd2 : out std_logic_vector(31 downto
o_eq <= '0'; 0) -- Output Data 2
end if; );
end process; end component;

end Behavioral; component alu32b is
Port ( in_a : in std_logic_vector(31 downto 0);
in_b : in std_logic_vector(31 downto 0);
6. Modulo principal (DATAPATH 3): in_s : in std_logic_vector(4 downto
0);

____________________________
DLX–MICROPROCESADOR(DATAPATH 3) Noviembre/2006/6
in_funct : in std_logic_vector(3 downto 0); i_d2 : in STD_LOGIC_VECTOR (7 downto
o_y : out std_logic_vector(31 downto 0); 0);
o_eq : out std_logic); i_d3 : in STD_LOGIC_VECTOR (7 downto
end component; 0);
i_sel : in STD_LOGIC_VECTOR (1 downto
component decopcode is 0);
Port ( i_opcode : in std_logic_vector(5 downto o_y : out STD_LOGIC_VECTOR (7 downto
0); 0));
i_funct : in std_logic_vector(5 downto 0); end component;
o_aluctrl : out std_logic_vector(3 downto 0);
o_alusrc : out std_logic; component DataMem is
o_regdest : out std_logic; Port ( i_addr : in STD_LOGIC_VECTOR (31
o_regwr : out std_logic; downto 0);
o_memwr : out std_logic; i_din : in STD_LOGIC_VECTOR (31
o_memtoreg : out std_logic; downto 0);
o_pcsrc : out std_logic_vector(1 i_clk : in STD_LOGIC;
downto 0)); i_we : in STD_LOGIC;
end component; o_dat : out STD_LOGIC_VECTOR (31
downto 0));
component extimmed is end component;
Port ( i_immed : in STD_LOGIC_VECTOR (15
downto 0); signal instruccion: std_logic_vector(31 downto 0);
o_ext : out STD_LOGIC_VECTOR (31 signal alures: std_logic_vector(31 downto 0);
downto 0)); signal aluoper: std_logic_vector(3 downto 0);
end component; signal alusrc, regdest, regwr, memwr, memtoreg,
alueq: STD_LOGIC;
component mux32b2a1 is signal pcsrc : std_logic_vector(1 downto 0);
Port ( i_a : in STD_LOGIC_VECTOR (31 signal add_ws: std_logic_vector(4
downto 0); downto 0);
i_b : in STD_LOGIC_VECTOR (31 downto signal dat_rd1, dat_rd2, dat_ext, dat_alu, dat_mem,
0); dat_2reg: std_logic_vector(31 downto 0);
i_sel : in STD_LOGIC; signal nuevoclk: std_logic;
o_y : out STD_LOGIC_VECTOR (31
downto 0)); begin
end component;
datapath: Datapath1 port map(i_rst => i_rst, i_clk =>
component mux5b2a1 is nuevoclk, o_data => instruccion, i_en => i_we,
Port ( i_a : in STD_LOGIC_VECTOR (4 downto i_pcsrc => pcsrc, i_offset => instruccion(25 downto
0); 0), i_eq => alueq);
i_b : in STD_LOGIC_VECTOR (4 downto decopcod: decopcode port map(i_opcode =>
0); instruccion(31 downto 26), i_funct => instruccion(5
i_sel : in STD_LOGIC; downto 0), o_aluctrl => aluoper, o_alusrc => alusrc,
o_y : out STD_LOGIC_VECTOR (4 downto o_regdest => regdest, o_memwr => memwr,
0)); o_memtoreg => memtoreg, o_pcsrc => pcsrc,
end component; o_regwr => regwr);
muxde5b: mux5b2a1 port map(i_a =>
component div_frec is instruccion(20 downto 16), i_b => instruccion(15
Port ( i_clk : in STD_LOGIC; downto 11), i_sel => regdest, o_y => add_ws);
i_rst : in STD_LOGIC; extinmed: extimmed port map(i_immed =>
o_clk : out STD_LOGIC); instruccion(15 downto 0), o_ext => dat_ext);
end component; regfle: Regfile port map(i_ws => add_ws, i_wd
=> dat_2reg, i_rs1 => instruccion(25 downto 21),
component mux8b4a1 is i_rs2 => instruccion(20 downto 16), i_we => regwr,
Port ( i_d0 : in STD_LOGIC_VECTOR (7 i_clk => nuevoclk, o_rd1 => dat_rd1, o_rd2 =>
downto 0); dat_rd2);
i_d1 : in STD_LOGIC_VECTOR (7 downto muxde32b: mux32b2a1 port map(i_a => dat_rd2, i_b
0); => dat_ext, i_sel => alusrc, o_y => dat_alu);

____________________________
DLX–MICROPROCESADOR(DATAPATH 3) Noviembre/2006/6
alu: alu32b port map(in_a => dat_rd1, in_b
=> dat_alu, in_s => instruccion(10 downto 6),
in_funct => aluoper, o_y => alures, o_eq => alueq);
datam : DataMem port map(i_addr => alures,
i_din => dat_rd2, i_clk => nuevoclk, i_we =>
memwr, o_dat => dat_mem);
divfrec: div_frec port map(i_clk => i_clk, i_rst =>
i_rst, o_clk => nuevoclk);
muxreg : mux32b2a1 port map(i_a => alures, i_b =>
dat_mem, i_sel => memtoreg, o_y => dat_2reg);
muxde8b: mux8b4a1 port map(i_d0 => alures(7
downto 0), i_d1 => alures(15 downto 8), i_d2 =>
alures(23 downto 16), i_d3 => alures(31
downto 24), i_sel => i_sel, o_y => o_output);

process (aluoper)
begin
o_prueba <= aluoper;
end process;

end Structural;

CONCLUSIONES Y RECOMENDACIONES

• El sistema tiene algunos problemas,
principalmente basados en las operaciones de
salto, ya que toman un ciclo adicional para
realizarse, sin comprometer los resultados de las
operaciones.
• Aunque el shift fue optimizado por el
sintetizador, la forma en que se aplicó es una
manera muy poco optimizada para realizarse.
• De resto, el sistema es capaz de incorporar todas
las demás funciones, sin problemas.

BIBLIOGRAFIA

*http://isc.utp.edu.co/~michaelm/
*MIPS Instruction Set Referente, http://www.mips.com/

____________________________