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

Subversion Repositories scarts

[/] [scarts/] [trunk/] [processor/] [VHDL/] [scarts_core/] [sysc.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_sysc is
27
  generic (
28
    CONF : scarts_conf_type);
29
  port (
30
    clk     : in  std_ulogic;
31
    extrst  : in  std_ulogic;
32
    sysrst  : out std_ulogic;
33
    hold    : in  std_ulogic;
34
    cpu_halt : out std_ulogic;
35
    extsel  : in std_ulogic;
36
    exti    : in  module_in_type;
37
    exto    : out module_out_type;
38
 
39
    staen       : in  std_ulogic;
40
    stactrl     : in  STACTRL;
41
    staflag     : in  std_logic_vector(ALUFLAG_W-1 downto 0);
42
    interruptin : in  std_logic_vector(15 downto 0);
43
    fptrwnew    : in  std_logic_vector(CONF.word_size-1 downto 0);
44
    fptrxnew    : in  std_logic_vector(CONF.word_size-1 downto 0);
45
    fptrynew    : in  std_logic_vector(CONF.word_size-1 downto 0);
46
    fptrznew    : in  std_logic_vector(CONF.word_size-1 downto 0);
47
 
48
    condflag    : out std_ulogic;
49
    carryflag   : out std_ulogic;
50
    interruptnr : out std_logic_vector(EXCADDR_W-2 downto 0);
51
    intcmd      : out std_ulogic;
52
    fptrw       : out std_logic_vector(CONF.word_size-1 downto 0);
53
    fptrx       : out std_logic_vector(CONF.word_size-1 downto 0);
54
    fptry       : out std_logic_vector(CONF.word_size-1 downto 0);
55
    fptrz       : out std_logic_vector(CONF.word_size-1 downto 0));
56
end scarts_sysc;
57
 
58
architecture behaviour of scarts_sysc is
59
 
60
  constant WORD_W : natural := CONF.word_size;
61
  subtype WORD is std_logic_vector(WORD_W-1 downto 0);
62
 
63
  subtype BYTE is std_logic_vector(7 downto 0);
64
  type register_set is array (0 to 24) of BYTE;
65
 
66
  constant STATUSREG_CUST : integer := 1;
67
  constant CONFIGREG_CUST : integer := 3;
68
 
69
  constant INT_PROT_LOW   : integer := 4;
70
  constant INT_PROT_HIGH  : integer := 5;
71
 
72
  constant INT_MASK_LOW   : integer := 6;
73
  constant INT_MASK_HIGH  : integer := 7;
74
 
75
  constant FPTRW_0        : integer := 8;
76
  constant FPTRW_1        : integer := 9;
77
  constant FPTRW_2        : integer := 10;
78
  constant FPTRW_3        : integer := 11;
79
 
80
  constant FPTRX_0        : integer := 12;
81
  constant FPTRX_1        : integer := 13;
82
  constant FPTRX_2        : integer := 14;
83
  constant FPTRX_3        : integer := 15;
84
 
85
  constant FPTRY_0        : integer := 16;
86
  constant FPTRY_1        : integer := 17;
87
  constant FPTRY_2        : integer := 18;
88
  constant FPTRY_3        : integer := 19;
89
 
90
  constant FPTRZ_0        : integer := 20;
91
  constant FPTRZ_1        : integer := 21;
92
  constant FPTRZ_2        : integer := 22;
93
  constant FPTRZ_3        : integer := 23;
94
 
95
  constant STATUSREG_CUST_SAVE : integer := 24;
96
 
97
  type reg_type is record
98
    ifacereg      : register_set;
99
    tmp_int_prot  : std_logic_vector(15 downto 0);
100
    savedsr       : std_ulogic;
101
    gie_backup    : std_logic;
102
    nmiact        : std_ulogic;
103
  end record;
104
 
105
 
106
  signal r_next : reg_type;
107
  signal r : reg_type := (
108
      ifacereg      => (INT_MASK_LOW => (others => '1'), INT_MASK_HIGH => (others => '1'), others => (others => '0')),
109
      tmp_int_prot  => (others => '0'),
110
      savedsr       => '0',
111
      gie_backup    => '0',
112
      nmiact        => '0');
113
 
114
  signal rstint : std_ulogic;
115
  signal int_hold : std_ulogic;
116
 
117
begin
118
 
119
  comb : process(r, staen, stactrl, staflag, interruptin, fptrwnew, fptrxnew, fptrynew, fptrznew,
120
                 exti, extsel, rstint, extrst, hold, int_hold)
121
  variable v : reg_type;
122
  variable v_interruptnr : std_logic_vector(EXCADDR_W-2 downto 0);
123
  variable v_intcmd : std_ulogic;
124
  begin
125
    v := r;
126
    v.ifacereg(FPTRW_0) := fptrwnew(7 downto 0);
127
    v.ifacereg(FPTRX_0) := fptrxnew(7 downto 0);
128
    v.ifacereg(FPTRY_0) := fptrynew(7 downto 0);
129
    v.ifacereg(FPTRZ_0) := fptrznew(7 downto 0);
130
 
131
    v.ifacereg(FPTRW_1) := fptrwnew(15 downto 8);
132
    v.ifacereg(FPTRX_1) := fptrxnew(15 downto 8);
133
    v.ifacereg(FPTRY_1) := fptrynew(15 downto 8);
134
    v.ifacereg(FPTRZ_1) := fptrznew(15 downto 8);
135
 
136
    if CONF.word_size = 32 then
137
      v.ifacereg(FPTRW_2) := fptrwnew(WORD_W-9 downto WORD_W-16);
138
      v.ifacereg(FPTRX_2) := fptrxnew(WORD_W-9 downto WORD_W-16);
139
      v.ifacereg(FPTRY_2) := fptrynew(WORD_W-9 downto WORD_W-16);
140
      v.ifacereg(FPTRZ_2) := fptrznew(WORD_W-9 downto WORD_W-16);
141
 
142
      v.ifacereg(FPTRW_3) := fptrwnew(WORD_W-1 downto WORD_W-8);
143
      v.ifacereg(FPTRX_3) := fptrxnew(WORD_W-1 downto WORD_W-8);
144
      v.ifacereg(FPTRY_3) := fptrynew(WORD_W-1 downto WORD_W-8);
145
      v.ifacereg(FPTRZ_3) := fptrznew(WORD_W-1 downto WORD_W-8);
146
    end if;
147
 
148
   --interrupts protokollieren
149
--    v.tmp_int_prot := interruptin;
150
--    v.ifacereg(INT_PROT_LOW) := r.ifacereg(INT_PROT_LOW) or interruptin(7 downto 0) or r.tmp_int_prot(7 downto 0);
151
--    v.ifacereg(INT_PROT_HIGH) := r.ifacereg(INT_PROT_HIGH) or interruptin(15 downto 8) or r.tmp_int_prot(15 downto 8);
152
 
153
 
154
    -- detect positve edge on interrupt lines and set flag in protocol register
155
    v.tmp_int_prot := interruptin;
156
    v.ifacereg(INT_PROT_LOW) := r.ifacereg(INT_PROT_LOW) or ((not r.tmp_int_prot(7 downto 0)) and interruptin(7 downto 0));
157
    v.ifacereg(INT_PROT_HIGH) := r.ifacereg(INT_PROT_HIGH) or ((not r.tmp_int_prot(15 downto 8)) and interruptin(15 downto 8));
158
 
159
    --schreiben
160
    if ((extsel = '1') and (exti.write_en = '1')) then
161
      case exti.addr(4 downto 2) is
162
        when "000" =>
163
          if ((exti.byte_en(0) = '1') or (exti.byte_en(1) = '1')) then
164
            v.ifacereg(STATUSREG)(STA_INT) := '1';
165
            v.ifacereg(CONFIGREG)(CONF_INTA) :='0';
166
          else
167
            if ((exti.byte_en(2) = '1')) then
168
              v.ifacereg(2) := exti.data(23 downto 16);
169
            end if;
170
            if ((exti.byte_en(3) = '1')) then
171
              v.ifacereg(3) := exti.data(31 downto 24);
172
            end if;
173
          end if;
174
        when "001" =>
175
          if ((exti.byte_en(0) = '1')) then
176
            v.ifacereg(4) := v.ifacereg(4) xor exti.data(7 downto 0);
177
          end if;
178
          if ((exti.byte_en(1) = '1')) then
179
            v.ifacereg(5) := v.ifacereg(5) xor exti.data(15 downto 8);
180
          end if;
181
          if ((exti.byte_en(2) = '1')) then
182
            v.ifacereg(6) := exti.data(23 downto 16);
183
          end if;
184
          if ((exti.byte_en(3) = '1')) then
185
            v.ifacereg(7) := exti.data(31 downto 24);
186
          end if;
187
        when "010" =>
188
          if ((exti.byte_en(0) = '1')) then
189
            v.ifacereg(8) := exti.data(7 downto 0);
190
          end if;
191
          if ((exti.byte_en(1) = '1')) then
192
            v.ifacereg(9) := exti.data(15 downto 8);
193
          end if;
194
          if CONF.word_size = 32 then
195
            if ((exti.byte_en(2) = '1')) then
196
              v.ifacereg(10) := exti.data(23 downto 16);
197
            end if;
198
            if ((exti.byte_en(3) = '1')) then
199
              v.ifacereg(11) := exti.data(31 downto 24);
200
            end if;
201
          end if;
202
        when "011" =>
203
          if ((exti.byte_en(0) = '1')) then
204
            v.ifacereg(12) := exti.data(7 downto 0);
205
          end if;
206
          if ((exti.byte_en(1) = '1')) then
207
            v.ifacereg(13) := exti.data(15 downto 8);
208
          end if;
209
          if CONF.word_size = 32 then
210
            if ((exti.byte_en(2) = '1')) then
211
              v.ifacereg(14) := exti.data(23 downto 16);
212
            end if;
213
            if ((exti.byte_en(3) = '1')) then
214
              v.ifacereg(15) := exti.data(31 downto 24);
215
            end if;
216
          end if;
217
        when "100" =>
218
          if ((exti.byte_en(0) = '1')) then
219
            v.ifacereg(16) := exti.data(7 downto 0);
220
          end if;
221
          if ((exti.byte_en(1) = '1')) then
222
            v.ifacereg(17) := exti.data(15 downto 8);
223
          end if;
224
          if CONF.word_size = 32 then
225
            if ((exti.byte_en(2) = '1')) then
226
              v.ifacereg(18) := exti.data(23 downto 16);
227
            end if;
228
            if ((exti.byte_en(3) = '1')) then
229
              v.ifacereg(19) := exti.data(31 downto 24);
230
            end if;
231
          end if;
232
        when "101" =>
233
          if ((exti.byte_en(0) = '1')) then
234
            v.ifacereg(20) := exti.data(7 downto 0);
235
          end if;
236
          if ((exti.byte_en(1) = '1')) then
237
            v.ifacereg(21) := exti.data(15 downto 8);
238
          end if;
239
          if CONF.word_size = 32 then
240
            if ((exti.byte_en(2) = '1')) then
241
              v.ifacereg(22) := exti.data(23 downto 16);
242
            end if;
243
            if ((exti.byte_en(3) = '1')) then
244
              v.ifacereg(23) := exti.data(31 downto 24);
245
            end if;
246
          end if;
247
        when "110" =>
248
          if ((exti.byte_en(0) = '1')) then
249
            v.ifacereg(24) := exti.data(7 downto 0);
250
          end if;
251
        when others =>
252
          null;
253
      end case;
254
    end if;
255
 
256
    -- Löschen des Interrupt Signals
257
    if r.ifacereg(STATUSREG)(STA_INT) = '1' and r.ifacereg(CONFIGREG)(CONF_INTA) ='1' then
258
      v.ifacereg(STATUSREG)(STA_INT) := '0';
259
    end if;
260
    exto.intreq <= r.ifacereg(STATUSREG)(STA_INT);
261
 
262
    --auslesen
263
    exto.data <= (others => '0');
264
    if ((extsel = '1') and (exti.write_en = '0')) then
265
      case exti.addr(4 downto 2) is
266
        when "000" =>
267
          exto.data <= r.ifacereg(3) & r.ifacereg(2) & r.ifacereg(1) & r.ifacereg(0);
268
        when "001" =>
269
          if (r.ifacereg(CONFIGREG)(CONF_ID) = '1') then
270
            exto.data <= MODULE_VER & MODULE_ID;
271
          else
272
            exto.data <= r.ifacereg(7) & r.ifacereg(6) & r.ifacereg(5) & r.ifacereg(4);
273
          end if;
274
        when "010" =>
275
          if CONF.word_size = 32 then
276
            exto.data <= r.ifacereg(11) & r.ifacereg(10) & r.ifacereg(9) & r.ifacereg(8);
277
          else
278
            exto.data <= "00000000"     & "00000000"     & r.ifacereg(9) & r.ifacereg(8);
279
          end if;
280
        when "011" =>
281
          if CONF.word_size = 32 then
282
            exto.data <= r.ifacereg(15) & r.ifacereg(14) & r.ifacereg(13) & r.ifacereg(12);
283
          else
284
            exto.data <= "00000000"     & "00000000"     & r.ifacereg(13) & r.ifacereg(12);
285
          end if;
286
        when "100" =>
287
          if CONF.word_size = 32 then
288
            exto.data <= r.ifacereg(19) & r.ifacereg(18) & r.ifacereg(17) & r.ifacereg(16);
289
          else
290
            exto.data <= "00000000"     & "00000000"     & r.ifacereg(17) & r.ifacereg(16);
291
          end if;
292
        when "101" =>
293
          if CONF.word_size = 32 then
294
            exto.data <= r.ifacereg(23) & r.ifacereg(22) & r.ifacereg(21) & r.ifacereg(20);
295
          else
296
            exto.data <= "00000000"     & "00000000"     & r.ifacereg(21) & r.ifacereg(20);
297
          end if;
298
        when "110" =>
299
          exto.data <= "00000000" & "00000000" & "00000000" & r.ifacereg(24);
300
        when others =>
301
          null;
302
      end case;
303
    end if;
304
 
305
    --berechnen der neuen status flags
306
    v.ifacereg(STATUSREG)(STA_LOOR) := r.ifacereg(CONFIGREG)(CONF_LOOW);
307
    v.ifacereg(STATUSREG)(STA_FSS) := '0';
308
    v.ifacereg(STATUSREG)(STA_RESH) := '0';
309
    v.ifacereg(STATUSREG)(STA_RESL) := '0';
310
    v.ifacereg(STATUSREG)(STA_BUSY) := '0';
311
    v.ifacereg(STATUSREG)(STA_ERR) := '0';
312
    v.ifacereg(STATUSREG)(STA_RDY) := '1';
313
--    if exti.extaddr(2 downto 1) = "11" then
314
--      v.ifacereg(STATUSREG)(STA_ERR) := '1';
315
--    end if;
316
 
317
    --module specific part
318
    --interupt handler
319
    v_interruptnr := (others => '0');
320
    v_intcmd := not EXC_ACT;
321
    v.ifacereg(INT_MASK_LOW)(0) := '0';
322
    if r.ifacereg(INT_PROT_LOW)(0) = '1' and r.nmiact = not EXC_ACT then
323
      --v_intcmd := EXC_ACT;
324
      v.nmiact := EXC_ACT;
325
      v_interruptnr := std_logic_vector(to_unsigned(0,EXCADDR_W-1));
326
      v.ifacereg(INT_MASK_LOW)(0) := '1';
327
      v.ifacereg(INT_PROT_LOW)(0) := '0';
328
    else
329
      for i in 1 to 7 loop
330
        if (r.ifacereg(INT_PROT_LOW)(i) = '1') and (r.ifacereg(INT_MASK_LOW)(i) = '0')
331
          and (r.ifacereg(INT_MASK_LOW)(0) = '0') and (r.ifacereg(CONFIGREG_CUST)(GIE) = '1') then
332
          v_intcmd := EXC_ACT;
333
          v_interruptnr := std_logic_vector(to_unsigned(i,EXCADDR_W-1));
334
          v.ifacereg(INT_MASK_LOW)(0) := '1';
335
          v.ifacereg(INT_PROT_LOW)(i) := '0';
336
        end if;
337
      end loop;
338
      for i in 0 to 7 loop
339
        if (r.ifacereg(INT_PROT_HIGH)(i) = '1') and (r.ifacereg(INT_MASK_HIGH)(i) = '0')
340
         and (r.ifacereg(INT_MASK_LOW)(0) = '0') and (r.ifacereg(CONFIGREG_CUST)(GIE) = '1') then
341
          v_intcmd := EXC_ACT;
342
          v_interruptnr := std_logic_vector(to_unsigned(i+8,EXCADDR_W-1));
343
          v.ifacereg(INT_MASK_LOW)(0) := '1';
344
          v.ifacereg(INT_PROT_HIGH)(i) := '0';
345
        end if;
346
      end loop;
347
    end if;
348
 
349
    --update der status flags
350
    if staen = STA_EN then
351
      case stactrl is
352
        when SET_FLAG =>
353
          v.ifacereg(STATUSREG_CUST)(ZERO) := staflag(ZERO);
354
          v.ifacereg(STATUSREG_CUST)(NEG) := staflag(NEG);
355
          v.ifacereg(STATUSREG_CUST)(CARRY) := staflag(CARRY);
356
          v.ifacereg(STATUSREG_CUST)(OVER) := staflag(OVER);
357
        when SET_COND =>
358
          v.ifacereg(STATUSREG_CUST)(COND) := staflag(COND);
359
          v.ifacereg(STATUSREG_CUST)(ZERO) := staflag(ZERO);
360
          v.ifacereg(STATUSREG_CUST)(NEG) := staflag(NEG);
361
          v.ifacereg(STATUSREG_CUST)(CARRY) := staflag(CARRY);
362
          v.ifacereg(STATUSREG_CUST)(OVER) := staflag(OVER);
363
        when SAVE_SR =>
364
          v.ifacereg(STATUSREG_CUST_SAVE) := r.ifacereg(STATUSREG_CUST);
365
          v.gie_backup := r.ifacereg(CONFIGREG_CUST)(GIE);
366
          v.ifacereg(STATUSREG_CUST) := (others => '0');
367
          v.ifacereg(CONFIGREG_CUST)(GIE) := '0';
368
          if v_intcmd = EXC_ACT then
369
            v.savedsr := '1';
370
          end if;
371
        when REST_SR =>
372
          v.nmiact := not EXC_ACT;
373
          if r.savedsr = '1' then
374
            v.savedsr := '0';
375
          else
376
            v.ifacereg(STATUSREG_CUST) := r.ifacereg(STATUSREG_CUST_SAVE);
377
            v.ifacereg(CONFIGREG_CUST)(GIE) := r.gie_backup;
378
          end if;
379
        when others => null;
380
      end case;
381
    end if;
382
 
383
    --soft- und hard-reset vereinen
384
    rstint <= not RST_ACT;
385
    if extrst = RST_ACT or r.ifacereg(CONFIGREG)(CONF_SRES) = '1' then
386
      rstint <= RST_ACT;
387
    end if;
388
 
389
    -- output
390
    condflag <= r.ifacereg(STATUSREG_CUST)(COND);
391
    carryflag <= r.ifacereg(STATUSREG_CUST)(CARRY);
392
    interruptnr <= v_interruptnr;
393
    intcmd <= v_intcmd;
394
    sysrst <= rstint;
395
 
396
 
397
    fptrw(7 downto 0)   <=    r.ifacereg(FPTRW_0) ;
398
    fptrx(7 downto 0)   <=    r.ifacereg(FPTRX_0) ;
399
    fptry(7 downto 0)   <=    r.ifacereg(FPTRY_0) ;
400
    fptrz(7 downto 0)   <=    r.ifacereg(FPTRZ_0) ;
401
 
402
    fptrw(15 downto 8)  <=    r.ifacereg(FPTRW_1) ;
403
    fptrx(15 downto 8)  <=    r.ifacereg(FPTRX_1) ;
404
    fptry(15 downto 8)  <=    r.ifacereg(FPTRY_1) ;
405
    fptrz(15 downto 8)  <=    r.ifacereg(FPTRZ_1) ;
406
 
407
    if CONF.word_size = 32 then
408
      fptrw(WORD_W-9 downto WORD_W-16) <=    r.ifacereg(FPTRW_2) ;
409
      fptrx(WORD_W-9 downto WORD_W-16) <=    r.ifacereg(FPTRX_2) ;
410
      fptry(WORD_W-9 downto WORD_W-16) <=    r.ifacereg(FPTRY_2) ;
411
      fptrz(WORD_W-9 downto WORD_W-16) <=    r.ifacereg(FPTRZ_2) ;
412
 
413
      fptrw(WORD_W-1 downto WORD_W-8) <=    r.ifacereg(FPTRW_3) ;
414
      fptrx(WORD_W-1 downto WORD_W-8) <=    r.ifacereg(FPTRX_3) ;
415
      fptry(WORD_W-1 downto WORD_W-8) <=    r.ifacereg(FPTRY_3) ;
416
      fptrz(WORD_W-1 downto WORD_W-8) <=    r.ifacereg(FPTRZ_3) ;
417
    end if;
418
 
419
    if (v_intcmd = EXC_ACT) then
420
      v.ifacereg(CONFIGREG_CUST)(SLEEP) := '0';
421
    end if;
422
    int_hold <= hold or r.ifacereg(CONFIGREG_CUST)(SLEEP);
423
    cpu_halt <= int_hold;
424
 
425
    r_next <= v;
426
  end process;
427
 
428
  reg : process(clk)--, rstint)
429
  begin
430
    if rising_edge(clk) then
431
      if rstint = RST_ACT then
432
        r.ifacereg      <= (INT_MASK_LOW => (others => '1'), INT_MASK_HIGH => (others => '1'), others => (others => '0'));
433
        r.tmp_int_prot  <= (others => '0');
434
        r.savedsr       <= '0';
435
        r.gie_backup    <= '0';
436
        r.nmiact        <= not EXC_ACT;
437
      else
438
        if (int_hold = not HOLD_ACT) then
439
          r <= r_next;
440
        end if;
441
        r.tmp_int_prot <= r_next.tmp_int_prot;
442
        r.ifacereg(CONFIGREG_CUST)(SLEEP) <= r_next.ifacereg(CONFIGREG_CUST)(SLEEP);
443
      end if;
444
    end if;
445
  end process;
446
 
447
end behaviour;

powered by: WebSVN 2.1.0

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