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

Subversion Repositories potato

[/] [potato/] [trunk/] [src/] [pp_core.vhd] - Blame information for rev 36

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_types.all;
10
use work.pp_constants.all;
11
use work.pp_utilities.all;
12
use work.pp_csr.all;
13
 
14
--! @brief The Potato Processor is a simple processor core for use in FPGAs.
15
--! @details
16
--! It implements the RV32I (RISC-V base integer subset) ISA with additional
17
--! instructions for manipulation of control and status registers from the
18
--! currently unpublished supervisor extension.
19
entity pp_core is
20
        generic(
21
                PROCESSOR_ID           : std_logic_vector(31 downto 0) := x"00000000"; --! Processor ID.
22
                RESET_ADDRESS          : std_logic_vector(31 downto 0) := x"00000000"  --! Address of the first instruction to execute.
23
        );
24
        port(
25
                -- Control inputs:
26
                clk       : in std_logic; --! Processor clock
27
                reset     : in std_logic; --! Reset signal
28
 
29
                timer_clk : in std_logic; --! Clock used for the timer/counter
30
 
31
                -- Instruction memory interface:
32
                imem_address : out std_logic_vector(31 downto 0); --! Address of the next instruction
33
                imem_data_in : in  std_logic_vector(31 downto 0); --! Instruction input
34
                imem_req     : out std_logic;
35
                imem_ack     : in  std_logic;
36
 
37
                -- Data memory interface:
38
                dmem_address   : out std_logic_vector(31 downto 0); --! Data address
39
                dmem_data_in   : in  std_logic_vector(31 downto 0); --! Input from the data memory
40
                dmem_data_out  : out std_logic_vector(31 downto 0); --! Ouptut to the data memory
41
                dmem_data_size : out std_logic_vector( 1 downto 0);  --! Size of the data, 1 = 8 bits, 2 = 16 bits, 0 = 32 bits. 
42
                dmem_read_req  : out std_logic;                      --! Data memory read request
43
                dmem_read_ack  : in  std_logic;                      --! Data memory read acknowledge
44
                dmem_write_req : out std_logic;                      --! Data memory write request
45
                dmem_write_ack : in  std_logic;                      --! Data memory write acknowledge
46
 
47
                -- Tohost/fromhost interface:
48
                fromhost_data     : in  std_logic_vector(31 downto 0); --! Data from the host/simulator.
49
                fromhost_write_en : in  std_logic;                     --! Write enable signal from the host/simulator.
50
                tohost_data       : out std_logic_vector(31 downto 0); --! Data to the host/simulator.
51
                tohost_write_en   : out std_logic;                     --! Write enable signal to the host/simulator.
52
 
53
                -- External interrupt input:
54
                irq : in std_logic_vector(7 downto 0) --! IRQ inputs.
55
        );
56
end entity pp_core;
57
 
58
architecture behaviour of pp_core is
59
 
60
        ------- Flush signals -------
61
        signal flush_if, flush_id, flush_ex : std_logic;
62
 
63
        ------- Stall signals -------
64
        signal stall_if, stall_id, stall_ex, stall_mem : std_logic;
65
 
66
        -- Signals used to determine if an instruction should be counted
67
        -- by the instret counter:
68
        signal if_count_instruction, id_count_instruction  : std_logic;
69
        signal ex_count_instruction, mem_count_instruction : std_logic;
70
        signal wb_count_instruction : std_logic;
71
 
72
        -- CSR read port signals:
73
        signal csr_read_data      : std_logic_vector(31 downto 0);
74
        signal csr_read_writeable : boolean;
75 36 skordal
        signal csr_read_address, csr_read_address_p : csr_address;
76 2 skordal
 
77
        -- Status register outputs:
78
        signal status : csr_status_register;
79
        signal evec   : std_logic_vector(31 downto 0);
80
 
81
        -- Load hazard detected in the execute stage:
82
        signal load_hazard_detected : std_logic;
83
 
84
        -- Branch targets:
85
        signal exception_target, branch_target : std_logic_vector(31 downto 0);
86
        signal branch_taken, exception_taken   : std_logic;
87
 
88
        -- Register file read ports:
89
        signal rs1_address_p, rs2_address_p : register_address;
