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

Subversion Repositories potato

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

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
entity pp_core is
16
        generic(
17
                PROCESSOR_ID           : std_logic_vector(31 downto 0) := x"00000000"; --! Processor ID.
18 58 skordal
                RESET_ADDRESS          : std_logic_vector(31 downto 0) := x"00000200"  --! Address of the first instruction to execute.
19 2 skordal
        );
20
        port(
21
                -- Control inputs:
22
                clk       : in std_logic; --! Processor clock
23
                reset     : in std_logic; --! Reset signal
24
 
25
                timer_clk : in std_logic; --! Clock used for the timer/counter
26
 
27
                -- Instruction memory interface:
28
                imem_address : out std_logic_vector(31 downto 0); --! Address of the next instruction
29
                imem_data_in : in  std_logic_vector(31 downto 0); --! Instruction input
30
                imem_req     : out std_logic;
31
                imem_ack     : in  std_logic;
32
 
33
                -- Data memory interface:
34
                dmem_address   : out std_logic_vector(31 downto 0); --! Data address
35
                dmem_data_in   : in  std_logic_vector(31 downto 0); --! Input from the data memory
36
                dmem_data_out  : out std_logic_vector(31 downto 0); --! Ouptut to the data memory
37
                dmem_data_size : out std_logic_vector( 1 downto 0);  --! Size of the data, 1 = 8 bits, 2 = 16 bits, 0 = 32 bits. 
38
                dmem_read_req  : out std_logic;                      --! Data memory read request
39
                dmem_read_ack  : in  std_logic;                      --! Data memory read acknowledge
40
                dmem_write_req : out std_logic;                      --! Data memory write request
41
                dmem_write_ack : in  std_logic;                      --! Data memory write acknowledge
42
 
43
                -- Tohost/fromhost interface:
44
                fromhost_data     : in  std_logic_vector(31 downto 0); --! Data from the host/simulator.
45
                fromhost_write_en : in  std_logic;                     --! Write enable signal from the host/simulator.
46
                tohost_data       : out std_logic_vector(31 downto 0); --! Data to the host/simulator.
47
                tohost_write_en   : out std_logic;                     --! Write enable signal to the host/simulator.
48
 
49
                -- External interrupt input:
50
                irq : in std_logic_vector(7 downto 0) --! IRQ inputs.
51
        );
52
end entity pp_core;
53
 
54
architecture behaviour of pp_core is
55
 
56
        ------- Flush signals -------
57
        signal flush_if, flush_id, flush_ex : std_logic;
58
 
59
        ------- Stall signals -------
60
        signal stall_if, stall_id, stall_ex, stall_mem : std_logic;
61
 
62
        -- Signals used to determine if an instruction should be counted
63
        -- by the instret counter:
64
        signal if_count_instruction, id_count_instruction  : std_logic;
65
        signal ex_count_instruction, mem_count_instruction : std_logic;
66 58 skordal
        signal wb_count_instruction : std_logic;
67 2 skordal
 
68
        -- CSR read port signals:
69
        signal csr_read_data      : std_logic_vector(31 downto 0);
70
        signal csr_read_writeable : boolean;
71 36 skordal
        signal csr_read_address, csr_read_address_p : csr_address;
72 2 skordal
 
73
        -- Status register outputs:
74 58 skordal
        signal mtvec   : std_logic_vector(31 downto 0);
75
        signal mie     : std_logic_vector(31 downto 0);
76
        signal ie, ie1 : std_logic;
77 2 skordal
 
78 58 skordal
        -- Internal interrupt signals:
79
        signal software_interrupt, timer_interrupt : std_logic;
80
 
81 2 skordal
        -- 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 58 skordal
                                irq => irq,
186 2 skordal
                                count_instruction => wb_count_instruction,
187
                                fromhost_data => fromhost_data,
188
                                fromhost_updated => fromhost_write_en,
189
                                tohost_data => tohost_data,
190
                                tohost_updated => tohost_write_en,
191 36 skordal
                                read_address => csr_read_address,
