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

Subversion Repositories potato

[/] [potato/] [trunk/] [src/] [pp_csr_unit.vhd] - Blame information for rev 45

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 skordal
-- The Potato Processor - A simple processor for FPGAs
2
-- (c) Kristian Klomsten Skordal 2014 - 2015 <kristian.skordal@wafflemail.net>
3 3 skordal
-- Report bugs and issues on <http://opencores.org/project,potato,bugtracker>
4 2 skordal
 
5
library ieee;
6
use ieee.std_logic_1164.all;
7
use ieee.numeric_std.all;
8
 
9
use work.pp_csr.all;
10
 
11
entity pp_csr_unit is
12
        generic(
13
                PROCESSOR_ID : std_logic_vector(31 downto 0)
14
        );
15
        port(
16
                clk, timer_clk : in std_logic;
17
                reset : in std_logic;
18
 
19
                -- Count retired instruction:
20
                count_instruction : in std_logic;
21
 
22
                -- HTIF interface:
23
                fromhost_data    : in  std_logic_vector(31 downto 0);
24
                fromhost_updated : in  std_logic;
25
                tohost_data      : out std_logic_vector(31 downto 0);
26
                tohost_updated   : out std_logic;
27
 
28
                -- Read port:
29
                read_address   : in csr_address;
30
                read_data_out  : out std_logic_vector(31 downto 0);
31
                read_writeable : out boolean;
32
 
33
                -- Write port:
34
                write_address : in csr_address;
35
                write_data_in : in std_logic_vector(31 downto 0);
36
                write_mode    : in csr_write_mode;
37
 
38
                -- Exception context write port:
39
                exception_context       : in csr_exception_context;
40
                exception_context_write : in std_logic;
41
 
42
                -- Registers needed for exception handling, always read:
43
                status_out : out csr_status_register;
44
                evec_out   : out std_logic_vector(31 downto 0)
45
        );
46
end entity pp_csr_unit;
47
 
48
architecture behaviour of pp_csr_unit is
49
 
50
        -- Implemented counters:
51
        signal counter_time    : std_logic_vector(63 downto 0);
52
        signal counter_cycle   : std_logic_vector(63 downto 0);
53
        signal counter_instret : std_logic_vector(63 downto 0);
54
 
55
        -- Implemented registers:
56
        signal sup0, sup1 : std_logic_vector(31 downto 0) := (others => '0');
57
        signal epc, evec  : std_logic_vector(31 downto 0) := (others => '0');
58
        signal badvaddr   : std_logic_vector(31 downto 0) := (others => '0');
59
        signal cause      : csr_exception_cause;
60
 
61
        -- HTIF FROMHOST register:
62
        signal fromhost: std_logic_vector(31 downto 0);
63
 
64
        -- Status register:
65
        signal status_register : csr_status_register;
66
 
67
begin
68
 
69
        read_writeable <= csr_is_writeable(read_address);
70
 
71
        --! Updates the FROMHOST register when new data is available.
72
        htif_fromhost: process(clk)
73
        begin
74
                if rising_edge(clk) then
75
                        if fromhost_updated = '1' then
76
                                fromhost <= fromhost_data;
77
                        end if;
78
                end if;
79
        end process htif_fromhost;
80
 
81
        --! Sends a word to the host over the HTIF interface.
82
        htif_tohost: process(clk)
83
        begin
84
                if rising_edge(clk) then
85
                        if reset = '1' then
86
                                tohost_data <= (others => '0');
87
                                tohost_updated <= '0';
88
                        else
89
                                if write_mode /= CSR_WRITE_NONE and write_address = CSR_TOHOST then
90
                                        tohost_data <= write_data_in;
91
                                        tohost_updated <= '1';
92
                                else
93
                                        tohost_updated <= '0';
94
                                end if;
95
                        end if;
96
                end if;
97
        end process htif_tohost;
98
 
99
        write: process(clk)
100
        begin
101
                if rising_edge(clk) then
102
                        if reset = '1' then
103
                                status_register <= CSR_SR_DEFAULT;
104
                        else
105
                                if exception_context_write = '1' then
106
                                        status_register <= exception_context.status;
107
                                        cause <= exception_context.cause;
108
                                        badvaddr <= exception_context.badvaddr;
109
                                end if;
110
 
111
                                if write_mode /= CSR_WRITE_NONE then
