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

Subversion Repositories ttl_library

[/] [ttl_library/] [trunk/] [TTLPrivatePkg.vhd] - Blame information for rev 14

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 14 david237
-----------------------------------------------------------------------
2
-- Bipolar TTL models (VHDL)                                         --
3
-- David R Brooks                                                    --
4
-- May, 2016.  Perth, Australia                                      --
5
-- Compliance: VHDL 2008                                             --
6
-- NB Simulation only: they are NOT synthesizable.                   --
7
-- Private package, used internally by the models.                   --
8
-----------------------------------------------------------------------
9
 
10
library ieee;
11
    use ieee.std_logic_1164.all;
12
    use ieee.std_logic_misc.all;
13
    use ieee.numeric_std.all;
14
    use ieee.std_logic_textio.all;
15
 
16
    use std.textio.all;
17
 
18
 
19
package TTLPrivate is
20
 
21
--                          For each gate      For each input
22
type    TTLInputs  is array(positive range <>, positive range <>) of std_logic;
23
type    TTLOutputs is array(positive range <>) of std_logic;
24
 
25
type    TTLMode    is (Zand, Zor, Zxor, Zbuf);      -- 'Z' so they aren't keywords
26
type    TTLSingle  is array(1 to 1) of std_logic;
27
 
28
subtype TTLword    is unsigned(3 downto 0);
29
type    TTL2word   is    array(2 downto 1) of TTLword;
30
 
31
subtype TTLquad    is std_logic_vector(4 downto 1);
32
type    TTLmem     is array(15 downto 0) of TTLquad;
33
subtype TTLaddr    is natural range 15 downto 0;
34
 
35
type    TTLmemop   is (Totem, OpenColl, TriState);  -- Memory-block outputs
36
type    TTLmemory  is array(natural range <>, natural range <>) of std_logic;
37
type    TTLmemptr  is access TTLmemory;
38
 
39
subtype TTLbyte    is integer range 0 to 255;       -- 8-bit integer
40
type    TTLline    is array(0 to 299) of TTLbyte;
41
 
42
-----------------------------------------------------------------------
43
-- Procedure: Initialise memory-block from a file (Intel format)
44
-----------------------------------------------------------------------
45
procedure TTL_mem_init(fname : in String; MA : inout TTLmemptr);
46
 
47
-----------------------------------------------------------------------
48
-- Function: "safe" conversion from unsigned to natural
49
-- Only "impure" because it references "now"   
50
-----------------------------------------------------------------------
51
impure function TTL_to_integer(i : unsigned) return natural;
52
 
53
-----------------------------------------------------------------------
54
-- Function: simulate open-collector outputs    
55
-----------------------------------------------------------------------
56
pure function TTL_OC(i : std_logic) return std_logic;
57
 
58
-----------------------------------------------------------------------
59
-- Function: successor fn. for LS490 & similar counters    
60
-----------------------------------------------------------------------
61
pure function TTL490(i : TTLword) return TTLword;
62
 
63
-----------------------------------------------------------------------
64
-- Function: "not", safe with 3-state signals
65
-----------------------------------------------------------------------
66
pure function notz(i : std_logic) return std_logic;
67
 
68
-----------------------------------------------------------------------
69
-- Function: "not", safe with 3-state signals
70
-----------------------------------------------------------------------
71
pure function notz(i : std_logic_vector) return std_logic_vector;
72
 
73
-----------------------------------------------------------------------
74
-- Function: reverse bit order
75
-----------------------------------------------------------------------
76
pure function TTL_REV(i : std_logic_vector) return std_logic_vector;
77
pure function TTL_REV(i : unsigned) return unsigned;
78
pure function TTL_REV(i : std_logic_vector) return unsigned;
79
pure function TTL_REV(i : unsigned) return std_logic_vector;
80
 
81
-----------------------------------------------------------------------
82
-- Standard testbench support
83
-----------------------------------------------------------------------
84
component TTLBench is
85
generic(
86
    StimClk   : std_logic      := '1';  -- Values after the relevant clock edge 
87
    CheckClk  : std_logic      := '0';
88
    Period    : time           := 50 ns;
89
    Finish    : time           := 20 us;
90
    SevLevel  : severity_level := failure
91
);
92
port(
93
    J    : out unsigned;
94
    B    : out unsigned;            -- Indefinite range
95
    CLK  : out std_logic;
96
    RS   : out std_logic;
97
    D    : in  std_logic_vector;
98
    E    : in  std_logic_vector;    -- Indefinite range
99
    ANS  : out std_logic            -- Result flag: view in waveforms, 'X' if fault
100
);
101
end component TTLBench;
102
 
103
-----------------------------------------------------------------------
104
-- Universal simple gate implementation
105
-----------------------------------------------------------------------
106
component TTLgate is
107
generic(
108
    mode   : TTLMode;       -- Zand, Zor, Zxor, Zbuf
109
    invert : std_logic;     -- '1' will invert the output
110
    ohigh  : std_logic;     -- '1' = normal, 'Z' = open collectors
111
    tPLH   : time := 10 ns;
112
    tPHL   : time := 10 ns
113
);
114
port(
115
    ins   : in  TTLInputs;
116
    outs  : out TTLOutputs
117
);
118
end component TTLgate;
119
 
120
-----------------------------------------------------------------------
121
-- Asymmetric propagation delays
122
-----------------------------------------------------------------------
123
component TTLdelay is
124
generic(
125
    tPLH : time := 10 ns;
126
    tPHL : time := 10 ns
127
);
128
port(
129
    A : in  std_logic;
130
    B : out std_logic
131
);
132
end component TTLdelay;
133
 
134
component TTLdelays is     -- The same, for a vector
135
generic(
136
    tPLH : time := 10 ns;
137
    tPHL : time := 10 ns
138
);
139
port(
140
    A : in  std_logic_vector;
141
    B : out std_logic_vector
142
);
143
end component TTLdelays;
144
 
145
-----------------------------------------------------------------------
146
-- 3-state buffer with delays
147
-----------------------------------------------------------------------
148
component TTL3State is
149
generic(
150
    tPLH : time :=  6.0 ns;
151
    tPHL : time :=  7.5 ns;
152
    tPZH : time := 19.5 ns;
153
    tPZL : time := 21.0 ns;
154
    tPHZ : time :=  8.5 ns;
155
    tPLZ : time := 14.0 ns
156
);
157
port(
158
    A    : in  std_logic;
159
    E    : in  std_logic;       -- Enable, active high
160
    Y    : out std_logic
161
);
162
end component TTL3State;
163
 
164
-----------------------------------------------------------------------
165
-- Basic monostable element
166
-----------------------------------------------------------------------
167
component TTLmonostable is
168
generic(
169
    pwidth        : time    := 100 us;  -- Triggered pulse width
170
    mintrig       : time    :=  50 ns;  -- Minimum trigger width
171
    retriggerable : boolean := true
172
);
173
port(
174
    trig  : in  std_logic;
175
    reset : in  std_logic;
176
    Q     : out std_logic
177
);
178
end component TTLmonostable;
179
 