192 2 skordal
                                read_data_out => csr_read_data,
193
                                read_writeable => csr_read_writeable,
194
                                write_address => wb_csr_address,
195
                                write_data_in => wb_csr_data,
196
                                write_mode => wb_csr_write,
197
                                exception_context => wb_exception_context,
198
                                exception_context_write => wb_exception,
199 58 skordal
                                mie_out => mie,
200
                                mtvec_out => mtvec,
201
                                ie_out => ie,
202
                                ie1_out => ie1,
203
                                software_interrupt_out => software_interrupt,
204
                                timer_interrupt_out => timer_interrupt
205 2 skordal
                        );
206
 
207 36 skordal
        csr_read_address <= id_csr_address when stall_ex = '0' else csr_read_address_p;
208
        store_previous_csr_addr: process(clk, stall_ex)
209
        begin
210
                if rising_edge(clk) and stall_ex = '0' then
211
                        csr_read_address_p <= id_csr_address;
212
                end if;
213
        end process store_previous_csr_addr;
214
 
215 2 skordal
        ------- Register file -------
216
        regfile: entity work.pp_register_file
217
                        port map(
218
                                clk => clk,
219
                                rs1_addr => rs1_address,
220
                                rs2_addr => rs2_address,
221
                                rs1_data => rs1_data,
222
                                rs2_data => rs2_data,
223
                                rd_addr => wb_rd_address,
224
                                rd_data => wb_rd_data,
225
                                rd_write => wb_rd_write
226
                        );
227
 
228
        rs1_address <= id_rs1_address when stall_ex = '0' else rs1_address_p;
229
        rs2_address <= id_rs2_address when stall_ex = '0' else rs2_address_p;
230
 
231
        store_previous_rsaddr: process(clk, stall_ex)
232
        begin
233
                if rising_edge(clk) and stall_ex = '0' then
234
                        rs1_address_p <= id_rs1_address;
235
                        rs2_address_p <= id_rs2_address;
236
                end if;
237
        end process store_previous_rsaddr;
238
 
239
        ------- Instruction Fetch (IF) Stage -------
240
        fetch: entity work.pp_fetch
241
                generic map(
242
                        RESET_ADDRESS => RESET_ADDRESS
243
                ) port map(
244
                        clk => clk,
245
                        reset => reset,
246
                        imem_address => imem_address,
247
                        imem_data_in => imem_data_in,
248
                        imem_req => imem_req,
249
                        imem_ack => imem_ack,
250
                        stall => stall_if,
251
                        flush => flush_if,
252
                        branch => branch_taken,
253
                        exception => exception_taken,
254
                        branch_target => branch_target,
255
                        evec => exception_target,
256
                        instruction_data => if_instruction,
257
                        instruction_address => if_pc,
258
                        instruction_ready => if_instruction_ready
259
                );
260
        if_count_instruction <= if_instruction_ready;
261
 
262
        ------- Instruction Decode (ID) Stage -------
263
        decode: entity work.pp_decode
264
                generic map(
265
                        RESET_ADDRESS => RESET_ADDRESS,
266
                        PROCESSOR_ID => PROCESSOR_ID
267
                ) port map(
268
                        clk => clk,
269
                        reset => reset,
270
                        flush => flush_id,
271
                        stall => stall_id,
272
                        instruction_data => if_instruction,
273
                        instruction_address => if_pc,
274
                        instruction_ready => if_instruction_ready,
275
                        instruction_count => if_count_instruction,
276
                        funct3 => id_funct3,
277
                        rs1_addr => id_rs1_address,
278
                        rs2_addr => id_rs2_address,
279
                        rd_addr => id_rd_address,
280
                        csr_addr => id_csr_address,
281
                        shamt => id_shamt,
282
                        immediate => id_immediate,
283
                        rd_write => id_rd_write,
284
                        branch => id_branch,
285
                        alu_x_src => id_alu_x_src,
286
                        alu_y_src => id_alu_y_src,
287
                        alu_op => id_alu_op,
288
                        mem_op => id_mem_op,
289
                        mem_size => id_mem_size,
290
                        count_instruction => id_count_instruction,
291
                        pc => id_pc,
292
                        csr_write => id_csr_write,
293
                        csr_use_imm => id_csr_use_immediate,
294
                        decode_exception => id_exception,
295
                        decode_exception_cause => id_exception_cause
296
                );
