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

Subversion Repositories vhdl_cpu_emulator

[/] [vhdl_cpu_emulator/] [trunk/] [cpu_sim.vhd] - Blame information for rev 3

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 nachumk
--Mango DSP Ltd. Copyright (C) 2006
2
--Creator: Nachum Kanovsky
3
 
4
library ieee;
5
use ieee.std_logic_1164.all;
6
use work.design_top_constants.all;
7
use std.textio.all;
8
use ieee.std_logic_unsigned.all;
9
use ieee.numeric_std.all;
10
 
11
entity cpu_sim is
12
  port(
13
    fname    : in    filename;
14
    clk      : out std_logic;
15
    rstN     : out   std_logic;
16
    cpu_cs1  : out   std_logic;
17
    cpu_cs2  : out   std_logic;
18
    cpu_cs3  : out   std_logic;
19
    cpu_we   : out   std_logic;
20
    cpu_a    : out std_logic_vector(4 downto 0);
21
    cpu_d    : inout std_logic_vector(7 downto 0);
22
    cpu_irq4 : in    std_logic;
23
    cpu_irq7 : in    std_logic
24
    );
25
end;
26
 
27
architecture cpu_sim_simple of cpu_sim is
28
  signal sig_clk : std_logic := '0';
29
  shared variable tclk : time    := 0 ns;
30
  shared variable rl   : integer := 1;
31
 
32
  function to_lower (
33
    constant c : character)
34
    return character is
35
  begin  -- to_lower
36
    if c >= 'A' and c <= 'Z' then
37
      return character'val(character'pos(c) - character'pos('A') + character'pos('a'));
38
    else
39
      return c;
40
    end if;
41
  end to_lower;
42
 
43
  procedure eat_white (
44
    variable l : inout line) is
45
    variable old_l : line := l;
46
    variable p     : integer;
47
  begin
48
    if l = null then
49
      return;
50
    end if;
51
    if l'length = 0 then
52
      --string is empty
53
      deallocate(l);
54
      return;
55
    end if;
56
    p := l'left;
57
    while l'length > p - l'left and (l(p) = ' ' or l(p) = HT) loop
58
      p := p + 1;
59
    end loop;
60
    if p = l'left then
61
      --no whitespace
62
      return;
63
    elsif l'length <= p - l'left then
64
      --only whitespace - p passed the whole string
65
      deallocate(l);
66
    else
67
      l := new string'(old_l(p to old_l'right));
68
      deallocate(old_l);
69
    end if;
70
  end eat_white;
71
 
72
  procedure shrink_line (
73
    variable l : inout line;
74
    variable p : inout integer) is
75
    variable old_l : line := l;
76
  begin
77
    assert l /= null report "shrink_line l equals null" severity failure;
78
    if p = 0 then
79
      return;
80
    elsif p = l'length then
81
      deallocate(l);
82
    else
83
      l := new string'(old_l(old_l'left + p + 1 to old_l'right));
84
      deallocate(old_l);
85
    end if;
86
  end shrink_line;
87
 
88
  procedure read_word (
89
    l     : inout line;
90
    value : inout line) is
91
    variable size : integer := 0;
92
    variable p    : integer;
93
  begin
94
    if value /= null then
95
      deallocate(value);
96
    end if;
97
    eat_white(l);
98
    if l = null then
99
      return;
100
    end if;
101
    p := l'left;
102
    while l'length > p - l'left and (l(p) /= ' ' and l(p) /= HT) loop
103
      l(p) := to_lower(l(p));
104
      p    := p + 1;
105
    end loop;
106
    p     := p - 1;
107
    value := new string'(l(l'left to p));
108
    p     := p + 1 - l'left;
109
    shrink_line(l, p);
110
  end read_word;
111
 
112
  procedure get_line(
113
    file f     :       text;
114
    variable l : inout line) is
115
  begin
116
    if l /= null then
117
      deallocate(l);
118
    end if;
119
    loop
120
      if endfile(f) then
121
        return;
122
      end if;
123
      readline(f, l);
124
      eat_white(l);
