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

Subversion Repositories potato

[/] [potato/] [trunk/] [src/] [pp_fetch.vhd] - Diff between revs 45 and 58

Only display areas with differences | Details | Blame | View Log

Rev 45 Rev 58
-- 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 ieee.numeric_std.all;
use ieee.numeric_std.all;
 
 
use work.pp_constants.all;
use work.pp_constants.all;
 
 
--! @brief Instruction fetch unit.
--! @brief Instruction fetch unit.
entity pp_fetch is
entity pp_fetch is
        generic(
        generic(
                RESET_ADDRESS : std_logic_vector(31 downto 0) := x"00000000"
                RESET_ADDRESS : std_logic_vector(31 downto 0)
        );
        );
        port(
        port(
                clk    : in std_logic;
                clk    : in std_logic;
                reset  : in std_logic;
                reset  : in std_logic;
 
 
                -- Instruction memory connections:
                -- Instruction memory connections:
                imem_address : out std_logic_vector(31 downto 0);
                imem_address : out std_logic_vector(31 downto 0);
                imem_data_in : in  std_logic_vector(31 downto 0);
                imem_data_in : in  std_logic_vector(31 downto 0);
                imem_req     : out std_logic;
                imem_req     : out std_logic;
                imem_ack     : in  std_logic;
                imem_ack     : in  std_logic;
 
 
                -- Control inputs:
                -- Control inputs:
                stall     : in std_logic;
                stall     : in std_logic;
                flush     : in std_logic;
                flush     : in std_logic;
                branch    : in std_logic;
                branch    : in std_logic;
                exception : in std_logic;
                exception : in std_logic;
 
 
                branch_target : in std_logic_vector(31 downto 0);
                branch_target : in std_logic_vector(31 downto 0);
                evec          : in std_logic_vector(31 downto 0);
                evec          : in std_logic_vector(31 downto 0);
 
 
                -- Outputs to the instruction decode unit:
                -- Outputs to the instruction decode unit:
                instruction_data    : out std_logic_vector(31 downto 0);
                instruction_data    : out std_logic_vector(31 downto 0);
                instruction_address : out std_logic_vector(31 downto 0);
                instruction_address : out std_logic_vector(31 downto 0);
                instruction_ready   : out std_logic
                instruction_ready   : out std_logic
        );
        );
end entity pp_fetch;
end entity pp_fetch;
 
 
architecture behaviour of pp_fetch is
architecture behaviour of pp_fetch is
        signal pc           : std_logic_vector(31 downto 0);
        signal pc           : std_logic_vector(31 downto 0);
        signal pc_next      : std_logic_vector(31 downto 0);
        signal pc_next      : std_logic_vector(31 downto 0);
        signal cancel_fetch : std_logic;
        signal cancel_fetch : std_logic;
begin
begin
 
 
        imem_address <= pc_next when cancel_fetch = '0' else pc;
        imem_address <= pc_next when cancel_fetch = '0' else pc;
 
 
        instruction_data <= imem_data_in;
        instruction_data <= imem_data_in;
        instruction_ready <= imem_ack and (not stall) and (not cancel_fetch);
        instruction_ready <= imem_ack and (not stall) and (not cancel_fetch);
        instruction_address <= pc;
        instruction_address <= pc;
 
 
        imem_req <= '1';
        imem_req <= '1';
 
 
        set_pc: process(clk)
        set_pc: process(clk)
        begin
        begin
                if rising_edge(clk) then
                if rising_edge(clk) then
                        if reset = '1' then
                        if reset = '1' then
                                pc <= RESET_ADDRESS;
                                pc <= RESET_ADDRESS;
                                cancel_fetch <= '0';
                                cancel_fetch <= '0';
                        else
                        else
                                if (exception = '1' or branch = '1') and imem_ack = '0' then
                                if (exception = '1' or branch = '1') and imem_ack = '0' then
                                        cancel_fetch <= '1';
                                        cancel_fetch <= '1';
                                        pc <= pc_next;
                                        pc <= pc_next;
                                elsif cancel_fetch = '1' and imem_ack = '1' then
                                elsif cancel_fetch = '1' and imem_ack = '1' then
                                        --pc <= pc_next;
                                        --pc <= pc_next;
                                        cancel_fetch <= '0';
                                        cancel_fetch <= '0';
                                else
                                else
                                        pc <= pc_next;
                                        pc <= pc_next;
                                end if;
                                end if;
                        end if;
                        end if;
                end if;
                end if;
        end process set_pc;
        end process set_pc;
 
 
        calc_next_pc: process(reset, stall, branch, exception, imem_ack, branch_target, evec, pc, cancel_fetch)
        calc_next_pc: process(reset, stall, branch, exception, imem_ack, branch_target, evec, pc, cancel_fetch)
        begin
        begin
                if exception = '1' then
                if exception = '1' then
                        pc_next <= evec;
                        pc_next <= evec;
                elsif branch = '1' then
                elsif branch = '1' then
                        pc_next <= branch_target;
                        pc_next <= branch_target;
                elsif imem_ack = '1' and stall = '0' and cancel_fetch = '0' then
                elsif imem_ack = '1' and stall = '0' and cancel_fetch = '0' then
                        pc_next <= std_logic_vector(unsigned(pc) + 4);
                        pc_next <= std_logic_vector(unsigned(pc) + 4);
                else
                else
                        pc_next <= pc;
                        pc_next <= pc;
                end if;
                end if;
        end process calc_next_pc;
        end process calc_next_pc;
 
 
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.