297
 
298
        ------- Execute (EX) Stage -------
299
        execute: entity work.pp_execute
300
                port map(
301
                        clk => clk,
302
                        reset => reset,
303
                        stall => stall_ex,
304
                        flush => flush_ex,
305
                        irq => irq,
306 58 skordal
                        software_interrupt => software_interrupt,
307
                        timer_interrupt => timer_interrupt,
308 2 skordal
                        dmem_address => ex_dmem_address,
309
                        dmem_data_size => ex_dmem_data_size,
310
                        dmem_data_out => ex_dmem_data_out,
311
                        dmem_read_req => ex_dmem_read_req,
312
                        dmem_write_req => ex_dmem_write_req,
313
                        rs1_addr_in => rs1_address,
314
                        rs2_addr_in => rs2_address,
315
                        rd_addr_in => id_rd_address,
316
                        rd_addr_out => ex_rd_address,
317
                        rs1_data_in => rs1_data,
318
                        rs2_data_in => rs2_data,
319
                        shamt_in => id_shamt,
320
                        immediate_in => id_immediate,
321
                        funct3_in => id_funct3,
322
                        pc_in => id_pc,
323
                        pc_out => ex_pc,
324 36 skordal
                        csr_addr_in => csr_read_address,
325 2 skordal
                        csr_addr_out => ex_csr_address,
326
                        csr_write_in => id_csr_write,
327
                        csr_write_out => ex_csr_write,
328
                        csr_value_in => csr_read_data,
329
                        csr_value_out => ex_csr_data,
330
                        csr_writeable_in => csr_read_writeable,
331
                        csr_use_immediate_in => id_csr_use_immediate,
332
                        alu_op_in => id_alu_op,
333
                        alu_x_src_in => id_alu_x_src,
334
                        alu_y_src_in => id_alu_y_src,
335
                        rd_write_in => id_rd_write,
336
                        rd_write_out => ex_rd_write,
337
                        rd_data_out => ex_rd_data,
338
                        branch_in => id_branch,
339
                        branch_out => ex_branch,
340
                        mem_op_in => id_mem_op,
341
                        mem_op_out => ex_mem_op,
342
                        mem_size_in => id_mem_size,
343
                        mem_size_out => ex_mem_size,
344
                        count_instruction_in => id_count_instruction,
345
                        count_instruction_out => ex_count_instruction,
346 58 skordal
                        ie_in => ie,
347
                        ie1_in => ie1,
348
                        mie_in => mie,
349
                        mtvec_in => mtvec,
350
                        mtvec_out => exception_target,
351 2 skordal
                        decode_exception_in => id_exception,
352
                        decode_exception_cause_in => id_exception_cause,
353
                        exception_out => exception_taken,
354
                        exception_context_out => ex_exception_context,
355
                        jump_out => branch_taken,
356
                        jump_target_out => branch_target,
357
                        mem_rd_write => mem_rd_write,
358
                        mem_rd_addr => mem_rd_address,
359
                        mem_rd_value => mem_rd_data,
360
                        mem_csr_addr => mem_csr_address,
361
                        mem_csr_value => mem_csr_data,
362
                        mem_csr_write => mem_csr_write,
363
                        mem_exception => mem_exception,
364
                        mem_exception_context => mem_exception_context,
365
                        wb_rd_write => wb_rd_write,
366
                        wb_rd_addr => wb_rd_address,
367
                        wb_rd_value => wb_rd_data,
368
                        wb_csr_addr => wb_csr_address,
369
                        wb_csr_value => wb_csr_data,
370
                        wb_csr_write => wb_csr_write,
371
                        wb_exception => wb_exception,
372
                        wb_exception_context => wb_exception_context,
373
                        mem_mem_op => mem_mem_op,
374
                        hazard_detected => load_hazard_detected
375
                );
