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

Subversion Repositories potato

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

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 58 skordal
                RESET_ADDRESS          : std_logic_vector(31 downto 0) := x"00000200"  --! Address of the first instruction to execute.
23 2 skordal
        );
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 58 skordal
        signal wb_count_instruction : std_logic;
71 2 skordal
 
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 58 skordal
        signal mtvec   : std_logic_vector(31 downto 0);
79
        signal mie     : std_logic_vector(31 downto 0);
80
        signal ie, ie1 : std_logic;
81 2 skordal
 
82 58 skordal
        -- Internal interrupt signals:
83
        signal software_interrupt, timer_interrupt : std_logic;
84
 
85 2 skordal
        -- Load hazard detected in the execute stage:
86
        signal load_hazard_detected : std_logic;
87
 
88
        -- Branch targets:
89
        signal exception_target, branch_target : std_logic_vector(31 downto 0);
90
        signal branch_taken, exception_taken   : std_logic;
91
 
92
        -- Register file read ports:
93
        signal rs1_address_p, rs2_address_p : register_address;
94
        signal rs1_address, rs2_address     : register_address;
95
        signal rs1_data, rs2_data           : std_logic_vector(31 downto 0);
96
 
97
        -- Data memory signals:
98
        signal dmem_address_p   : std_logic_vector(31 downto 0);
99
        signal dmem_data_size_p : std_logic_vector(1 downto 0);
100
        signal dmem_data_out_p  : std_logic_vector(31 downto 0);
101
        signal dmem_read_req_p  : std_logic;
102
        signal dmem_write_req_p : std_logic;
103
 
104
        -- Fetch stage signals:
105
        signal if_instruction, if_pc : std_logic_vector(31 downto 0);
106
        signal if_instruction_ready  : std_logic;
107
 
108
        -- Decode stage signals:
109
        signal id_funct3          : std_logic_vector(2 downto 0);
110
        signal id_rd_address      : register_address;
111
        signal id_rd_write        : std_logic;
112
        signal id_rs1_address     : register_address;
113
        signal id_rs2_address     : register_address;
114
        signal id_csr_address     : csr_address;
115
        signal id_csr_write       : csr_write_mode;
116
        signal id_csr_use_immediate : std_logic;
117
        signal id_shamt           : std_logic_vector(4 downto 0);
118
        signal id_immediate       : std_logic_vector(31 downto 0);
119
        signal id_branch          : branch_type;
120
        signal id_alu_x_src, id_alu_y_src : alu_operand_source;
121
        signal id_alu_op          : alu_operation;
122
        signal id_mem_op          : memory_operation_type;
123
        signal id_mem_size        : memory_operation_size;
124
        signal id_pc              : std_logic_vector(31 downto 0);
125
        signal id_exception       : std_logic;
126
        signal id_exception_cause : csr_exception_cause;
127
 
128
        -- Execute stage signals:
129
        signal ex_dmem_address   : std_logic_vector(31 downto 0);
130
        signal ex_dmem_data_size : std_logic_vector(1 downto 0);
131
        signal ex_dmem_data_out  : std_logic_vector(31 downto 0);
132
        signal ex_dmem_read_req  : std_logic;
133
        signal ex_dmem_write_req : std_logic;
134
        signal ex_rd_address     : register_address;
135
        signal ex_rd_data        : std_logic_vector(31 downto 0);
136
        signal ex_rd_write       : std_logic;
137
        signal ex_pc             : std_logic_vector(31 downto 0);
138
        signal ex_csr_address    : csr_address;
139
        signal ex_csr_write      : csr_write_mode;
140
        signal ex_csr_data       : std_logic_vector(31 downto 0);
141
        signal ex_branch         : branch_type;
142
        signal ex_mem_op         : memory_operation_type;
143
        signal ex_mem_size       : memory_operation_size;
144
        signal ex_exception_context : csr_exception_context;
145
 
146
        -- Memory stage signals:
147
        signal mem_rd_write    : std_logic;
148
        signal mem_rd_address  : register_address;
149
        signal mem_rd_data     : std_logic_vector(31 downto 0);
150
        signal mem_csr_address : csr_address;
151
        signal mem_csr_write   : csr_write_mode;
152
        signal mem_csr_data    : std_logic_vector(31 downto 0);
153
        signal mem_mem_op      : memory_operation_type;
154
 
155
        signal mem_exception         : std_logic;
156
        signal mem_exception_context : csr_exception_context;
157
 
158
        -- Writeback signals:
159
        signal wb_rd_address  : register_address;