180
-----------------------------------------------------------------------
181
-- Elementary flipflop
182
-- A basic JK flipflop with resets. All active high
183
-----------------------------------------------------------------------
184
component TTLflipflop is
185
generic(
186
    tPLHCP  : time    := 20 ns;     -- Clock rising
187
    tPHLCP  : time    := 30 ns;     -- Clock falling
188
    tPLHSC  : time    := 20 ns;     -- S/C rising
189
    tPHLSC  : time    := 30 ns;     -- S/C falling
190
    tSETUP  : time    :=  0 ns;     -- Setup time before clock (0 = no test)
191
    Safeclk : boolean := false      -- Enforce stable inputs before active clock edge
192
);
193
port(
194
    J, K, C, S, R : in  std_logic;
195
    Q, QB         : out std_logic
196
);
197
end component TTLflipflop;
198
 
199
-----------------------------------------------------------------------
200
-- 1-bit & 3-bit counter with adjustable modulus
201
-- See 7490/92/93 & similar parts
202
-----------------------------------------------------------------------
203
component TTLcount4 is
204
generic(
205
    tPLH0   : time     := 16 ns;
206
    tPHL0   : time     := 18 ns;
207
    tPLH1   : time     := 16 ns;
208
    tPHL1   : time     := 21 ns;
209
    tPLH2   : time     := 32 ns;
210
    tPHL2   : time     := 35 ns;
211
    tPLH3   : time     := 32 ns;
212
    tPHL3   : time     := 35 ns;
213
    modulus : positive := 10        -- Legal values are 10,12,16
214
);
215
port(
216
    ld          : in  std_logic;
217
    d           : in  std_logic_vector(3 downto 0);
218
    clka, clkb  : in  std_logic;    -- Falling-edge clock
219
    rst, set    : in  std_logic;    -- Active-low reset, set
220
    val         : out std_logic_vector(3 downto 0)
221
);
222
end component TTLcount4;
223
 
224
-----------------------------------------------------------------------
225
-- 4-bit synchronous counter with adjustable modulus
226
-- See 74160..3 & similar parts
227
-----------------------------------------------------------------------
228
component TTLsynccount is
229
generic(
230
    asyncreset : boolean := false;
231
    modulus    : natural := 10;     -- 10, 16 are legal
232
    tPLHT      : time    := 25 ns;
233
    tPHLT      : time    := 23 ns;
234
    tPLHQ      : time    := 24 ns;
235
    tPHLQ      : time    := 27 ns
236
);
237
port(
238
    PE, CP, CEP, CET, RST : in  std_logic;
239
    TC                    : out std_logic;
240
    P                     : in  std_logic_vector(3 downto 0);
241
    Q                     : out std_logic_vector(3 downto 0)
242
);
243
end component TTLsynccount;
244
 
245
-----------------------------------------------------------------------
246
-- Synchronous bidirectional binary/decade bidirectional counter
247
-----------------------------------------------------------------------
248
component TTLbiCount is
249
generic(
250
    decade  : boolean := true;
251
    tPLHQ   : time    := 20 ns;
252
    tPHLQ   : time    := 20 ns;
253
    tPLHT   : time    := 30 ns;
254
    tPHLT   : time    := 30 ns;
255
    tSU     : time    := 15 ns;
256
    tSUPE   : time    := 20 ns
257
);
258
port(
259
    PE, CP, CEP, CET, U_D : in std_logic;
260
    P                     : in  std_logic_vector(3 downto 0);
261
    Q                     : out std_logic_vector(3 downto 0);
262
    TC                    : out std_logic
263
);
264
end component TTLbiCount;
265
 
266
-----------------------------------------------------------------------
267
-- Generic RAM block with 3-wire asynchronous control
268
-- NB Control inputs are active low (as in physical chips)
269
-----------------------------------------------------------------------
270
component TTLramblock is
271
generic(
272
    fname : String    := "";        -- Name of initialisation file (if any)
273
    Omode : TTLmemop  := OpenColl;  -- Output mode
274
    INVT  : std_logic := '0';       -- '1' will invert outputs
275
    tPLC  : time      := 10 ns;
276
    tPLA  : time      := 37 ns;
277
    tSUD  : time      := 25 ns;
278
    tSUA  : time      := 10 ns
279
);
280
port(
281
    RA    : in    std_logic_vector;
282
    WA    : in    std_logic_vector;
283
    D     : in    std_logic_vector;
284
    O     : out   std_logic_vector;
285
    CE    : in    std_logic;
286
    RE    : in    std_logic;
287
    WE    : in    std_logic
288
);
289
end component TTLramblock;
290
 
291
-----------------------------------------------------------------------
292
-- Generic addressable latch
293
-----------------------------------------------------------------------
294
component TTLadLatch is
295
generic(
296
    ABits   : positive := 2;
297
    tPXDA   : time     := 30 ns;
298
    tPHLC   : time     := 18 ns
299
);
300
port(
301
    D   : in  std_logic;
302
    En  : in  std_logic;
303
    Cn  : in  std_logic;
304
    A   : in  unsigned(ABits-1 downto 0);
305
    Z   : out std_logic_vector(2**ABits-1 downto 0)
306
);
307
end component TTLadLatch;
308
 
309
-----------------------------------------------------------------------
310
-- Simple blocks used by testbenches
311
-----------------------------------------------------------------------
312
component TTLxcvr is
313
generic(
314
    INVT : boolean := false;
315
    tPLH : time    :=  6.0 ns;
316
    tPHL : time    :=  7.5 ns;
317
    tPZH : time    := 19.5 ns;
318
    tPZL : time    := 21.0 ns;
319
    tPHZ : time    :=  8.5 ns;
320
    tPLZ : time    := 14.0 ns
321
);
322
port(
323
    A, B : inout  std_logic_vector; -- Ports, indefinite width       
324
    EN   : in     std_logic;        -- Enable, active low
325
    A2B  : in     std_logic         -- Direction
326
);
327
end component TTLxcvr;
328
 
329
component TTL_FF is
330
port(
331
    q   : out std_logic;
332
    d   : in  std_logic;
333
    clk : in  std_logic;
334
    cl  : in  std_logic
335
);
336
end component TTL_FF;
337
 
338
end package TTLPrivate;
339
 
340
--=====================================================================
341
package body TTLPrivate is
342
--=====================================================================
343
 
344
-----------------------------------------------------------------------
345
-- Procedure: Initialise memory-block from a file (Intel format)
346
-----------------------------------------------------------------------
347
procedure TTL_mem_init(fname : in String; MA : inout TTLmemptr) is
348
    file     fptr   : text;                                 -- Source file, Intel hex format
349
    variable lptr   : line;                                 -- Line from file
350
    variable data   : TTLline;                              -- Ditto, converted to bytes
351
    variable lsize  : integer;                              -- Line size
352
    variable stchar : character;                            -- Start char. - ':'
353
    variable valid  : boolean;                              -- Result of "read"
