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

Subversion Repositories potato

[/] [potato/] [trunk/] [src/] [pp_csr_unit.vhd] - Diff between revs 3 and 45

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

Rev 3 Rev 45
-- 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_csr.all;
use work.pp_csr.all;
 
 
entity pp_csr_unit is
entity pp_csr_unit is
        generic(
        generic(
                PROCESSOR_ID : std_logic_vector(31 downto 0)
                PROCESSOR_ID : std_logic_vector(31 downto 0)
        );
        );
        port(
        port(
                clk, timer_clk : in std_logic;
                clk, timer_clk : in std_logic;
                reset : in std_logic;
                reset : in std_logic;
 
 
                -- Count retired instruction:
                -- Count retired instruction:
                count_instruction : in std_logic;
                count_instruction : in std_logic;
 
 
                -- HTIF interface:
                -- HTIF interface:
                fromhost_data    : in  std_logic_vector(31 downto 0);
                fromhost_data    : in  std_logic_vector(31 downto 0);
                fromhost_updated : in  std_logic;
                fromhost_updated : in  std_logic;
                tohost_data      : out std_logic_vector(31 downto 0);
                tohost_data      : out std_logic_vector(31 downto 0);
                tohost_updated   : out std_logic;
                tohost_updated   : out std_logic;
 
 
                -- Read port:
                -- Read port:
                read_address   : in csr_address;
                read_address   : in csr_address;
                read_data_out  : out std_logic_vector(31 downto 0);
                read_data_out  : out std_logic_vector(31 downto 0);
                read_writeable : out boolean;
                read_writeable : out boolean;
 
 
                -- Write port:
                -- Write port:
                write_address : in csr_address;
                write_address : in csr_address;
                write_data_in : in std_logic_vector(31 downto 0);
                write_data_in : in std_logic_vector(31 downto 0);
                write_mode    : in csr_write_mode;
                write_mode    : in csr_write_mode;
 
 
                -- Exception context write port:
                -- Exception context write port:
                exception_context       : in csr_exception_context;
                exception_context       : in csr_exception_context;
                exception_context_write : in std_logic;
                exception_context_write : in std_logic;
 
 
                -- Registers needed for exception handling, always read:
                -- Registers needed for exception handling, always read:
                status_out : out csr_status_register;
                status_out : out csr_status_register;
                evec_out   : out std_logic_vector(31 downto 0)
                evec_out   : out std_logic_vector(31 downto 0)
        );
        );
end entity pp_csr_unit;
end entity pp_csr_unit;
 
 
architecture behaviour of pp_csr_unit is
architecture behaviour of pp_csr_unit is
 
 
        -- Implemented counters:
        -- Implemented counters:
        signal counter_time    : std_logic_vector(63 downto 0);
        signal counter_time    : std_logic_vector(63 downto 0);
        signal counter_cycle   : std_logic_vector(63 downto 0);
        signal counter_cycle   : std_logic_vector(63 downto 0);
        signal counter_instret : std_logic_vector(63 downto 0);
        signal counter_instret : std_logic_vector(63 downto 0);
 
 
        -- Implemented registers:
        -- Implemented registers:
        signal sup0, sup1 : std_logic_vector(31 downto 0) := (others => '0');
        signal sup0, sup1 : std_logic_vector(31 downto 0) := (others => '0');
        signal epc, evec  : std_logic_vector(31 downto 0) := (others => '0');
        signal epc, evec  : std_logic_vector(31 downto 0) := (others => '0');
        signal badvaddr   : std_logic_vector(31 downto 0) := (others => '0');
        signal badvaddr   : std_logic_vector(31 downto 0) := (others => '0');
        signal cause      : csr_exception_cause;
        signal cause      : csr_exception_cause;
 
 
        -- HTIF FROMHOST register:
        -- HTIF FROMHOST register:
        signal fromhost: std_logic_vector(31 downto 0);
        signal fromhost: std_logic_vector(31 downto 0);
 
 
        -- Status register:
        -- Status register:
        signal status_register : csr_status_register;
        signal status_register : csr_status_register;
 
 