160
        signal wb_rd_data     : std_logic_vector(31 downto 0);
161
        signal wb_rd_write    : std_logic;
162
        signal wb_csr_address : csr_address;
163
        signal wb_csr_write   : csr_write_mode;
164
        signal wb_csr_data    : std_logic_vector(31 downto 0);
165
 
166
        signal wb_exception         : std_logic;
167
        signal wb_exception_context : csr_exception_context;
168
 
169
begin
170
 
171
        stall_if <= stall_id;
172
        stall_id <= stall_ex;
173
        stall_ex <= load_hazard_detected or stall_mem;
174
        stall_mem <= to_std_logic(memop_is_load(mem_mem_op) and dmem_read_ack = '0')
175
                or to_std_logic(mem_mem_op = MEMOP_TYPE_STORE and dmem_write_ack = '0');
176
 
177 34 skordal
        flush_if <= (branch_taken or exception_taken) and not stall_if;
178
        flush_id <= (branch_taken or exception_taken) and not stall_id;
179
        flush_ex <= (branch_taken or exception_taken) and not stall_ex;
180 2 skordal
 
181
        ------- Control and status module -------
182
        csr_unit: entity work.pp_csr_unit
183
                        generic map(
184
                                PROCESSOR_ID => PROCESSOR_ID
185
                        ) port map(
186
                                clk => clk,
187
                                reset => reset,
188
                                timer_clk => timer_clk,
189 58 skordal
                                irq => irq,
190 2 skordal
                                count_instruction => wb_count_instruction,
191
                                fromhost_data => fromhost_data,
192
                                fromhost_updated => fromhost_write_en,
193
                                tohost_data => tohost_data,
194
                                tohost_updated => tohost_write_en,
195 36 skordal
                                read_address => csr_read_address,
196 2 skordal
                                read_data_out => csr_read_data,
197
                                read_writeable => csr_read_writeable,
198
                                write_address => wb_csr_address,
199
                                write_data_in => wb_csr_data,
200
                                write_mode => wb_csr_write,
201
                                exception_context => wb_exception_context,
202
                                exception_context_write => wb_exception,
203 58 skordal
                                mie_out => mie,
204
                                mtvec_out => mtvec,
205
                                ie_out => ie,
206
                                ie1_out => ie1,
207
                                software_interrupt_out => software_interrupt,
208
                                timer_interrupt_out => timer_interrupt
209 2 skordal
                        );
210
 
211 36 skordal
        csr_read_address <= id_csr_address when stall_ex = '0' else csr_read_address_p;
212
        store_previous_csr_addr: process(clk, stall_ex)
213
        begin
214
                if rising_edge(clk) and stall_ex = '0' then
215
                        csr_read_address_p <= id_csr_address;
216
                end if;
217
        end process store_previous_csr_addr;
218
 
219 2 skordal
        ------- Register file -------
220
        regfile: entity work.pp_register_file
221
                        port map(
222
                                clk => clk,
223
                                rs1_addr => rs1_address,
224
                                rs2_addr => rs2_address,
225
                                rs1_data => rs1_data,
226
                                rs2_data => rs2_data,
227
                                rd_addr => wb_rd_address,
228
                                rd_data => wb_rd_data,
229
                                rd_write => wb_rd_write
230
                        );
231
 
232
        rs1_address <= id_rs1_address when stall_ex = '0' else rs1_address_p;
233
        rs2_address <= id_rs2_address when stall_ex = '0' else rs2_address_p;
234
 
235
        store_previous_rsaddr: process(clk, stall_ex)
236
        begin
237
                if rising_edge(clk) and stall_ex = '0' then
238
                        rs1_address_p <= id_rs1_address;
239
                        rs2_address_p <= id_rs2_address;
240
                end if;
241
        end process store_previous_rsaddr;
242
 
243
        ------- Instruction Fetch (IF) Stage -------
244
        fetch: entity work.pp_fetch
245
                generic map(
246
                        RESET_ADDRESS => RESET_ADDRESS
247
                ) port map(
248
                        clk => clk,
249
                        reset => reset,
250
                        imem_address => imem_address,
251
                        imem_data_in => imem_data_in,
252
                        imem_req => imem_req,
253
                        imem_ack => imem_ack,
254
                        stall => stall_if,
255
                        flush => flush_if,
256
                        branch => branch_taken,
257
                        exception => exception_taken,
258
                        branch_target => branch_target,
259
                        evec => exception_target,
260
                        instruction_data => if_instruction,
261
                        instruction_address => if_pc,
262
                        instruction_ready => if_instruction_ready
263
                );
