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

Subversion Repositories the_wizardry_project

[/] [the_wizardry_project/] [trunk/] [Wizardry/] [VHDL/] [Wizardry Top Level/] [Address Generation/] [JOP/] [mem_sc.vhd] - Blame information for rev 22

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 22 mcwaccent
--
2
--
3
--  This file is a part of JOP, the Java Optimized Processor
4
--
5
--  Copyright (C) 2001-2008, Martin Schoeberl (martin@jopdesign.com)
6
--
7
--  This program is free software: you can redistribute it and/or modify
8
--  it under the terms of the GNU General Public License as published by
9
--  the Free Software Foundation, either version 3 of the License, or
10
--  (at your option) any later version.
11
--
12
--  This program is distributed in the hope that it will be useful,
13
--  but WITHOUT ANY WARRANTY; without even the implied warranty of
14
--  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
--  GNU General Public License for more details.
16
--
17
--  You should have received a copy of the GNU General Public License
18
--  along with this program.  If not, see <http://www.gnu.org/licenses/>.
19
--
20
 
21
 
22
--
23
--      mem_sc.vhd
24
--
25
--      External memory interface with SimpCon.
26
--      Translates between JOP/extension memory interface
27
--      and SimpCon memory interface.
28
--      Does the method cache load.
29
--
30
--
31
--      todo:
32
--
33
--      2005-11-22  first version adapted from mem(_wb)
34
--      2006-06-15      removed unnecessary state in BC load
35
--                              len decrement in bc_rn and exit from bc_wr
36
--      2007-04-13      Changed memory connection to records
37
--      2007-04-14      xaload and xastore in hardware
38
--      2008-02-19      put/getfield in hardware
39
--      2008-04-30  copy step in hardware
40
--      2008-10-10      correct array access for fast (SPM) memory (+iald23 state)
41
--
42
 
43
Library IEEE;
44
use IEEE.std_logic_1164.all;
45
use ieee.numeric_std.all;
46
 
47
use work.jop_types.all;
48
use work.sc_pack.all;
49
 
50
entity mem_sc is
51
generic (jpc_width : integer; block_bits : integer);
52
 
53
port (
54
 
55
-- jop interface
56
 
57
        clk, reset      : in std_logic;
58
 
59
        ain             : in std_logic_vector(31 downto 0);              -- TOS
60
        bin             : in std_logic_vector(31 downto 0);              -- NOS
61
 
62
-- exceptions
63
 
64
        np_exc          : out std_logic;
65
        ab_exc          : out std_logic;
66
 
67
-- extension connection
68
        mem_in          : in mem_in_type;
69
        mem_out         : out mem_out_type;
70
 
71
-- jbc connections
72
 
73
        jbc_addr        : in std_logic_vector(jpc_width-1 downto 0);
74
        jbc_data        : out std_logic_vector(7 downto 0);
75
 
76
-- SimpCon interface
77
 
78
        sc_mem_out      : out sc_out_type;
79
        sc_mem_in       : in sc_in_type
80
);
81
end mem_sc;
82
 
83
architecture rtl of mem_sc is
84
 
85
component cache is
86
generic (jpc_width : integer; block_bits : integer);
87
 
88
port (
89
 
90
        clk, reset      : in std_logic;
91
 
92
        bc_len          : in std_logic_vector(METHOD_SIZE_BITS-1 downto 0);      -- length of method in words
93
        bc_addr         : in std_logic_vector(17 downto 0);              -- memory address of bytecode
94
 
95
        find            : in std_logic;                                 -- start lookup
96
 
97
        bcstart         : out std_logic_vector(jpc_width-3 downto 0);    -- start of method in bc cache
98
 
99
        rdy             : out std_logic;                                -- lookup finished
100
        in_cache        : out std_logic                                 -- method is in cache
101
 
102
);
103
end component;
104
 
105
--
106
--      jbc component (use technology specific vhdl-file cyc_jbc,...)
107
--
108
--      ajbc,xjbc are OLD!
109
--      check if ajbc.vhd can still be used (multicycle write!)
110
--
111
--      dual port ram
112
--      wraddr and wrena registered
113
--      rdaddr is registered
114
--      indata registered
115
--      outdata is unregistered
116
--
117
 