begin
begin
 
 
        read_writeable <= csr_is_writeable(read_address);
        read_writeable <= csr_is_writeable(read_address);
 
 
        --! Updates the FROMHOST register when new data is available.
        --! Updates the FROMHOST register when new data is available.
        htif_fromhost: process(clk)
        htif_fromhost: process(clk)
        begin
        begin
                if rising_edge(clk) then
                if rising_edge(clk) then
                        if fromhost_updated = '1' then
                        if fromhost_updated = '1' then
                                fromhost <= fromhost_data;
                                fromhost <= fromhost_data;
                        end if;
                        end if;
                end if;
                end if;
        end process htif_fromhost;
        end process htif_fromhost;
 
 
        --! Sends a word to the host over the HTIF interface.
        --! Sends a word to the host over the HTIF interface.
        htif_tohost: process(clk)
        htif_tohost: process(clk)
        begin
        begin
                if rising_edge(clk) then
                if rising_edge(clk) then
                        if reset = '1' then
                        if reset = '1' then
                                tohost_data <= (others => '0');
                                tohost_data <= (others => '0');
                                tohost_updated <= '0';
                                tohost_updated <= '0';
                        else
                        else
                                if write_mode /= CSR_WRITE_NONE and write_address = CSR_TOHOST then
                                if write_mode /= CSR_WRITE_NONE and write_address = CSR_TOHOST then
                                        tohost_data <= write_data_in;
                                        tohost_data <= write_data_in;
                                        tohost_updated <= '1';
                                        tohost_updated <= '1';
                                else
                                else
                                        tohost_updated <= '0';
                                        tohost_updated <= '0';
                                end if;
                                end if;
                        end if;
                        end if;
                end if;
                end if;
        end process htif_tohost;
        end process htif_tohost;
 
 
        write: process(clk)
        write: process(clk)
        begin
        begin
                if rising_edge(clk) then
                if rising_edge(clk) then
                        if reset = '1' then
                        if reset = '1' then
                                status_register <= CSR_SR_DEFAULT;
                                status_register <= CSR_SR_DEFAULT;
                        else
                        else
                                if exception_context_write = '1' then
                                if exception_context_write = '1' then
                                        status_register <= exception_context.status;
                                        status_register <= exception_context.status;
                                        cause <= exception_context.cause;
                                        cause <= exception_context.cause;
                                        badvaddr <= exception_context.badvaddr;
                                        badvaddr <= exception_context.badvaddr;
                                end if;
                                end if;
 
 
                                if write_mode /= CSR_WRITE_NONE then
                                if write_mode /= CSR_WRITE_NONE then
                                        case write_address is
                                        case write_address is
                                                when CSR_STATUS =>
                                                when CSR_STATUS =>
                                                        if exception_context_write = '0' then
                                                        if exception_context_write = '0' then
                                                                status_register <= to_csr_status_register(write_data_in);
                                                                status_register <= to_csr_status_register(write_data_in);
                                                        end if;
                                                        end if;
                                                when CSR_EPC =>
                                                when CSR_EPC =>
                                                        epc <= write_data_in;
                                                        epc <= write_data_in;
                                                when CSR_EVEC =>
                                                when CSR_EVEC =>
                                                        evec <= write_data_in;
                                                        evec <= write_data_in;
                                                when CSR_SUP0 =>
                                                when CSR_SUP0 =>
                                                        sup0 <= write_data_in;
                                                        sup0 <= write_data_in;
                                                when CSR_SUP1 =>
                                                when CSR_SUP1 =>
                                                        sup1 <= write_data_in;
                                                        sup1 <= write_data_in;
                                                when others =>
                                                when others =>
                                                        -- Ignore writes to invalid or read-only registers
                                                        -- Ignore writes to invalid or read-only registers
                                        end case;
                                        end case;
                                end if;
                                end if;
                        end if;
                        end if;
                end if;
                end if;
        end process write;
        end process write;
 
 
 
        status_out <= exception_context.status when exception_context_write = '1' else status_register;
 
 
        read: process(clk)
        read: process(clk)
        begin
        begin
                if rising_edge(clk) then
                if rising_edge(clk) then
                        if exception_context_write  = '1' then
                        --if exception_context_write  = '1' then
                                status_out <= exception_context.status;
                        --      status_out <= exception_context.status;
                        else
                        --else
                                status_out <= status_register;
                        --      status_out <= status_register;
                        end if;
                        --end if;
 
 
                        if write_mode /= CSR_WRITE_NONE and write_address = CSR_EVEC then
                        if write_mode /= CSR_WRITE_NONE and write_address = CSR_EVEC then
                                evec_out <= write_data_in;
                                evec_out <= write_data_in;
                        else
                        else
                                evec_out <= evec;
                                evec_out <= evec;
                        end if;
                        end if;
 
 
                        if write_mode /= CSR_WRITE_NONE and write_address = read_address then
                        if write_mode /= CSR_WRITE_NONE and write_address = read_address then
                                read_data_out <= write_data_in;
                                read_data_out <= write_data_in;
                        else
                        else
                                case read_address is
                                case read_address is
 
 
                                        -- Status and control registers:
                                        -- Status and control registers:
                                        when CSR_STATUS => -- Status register
                                        when CSR_STATUS => -- Status register
                                                read_data_out <= to_std_logic_vector(status_register);
                                                read_data_out <= to_std_logic_vector(status_register);
                                        when CSR_HARTID => -- Processor ID
                                        when CSR_HARTID => -- Processor ID
                                                read_data_out <= PROCESSOR_ID;
                                                read_data_out <= PROCESSOR_ID;
                                        when CSR_FROMHOST => -- Fromhost data
                                        when CSR_FROMHOST => -- Fromhost data
                                                read_data_out <= fromhost;
                                                read_data_out <= fromhost;
                                        when CSR_EPC | CSR_EPC_SRET => -- Exception PC value
                                        when CSR_EPC | CSR_EPC_SRET => -- Exception PC value
                                                read_data_out <= epc;
                                                read_data_out <= epc;
                                        when CSR_EVEC => -- Exception handler address
                                        when CSR_EVEC => -- Exception handler address
                                                read_data_out <= evec;
                                                read_data_out <= evec;
                                        when CSR_CAUSE => -- Exception cause
                                        when CSR_CAUSE => -- Exception cause
                                                read_data_out <= to_std_logic_vector(cause);
                                                read_data_out <= to_std_logic_vector(cause);
                                        when CSR_BADVADDR => -- Load/store address responsible for the exception
                                        when CSR_BADVADDR => -- Load/store address responsible for the exception
                                                read_data_out <= badvaddr;
                                                read_data_out <= badvaddr;
 
 
                                        -- Supporting registers:
                                        -- Supporting registers:
                                        when CSR_SUP0 =>
                                        when CSR_SUP0 =>
                                                read_data_out <= sup0;
                                                read_data_out <= sup0;
                                        when CSR_SUP1 =>
                                        when CSR_SUP1 =>
                                                read_data_out <= sup1;
                                                read_data_out <= sup1;
 
 
                                        -- Timers and counters:
                                        -- Timers and counters:
                                        when CSR_TIME =>
                                        when CSR_TIME =>
                                                read_data_out <= counter_time(31 downto 0);
                                                read_data_out <= counter_time(31 downto 0);
                                        when CSR_TIMEH =>
                                        when CSR_TIMEH =>
                                                read_data_out <= counter_time(63 downto 32);
                                                read_data_out <= counter_time(63 downto 32);
                                        when CSR_CYCLE =>
                                        when CSR_CYCLE =>
                                                read_data_out <= counter_cycle(31 downto 0);
                                                read_data_out <= counter_cycle(31 downto 0);
                                        when CSR_CYCLEH =>
                                        when CSR_CYCLEH =>
                                                read_data_out <= counter_cycle(63 downto 32);
                                                read_data_out <= counter_cycle(63 downto 32);
                                        when CSR_INSTRET =>
                                        when CSR_INSTRET =>
                                                read_data_out <= counter_instret(31 downto 0);
                                                read_data_out <= counter_instret(31 downto 0);
                                        when CSR_INSTRETH =>
                                        when CSR_INSTRETH =>
                                                read_data_out <= counter_instret(63 downto 32);
                                                read_data_out <= counter_instret(63 downto 32);
 
 
                                        -- Return zero from write-only registers and invalid register addresses:
                                        -- Return zero from write-only registers and invalid register addresses:
                                        when others =>
                                        when others =>
                                                read_data_out <= (others => '0');
                                                read_data_out <= (others => '0');
                                end case;
                                end case;
                        end if;
                        end if;
                end if;
                end if;
        end process read;
        end process read;
 
 
        timer_counter: entity work.pp_counter
        timer_counter: entity work.pp_counter
                port map(
                port map(
                        clk => timer_clk,
                        clk => timer_clk,
                        reset => reset,
                        reset => reset,
                        count => counter_time,
                        count => counter_time,
                        increment => '1'
                        increment => '1'
                );
                );
 
 
        cycle_counter: entity work.pp_counter
        cycle_counter: entity work.pp_counter
                port map(
                port map(
                        clk => clk,
                        clk => clk,
                        reset => reset,
                        reset => reset,
                        count => counter_cycle,
                        count => counter_cycle,
                        increment => '1'
                        increment => '1'
                );
                );
 
 
        instret_counter: entity work.pp_counter
        instret_counter: entity work.pp_counter
                port map(
                port map(
                        clk => clk,
                        clk => clk,
                        reset => reset,
                        reset => reset,
                        count => counter_instret,
                        count => counter_instret,
                        increment => count_instruction
                        increment => count_instruction
                );
                );
 
 
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.