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

Subversion Repositories ion

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

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

powered by: WebSVN 2.1.0

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