118
component jbc is
119
generic (jpc_width : integer);
120
port (
121
        clk             : in std_logic;
122
        data            : in std_logic_vector(31 downto 0);
123
        rd_addr         : in std_logic_vector(jpc_width-1 downto 0);
124
        wr_addr         : in std_logic_vector(jpc_width-3 downto 0);
125
        wr_en           : in std_logic;
126
        q               : out std_logic_vector(7 downto 0)
127
);
128
end component;
129
 
130
 
131
--
132
--      signals for mem interface
133
--
134
        type state_type         is (
135
                                                        idl, rd1, wr1,
136
                                                        bc_cc, bc_r1, bc_w, bc_rn, bc_wr, bc_wl,
137
                                                        iald0, iald1, iald2, iald23, iald3, iald4,
138
                                                        iasrd, ialrb,
139
                                                        iast0, iaswb, iasrb, iasst,
140
                                                        gf0, gf1, gf2, gf3,
141
                                                        pf0, pf3,
142
                                                        cp0, cp1, cp2, cp3, cp4, cpstop,
143
                                                        last,
144
                                                        npexc, abexc, excw
145
                                                );
146
        signal state            : state_type;
147
        signal next_state       : state_type;
148
 
149
        -- length should be 'real' RAM size and not RAM + Flash + NAND
150
        -- should also be considered in the cacheable range
151
 
152
        -- addr_reg used to 'store' the address for wr, bc load, and array access
153
        signal addr_reg         : unsigned(SC_ADDR_SIZE-1 downto 0);
154
        signal addr_next        : unsigned(SC_ADDR_SIZE-1 downto 0);
155
 
156
        -- MUX for SimpCon address and write data
157
        signal ram_addr         : std_logic_vector(SC_ADDR_SIZE-1 downto 0);
158
        signal ram_wr_data      : std_logic_vector(31 downto 0);
159
 
160
--
161
--      signals for access from the state machine
162
--
163
        signal state_bsy        : std_logic;
164
        signal state_rd         : std_logic;
165
        signal state_wr         : std_logic;
166
 
167
--
168
--      signals for object and array access
169
--
170
        signal index            : std_logic_vector(SC_ADDR_SIZE-1 downto 0);     -- array or field index
171
        signal value            : std_logic_vector(31 downto 0);         -- store value
172
 
173
        signal null_pointer     : std_logic;
174
        signal bounds_error     : std_logic;
175
 
176
        signal was_a_store      : std_logic;
177
 
178
--
179
--      values for bytecode read/cache
180
--
181
--      len is in words, 10 bits range is 'hardcoded' in JOPWriter.java
182
--      start is address in external memory (rest of the word)
183
--
184
        signal bc_len           : unsigned(METHOD_SIZE_BITS-1 downto 0); -- length of method in words
185
        signal inc_addr_reg     : std_logic;
186
        signal dec_len          : std_logic;
187
        signal bc_wr_addr       : unsigned(jpc_width-3 downto 0);        -- address for jbc (in words!)
188
        signal bc_wr_data       : std_logic_vector(31 downto 0); -- write data for jbc
189
        signal bc_wr_ena        : std_logic;
190
 
191
--
192
--      signals for cache connection
193
--
194
        signal cache_rdy        : std_logic;
195
        signal cache_in_cache   : std_logic;
196
        signal cache_bcstart    : std_logic_vector(jpc_width-3 downto 0);
197
 
198
--
199
-- signals for copying and address translation
200
--
201
        signal base_reg         : unsigned(SC_ADDR_SIZE-1 downto 0);
202
        signal pos_reg          : unsigned(SC_ADDR_SIZE-1 downto 0);
203
    signal offset_reg   : unsigned(SC_ADDR_SIZE-1 downto 0);
204
        signal translate_bit : std_logic;
205
        signal cp_stopbit   : std_logic;
206
 
207
begin
208
 
209
process(sc_mem_in, state_bsy, state)
210
begin
211
        mem_out.bsy <= '0';
212
        if sc_mem_in.rdy_cnt=3 then
213
                mem_out.bsy <= '1';
214
        else
215
                if state/=ialrb and state/=last and state_bsy='1' then
216
                        mem_out.bsy <= '1';
217
                end if;
218
        end if;
219
end process;
220
 
221
        mem_out.bcstart <= std_logic_vector(to_unsigned(0, 32-jpc_width)) & cache_bcstart & "00";
222
 
223
 
224
        np_exc <= null_pointer;
225
        ab_exc <= bounds_error;
226
 
227
        -- change byte order for jbc memory (high byte first)