90
        signal rs1_address, rs2_address     : register_address;
91
        signal rs1_data, rs2_data           : std_logic_vector(31 downto 0);
92
 
93
        -- Data memory signals:
94
        signal dmem_address_p   : std_logic_vector(31 downto 0);
95
        signal dmem_data_size_p : std_logic_vector(1 downto 0);
96
        signal dmem_data_out_p  : std_logic_vector(31 downto 0);
97
        signal dmem_read_req_p  : std_logic;
98
        signal dmem_write_req_p : std_logic;
99
 
100
        -- Fetch stage signals:
101
        signal if_instruction, if_pc : std_logic_vector(31 downto 0);
102
        signal if_instruction_ready  : std_logic;
103
 
104
        -- Decode stage signals:
105
        signal id_funct3          : std_logic_vector(2 downto 0);
106
        signal id_rd_address      : register_address;
107
        signal id_rd_write        : std_logic;
108
        signal id_rs1_address     : register_address;
109
        signal id_rs2_address     : register_address;
110
        signal id_csr_address     : csr_address;
111
        signal id_csr_write       : csr_write_mode;
112
        signal id_csr_use_immediate : std_logic;
113
        signal id_shamt           : std_logic_vector(4 downto 0);
114
        signal id_immediate       : std_logic_vector(31 downto 0);
115
        signal id_branch          : branch_type;
116
        signal id_alu_x_src, id_alu_y_src : alu_operand_source;
117
        signal id_alu_op          : alu_operation;
118
        signal id_mem_op          : memory_operation_type;
119
        signal id_mem_size        : memory_operation_size;
120
        signal id_pc              : std_logic_vector(31 downto 0);
121
        signal id_exception       : std_logic;
122
        signal id_exception_cause : csr_exception_cause;
123
 
124
        -- Execute stage signals:
125
        signal ex_dmem_address   : std_logic_vector(31 downto 0);
126
        signal ex_dmem_data_size : std_logic_vector(1 downto 0);
127
        signal ex_dmem_data_out  : std_logic_vector(31 downto 0);
128
        signal ex_dmem_read_req  : std_logic;
129
        signal ex_dmem_write_req : std_logic;
130
        signal ex_rd_address     : register_address;
131
        signal ex_rd_data        : std_logic_vector(31 downto 0);
132
        signal ex_rd_write       : std_logic;
133
        signal ex_pc             : std_logic_vector(31 downto 0);
134
        signal ex_csr_address    : csr_address;
135
        signal ex_csr_write      : csr_write_mode;
136
        signal ex_csr_data       : std_logic_vector(31 downto 0);
137
        signal ex_branch         : branch_type;
138
        signal ex_mem_op         : memory_operation_type;
139
        signal ex_mem_size       : memory_operation_size;
140
        signal ex_exception_context : csr_exception_context;
141
 
142
        -- Memory stage signals:
143
        signal mem_rd_write    : std_logic;
144
        signal mem_rd_address  : register_address;
145
        signal mem_rd_data     : std_logic_vector(31 downto 0);
146
        signal mem_csr_address : csr_address;
147
        signal mem_csr_write   : csr_write_mode;
148
        signal mem_csr_data    : std_logic_vector(31 downto 0);
149
        signal mem_mem_op      : memory_operation_type;
150
 
151
        signal mem_exception         : std_logic;
152
        signal mem_exception_context : csr_exception_context;
153
 
154
        -- Writeback signals:
155
        signal wb_rd_address  : register_address;
156
        signal wb_rd_data     : std_logic_vector(31 downto 0);
157
        signal wb_rd_write    : std_logic;
158
        signal wb_csr_address : csr_address;
159
        signal wb_csr_write   : csr_write_mode;
160
        signal wb_csr_data    : std_logic_vector(31 downto 0);
161
 
162
        signal wb_exception         : std_logic;
163
        signal wb_exception_context : csr_exception_context;
164
 
165
begin
166
 
167
        stall_if <= stall_id;
168
        stall_id <= stall_ex;
169
        stall_ex <= load_hazard_detected or stall_mem;
170
        stall_mem <= to_std_logic(memop_is_load(mem_mem_op) and dmem_read_ack = '0')
