OpenCores
URL https://opencores.org/ocsvn/potato/potato/trunk

Subversion Repositories potato

[/] [potato/] [trunk/] [src/] [pp_alu_control_unit.vhd] - Diff between revs 3 and 14

Go to most recent revision | Only display areas with differences | Details | Blame | View Log

Rev 3 Rev 14
-- The Potato Processor - A simple processor for FPGAs
-- The Potato Processor - A simple processor for FPGAs
-- (c) Kristian Klomsten Skordal 2014 - 2015 <kristian.skordal@wafflemail.net>
-- (c) Kristian Klomsten Skordal 2014 - 2015 <kristian.skordal@wafflemail.net>
-- Report bugs and issues on <http://opencores.org/project,potato,bugtracker>
-- Report bugs and issues on <http://opencores.org/project,potato,bugtracker>
 
 
library ieee;
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_1164.all;
 
 
use work.pp_types.all;
use work.pp_types.all;
use work.pp_constants.all;
use work.pp_constants.all;
 
 
entity pp_alu_control_unit is
entity pp_alu_control_unit is
        port(
        port(
                opcode  : in std_logic_vector( 4 downto 0);
                opcode  : in std_logic_vector( 4 downto 0);
                funct3  : in std_logic_vector( 2 downto 0);
                funct3  : in std_logic_vector( 2 downto 0);
                funct7  : in std_logic_vector( 6 downto 0);
                funct7  : in std_logic_vector( 6 downto 0);
 
 
                -- Sources of ALU operands:
                -- Sources of ALU operands:
                alu_x_src, alu_y_src : out alu_operand_source;
                alu_x_src, alu_y_src : out alu_operand_source;
 
 
                -- ALU operation:
                -- ALU operation:
                alu_op : out alu_operation
                alu_op : out alu_operation
        );
        );