228
        bc_wr_data <= sc_mem_in.rd_data(7 downto 0) &
229
                                sc_mem_in.rd_data(15 downto 8) &
230
                                sc_mem_in.rd_data(23 downto 16) &
231
                                sc_mem_in.rd_data(31 downto 24);
232
 
233
 
234
        cmp_cache: cache generic map (jpc_width, block_bits) port map(
235
                clk, reset,
236
                std_logic_vector(bc_len), std_logic_vector(addr_reg(17 downto 0)),
237
                mem_in.bc_rd,
238
                cache_bcstart,
239
                cache_rdy, cache_in_cache
240
        );
241
 
242
 
243
        cmp_jbc: jbc generic map (jpc_width)
244
        port map(
245
                clk => clk,
246
                data => bc_wr_data,
247
                wr_en => bc_wr_ena,
248
                wr_addr => std_logic_vector(bc_wr_addr),
249
                rd_addr => jbc_addr,
250
                q => jbc_data
251
        );
252
 
253
--
254
--      SimpCon connections
255
--
256
 
257
        sc_mem_out.address <= ram_addr;
258
        sc_mem_out.wr_data <= ram_wr_data;
259
        sc_mem_out.rd <= mem_in.rd or state_rd;
260
        sc_mem_out.wr <= mem_in.wr or state_wr;
261
        mem_out.dout <= sc_mem_in.rd_data;
262
 
263
 
264
--
265
--      Store the write address
266
--      TODO: wouldn't it be easier to use A and B
267
--              for data and address with a single write
268
--              command?
269
--              - see jvm.asm...
270
--
271
--      and array access stores
272
--
273
process(clk, reset)
274
begin
275
        if reset='1' then
276
                addr_reg <= (others => '0');
277
                index <= (others => '0');
278
                value <= (others => '0');
279
                was_a_store <= '0';
280
                bc_len <= (others => '0');
281
 
282
                base_reg <= (others => '0');
283
                pos_reg <= (others => '0');
284
                offset_reg <= (others => '0');
285
 
286
        elsif rising_edge(clk) then
287
                if mem_in.bc_rd='1' then
288
                        bc_len <= unsigned(ain(METHOD_SIZE_BITS-1 downto 0));
289
                else
290
                        if dec_len='1' then
291
                                bc_len <= bc_len-1;
292
                        end if;
293
                end if;
294
 
295
                -- save array address and index
296
                if mem_in.iaload='1' or mem_in.getfield='1' then
297
                        index <= ain(SC_ADDR_SIZE-1 downto 0);           -- store array index
298
                end if;
299
                -- first step of three-operand operations
300
                if mem_in.iastore='1' or mem_in.putfield='1' then
301
                        value <= ain;
302
                end if;
303
                -- get reference and index for putfield and array stores
304
                if state=pf0 or state=iast0 then
305
                        index <= ain(SC_ADDR_SIZE-1 downto 0);           -- store array index                    
306
                end if;
307
 
308
                -- get source and index for copying
309
                if mem_in.copy='1' then
310
                        base_reg <= unsigned(bin(SC_ADDR_SIZE-1 downto 0));
311
                        pos_reg <= unsigned(ain(SC_ADDR_SIZE-1 downto 0)) + unsigned(bin(SC_ADDR_SIZE-1 downto 0));
312
                        cp_stopbit <= ain(31);
313
                end if;
314
                -- get destination for copying
315
                if state=cp0 then
316
                        offset_reg <= unsigned(bin(SC_ADDR_SIZE-1 downto 0)) - base_reg;
317
                end if;
318
 
319
                -- address and data tweaking for copying
320
                if state=cp3 then
321
                        pos_reg <= pos_reg+1;
322
                        value <= sc_mem_in.rd_data;
323
                end if;
324
                if state=cpstop then
325
                        pos_reg <= base_reg;
326
                end if;
327
 
328
                -- precompute address translation
329
                if addr_next >= base_reg and addr_next < pos_reg then
330
                        translate_bit <= '1';
331
                else
332
                        translate_bit <= '0';
333
                end if;
334
                addr_reg <= addr_next;
335
 
336
                -- set flag for state sharing
337
                if mem_in.iaload='1' or mem_in.getfield='1' then
338
                        was_a_store <= '0';
339
                elsif mem_in.iastore='1' or mem_in.putfield='1' then
340
                        was_a_store <= '1';
341
                end if;
342
        end if;
343
end process;
344
 
345
 
