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

Subversion Repositories scarts

[/] [scarts/] [trunk/] [processor/] [VHDL/] [scarts_core/] [core.vhd] - Blame information for rev 3

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 3 jlechner
-----------------------------------------------------------------------
2
-- This file is part of SCARTS.
3
-- 
4
-- SCARTS is free software: you can redistribute it and/or modify
5
-- it under the terms of the GNU General Public License as published by
6
-- the Free Software Foundation, either version 3 of the License, or
7
-- (at your option) any later version.
8
-- 
9
-- SCARTS is distributed in the hope that it will be useful,
10
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
11
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
-- GNU General Public License for more details.
13
-- 
14
-- You should have received a copy of the GNU General Public License
15
-- along with SCARTS.  If not, see <http://www.gnu.org/licenses/>.
16
-----------------------------------------------------------------------
17
 
18
 
19
library ieee;
20
use ieee.std_logic_1164.all;
21
use ieee.numeric_std.all;
22
 
23
use work.scarts_core_pkg.all;
24
use work.scarts_pkg.all;
25
 
26
entity scarts_core is
27
  generic (
28
    CONF : scarts_conf_type);
29
  port (
30
    clk   : in  std_ulogic;
31
    sysrst : in  std_ulogic;
32
    hold  : in  std_ulogic;
33
 
34
    iramo_rdata       : in INSTR;
35
    irami_wdata       : out INSTR;
36
    irami_waddr       : out std_logic_vector(CONF.instr_ram_size-1 downto 0);
37
    irami_wen         : out std_ulogic;
38
    irami_raddr       : out std_logic_vector(CONF.instr_ram_size-1 downto 0);
39
 
40
    regfi_wdata       : out std_logic_vector(CONF.word_size-1 downto 0);
41
    regfi_waddr       : out std_logic_vector(REGADDR_W-1 downto 0);
42
    regfi_wen         : out std_ulogic;
43
    regfi_raddr1      : out std_logic_vector(REGADDR_W-1 downto 0);
44
    regfi_raddr2      : out std_logic_vector(REGADDR_W-1 downto 0);
45
    regfo_rdata1      : in  std_logic_vector(CONF.word_size-1 downto 0);
46
    regfo_rdata2      : in  std_logic_vector(CONF.word_size-1 downto 0);
47
 
48
    corei_interruptin : in  std_logic_vector(15 downto 0);
49
    corei_extdata     : in  std_logic_vector(CONF.word_size-1 downto 0);
50
    coreo_extwr       : out std_ulogic;
51
    coreo_signedac    : out std_ulogic;
52
    coreo_extaddr     : out std_logic_vector(CONF.word_size-1 downto 0);
53
    coreo_extdata     : out std_logic_vector(CONF.word_size-1 downto 0);
54
    coreo_memaccess   : out MEMACCESSTYPE;
55
    coreo_memen       : out std_ulogic;
56
    coreo_illop       : out std_ulogic;
57
 
58
    bromi_addr        : out std_logic_vector(CONF.word_size-1 downto 0);
59
    bromo_data        : in  INSTR;
60
 
61
    vecti_data_in     : out std_logic_vector(CONF.word_size-1 downto 0);
62
    vecti_interruptnr : out std_logic_vector(EXCADDR_W-2 downto 0);
63
    vecti_trapnr      : out std_logic_vector(EXCADDR_W-1 downto 0);
64
    vecti_wrvecnr     : out std_logic_vector(EXCADDR_W-1 downto 0);
65
    vecti_intcmd      : out std_ulogic;
66
    vecti_wrvecen     : out std_ulogic;
67
    vecto_data_out    : in  std_logic_vector(CONF.word_size-1 downto 0);
68
 
69
    sysci_staen       : out std_ulogic;
70
    sysci_stactrl     : out STACTRL;
71
    sysci_staflag     : out std_logic_vector(ALUFLAG_W-1 downto 0);
72
    sysci_interruptin : out std_logic_vector(15 downto 0);
73
    sysci_fptrwnew    : out std_logic_vector(CONF.word_size-1 downto 0);
74
    sysci_fptrxnew    : out std_logic_vector(CONF.word_size-1 downto 0);
75
    sysci_fptrynew    : out std_logic_vector(CONF.word_size-1 downto 0);
76
    sysci_fptrznew    : out std_logic_vector(CONF.word_size-1 downto 0);
77
 
78
    sysco_condflag    : in  std_ulogic;
79
    sysco_carryflag   : in  std_ulogic;
80
    sysco_interruptnr : in  std_logic_vector(EXCADDR_W-2 downto 0);
81
    sysco_intcmd      : in  std_ulogic;
82
    sysco_fptrw       : in  std_logic_vector(CONF.word_size-1 downto 0);
83
    sysco_fptrx       : in  std_logic_vector(CONF.word_size-1 downto 0);
84
    sysco_fptry       : in  std_logic_vector(CONF.word_size-1 downto 0);
85
    sysco_fptrz       : in  std_logic_vector(CONF.word_size-1 downto 0);
86
 
87
    progo_instrsrc    : in  std_ulogic;
88
    progo_prupdate    : in  std_ulogic;
89
    progo_praddr      : in  std_logic_vector(CONF.instr_ram_size-1 downto 0);
90
    progo_prdata      : in  INSTR);
91
end scarts_core;
92
 
93
architecture behaviour of scarts_core is
94
 
95
constant WORD_W : natural := CONF.word_size;
96
 
97
subtype WORD is std_logic_vector(WORD_W-1 downto 0);
98
 
99
constant ZEROVALUE : WORD := (others => '0');
100
 
101
type fetch_stage_reg_type is record
102
  pcnt        : WORD;
103
  jmpdest     : WORD;
104
  jmpexe      : std_ulogic;
105
end record;
106
 
107
type decode_reg_type is record
108
  illop       : std_ulogic;
109
  regfwr      : std_ulogic;
110
  vectabwr    : std_ulogic;
111
  memen       : std_ulogic;
112
  memaccess   : MEMACCESSTYPE;
113
  memwr       : std_ulogic;
114
  staen       : std_ulogic;
115
  stactrl     : STACTRL;
116
  trap        : std_ulogic;
117
  jmpexe      : std_ulogic;
118
  jmpctrl     : JMPCTRL;
119
  aluctrl     : ALUCTRL;
120
  fptrupdate  : std_ulogic;
121
end record;
122
 
123
type decode_fix_reg_type is record
124
  imm         : WORD;
125
  signedac    : std_ulogic;
126
  negdata2    : std_ulogic;
127
  carry       : CARRYCTRL;
128
  useimm      : std_ulogic;
129
  usepc       : std_ulogic;
130
  fptr        : std_ulogic;
131
end record;
132
 
133
type decode_stage_reg_type is record
134
  dec         : decode_reg_type;
135
  decfix      : decode_fix_reg_type;
136
  pcnt        : WORD;
137
  vectabaddr  : std_logic_vector(EXCADDR_W-1 downto 0);
