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

Subversion Repositories ion

[/] [ion/] [trunk/] [vhdl/] [mips_cpu.vhdl] - Blame information for rev 8

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

Line No. Rev Author Line
1 2 ja_rd
--------------------------------------------------------------------------------
2
-- ion_cpu.vhdl -- MIPS-I(tm) compatible CPU core
3
--------------------------------------------------------------------------------
4
-- project:       ION (http://www.opencores.org/project,ion_cpu)
5
-- author:        Jose A. Ruiz (ja_rd@hotmail.com)
6
-- created:       Jan/11/2011
7
-- last modified: Jan/25/2011 (ja_rd@hotmail.com)
8
--------------------------------------------------------------------------------
9
-- Software placed into the public domain by the author. Use under the terms of
10
-- the GPL.
11
-- Software 'as is' without warranty.  Author liable for nothing.
12
--------------------------------------------------------------------------------
13
-- NOTE: exceptions only partially implemented; jumps, loads and stores are
14
-- not aborted.
15
-- 
16
--
17
--------------------------------------------------------------------------------
18
--### PLASMA features not implemented yet
19
--  # MUL/DIV
20
--
21
--### MIPS-I things not implemented
22
--  # Invalid instruction detection
23
--  # Kernel/user status
24
--  # RTE instruction
25
--  # Most of the CP0 registers and of course all of the CP1
26
--  # External interrupts
27
--
28
--### Things implemented but not tested
29
--  # Syscall instruction (does a jal to 0x3c and that's it)
30
--  # Memory pause input
31
--
32
--### Things with provisional implementation
33
-- 
34
-- 1.- Load interlocks: the pipeline is stalled for every load instruction, even
35
--     if the target register is not used in the following instruction. So that
36
--     every load takes two cycles.
37
--     The interlock logic should check register indices.
38
--
39
-- 2.- Invalid instructions are not detected as such. Their behaviour is
40
--     undefined and inpredictable.
41
--     Invalid instructions should trigger an exception or at least just NOP.
42
--     This is closely related to privilege level so it will have to wait.
43
--------------------------------------------------------------------------------
44
 
45
library ieee;
46
use ieee.std_logic_1164.all;
47
use ieee.std_logic_arith.all;
48
use ieee.std_logic_unsigned.all;
49
use work.mips_pkg.all;
50
 
51
entity mips_cpu is
52
    generic(
53
        XILINX_REGBANK  : string  := "distributed" -- {distributed|block}
54
    );
55
    port(
56
        clk             : in std_logic;
57
        reset           : in std_logic;
58
        interrupt       : in std_logic;
59
 
60
        data_rd_addr    : out std_logic_vector(31 downto 0);
61
        data_rd         : in std_logic_vector(31 downto 0);
62
        data_rd_vma     : out std_logic;
63
 
64
        code_rd_addr    : out std_logic_vector(31 downto 2);
65
        code_rd         : in std_logic_vector(31 downto 0);
66
        code_rd_vma     : out std_logic;
67
 
68
        data_wr_addr    : out std_logic_vector(31 downto 2);
69
        byte_we         : out std_logic_vector(3 downto 0);
70
        data_wr         : out std_logic_vector(31 downto 0);
71
 
72
        -- NOTE: needs to be synchronous to clk
73
        mem_wait        : in std_logic
74
    );
75
end; --entity mips_cpu
76
 
77
architecture rtl of mips_cpu is
78
 
79
--------------------------------------------------------------------------------
80
-- Pipeline stage 0
81
 
82
signal p0_pc_reg :          t_pc;
83 8 ja_rd
signal p0_pc_restart :      t_pc;
84 2 ja_rd
signal p0_pc_incremented :  t_pc;
85
signal p0_pc_jump :         t_pc;
86
signal p0_pc_branch :       t_pc;
87
signal p0_pc_target :       t_pc;
88
signal p0_pc_next :         t_pc;
89
signal p0_rs_num :          t_regnum;
90
signal p0_rt_num :          t_regnum;
91
signal p0_jump_cond_value : std_logic;
92
signal p0_rbank_rs_hazard : std_logic;
93
signal p0_rbank_rt_hazard : std_logic;
94
 
95
--------------------------------------------------------------------------------
96
-- Pipeline stage 1
97
 
98
 
99
signal p1_rbank :           t_rbank := (others => X"00000000");
100
 
101
-- IMPORTANT: This attribute is used by Xilinx tools to select how to implement
102
-- the register bank. If we don't use it, by default XST would infer 2 BRAMs for
103
-- the 1024-bit 3-port reg bank, which you probably don't want.
104
-- This can take the values {distributed|block}.
105
attribute ram_style :       string;
106
attribute ram_style of p1_rbank : signal is "distributed";
107
 
108
signal p1_rs, p1_rt :       t_word;
109
signal p1_rs_rbank :        t_word;
110
signal p1_rt_rbank :        t_word;
111
signal p1_rbank_forward :   t_word;
112
signal p1_rd_num :          t_regnum;
113
signal p1_rbank_wr_addr :   t_regnum;
114
signal p1_rbank_we :        std_logic;
115
signal p1_rbank_wr_data :   t_word;
116
signal p1_alu_inp1 :        t_word;
117
signal p1_alu_inp2 :        t_word;
118
signal p1_alu_outp :        t_word;
119
-- ALU control inputs (shortened name for brevity in expressions)
120
signal p1_ac :              t_alu_control;
121
-- ALU flag outputs (comparison results)
122
signal p1_alu_flags :       t_alu_flags;
123
-- immediate data, sign- or zero-extended as required by IR
124
signal p1_data_imm :        t_word;
125
signal p1_muldiv_result :   t_dword;
126
signal p1_branch_offset :   t_pc;
127
signal p1_branch_offset_sex:std_logic_vector(31 downto 18);
128
signal p1_rbank_rs_hazard : std_logic;
129
signal p1_rbank_rt_hazard : std_logic;
130
signal p1_jump_type_set0 :  std_logic_vector(1 downto 0);
131
signal p1_jump_type_set1 :  std_logic_vector(1 downto 0);
132
signal p1_ir_reg :          std_logic_vector(31 downto 0);
133
signal p1_ir_op :           std_logic_vector(31 downto 26);
134
signal p1_ir_fn :           std_logic_vector(5 downto 0);
135
signal p1_op_special :      std_logic;
136
signal p1_exception :       std_logic;
137
signal p1_do_reg_jump :     std_logic;
138
signal p1_do_zero_ext_imm : std_logic;
139
signal p1_set_cp0 :         std_logic;
140
signal p1_get_cp0 :         std_logic;
141
signal p1_load_hi :         std_logic;
142
signal p1_load_lo :         std_logic;
143
signal p1_alu_op2_sel :     std_logic_vector(1 downto 0);
144
signal p1_alu_op2_sel_set0: std_logic_vector(1 downto 0);
145
signal p1_alu_op2_sel_set1: std_logic_vector(1 downto 0);
146
signal p1_do_load :         std_logic;
147
signal p1_do_store :        std_logic;
148
signal p1_store_size :      std_logic_vector(1 downto 0);
149
signal p1_we_control :      std_logic_vector(5 downto 0);
150
signal p1_load_alu :        std_logic;
151
signal p1_load_alu_set0 :   std_logic;
152
signal p1_load_alu_set1 :   std_logic;
153
signal p1_ld_upper_hword :  std_logic;
154
signal p1_ld_upper_byte :   std_logic;
155
signal p1_ld_unsigned :     std_logic;
156
signal p1_jump_type :       std_logic_vector(1 downto 0);
157
signal p1_link :            std_logic;
158
signal p1_jump_cond_sel :   std_logic_vector(2 downto 0);
159
signal p1_data_addr :       t_addr;
160
signal p1_data_offset :     t_addr;
161
 
162
--------------------------------------------------------------------------------
163
-- Pipeline stage 2
164
 
165
signal p2_exception :       std_logic;
166
signal p2_rd_addr :         std_logic_vector(1 downto 0);
167
signal p2_rd_mux_control :  std_logic_vector(3 downto 0);
168
signal p2_load_target :     t_regnum;
169
signal p2_do_load :         std_logic;
170
signal p2_ld_upper_hword :  std_logic;
171
signal p2_ld_upper_byte :   std_logic;
172
signal p2_ld_unsigned :     std_logic;
173
signal p2_wback_mux_sel :   std_logic_vector(1 downto 0);
174
signal p2_data_word_rd :    t_word;
175
signal p2_data_word_ext :   std_logic;
176
 
177
--------------------------------------------------------------------------------
178
-- Global control signals 
179
 
180
signal load_interlock :     std_logic;
181
signal stall_pipeline :     std_logic;
182
-- pipeline is stalled for any reason
183
signal pipeline_stalled :   std_logic;
184
-- pipeline is stalled because of a load instruction interlock
185
signal pipeline_interlocked:std_logic;
186
 
187
 
188
--------------------------------------------------------------------------------
189
-- Multiplier interface registers
190
 
191
signal mdiv_hi_reg :        t_word;
192
signal mdiv_lo_reg :        t_word;
193
 
194
--------------------------------------------------------------------------------
195
-- CP0 registers and signals
196
 
197
-- CP0[12]: status register 
198
-- FIXME status flags unimplemented
199
signal cp0_status :         std_logic_vector(1 downto 0);
200
-- Output of CP0 register bank (only a few regs are implemented)
201
signal cp0_reg_read :       t_word;
202
-- CP0[14]: EPC register (PC value saved at exceptions)
203
signal cp0_epc :            t_pc;
204
 
205
begin
206
 
207
--##############################################################################
208
-- Register bank & datapath
209
 
210
-- Register indices are 'decoded' out of the instruction word BEFORE loading IR
211
p0_rs_num <= std_logic_vector(code_rd(25 downto 21));
212
with p1_ir_reg(31 downto 26) select p1_rd_num <=
213
    p1_ir_reg(15 downto 11)    when "000000",
214
    p1_ir_reg(20 downto 16)    when others;
215
 
216
p0_rt_num <= std_logic_vector(code_rd(20 downto 16)); -- also called rs2 in the docs
217
 
218
--------------------------------------------------------------------------------
219
-- Data input shifter & masker (LB,LBU,LH,LHU,LW)
220
 
221
p2_rd_mux_control <= p2_ld_upper_hword & p2_ld_upper_byte & p2_rd_addr;
222
 
223
-- Extension for unused bits will be zero or the sign (bit 7 or bit 15)
224
p2_data_word_ext <= '0'         when p2_ld_unsigned='1' else
225
                    data_rd(15)  when p2_ld_upper_byte='1' else
226
                    data_rd(7)   when p2_rd_addr="11" else
227
                    data_rd(15)  when p2_rd_addr="10" else
228
                    data_rd(23);
229
 
230
-- byte 0 may come from any of the 4 bytes of the input word
231
with p2_rd_mux_control select p2_data_word_rd(7 downto 0) <=
232
    data_rd(31 downto 24)        when "0000",
233
    data_rd(23 downto 16)        when "0001",
234
    data_rd(23 downto 16)        when "0100",
235
    data_rd(15 downto  8)        when "0010",
236
    data_rd( 7 downto  0)        when others;
237
 
238
-- byte 1 may come from input bytes 1 or 3 or may be extended for LB, LBU
239
with p2_rd_mux_control select p2_data_word_rd(15 downto 8) <=
240
    data_rd(31 downto 24)        when "0100",
241
    data_rd(15 downto  8)        when "0110",
242
    data_rd(15 downto  8)        when "1100",
243
    data_rd(15 downto  8)        when "1101",
244
    data_rd(15 downto  8)        when "1110",
245
    data_rd(15 downto  8)        when "1111",
246
    (others => p2_data_word_ext) when others;
247
 
248
-- bytes 2,3 come straight from input or are extended for LH,LHU
249
with p2_ld_upper_hword select p2_data_word_rd(31 downto 16) <=
250
    (others => p2_data_word_ext)    when '0',
251
    data_rd(31 downto 16)            when others;
252
 
253
-- Select which data is to be written back to the reg bank and where
254
p1_rbank_wr_addr <= p1_rd_num   when p2_do_load='0' and p1_link='0' else
255
                    "11111"     when p2_do_load='0' and p1_link='1' else
256
                    p2_load_target;
257
 
258
p2_wback_mux_sel <=
259
    "00" when p2_do_load='0' and p1_get_cp0='0' and p1_link='0' else
260
    "01" when p2_do_load='1' and p1_get_cp0='0' and p1_link='0' else
261
    "10" when p2_do_load='0' and p1_get_cp0='1' and p1_link='0' else
262
    "11";
263
 
264
with (p2_wback_mux_sel) select p1_rbank_wr_data <=
265
    p1_alu_outp                when "00",
266
    p2_data_word_rd            when "01",
267
    p0_pc_incremented & "00"   when "11",
268
    cp0_reg_read               when others;
269
 
270
p1_rbank_we <= '1' when (p2_do_load='1' or p1_load_alu='1' or
271
                        p1_link='1' or p1_get_cp0='1') and
272
                        p1_rbank_wr_addr/="00000" and
273
                        -- on exception, abort next instruction (by preventing 
274
                        -- regbank writeback).
275
                        p2_exception='0'
276
                else '0';
277
 
278
-- Register bank as triple-port RAM. Should synth to 2 BRAMs unless you use
279
-- synth attributes to prevent it (see 'ram_style' attribute above) or your
280
-- FPGA has 3-port BRAMS, or has none.
281
synchronous_reg_bank:
282
process(clk)
283
begin
284
    if clk'event and clk='1' then
285
        if p1_rbank_we='1' and
286
           (pipeline_stalled='0' or pipeline_interlocked='1') then -- @note1
287
            p1_rbank(conv_integer(p1_rbank_wr_addr)) <= p1_rbank_wr_data;
288
        end if;
289
        p1_rt_rbank <= p1_rbank(conv_integer(p0_rt_num));
290
        p1_rs_rbank <= p1_rbank(conv_integer(p0_rs_num));
291
    end if;
292
end process synchronous_reg_bank;
293
 
294
-- Register writeback data in case it needs to be forwarded.
295
data_forward_register:
296
process(clk)
297
begin
298
    if clk'event and clk='1' then
299
        if p1_rbank_we='1' then -- no need to check for stall cycles
300
            p1_rbank_forward <= p1_rbank_wr_data;
301
        end if;
302
    end if;
303
end process data_forward_register;
304
 
305
-- Bypass sync RAM if we're reading and writing to the same address. This saves
306
-- 1 stall cycle and fixes the data hazard.
307
p0_rbank_rs_hazard <= '1' when p1_rbank_wr_addr=p0_rs_num and p1_rbank_we='1'
308
                      else '0';
309
p0_rbank_rt_hazard <= '1' when p1_rbank_wr_addr=p0_rt_num and p1_rbank_we='1'
310
                      else '0';
311
 
312
p1_rs <= p1_rs_rbank when p1_rbank_rs_hazard='0' else p1_rbank_forward;
313
p1_rt <= p1_rt_rbank when p1_rbank_rt_hazard='0' else p1_rbank_forward;
314
 
315
-- Zero extension/Sign extension for instruction immediate data
316
p1_data_imm(15 downto 0)  <= p1_ir_reg(15 downto 0);
317
 
318
with p1_do_zero_ext_imm select p1_data_imm(31 downto 16) <=
319
    (others => '0')             when '1',
320
    (others => p1_ir_reg(15))   when others;
321
 
322
 
323
--------------------------------------------------------------------------------
324
-- ALU & ALU input multiplexors
325
 
326
p1_alu_inp1 <= p1_rs;
327
 
328
with p1_alu_op2_sel select p1_alu_inp2 <=
329
    p1_data_imm                     when "11",
330
    p1_muldiv_result(63 downto 32)  when "01",
331
    p1_muldiv_result(31 downto  0)  when "10",
332
    p1_rt              when others;
333
 
334
alu_inst : entity work.mips_alu
335
    port map (
336
        clk             => clk,
337
        reset           => reset,
338
        ac              => p1_ac,
339
        flags           => p1_alu_flags,
340
 
341
        inp1            => p1_alu_inp1,
342
        inp2            => p1_alu_inp2,
343
        outp            => p1_alu_outp
344
    );
345
 
346
 
347
--------------------------------------------------------------------------------
348
-- Mul/Div block interface
349
 
350
-- FIXME when MUL*/DIV* are implemented, these registers and the load enable
351
-- logic will change a little. It may be better to move them into the alu.
352
mult_registers:
353
process(clk)
354
begin
355
    if clk'event and clk='1' then
356
        -- MTHI, MTLO are never involved in stall cycles, no need to check
357
        if p1_load_hi='1' then
358
            mdiv_hi_reg <= p1_rs;
359
        end if;
360
        if p1_load_lo='1' then
361
            mdiv_lo_reg <= p1_rs;
362
        end if;
363
    end if;
364
end process mult_registers;
365
 
366
p1_muldiv_result <= mdiv_hi_reg & mdiv_lo_reg; -- FIXME stub, mdiv missing
367
 
368
 
369
--##############################################################################
370
-- PC register and branch logic
371
 
372
-- p0_pc_reg will not be incremented on stall cycles
373
p0_pc_incremented <= p0_pc_reg + (not stall_pipeline);
374
 
375
-- main pc mux: jump or continue
376
p0_pc_next <=
377
    p0_pc_target when
378
        -- We jump on jump instructions whose condition is met...
379 6 ja_rd
        ((p1_jump_type(1)='1' and p0_jump_cond_value='1' and
380
        -- ...except we abort any jump that follows the victim of an exception
381
          p2_exception='0') or
382
        -- We jump on exceptions too...
383 2 ja_rd
        p1_exception='1')
384 6 ja_rd
        -- ... but we only jump at all if the pipeline is not stalled
385 2 ja_rd
        and stall_pipeline='0'
386
    else p0_pc_incremented;
387
 
388
pc_register:
389
process(clk)
390
begin
391
    if clk'event and clk='1' then
392
        if reset='1' then
393
            -- reset to 0xffffffff so that 1st fetch addr is 0x00000000
394
            p0_pc_reg <= (others => '1');
395
        else
396
            -- p0_pc_reg holds the same value as external sync ram addr register
397
            p0_pc_reg <= p0_pc_next;
398 8 ja_rd
            -- p0_pc_restart = addr saved to EPC on interrupts (@note2)
399
            -- It's the addr of the instruction triggering the exception
400
            -- FIXME handle delay slot case
401
            if (p1_jump_type="00" or p0_jump_cond_value='0') then
402
                p0_pc_restart <= p0_pc_reg;
403
            end if;
404 2 ja_rd
        end if;
405
    end if;
406
end process pc_register;
407
 
408
-- p0_pc_reg holds the same addr as the addr register of the external synchronous 
409
-- memory; what we put on the addr bus is p0_pc_next.
410
data_rd_addr <= p1_data_addr(31 downto 0);
411
 
412
-- FIXME these two need to pushed behind a register, they are glitch-prone
413
data_rd_vma <= p1_do_load and not pipeline_stalled; -- FIXME register
414
code_rd_vma <= not stall_pipeline; -- FIXME registe
415
 
416
code_rd_addr <= p0_pc_next;
417
 
418
data_wr_addr <= p1_data_addr(31 downto 2);
419
 
420
-- compute target of J/JR instructions
421
p0_pc_jump <=   p1_rs(31 downto 2) when p1_do_reg_jump='1' else
422
                p0_pc_reg(31 downto 28) & p1_ir_reg(25 downto 0);
423
 
424
-- compute target of relative branch instructions
425
p1_branch_offset_sex <= (others => p1_ir_reg(15));
426
p1_branch_offset <= p1_branch_offset_sex & p1_ir_reg(15 downto 0);
427
-- p0_pc_reg is the addr of the instruction in delay slot
428
p0_pc_branch <= p0_pc_reg + p1_branch_offset;
429
 
430
-- decide which jump target is to be used
431
p0_pc_target <= X"0000003"&"11"     when p1_exception='1' else
432
             p0_pc_jump             when p1_jump_type(0)='1' else
433
             p0_pc_branch;
434
 
435
 
436
--##############################################################################
437
-- Instruction decoding and IR
438
 
439
instruction_register:
440
process(clk)
441
begin
442
    if clk'event and clk='1' then
443
        if reset='1' then
444
            p1_ir_reg <= (others => '0');
445
        elsif stall_pipeline='0' then
446
            p1_ir_reg <= code_rd;
447
        end if;
448
    end if;
449
end process instruction_register;
450
 
451
-- 'Extract' main fields from IR, for convenience
452
p1_ir_op <= p1_ir_reg(31 downto 26);
453
p1_ir_fn <= p1_ir_reg(5 downto 0);
454
 
455
-- Decode jump type, if any, for instructions with op/=0
456
with p1_ir_op select p1_jump_type_set0 <=
457
    -- FIXME weed out invalid instructions
458
    "10" when "000001", -- BLTZ, BGEZ, BLTZAL, BGTZAL
459
    "11" when "000010", -- J
460
    "11" when "000011", -- JAL
461
    "10" when "000100", -- BEQ
462
    "10" when "000101", -- BNE
463
    "10" when "000110", -- BLEZ
464
    "10" when "000111", -- BGTZ
465
    "00" when others;   -- no jump
466
 
467
-- Decode jump type, if any, for instructions with op=0
468
p1_jump_type_set1 <= "11" when p1_op_special='1' and
469
                               p1_ir_reg(5 downto 1)="00100"
470
                     else "00";
471
 
472
-- Decode jump type for the instruction in IR (composite of two formats)
473
p1_jump_type <= p1_jump_type_set0 or p1_jump_type_set1;
474
 
475
p1_link <= '1' when (p1_ir_op="000000" and p1_ir_reg(5 downto 0)="001001") or
476
                    (p1_ir_op="000001" and p1_ir_reg(20)='1') or
477
                    (p1_ir_op="000011")
478
           else '0';
479
 
480
-- Decode jump condition: encode a mux control signal from IR...
481
p1_jump_cond_sel <=
482
    "001" when p1_ir_op="000001" and p1_ir_reg(16)='0' else --   op1 < 0   BLTZ*
483
    "101" when p1_ir_op="000001" and p1_ir_reg(16)='1' else -- !(op1 < 0) BNLTZ*
484
    "010" when p1_ir_op="000100" else                       --   op1 == op2  BEQ
485
    "110" when p1_ir_op="000101" else                       -- !(op1 == op2) BNE
486
    "011" when p1_ir_op="000110" else                       --   op1 <= 0   BLEZ
487
    "111" when p1_ir_op="000111" else                       -- !(op1 <= 0)  BGTZ
488
    "000";                                                  -- always
489
 
490
-- ... and use mux control signal to select the condition value
491
with p1_jump_cond_sel select p0_jump_cond_value <=
492
        p1_alu_flags.inp1_lt_zero       when "001",
493
    not p1_alu_flags.inp1_lt_zero       when "101",
494
        p1_alu_flags.inp1_eq_inp2       when "010",
495
    not p1_alu_flags.inp1_eq_inp2       when "110",
496
        (p1_alu_flags.inp1_lt_inp2 or
497
         p1_alu_flags.inp1_eq_inp2)     when "011",
498
    not (p1_alu_flags.inp1_lt_inp2 or
499
         p1_alu_flags.inp1_eq_inp2)     when "111",
500
    '1'                                 when others;
501
 
502
-- Decode instructions that launch exceptions
503
p1_exception <= '1' when p1_op_special='1' and p1_ir_reg(5 downto 1)="00110"
504
                else '0';
505
 
506
-- Decode MTC0/MFC0 instructions
507
p1_set_cp0 <= '1' when p1_ir_reg(31 downto 21)="01000000100" else '0';
508
p1_get_cp0 <= '1' when p1_ir_reg(31 downto 21)="01000000000" else '0';
509
 
510
-- FIXME elaborate and explain this
511
 
512
p1_op_special <= '1' when p1_ir_op="000000" else '0';
513
 
514
p1_do_reg_jump <= '1' when p1_op_special='1' and p1_ir_fn(5 downto 1)="00100" else '0';
515
p1_do_zero_ext_imm <= '1' when (p1_ir_op(31 downto 28)="0011") else '0';
516
 
517
-- Decode input data mux control (LW, LH, LB, LBU, LHU) and load enable
518 6 ja_rd
p1_do_load <= '1' when p1_ir_op(31 downto 29)="100" and
519
                       p2_exception='0'
520
              else '0';
521 2 ja_rd
 
522
p1_load_alu_set0 <= '1'
523
    when p1_op_special='1' and
524
        ((p1_ir_op(31 downto 29)="000" and p1_ir_op(27 downto 26)="00") or
525
         (p1_ir_op(31 downto 29)="000" and p1_ir_op(27 downto 26)="10") or
526
         (p1_ir_op(31 downto 29)="000" and p1_ir_op(27 downto 26)="11") or
527
         (p1_ir_op(31 downto 29)="000" and p1_ir_op(27 downto 26)="00") or
528
         (p1_ir_op(31 downto 28)="0100" and p1_ir_op(27 downto 26)="00") or
529
         (p1_ir_op(31 downto 28)="0100" and p1_ir_op(27 downto 26)="10") or
530
         (p1_ir_op(31 downto 28)="1000") or
531
         (p1_ir_op(31 downto 28)="1001") or
532
         (p1_ir_op(31 downto 28)="1010" and p1_ir_op(27 downto 26)="10") or
533
         (p1_ir_op(31 downto 28)="1010" and p1_ir_op(27 downto 26)="11") or
534
         (p1_ir_op(31 downto 28)="0010" and p1_ir_op(27 downto 26)="01"))
535
    else '0';
536
 
537
with p1_ir_op select p1_load_alu_set1 <=
538
    '1' when "001000",
539
    '1' when "001001",
540
    '1' when "001010",
541
    '1' when "001011",
542
    '1' when "001100",
543
    '1' when "001101",
544
    '1' when "001110",
545
    '1' when "001111",
546
    -- FIXME a few others missing: MFC0, etc
547
    '0' when others;
548
p1_load_alu <= p1_load_alu_set0 or p1_load_alu_set1;
549
 
550
p1_ld_upper_hword <= p1_ir_op(27); -- use input upper hword vs. sign extend/zero
551
p1_ld_upper_byte <= p1_ir_op(26);  -- use input upper byte vs. sign extend/zero
552
p1_ld_unsigned <= p1_ir_op(28);    -- sign extend vs. zero extend
553
 
554
-- ALU input-2 selection: use external data for 2x opcodes (loads)
555
p1_alu_op2_sel_set0 <=
556
    "11" when    p1_ir_op(31 downto 30)="10" or p1_ir_op(29)='1' else
557
    "00";
558
 
559
-- ALU input-2 selection: use registers Hi and Lo for MFHI, MFLO
560
with p1_ir_fn select p1_alu_op2_sel_set1 <=
561
    "01" when "010000",
562
    "10" when "010010",
563
    "00" when others;
564
 
565
-- ALU input-2 final selection
566
p1_alu_op2_sel <= p1_alu_op2_sel_set0 or p1_alu_op2_sel_set1;
567
 
568
-- Decode store operations
569
p1_do_store <= '1' when p1_ir_op(31 downto 29)="101" else '0';
570
p1_store_size <= p1_ir_op(27 downto 26);
571
 
572
 
573
-- Decode load enables for Hi and Lo registers (MTHI and MTLO)
574
p1_load_hi <= '1' when p1_op_special='1' and p1_ir_fn="010001" else '0';
575
p1_load_lo <= '1' when p1_op_special='1' and p1_ir_fn="010011" else '0';
576
 
577
-- Decode ALU control dignals
578
 
579
p1_ac.use_slt <= '1' when (p1_ir_op="000001" and p1_ir_reg(20 downto 17)="01000") or
580
                        (p1_ir_op="000000" and p1_ir_reg(5 downto 1)="10101") or
581
                        p1_ir_op="001010" or p1_ir_op="001011"
582
               else '0';
583
p1_ac.arith_unsigned <= p1_ac.use_slt and p1_ir_reg(0);
584
 
585
p1_ac.use_logic(0) <= '1' when (p1_op_special='1' and p1_ir_fn(5 downto 3)/="000") or
586
                    -- all immediate arith and logic
587
                    p1_ir_op(31 downto 29)="001"
588
                 else '0';
589
p1_ac.use_logic(1) <= '1' when (p1_op_special='1' and p1_ir_fn="100111") else '0';
590
 
591
p1_ac.use_arith <= '1' when p1_ir_op(31 downto 28)="0010" or
592
                            (p1_op_special='1' and
593
                                (p1_ir_fn(5 downto 2)="1000" or
594
                                p1_ir_fn(5 downto 2)="1010"))
595
                 else '0';
596
 
597
-- selection of 2nd internal alu operand: {i2, /i2, i2<<16, 0x0}
598
p1_ac.neg_sel(1)<= '1' when p1_ir_op(29 downto 26) = "1111" else '0';
599
p1_ac.neg_sel(0)<= '1' when   p1_ir_op="001010" or
600
                            p1_ir_op="001011" or
601
                            p1_ir_op(31 downto 28)="0001" or
602
                            (p1_op_special='1' and
603
                                (p1_ir_fn="100010" or
604
                                 p1_ir_fn="100011" or
605
                                 p1_ir_fn(5 downto 2)="1010"))
606
                 else '0';
607
p1_ac.cy_in <= p1_ac.neg_sel(0);
608
 
609
p1_ac.shift_sel <= p1_ir_fn(1 downto 0);
610
 
611
p1_ac.logic_sel <= "00" when (p1_op_special='1' and p1_ir_fn="100100") else
612
                 "01" when (p1_op_special='1' and p1_ir_fn="100101") else
613
                 "10" when (p1_op_special='1' and p1_ir_fn="100110") else
614
                 "01" when (p1_op_special='1' and p1_ir_fn="100111") else
615
                 "00" when (p1_ir_op="001100") else
616
                 "01" when (p1_ir_op="001101") else
617
                 "10" when (p1_ir_op="001110") else
618
                 "11";
619
 
620
p1_ac.shift_amount <= p1_ir_reg(10 downto 6) when p1_ir_fn(2)='0' else p1_rs(4 downto 0);
621
 
622
--------------------------------------------------------------------------------
623
 
624
-- Stage 1 pipeline register. Involved in ALU control.
625
pipeline_stage1_register:
626
process(clk)
627
begin
628
    if clk'event and clk='1' then
629
        if reset='1' then
630
            p1_rbank_rs_hazard <= '0';
631
            p1_rbank_rt_hazard <= '0';
632
        elsif stall_pipeline='0' then
633
            p1_rbank_rs_hazard <= p0_rbank_rs_hazard;
634
            p1_rbank_rt_hazard <= p0_rbank_rt_hazard;
635
        end if;
636
    end if;
637
end process pipeline_stage1_register;
638
 
639 6 ja_rd
 
640
-- Stage 2 pipeline register. Split in two for convenience.
641 2 ja_rd
-- This register deals with two kinds of stalls:
642
-- * When the pipeline stalls because of a load interlock, this register is 
643
--   allowed to update so that the load operation can complete while the rest of
644
--   the pipeline is frozen.
645
-- * When the stall is caused by any other reason, this register freezes with 
646
--   the rest of the machine.
647 6 ja_rd
 
648
-- Part of stage 2 register that controls load operation
649
pipeline_stage2_register_load_control:
650 2 ja_rd
process(clk)
651
begin
652
    if clk'event and clk='1' then
653 6 ja_rd
        -- Clear load control, effectively preventing load, at reset or if
654
        -- the previous instruction raised an exception.
655
        if reset='1' or p2_exception='1' then
656 2 ja_rd
            p2_do_load <= '0';
657
            p2_ld_upper_hword <= '0';
658
            p2_ld_upper_byte <= '0';
659
            p2_ld_unsigned <= '0';
660
            p2_load_target <= "00000";
661 6 ja_rd
 
662
        -- Load signals from previous stage only if there is no pipeline stall
663
        -- unless the stall is caused by interlock (@note1).
664
        elsif (stall_pipeline='0' or load_interlock='1') then
665
            -- Disable reg bank writeback if pipeline is stalled; this prevents
666
            -- duplicate writes in case the stall is a mem_wait.
667 2 ja_rd
            if pipeline_stalled='0' then
668
                p2_do_load <= p1_do_load;
669
            else
670
                p2_do_load <= '0';
671
            end if;
672
            p2_load_target <= p1_rd_num;
673
            p2_ld_upper_hword <= p1_ld_upper_hword;
674
            p2_ld_upper_byte <= p1_ld_upper_byte;
675
            p2_ld_unsigned <= p1_ld_unsigned;
676 6 ja_rd
        end if;
677
    end if;
678
end process pipeline_stage2_register_load_control;
679
 
680
-- All the rest of the stage 2 register
681
pipeline_stage2_register_others:
682
process(clk)
683
begin
684
    if clk'event and clk='1' then
685
        if reset='1' then
686
            p2_exception <= '0';
687
 
688
        -- Load signals from previous stage only if there is no pipeline stall
689
        -- unless the stall is caused by interlock (@note1).
690
        elsif (stall_pipeline='0' or load_interlock='1') then
691 2 ja_rd
            p2_rd_addr <= p1_data_addr(1 downto 0);
692 6 ja_rd
            p2_exception <= p1_exception;
693 2 ja_rd
        end if;
694
    end if;
695 6 ja_rd
end process pipeline_stage2_register_others;
696 2 ja_rd
 
697
--------------------------------------------------------------------------------
698
 
699
-- FIXME stall when needed: mem pause, mdiv pause and load interlock
700
 
701
pipeline_stall_registers:
702
process(clk)
703
begin
704
    if clk'event and clk='1' then
705
        if reset='1' then
706
            pipeline_stalled <= '0';
707
            pipeline_interlocked <= '0';
708
        else
709
            if stall_pipeline='1' then
710
                pipeline_stalled <= '1';
711
            else
712
                pipeline_stalled <= '0';
713
            end if;
714
            if load_interlock='1' then
715
                pipeline_interlocked <= '1';
716
            else
717
                pipeline_interlocked <= '0';
718
            end if;
719
        end if;
720
    end if;
721
end process pipeline_stall_registers;
722
 
723
-- FIXME make sure this combinational will not have bad glitches
724
stall_pipeline <= mem_wait or load_interlock;
725
 
726
 
727
-- FIXME load interlock should happen only if the instruction following 
728
-- the load actually uses the load target register. Something like this:
729
-- (p1_do_load='1' and (p1_rd_num=p0_rs_num or p1_rd_num=p0_rt_num))
730
load_interlock <= '1' when (p1_do_load='1' and pipeline_stalled='0') else '0';
731
 
732
--------------------------------------------------------------------------------
733
 
734
p1_data_offset(31 downto 16) <= (others => p1_data_imm(15));
735
p1_data_offset(15 downto 0) <= p1_data_imm(15 downto 0);
736
 
737
p1_data_addr <= p1_rs + p1_data_offset;
738
 
739
--------------------------------------------------------------------------------
740
 
741
-- byte_we is a function of the write size and alignment
742
-- size = {00=1,01=2,11=4}; we 3 is MSB, 0 is LSB; big endian => 00 is msb
743
p1_we_control <= pipeline_stalled & p1_do_store & p1_store_size & p1_data_addr(1 downto 0);
744
 
745
with p1_we_control select byte_we <=
746
    "1000"  when "010000",    -- SB %0
747
    "0100"  when "010001",    -- SB %1
748
    "0010"  when "010010",    -- SB %2
749
    "0001"  when "010011",    -- SB %3
750
    "1100"  when "010100",    -- SH %0
751
    "0011"  when "010110",    -- SH %2
752
    "1111"  when "011100",    -- SW %4
753
    "0000"  when others; -- all other combinations are spurious so don't write
754
 
755
-- Data to be stored always comes straight from the reg bank, but it needs to 
756
-- be shifted so that the LSB is aligned to the write address:
757
 
758
data_wr(7 downto 0) <= p1_rt(7 downto 0);
759
 
760
with p1_we_control select data_wr(15 downto 8) <=
761
    p1_rt( 7 downto  0) when "010010",  -- SB %2
762
    p1_rt(15 downto  8) when others;
763
 
764
with p1_we_control select data_wr(23 downto 16) <=
765
    p1_rt( 7 downto  0) when "010001",  -- SB %1
766
    p1_rt( 7 downto  0) when "010100",  -- SH %0
767
    p1_rt(23 downto 16) when others;
768
 
769
with p1_we_control select data_wr(31 downto 24) <=
770
    p1_rt( 7 downto  0) when "010000",  -- SB %0
771
    p1_rt(15 downto  8) when "010100",  -- SH %0
772
    p1_rt(31 downto 24) when others;
773
 
774
 
775
--##############################################################################
776
-- CP0 (what little is implemented of it)
777
 
778
process(clk)
779
begin
780
    if clk'event and clk='1' then
781
        if reset='1' then
782
            -- "10" => mode=kernel; ints=disabled
783
            cp0_status <= "10";
784
        else
785
            -- no need to check for stall cycles when loading these
786
            if p1_set_cp0='1' then
787
                -- FIXME check for CP0 reg index
788
                cp0_status <= p1_rs(cp0_status'high downto 0);
789
            end if;
790
            if p1_exception='1' then
791 8 ja_rd
                cp0_epc <= p0_pc_restart;
792 2 ja_rd
            end if;
793
        end if;
794
    end if;
795
end process;
796
 
797
-- FIXME the mux should mask to zero for any unused reg index
798
cp0_reg_read <= X"0000000" & "00" & cp0_status when p1_rd_num="01100" else
799
                cp0_epc & "00";
800
 
801
end architecture rtl;
802
 
803
--------------------------------------------------------------------------------
804
-- Implementation notes
805
--------------------------------------------------------------------------------
806
-- @note1 : 
807
--
808
-- This is the meaning of these two signals:
809
-- pipeline_stalled & pipeline_interlocked =>
810
--  "00" => normal state
811
--  "01" => normal state (makes for easier decoding)
812
--  "10" => all stages of pipeline stalled, including rbank
813
--  "11" => all stages of pipeline stalled, except reg bank write port
814
-- 
815
-- Just to clarify, 'stage X stalled' here means that the registers named 
816
-- pX_* don't load.
817
--
818
-- The register bank WE is enabled when the pipeline is not stalled and when 
819
-- it is stalled because of a load interlock; so that in case of interlock the
820
-- load operation can complete while the rest of the pipeline is frozen.
821
--------------------------------------------------------------------------------

powered by: WebSVN 2.1.0

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