346
--
347
--      RAM address MUX (combinational)
348
--
349
process(ain, addr_reg, offset_reg, mem_in, base_reg, pos_reg, translate_bit)
350
begin
351
        if mem_in.rd='1' then
352
                if unsigned(ain(SC_ADDR_SIZE-1 downto 0)) >= base_reg and unsigned(ain(SC_ADDR_SIZE-1 downto 0)) < pos_reg then
353
                        ram_addr <= std_logic_vector(unsigned(ain(SC_ADDR_SIZE-1 downto 0)) + offset_reg);
354
                else
355
                        ram_addr <= ain(SC_ADDR_SIZE-1 downto 0);
356
                end if;
357
        else
358
                -- default is the registered address for wr, bc load
359
                if translate_bit='1' then
360
                        ram_addr <= std_logic_vector(addr_reg(SC_ADDR_SIZE-1 downto 0) + offset_reg);
361
                else
362
                        ram_addr <= std_logic_vector(addr_reg(SC_ADDR_SIZE-1 downto 0));
363
                end if;
364
        end if;
365
end process;
366
 
367
--
368
-- prepare RAM address registering
369
--
370
process(addr_reg, sc_mem_in, mem_in, ain, bin, state, inc_addr_reg, index, pos_reg, offset_reg)
371
begin
372
 
373
        -- default values
374
        addr_next <= addr_reg;
375
        if inc_addr_reg='1' then
376
                addr_next <= addr_reg+1;
377
        end if;
378
 
379
        -- computations that depend on mem_in
380
        if mem_in.addr_wr='1' then
381
                addr_next <= unsigned(ain(SC_ADDR_SIZE-1 downto 0));
382
        end if;
383
 
384
        if mem_in.bc_rd='1' then
385
                addr_next(17 downto 0) <= unsigned(ain(27 downto 10));
386
                -- addr_bits is 17
387
                if SC_ADDR_SIZE>18 then
388
                        addr_next(SC_ADDR_SIZE-1 downto 18) <= (others => '0');
389
                end if;
390
        end if;
391
 
392
        if mem_in.iaload='1' or mem_in.getfield='1' then
393
                addr_next <= unsigned(bin(SC_ADDR_SIZE-1 downto 0));
394
        end if;
395
 
396
        -- computations that depend on the state
397
        if state=pf0 or state=iast0 then
398
                addr_next <= unsigned(bin(SC_ADDR_SIZE-1 downto 0));
399
        end if;
400
 
401
        -- get/putfield could be optimized for faster memory (e.g. SPM)
402
        if state=iald3 or state=iald23 or state=gf2 then
403
                addr_next <= unsigned(sc_mem_in.rd_data(SC_ADDR_SIZE-1 downto 0))+unsigned(index);
404
        end if;
405
 
406
        if state=cp0 then
407
                addr_next <= pos_reg;
408
        end if;
409
 
410
        if state=cp3 then
411
                addr_next <= pos_reg + offset_reg;
412
        end if;
413
 
414
end process;
415
 
416
 
417
--
418
--      RAM write data MUX (combinational)
419
--
420
process(ain, addr_reg, mem_in, value)
421
begin
422
        if mem_in.wr='1' then
423
                ram_wr_data <= ain;
424
        else
425
                -- default is the registered value
426
                ram_wr_data <= value;
427
        end if;
428
end process;
429
 
430
 
431
--
432
--      next state logic
433
--
434
process(state, mem_in, sc_mem_in,
435
        cache_rdy, cache_in_cache, bc_len, value, index,
436
        addr_reg, cp_stopbit, was_a_store)
437
begin
438
 
439
        next_state <= state;
440
 
441
        case state is
442
 
443
                when idl =>
444
                        if mem_in.rd='1' then
445
                                next_state <= rd1;
446
                        elsif mem_in.wr='1' then
447
                                next_state <= wr1;
448
                        elsif mem_in.bc_rd='1' then
449
                                next_state <= bc_cc;
450
                        elsif mem_in.iaload='1' then
451
                                next_state <= iald0;
452
                        elsif mem_in.getfield='1' then
453
                                next_state <= gf0;
454
                        elsif mem_in.putfield='1' then
455
                                next_state <= pf0;
456
                        elsif mem_in.copy='1' then
457
                                next_state <= cp0;
458
                        elsif mem_in.iastore='1' then
459
                                next_state <= iast0;
460
                        end if;
461
 
