Loading files
This file is pinned to the selected release. Download the original to open it in your design tool.
-- The Potato Processor - A simple processor for FPGAs
-- (c) Kristian Klomsten Skordal 2014 - 2015 <kristian.skordal@wafflemail.net>
-- Report bugs and issues on <https://github.com/skordal/potato/issues>
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.pp_types.all;
use work.pp_constants.all;
use work.pp_csr.all;
--! @brief Instruction decode unit.
entity pp_decode is
generic(
RESET_ADDRESS : std_logic_vector(31 downto 0);
PROCESSOR_ID : std_logic_vector(31 downto 0)
);
port(
clk : in std_logic;
reset : in std_logic;
flush : in std_logic;
stall : in std_logic;
-- Instruction input:
instruction_data : in std_logic_vector(31 downto 0);
instruction_address : in std_logic_vector(31 downto 0);
instruction_ready : in std_logic;
instruction_count : in std_logic;
-- Register addresses:
rs1_addr, rs2_addr, rd_addr : out register_address;
csr_addr : out csr_address;
-- Shamt value for shift operations:
shamt : out std_logic_vector(4 downto 0);
funct3 : out std_logic_vector(2 downto 0);
-- Immediate value for immediate instructions:
immediate : out std_logic_vector(31 downto 0);
-- Control signals:
rd_write : out std_logic;
branch : out branch_type;
alu_x_src : out alu_operand_source;
alu_y_src : out alu_operand_source;
alu_op : out alu_operation;
mem_op : out memory_operation_type;
mem_size : out memory_operation_size;
count_instruction : out std_logic;
-- Instruction address:
pc : out std_logic_vector(31 downto 0);
-- CSR control signals:
csr_write : out csr_write_mode;
csr_use_imm : out std_logic;
-- Exception output signals:
decode_exception : out std_logic;
decode_exception_cause : out csr_exception_cause
);
end entity pp_decode;
architecture behaviour of pp_decode is
signal instruction : std_logic_vector(31 downto 0);
signal immediate_value : std_logic_vector(31 downto 0);
begin
immediate <= immediate_value;
get_instruction: process(clk)
begin
if rising_edge(clk) then
if reset = '1' then
instruction <= RISCV_NOP;
pc <= RESET_ADDRESS;
count_instruction <= '0';
elsif stall = '1' then
count_instruction <= '0';
elsif flush = '1' or instruction_ready = '0' then
instruction <= RISCV_NOP;
count_instruction <= '0';
else
instruction <= instruction_data;
count_instruction <= instruction_count;
pc <= instruction_address;
end if;
end if;
end process get_instruction;
-- -- Extract register addresses from the instruction word:
rs1_addr <= instruction(19 downto 15);
rs2_addr <= instruction(24 downto 20);
rd_addr <= instruction(11 downto 7);
-- Extract the shamt value from the instruction word:
shamt <= instruction(24 downto 20);
-- Extract the value specifying which comparison to do in branch instructions:
funct3 <= instruction(14 downto 12);
-- Extract the immediate value from the instruction word:
immediate_decoder: entity work.pp_imm_decoder
port map(
instruction => instruction(31 downto 2),
immediate => immediate_value
);
decode_csr_addr: process(immediate_value)
begin
if immediate_value(11 downto 0) = CSR_EPC_MRET then
csr_addr <= CSR_MEPC;
else
csr_addr <= immediate_value(11 downto 0);
end if;
end process decode_csr_addr;
control_unit: entity work.pp_control_unit
port map(
opcode => instruction(6 downto 2),
funct3 => instruction(14 downto 12),
funct7 => instruction(31 downto 25),
funct12 => instruction(31 downto 20),
rd_write => rd_write,
branch => branch,
alu_x_src => alu_x_src,
alu_y_src => alu_y_src,
alu_op => alu_op,
mem_op => mem_op,
mem_size => mem_size,
decode_exception => decode_exception,
decode_exception_cause => decode_exception_cause,
csr_write => csr_write,
csr_imm => csr_use_imm
);
end architecture behaviour;
404e6bb26This file is pinned to the selected release. Download the original to open it in your design tool.