354
    variable abyte  : std_logic_vector(7 downto 0);         -- Byte, read by hread
355
    variable sum    : TTLbyte;                              -- Intel-hex checksum
356
    variable adbase : natural;                              -- MS 16 bits of load address
357
    variable addr   : natural;                              -- Current load address
358
    variable word   : std_logic_vector(MA.all'range(2));    -- 1 word of memory
359
    variable nwrds  : natural;                              -- No. of words in the line
360
    variable bptr   : natural;                              -- Byte pointer
361
    variable linum  : natural := 0;                         -- Source line number (for messages)
362
 
363
    constant nbytes : natural := (MA.all'length(2) / 8);    -- No. of bytes per memory word
364
 
365
begin
366
    if fname /= "" then             -- If no file, skip initialisation
367
        assert MA.all'length(2) mod 8 = 0
368
            report "Memory <" & fname & "> memory width /= 8*N"
369
            severity failure;       -- Loads 8-bit bytes
370
 
371
        file_open(fptr, fname, READ_MODE);
372
        adbase := 0;                -- Default address-base
373
        while not endfile(fptr) loop
374
            readline(fptr, lptr);
375
            linum := linum + 1;
376
            read(lptr, stchar, valid);
377
            assert valid and stchar = ':'
378
                report "Memory <" & fname & "> line " & natural'image(linum)
379
                                  & ": bad start"
380
                severity failure;   -- Line should start with ':'
381
            hread(lptr, abyte);     -- Read 1st byte
382
            data(0) := to_integer(unsigned(abyte));
383
            sum     := data(0);
384
            lsize   := sum + 4;     -- Total record length (excl. length byte)
385
            for i in 1 to lsize loop
386
                hread(lptr, abyte);
387
                data(i) := to_integer(unsigned(abyte));
388
                sum     := (sum + data(i)) mod 256;
389
            end loop;
390
            assert sum = 0          -- Line checksum
391
                report "Memory <" & fname & "> line " & natural'image(linum)
392
                                  & ": bad checksum: " & natural'image(sum)
393
                severity failure;
394
 
395
            case data(3) is         -- Record type...
396
                when 0      =>          -- Data
397
                    assert data(0) mod nbytes = 0
398
                        report "Memory <" & fname & "> line " & natural'image(linum)
399
                                          & ": line length not an exact number of words"
400
                        severity failure;
401
                    addr := adbase + (data(1) * 2**8) + data(2);
402
                    assert addr mod nbytes = 0
403
                        report "Memory <" & fname & "> line " & natural'image(linum)
404
                                          & ": line not word aligned"
405
                        severity failure;
406
                    addr  := addr / nbytes;             -- Make a word address
407
                    nwrds := data(0) / nbytes;          -- No. of words, this line
408
                    bptr  := 4;                         -- 1st data byte
409
                    for j in 0 to nwrds-1 loop
410
                        word := (others => '0');
411
                        for i in 0 to nbytes-1 loop     -- Assemble 1 memory word
412
                            word := word(word'left-8 downto 0)
413
                                    & std_logic_vector(to_unsigned(data(bptr), 8));
414
                            bptr := bptr + 1;
415
                        end loop;
416
                        for i in word'range loop
417
                            MA.all(addr,i) := word(i);  -- Load, bit by bit
418
                        end loop;
419
                        addr := addr + 1;
420
                    end loop;
421
 
422
                when 1      =>          -- End of file
423
                    exit;
424
 
425
                when 4      =>          -- Extended linear address
426
                    adbase := (data(4) * 2**24) + (data(5) * 2**16);
427
 
428
                when others =>          -- Garbage
429
                    assert false
430
                        report "Memory <" & fname & "> line " & natural'image(linum)
431
                                          & ": bad record type"
432
                        severity failure;
433
            end case;
434
        end loop;
435
        file_close(fptr);
436
    end if;
437
end TTL_mem_init;
438
 
439
-----------------------------------------------------------------------
440
-- Function: "safe" conversion from unsigned to natural   
441
-- Only "impure" because it references "now"   
442
-----------------------------------------------------------------------
443
impure function TTL_to_integer(i : unsigned) return natural is
444
begin
445
    if now < 1 ns then          -- Suppress bad values at start-up
446
        return 0;
447
    else
448
        return to_integer(i);
449
    end if;
450
end function TTL_to_integer;
451
 
452
-----------------------------------------------------------------------
453
-- Function: simulate open-collector outputs    
454
-----------------------------------------------------------------------
455
pure function TTL_OC(i : std_logic) return std_logic is
456
begin
457
    if i = '1' then return 'Z';
458
               else return i;
459
    end if;
460
end function TTL_OC;
461
 
462
-----------------------------------------------------------------------
463
-- Function: successor fn. for LS490 & similar counters    
464
-----------------------------------------------------------------------
465
pure function TTL490(i : TTLword) return TTLword is
466
begin
467
    case to_integer(i) is
468
        when 11 | 13 | 15 => return i - 9;
469
        when others       => return i + 1;
470
    end case;
471
end function TTL490;
472
 
473
-----------------------------------------------------------------------
474
-- Function: "not", safe with 3-state signals
475
-----------------------------------------------------------------------
476
pure function notz(i : std_logic) return std_logic is
477
begin
478
    case i is
479
        when 'Z'    => return 'Z';  -- IEEE "not" would return 'X'
480
        when others => return not i;
481
    end case;
482
end function notz;
483
 
484
-----------------------------------------------------------------------
485
-- Function: "not", safe with 3-state signals
486
-----------------------------------------------------------------------
487
pure function notz(i : std_logic_vector) return std_logic_vector is
488
    variable k : std_logic_vector(i'range);
489
begin
490
    for j in i'range loop
491
        case i(j) is
492
            when 'Z'    => k(j) := 'Z';  -- IEEE "not" would return 'X'
493
            when others => k(j) := not i(j);
494
        end case;
495
    end loop;
496
    return k;
497
end function notz;
498
 
499
-----------------------------------------------------------------------
500
-- Function: reverse bit order
501
-----------------------------------------------------------------------
502
pure function TTL_REV(i : std_logic_vector) return std_logic_vector is
503
    variable result: std_logic_vector(i'RANGE);
504
    alias aa: std_logic_vector(i'REVERSE_RANGE) is i;
505
begin
506
    for i in aa'RANGE loop
507
        result(i) := aa(i);
508
    end loop;
509
    return result;
510
end function TTL_REV;
511
 
512
pure function TTL_REV(i : unsigned) return unsigned is
513
    variable result: unsigned(i'RANGE);
514
    alias aa: unsigned(i'REVERSE_RANGE) is i;
515
begin
516
    for i in aa'RANGE loop
517
        result(i) := aa(i);
518
    end loop;
519
    return result;
520
end function TTL_REV;
521
 
522
pure function TTL_REV(i : std_logic_vector) return unsigned is
523
    variable result: unsigned(i'RANGE);
524
    alias aa: std_logic_vector(i'REVERSE_RANGE) is i;
525
begin
526
    for i in aa'RANGE loop
527
        result(i) := aa(i);
528
    end loop;
529
    return result;
530
end function TTL_REV;
531
 
532
pure function TTL_REV(i : unsigned) return std_logic_vector is
533
    variable result: std_logic_vector(i'RANGE);
534
    alias aa: unsigned(i'REVERSE_RANGE) is i;
535
begin
536
    for i in aa'RANGE loop
537
        result(i) := aa(i);
538
    end loop;
539
    return result;
540
end function TTL_REV;
541
 
542
 
543
 
544
--=====================================================================
545
end package body TTLPrivate;
546
--=====================================================================
547
 
548
-----------------------------------------------------------------------
549
-- Standard testbench support
550
-----------------------------------------------------------------------
551
library ieee;
552
    use ieee.std_logic_1164.all;
553
    use ieee.numeric_std.all;
554
    use work.TTLPrivate.all;
555
 
556
entity TTLBench is
557
generic(
558
    StimClk   : std_logic      := '1';  -- Values after the relevant clock edge 
559
    CheckClk  : std_logic      := '0';
560
    Period    : time           := 50 ns;
561
    Finish    : time           := 20 us;
562
    SevLevel  : severity_level := failure
563
);
564
port(
565
    J    : out unsigned;
566
    B    : out unsigned;            -- Indefinite range
567
    CLK  : out std_logic;
568
    RS   : out std_logic;
569
    D    : in  std_logic_vector;
570
    E    : in  std_logic_vector;    -- Indefinite range
571
    ANS  : out std_logic            -- Result flag: view in waveforms, 'X' if fault
572
);
573
end entity;
574
 
575
architecture Test of TTLBench is
576
    signal JI, BI : unsigned(J'length-1 downto 0) := (others => '0');
577
    signal CLKI   : std_logic := not StimClk;
578
    signal RSI    : std_logic;
579
 
580
begin
581
    J   <= JI;
582
    B   <= BI;
583
    CLK <= CLKI;
584
    RS  <= RSI;
585
 
586
    -----------------------------------------------------------------------
587
    -- Test-Pattern Generators                        
588
    -----------------------------------------------------------------------
589
    process is                              -- Generate clock, until we stop
590
    begin
591
        if now > Finish then
592
            wait;
593
        else
594
            wait for Period / 2;
595
            CLKI <= not CLKI;
596
        end if;
597
    end process;
598
 
599
    -- To ensure things really do reset, ensure an active transition of RS
600
    -- after the simulation initialises.
601
    RSI <= '1', '0' after 5 ns, '1' after Period * 1.25;            -- Active-low reset
602
 
603
    process(CLKI) is
604
        variable MLS : unsigned(32 downto 0) := (others => '1');
605
    begin
606
        if CLKI'event and CLKI = StimClk then
607
            MLS := MLS(31 downto 0) & (MLS(32) xor MLS(12));        -- Max-length sequence
608
            JI  <= MLS(JI'range);
609
            BI <= BI + 1;                                           -- Binary counter
610
        end if;
611
    end process;
612
 
613
    -----------------------------------------------------------------------
614
    -- Validate the results
615
    -- Test patterns change on CLK active, check on CLK inactive
616
    -----------------------------------------------------------------------
617
    process(CLKI) is
618
    begin
619
        if CLKI'event and CLKI = CheckClk then
620
            if D /= E then          -- Verify failed
621
                ANS <= 'X';
622
                assert RSI = '0'    -- Don't check during initialisation
623
                    report "Verify failed: Exp """ & to_string(D) & """" &
624
                                         " Rcv """ & to_string(E) & """" &
625
                                            " at " & time'image(now)
626
                    severity SevLevel;
627
            else
628
                ANS <= '0';
629
            end if;
630
        end if;
631
    end process;
632
 
633
end architecture Test;
634
 
635
-----------------------------------------------------------------------
636
-- Universal simple gate implementation
637
-----------------------------------------------------------------------
638
library ieee;
639
    use ieee.std_logic_1164.all;
640
    use ieee.std_logic_misc.all;
641
    use work.TTLPrivate.all;
642
 
643
entity TTLgate is
644
generic(
645
    mode   : TTLMode;
646
    invert : std_logic;     -- '1' will invert the output
647
    ohigh  : std_logic;     -- '1' = normal, 'Z' = open collectors
648
    tPLH   : time := 10 ns;
649
    tPHL   : time := 10 ns
650
);
651
port(
652
    ins   : in  TTLInputs;
653
    outs  : out TTLOutputs
654
);
655
end entity TTLgate;
656
 
657
architecture BEHAV of TTLgate is
658
    signal Y, Z : TTLOutputs(outs'range);
659
begin
660
    process(ins) is
661
        variable X : std_logic_vector(ins'range(2));
662
    begin
663
        for i in outs'range loop
664
            for j in ins'range(2) loop
665
                X(j) := ins(i,j);   -- Extract column into a slv
666
            end loop;
667
 
668
            case mode is            -- The gate function
669
                when Zand   => Y(i) <= and_reduce(X);
670
                when Zor    => Y(i) <= or_reduce(X);
671
                when Zxor   => Y(i) <= xor_reduce(X);
672
                when others => Y(i) <= X(1);  -- Just a 1-input buffer
673
            end case;
674
        end loop;
675
    end process;
676
    G1: for i in outs'range generate
677
    begin
678
                                    -- Output inverted & open collector, as reqd.
679
        Z(i) <= '0' when Y(i) = invert else ohigh;
680
 
681
        OP: TTLdelay                -- Apply gate delays
682
        generic map(
683
            tPLH => tPLH,
684
            tPHL => tPHL
685
        )
686
        port map(
687
            A => Z(i),
688
            B => outs(i)
689
        );
690
    end generate;
691
end architecture BEHAV;
692
 
693
-----------------------------------------------------------------------
694
-- Apply asymmetric propagation delays
695
-----------------------------------------------------------------------
696
library ieee;
697
    use ieee.std_logic_1164.all;
698
 
699
entity TTLdelay is
700
generic(
701
    tPLH : time := 10 ns;
702
    tPHL : time := 10 ns
703
);
704
port(
705
    A : in  std_logic;
706
    B : out std_logic := 'U'
707
);
708
end entity TTLdelay;
709
 
710
architecture BEHAV of TTLdelay is
711
begin
712
    process(A) is
713
    begin
714
        if    rising_edge(A) then
715
            B <= 'X', A after tPLH;     -- Rising delay
716
        elsif falling_edge(A) then
717
            B <= 'X', A after tPHL;     -- Falling delay
718
        else
719
            B <= A;                     -- 'Z', or bad value
720
        end if;
721
    end process;
722
end architecture BEHAV;
723
 
724
library ieee;
725
    use ieee.std_logic_1164.all;
726
    use work.TTLPrivate.all;
727
 
728
entity TTLdelays is     -- The same, for a vector
729
generic(
730
    tPLH : time := 10 ns;
731
    tPHL : time := 10 ns
732
);
733
port(
734
    A : in  std_logic_vector;
735
    B : out std_logic_vector
736
);
737
end entity TTLdelays;
738
 
739
architecture BEHAV of TTLdelays is
740
begin
741
    G: for i in A'range generate
742
        DO: TTLdelay
743
        generic map(
744
            tPLH => tPLH,
745
            tPHL => tPHL
746
        )
747
        port map(
748
            A => A(i),
749
            B => B(i)
750
        );
751
    end generate;
752
end architecture BEHAV;
753
 
754
-----------------------------------------------------------------------
755
-- 3-state buffer with delays
756
-----------------------------------------------------------------------
757
library ieee;
758
    use ieee.std_logic_1164.all;
759
 
760
entity TTL3State is
761
generic(
762
    tPLH : time :=  6.0 ns;
763
    tPHL : time :=  7.5 ns;
764
    tPZH : time := 19.5 ns;
765
    tPZL : time := 21.0 ns;
766
    tPHZ : time :=  8.5 ns;
767
    tPLZ : time := 14.0 ns
768
);
769
port(
770
    A    : in  std_logic;
771
    E    : in  std_logic;       -- Enable, active high
772
    Y    : out std_logic
773
);
774
end entity TTL3State;
775
 
776
architecture BEHAV of TTL3State is
777
begin
778
    process(A, E) is
779
        variable tPD, tPZX, tPXZ : time;
780
    begin
781
        if A = '1' then
782
            tPD  := tPLH;
783
            tPZX := tPZH;
784
            tPXZ := tPHZ;
785
        else
786
            tPD  := tPHL;
787
            tPZX := tPZL;
788
            tPXZ := tPLZ;
789
        end if;
790
 
791
        if    rising_edge(E)      then  -- Enable
792
            Y <= A after tPZX;
793
        elsif falling_edge(E)     then  -- Disable
794
            Y <= 'Z' after tPXZ;
795
        elsif A'event and E = '1' then  -- Data change (& enabled)
796
            Y <= A after tPD;
797
        else
798
            Y <= 'Z';                   -- Correct? (or null)
799
        end if;
800
    end process;
801
end architecture BEHAV;
802
 
803
-----------------------------------------------------------------------
804
-- 3-state transceiver with delays
805
-----------------------------------------------------------------------
806
library ieee;
807
    use ieee.std_logic_1164.all;
808
 
809
entity TTLxcvr is
810
generic(
811
    INVT : boolean := false;
812
    tPLH : time    :=  6.0 ns;
813
    tPHL : time    :=  7.5 ns;
814
    tPZH : time    := 19.5 ns;
815
    tPZL : time    := 21.0 ns;
816
    tPHZ : time    :=  8.5 ns;
817
    tPLZ : time    := 14.0 ns
818
);
819
port(
820
    A, B : inout  std_logic_vector; -- Ports, indefinite width       
821
    EN   : in     std_logic;        -- Enable, active low
822
    A2B  : in     std_logic         -- Direction
823
);
824
end entity TTLxcvr;
825
 
826
architecture BEHAV of TTLxcvr is
827
begin
828
    assert A'left = B'left and A'right = B'right report "Range mismatch" severity failure;
829
 
830
    process(all) is
831
        variable STATE   : std_logic_vector(3 downto 0);
832
        variable OUTPUTS : std_logic_vector(1 downto 0);
833
    begin
834
        for i in A'range loop
835
            STATE := (EN, A2B, A(i), B(i));
836
            if INVT then
837
                STATE := STATE xor "0011";
838
            end if;
839
 
840
            case STATE is
841
                when "X---" => OUTPUTS := "XX";     -- Bad controls
842
                when "-X--" => OUTPUTS := "XX";
843
                when "00-0" => OUTPUTS := "0Z";     -- Drive B -> A
844
                when "00-1" => OUTPUTS := "1Z";
845
                when "00-X" => OUTPUTS := "XZ";
846
                when "010-" => OUTPUTS := "Z0";     -- Drive A -> B
847
                when "011-" => OUTPUTS := "Z1";
848
                when "01X-" => OUTPUTS := "ZX";
849
                when others => OUTPUTS := "ZZ";     -- Disable
850
            end case;
851
            A(i) <= OUTPUTS(1);
852
            B(i) <= OUTPUTS(0);
853
        end loop;
854
    end process;
855
 
856
end architecture BEHAV;
857
 
858
-----------------------------------------------------------------------
859
-- Basic monostable element
860
-----------------------------------------------------------------------
861
library ieee;
862
    use ieee.std_logic_1164.all;
863
 
864
entity TTLmonostable is
865
generic(
866
    pwidth        : time    := 100 us;  -- Triggered pulse width
867
    mintrig       : time    :=  50 ns;  -- Minimum trigger width
868
    retriggerable : boolean := true
869
);
870
port(
871
    trig  : in  std_logic;
872
    reset : in  std_logic;
873
    Q     : out std_logic
874
);
875
end entity TTLmonostable;
876
 
877
architecture BEHAV of TTLmonostable is
878
  constant resolution : positive := pwidth / mintrig;
879
 
880
  signal clk : std_logic := '0';
881
  signal ctr : natural   :=  0;
882
begin
883
    osc: process is                     -- "Clock oscillator"
884
    begin
885
        if ctr /= 0 then
886
            wait for mintrig / 2;
887
            clk <= not clk;             -- <resolution> clocks = width
888
        else
889
            wait on ctr;
890
        end if;
891
    end process;
892
 
893
    tim: process(all) is                -- The timer proper
894
    begin
895
        if reset = '1' then
896
            ctr <= 0;
897
        elsif rising_edge(trig) and (ctr = 0 or retriggerable) then
898
            ctr <= 1;                   -- Start (or restart) a cycle
899
        elsif rising_edge(clk) and ctr > 0 then
900
            if ctr = resolution then
901
                ctr <= 0;               -- Cycle completed
902
            else
903
                ctr <= ctr + 1;         -- Advance count
904
            end if;
905
        end if;
906
    end process;
907
 
908
    Q <= '0' when ctr = 0 else '1';     -- '1' while time runs
909
 
910
end architecture BEHAV;
911
 
912
-----------------------------------------------------------------------
913
-- Elementary TTLflipflop
914
-- A basic JK TTLflipflop with resets. All active high
915
--
916
-- NB This package models gate delay variation by setting outputs to
917
--    'X' during the uncertain period. If such an output is used as a
918
--    clock, the active edge will transition from 'X' to the active
919
--    level. This will NOT trigger the rising/falling_edge() functions,
920
--    so this model uses the (CLK'event and CLK='1') paradigm.
921
-----------------------------------------------------------------------
922
library ieee;
923
    use ieee.std_logic_1164.all;
924
 
925
entity TTLflipflop is
926
generic(
927
    tPLHCP  : time    := 20 ns;     -- Clock rising
928
    tPHLCP  : time    := 30 ns;     -- Clock falling
929
    tPLHSC  : time    := 20 ns;     -- S/C rising
930
    tPHLSC  : time    := 30 ns;     -- S/C falling
931
    tSETUP  : time    :=  0 ns;     -- Setup time before clock (0 = no test)
932
    Safeclk : boolean := false      -- Enforce stable inputs over inactive clock edge
933
);
934
port(
935
    J, K, C, S, R : in  std_logic;
936
    Q, QB         : out std_logic
937
);
938
end entity TTLflipflop;
939
 
940
architecture BEHAV of TTLflipflop is
941
    signal qi : std_logic := 'X';
942
begin
943
    VV: process(J, K) is            -- Verify data is stable before active clock edge
944
    begin
945
        if J'event or K'event then                  -- Either is unstable
946
            if Safeclk and ((R or S) = '0') then    -- Test requested, & not defeated by reset/set
947
                assert C = '1' report "Data unstable" severity error;
948
            end if;
949
        end if;
950
    end process;
951
 
952
    FF: process(C, S, R) is         -- The flipflop proper
953
        variable ip : std_logic_vector(1 downto 0);
954
        variable qt : std_logic;
955
        variable dl : time;
956
    begin
957
        if    R = '1' then
958
            if qi /= '0' then               -- Only apply delays if state is changed
959
                qi <= 'X', '0' after tPHLSC;
960
            end if;
961
        elsif S = '1' then
962
            if qi /= '1' then
963
                qi <= 'X', '1' after tPLHSC;
964
            end if;
965
        elsif C'event and C = '1' then      -- Don't use "rising_edge": unsafe with 'X' values
966
            if tSETUP > 0 ns then
967
                assert J'stable(tSETUP) and K'stable(tSETUP)
968
                    report "Setup time violation"
969
                    severity warning;
970
            end if;
971
            ip := J & K;
972
            case ip is
973
                when "00"   =>
974
                    qt := qi;           -- Hold
975
                    dl := 0 ns;
976
                when "01"   =>
977
                    qt := '0';          -- Reset
978
                    dl := tPHLCP;
979
                when "10"   =>
980
                    qt := '1';          -- Set
981
                    dl := tPLHCP;
982
                when "11"   =>
983
                    if    qi = '0' then -- Toggle
984
                        qt := '1';
985
                        dl := tPLHCP;
986
                    elsif qi = '1' then
987
                        qt := '0';
988
                        dl := tPHLCP;
989
                    end if;
990
                when others =>
991
                    qt := 'X';          -- Illegal
992
                    dl := tPLHCP;
993
            end case;
994
            if qt /= qi then            -- Only apply delays if state is changed
995
                qi <= 'X', qt after dl;
996
            end if;
997
        end if;
998
    end process;
999
 
1000
    Q  <= qi;
1001
    QB <= not qi;
1002
end architecture BEHAV;
1003
 
1004
---------------------------------------------------------------
1005
-- 1-bit & 3-bit counter with adjustable modulus
1006
--         See 7490/92/93 & similar parts
1007
-- NB Don't use "falling_edge" for clocks: the drivers model delays,
1008
--    & set 'X' during the delay period. So a clock goes '1' - 'X' - '0'
1009
--    This must read as a valid edge.
1010
-----------------------------------------------------------------------
1011
library ieee;
1012
    use ieee.std_logic_1164.all;
1013
    use ieee.numeric_std.all;
1014
    use work.TTLPrivate.all;
1015
 
1016
entity TTLcount4 is
1017
generic(
1018
    tPLH0   : time     := 16 ns;
1019
    tPHL0   : time     := 18 ns;
1020
    tPLH1   : time     := 16 ns;
1021
    tPHL1   : time     := 21 ns;
1022
    tPLH2   : time     := 32 ns;
1023
    tPHL2   : time     := 35 ns;
1024
    tPLH3   : time     := 32 ns;
1025
    tPHL3   : time     := 35 ns;
1026
    modulus : positive := 10        -- Legal values are 10,12,16
1027
);
1028
port(
1029
    ld          : in  std_logic;
1030
    d           : in  std_logic_vector(3 downto 0);
1031
    clka, clkb  : in  std_logic;    -- Falling-edge clock
1032
    rst, set    : in  std_logic;    -- Active-low reset / set
1033
    val         : out std_logic_vector(3 downto 0)
1034
);
1035
end entity TTLcount4;
1036
 
1037
architecture BEHAV of TTLcount4 is
1038
    type tval is array(0 to 7) of natural;      -- Next counter values
1039
    -- Current count value: 0 1 2 3 4 5 6 7
1040
    constant D5 : tval :=  (1,2,3,4,0,1,2,3);   -- For the 3 moduli
1041
    constant D6 : tval :=  (1,2,4,0,5,6,0,0);   -- A "bi-ternary" count
1042
    constant D8 : tval :=  (1,2,3,4,5,6,7,0);
1043
 
1044
    signal q   : natural := 100;  -- Use 100 as "undefined"
1045
    signal q0  : std_logic;
1046
    signal q31 : std_logic_vector(3 downto 1);
1047
 
1048
begin
1049
    process(ld, clka, rst, set) is
1050
    begin
1051
        if    rst = '0' then
1052
            q0 <= '0';
1053
        elsif ld  = '0' then
1054
            q0 <= d(0);
1055
        elsif set = '0' then
1056
            q0 <= '1';
1057
        elsif clka'event and clka = '0' then
1058
            q0 <= not q0;
1059
        end if;
1060
    end process;
1061
 
1062
    process(ld, clkb, rst, set) is
1063
    begin
1064
        if    rst = '0' then
1065
            q <= 0;
1066
        elsif ld  = '0' then
1067
            q <= to_integer(unsigned(d(3 downto 1)));
1068
        elsif set = '0' then
1069
            case modulus is
1070
                when 10     => q <= 4;
1071
                when 16     => q <= 7;
1072
                when others => assert false report "Illegal modulus" severity failure;
1073
            end case;
1074
        elsif clkb'event and clkb = '0' and q < 8 then
1075
            case modulus is
1076
                when 10     => q <= D5(q);
1077
                when 12     => q <= D6(q);
1078
                when 16     => q <= D8(q);
1079
                when others => assert false report "Illegal modulus" severity failure;
1080
            end case;
1081
        end if;
1082
    end process;
1083
 
1084
    process(all) is
1085
    begin
1086
        if q < 8 then
1087
            q31 <= std_logic_vector(to_unsigned(q, q31'length));
1088
        else
1089
            q31 <= (others => 'X');
1090
        end if;
1091
--        val <= q31 & q0;
1092
    end process;
1093
 
1094
 
1095
    D0: TTLdelay
1096
    generic map(
1097
        tPLH => tPLH0,
1098
        tPHL => tPHL0
1099
    )
1100
    port map(
1101
        A => q0,
1102
        B => val(0)
1103
    );
1104
 
1105
    D1: TTLdelay
1106
    generic map(
1107
        tPLH => tPLH1,
1108
        tPHL => tPHL1
1109
    )
1110
    port map(
1111
        A => q31(1),
1112
        B => val(1)
1113
    );
1114
 
1115
    D2: TTLdelay
1116
    generic map(
1117
        tPLH => tPLH2,
1118
        tPHL => tPHL2
1119
    )
1120
    port map(
1121
        A => q31(2),
1122
        B => val(2)
1123
    );
1124
 
1125
    D3: TTLdelay
1126
    generic map(
1127
        tPLH => tPLH3,
1128
        tPHL => tPHL3
1129
    )
1130
    port map(
1131
        A => q31(3),
1132
        B => val(3)
1133
    );
1134
end architecture BEHAV;
1135
 
1136
-----------------------------------------------------------------------
1137
-- 4-bit synchronous counter with adjustable modulus
1138
-- See 74160..3 & similar parts
1139
-----------------------------------------------------------------------
1140
library ieee;
1141
    use ieee.std_logic_1164.all;
1142
    use ieee.numeric_std.all;
1143
    use work.TTLPrivate.all;
1144
 
1145
entity TTLsynccount is
1146
generic(
1147
    asyncreset : boolean := false;
1148
    modulus    : natural := 10;     -- 10, 16 are legal
1149
    tPLHT      : time    := 25 ns;
1150
    tPHLT      : time    := 23 ns;
1151
    tPLHQ      : time    := 24 ns;
1152
    tPHLQ      : time    := 27 ns
1153
);
1154
port(
1155
    PE, CP, CEP, CET, RST : in  std_logic;
1156
    TC                    : out std_logic;
1157
    P                     : in  std_logic_vector(3 downto 0);
1158
    Q                     : out std_logic_vector(3 downto 0)
1159
);
1160
end entity TTLsynccount;
1161
 
1162
architecture BEHAV of TTLsynccount is
1163
    signal Z   : std_logic_vector(3 downto 0);
1164
    signal TCI : std_logic;
1165
begin
1166
    process(RST, CP, CET) is
1167
        variable N : unsigned(3 downto 0);
1168
    begin
1169
        if asyncreset and (RST = '0') then
1170
            N := (others => '0');
1171
        elsif CP'event and CP = '1' then
1172
            if RST = '0' then
1173
                N := (others => '0');
1174
            elsif PE = '0' then
1175
                N := unsigned(P);
1176
            elsif (CEP and CET) = '1' then
1177
                if modulus = 16 then        -- Simple binary count
1178
                    N := N + 1;
1179
                else                        -- Decade count, cover illegal cases
1180
                    case N is
1181
                        when "1001"          => N := "0000";
1182
                        when "1011" | "1101" => N := "0100";
1183
                        when "1111"          => N := "1000";
1184
                        when others          => N := N + 1;
1185
                    end case;
1186
                end if;
1187
            end if;
1188
        end if;
1189
        Z <= std_logic_vector(N);           -- Export results
1190
        if TTL_to_integer(N) = modulus-1 then
1191
            TCI <= CET;
1192
        else
1193
            TCI <= '0';
1194
        end if;
1195
    end process;
1196
 
1197
    OQ: TTLdelays
1198
    generic map(
1199
        tPLH => tPLHQ,
1200
        tPHL => tPHLQ
1201
    )
1202
    port map(
1203
        A => Z,
1204
        B => Q
1205
    );
1206
 
1207
    OT: TTLdelay
1208
    generic map(
1209
        tPLH => tPLHT,
1210
        tPHL => tPHLT
1211
    )
1212
    port map(
1213
        A => TCI,
1214
        B => TC
1215
    );
1216
end architecture BEHAV;
1217
 
1218
-----------------------------------------------------------------------
1219
-- Synchronous bidirectional binary/decade bidirectional counter
1220
-----------------------------------------------------------------------
1221
library ieee;
1222
    use ieee.std_logic_1164.all;
1223
    use ieee.std_logic_misc.all;
1224
    use ieee.numeric_std.all;
1225
 
1226
    use work.LSTTL.all;
1227
    use work.TTLPrivate.all;
1228
 
1229
entity TTLbiCount is
1230
generic(
1231
    decade  : boolean := true;
1232
    tPLHQ   : time    := 20 ns;
1233
    tPHLQ   : time    := 20 ns;
1234
    tPLHT   : time    := 30 ns;
1235
    tPHLT   : time    := 30 ns;
1236
    tSU     : time    := 15 ns;
1237
    tSUPE   : time    := 20 ns
1238
);
1239
port(
1240
    PE, CP, CEP, CET, U_D : in std_logic;
1241
    P                     : in  std_logic_vector(3 downto 0);
1242
    Q                     : out std_logic_vector(3 downto 0);
1243
    TC                    : out std_logic
1244
);
1245
end entity TTLbiCount;
1246
 
1247
architecture BEHAV of TTLbiCount is
1248
    signal R       : unsigned(3 downto 0);
1249
    signal CEN     : std_logic;
1250
    signal X, Y, Z : std_logic;
1251
    signal W       : std_logic_vector(3 downto 0);
1252
 
1253
begin
1254
    X <= R(0) and R(3) and not CET when decade else and_reduce(std_logic_vector(R)) and not CET;
1255
    Y <= nor_reduce(std_logic_vector(R)) and not CET;
1256
    Z <= not X when U_D = '1' else not Y;
1257
    W <= std_logic_vector(R);
1258
 
1259
    process(CP) is
1260
        variable SW : std_logic_vector(3 downto 0);
1261
    begin
1262
        if CP'event and CP = '1' then       -- Everything is synchronous
1263
            assert PE'stable(tSUPE) report "PE setup violation"  severity failure;
1264
            assert CEP'stable(tSU)  report "CEP setup violation" severity failure;
1265
            assert CET'stable(tSU)  report "CET setup violation" severity failure;
1266
            SW := (PE, CEP, CET, U_D);
1267
            case SW is
1268
                when "0000" | "0001" | "0010" | "0011" |
1269
                     "0100" | "0101" | "0110" | "0111"=>              -- Load
1270
                    assert P'stable(tSU) report "P setup violation" severity failure;
1271
                    R <= unsigned(P);
1272
                when "1001" =>              -- Count up
1273
                    if decade then
1274
                        case R is
1275
                            when "1001" => R <= "0000";
1276
                            when "1011" => R <= "0100";
1277
                            when "1101" => R <= "0100";
1278
                            when others => R <= R + 1;
1279
                        end case;
1280
                    else
1281
                        R <= R + 1;
1282
                    end if;
1283
                when "1000" =>              -- Count down
1284
                    if decade then
1285
                        case R is
1286
                            when "0000" => R <= "1001";
1287
                            when "1010" => R <= "0001";
1288
                            when "1100" => R <= "0011";
1289
                            when "1110" => R <= "0101";
1290
                            when others => R <= R - 1;
1291
                        end case;
1292
                    else
1293
                        R <= R - 1;
1294
                    end if;
1295
                when others =>              -- No change
1296
                    null;
1297
            end case;
1298
        end if;
1299
    end process;
1300
 
1301
    OQ: TTLdelays
1302
    generic map(
1303
        tPLH => tPLHQ,
1304
        tPHL => tPHLQ
1305
    )
1306
    port map(
1307
        A => W,
1308
        B => Q
1309
    );
1310
 
1311
    OT: TTLdelay
1312
    generic map(
1313
        tPLH => tPLHT,
1314
        tPHL => tPHLT
1315
    )
1316
    port map(
1317
        A => Z,
1318
        B => TC
1319
    );
1320
end architecture BEHAV;
1321
 
1322
-----------------------------------------------------------------------
1323
-- Generic RAM block with 3-wire asynchronous control
1324
-- NB Control inputs are active low (as in physical chips)
1325
-----------------------------------------------------------------------
1326
library ieee;
1327
    use ieee.std_logic_1164.all;
1328
    use ieee.std_logic_misc.all;
1329
    use ieee.numeric_std.all;
1330
 
1331
    use work.LSTTL.all;
1332
    use work.TTLPrivate.all;
1333
 
1334
entity TTLramblock is
1335
generic(
1336
    fname : String    := "";        -- Name of initialisation file (if any)
1337
    Omode : TTLmemop  := OpenColl;  -- Output mode
1338
    INVT  : std_logic := '0';       -- '1' will invert outputs
1339
    tPLC  : time      := 10 ns;
1340
    tPLA  : time      := 37 ns;
1341
    tSUD  : time      := 25 ns;
1342
    tSUA  : time      := 10 ns
1343
);
1344
port(
1345
    RA    : in    std_logic_vector;
1346
    WA    : in    std_logic_vector;
1347
    D     : in    std_logic_vector;
1348
    O     : out   std_logic_vector;
1349
    CE    : in    std_logic;
1350
    RE    : in    std_logic;
1351
    WE    : in    std_logic
1352
);
1353
end entity TTLramblock;
1354
 
1355
architecture BEHAV of TTLramblock is
1356
    subtype  T_word  is std_logic_vector(O'range);
1357
    constant C_size  :  positive := 2**RA'length;
1358
 
1359
    signal   RP, WP     : natural;
1360
    signal   CI, RI, WI : std_logic;
1361
 
1362
begin
1363
    assert RA'left = WA'left and RA'right = WA'right report "Address range mismatch" severity failure;
1364
    assert  D'left =  O'left and  D'right =  O'right report "Data range mismatch"    severity failure;
1365
 
1366
    VR: process(all) is
1367
    begin
1368
        if WA'event or D'event then
1369
            assert WE = '1' report "Address or data changed during write" severity failure;
1370
        end if;
1371
        if WE'event and WE = '0' then
1372
            assert WA'stable(tSUA) report "Address setup violation" severity failure;
1373
            assert D'stable(tSUD)  report "Data setup violation" severity failure;
1374
        end if;
1375
    end process;
1376
 
1377
    RP <= to_integer(unsigned(RA)) after tPLA;
1378
    WP <= to_integer(unsigned(WA)) after tPLA;
1379
    CI <= CE after tPLC;
1380
    RI <= RE after tPLC;
1381
    WI <= WE after tPLC;
1382
 
1383
    RM: process(all) is
1384
        variable QQ : std_logic;
1385
        variable MA : TTLmemptr := null;
1386
    begin
1387
        if MA = null then               -- Create the memory array, once only
1388
            MA := new TTLmemory(C_size-1 downto 0, O'range);
1389
            TTL_mem_init(fname, MA);    -- Initialise from file, if given
1390
        end if;
1391
 
1392
        for i in O'range loop           -- Can't use "others" with unconstrained array
1393
            O(i) <= 'Z';                -- Deselected, or not reading
1394
        end loop;
1395
 
1396
        if CI = '0' then
1397
            if WI = '0' then
1398
                for i in O'range loop
1399
                    MA.all(WP,i) := D(i);
1400
                end loop;
1401
            end if;
1402
 
1403
            if RI = '0' then
1404
                for i in O'range loop
1405
                    QQ := MA.all(RP,i) xor INVT;
1406
                    case Omode is
1407
                        when Totem    => O(i) <= QQ;
1408
                        when OpenColl => O(i) <= TTL_OC(QQ);
1409
                        when TriState => O(i) <= QQ;
1410
                        when others => null;
1411
                    end case;
1412
                end loop;
1413
 
1414
            end if;
1415
        end if;
1416
    end process;
1417
end architecture BEHAV;
1418
 
1419
-----------------------------------------------------------------------
1420
-- Generic addressable latch
1421
-----------------------------------------------------------------------
1422
library ieee;
1423
    use ieee.std_logic_1164.all;
1424
    use ieee.std_logic_misc.all;
1425
    use ieee.numeric_std.all;
1426
 
1427
    use work.LSTTL.all;
1428
    use work.TTLPrivate.all;
1429
 
1430
entity TTLadLatch is
1431
generic(
1432
    ABits   : positive := 2;        -- No. of address bits (so no. of latches)
1433
    tPXDA   : time     := 30 ns;
1434
    tPHLC   : time     := 18 ns
1435
);
1436
port(
1437
    D   : in  std_logic;
1438
    En  : in  std_logic;
1439
    Cn  : in  std_logic;
1440
    A   : in  unsigned(ABits-1 downto 0);
1441
    Z   : out std_logic_vector(2**ABits-1 downto 0)
1442
);
1443
end entity TTLadLatch;
1444
 
1445
architecture BEHAV of TTLadLatch is
1446
--    signal latch : std_logic_vector(2**ABits-1 downto 0);
1447
    signal addr  : natural;
1448
begin
1449
--    Z    <= latch;                  -- Export the latch
1450
--    addr <= to_integer(A);
1451
 
1452
    process(all)
1453
    begin
1454
        if falling_edge(Cn) then
1455
            Z <= (others => '0') after tPHLC;
1456
        elsif Cn = '1' then
1457
            if En = '0' then
1458
                Z(to_integer(A)) <= D after tPXDA;
1459
            end if;
1460
        end if;
1461
    end process;
1462
end architecture BEHAV;
1463
 
1464
-----------------------------------------------------------------------
1465
-- Simple blocks used by testbenches
1466
-----------------------------------------------------------------------
1467
library ieee;
1468
    use ieee.std_logic_1164.all;
1469
    use ieee.std_logic_misc.all;
1470
    use ieee.numeric_std.all;
1471
 
1472
    use work.LSTTL.all;
1473
    use work.TTLPrivate.all;
1474
 
1475
entity TTL_FF is
1476
port(
1477
    q   : out std_logic;
1478
    d   : in  std_logic;
1479
    clk : in  std_logic;
1480
    cl  : in  std_logic
1481
);
1482
end entity TTL_FF;
1483
 
1484
architecture BEHAV of TTL_FF is
1485
begin
1486
    process(clk, cl) is
1487
    begin
1488
        if cl = '0' then
1489
            q <= '0';
1490
        elsif rising_edge(clk) then
1491
            q <= d;
1492
        end if;
1493
    end process;
1494
end architecture BEHAV;
1495
 

powered by: WebSVN 2.1.0

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