112
                                        case write_address is
113
                                                when CSR_STATUS =>
114
                                                        if exception_context_write = '0' then
115
                                                                status_register <= to_csr_status_register(write_data_in);
116
                                                        end if;
117
                                                when CSR_EPC =>
118
                                                        epc <= write_data_in;
119
                                                when CSR_EVEC =>
120
                                                        evec <= write_data_in;
121
                                                when CSR_SUP0 =>
122
                                                        sup0 <= write_data_in;
123
                                                when CSR_SUP1 =>
124
                                                        sup1 <= write_data_in;
125
                                                when others =>
126
                                                        -- Ignore writes to invalid or read-only registers
127
                                        end case;
128
                                end if;
129
                        end if;
130
                end if;
131
        end process write;
132
 
133 45 skordal
        status_out <= exception_context.status when exception_context_write = '1' else status_register;
134
 
135 2 skordal
        read: process(clk)
136
        begin
137
                if rising_edge(clk) then
138 45 skordal
                        --if exception_context_write  = '1' then
139
                        --      status_out <= exception_context.status;
140
                        --else
141
                        --      status_out <= status_register;
142
                        --end if;
143 2 skordal
 
144
                        if write_mode /= CSR_WRITE_NONE and write_address = CSR_EVEC then
145
                                evec_out <= write_data_in;
146
                        else
147
                                evec_out <= evec;
148
                        end if;
149
 
150
                        if write_mode /= CSR_WRITE_NONE and write_address = read_address then
151
                                read_data_out <= write_data_in;
152
                        else
153
                                case read_address is
154
 
155
                                        -- Status and control registers:
156
                                        when CSR_STATUS => -- Status register
157
                                                read_data_out <= to_std_logic_vector(status_register);
158
                                        when CSR_HARTID => -- Processor ID
159
                                                read_data_out <= PROCESSOR_ID;
160
                                        when CSR_FROMHOST => -- Fromhost data
161
                                                read_data_out <= fromhost;
162
                                        when CSR_EPC | CSR_EPC_SRET => -- Exception PC value
163
                                                read_data_out <= epc;
164
                                        when CSR_EVEC => -- Exception handler address
165
                                                read_data_out <= evec;
166
                                        when CSR_CAUSE => -- Exception cause
167
                                                read_data_out <= to_std_logic_vector(cause);
168
                                        when CSR_BADVADDR => -- Load/store address responsible for the exception
169
                                                read_data_out <= badvaddr;
170
 
171
                                        -- Supporting registers:
172
                                        when CSR_SUP0 =>
173
                                                read_data_out <= sup0;
174
                                        when CSR_SUP1 =>
175
                                                read_data_out <= sup1;
176
 
177
                                        -- Timers and counters:
178
                                        when CSR_TIME =>
179
                                                read_data_out <= counter_time(31 downto 0);
180
                                        when CSR_TIMEH =>
181
                                                read_data_out <= counter_time(63 downto 32);
182
                                        when CSR_CYCLE =>
183
                                                read_data_out <= counter_cycle(31 downto 0);
184
                                        when CSR_CYCLEH =>
185
                                                read_data_out <= counter_cycle(63 downto 32);
186
                                        when CSR_INSTRET =>
187
                                                read_data_out <= counter_instret(31 downto 0);
188
                                        when CSR_INSTRETH =>
189
                                                read_data_out <= counter_instret(63 downto 32);
190
 
191
                                        -- Return zero from write-only registers and invalid register addresses:
192
                                        when others =>
193
                                                read_data_out <= (others => '0');
194
                                end case;
195
                        end if;
196
                end if;
197
        end process read;
198
 
199
        timer_counter: entity work.pp_counter
200
                port map(
201
                        clk => timer_clk,
202
                        reset => reset,
203
                        count => counter_time,
204
                        increment => '1'
205
                );
206
 
207
        cycle_counter: entity work.pp_counter
208
                port map(
209
                        clk => clk,
210
                        reset => reset,
211
                        count => counter_cycle,
212
                        increment => '1'
213
                );
214
 
215
        instret_counter: entity work.pp_counter
216
                port map(
217
                        clk => clk,
218
                        reset => reset,
219
                        count => counter_instret,
220
                        increment => count_instruction
221
                );
222
 
223
end architecture behaviour;

powered by: WebSVN 2.1.0

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