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

Subversion Repositories potato

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

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
        read: process(clk)
134
        begin
135
                if rising_edge(clk) then
136
                        if exception_context_write  = '1' then
137
                                status_out <= exception_context.status;
138
                        else
139
                                status_out <= status_register;
140
                        end if;
141
 
142
                        if write_mode /= CSR_WRITE_NONE and write_address = CSR_EVEC then
143
                                evec_out <= write_data_in;
144
                        else
145
                                evec_out <= evec;
146
                        end if;
147
 
148
                        if write_mode /= CSR_WRITE_NONE and write_address = read_address then
149
                                read_data_out <= write_data_in;
150
                        else
151
                                case read_address is
152
 
153
                                        -- Status and control registers:
154
                                        when CSR_STATUS => -- Status register
155
                                                read_data_out <= to_std_logic_vector(status_register);
156
                                        when CSR_HARTID => -- Processor ID
157
                                                read_data_out <= PROCESSOR_ID;
158
                                        when CSR_FROMHOST => -- Fromhost data
159
                                                read_data_out <= fromhost;
160
                                        when CSR_EPC | CSR_EPC_SRET => -- Exception PC value
161
                                                read_data_out <= epc;
162
                                        when CSR_EVEC => -- Exception handler address
163
                                                read_data_out <= evec;
164
                                        when CSR_CAUSE => -- Exception cause
165
                                                read_data_out <= to_std_logic_vector(cause);
166
                                        when CSR_BADVADDR => -- Load/store address responsible for the exception
167
                                                read_data_out <= badvaddr;
168
 
169
                                        -- Supporting registers:
170
                                        when CSR_SUP0 =>
171
                                                read_data_out <= sup0;
172
                                        when CSR_SUP1 =>
173
                                                read_data_out <= sup1;
174
 
175
                                        -- Timers and counters:
176
                                        when CSR_TIME =>
177
                                                read_data_out <= counter_time(31 downto 0);
178
                                        when CSR_TIMEH =>
179
                                                read_data_out <= counter_time(63 downto 32);
180
                                        when CSR_CYCLE =>
181
                                                read_data_out <= counter_cycle(31 downto 0);
182
                                        when CSR_CYCLEH =>
183
                                                read_data_out <= counter_cycle(63 downto 32);
184
                                        when CSR_INSTRET =>
185
                                                read_data_out <= counter_instret(31 downto 0);
186
                                        when CSR_INSTRETH =>
187
                                                read_data_out <= counter_instret(63 downto 32);
188
 
189
                                        -- Return zero from write-only registers and invalid register addresses:
190
                                        when others =>
191
                                                read_data_out <= (others => '0');
192
                                end case;
193
                        end if;
194
                end if;
195
        end process read;
196
 
197
        timer_counter: entity work.pp_counter
198
                port map(
199
                        clk => timer_clk,
200
                        reset => reset,
201
                        count => counter_time,
202
                        increment => '1'
203
                );
204
 
205
        cycle_counter: entity work.pp_counter
206
                port map(
207
                        clk => clk,
208
                        reset => reset,
209
                        count => counter_cycle,
210
                        increment => '1'
211
                );
212
 
213
        instret_counter: entity work.pp_counter
214
                port map(
215
                        clk => clk,
216
                        reset => reset,
217
                        count => counter_instret,
218
                        increment => count_instruction
219
                );
220
 
221
end architecture behaviour;

powered by: WebSVN 2.1.0

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