376
 
377
        dmem_address <= ex_dmem_address when stall_mem = '0' else dmem_address_p;
378
        dmem_data_size <= ex_dmem_data_size when stall_mem = '0' else dmem_data_size_p;
379
        dmem_data_out <= ex_dmem_data_out when stall_mem = '0' else dmem_data_out_p;
380
        dmem_read_req <= ex_dmem_read_req when stall_mem = '0' else dmem_read_req_p;
381
        dmem_write_req <= ex_dmem_write_req when stall_mem = '0' else dmem_write_req_p;
382
 
383
        store_previous_dmem_address: process(clk, stall_mem)
384
        begin
385
                if rising_edge(clk) and stall_mem = '0' then
386
                        dmem_address_p <= ex_dmem_address;
387
                        dmem_data_size_p <= ex_dmem_data_size;
388
                        dmem_data_out_p <= ex_dmem_data_out;
389
                        dmem_read_req_p <= ex_dmem_read_req;
390
                        dmem_write_req_p <= ex_dmem_write_req;
391
                end if;
392
        end process store_previous_dmem_address;
393
 
394
        ------- Memory (MEM) Stage -------
395
        memory: entity work.pp_memory
396
                port map(
397
                        clk => clk,
398
                        reset => reset,
399
                        stall => stall_mem,
400
                        dmem_data_in => dmem_data_in,
401
                        dmem_read_ack => dmem_read_ack,
402
                        dmem_write_ack => dmem_write_ack,
403
                        pc => ex_pc,
404
                        rd_write_in => ex_rd_write,
405
                        rd_write_out => mem_rd_write,
406
                        rd_data_in => ex_rd_data,
407
                        rd_data_out => mem_rd_data,
408
                        rd_addr_in => ex_rd_address,
409
                        rd_addr_out => mem_rd_address,
410
                        branch => ex_branch,
411
                        mem_op_in => ex_mem_op,
412
                        mem_op_out => mem_mem_op,
413
                        mem_size_in => ex_mem_size,
414
                        count_instr_in => ex_count_instruction,
415
                        count_instr_out => mem_count_instruction,
416
                        exception_in => exception_taken,
417
                        exception_out => mem_exception,
418
                        exception_context_in => ex_exception_context,
419
                        exception_context_out => mem_exception_context,
420
                        csr_addr_in => ex_csr_address,
421
                        csr_addr_out => mem_csr_address,
422
                        csr_write_in => ex_csr_write,
423
                        csr_write_out => mem_csr_write,
424
                        csr_data_in => ex_csr_data,
425
                        csr_data_out => mem_csr_data
426
                );
427
 
428
        ------- Writeback (WB) Stage -------
429
        writeback: entity work.pp_writeback
430
                port map(
431
                        clk => clk,
432
                        reset => reset,
433
                        count_instr_in => mem_count_instruction,
434
                        count_instr_out => wb_count_instruction,
435
                        exception_ctx_in => mem_exception_context,
436
                        exception_ctx_out => wb_exception_context,
437
                        exception_in => mem_exception,
438
                        exception_out => wb_exception,
439
                        csr_write_in => mem_csr_write,
440
                        csr_write_out => wb_csr_write,
441
                        csr_data_in => mem_csr_data,
442
                        csr_data_out => wb_csr_data,
443
                        csr_addr_in => mem_csr_address,
444
                        csr_addr_out => wb_csr_address,
445
                        rd_addr_in => mem_rd_address,
446
                        rd_addr_out => wb_rd_address,
447
                        rd_write_in => mem_rd_write,
448
                        rd_write_out => wb_rd_write,
449
                        rd_data_in => mem_rd_data,
450
                        rd_data_out => wb_rd_data
451
                );
452
 
453
end architecture behaviour;
454
 

powered by: WebSVN 2.1.0

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