171
                or to_std_logic(mem_mem_op = MEMOP_TYPE_STORE and dmem_write_ack = '0');
172
 
173 34 skordal
        flush_if <= (branch_taken or exception_taken) and not stall_if;
174
        flush_id <= (branch_taken or exception_taken) and not stall_id;
175
        flush_ex <= (branch_taken or exception_taken) and not stall_ex;
176 2 skordal
 
177
        ------- Control and status module -------
178
        csr_unit: entity work.pp_csr_unit
179
                        generic map(
180
                                PROCESSOR_ID => PROCESSOR_ID
181
                        ) port map(
182
                                clk => clk,
183
                                reset => reset,
184
                                timer_clk => timer_clk,
185
                                count_instruction => wb_count_instruction,
186
                                fromhost_data => fromhost_data,
187
                                fromhost_updated => fromhost_write_en,
188
                                tohost_data => tohost_data,
189
                                tohost_updated => tohost_write_en,
190 36 skordal
                                read_address => csr_read_address,
191 2 skordal
                                read_data_out => csr_read_data,
192
                                read_writeable => csr_read_writeable,
193
                                write_address => wb_csr_address,
194
                                write_data_in => wb_csr_data,
195
                                write_mode => wb_csr_write,
196
                                exception_context => wb_exception_context,
197
                                exception_context_write => wb_exception,
198
                                status_out => status,
199
                                evec_out => evec
200
                        );
201
 
202 36 skordal
        csr_read_address <= id_csr_address when stall_ex = '0' else csr_read_address_p;
203
 
204
        store_previous_csr_addr: process(clk, stall_ex)
205
        begin
206
                if rising_edge(clk) and stall_ex = '0' then
207
                        csr_read_address_p <= id_csr_address;
208
                end if;
209
        end process store_previous_csr_addr;
210
 
211 2 skordal
        ------- Register file -------
212
        regfile: entity work.pp_register_file
213
                        port map(
214
                                clk => clk,
215
                                rs1_addr => rs1_address,
216
                                rs2_addr => rs2_address,
217
                                rs1_data => rs1_data,
218
                                rs2_data => rs2_data,
219
                                rd_addr => wb_rd_address,
220
                                rd_data => wb_rd_data,
221
                                rd_write => wb_rd_write
222
                        );
223
 
224
        rs1_address <= id_rs1_address when stall_ex = '0' else rs1_address_p;
225
        rs2_address <= id_rs2_address when stall_ex = '0' else rs2_address_p;
226
 
227
        store_previous_rsaddr: process(clk, stall_ex)
228
        begin
229
                if rising_edge(clk) and stall_ex = '0' then
230
                        rs1_address_p <= id_rs1_address;
231
                        rs2_address_p <= id_rs2_address;
232
                end if;
233
        end process store_previous_rsaddr;
234
 
235
        ------- Instruction Fetch (IF) Stage -------
236
        fetch: entity work.pp_fetch
237
                generic map(
238
                        RESET_ADDRESS => RESET_ADDRESS
239
                ) port map(
240
                        clk => clk,
241
                        reset => reset,
242
                        imem_address => imem_address,
243
                        imem_data_in => imem_data_in,
244
                        imem_req => imem_req,
245
                        imem_ack => imem_ack,
246
                        stall => stall_if,
247
                        flush => flush_if,
248
                        branch => branch_taken,
249
                        exception => exception_taken,
250
                        branch_target => branch_target,
251
                        evec => exception_target,
252
                        instruction_data => if_instruction,
253
                        instruction_address => if_pc,
254
                        instruction_ready => if_instruction_ready
255
                );
256
        if_count_instruction <= if_instruction_ready;
257
 
258
        ------- Instruction Decode (ID) Stage -------
259
        decode: entity work.pp_decode