264
        if_count_instruction <= if_instruction_ready;
265
 
266
        ------- Instruction Decode (ID) Stage -------
267
        decode: entity work.pp_decode
268
                generic map(
269
                        RESET_ADDRESS => RESET_ADDRESS,
270
                        PROCESSOR_ID => PROCESSOR_ID
271
                ) port map(
272
                        clk => clk,
273
                        reset => reset,
274
                        flush => flush_id,
275
                        stall => stall_id,
276
                        instruction_data => if_instruction,
277
                        instruction_address => if_pc,
278
                        instruction_ready => if_instruction_ready,
279
                        instruction_count => if_count_instruction,
280
                        funct3 => id_funct3,
281
                        rs1_addr => id_rs1_address,
282
                        rs2_addr => id_rs2_address,
283
                        rd_addr => id_rd_address,
284
                        csr_addr => id_csr_address,
285
                        shamt => id_shamt,
286
                        immediate => id_immediate,
287
                        rd_write => id_rd_write,
288
                        branch => id_branch,
289
                        alu_x_src => id_alu_x_src,
290
                        alu_y_src => id_alu_y_src,
291
                        alu_op => id_alu_op,
292
                        mem_op => id_mem_op,
293
                        mem_size => id_mem_size,
294
                        count_instruction => id_count_instruction,
295
                        pc => id_pc,
296
                        csr_write => id_csr_write,
297
                        csr_use_imm => id_csr_use_immediate,
298
                        decode_exception => id_exception,
299
                        decode_exception_cause => id_exception_cause
300
                );
301
 
302
        ------- Execute (EX) Stage -------
303
        execute: entity work.pp_execute
304
                port map(
305
                        clk => clk,
306
                        reset => reset,
307
                        stall => stall_ex,
308
                        flush => flush_ex,
309
                        irq => irq,
310 58 skordal
                        software_interrupt => software_interrupt,
311
                        timer_interrupt => timer_interrupt,
312 2 skordal
                        dmem_address => ex_dmem_address,
313
                        dmem_data_size => ex_dmem_data_size,
314
                        dmem_data_out => ex_dmem_data_out,
315
                        dmem_read_req => ex_dmem_read_req,
316
                        dmem_write_req => ex_dmem_write_req,
317
                        rs1_addr_in => rs1_address,
318
                        rs2_addr_in => rs2_address,
319
                        rd_addr_in => id_rd_address,
320
                        rd_addr_out => ex_rd_address,
321
                        rs1_data_in => rs1_data,
322
                        rs2_data_in => rs2_data,
323
                        shamt_in => id_shamt,
324
                        immediate_in => id_immediate,
325
                        funct3_in => id_funct3,
326
                        pc_in => id_pc,
327
                        pc_out => ex_pc,
328 36 skordal
                        csr_addr_in => csr_read_address,
329 2 skordal
                        csr_addr_out => ex_csr_address,
330
                        csr_write_in => id_csr_write,
331
                        csr_write_out => ex_csr_write,
332
                        csr_value_in => csr_read_data,
333
                        csr_value_out => ex_csr_data,
334
                        csr_writeable_in => csr_read_writeable,
335
                        csr_use_immediate_in => id_csr_use_immediate,
336
                        alu_op_in => id_alu_op,
337
                        alu_x_src_in => id_alu_x_src,
338
                        alu_y_src_in => id_alu_y_src,
339
                        rd_write_in => id_rd_write,
340
                        rd_write_out => ex_rd_write,
341
                        rd_data_out => ex_rd_data,
342
                        branch_in => id_branch,
343
                        branch_out => ex_branch,
344
                        mem_op_in => id_mem_op,
345
                        mem_op_out => ex_mem_op,
346
                        mem_size_in => id_mem_size,
347
                        mem_size_out => ex_mem_size,
348
                        count_instruction_in => id_count_instruction,
349
                        count_instruction_out => ex_count_instruction,
350 58 skordal
                        ie_in => ie,
351
                        ie1_in => ie1,
352
                        mie_in => mie,
353
                        mtvec_in => mtvec,
354
                        mtvec_out => exception_target,
355 2 skordal
                        decode_exception_in => id_exception,
356
                        decode_exception_cause_in => id_exception_cause,
357
                        exception_out => exception_taken,
358
                        exception_context_out => ex_exception_context,
359
                        jump_out => branch_taken,
360
                        jump_target_out => branch_target,
361
                        mem_rd_write => mem_rd_write,
362
                        mem_rd_addr => mem_rd_address,
363
                        mem_rd_value => mem_rd_data,
364
                        mem_csr_addr => mem_csr_address,
365
                        mem_csr_value => mem_csr_data,
366
                        mem_csr_write => mem_csr_write,
367
                        mem_exception => mem_exception,
368
                        mem_exception_context => mem_exception_context,
369
                        wb_rd_write => wb_rd_write,
370
                        wb_rd_addr => wb_rd_address,
371
                        wb_rd_value => wb_rd_data,
372
                        wb_csr_addr => wb_csr_address,
373
                        wb_csr_value => wb_csr_data,
374
                        wb_csr_write => wb_csr_write,
375
                        wb_exception => wb_exception,
376
                        wb_exception_context => wb_exception_context,
377
                        mem_mem_op => mem_mem_op,
378
                        hazard_detected => load_hazard_detected
379
                );
