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

Subversion Repositories potato

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

Show entire file | Details | Blame | View Log

Rev 45 Rev 58
Line 5... Line 5...
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;
 
use work.pp_utilities.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;
 
 
 
                -- IRQ signals:
 
                irq : in std_logic_vector(7 downto 0);
 
 
                -- 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);
Line 37... Line 41...
 
 
                -- 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;
 
 
 
                -- Interrupts originating from this unit:
 
                software_interrupt_out : out std_logic;
 
                timer_interrupt_out    : out std_logic;
 
 
                -- Registers needed for exception handling, always read:
                -- Registers needed for exception handling, always read:
                status_out : out csr_status_register;
                mie_out         : out std_logic_vector(31 downto 0);
                evec_out   : out std_logic_vector(31 downto 0)
                mtvec_out       : out std_logic_vector(31 downto 0);
 
                ie_out, ie1_out : out std_logic
        );
        );
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:
        -- 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:
        -- Machine time counter:
        signal sup0, sup1 : std_logic_vector(31 downto 0) := (others => '0');
        signal counter_mtime : std_logic_vector(31 downto 0);
        signal epc, evec  : std_logic_vector(31 downto 0) := (others => '0');
        signal mtime_compare : std_logic_vector(31 downto 0);
        signal badvaddr   : std_logic_vector(31 downto 0) := (others => '0');
 
        signal cause      : csr_exception_cause;
        -- Machine-mode registers:
 
        signal mcause   : csr_exception_cause;
 
        signal mbadaddr : std_logic_vector(31 downto 0);
 
        signal mscratch : std_logic_vector(31 downto 0);
 
        signal mepc     : std_logic_vector(31 downto 0);
 
        signal mtvec    : std_logic_vector(31 downto 0) := x"00000100";
 
        signal mie      : std_logic_vector(31 downto 0) := (others => '0');
 
 
 
        -- Interrupt enable bits:
 
        signal ie, ie1    : std_logic;
 
 
        -- HTIF FROMHOST register:
        -- HTIF FROMHOST register:
        signal fromhost: std_logic_vector(31 downto 0);
        signal fromhost: std_logic_vector(31 downto 0);
 
 
        -- Status register:
        -- Interrupt signals:
        signal status_register : csr_status_register;
        signal timer_interrupt    : std_logic;
 
        signal software_interrupt : std_logic;
 
 
begin
begin
 
 
        read_writeable <= csr_is_writeable(read_address);
        -- Interrupt signals:
 
        software_interrupt_out <= software_interrupt;
 
        timer_interrupt_out <= timer_interrupt;
 
        ie_out <= ie;
 
        ie1_out <= ie1;
 
        mie_out <= mie;
 
 
 
        -- The two upper bits of the CSR address encodes the accessibility of the CSR:
 
        read_writeable <= read_address(11 downto 10) /= b"11";
 
 
        --! 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