462
                -- after a read the idl state is the result cycle
463
                -- where the data is available
464
                when rd1 =>
465
                        -- either 1 or 0
466
                        if sc_mem_in.rdy_cnt(1)='0' then
467
                                next_state <= idl;
468
                        end if;
469
 
470
                -- We could avoid the idl state after wr1 to
471
                -- get back to back wr/wr or wr/rd.
472
                -- However, it is not used in JOP (at the moment).
473
                when wr1 =>
474
                        -- either 1 or 0
475
                        if sc_mem_in.rdy_cnt(1)='0' then
476
                                next_state <= idl;
477
                        end if;
478
 
479
--
480
--      bytecode read
481
--
482
                -- cache lookup
483
                when bc_cc =>
484
                        if cache_rdy = '1' then
485
                                if cache_in_cache = '1' then
486
                                        next_state <= idl;
487
                                else
488
                                        next_state <= bc_r1;
489
                                end if;
490
                        end if;
491
 
492
                -- not in cache
493
                -- start first read
494
                when bc_r1 =>
495
                        next_state <= bc_w;
496
                        -- even for a two cycle memory we have to go to
497
                        -- wait for the first time as rdy_cnt is 0 in
498
                        -- this state. Becomes valid in the next cycle
499
 
500
                -- wait
501
                when bc_w =>
502
                        -- this works with pipeline level 1
503
                        -- if sc_mem_in.rdy_cnt(1)='0' then
504
                        -- we need a pipeline level of 2 in
505
                        -- the memory interface for this to work!
506
                        if sc_mem_in.rdy_cnt/=3 then
507
                                next_state <= bc_rn;
508
                        end if;
509
 
510
                -- start read 2 to n
511
                when bc_rn =>
512
                        next_state <= bc_wr;
513
 
514
                when bc_wr =>
515
                        if bc_len=to_unsigned(0, jpc_width-3) then
516
                                next_state <= bc_wl;
517
                        else
518
                                -- w. pipeline level 2
519
                                if sc_mem_in.rdy_cnt/=3 then
520
                                        next_state <= bc_rn;
521
                                else
522
                                        next_state <= bc_w;
523
                                end if;
524
                        end if;
525
 
526
                -- wait for the last ack
527
                when bc_wl =>
528
                        if sc_mem_in.rdy_cnt(1)='0' then
529
                                next_state <= idl;
530
                        end if;
531
 
532
--
533
--      array access
534
--
535
                when iast0 =>
536
                        -- just one cycle wait to store the value
537
                        next_state <= iald0;
538
 
539
                --
540
                -- iald0 to iald3 are shared with iastore
541
                --
542
                when iald0 =>
543
                        if addr_reg=0 then
544
                                next_state <= npexc;
545
                        elsif index(SC_ADDR_SIZE-1)='1' then
546
                                next_state <= abexc;
547
                        else
548
                                next_state <= iald1;
549
                        end if;
550
 
551
                when iald1 =>
552
                        -- w. pipeline level 2
553
                        -- would waste one cycle in a single cycle memory (similar
554
                        -- to bc load) - SimpCon rd comes from registered state_rd.
555
                        if sc_mem_in.rdy_cnt<=1 then
556
                                next_state <= iald23;
557
                        elsif sc_mem_in.rdy_cnt/=3 then
558
                                next_state <= iald2;
559
                        end if;
560
 
561
                --
562
                -- a quick hack for faster memory: we need to read
563
                -- it now! TODO: get better state names
564
                -- it's a mix of iald2 and iald3
565
                --
566
                when iald23 =>
567
                        next_state <= iald4;
568
------ that's now load specific!
569
-- we start loading before we know the upper bound exception!
570
-- is there an issue with read peripherals????
571
                        if was_a_store='1' then
572
                                next_state <= iaswb;
573
                        -- w. pipeline level 2
574
                        elsif sc_mem_in.rdy_cnt/=3 then
575
                                next_state <= iasrd;
576
                        end if;
577
 
578
                when iald2 =>
579
                        next_state <= iald3;
580
 
581
                when iald3 =>
582
                        next_state <= iald4;
583
------ that's now load specific!
584
-- we start loading before we know the upper bound exception!
585
-- is there an issue with read peripherals????
586
                        if was_a_store='1' then
587
                                next_state <= iaswb;
588
                        -- w. pipeline level 2
589
                        elsif sc_mem_in.rdy_cnt/=3 then