380
 
381
        dmem_address <= ex_dmem_address when stall_mem = '0' else dmem_address_p;
382
        dmem_data_size <= ex_dmem_data_size when stall_mem = '0' else dmem_data_size_p;
383
        dmem_data_out <= ex_dmem_data_out when stall_mem = '0' else dmem_data_out_p;
384
        dmem_read_req <= ex_dmem_read_req when stall_mem = '0' else dmem_read_req_p;
385
        dmem_write_req <= ex_dmem_write_req when stall_mem = '0' else dmem_write_req_p;
386
 
387
        store_previous_dmem_address: process(clk, stall_mem)
388
        begin
389
                if rising_edge(clk) and stall_mem = '0' then
390
                        dmem_address_p <= ex_dmem_address;
391
                        dmem_data_size_p <= ex_dmem_data_size;
392
                        dmem_data_out_p <= ex_dmem_data_out;
393
                        dmem_read_req_p <= ex_dmem_read_req;
394
                        dmem_write_req_p <= ex_dmem_write_req;
395
                end if;
396
        end process store_previous_dmem_address;
397
 
398
        ------- Memory (MEM) Stage -------
399
        memory: entity work.pp_memory
400
                port map(
401
                        clk => clk,
402
                        reset => reset,
403
                        stall => stall_mem,
404
                        dmem_data_in => dmem_data_in,
405
                        dmem_read_ack => dmem_read_ack,
406
                        dmem_write_ack => dmem_write_ack,
407
                        pc => ex_pc,
408
                        rd_write_in => ex_rd_write,
409
                        rd_write_out => mem_rd_write,
410
                        rd_data_in => ex_rd_data,
411
                        rd_data_out => mem_rd_data,
412
                        rd_addr_in => ex_rd_address,
413
                        rd_addr_out => mem_rd_address,
414
                        branch => ex_branch,
415
                        mem_op_in => ex_mem_op,
416
                        mem_op_out => mem_mem_op,
417
                        mem_size_in => ex_mem_size,
418
                        count_instr_in => ex_count_instruction,
419
                        count_instr_out => mem_count_instruction,
420
                        exception_in => exception_taken,
421
                        exception_out => mem_exception,
422
                        exception_context_in => ex_exception_context,
423
                        exception_context_out => mem_exception_context,
424
                        csr_addr_in => ex_csr_address,
425
                        csr_addr_out => mem_csr_address,
426
                        csr_write_in => ex_csr_write,
427
                        csr_write_out => mem_csr_write,
428
                        csr_data_in => ex_csr_data,
429
                        csr_data_out => mem_csr_data
430
                );
431
 
432
        ------- Writeback (WB) Stage -------
433
        writeback: entity work.pp_writeback
434
                port map(
435
                        clk => clk,
436
                        reset => reset,
437
                        count_instr_in => mem_count_instruction,
438
                        count_instr_out => wb_count_instruction,
439
                        exception_ctx_in => mem_exception_context,
440
                        exception_ctx_out => wb_exception_context,
441
                        exception_in => mem_exception,
442
                        exception_out => wb_exception,
443
                        csr_write_in => mem_csr_write,
444
                        csr_write_out => wb_csr_write,
445
                        csr_data_in => mem_csr_data,
446
                        csr_data_out => wb_csr_data,
447
                        csr_addr_in => mem_csr_address,
448
                        csr_addr_out => wb_csr_address,
449
                        rd_addr_in => mem_rd_address,
450
                        rd_addr_out => wb_rd_address,
451
                        rd_write_in => mem_rd_write,
452
                        rd_write_out => wb_rd_write,
453
                        rd_data_in => mem_rd_data,
454
                        rd_data_out => wb_rd_data
455
                );
456
 
457
end architecture behaviour;
458
 

powered by: WebSVN 2.1.0

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