125
      if l /= null and l(l'left) /= '#' then
126
        return;
127
      else
128
        deallocate(l);
129
      end if;
130
    end loop;
131
  end get_line;
132
 
133
  type dfile is record
134
    fn : line;
135
    ln : integer;
136
  end record;
137
  type dfile_access is access dfile;
138
 
139
  procedure readline(
140
    variable dfa : inout dfile_access;
141
    l            : inout line) is
142
    file fl    : text;
143
    variable c : integer := 0;
144
  begin
145
    file_open(fl, dfa.fn.all, read_mode);
146
    if l /= null then
147
      deallocate(l);
148
    end if;
149
    while c /= dfa.ln loop
150
      if endfile(fl) then
151
        if l /= null then
152
          deallocate(l);
153
        end if;
154
        file_close(fl);
155
        return;
156
      end if;
157
      readline(fl, l);
158
      c := c + 1;
159
    end loop;
160
    if endfile(fl) then
161
      if l /= null then
162
        deallocate(l);
163
      end if;
164
      file_close(fl);
165
      return;
166
    end if;
167
    readline(fl, l);
168
    file_close(fl);
169
    dfa.ln := dfa.ln + 1;
170
  end readline;
171
 
172
  --writeline deallocates the line
173
  procedure write(
174
    variable fn : in    line;
175
    variable l  : inout line) is
176
    file fl        : text;
177
    file fl_tmp    : text;
178
    variable l_tmp : line;
179
  begin
180
    file_open(fl_tmp, "tmp.txt", write_mode);
181
    file_open(fl, fn.all, read_mode);
182
    while not endfile(fl) loop
183
      readline(fl, l_tmp);
184
      writeline(fl_tmp, l_tmp);
185
    end loop;
186
    l_tmp := new string'(l(l'left to l'right));
187
    writeline(fl_tmp, l_tmp);
188
    file_close(fl_tmp);
189
    file_close(fl);
190
    file_open(fl_tmp, "tmp.txt", read_mode);
191
    file_open(fl, fn.all, write_mode);
192
    while not endfile(fl_tmp) loop
193
      readline(fl_tmp, l_tmp);
194
      writeline(fl, l_tmp);
195
    end loop;
196
    file_close(fl_tmp);
197
    file_close(fl);
198
  end write;
199
 
200
  procedure write(
201
    variable fn : in line;
202
    variable sl : in std_logic) is
203
    file fl        : text;
204
    file fl_tmp    : text;
205
    variable b     : bit;
206
    variable l_tmp : line;
207
  begin
208
    file_open(fl_tmp, "tmp.txt", write_mode);
209
    file_open(fl, fn.all, read_mode);
210
    while not endfile(fl) loop
211
      readline(fl, l_tmp);
212
      writeline(fl_tmp, l_tmp);
213
    end loop;
214
    if sl = '1' then
215
      b := '1';
216
    else
217
      b := '0';
218
    end if;
219
    write(l_tmp, b);
220
    writeline(fl, l_tmp);
221
    file_close(fl_tmp);
222
    file_close(fl);
223
    file_open(fl_tmp, "tmp.txt", read_mode);
224
    file_open(fl, fn.all, write_mode);
225
    while not endfile(fl_tmp) loop
226
      readline(fl_tmp, l_tmp);
227
      writeline(fl, l_tmp);
228
    end loop;
229
    file_close(fl_tmp);
230
    file_close(fl);
231
  end write;
232
 
233
  procedure write(
234
    variable fn   : in line;
235
    variable slv8 : in std_logic_vector(7 downto 0)) is
236
    file fl        : text;
237
    file fl_tmp    : text;
238
    variable l_tmp : line;
239
  begin
240
    file_open(fl_tmp, "tmp.txt", write_mode);
241
    file_open(fl, fn.all, read_mode);
242
    while not endfile(fl) loop
243
      readline(fl, l_tmp);
244
      writeline(fl_tmp, l_tmp);
245
    end loop;
246
    write(l_tmp, to_bitVector(slv8));
247
    writeline(fl_tmp, l_tmp);
248
    file_close(fl_tmp);
249
    file_close(fl);
250
    file_open(fl_tmp, "tmp.txt", read_mode);
251
    file_open(fl, fn.all, write_mode);
252
    while not endfile(fl_tmp) loop
253
      readline(fl_tmp, l_tmp);
254
      writeline(fl, l_tmp);
255
    end loop;
256
    file_close(fl_tmp);
257
    file_close(fl);
258
  end write;
259
 
260
  procedure get_line(
261
    variable dfa : inout dfile_access;
262
    variable l   : inout line) is
263
    variable l_temp : line;
264
  begin
265
    if l /= null then
266
      deallocate(l);
267
    end if;
268
    loop
269
      readline(dfa, l_temp);
270
      if l_temp = null then
271
        l := null;
272
        return;
273
      end if;
274
      eat_white(l_temp);
275
      if l_temp /= null and l_temp(l_temp'left) /= '#' then
276
        l := l_temp;
277
        return;
278
      end if;
279
    end loop;
280
  end get_line;
281
 
282
  type wait_commands is (wt_done, wt_time, wt_irq4, wt_irq7);
283
 
284
  type waiter is record
285
    cmd    : wait_commands;
286
    tm_end : time;
287
    v      : std_logic;
288
  end record;
289
  type waiter_access is access waiter;
290
 
291
  procedure check_wait(
292
    variable w : inout waiter) is
293
  begin
294
    case w.cmd is
295
      when wt_time =>
296
        if now >= w.tm_end then
297
          w.cmd := wt_done;
298
        end if;
299
      when wt_irq4 =>
300
        if cpu_irq4 = w.v then
301
          w.cmd := wt_done;
302
        end if;
303
      when wt_irq7 =>
304
        if cpu_irq7 = w.v then
305
          w.cmd := wt_done;
306
        end if;
307
      when others => null;
308
    end case;
309
  end check_wait;
310
 
311
  type var_types is (vt_string, vt_bit, vt_vector8);
312
  type var;
313
  type var_access is access var;
314
  type var_accessx16 is array (15 downto 0) of var_access;
315
  type var is record
316
    n    : line;
317
    vt   : var_types;
318
    s    : line;
319
    sl   : std_logic;
320
    slv8 : std_logic_vector(7 downto 0);
321
  end record;
322
  type vars;
323
  type vars_access is access vars;
324
  type vars is record
325
    va16     : var_accessx16;
326
    next_vsa : vars_access;
327
  end record;
328
 
329
  procedure get_var(
330
    variable n   : in  line;
331
    variable vsa : in  vars_access;
332
    variable va  : out var_access) is
333
  begin
334
    if vsa = null then
335
      return;
336
    end if;
337
    va := null;
338
    for i in vsa.va16'range loop
339
      if vsa.va16(i) /= null and vsa.va16(i).n.all = n.all then
340
        va := vsa.va16(i);
341
        return;
342
      end if;
343
    end loop;
344
    get_var(n, vsa.next_vsa, va);
345
  end get_var;
346
 
347
  procedure add_var(
348
    variable vsa : inout vars_access;
349
    variable n   : in    line;
350
    variable vt  : in    var_types) is
351
    variable vsa_temp : vars_access;
352
    variable v_temp   : var_access;
353
  begin
354
    vsa_temp     := vsa.next_vsa;
355
    vsa.next_vsa := null;
356
    get_var(n, vsa, v_temp);
357
    vsa.next_vsa := vsa_temp;
358
    vsa_temp     := null;
359
    if v_temp /= null then
360
      return;
361
    end if;
362
    for i in vsa.va16'range loop
363
      if vsa.va16(i) = null then
364
        vsa.va16(i)    := new var;
365
        vsa.va16(i).n  := new string'(n(n'left to n'right));
366
        vsa.va16(i).vt := vt;
367
        return;
368
      end if;
369
    end loop;
370
    report "too many variables" severity failure;
371
  end add_var;
372
 
373
  procedure add_var(
374
    variable vsa : inout vars_access;
375
    variable n   : in    line;
376
    variable s   : in    line) is
377
    variable v_temp : var_access;
378
    variable vt     : var_types;
379
  begin
380
    vt       := vt_string;
381
    add_var(vsa, n, vt);
382
    get_var(n, vsa, v_temp);
383
    v_temp.s := new string'(s(s'left to s'right));
384
  end add_var;
385
 
386
  procedure add_var(
387
    variable vsa : inout vars_access;
388
    variable n   : in    line;
389
    variable sl  : in    std_logic) is
390
    variable v_temp : var_access;
391
    variable vt     : var_types;
392
  begin
393
    vt        := vt_string;
394
    add_var(vsa, n, vt);
395
    get_var(n, vsa, v_temp);
396
    v_temp.sl := sl;
397
  end add_var;
398
 
399
  procedure add_var(
400
    variable vsa  : inout vars_access;
401
    variable n    : in    line;
402
    variable slv8 : in    std_logic_vector(7 downto 0)) is
403
    variable v_temp : var_access;
404
    variable vt     : var_types;
405
  begin
406
    vt          := vt_string;
407
    add_var(vsa, n, vt);
408
    get_var(n, vsa, v_temp);
409
    v_temp.slv8 := slv8;
410
  end add_var;
411
 
412
  type thread_states is (st_ready, st_done);
413
  type thread;
414
  type thread_access is access thread;
415
  type thread is record
416
    dfa      : dfile_access;
417
    ln_start : integer;
418
    st       : thread_states;
419
    w        : waiter_access;
420
    vsa      : vars_access;
421
    next_tha : thread_access;
422
  end record;
423
 
424
  type tholder;
425
  type tholder_access is access tholder;
426
  type tholder is record
427
    th : thread_access;
428
    n  : tholder_access;
429
    p  : tholder_access;
430
  end record;
431
 
432
  procedure init_thread (
433
    variable tha : inout thread_access;
434
    variable dfa : in    dfile_access;
435
    variable ln  : in    integer;
436
    variable w   : in    waiter_access;
437
    variable vsa : in    vars_access) is
438
    variable int : integer;
439
  begin
440
    tha.dfa          := dfa;
441
    tha.ln_start     := ln;
442
    tha.st           := st_ready;
443
    tha.w            := w;
444
    tha.vsa          := new vars;
445
    tha.vsa.next_vsa := vsa;
446
    tha.w.cmd        := wt_done;
447
  end init_thread;
448
 
449
  procedure declare_var(
450
    variable l_type    : inout line;
451
    variable l_varname : inout line;
452
    variable vsa       : inout vars_access) is
453
    variable vt : var_types;
454
  begin
455
    assert l_type /= null and l_varname /= null report "declare_var bad parameters" severity failure;
456
    if l_type.all = "bit" then
457
      vt := vt_bit;
458
      add_var(vsa, l_varname, vt);
459
    elsif l_type.all = "vector8" then
460
      vt := vt_vector8;
461
      add_var(vsa, l_varname, vt);
462
    elsif l_type.all = "string" then
463
      vt := vt_string;
464
      add_var(vsa, l_varname, vt);
465
    else
466
      report "l_type is not bit, vector8, or string" severity failure;
467
    end if;
468
  end declare_var;
469
 
470
  procedure var_test(
471
    variable l_left  : inout line;
472
    variable l_op    : inout line;
473
    variable l_right : inout line;
474
    variable bl_good : inout boolean;
475
    variable vsa     : inout vars_access) is
476
    variable va_left  : var_access;
477
    variable va_right : var_access;
478
    variable sl       : std_logic;
479
    variable slv8     : std_logic_vector(7 downto 0);
480
    variable b        : bit;
481
    variable bv8      : bit_vector(7 downto 0);
482
    variable s        : line;
483
  begin
484
    assert l_left /= null and l_op /= null and l_right /= null report "var_test invalid null parameters" severity failure;
485
    get_var(l_left, vsa, va_left);
486
    assert va_left /= null report "var_test left variable not found" severity failure;
487
    get_var(l_right, vsa, va_right);
488
    if va_right /= null then
489
      assert va_left.vt = va_right.vt report "var_test var types not the same" severity failure;
490
      case va_right.vt is
491
        when vt_bit =>
492
          sl := va_right.sl;
493
        when vt_vector8 =>
494
          slv8 := va_right.slv8;
495
        when vt_string =>
496
          s := va_right.s;
497
      end case;
498
    else
499
      case va_left.vt is
500
        when vt_bit =>
501
          read(l_right, b, bl_good);
502
          assert bl_good = true report "var_test last parameter failed read" severity failure;
503
          if b = '1' then
504
            sl := '1';
505
          else
506
            sl := '0';
507
          end if;
508
        when vt_vector8 =>
509
          read(l_right, bv8, bl_good);
510
          assert bl_good = true report "var_test last parameter failed read" severity failure;
511
          slv8 := to_stdlogicvector(bv8);
512
        when vt_string =>
513
          s := l_right;
514
      end case;
515
    end if;
516
    bl_good := false;
517
    case va_left.vt is
518
      when vt_bit =>
519
        assert l_op.all = "==" or l_op.all = ">" or l_op.all = "<" or l_op.all = "&" or l_op.all = "|" report "var_test invalid operation for bit, use ==,>,<,&,|" severity failure;
520
        if l_op.all = "==" then
521
          if va_left.sl = sl then
522
            bl_good := true;
523
            return;
524
          end if;
525
        elsif l_op.all = ">" then
526
          if va_left.sl > sl then
527
            bl_good := true;
528
            return;
529
          end if;
530
        elsif l_op.all = "<" then
531
          if va_left.sl < sl then
532
            bl_good := true;
533
            return;
534
          end if;
535
        elsif l_op.all = "&" then
536
          if (va_left.sl and sl) /= '0' then
537
            bl_good := true;
538
            return;
539
          end if;
540
        elsif l_op.all = "|" then
541
          if (va_left.sl or sl) /= '0' then
542
            bl_good := true;
543
            return;
544
          end if;
545
        end if;
546
      when vt_vector8 =>
547
        assert l_op.all = "==" or l_op.all = ">" or l_op.all = "<" or l_op.all = "&" or l_op.all = "|" report "var_test invalid operation for vector8, use ==,>,<,&,|" severity failure;
548
        if l_op.all = "==" then
549
          if va_left.slv8 = slv8 then
550
            bl_good := true;
551
            return;
552
          end if;
553
        elsif l_op.all = ">" then
554
          if va_left.slv8 > slv8 then
555
            bl_good := true;
556
            return;
557
          end if;
558
        elsif l_op.all = "<" then
559
          if va_left.slv8 < slv8 then
560
            bl_good := true;
561
            return;
562
          end if;
563
        elsif l_op.all = "&" then
564
          if (va_left.slv8 and slv8) /= "00000000" then
565
            bl_good := true;
566
            return;
567
          end if;
568
        elsif l_op.all = "|" then
569
          if (va_left.slv8 or slv8) /= "00000000" then
570
            bl_good := true;
571
            return;
572
          end if;
573
        end if;
574
      when vt_string =>
575
        assert l_op.all = "==" report "var_test string has only == operation" severity failure;
576
        if va_left.s = s then
577
          bl_good := true;
578
          return;
579
        end if;
580
      when others => null;
581
    end case;
582
  end var_test;
583
 
584
--variables are deallocated in this function
585
  procedure var_op (
586
    variable l_left  : inout line;
587
    variable l_op    : inout line;
588
    variable l_right : inout line;
589
    variable vsa     : inout vars_access) is
590
    variable va_left  : var_access;
591
    variable va_right : var_access;
592
    variable slv8     : std_logic_vector(7 downto 0);
593
    variable slv16    : std_logic_vector(15 downto 0);
594
    variable b        : bit;
595
    variable bv8      : bit_vector(7 downto 0);
596
    variable bl_good  : boolean;
597
  begin
598
    assert l_left /= null and l_op /= null and l_right /= null report "l_left or l_op or l_right are null" severity failure;
599
    if l_left.all = "bit" or l_left.all = "vector8" or l_left.all = "string" then
600
      declare_var(l_left, l_op, vsa);
601
      l_left := l_op;
602
      l_op   := null;
603
      read_word(l_right, l_op);
604
    end if;
605
    get_var(l_left, vsa, va_left);
606
    assert va_left /= null report "variable not found" severity failure;
607
    case va_left.vt is
608
      when vt_string =>
609
        assert l_op.all = "=" report "illegal op, string has only = operation" severity failure;
610
        if va_left.s /= null then
611
          deallocate(va_left.s);
612
        end if;
613
        get_var(l_right, vsa, va_right);
614
        if va_right /= null then
615
          va_left.s := new string'(va_right.s(va_right.s'left to va_right.s'right));
616
        else
617
          read_word(l_right, va_left.s);
618
        end if;
619
      when vt_bit =>
620
        assert l_op.all = "=" report "illegal op, bit has only = operation" severity failure;
621
        get_var(l_right, vsa, va_right);
622
        if va_right /= null then
623
          assert va_right.vt = vt_bit report "non bit variable being op'ed with bit variable" severity failure;
624
          va_left.sl := va_right.sl;
625
        else
626
          read(l_right, b, bl_good);
627
          if bl_good = true then
628
            if b = '1' then
629
              va_left.sl := '1';
630
            else
631
              va_left.sl := '0';
632
            end if;
633
          else
634
            report "bit operation missing bit value" severity failure;
635
          end if;
636
        end if;
637
      when vt_vector8 =>
638
        get_var(l_right, vsa, va_right);
639
        if va_right /= null then
640
          assert va_right.vt = vt_vector8 report "non vector8 variable being op'ed with vector8 variable" severity failure;
641
          slv8 := va_right.slv8;
642
        else
643
          read(l_right, bv8);
644
          slv8 := to_stdlogicvector(bv8);
645
        end if;
646
        if l_op.all = "=" then
647
          va_left.slv8 := slv8;
648
        elsif l_op.all = "+=" then
649
          va_left.slv8 := va_left.slv8 + slv8;
650
        elsif l_op.all = "-=" then
651
          va_left.slv8 := va_left.slv8 - slv8;
652
        elsif l_op.all = "*=" then
653
          slv16        := va_left.slv8 * slv8;
654
          va_left.slv8 := slv16(7 downto 0);
655
        elsif l_op.all = "&=" then
656
          va_left.slv8 := va_left.slv8 and slv8;
657
        elsif l_op.all = "|=" then
658
          va_left.slv8 := va_left.slv8 or slv8;
659
        else
660
          report "illegal op, vector8 has only =, +, -, &, | operations" severity failure;
661
        end if;
662
    end case;
663
    deallocate(l_left);
664
    deallocate(l_op);
665
    deallocate(l_right);
666
  end var_op;
667
 
668
  procedure clear(
669
    variable fn : inout line) is
670
    file fl : text;
671
  begin
672
    file_open(fl, fn.all, write_mode);
673
    file_close(fl);
674
  end clear;
675
 
676
  procedure find_match (
677
    variable dfa     : inout dfile_access;
678
    constant s_open  : in    string;
679
    constant s_close : in    string) is
680
    variable l   : line;
681
    variable cmd : line;
682
  begin
683
    get_line(dfa, l);
684
    read_word(l, cmd);
685
    while cmd.all /= s_close loop
686
      if cmd.all = s_open then
687
        find_match(dfa, s_open, s_close);
688
      end if;
689
      get_line(dfa, l);
690
      read_word(l, cmd);
691
    end loop;
692
  end find_match;
693
 
694
  procedure find_match (
695
    variable dfa     : inout dfile_access;
696
    constant s_open  : in    string;
697
    constant s_other  : in    string;
698
    constant s_close : in    string) is
699
    variable l   : line;
700
    variable cmd : line;
701
  begin
702
    get_line(dfa, l);
703
    read_word(l, cmd);
704
    while cmd.all /= s_close and cmd.all /= s_other loop
705
      if cmd.all = s_open then
706
        find_match(dfa, s_open, s_close);
707
      end if;
708
      get_line(dfa, l);
709
      read_word(l, cmd);
710
    end loop;
711
  end find_match;
712
 
713
  procedure read_dma (
714
    variable l       : inout line;
715
    variable vsa     : inout vars_access;
716
    signal   cpu_cs1 : out   std_logic;
717
    signal   cpu_we  : out   std_logic;
718
    signal   cpu_a   : out std_logic_vector(4 downto 0);
719
    signal   cpu_d   : inout std_logic_vector(7 downto 0)) is
720
    variable l_tmp : line;
721
    variable va : var_access;
722
    variable addr : std_logic_vector(7 downto 0);
723
    variable size : integer;
724
    variable incr : integer;
725
    variable bl_good : boolean;
726
    variable bv8 : bit_vector(7 downto 0);
727
    variable filename : line;
728
    variable slv8 : std_logic_vector(7 downto 0);
729
  begin
730
    read_word(l, l_tmp);
731
    assert l_tmp /= null report "read_dma parameter missing" severity failure;
732
    get_var(l_tmp, vsa, va);
733
    if va = null then
734
      read(l_tmp, bv8, bl_good);
735
      assert bl_good report "read_dma address invalid" severity failure;
736
      addr := to_stdlogicvector(bv8);
737
    else
738
      assert va.vt = vt_vector8 report "read_dma address variable not found" severity failure;
739
      addr := va.slv8;
740
    end if;
741
    read_word(l, l_tmp);
742
    assert l_tmp /= null report "read_dma parameter missing" severity failure;
743
    get_var(l_tmp, vsa, va);
744
    if va = null then
745
      read(l_tmp, bv8, bl_good);
746
      assert bl_good report "read_dma size invalid" severity failure;
747
      size := to_integer(unsigned(to_stdlogicvector(bv8)));
748
    else
749
      assert va /= null and va.vt = vt_vector8 report "read_dma size variable not found" severity failure;
750
      size := to_integer(unsigned(va.slv8));
751
    end if;
752
    read_word(l, l_tmp);
753
    assert l_tmp /= null report "read_dma parameter missing" severity failure;
754
    get_var(l_tmp, vsa, va);
755
    if va = null then
756
      read(l_tmp, bv8, bl_good);
757
      assert bl_good report "read_dma incr invalid" severity failure;
758
      incr := to_integer(unsigned(to_stdlogicvector(bv8)));
759
    else
760
      assert va /= null and va.vt = vt_vector8 report "read_dma incr variable not found" severity failure;
761
      incr := to_integer(unsigned(va.slv8));
762
    end if;
763
    read_word(l, l_tmp);
764
    assert l_tmp /= null report "read_dma parameter missing" severity failure;
765
    filename := l_tmp;
766
    l_tmp := null;
767
 
768
    for i in 0 to size - 1 loop
769
      if i < (size + rl) then
770
        cpu_cs1 <= '1';
771
        cpu_a <= addr(cpu_a'range);
772
        addr := addr + incr;
773
      end if;
774
      if i > rl then
775
        slv8 := cpu_d;
776
        write(filename, slv8);
777
      end if;
778
      wait for 1 ps;
779
      wait until rising_edge(sig_clk);
780
    end loop;
781
    cpu_cs1 <= '0';
782
    cpu_a   <= (others => '0');
783
    for i in 0 to rl - 1 loop
784
      if (size + i) > rl then
785
        slv8 := cpu_d;
786
        write(filename, slv8);
787
      end if;
788
      wait for 1 ps;
789
      wait until rising_edge(sig_clk);
790
    end loop;
791
    slv8 := cpu_d;
792
    write(filename, slv8);
793
--        cpu_cs1 <= '1';
794
--        wait for 1 ps;
795
--        wait until rising_edge(sig_clk);
796
--        cpu_cs1 <= '0';
797
--        cpu_a   <= (others => '0');
798
--        for i in 1 to rl loop
799
--          --waiting for data to get back
800
--          wait for 1 ps;
801
--          wait until rising_edge(sig_clk);
802
--        end loop;  -- i
803
--        read_word(l, l_first);
804
--        if l_first = null then
805
--          exit;
806
--        end if;
807
--        get_var(l_first, tha.vsa, va);
808
--        assert va /= null and va.vt = vt_vector8 report "illegal address for read" severity failure;
809
--        va.slv8 := cpu_d;
810
--        va      := null;
811
  end read_dma;
812
 
813
  procedure process_thread (
814
    variable tha     : inout thread_access;
815
    signal   cpu_cs1 : out   std_logic;
816
    signal   cpu_we  : out   std_logic;
817
    signal   cpu_a   : out std_logic_vector(4 downto 0);
818
    signal   cpu_d   : inout std_logic_vector(7 downto 0)) is
819
    variable va       : var_access;
820
    variable l        : line;
821
    variable tm       : time;
822
    variable b        : bit;
823
    variable l_first  : line;
824
    variable l_second : line;
825
    variable bl_good  : boolean;
826
    variable bv8      : bit_vector(7 downto 0);
827
  begin
828
    while tha.st = st_ready and tha.w.all.cmd = wt_done loop
829
      if tha.next_tha /= null then
830
        if tha.next_tha.st = st_done then
831
          find_match(tha.dfa, "while", "while_end");
832
          deallocate(tha.next_tha);
833
        else
834
          process_thread(tha.next_tha, cpu_cs1, cpu_we, cpu_a, cpu_d);
835
          exit;
836
        end if;
837
      end if;
838
      if tha.st = st_ready then
839
        get_line(tha.dfa, l);
840
        read_word(l, l_first);
841
      end if;
842
      tha.st := st_ready;
843
      if l_first = null then
844
        tha.st := st_done;
845
      elsif l_first.all = "wait" then
846
        read(l, tm);
847
        tha.w.cmd    := wt_time;
848
        tha.w.tm_end := tm + now;
849
        check_wait(tha.w.all);
850
      elsif l_first.all = "wait_interrupt4" then
851
        tha.w.cmd := wt_irq4;
852
        read(l, b, bl_good);
853
        if bl_good then
854
          if b = '1' then
855
            tha.w.v := '1';
856
          else
857
            tha.w.v := '0';
858
          end if;
859
        else
860
          tha.w.v := '1';
861
        end if;
862
        check_wait(tha.w.all);
863
      elsif l_first.all = "while" then
864
        tha.next_tha := new thread;
865
        init_thread(tha.next_tha, tha.dfa, tha.dfa.ln, tha.w, tha.vsa);
866
      elsif l_first.all = "while_exit" then
867
        tha.st := st_done;
868
      elsif l_first.all = "while_end" then
869
        tha.dfa.ln := tha.ln_start;
870
      elsif l_first.all = "if" then
871
        read_word(l, l_first);
872
        read_word(l, l_second);
873
        var_test(l_first, l_second, l, bl_good, tha.vsa);
874
        if bl_good = false then
875
          find_match(tha.dfa, "if", "if_else", "if_end");
876
        end if;
877
      elsif l_first.all = "if_else" then
878
        find_match(tha.dfa, "if", "if_end");
879
      elsif l_first.all = "if_end" then
880
      elsif l_first.all = "clear" then
881
        read_word(l, l_first);
882
        assert l_first /= null report "clear without file or variable name" severity failure;
883
        get_var(l_first, tha.vsa, va);
884
        if va /= null then
885
          assert va.vt = vt_string report "non string variable name" severity failure;
886
          clear(va.s);
887
        else
888
          clear(l_first);
889
        end if;
890
        deallocate(l_first);
891
        va := null;
892
      elsif l_first.all = "read" then
893
        cpu_cs1 <= '1';
894
        read_word(l, l_first);
895
        assert l_first /= null report "read parameter missing" severity failure;
896
        get_var(l_first, tha.vsa, va);
897
        assert va = null or va.vt = vt_vector8 report "illegal address for read" severity failure;
898
        if va = null then
899
          read(l_first, bv8);
900
          cpu_a <= to_stdlogicvector(bv8)(cpu_a'left downto 0);
901
        else
902
          cpu_a <= va.slv8(cpu_a'left downto 0);
903
          va    := null;
904
        end if;
905
        --waiting for request to get to cpu block
906
        wait for 1 ps;
907
        wait until rising_edge(sig_clk);
908
        cpu_cs1 <= '0';
909
        cpu_a   <= (others => '0');
910
        for i in 1 to rl loop
911
          --waiting for data to get back
912
          wait for 1 ps;
913
          wait until rising_edge(sig_clk);
914
        end loop;  -- i
915
        read_word(l, l_first);
916
        if l_first = null then
917
          exit;
918
        end if;
919
        get_var(l_first, tha.vsa, va);
920
        assert va /= null and va.vt = vt_vector8 report "illegal address for read" severity failure;
921
        va.slv8 := cpu_d;
922
        va      := null;
923
      elsif l_first.all = "write" then
924
        cpu_cs1 <= '1';
925
        cpu_we  <= '1';
926
        read_word(l, l_first);
927
        assert l_first /= null report "write parameter missing" severity failure;
928
        get_var(l_first, tha.vsa, va);
929
        assert va = null or va.vt = vt_vector8 report "illegal address for write" severity failure;
930
        if va = null then
931
          read(l_first, bv8);
932
          cpu_a <= to_stdlogicvector(bv8)(cpu_a'left downto 0);
933
        else
934
          cpu_a <= va.slv8(cpu_a'left downto 0);
935
          va    := null;
936
        end if;
937
        deallocate(l_first);
938
        read_word(l, l_first);
939
        assert l_first /= null report "write parameter missing" severity failure;
940
        get_var(l_first, tha.vsa, va);
941
        assert va = null or va.vt = vt_vector8 report "illegal data for write" severity failure;
942
        if va = null then
943
          read(l_first, bv8);
944
          cpu_d <= to_stdlogicvector(bv8)(cpu_d'left downto 0);
945
        else
946
          cpu_d <= va.slv8(cpu_d'left downto 0);
947
          va    := null;
948
        end if;
949
        deallocate(l_first);
950
        wait for 1 ps;
951
        wait until rising_edge(sig_clk);
952
        cpu_cs1 <= '0';
953
        cpu_we  <= '0';
954
        cpu_a   <= (others => '0');
955
        cpu_d   <= (others => 'Z');
956
      elsif l_first.all = "read_dma" then
957
        read_dma(l, tha.vsa, cpu_cs1, cpu_we, cpu_a, cpu_d);
958
      elsif l_first.all = "write" then
959
--        write_dma(l, tha.vsa, cpu_cs1, cpu_we, cpu_a, cpu_d);
960
      elsif l_first.all = "print" then
961
        read_word(l, l_first);
962
        assert l_first /= null report "no file or variable name for print" severity failure;
963
        get_var(l_first, tha.vsa, va);
964
        if va /= null then
965
          deallocate(l_first);
966
          l_first := va.s;
967
          va      := null;
968
        end if;
969
        read_word(l, l_second);
970
        assert l_second /= null report "no variable name for print" severity failure;
971
        get_var(l_second, tha.vsa, va);
972
        l_second := null;
973
        assert va /= null report "invalid variable for print" severity failure;
974
        if va.vt = vt_string then
975
          write(l_first, va.s);
976
        elsif va.vt = vt_bit then
977
          write(l_first, va.sl);
978
        elsif va.vt = vt_vector8 then
979
          write(l_first, va.slv8);
980
        end if;
981
        l_first := null;
982
        va      := null;
983
      elsif l_first.all = "breakpoint" then
984
        deallocate(l_first);
985
      else
986
        read_word(l, l_second);
987
        var_op(l_first, l_second, l, tha.vsa);
988
      end if;
989
    end loop;
990
    deallocate(l);
991
    deallocate(l_first);
992
  end process_thread;
993
 
994
begin
995
  sig_clk <= not sig_clk after tclk;
996
  clk <= sig_clk;
997
  process
998
    file fl               : text;
999
    variable l            : line;
1000
    variable l_params     : line;
1001
    variable tm           : time;
1002
    variable bl_alldone   : boolean;
1003
    variable vsa          : vars_access;
1004
    variable l_first      : line;
1005
    variable l_second     : line;
1006
    variable l_third      : line;
1007
    variable wa           : waiter_access;
1008
    variable dfa          : dfile_access;
1009
    variable tholda_start : tholder_access;
1010
    variable tholda       : tholder_access;
1011
    variable tholda_prev  : tholder_access;
1012
  begin
1013
    rstN    <= '0';
1014
    cpu_cs1 <= '0';
1015
    cpu_cs2 <= '0';
1016
    cpu_cs3 <= '0';
1017
    cpu_we  <= '0';
1018
    cpu_a   <= (others => '0');
1019
    cpu_d   <= (others => 'Z');
1020
    file_open(fl, fname, read_mode);
1021
    vsa     := new vars;
1022
    loop
1023
      get_line(fl, l);
1024
      read_word(l, l_first);
1025
      if l_first = null then
1026
        exit;
1027
      elsif l_first.all = "clock" then
1028
        read(l, tm);
1029
        tclk := tm;
1030
      elsif l_first.all = "reset" then
1031
        read(l, tm);
1032
        wait for tm;
1033
        rstN <= '1';
1034
      elsif l_first.all = "read_latency" then
1035
        read(l, rl);
1036
      elsif l_first.all = "thread" then
1037
        tholda := new tholder;
1038
        if tholda_start = null then
1039
          tholda_start := tholda;
1040
          tholda_prev  := tholda_start;
1041
        else
1042
          tholda_prev.n := tholda;
1043
          tholda_prev   := tholda;
1044
        end if;
1045
        tholda.th := new thread;
1046
        read_word(l, l_second);
1047
        wa        := new waiter;
1048
        dfa       := new dfile;
1049
        dfa.fn    := l_second;
1050
        l_second  := null;
1051
        dfa.ln    := 0;
1052
        init_thread(tholda.th, dfa, dfa.ln, wa, vsa);
1053
        while l_first /= null and l_first.all /= "parameters" loop
1054
          get_line(tholda.th.dfa, l_params);
1055
          read_word(l_params, l_first);
1056
        end loop;
1057
        if l_first /= null and l_first.all = "parameters" then
1058
          loop
1059
            read_word(l_params, l_first);
1060
            if l_first = null then
1061
              exit;
1062
            end if;
1063
            assert l_first.all = "bit" or l_first.all = "vector8" or l_first.all = "string" report "illegal variable type in parameter list" severity failure;
1064
            read_word(l_params, l_second);
1065
            assert l_second /= null report "variable name missing in parameter list" severity failure;
1066
            declare_var(l_first, l_second, tholda.th.vsa);
1067
            deallocate(l_first);
1068
            l_first  := l_second;
1069
            l_second := new string'("=");
1070
            read_word(l, l_third);
1071
            assert l_third /= null report "variable value missing in thread spawn call" severity failure;
1072
            var_op(l_first, l_second, l_third, tholda.th.vsa);
1073
          end loop;
1074
        else
1075
          tholda.th.dfa.ln := 0;
1076
        end if;
1077
        tholda := tholda.n;
1078
      else
1079
        read_word(l, l_second);
1080
        var_op(l_first, l_second, l, vsa);
1081
      end if;
1082
    end loop;
1083
    wait for 1 ps;
1084
    wait until rising_edge(sig_clk);
1085
    loop
1086
      bl_alldone := true;
1087
      tholda     := tholda_start;
1088
      while tholda /= null loop
1089
        if tholda.th.w.cmd /= wt_done then
1090
          check_wait(tholda.th.w.all);
1091
          bl_alldone := false;
1092
        end if;
1093
        tholda := tholda.n;
1094
      end loop;
1095
      tholda      := tholda_start;
1096
      tholda_prev := null;
1097
      while tholda /= null loop
1098
        if tholda.th.w.cmd = wt_done then
1099
          process_thread(tholda.th, cpu_cs1, cpu_we, cpu_a, cpu_d);
1100
          bl_alldone := false;
1101
        end if;
1102
        if tholda.th.st = st_done then
1103
          if tholda_prev /= null then
1104
            tholda_prev.n := tholda.n;
1105
          else
1106
            tholda_start := tholda.n;
1107
          end if;
1108
          deallocate(tholda.th.w);
1109
          deallocate(tholda.th.vsa);
1110
          deallocate(tholda.th.dfa);
1111
          deallocate(tholda.th);
1112
        end if;
1113
        tholda_prev := tholda;
1114
        tholda      := tholda.n;
1115
      end loop;
1116
      wait for 1 ps;
1117
      wait until rising_edge(sig_clk);
1118
      if bl_alldone then
1119
        cpu_cs1 <= '0';
1120
        cpu_we  <= '0';
1121
        cpu_a   <= (others => '0');
1122
        cpu_d   <= (others => 'Z');
1123
        wait;
1124
      end if;
1125
    end loop;
1126
  end process;
1127
end cpu_sim_simple;
1128
 

powered by: WebSVN 2.1.0

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