590
                                next_state <= iasrd;
591
                        end if;
592
 
593
                when iald4 =>
594
                        if sc_mem_in.rdy_cnt/=3 then
595
                                next_state <= iasrd;
596
                        end if;
597
 
598
                -- rdy_cnt is less than 3 we can move on
599
                when iasrd =>
600
                        next_state <= ialrb;
601
 
602
                when ialrb =>
603
                        -- can we optimize this when we increment index at some state?
604
                        if unsigned(index) >= unsigned(sc_mem_in.rd_data(SC_ADDR_SIZE-1 downto 0)) then
605
                                next_state <= abexc;
606
                        -- either 1 or 0
607
                        elsif sc_mem_in.rdy_cnt(1)='0' then
608
                                next_state <= idl;
609
                        end if;
610
 
611
                when iaswb =>
612
                        if sc_mem_in.rdy_cnt(1)='0' then
613
                                next_state <= iasrb;
614
                        end if;
615
 
616
                when iasrb =>
617
                        next_state <= iasst;
618
                        -- can we optimize this when we increment index at some state?
619
                        if unsigned(index) >= unsigned(sc_mem_in.rd_data(SC_ADDR_SIZE-1 downto 0)) then
620
                                next_state <= abexc;
621
                        end if;
622
 
623
                when iasst =>
624
                        next_state <= last;
625
 
626
                when gf0 =>
627
                        if addr_reg=0 then
628
                                next_state <= npexc;
629
                        else
630
                                next_state <= gf1;
631
                        end if;
632
                when gf1 =>
633
                        -- either 1 or 0
634
                        if sc_mem_in.rdy_cnt(1)='0' then
635
                                next_state <= gf2;
636
                        end if;
637
                when gf2 =>
638
                        next_state <= gf3;
639
                        if was_a_store='1' then
640
                                next_state <= pf3;
641
                        end if;
642
                when gf3 =>
643
                        next_state <= last;
644
 
645
                when pf0 =>
646
                        -- just one cycle wait to store the value
647
                        next_state <= gf0;
648
                        -- states pf1 and pf2 are shared with getfield
649
                when pf3 =>
650
                        next_state <= last;
651
 
652
                when cp0 =>
653
                        next_state <= cp1;
654
                        if cp_stopbit = '1' then
655
                                next_state <= cpstop;
656
                        end if;
657
                when cp1 =>
658
                        next_state <= cp2;
659
                when cp2 =>
660
                        -- either 1 or 0
661
                        if sc_mem_in.rdy_cnt(1)='0' then
662
                                next_state <= cp3;
663
                        end if;
664
                when cp3 =>
665
                        next_state <= cp4;
666
                when cp4 =>
667
                        next_state <= last;
668
                when cpstop =>
669
                        next_state <= idl;
670
 
671
                when last =>
672
                        -- either 1 or 0
673
                        if sc_mem_in.rdy_cnt(1)='0' then
674
                                next_state <= idl;
675
                        end if;
676
 
677
                when npexc =>
678
                        next_state <= excw;
679
 
680
                when abexc =>
681
                        next_state <= excw;
682
 
683
                when excw =>
684
                        if sc_mem_in.rdy_cnt="00" then
685
                                next_state <= idl;
686
                        end if;
687
 
688
        end case;
689
end process;
690
 
691
--
692
--      state machine register
693
--      output register
694
--
695
process(clk, reset)
696
 
697
begin
698
        if (reset='1') then
699
                state <= idl;
700
                bc_wr_ena <= '0';
701
                inc_addr_reg <= '0';
702
                dec_len <= '0';
703
                state_rd <= '0';
704
                state_bsy <= '0';
705
                null_pointer <= '0';
706
                bounds_error <= '0';
707
                state_wr <= '0';
708
                sc_mem_out.atomic       <= '0';
709
 
710
        elsif rising_edge(clk) then
711
 
712
                state <= next_state;
713
 
714
                bc_wr_ena <= '0';
715
                inc_addr_reg <= '0';
716
                dec_len <= '0';
717
                state_rd <= '0';
718
                null_pointer <= '0';
719
                bounds_error <= '0';
720
                state_wr <= '0';
721
                sc_mem_out.atomic       <= '0';
722
 
723
                case next_state is
724
 
725
                        when idl =>
726
                                state_bsy <= '0';
727
 
728
                        when rd1 =>
729
 
730
                        when wr1 =>
731
 