Line 84... Line 111...
                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_MTOHOST 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;
 
 
 
        mtime_counter: process(timer_clk, reset)
 
        begin
 
                if reset = '1' then -- Asynchronous reset because timer_clk is slower than clk
 
                        counter_mtime <= (others => '0');
 
                elsif rising_edge(timer_clk) then
 
                        counter_mtime <= std_logic_vector(unsigned(counter_mtime) + 1);
 
                end if;
 
        end process mtime_counter;
 
 
 
        mtime_interrupt: process(clk)
 
        begin
 
                if rising_edge(clk) then
 
                        if reset = '1' then
 
                                timer_interrupt <= '0';
 
                        else
 
                                if write_mode /= CSR_WRITE_NONE and write_address = CSR_MTIMECMP then
 
                                        timer_interrupt <= '0';
 
                                elsif counter_mtime = mtime_compare then
 
                                        timer_interrupt <= '1';
 
                                end if;
 
                        end if;
 
                end if;
 
        end process mtime_interrupt;
 
 
        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;
                                software_interrupt <= '0';
 
                                mtvec <= x"00000100";
 
                                mepc <= x"00000100";
 
                                mie <= (others => '0');
 
                                ie <= '0';
 
                                ie1 <= '0';
                        else
                        else
                                if exception_context_write = '1' then
                                if exception_context_write = '1' then
                                        status_register <= exception_context.status;
                                        ie <= exception_context.ie;
                                        cause <= exception_context.cause;
                                        ie1 <= exception_context.ie1;
                                        badvaddr <= exception_context.badvaddr;
                                        mcause <= exception_context.cause;
 
                                        mbadaddr <= exception_context.badaddr;
                                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_MSTATUS => -- Status register
                                                        if exception_context_write = '0' then
                                                        ie1 <= write_data_in(CSR_SR_IE1);
                                                                status_register <= to_csr_status_register(write_data_in);
                                                        ie <= write_data_in(CSR_SR_IE);
                                                        end if;
                                                when CSR_MSCRATCH => -- Scratch register
                                                when CSR_EPC =>
                                                        mscratch <= write_data_in;
                                                        epc <= write_data_in;
                                                when CSR_MEPC => -- Exception return address
                                                when CSR_EVEC =>
                                                        mepc <= write_data_in;
                                                        evec <= write_data_in;
                                                --when CSR_MCAUSE => -- Exception cause
                                                when CSR_SUP0 =>
                                                --      mcause <= write_data_in(31) & write_data_in(4 downto 0);
                                                        sup0 <= write_data_in;
                                                when CSR_MTVEC => -- Exception vector address
                                                when CSR_SUP1 =>
                                                        mtvec <= write_data_in;
                                                        sup1 <= write_data_in;
                                                when CSR_MTIMECMP => -- Time compare register
 
                                                        mtime_compare <= write_data_in;
 
                                                when CSR_MIE => -- Interrupt enable register:
 
                                                        mie <= write_data_in;
 
                                                when CSR_MIP => -- Interrupt pending register:
 
                                                        software_interrupt <= write_data_in(CSR_MIP_MSIP);
                                                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
 
                        --      status_out <= exception_context.status;
 
                        --else
 
                        --      status_out <= status_register;
 
                        --end if;
 
 
 
                        if write_mode /= CSR_WRITE_NONE and write_address = CSR_EVEC then
                        if write_mode /= CSR_WRITE_NONE and write_address = CSR_MTVEC then
                                evec_out <= write_data_in;
                                mtvec_out <= write_data_in;
                        else
                        else
                                evec_out <= evec;
                                mtvec_out <= mtvec;
                        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:
                                        -- Machine mode registers:
                                        when CSR_STATUS => -- Status register
                                        when CSR_MCPUID => -- CPU features register
                                                read_data_out <= to_std_logic_vector(status_register);
                                                read_data_out <= (
                                        when CSR_HARTID => -- Processor ID
                                                                8 => '1', -- Set the bit corresponding to I
 
                                                                others => '0');
 
                                        when CSR_MIMPID => -- Implementation/Implementor ID
 
                                                read_data_out <= (31 downto 16 => '0') & x"8000";
 
                                                -- The anonymous source ID, 0x8000 is used until an open-source implementation ID
 
                                                -- is available for use.
 
                                        when CSR_MHARTID => -- Hardware thread ID
                                                read_data_out <= PROCESSOR_ID;
                                                read_data_out <= PROCESSOR_ID;
                                        when CSR_FROMHOST => -- Fromhost data
                                        when CSR_MFROMHOST => -- Data from a host environment
                                                read_data_out <= fromhost;
                                                read_data_out <= fromhost;
                                        when CSR_EPC | CSR_EPC_SRET => -- Exception PC value
                                        when CSR_MSTATUS => -- Status register
                                                read_data_out <= epc;
                                                read_data_out <= csr_make_mstatus(ie, ie1);
                                        when CSR_EVEC => -- Exception handler address
                                        when CSR_MSCRATCH => -- Scratch register
                                                read_data_out <= evec;
                                                read_data_out <= mscratch;
                                        when CSR_CAUSE => -- Exception cause
                                        when CSR_MEPC => -- Exception PC value
                                                read_data_out <= to_std_logic_vector(cause);
                                                read_data_out <= mepc;
                                        when CSR_BADVADDR => -- Load/store address responsible for the exception
                                        when CSR_MTVEC => -- Exception vector address
                                                read_data_out <= badvaddr;
                                                read_data_out <= mtvec;
 
                                        when CSR_MTDELEG => -- Exception vector delegation register, unsupported
                                        -- Supporting registers:
                                                read_data_out <= (others => '0');
                                        when CSR_SUP0 =>
                                        when CSR_MIP => -- Interrupt pending
                                                read_data_out <= sup0;
                                                read_data_out <= irq & (CSR_MIP_MTIP => timer_interrupt, CSR_MIP_MSIP => software_interrupt,
                                        when CSR_SUP1 =>
                                                        23 downto 8 => '0', 6 downto 4 => '0', 2 downto 0 => '0');
                                                read_data_out <= sup1;
                                        when CSR_MIE => -- Interrupt enable register
 
                                                read_data_out <= mie;
 
                                        when CSR_MBADADDR => -- Bad memory address
 
                                                read_data_out <= mbadaddr;
 
                                        when CSR_MCAUSE => -- Exception cause
 
                                                read_data_out <= mcause(5) & (30 downto 5 => '0') & mcause(4 downto 0); --to_std_logic_vector(mcause);
 
 
                                        -- Timers and counters:
                                        -- Timers and counters:
 
                                        when CSR_MTIME => -- Machine time counter register
 
                                                read_data_out <= counter_mtime;
 
                                        when CSR_MTIMECMP => -- Machine time compare register
 
                                                read_data_out <= mtime_compare;
 
 
                                        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 =>

powered by: WebSVN 2.1.0

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