138
  regfaddr1   : REGADDR;
139
  regfaddr2   : REGADDR;
140
  fptrsel     : std_logic_vector(1 downto 0);
141
  fptrinc     : std_ulogic;
142
  alusrc1     : ALUSRCCTRL;
143
  alusrc2     : ALUSRCCTRL;
144
  condop1     : std_ulogic;
145
  condop2     : std_ulogic;
146
  condition   : std_ulogic;
147
  normalop    : std_ulogic;
148
end record;
149
 
150
type execute_stage_reg_type is record
151
  result      : WORD;
152
  regfwr      : std_ulogic;
153
  vectabaddr  : std_logic_vector(EXCADDR_W-1 downto 0);
154
  vectabwr    : std_ulogic;
155
  regfaddr    : REGADDR;
156
  wbsrc       : WBSRCCTRL;
157
end record;
158
 
159
type writeb_stage_reg_type is record
160
  result      : WORD;
161
end record;
162
 
163
type reg_type is record
164
  f   : fetch_stage_reg_type;
165
  d   : decode_stage_reg_type;
166
  e   : execute_stage_reg_type;
167
  w   : writeb_stage_reg_type;
168
end record;
169
 
170
--
171
-- for 16-bit version
172
--
173
function my_sll1 (vec : WORD;
174
                  cnt : std_logic_vector(3 downto 0))
175
                  return WORD is
176
variable result : WORD;
177
begin
178
  result := vec;
179
  for i in 0 to 3 loop
180
    if cnt(i) = '1' then