260
                generic map(
261
                        RESET_ADDRESS => RESET_ADDRESS,
262
                        PROCESSOR_ID => PROCESSOR_ID
263
                ) port map(
264
                        clk => clk,
265
                        reset => reset,
266
                        flush => flush_id,
267
                        stall => stall_id,
268
                        instruction_data => if_instruction,
269
                        instruction_address => if_pc,
270
                        instruction_ready => if_instruction_ready,
271
                        instruction_count => if_count_instruction,
272
                        funct3 => id_funct3,
273
                        rs1_addr => id_rs1_address,
274
                        rs2_addr => id_rs2_address,
275
                        rd_addr => id_rd_address,
276
                        csr_addr => id_csr_address,
277
                        shamt => id_shamt,
278
                        immediate => id_immediate,
279
                        rd_write => id_rd_write,
280
                        branch => id_branch,
281
                        alu_x_src => id_alu_x_src,
282
                        alu_y_src => id_alu_y_src,
283
                        alu_op => id_alu_op,
284
                        mem_op => id_mem_op,
285
                        mem_size => id_mem_size,
286
                        count_instruction => id_count_instruction,
287
                        pc => id_pc,
288
                        csr_write => id_csr_write,
289
                        csr_use_imm => id_csr_use_immediate,
290
                        decode_exception => id_exception,
291
                        decode_exception_cause => id_exception_cause
292
                );
293
 
294
        ------- Execute (EX) Stage -------
295
        execute: entity work.pp_execute
296
                port map(
297
                        clk => clk,
298
                        reset => reset,
299
                        stall => stall_ex,
300
                        flush => flush_ex,
301
                        irq => irq,
302
                        dmem_address => ex_dmem_address,
303
                        dmem_data_size => ex_dmem_data_size,
304
                        dmem_data_out => ex_dmem_data_out,
305
                        dmem_read_req => ex_dmem_read_req,
306
                        dmem_write_req => ex_dmem_write_req,
307
                        rs1_addr_in => rs1_address,
308
                        rs2_addr_in => rs2_address,
309
                        rd_addr_in => id_rd_address,
310
                        rd_addr_out => ex_rd_address,
311
                        rs1_data_in => rs1_data,
312
                        rs2_data_in => rs2_data,
313
                        shamt_in => id_shamt,
314
                        immediate_in => id_immediate,
315
                        funct3_in => id_funct3,
316
                        pc_in => id_pc,
317
                        pc_out => ex_pc,
318 36 skordal
                        csr_addr_in => csr_read_address,
319 2 skordal
                        csr_addr_out => ex_csr_address,
320
                        csr_write_in => id_csr_write,
321
                        csr_write_out => ex_csr_write,
322
                        csr_value_in => csr_read_data,
323
                        csr_value_out => ex_csr_data,
324
                        csr_writeable_in => csr_read_writeable,
325
                        csr_use_immediate_in => id_csr_use_immediate,
326
                        alu_op_in => id_alu_op,
327
                        alu_x_src_in => id_alu_x_src,
328
                        alu_y_src_in => id_alu_y_src,
329
                        rd_write_in => id_rd_write,
330
                        rd_write_out => ex_rd_write,
331
                        rd_data_out => ex_rd_data,
332
                        branch_in => id_branch,
333
                        branch_out => ex_branch,
334
                        mem_op_in => id_mem_op,
335
                        mem_op_out => ex_mem_op,
336
                        mem_size_in => id_mem_size,
337
                        mem_size_out => ex_mem_size,
338
                        count_instruction_in => id_count_instruction,
339
                        count_instruction_out => ex_count_instruction,
340
                        status_in => status,
341
                        evec_in => evec,
342
                        evec_out => exception_target,
343
                        decode_exception_in => id_exception,
344
                        decode_exception_cause_in => id_exception_cause,
345
                        exception_out => exception_taken,
346
                        exception_context_out => ex_exception_context,
347
                        jump_out => branch_taken,
348
                        jump_target_out => branch_target,
349
                        mem_rd_write => mem_rd_write,
350
                        mem_rd_addr => mem_rd_address,
351
                        mem_rd_value => mem_rd_data,
352
                        mem_csr_addr => mem_csr_address,
353
                        mem_csr_value => mem_csr_data,
354
                        mem_csr_write => mem_csr_write,
355
                        mem_exception => mem_exception,
356
                        mem_exception_context => mem_exception_context,
357
                        wb_rd_write => wb_rd_write,
358
                        wb_rd_addr => wb_rd_address,
359
                        wb_rd_value => wb_rd_data,
360
                        wb_csr_addr => wb_csr_address,
361
                        wb_csr_value => wb_csr_data,
362
                        wb_csr_write => wb_csr_write,
363
                        wb_exception => wb_exception,
364
                        wb_exception_context => wb_exception_context,
365
                        mem_mem_op => mem_mem_op,
366
                        hazard_detected => load_hazard_detected
367
                );