732
                        when bc_cc =>
733
                                state_bsy <= '1';
734
                                -- cache check
735
 
736
                        when bc_r1 =>
737
                                -- setup data
738
                                bc_wr_addr <= unsigned(cache_bcstart);
739
                                -- first memory read
740
                                inc_addr_reg <= '1';
741
                                state_rd <= '1';
742
                                sc_mem_out.atomic       <= '1';
743
 
744
                        when bc_w =>
745
                                -- wait
746
                                sc_mem_out.atomic       <= '1';
747
 
748
                        when bc_rn =>
749
                                -- following memory reads
750
                                inc_addr_reg <= '1';
751
                                dec_len <= '1';
752
                                state_rd <= '1';
753
                                sc_mem_out.atomic       <= '1';
754
 
755
                        when bc_wr =>
756
                                -- BC write
757
                                bc_wr_ena <= '1';
758
                                sc_mem_out.atomic       <= '1';
759
 
760
                                if bc_len=to_unsigned(1, jpc_width-3) then
761
                                        sc_mem_out.atomic       <= '0';
762
                                end if;
763
 
764
                        when bc_wl =>
765
                                -- wait for last (unnecessary read)
766
 
767
                        when iast0 =>
768
                                state_bsy <= '1';
769
 
770
                        when iald0 =>
771
                                state_rd <= '1';
772
                                state_bsy <= '1';
773
                                inc_addr_reg <= '1';
774
                                sc_mem_out.atomic <= '1';
775
 
776
                        when iald1 =>
777
                                sc_mem_out.atomic <= '1';
778
 
779
                        when iald2 =>
780
                                state_rd <= '1';
781
                                sc_mem_out.atomic <= '1';
782
 
783
                        when iald23 =>
784
                                state_rd <= '1';
785
                                sc_mem_out.atomic <= '1';
786
 
787
                        when iald3 =>
788
                                sc_mem_out.atomic <= '1';
789
 
790
                        when iald4 =>
791
                                sc_mem_out.atomic <= '1';
792
 
793
                        when iasrd =>
794
                                state_rd <= '1';
795
                                sc_mem_out.atomic <= '1';
796
 
797
                        when ialrb =>
798
                                sc_mem_out.atomic <= '1';
799
 
800
                        when iaswb =>
801
                                sc_mem_out.atomic <= '1';
802
 
803
                        when iasrb =>
804
                                sc_mem_out.atomic <= '1';
805
 
806
                        when iasst =>
807
                                state_wr <= '1';
808
                                sc_mem_out.atomic <= '1';
809
 
810
                        when gf0 =>
811
                                state_rd <= '1';
812
                                state_bsy <= '1';
813
                                sc_mem_out.atomic <= '1';
814
 
815
                        when gf1 =>
816
                                sc_mem_out.atomic <= '1';
817
 
818
                        when gf2 =>
819
                                sc_mem_out.atomic <= '1';
820
 
821
                        when gf3 =>
822
                                state_rd <= '1';
823
                                sc_mem_out.atomic <= '1';
824
 
825
                        when pf0 =>
826
                                state_bsy <= '1';
827
 
828
                        when pf3 =>
829
                                state_wr <= '1';
830
                                sc_mem_out.atomic <= '1';
831
 
832
                        when cp0 =>
833
                                sc_mem_out.atomic <= '1';
834
                                state_bsy <= '1';
835
 
836
                        when cp1 =>
837
                                state_rd <= '1';
838
                                sc_mem_out.atomic <= '1';
839
 
840
                        when cp2 =>
841
                                sc_mem_out.atomic <= '1';
842
 
843
                        when cp3 =>
844
                                sc_mem_out.atomic <= '1';
845
 
846
                        when cp4 =>
847
                                state_wr <= '1';
848
                                sc_mem_out.atomic <= '1';
849
 
850
                        when cpstop =>
851
 
852
                        when last =>
853
                                sc_mem_out.atomic <= '1';
854
 
855
                        when npexc =>
856
                                null_pointer <= '1';
857
 
858
                        when abexc =>
859
                                bounds_error <= '1';
860
 
861
                        when excw =>
862
 
863
                end case;
864
 
865
                -- increment in state write
866
                if state=bc_wr then
867
                        bc_wr_addr <= bc_wr_addr+1;             -- next jbc address
868
                end if;
869
        end if;
870
end process;
871
 
872
end rtl;

powered by: WebSVN 2.1.0

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