181
      result := result(result'high-2**i downto 0) & ZEROVALUE(2**i downto 1);
182
    end if;
183
  end loop;
184
  return result;
185
end;
186
 
187
--
188
-- for 32-bit version
189
--
190
function my_sll2 (vec : WORD;
191
                  cnt : std_logic_vector(4 downto 0))
192
                  return WORD is
193
variable result : WORD;
194
begin
195
  result := vec;
196
  for i in 0 to 4 loop
197
    if cnt(i) = '1' then
198
      result := result(result'high-2**i downto 0) & ZEROVALUE(2**i downto 1);
199
    end if;
200
  end loop;
201
  return result;
202
end;
203
 
204
--
205
-- for 16-bit version
206
--
207
function my_sr1 (vec : WORD;
208
                 cnt : std_logic_vector(3 downto 0);
209
                 fillbit : std_ulogic)
210
                 return WORD is
211
variable result : WORD;
212
variable fillvec : std_logic_vector(15 downto 0);
213
begin
214
  result := vec;
215
  fillvec := (others => fillbit);
216
  for i in 0 to 3 loop
217
    if cnt(i) = '1' then
218
      result := fillvec(2**i downto 1) & result(result'high downto 2**i);
219
    end if;
220
  end loop;
221
  return result;
222
end;
223
 
224
--
225
-- for 32-bit version
226
--
227
function my_sr2 (vec : WORD;
228
                 cnt : std_logic_vector(4 downto 0);
229
                 fillbit : std_ulogic)
230
                 return WORD is
231
variable result : WORD;
232
variable fillvec : std_logic_vector(31 downto 0);
233
begin
234
  result := vec;
235
  fillvec := (others => fillbit);
236
  for i in 0 to 4 loop
237
    if cnt(i) = '1' then
238
      result := fillvec(2**i downto 1) & result(WORD_W-1 downto 2**i);
239
    end if;
240
  end loop;
241
  return result;
242
end;
243
 
244
--
245
-- program counter
246
--
247
function pc (jmpexe : std_ulogic;
248
             jmpaddr, pc :WORD)
249
             return WORD is
250
variable instraddr : WORD;
251
begin
252
  if jmpexe = JMP_EXE then
253
    instraddr := jmpaddr;
254
  else
255
    instraddr := std_logic_vector(unsigned(pc) + 1);
256
  end if;
257
  return(instraddr);
258
end;
259
 
260
 
261
procedure decode (instr : INSTR;
262
                  decfix : out decode_fix_reg_type;
263
                  decvar : out decode_reg_type) is
264
variable v : decode_reg_type;
265
variable f : decode_fix_reg_type;
266
begin
267
  f.imm       := (others => '0');
268
  v.aluctrl   := ALU_NOP;
269
  v.illop     := not ILLOP;
270
  v.regfwr    := not REGF_WR;
271
  v.vectabwr  := not VECTAB_WR;
272
  v.memen     := not MEM_EN;
273
  v.memaccess := MEM_DISABLE;
274
  v.memwr     := not MEM_WR;
275
  v.staen     := not STA_EN;
276
  v.stactrl   := SET_FLAG;
277
  v.jmpexe    := not JMP_EXE;
278
  v.jmpctrl   := NO_SAVE;
279
  v.trap      := not TRAP_ACT;
280
  f.signedac  := not SIGNED_AC;
281
  f.fptr      := '0';
282
  v.fptrupdate := '0';
283
  f.useimm    := '0';
284
  f.usepc     := '0';
285
  f.negdata2  := '0';
286
  f.carry     := CARRY_IN;
287
 
288
 
289
  case instr(15 downto 12) is
290
    when "0000" =>
291
      -- LDLI
292
      v.regfwr := REGF_WR;
293
      f.imm := (others => instr(11));
294
      f.imm(7 downto 0) := instr(11 downto 4);
295
      v.aluctrl := ALU_BYPR2;
296
      f.useimm    := '1';
297
    when "0001" =>
298
      -- LDHI
299
      v.regfwr := REGF_WR;
300
      if CONF.word_size = 32 then
301
        f.imm := (others => instr(11));
302
      end if;
303
      f.imm(15 downto 8) := instr(11 downto 4);
304
      f.imm(7 downto 0) := (others => '0');
305
      v.aluctrl := ALU_LDHI;
306
      f.useimm    := '1';
307
    when "0010" =>
308
      -- LDLIU
309
      v.regfwr := REGF_WR;
310
      f.imm(15 downto 8) := (others => '0');
311
      f.imm(7 downto 0) := instr(11 downto 4);
312
      v.aluctrl := ALU_LDLIU;
313
      f.useimm    := '1';
314
    when "0011" =>
315
      if (instr(11) = '0') then
316
        -- CMPI_LT
317
        f.imm := (others => instr(10));
318
        f.imm(6 downto 0) := instr(10 downto 4);
319
        v.aluctrl := ALU_CMPLT;
320
        v.staen := STA_EN;
321
        v.stactrl := SET_COND;
322
        f.useimm    := '1';
323
        f.carry := CARRY_ONE;
324
        f.negdata2 := '1';
325
      else
326
        -- CMPI_GT
327
        f.imm := (others => instr(10));
328
        f.imm(6 downto 0) := instr(10 downto 4);
329
        v.aluctrl := ALU_CMPGT;
330
        v.staen := STA_EN;
331
        v.stactrl := SET_COND;
332
        f.useimm    := '1';
333
        f.carry := CARRY_ONE;
334
        f.negdata2 := '1';
335
      end if;
336
    when "0100" =>
337
      -- LDFP_INC/DEC
338
      v.fptrupdate := '1';
339
      v.memen := MEM_EN;
340
      v.regfwr := REGF_WR;
341
      f.imm := (others => instr(8));
342
      f.imm(4 downto 0) := instr(8 downto 4);
343
      f.fptr := '1';
344
      if CONF.word_size = 32 then
345
        v.memaccess := WORD_A;
346
      else
347
        v.memaccess := HWORD_A;
348
      end if;
349
    when "0101" =>
350
      -- STFP_INC/DEC
351
      v.fptrupdate := '1';
352
      v.memwr := MEM_WR;
353
      f.imm := (others => instr(8));
354
      f.imm(4 downto 0) := instr(8 downto 4);
355
      f.fptr := '1';
356
      if CONF.word_size = 32 then
357
        v.memaccess := WORD_A;
358
      else
359
        v.memaccess := HWORD_A;
360
      end if;
361
    when "0110" =>
362
      -- LDFP
363
      v.memen := MEM_EN;
364
      v.regfwr := REGF_WR;
365
      f.imm := (others => instr(9));
366
      f.imm(5 downto 0) := instr(9 downto 4);
367
      f.fptr := '1';
368
      if CONF.word_size = 32 then
369
        v.memaccess := WORD_A;
370
      else
371
        v.memaccess := HWORD_A;
372
      end if;
373
    when "0111" =>
374
      -- STFP
375
      v.memwr := MEM_WR;
376
      f.imm := (others => instr(9));
377
      f.imm(5 downto 0) := instr(9 downto 4);
378
      f.fptr := '1';
379
      if CONF.word_size = 32 then
380
        v.memaccess := WORD_A;
381
      else
382
        v.memaccess := HWORD_A;
383
      end if;
384
    when "1011" =>
385
      case instr(11 downto 8) is
386
        when "0000" =>
387
          -- CMP_EQ
388
          v.aluctrl := ALU_CMPEQ;
389
          v.staen := STA_EN;
390
          v.stactrl := SET_COND;
391
          f.carry := CARRY_ONE;
392
          f.negdata2 := '1';
393
        when "0001" =>
394
          -- CMP_LT
395
          v.aluctrl := ALU_CMPLT;
396
          v.staen := STA_EN;
397
          v.stactrl := SET_COND;
398
          f.carry := CARRY_ONE;
399
          f.negdata2 := '1';
400
        when "0010" =>
401
          -- CMP_GT
402
          v.aluctrl := ALU_CMPGT;
403
          v.staen := STA_EN;
404
          v.stactrl := SET_COND;
405
          f.carry := CARRY_ONE;
406
          f.negdata2 := '1';
407
       when "0011" =>
408
          -- CMPU_LT
409
          v.aluctrl := ALU_CMPULT;
410
          v.staen := STA_EN;
411
          v.stactrl := SET_COND;
412
          f.carry := CARRY_ONE;
413
          f.negdata2 := '1';
414
        when "0100" =>
415
          -- CMPU_GT
416
          v.aluctrl := ALU_CMPUGT;
417
          v.staen := STA_EN;
418
          v.stactrl := SET_COND;
419
          f.carry := CARRY_ONE;
420
          f.negdata2 := '1';
421
        when "0110" | "0111" =>
422
          -- BTEST
423
          v.aluctrl := ALU_AND;
424
          f.imm(to_integer(unsigned(instr(CONF.word_size/16+6 downto 4)))) := '1';
425
          v.staen := STA_EN;
426
          v.stactrl := SET_COND;
427
          f.useimm    := '1';
428
        when "1000" | "1001" | "1010" | "1011" |
429
                "1100" | "1101" | "1110" | "1111" =>
430
          -- CMPI_EQ
431
          f.imm := (others => instr(10));
432
          f.imm(6 downto 0) := instr(10 downto 4);
433
          v.aluctrl := ALU_CMPEQ;
434
          v.staen := STA_EN;
435
          v.stactrl := SET_COND;
436
          f.useimm    := '1';
437
          f.carry := CARRY_ONE;
438
          f.negdata2 := '1';
439
        when others =>
440
          v.illop := ILLOP;
441
      end case;
442
    when "1000" | "1001" | "1010" =>
443
      case instr(11 downto 9) is
444
        when "000" =>
445
          -- SL
446
          v.regfwr := REGF_WR;
447
          v.aluctrl := ALU_SL;
448
          v.staen := STA_EN;
449
          f.imm(3 downto 0) := instr(7 downto 4);
450
          if (instr(8) = '1') then
451
            f.useimm    := '1';
452
          end if;
453
        when "001" =>
454
          -- SR
455
          v.regfwr := REGF_WR;
456
          v.aluctrl := ALU_SR;
457
          v.staen := STA_EN;
458
          f.imm(3 downto 0) := instr(7 downto 4);
459
          if (instr(8) = '1') then
460
            f.useimm    := '1';
461
          end if;
462
        when "010" =>
463
          -- BSET
464
          v.regfwr := REGF_WR;
465
          v.aluctrl := ALU_OR;
466
          f.imm(to_integer(unsigned(instr(CONF.word_size/16+6 downto 4)))) := '1';
467
          v.staen := STA_EN;
468
          f.useimm    := '1';
469
        when "011" =>
470
          -- BCLR
471
          v.regfwr := REGF_WR;
472
          v.aluctrl := ALU_AND;
473
          f.imm := (others => '1');
474
          f.imm(to_integer(unsigned(instr(CONF.word_size/16+6 downto 4)))) := '0';
475
          v.staen := STA_EN;
476
          f.useimm    := '1';
477
        when "100" | "101" =>
478
          -- ADDI
479
          v.regfwr := REGF_WR;
480
          f.imm := (others => instr(9));
481
          f.imm(5 downto 0) := instr(9 downto 4);
482
          v.aluctrl := ALU_ADD;
483
          v.staen := STA_EN;
484
          f.useimm    := '1';
485
          f.carry := CARRY_ZERO;
486
        when "110" | "111" =>
487
          -- JMPI
488
          v.jmpexe := JMP_EXE;
489
          f.imm := (others => instr(9));
490
          f.imm(9 downto 0) := instr(9 downto 0);
491
          v.aluctrl := ALU_ADD;
492
          f.useimm  := '1';
493
          f.usepc   := '1';
494
          f.carry := CARRY_ZERO;
495
        when others => null;
496
      end case;
497
    when "1100" | "1101" | "1110" =>
498
      case instr(11 downto 8) is
499
        when "0000" =>
500
          -- MOV
501
          v.regfwr := REGF_WR;
502
          v.aluctrl := ALU_BYPR2;
503
        when "0001" =>
504
          -- ADD
505
          v.regfwr := REGF_WR;
506
          v.aluctrl := ALU_ADD;
507
          v.staen := STA_EN;
508
          f.carry := CARRY_ZERO;
509
        when "0010" =>
510
          -- ADDC
511
          v.regfwr := REGF_WR;
512
          v.aluctrl := ALU_ADD;
513
          v.staen := STA_EN;
514
          f.carry := CARRY_IN;
515
        when "0011" =>
516
          -- SUB
517
          v.regfwr := REGF_WR;
518
          v.aluctrl := ALU_SUB;
519
          v.staen := STA_EN;
520
          f.carry := CARRY_ONE;
521
          f.negdata2 := '1';
522
        when "0100" =>
523
          -- SUBC
524
          v.regfwr := REGF_WR;
525
          v.aluctrl := ALU_SUB;
526
          v.staen := STA_EN;
527
          f.carry := CARRY_NOT;
528
          f.negdata2 := '1';
529
        when "0101" =>
530
          -- AND
531
          v.regfwr := REGF_WR;
532
          v.aluctrl := ALU_AND;
533
          v.staen := STA_EN;
534
        when "0110" =>
535
          -- OR
536
          v.regfwr := REGF_WR;
537
          v.aluctrl := ALU_OR;
538
          v.staen := STA_EN;
539
        when "0111" =>
540
          -- EOR
541
          v.regfwr := REGF_WR;
542
          v.aluctrl := ALU_EOR;
543
          v.staen := STA_EN;
544
        when "1000" =>
545
          -- SRA
546
          v.regfwr := REGF_WR;
547
          v.aluctrl := ALU_SRA;
548
          v.staen := STA_EN;
549
        when "1001" =>
550
          -- SRA
551
          v.regfwr := REGF_WR;
552
          v.aluctrl := ALU_SRA;
553
          v.staen := STA_EN;
554
          f.imm(3 downto 0) := instr(7 downto 4);
555
          f.useimm    := '1';
556
        when "1010" =>
557
          -- RRC
558
          v.regfwr := REGF_WR;
559
          v.aluctrl := ALU_RRC;
560
          v.staen := STA_EN;
561
        when "1011" =>
562
          -- TRAP
563
          v.jmpexe := JMP_EXE;
564
          v.aluctrl := ALU_BYPEXC;
565
          v.jmpctrl := SAVE_EXC;
566
          v.staen := STA_EN;
567
          v.stactrl := SAVE_SR;
568
          v.regfwr := REGF_WR;
569
          v.trap := TRAP_ACT;
570
        when "1100" =>
571
          -- NOT
572
          v.regfwr := REGF_WR;
573
          v.aluctrl := ALU_NOT;
574
          v.staen := STA_EN;
575
        when "1101" =>
576
          -- NEG
577
          v.regfwr := REGF_WR;
578
          v.aluctrl := ALU_NEG;
579
          v.staen := STA_EN;
580
        when "1110" =>
581
          -- JSR
582
          v.regfwr := REGF_WR;
583
          v.aluctrl := ALU_BYPR1;
584
          v.jmpexe := JMP_EXE;
585
          v.jmpctrl := SAVE_JMP;
586
        when "1111" =>
587
          -- JMP
588
          v.jmpexe := JMP_EXE;
589
          v.aluctrl := ALU_BYPR1;
590
          v.jmpctrl := NO_SAVE;
591
        when others => null;
592
      end case;
593
    when "1111" =>
594
      case instr(11 downto 8) is
595
        when "0000" =>
596
          -- LDW
597
          if CONF.word_size = 32 then
598
            v.memen := MEM_EN;
599
            v.regfwr := REGF_WR;
600
            v.memaccess := WORD_A;
601
          else
602
            v.illop := ILLOP;
603
          end if;
604
        when "0001" =>
605
          -- LDH
606
            v.memen := MEM_EN;
607
            v.regfwr := REGF_WR;
608
            v.memaccess := HWORD_A;
609
            f.signedac := SIGNED_AC;
610
        when "0010" =>
611
          -- LDHU
612
          if CONF.word_size = 32 then
613
            v.memen := MEM_EN;
614
            v.regfwr := REGF_WR;
615
            v.memaccess := HWORD_A;
616
          else
617
            v.illop := ILLOP;
618
          end if;
619
        when "0011" =>
620
          -- LDB
621
            v.memen := MEM_EN;
622
            v.regfwr := REGF_WR;
623
            f.signedac := SIGNED_AC;
624
            v.memaccess := BYTE_A;
625
        when "0100" =>
626
          -- LDBU
627
            v.memen := MEM_EN;
628
            v.regfwr := REGF_WR;
629
            v.memaccess := BYTE_A;
630
        when "0101" =>
631
          -- STW
632
          if CONF.word_size = 32 then
633
            v.memwr := MEM_WR;
634
            v.memaccess := WORD_A;
635
          else
636
            v.illop := ILLOP;
637
          end if;
638
        when "0110" =>
639
          -- STH
640
            v.memwr := MEM_WR;
641
            v.memaccess := HWORD_A;
642
        when "0111" =>
643
          -- STB
644
            v.memwr := MEM_WR;
645
            v.memaccess := BYTE_A;
646
        when "1000" =>
647
          -- RTS
648
          v.jmpexe := JMP_EXE;
649
          v.aluctrl := ALU_BYPR1;
650
        when "1001" =>
651
          -- RTE
652
          v.jmpexe := JMP_EXE;
653
          v.aluctrl := ALU_BYPR1;
654
          v.staen := STA_EN;
655
          v.stactrl := REST_SR;
656
        when "1010" | "1011" =>
657
          -- LDVEC
658
          v.aluctrl := ALU_BYPEXC;
659
          v.regfwr := REGF_WR;
660
        when "1100" | "1101" =>
661
          -- STVEC
662
          v.vectabwr := VECTAB_WR;
663
          v.aluctrl := ALU_BYPR1;
664
       when "1110" =>
665
          -- NOP
666
          null;
667
        when "1111" =>
668
          -- ILLOP
669
          v.illop := ILLOP;
670
        when others => null;
671
      end case;
672
    when others => null;
673
  end case;
674
  decfix := f;
675
  decvar := v;
676
end;
677
 
678
procedure alu (data1, data2 : WORD;
679
               excvec : WORD;
680
               aluctrl : ALUCTRL;
681
               carryin : std_ulogic;
682
               staflag : out ALUFLAG;
683
               result : out WORD) is
684
variable op1, op2, fulladderresult : std_logic_vector(WORD_W downto 0);
685
variable vcarryin : std_logic_vector(0 downto 0);
686
variable vcarryout : std_ulogic;
687
variable vresult, adderresult : WORD;
688
begin
689
  vresult := (others => '0');
690
  staflag := (others => '0');
691
 
692
  op1(WORD_W) := '0';
693
  op1(WORD_W-1 downto 0) := data1;
694
  op2(WORD_W) := '0';
695
  op2(WORD_W-1 downto 0) := data2;
696
  vcarryin(0) := carryin;
697
  fulladderresult := std_logic_vector(unsigned(op1) + unsigned(op2) + unsigned(vcarryin));
698
  vcarryout := fulladderresult(WORD_W);
699
  adderresult := fulladderresult(WORD_W-1 downto 0);
700
 
701
  case aluctrl is
702
    when ALU_NOP =>
703
      null;
704
 
705
    when ALU_LDLIU =>
706
      vresult(WORD_W-1 downto 8) := data1(WORD_W-1 downto 8);
707
      vresult(7 downto 0) := data2(7 downto 0);
708
 
709
    when ALU_LDHI =>
710
      vresult(WORD_W-1 downto 8) := data2(WORD_W-1 downto 8);
711
      vresult(7 downto 0) := data1(7 downto 0);
712
 
713
    when ALU_AND =>
714
      vresult := data1 and data2;
715
      if vresult /= ZEROVALUE then
716
        staflag(COND) := '1';
717
      end if;
718
 
719
    when ALU_OR =>
720
      vresult := data1 or data2;
721
 
722
    when ALU_EOR =>
723
      vresult := data1 xor data2;
724
 
725
    when ALU_ADD =>
726
      vresult := adderresult;
727
      staflag(CARRY) := vcarryout;
728
 
729
    when ALU_SUB =>
730
      vresult := adderresult;
731
      staflag(CARRY) := not vcarryout;
732
 
733
    when ALU_CMPEQ =>
734
      if adderresult = ZEROVALUE then
735
        staflag(COND) := '1';
736
      end if;
737
 
738
    when ALU_CMPUGT =>
739
      if adderresult /= ZEROVALUE then
740
        staflag(COND) := vcarryout;
741
      end if;
742
 
743
    when ALU_CMPULT =>
744
      staflag(COND) := not vcarryout;
745
 
746
    when ALU_CMPGT =>
747
      if data1(WORD_W-1) /= data2(WORD_W-1) then
748
        if adderresult = ZEROVALUE then
749
          staflag(COND) := adderresult(WORD_W-1);
750
        else
751
          staflag(COND) := not adderresult(WORD_W-1);
752
        end if;
753
      else
754
        staflag(COND) := not data1(WORD_W-1);
755
      end if;
756
 
757
    when ALU_CMPLT =>
758
      if data1(WORD_W-1) /= data2(WORD_W-1) then
759
          staflag(COND) := adderresult(WORD_W-1);
760
      else
761
        staflag(COND) :=  data1(WORD_W-1);
762
      end if;
763
 
764
    when ALU_NOT =>
765
      vresult := not data1;
766
 
767
    when ALU_NEG =>
768
      vresult := std_logic_vector(unsigned(not data1) + 1);
769
 
770
    when ALU_SL =>
771
      if CONF.word_size = 16 then
772
        vresult := my_sll1(data1, data2(3 downto 0));
773
      else
774
        vresult := my_sll2(data1, data2(4 downto 0));
775
      end if;
776
      staflag(CARRY) := data1(WORD_W-1);
777
 
778
    when ALU_SR =>
779
      if CONF.word_size = 16 then
780
        vresult := my_sr1(data1, data2(3 downto 0),'0');
781
       else
782
        vresult := my_sr2(data1, data2(4 downto 0),'0');
783
      end if;
784
      staflag(CARRY) := data1(0);
785
 
786
    when ALU_SRA =>
787
      if CONF.word_size = 16 then
788
        vresult := my_sr1(data1, data2(3 downto 0),data1(WORD_W-1));
789
       else
790
        vresult := my_sr2(data1, data2(4 downto 0),data1(WORD_W-1));
791
      end if;
792
      staflag(CARRY) := data1(0);
793
 
794
    when ALU_RRC =>
795
      vresult(WORD_W-2 downto 0) := data1(WORD_W-1 downto 1);
796
      vresult(WORD_W-1) := carryin;
797
      staflag(CARRY)  := data1(0);
798
 
799
    when ALU_BYPR1 =>
800
      vresult := data1;
801
 
802
    when ALU_BYPR2 =>
803
      vresult := data2;
804
 
805
    when ALU_BYPEXC =>
806
      vresult := excvec;
807
 
808
    when others => null;
809
  end case;
810
 
811
  if vresult = ZEROVALUE then
812
    staflag(ZERO) := '1';
813
  end if;
814
 
815
  if data1(WORD_W-1) = data2(WORD_W-1) then
816
    staflag(OVER) := vresult(WORD_W-1) xor data1(WORD_W-1);
817
  end if;
818
 
819
  staflag(NEG) := vresult(WORD_W-1);
820
 
821
  result := vresult;
822
end;
823
 
824
--
825
-- Tests if it is a conditional instruction
826
--
827
function eval_cond (condop1   : std_ulogic;
828
                    condop2   : std_ulogic;
829
                    condition : std_ulogic;
830
                    condflag  : std_ulogic
831
                   ) return std_ulogic is
832
variable notinstrexe : std_ulogic;
833
begin
834
  notinstrexe := '0';
835
  if (condop1 = COND_INSTR) and (condop2 = '0') then
836
    notinstrexe := condition xor condflag;
837
  end if;
838
  return notinstrexe;
839
end;
840
 
841
signal r_next : reg_type;
842
signal r : reg_type := (
843
    f => (
844
      pcnt    => (others =>'1'),
845
      jmpdest => (others =>'0'),
846
      jmpexe  => '0'
847
      ),
848
    d => (
849
      dec => (
850
        aluctrl   => ALU_NOP,
851
        illop     => '0',
852
        regfwr    => '0',
853
        vectabwr  => '0',
854
        memen     => '0',
855
        memaccess => MEM_DISABLE,
856
        memwr     => '0',
857
        staen     => '0',
858
        stactrl   => SET_FLAG,
859
        jmpexe    => '0',
860
        jmpctrl   => NO_SAVE,
861
        trap      => '0',
862
        fptrupdate => '0'
863
        ),
864
      decfix => (
865
        imm    => (others => '0'),
866
        signedac  => '0',
867
        fptr      => '0',
868
        useimm    => '0',
869
        usepc     => '0',
870
        negdata2  => '0',
871
        carry     => CARRY_IN
872
        ),
873
      fptrsel       => (others =>'0'),
874
      fptrinc       => '0',
875
      pcnt          => (others =>'0'),
876
      vectabaddr    => (others =>'0'),
877
      regfaddr1     => (others =>'0'),
878
      regfaddr2     => (others =>'0'),
879
      alusrc1       => REGF_SRC,
880
      alusrc2       => REGF_SRC,
881
      condop1       => '0',
882
      condop2       => '0',
883
      condition     => '0',
884
      normalop      => '0'
885
      ),
886
    e => (
887
      result   => (others =>'0'),
888
      regfwr   => '0',
889
      vectabwr => '0',
890
      regfaddr => (others =>'0'),
891
      wbsrc    => ALU_SRC,
892
      vectabaddr    => (others =>'0')
893
      ),
894
    w => (
895
    result   => (others =>'0')
896
    )
897
);
898
 
899
signal s_wbresult : WORD;
900
signal s_condregfwr, s_condjmpexe, s_condstaen : std_ulogic;
901
constant INST_ADDR_NULL : std_logic_vector (WORD_W-1 downto CONF.bootrom_base_address) := (others => '0');
902
 
903
begin
904
 
905
 
906
  comb : process(r, corei_interruptin, corei_extdata, bromo_data, regfo_rdata1, regfo_rdata2, iramo_rdata, vecto_data_out,
907
                 sysco_condflag, sysco_carryflag, sysco_interruptnr, sysco_intcmd, sysco_fptrw, sysco_fptrx,
908
                 sysco_fptry, sysco_fptrz, s_wbresult,
909
                 progo_instrsrc, progo_prupdate, progo_praddr, progo_prdata,
910
                 s_condregfwr, s_condjmpexe, s_condstaen)
911
 
912
    variable v : reg_type;
913
    variable decinstr : INSTR := (others => '0');
914
    variable exedata1, exedata2 : WORD := (others => '0');
915
    variable v_aludata2 : WORD := (others => '0');
916
    variable regfdata1, regfdata2 : WORD := (others => '0');
917
    variable staflag : ALUFLAG := (others => '0');
918
    variable notinstrexe : std_ulogic := '0';
919
    variable decbuffer : decode_reg_type;
920
    variable regfiaddr : REGADDR := (others => '0');
921
    variable v_fptr : WORD := (others => '0');
922
    variable v_carry : std_ulogic := '0';
923
 
924
  begin
925
    v := r;
926
    exedata2 := (others => '0');
927
    -- fetch stage
928
    v.f.jmpexe := s_condjmpexe;
929
    v.f.pcnt := pc(r.f.jmpexe, r.f.jmpdest, r.f.pcnt);
930
    -- fetch output
931
    irami_raddr <= v.f.pcnt(CONF.instr_ram_size-1 downto 0);
932
    bromi_addr(WORD_W-1 downto CONF.bootrom_base_address)
933
        <= std_logic_vector(UNSIGNED(v.f.pcnt(WORD_W-1 downto CONF.bootrom_base_address)) - 1);
934
--    bromi_addr(CONF.bootrom_base_address) <= not v.f.pcnt(CONF.bootrom_base_address);
935
    bromi_addr(CONF.bootrom_base_address-1 downto 0) <= v.f.pcnt(CONF.bootrom_base_address-1 downto 0);
936
 
937
    --
938
    -- fetch stage end
939
    --
940
    -- decode stage begin
941
    --
942
 
943
    -- decode input
944
    if r.f.jmpexe = JMP_EXE then
945
      decinstr := NOP;
946
    else
947
      --
948
      -- decides if instructions are taken from bootrom or instruction-RAM
949
      --
950
 
951
--      MWA: the BOOTROM shall be mapped permanently into the address space.
952
--      this way, the instruction src selection bit of the programmer module
953
--      becomes obsolete (the instruction source is determined solely by the
954
--      program counter value)
955
 
956
--      if GDB_MODE_C = 1 then
957
        if r.f.pcnt(WORD_W-1 downto CONF.bootrom_base_address) /= INST_ADDR_NULL then
958
          decinstr := bromo_data;
959
        else
960
          decinstr := iramo_rdata;
961
        end if;
962
--      else -- Not GDB-mode
963
--        if progo_instrsrc = BROM_SEL then
964
--          decinstr := bromo_data;
965
--        else
966
--          decinstr := iramo_rdata;
967
--        end if;
968
--      end if;
969
    end if;
970
 
971
    -- decode stage
972
    decode(decinstr, v.d.decfix, decbuffer);
973
 
974
    v.d.dec.aluctrl   := ALU_NOP;
975
    v.d.dec.illop     := not ILLOP;
976
    v.d.dec.regfwr    := not REGF_WR;
977
    v.d.dec.vectabwr  := not VECTAB_WR;
978
    v.d.dec.memen     := not MEM_EN;
979
    v.d.dec.memaccess := MEM_DISABLE ;
980
    v.d.dec.memwr     := not MEM_WR;
981
    v.d.dec.staen     := not STA_EN;
982
    v.d.dec.jmpexe    := not JMP_EXE;
983
    v.d.dec.trap      := not TRAP_ACT;
984
    v.d.dec.fptrupdate := '0';
985
    v.d.fptrsel       := decinstr(11 downto 10);
986
    v.d.fptrinc       := decinstr(9);
987
    v.d.regfaddr1     := decinstr(3 downto 0);
988
    v.d.regfaddr2     := decinstr(7 downto 4);
989
    v.d.vectabaddr    := decinstr(8 downto 4);
990
    v.d.condop1       := decinstr(15);
991
    v.d.condop2       := decinstr(13);
992
    v.d.condition     := decinstr(12);
993
    --
994
    -- if a jump is in action, save destination address
995
    -- as program counter.
996
    -- Important if an interrupt occurs during jump
997
    --
998
    if r.f.jmpexe=JMP_EXE then
999
      v.d.pcnt        := r.f.jmpdest;
1000
    else
1001
      v.d.pcnt        := r.f.pcnt;
1002
    end if;
1003
 
1004
 
1005
    v.d.normalop := '0';
1006
    if sysco_intcmd = EXC_ACT then
1007
      -- interrupt
1008
      if r.d.dec.stactrl = SAVE_SR then
1009
        v.d.dec.staen := not STA_EN;
1010
      else
1011
        v.d.dec.staen := STA_EN;
1012
      end if;
1013
      v.d.dec.stactrl := SAVE_SR;
1014
      v.d.dec.regfwr := REGF_WR;
1015
      v.d.dec.jmpexe := JMP_EXE;
1016
      v.d.dec.jmpctrl := SAVE_EXC;
1017
      v.d.dec.aluctrl := ALU_BYPEXC;
1018
    elsif s_condjmpexe = JMP_EXE then
1019
      -- jump is executed
1020
      -- default assignments are used
1021
      null;
1022
    else
1023
      -- normal instruction
1024
      v.d.dec := decbuffer;
1025
      v.d.normalop := '1';
1026
    end if;
1027
 
1028
 
1029
    v.d.alusrc1 := REGF_SRC;
1030
    v.d.alusrc2 := REGF_SRC;
1031
 
1032
    -- decide forwarding for source-register 1
1033
    if v.d.decfix.usepc = '1' then
1034
      v.d.alusrc1 := DEC_SRC;
1035
    elsif (v.d.regfaddr1 = r.d.regfaddr1) and (s_condregfwr = REGF_WR) then
1036
      v.d.alusrc1 := EXE_SRC;
1037
    elsif (v.d.regfaddr1 = r.e.regfaddr) and (r.e.regfwr = REGF_WR) then
1038
      v.d.alusrc1 := WB_SRC;
1039
    end if;
1040
 
1041
    -- decide forwarding for source-register 2
1042
    if v.d.decfix.useimm = '1' then
1043
      v.d.alusrc2 := DEC_SRC;
1044
    elsif (v.d.regfaddr2 = r.d.regfaddr1) and (s_condregfwr = REGF_WR) then
1045
      v.d.alusrc2 := EXE_SRC;
1046
    elsif (v.d.regfaddr2 = r.e.regfaddr) and (r.e.regfwr = REGF_WR) then
1047
      v.d.alusrc2 := WB_SRC;
1048
    end if;
1049
 
1050
    -- decode output
1051
    regfi_raddr1 <= v.d.regfaddr1;
1052
    regfi_raddr2 <= v.d.regfaddr2;
1053
 
1054
    --
1055
    -- decode stage end
1056
 
1057
    -- execute stage begin
1058
    --
1059
 
1060
    -- execute input
1061
    regfdata1 := regfo_rdata1;
1062
    regfdata2 := regfo_rdata2;
1063
 
1064
    -- execute stage
1065
    coreo_illop <= r.d.dec.illop;
1066
 
1067
    notinstrexe := '0';
1068
    if r.d.normalop = '1' then
1069
      notinstrexe := eval_cond(r.d.condop1, r.d.condop2, r.d.condition, sysco_condflag);
1070
    end if;
1071
 
1072
    if notinstrexe = '1' then
1073
      s_condregfwr <= not REGF_WR;
1074
      s_condjmpexe <= not JMP_EXE;
1075
      s_condstaen <= not STA_EN;
1076
    else
1077
      s_condregfwr <= r.d.dec.regfwr;
1078
      s_condjmpexe <= r.d.dec.jmpexe;
1079
      s_condstaen <= r.d.dec.staen;
1080
    end if;
1081
 
1082
    v.e.regfwr := s_condregfwr;
1083
    v.e.vectabwr := r.d.dec.vectabwr;
1084
    v.e.vectabaddr := r.d.vectabaddr;
1085
--    v.e.memen := r.d.dec.memen;
1086
 
1087
    case r.d.alusrc1 is
1088
      when REGF_SRC =>
1089
        exedata1 := regfdata1;
1090
      when EXE_SRC =>
1091
        exedata1 := s_wbresult;
1092
      when WB_SRC =>
1093
        exedata1 := r.w.result;
1094
      when DEC_SRC =>
1095
        exedata1 := r.d.pcnt;
1096
      when others => null;
1097
    end case;
1098
 
1099
    case r.d.alusrc2 is
1100
      when REGF_SRC =>
1101
        exedata2 := regfdata2;
1102
      when EXE_SRC =>
1103
        exedata2 := s_wbresult;
1104
      when WB_SRC =>
1105
        exedata2 := r.w.result;
1106
      when DEC_SRC =>
1107
        exedata2 := r.d.decfix.imm;
1108
      when others => null;
1109
    end case;
1110
 
1111
    case r.d.decfix.carry is
1112
      when CARRY_IN =>
1113
        v_carry := sysco_carryflag;
1114
      when CARRY_NOT =>
1115
        v_carry := not sysco_carryflag;
1116
      when CARRY_ZERO =>
1117
        v_carry := '0';
1118
      when CARRY_ONE =>
1119
        v_carry := '1';
1120
      when others => null;
1121
    end case;
1122
 
1123
    if r.d.decfix.negdata2 = '1' then
1124
      v_aludata2 := not exedata2;
1125
    else
1126
      v_aludata2 := exedata2;
1127
    end if;
1128
 
1129
    alu(exedata1, v_aludata2, vecto_data_out, r.d.dec.aluctrl, v_carry, staflag, v.e.result);
1130
    v.f.jmpdest := v.e.result;
1131
 
1132
    v.e.regfaddr := (others => '0');
1133
    case r.d.dec.jmpctrl is
1134
      when SAVE_JMP =>
1135
        -- normal jump => save program counter of fetch stage
1136
        v.e.result := r.f.pcnt;
1137
        v.e.regfaddr := std_logic_vector(to_unsigned(SUBRETREG,REGADDR_W));
1138
      when SAVE_EXC =>
1139
        if r.d.dec.trap = not TRAP_ACT then
1140
            if r.f.jmpexe=JMP_EXE then
1141
              -- if jump is in progress => save destination address
1142
              v.e.result            := r.f.jmpdest;
1143
            else
1144
              -- normal operation => save program counter of discarded instruction
1145
              v.e.result            := r.d.pcnt;
1146
            end if;
1147
          v.e.regfaddr := std_logic_vector(to_unsigned(EXCRETREG,REGADDR_W));
1148
        else
1149
          v.e.result:= r.f.pcnt;
1150
          v.e.regfaddr := std_logic_vector(to_unsigned(EXCRETREG,REGADDR_W));
1151
        end if;
1152
      when NO_SAVE =>
1153
        -- jump without return
1154
        v.e.result := v.e.result;
1155
        v.e.regfaddr := r.d.regfaddr1;
1156
      when others =>
1157
        null;
1158
    end case;
1159
    --frame pointer
1160
    v_fptr := (others => '0');
1161
    sysci_fptrwnew <= sysco_fptrw;
1162
    sysci_fptrxnew <= sysco_fptrx;
1163
    sysci_fptrynew <= sysco_fptry;
1164
    sysci_fptrznew <= sysco_fptrz;
1165
    case r.d.fptrsel is
1166
      when "00" =>
1167
          v_fptr := sysco_fptrw;
1168
        if r.d.dec.fptrupdate = '1' then
1169
          if r.d.fptrinc = '0' then
1170
            sysci_fptrwnew(WORD_W-1 downto CONF.word_size/16) <= std_logic_vector(unsigned(sysco_fptrw(WORD_W-1 downto CONF.word_size/16)) + 1);
1171
          else
1172
            sysci_fptrwnew(WORD_W-1 downto CONF.word_size/16) <= std_logic_vector(unsigned(sysco_fptrw(WORD_W-1 downto CONF.word_size/16)) - 1);
1173
          end if;
1174
        end if;
1175
      when "01" =>
1176
          v_fptr := sysco_fptrx;
1177
        if r.d.dec.fptrupdate = '1' then
1178
          if r.d.fptrinc = '0' then
1179
            sysci_fptrxnew(WORD_W-1 downto CONF.word_size/16) <= std_logic_vector(unsigned(sysco_fptrx(WORD_W-1 downto CONF.word_size/16)) + 1);
1180
          else
1181
            sysci_fptrxnew(WORD_W-1 downto CONF.word_size/16) <= std_logic_vector(unsigned(sysco_fptrx(WORD_W-1 downto CONF.word_size/16)) - 1);
1182
          end if;
1183
        end if;
1184
      when "10" =>
1185
          v_fptr := sysco_fptry;
1186
        if r.d.dec.fptrupdate = '1' then
1187
          if r.d.fptrinc = '0' then
1188
            sysci_fptrynew(WORD_W-1 downto CONF.word_size/16) <= std_logic_vector(unsigned(sysco_fptry(WORD_W-1 downto CONF.word_size/16)) + 1);
1189
          else
1190
            sysci_fptrynew(WORD_W-1 downto CONF.word_size/16) <= std_logic_vector(unsigned(sysco_fptry(WORD_W-1 downto CONF.word_size/16)) - 1);
1191
          end if;
1192
        end if;
1193
      when "11" =>
1194
          v_fptr := sysco_fptrz;
1195
        if r.d.dec.fptrupdate = '1' then
1196
          if r.d.fptrinc = '0' then
1197
            sysci_fptrznew(WORD_W-1 downto CONF.word_size/16) <= std_logic_vector(unsigned(sysco_fptrz(WORD_W-1 downto CONF.word_size/16)) + 1);
1198
          else
1199
            sysci_fptrznew(WORD_W-1 downto CONF.word_size/16) <= std_logic_vector(unsigned(sysco_fptrz(WORD_W-1 downto CONF.word_size/16)) - 1);
1200
          end if;
1201
        end if;
1202
      when others => null;
1203
    end case;
1204
    v_fptr(WORD_W-1 downto CONF.word_size/16) := std_logic_vector(unsigned(v_fptr(WORD_W-1 downto CONF.word_size/16)) + unsigned(r.d.decfix.imm(WORD_W-CONF.word_size/16-1 downto 0)));
1205
    if r.d.decfix.fptr = '1' then
1206
      exedata2 := v_fptr;
1207
    end if;
1208
 
1209
    -- execute output
1210
    sysci_staflag <= staflag;
1211
    sysci_staen <= s_condstaen;
1212
    sysci_stactrl <= r.d.dec.stactrl;
1213
 
1214
    coreo_extwr <= r.d.dec.memwr;
1215
    coreo_memaccess <= r.d.dec.memaccess;
1216
    coreo_memen <= r.d.dec.memen;
1217
 
1218
    coreo_signedac <= r.d.decfix.signedac;
1219
    coreo_extaddr <= exedata2;
1220
    coreo_extdata <= exedata1;
1221
 
1222
    if r.d.dec.memen = MEM_EN then
1223
      v.e.wbsrc := MEM_SRC;
1224
    else
1225
      v.e.wbsrc := ALU_SRC;
1226
    end if;
1227
 
1228
    --
1229
    -- execute stage end
1230
    --
1231
    -- write back stage begin
1232
    --
1233
 
1234
    -- decides if memory access or normal operation
1235
    s_wbresult <= (others => '0');
1236
    case r.e.wbsrc is
1237
      when ALU_SRC =>
1238
        s_wbresult <= r.e.result;
1239
      when MEM_SRC =>
1240
        s_wbresult <= corei_extdata;
1241
      when others => null;
1242
    end case;
1243
 
1244
    v.w.result := s_wbresult;
1245
 
1246
    -- writeb output
1247
    regfi_wdata <= s_wbresult;
1248
    regfi_waddr <= r.e.regfaddr;
1249
    regfi_wen   <= r.e.regfwr;
1250
 
1251
    sysci_interruptin <= corei_interruptin;
1252
 
1253
    vecti_intcmd <= sysco_intcmd;
1254
    vecti_interruptnr <= sysco_interruptnr;
1255
    vecti_trapnr <= decinstr(8 downto 4);
1256
    vecti_wrvecnr <= r.e.vectabaddr;
1257
    vecti_data_in <= r.e.result;
1258
    vecti_wrvecen <= r.e.vectabwr;
1259
 
1260
 
1261
    irami_wdata <= progo_prdata;
1262
    irami_waddr <= progo_praddr(CONF.instr_ram_size-1 downto 0);
1263
    irami_wen <= progo_prupdate;
1264
 
1265
 
1266
    r_next <= v;
1267
  end process;
1268
 
1269
 
1270
  reg : process(clk)--, sysrst)
1271
  begin
1272
 
1273
    if rising_edge(clk) then
1274
      if sysrst = RST_ACT then
1275
 
1276
--        MWA: the execution shall always start at the BOOTROM
1277
 
1278
--        if GDB_MODE_C = 1 then
1279
          --  Start execution at adress 0x0 in Boot-Rom
1280
          --  Boot rom is mapped to 2**CONF.bootrom_base_address
1281
          r.f.pcnt(WORD_W-1 downto CONF.bootrom_base_address) <= (others =>'0');
1282
          r.f.pcnt(CONF.bootrom_base_address-1 downto 0) <= (others =>'1');
1283
--        else
1284
--          r.f.pcnt    <= (others =>'1');
1285
--        end if;
1286
        r.f.jmpdest <= (others =>'0');
1287
        r.f.jmpexe  <= '0';
1288
 
1289
        r.d.dec.aluctrl   <= ALU_NOP;
1290
        r.d.dec.illop     <= '0';
1291
        r.d.dec.regfwr    <= '0';
1292
        r.d.dec.vectabwr  <= '0';
1293
        r.d.dec.memen     <= '0';
1294
        r.d.dec.memaccess <= MEM_DISABLE;
1295
        r.d.dec.memwr     <= '0';
1296
        r.d.dec.staen     <= '0';
1297
        r.d.dec.stactrl   <= SET_FLAG;
1298
        r.d.dec.jmpexe    <= '0';
1299
        r.d.dec.jmpctrl   <= NO_SAVE;
1300
        r.d.dec.trap      <= '0';
1301
        r.d.dec.fptrupdate   <= '0';
1302
        r.d.decfix.imm    <= (others => '0');
1303
        r.d.decfix.signedac  <= '0';
1304
        r.d.decfix.fptr      <= '0';
1305
        r.d.decfix.useimm    <= '0';
1306
        r.d.decfix.usepc     <= '0';
1307
        r.d.decfix.negdata2  <= '0';
1308
        r.d.decfix.carry     <= CARRY_IN;
1309
        r.d.fptrsel       <= (others =>'0');
1310
        r.d.fptrinc       <= '0';
1311
        r.d.pcnt          <= (others =>'0');
1312
        r.d.vectabaddr    <= (others =>'0');
1313
        r.d.regfaddr1     <= (others =>'0');
1314
        r.d.regfaddr2     <= (others =>'0');
1315
        r.d.alusrc1       <= REGF_SRC;
1316
        r.d.alusrc2       <= REGF_SRC;
1317
        r.d.condop1       <= '0';
1318
        r.d.condop2       <= '0';
1319
        r.d.condition     <= '0';
1320
        r.d.normalop      <= '0';
1321
 
1322
        r.e.result   <= (others =>'0');
1323
        r.e.regfwr   <= '0';
1324
        r.e.vectabwr <= '0';
1325
--        r.e.regfaddr <= (others =>'0');
1326
        r.e.wbsrc    <= ALU_SRC;
1327
--        r.e.vectabaddr    <= (others =>'0');
1328
 
1329
            r.w.result   <= (others =>'0');
1330
 
1331
      else
1332
        if (hold = not HOLD_ACT) then
1333
          r <= r_next;
1334
        end if;
1335
      end if;
1336
    end if;
1337
  end process;
1338
 
1339
 
1340
end behaviour;

powered by: WebSVN 2.1.0

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