368
 
369
        dmem_address <= ex_dmem_address when stall_mem = '0' else dmem_address_p;
370
        dmem_data_size <= ex_dmem_data_size when stall_mem = '0' else dmem_data_size_p;
371
        dmem_data_out <= ex_dmem_data_out when stall_mem = '0' else dmem_data_out_p;
372
        dmem_read_req <= ex_dmem_read_req when stall_mem = '0' else dmem_read_req_p;
373
        dmem_write_req <= ex_dmem_write_req when stall_mem = '0' else dmem_write_req_p;
374
 
375
        store_previous_dmem_address: process(clk, stall_mem)
376
        begin
377
                if rising_edge(clk) and stall_mem = '0' then
378
                        dmem_address_p <= ex_dmem_address;
379
                        dmem_data_size_p <= ex_dmem_data_size;
380
                        dmem_data_out_p <= ex_dmem_data_out;
381
                        dmem_read_req_p <= ex_dmem_read_req;
382
                        dmem_write_req_p <= ex_dmem_write_req;
383
                end if;
384
        end process store_previous_dmem_address;
385
 
386
        ------- Memory (MEM) Stage -------
387
        memory: entity work.pp_memory
388
                port map(
389
                        clk => clk,
390
                        reset => reset,
391
                        stall => stall_mem,
392
                        dmem_data_in => dmem_data_in,
393
                        dmem_read_ack => dmem_read_ack,
394
                        dmem_write_ack => dmem_write_ack,
395
                        pc => ex_pc,
396
                        rd_write_in => ex_rd_write,
397
                        rd_write_out => mem_rd_write,
398
                        rd_data_in => ex_rd_data,
399
                        rd_data_out => mem_rd_data,
400
                        rd_addr_in => ex_rd_address,
401
                        rd_addr_out => mem_rd_address,
402
                        branch => ex_branch,
403
                        mem_op_in => ex_mem_op,
404
                        mem_op_out => mem_mem_op,
405
                        mem_size_in => ex_mem_size,
406
                        count_instr_in => ex_count_instruction,
407
                        count_instr_out => mem_count_instruction,
408
                        exception_in => exception_taken,
409
                        exception_out => mem_exception,
410
                        exception_context_in => ex_exception_context,
411
                        exception_context_out => mem_exception_context,
412
                        csr_addr_in => ex_csr_address,
413
                        csr_addr_out => mem_csr_address,
414
                        csr_write_in => ex_csr_write,
415
                        csr_write_out => mem_csr_write,
416
                        csr_data_in => ex_csr_data,
417
                        csr_data_out => mem_csr_data
418
                );
419
 
420
        ------- Writeback (WB) Stage -------
421
        writeback: entity work.pp_writeback
422
                port map(
423
                        clk => clk,
424
                        reset => reset,
425
                        count_instr_in => mem_count_instruction,
426
                        count_instr_out => wb_count_instruction,
427
                        exception_ctx_in => mem_exception_context,
428
                        exception_ctx_out => wb_exception_context,
429
                        exception_in => mem_exception,
430
                        exception_out => wb_exception,
431
                        csr_write_in => mem_csr_write,
432
                        csr_write_out => wb_csr_write,
433
                        csr_data_in => mem_csr_data,
434
                        csr_data_out => wb_csr_data,
435
                        csr_addr_in => mem_csr_address,
436
                        csr_addr_out => wb_csr_address,
437
                        rd_addr_in => mem_rd_address,
438
                        rd_addr_out => wb_rd_address,
439
                        rd_write_in => mem_rd_write,
440
                        rd_write_out => wb_rd_write,
441
                        rd_data_in => mem_rd_data,
442
                        rd_data_out => wb_rd_data
443
                );
444
 
445
end architecture behaviour;
446
 

powered by: WebSVN 2.1.0

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