end entity pp_alu_control_unit;
end entity pp_alu_control_unit;
 
 
architecture behaviour of pp_alu_control_unit is
architecture behaviour of pp_alu_control_unit is
begin
begin
 
 
        decode_alu: process(opcode, funct3, funct7)
        decode_alu: process(opcode, funct3, funct7)
        begin
        begin
                case opcode is
                case opcode is
                        when b"01101" => -- Load upper immediate
                        when b"01101" => -- Load upper immediate
                                alu_x_src <= ALU_SRC_NULL;
                                alu_x_src <= ALU_SRC_NULL;
                                alu_y_src <= ALU_SRC_IMM;
                                alu_y_src <= ALU_SRC_IMM;
                                alu_op <= ALU_ADD;
                                alu_op <= ALU_ADD;
                        when b"00101" => -- Add upper immediate to PC
                        when b"00101" => -- Add upper immediate to PC
                                alu_x_src <= ALU_SRC_PC;
                                alu_x_src <= ALU_SRC_PC;
                                alu_y_src <= ALU_SRC_IMM;
                                alu_y_src <= ALU_SRC_IMM;
                                alu_op <= ALU_ADD;
                                alu_op <= ALU_ADD;
                        when b"11011" => -- Jump and link
                        when b"11011" => -- Jump and link
                                alu_x_src <= ALU_SRC_PC_NEXT;
                                alu_x_src <= ALU_SRC_PC_NEXT;
                                alu_y_src <= ALU_SRC_NULL;
                                alu_y_src <= ALU_SRC_NULL;
                                alu_op <= ALU_ADD;
                                alu_op <= ALU_ADD;
                        when b"11001" => -- Jump and link register
                        when b"11001" => -- Jump and link register
                                alu_x_src <= ALU_SRC_PC_NEXT;
                                alu_x_src <= ALU_SRC_PC_NEXT;
                                alu_y_src <= ALU_SRC_NULL;
                                alu_y_src <= ALU_SRC_NULL;
                                alu_op <= ALU_ADD;
                                alu_op <= ALU_ADD;
                        when b"11000" => -- Branch operations
                        when b"11000" => -- Branch operations
                                -- The funct3 field decides which type of branch comparison is
                                -- The funct3 field decides which type of branch comparison is
                                -- done; this is decoded in the branch comparator module.
                                -- done; this is decoded in the branch comparator module.
                                alu_x_src <= ALU_SRC_NULL;
                                alu_x_src <= ALU_SRC_NULL;
                                alu_y_src <= ALU_SRC_NULL;
                                alu_y_src <= ALU_SRC_NULL;
                                alu_op <= ALU_NOP;
                                alu_op <= ALU_NOP;
                        when b"00000" => -- Load instruction
                        when b"00000" => -- Load instruction
                                alu_x_src <= ALU_SRC_REG;
                                alu_x_src <= ALU_SRC_REG;
                                alu_y_src <= ALU_SRC_IMM;
                                alu_y_src <= ALU_SRC_IMM;
                                alu_op <= ALU_ADD;
                                alu_op <= ALU_ADD;
                        when b"01000" => -- Store instruction
                        when b"01000" => -- Store instruction
                                alu_x_src <= ALU_SRC_REG;
                                alu_x_src <= ALU_SRC_REG;
                                alu_y_src <= ALU_SRC_IMM;
                                alu_y_src <= ALU_SRC_IMM;
                                alu_op <= ALU_ADD;
                                alu_op <= ALU_ADD;
                        when b"00100" => -- Register-immediate operations
                        when b"00100" => -- Register-immediate operations
                                alu_x_src <= ALU_SRC_REG;
                                alu_x_src <= ALU_SRC_REG;
 
 
                                if funct3 = b"001" or funct3 = b"101" then
                                if funct3 = b"001" or funct3 = b"101" then
                                        alu_y_src <= ALU_SRC_SHAMT;
                                        alu_y_src <= ALU_SRC_SHAMT;
                                else
                                else
                                        alu_y_src <= ALU_SRC_IMM;
                                        alu_y_src <= ALU_SRC_IMM;
                                end if;
                                end if;
 
 
                                case funct3 is
                                case funct3 is
                                        when b"000" =>
                                        when b"000" =>
                                                alu_op <= ALU_ADD;
                                                alu_op <= ALU_ADD;
                                        when b"001" =>
                                        when b"001" =>
                                                alu_op <= ALU_SLL;
                                                alu_op <= ALU_SLL;
                                        when b"010" =>
                                        when b"010" =>
                                                alu_op <= ALU_SLT;
                                                alu_op <= ALU_SLT;
                                        when b"011" =>
                                        when b"011" =>
                                                alu_op <= ALU_SLTU;
                                                alu_op <= ALU_SLTU;
                                        when b"100" =>
                                        when b"100" =>
                                                alu_op <= ALU_XOR;
                                                alu_op <= ALU_XOR;
                                        when b"101" =>
                                        when b"101" =>
                                                if funct7 = b"0000000" then
                                                if funct7 = b"0000000" then
                                                        alu_op <= ALU_SRL;
                                                        alu_op <= ALU_SRL;
                                                else
                                                else
                                                        alu_op <= ALU_SRA;
                                                        alu_op <= ALU_SRA;
                                                end if;
                                                end if;
                                        when b"110" =>
                                        when b"110" =>
                                                alu_op <= ALU_OR;
                                                alu_op <= ALU_OR;
                                        when b"111" =>
                                        when b"111" =>
                                                alu_op <= ALU_AND;
                                                alu_op <= ALU_AND;
                                        when others =>
                                        when others =>
                                                alu_op <= ALU_NOP;
                                                alu_op <= ALU_INVALID;
                                end case;
                                end case;
                        when b"01100" => -- Register-register operations
                        when b"01100" => -- Register-register operations
                                alu_x_src <= ALU_SRC_REG;
                                alu_x_src <= ALU_SRC_REG;
                                alu_y_src <= ALU_SRC_REG;
                                alu_y_src <= ALU_SRC_REG;
 
 
                                case funct3 is
                                case funct3 is
                                        when b"000" =>
                                        when b"000" =>
                                                if funct7 = b"0000000" then
                                                if funct7 = b"0000000" then
                                                        alu_op <= ALU_ADD;
                                                        alu_op <= ALU_ADD;
                                                else
                                                else
                                                        alu_op <= ALU_SUB;
                                                        alu_op <= ALU_SUB;
                                                end if;
                                                end if;
                                        when b"001" =>
                                        when b"001" =>
                                                alu_op <= ALU_SLL;
                                                alu_op <= ALU_SLL;
                                        when b"010" =>
                                        when b"010" =>
                                                alu_op <= ALU_SLT;
                                                alu_op <= ALU_SLT;
                                        when b"011" =>
                                        when b"011" =>
                                                alu_op <= ALU_SLTU;
                                                alu_op <= ALU_SLTU;
                                        when b"100" =>
                                        when b"100" =>
                                                alu_op <= ALU_XOR;
                                                alu_op <= ALU_XOR;
                                        when b"101" =>
                                        when b"101" =>
                                                if funct7 = b"0000000" then
                                                if funct7 = b"0000000" then
                                                        alu_op <= ALU_SRL;
                                                        alu_op <= ALU_SRL;
                                                else
                                                else
                                                        alu_op <= ALU_SRA;
                                                        alu_op <= ALU_SRA;
                                                end if;
                                                end if;
                                        when b"110" =>
                                        when b"110" =>
                                                alu_op <= ALU_OR;
                                                alu_op <= ALU_OR;
                                        when b"111" =>
                                        when b"111" =>
                                                alu_op <= ALU_AND;
                                                alu_op <= ALU_AND;
                                        when others =>
                                        when others =>
                                                alu_op <= ALU_NOP;
                                                alu_op <= ALU_INVALID;
                                end case;
                                end case;
 
                        when b"00011" => -- Fence instructions, ignored
 
                                alu_x_src <= ALU_SRC_REG;
 
                                alu_y_src <= ALU_SRC_REG;
 
                                alu_op <= ALU_NOP;
                        when b"11100" => -- System instructions
                        when b"11100" => -- System instructions
                                alu_x_src <= ALU_SRC_CSR;
                                alu_x_src <= ALU_SRC_CSR;
                                alu_y_src <= ALU_SRC_NULL;
                                alu_y_src <= ALU_SRC_NULL;
                                alu_op <= ALU_ADD;
                                alu_op <= ALU_ADD;
                        when others =>
                        when others =>
                                alu_x_src <= ALU_SRC_REG;
                                alu_x_src <= ALU_SRC_REG;
                                alu_y_src <= ALU_SRC_REG;
                                alu_y_src <= ALU_SRC_REG;
                                alu_op <= ALU_NOP;
                                alu_op <= ALU_INVALID;
                end case;
                end case;
        end process decode_alu;
        end process decode_alu;
 
 
end architecture behaviour;
end architecture behaviour;
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.