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

Subversion Repositories tms1000

[/] [tms1000/] [trunk/] [rtl/] [tms1000.v] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 nand_gates
// This file is part of TMS1000 CPU
2
// 
3
// tms1000.v -  Hadrware description of the TMS1000 processor
4
//
5
// Written By -  Nand Gates (2021)
6
//
7
// This program is free software; you can redistribute it and/or modify it
8
// under the terms of the GNU General Public License as published by the
9
// Free Software Foundation; either version 2, or (at your option) any
10
// later version.
11
//
12
// This program is distributed in the hope that it will be useful,
13
// but WITHOUT ANY WARRANTY; without even the implied warranty of
14
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
// GNU General Public License for more details.
16
//
17
// In other words, you are welcome to use, share and improve this program.
18
// You are forbidden to forbid anyone else to use, share and improve
19
// what you give them.   Help stamp out software-hoarding!
20
 
21
module tms1000(/*AUTOARG*/
22
   // Outputs
23
   r, q,
24
   // Inputs
25
   clk, reset_n, k
26
   );
27
   input clk, reset_n;
28
   output [10:0] r;
29
   input [3:0]   k;
30
   output [7:0]  q;
31
 
32
   reg [7:0]  q;
33
   reg [10:0] r, r_nx;
34
   reg [3:0]   pa, pa_nx; // Page address register
35
   reg [3:0]   pb, pb_nx; // Page buffer register
36
   //reg [5:0]   pc, pc_nx; // Program counter
37
   reg [5:0]   sr, sr_nx; // Subroutine return register
38
   reg         cl, cl_nx; //  Call latch
39
   reg [1:0]   xx, xx_nx; //  
40
   reg [3:0]   y , y_nx ; // pointer/storage register 
41
   reg         s , s_nx ; // Logic status
42
   reg         sl, sl_nx; // Conditional branch status
43
   reg [3:0]   a , a_nx ; // Accumulator
44
   reg [3:0]   k_reg;
45
 
46
   reg [7:0]   out_pla [0:31]; // simulation of output PLA
47
   //microinstructions
48
   reg ckp  ;
49
   reg ytp  ;
50
   reg mtp  ;
51
   reg atn  ;
52
   reg natn ;
53
   reg mtn  ;
54
   reg ftn  ;
55
   reg ckn  ;
56
   reg cin  ;
57
   reg ne   ;
58
   reg c8   ;
59
   reg sto  ;
60
   reg ckm  ;
61
   reg auta ;
62
   reg auty ;
63
   reg stsl ;
64
 
65
   reg [3:0] n_mux; // Multiplexer downto adder
66
   reg [3:0] p_mux; // Multiplexer downto adder
67
 
68
   reg       br    ;
69
   reg       call  ;
70
   reg       clo   ;
71
   reg       comx  ;
72
   reg       ldp   ;
73
   reg       ldx   ;
74
   reg       sbit  ;
75
   reg       rbit  ;
76
   reg       retn  ;
77
   reg       rstr  ;
78
   reg       setr  ;
79
   reg       tdo   ;
80
   reg       alec  ;
81
   reg       alem  ;
82
   reg       amaac ;
83
   reg       a6aac ;
84
   reg       a8aac ;
85
   reg       a10aac;
86
   reg       cla   ;
87
   reg       cpaiz ;
88
   reg       dan   ;
89
   reg       dman  ;
90
   reg       dyn   ;
91
   reg       ia    ;
92
   reg       imac  ;
93
   reg       iyc   ;
94
   reg       knez  ;
95
   reg       mnez  ;
96
   reg       saman ;
97
   reg       tam   ;
98
   reg       tamiy ;
99
   reg       tamza ;
100
   reg       tay   ;
101
   reg       tbit1 ;
102
   reg       tcy   ;
103
   reg       tcmiy ;
104
   reg       tka   ;
105
   reg       tma   ;
106
   reg       tmy   ;
107
   reg       tya   ;
108
   reg       xma   ;
109
   reg       ynea  ;
110
   reg       ynec  ;
111
   //T state generator
112
   reg [2:0] count;
113
   wire      t1 = count[0];
114
   wire      t2 = count[1];
115
   wire      t3 = count[2];
116
   //wire      t4 = count[3];
117
 
118
   wire [3:0] ram_do;
119
   wire [5:0] pc;
120
 
121
   reg  w2pc  ;
122
   reg  sr2pc ;
123
   reg  ld_sr ;
124
   reg  ld_pa ;
125
   reg  ld_pb ;
126
   reg  cl_set;
127
   reg  cl_reset;
128
   reg  set_s;
129
   reg [4:0] o, o_nx;
130
 
131
   wire      status;
132
   wire [3:0] alu_out;
133
   wire [7:0] i_bus;
134
   reg [3:0]  cki_bus;
135
   reg [3:0]  ram_din;
136
   wire       ram_wr;
137
 
138
   always @(posedge clk or negedge reset_n)
139
     if (!reset_n)
140
       count <= 0;
141
     else
142
       count <= {count[1:0],~|count[1:0]};
143
/* -----\/----- EXCLUDED -----\/-----
144
RETN
145
   pa = pb;
146
   if (cl == 1)
147
      pc = sr;
148
      cl = 0;
149
   else if (cl = 0)
150
      pc = pc + 1;
151
 
152
BR
153
  if (s == 1)
154
     pc = w;
155
     if (cl==0)
156
       pa = pb;
157
  else if (s == 0)
158
     pc = pc+1;
159
     s = 1;
160
 
161
CALL
162
    if (s == 1) & (cl == 0)
163
       sr = pc + 1;
164
       pc = w;
165
       pb = pa;
166
       pa = pb;
167
       cl = 1;
168
     else if (s == 1) & (cl == 1)
169
       pc = w;
170
       pb = pa;
171
     else if (s == 0)
172
       pc = pc + 1;
173
       s = 1;
174
 -----/\----- EXCLUDED -----/\----- */
175
 
176
   always @(/*AS*/br or call or cl or ldx or retn or s) begin
177
      //PC select
178
      w2pc = (br | call) & s;
179
      sr2pc = retn & cl;
180
      //sr select
181
      ld_sr = call & s & ~cl;
182
      //pa select
183
      ld_pa = retn | (((br & ~cl)|call) & s);
184
      //pb select
185
      ld_pb =  (call & s);
186
      //cl select
187
      cl_set   = call & s & ~cl;
188
      cl_reset = retn & cl;
189
      //s
190
      set_s = br | call | ldx | comx |
191
              tam | tamza | tka | tdo | clo |
192
              rstr | setr | ia | retn | ldp |
193
              tamiy | tma | tmy | tya | tay |
194
              xma | cla | sbit | rbit | ldx |
195
              tcy | tcmiy;
196
   end
197
 
198
   // Main registers
199
   always @(posedge clk or negedge reset_n) begin
200
       if (!reset_n) begin
201
          pa <= 4'b1111;//4'b1111;
202
          pb <= 4'b1111;//4'b1111;
203
          sr <= 6'b00_0000;
204
          r  <= 11'b00000000000;
205
          o  <= 5'b00000;
206
          cl <= 1'b0;
207
          s  <= 1'b1; // s=0 on power on
208
          sl <= 1'b0;
209
          a  <= 4'b0000;
210
          y  <= 4'b0000;
211
          xx <= 2'b00;
212
          k_reg <= 4'b0000;
213
       end else begin // if (!reset_n)
214
          pa <= pa_nx;
215
          pb <= pb_nx;
216
          sr <= sr_nx;
217
          r  <= r_nx;
218
          o  <= o_nx;
219
          a  <= a_nx;
220
          y  <= y_nx;
221
          xx <= xx_nx;
222
          sl <= sl_nx;
223
          cl <= cl_nx;
224
          s  <= s_nx;
225
          k_reg <= k;
226
       end
227
   end // always @ (posedge clk or negedge reset_n)
228
 
229
   //pa pb sr cl
230
   always @(/*AS*/c8 or cl or cl_reset or cl_set or ld_pa or ld_pb or ld_sr
231
            or ne or pa or pb or pc or s or set_s or sr or status or t3 or t3) begin
232
      pa_nx = pa;
233
      pb_nx = pb;
234
      sr_nx = sr;
235
      cl_nx = cl;
236
      s_nx = s;
237
 
238
      if (ld_sr & t3)
239
        sr_nx = {pc[4:0], !((pc != 31) && (|pc[5:4]) && ((pc[3:0] == 15) || (pc[5:4] != 3)))};
240
 
241
      if (ld_pa & t3)
242
        pa_nx = pb;
243
 
244
      if (ld_pb & t3)
245
        pb_nx = pa;
246
      else if (ldp & t3)
247
        pb_nx = {i_bus[0],i_bus[1],i_bus[2],i_bus[3]};
248
 
249
      if (cl_set & t3)
250
        cl_nx = 1'b1;
251
      else if (cl_reset & t3)
252
        cl_nx = 1'b0;
253
 
254
      if (t3 & (c8 | ne))
255
        s_nx = status;
256
      else if (set_s & t3)
257
        s_nx = 1'b1;
258
   end // always @ (...
259
 
260
   always @(/*AS*/a or alu_out or auta or t3) begin
261
       a_nx = a;
262
       if (auta & t3)
263
         a_nx = alu_out;
264
   end
265
 
266
   always @(/*AS*/alu_out or auty or t3 or y) begin
267
      y_nx = y;
268
      if (auty & t3)
269
        y_nx = alu_out;
270
   end
271
 
272
   always @ (/*AS*/status or sl or stsl) begin
273
      sl_nx = sl;
274
      if (stsl)
275
        sl_nx = status;
276
   end
277
 
278
   always @(/*AS*/comx or i_bus or ldx or t3 or xx) begin
279
      xx_nx = xx;
280
      if (ldx & t3)
281
        xx_nx = {i_bus[0],i_bus[1]};
282
      else if (comx & t3)
283
        xx_nx = ~xx;
284
   end
285
 
286
   always @(/*AS*/a or clo or o or sl or tdo) begin
287
       o_nx = o;
288
       if (clo)
289
         o_nx = 0;
290
       else if (tdo)
291
         o_nx = {sl, a};
292
   end
293
 
294
   // Instruction decoder CPLD and logic
295
   always @(/*AS*/i_bus) begin
296
      br     = 1'b0;
297
      call   = 1'b0;
298
      clo    = 1'b0;
299
      comx   = 1'b0;
300
      ldp    = 1'b0;
301
      ldx    = 1'b0;
302
      sbit   = 1'b0;
303
      rbit   = 1'b0;
304
      retn   = 1'b0;
305
      rstr   = 1'b0;
306
      setr   = 1'b0;
307
      tdo    = 1'b0;
308
      alec   = 1'b0;
309
      alem   = 1'b0;
310
      amaac  = 1'b0;
311
      a6aac  = 1'b0;
312
      a8aac  = 1'b0;
313
      a10aac = 1'b0;
314
      cla    = 1'b0;
315
      cpaiz  = 1'b0;
316
      dan    = 1'b0;
317
      dman   = 1'b0;
318
      dyn    = 1'b0;
319
      ia     = 1'b0;
320
      imac   = 1'b0;
321
      iyc    = 1'b0;
322
      knez   = 1'b0;
323
      mnez   = 1'b0;
324
      saman  = 1'b0;
325
      tam    = 1'b0;
326
      tamiy  = 1'b0;
327
      tamza  = 1'b0;
328
      tay    = 1'b0;
329
      tbit1  = 1'b0;
330
      tcy    = 1'b0;
331
      tcmiy  = 1'b0;
332
      tka    = 1'b0;
333
      tma    = 1'b0;
334
      tmy    = 1'b0;
335
      tya    = 1'b0;
336
      xma    = 1'b0;
337
      ynea   = 1'b0;
338
      ynec   = 1'b0;
339
      casex(i_bus[7:0])
340
        //Fixed instructions
341
        8'b10xx_xxxx : br   = 1'b1;
342
        8'b11xx_xxxx : call = 1'b1;
343
        8'b0000_1011 : clo  = 1'b1;
344
        8'b0000_0000 : comx = 1'b1;
345
        8'b0001_xxxx : ldp  = 1'b1;
346
        8'b0011_11xx : ldx  = 1'b1;
347
        8'b0011_00xx : sbit = 1'b1;
348
        8'b0011_01xx : rbit = 1'b1;
349
        8'b0000_1111 : retn = 1'b1;
350
        8'b0000_1100 : rstr = 1'b1;
351
        8'b0000_1101 : setr = 1'b1;
352
        8'b0000_1010 : tdo  = 1'b1;
353
        // Programable instructions
354
        8'b0111_xxxx : alec   = 1'b1;
355
        8'b0010_1001 : alem   = 1'b1;
356
        8'b0010_0101 : amaac  = 1'b1;
357
        8'b0000_0110 : a6aac  = 1'b1;
358
        8'b0000_0001 : a8aac  = 1'b1;
359
        8'b0000_0101 : a10aac = 1'b1;
360
        8'b0010_1111 : cla    = 1'b1;
361
        8'b0010_1101 : cpaiz  = 1'b1;
362
        8'b0000_0111 : dan    = 1'b1;
363
        8'b0010_1010 : dman   = 1'b1;
364
        8'b0010_1100 : dyn    = 1'b1;
365
        8'b0000_1110 : ia     = 1'b1;
366
        8'b0010_1000 : imac   = 1'b1;
367
        8'b0010_1011 : iyc    = 1'b1;
368
        8'b0000_1001 : knez   = 1'b1;
369
        8'b0010_0110 : mnez   = 1'b1;
370
        8'b0010_0111 : saman  = 1'b1;
371
        8'b0000_0011 : tam    = 1'b1;
372
        8'b0010_0000 : tamiy  = 1'b1;
373
        8'b0000_0100 : tamza  = 1'b1;
374
        8'b0010_0100 : tay    = 1'b1;
375
        8'b0011_10xx : tbit1  = 1'b1;
376
        8'b0100_xxxx : tcy    = 1'b1;
377
        8'b0110_xxxx : tcmiy  = 1'b1;
378
        8'b0000_1000 : tka    = 1'b1;
379
        8'b0010_0001 : tma    = 1'b1;
380
        8'b0010_0010 : tmy    = 1'b1;
381
        8'b0010_0011 : tya    = 1'b1;
382
        8'b0010_1110 : xma    = 1'b1;
383
        8'b0000_0010 : ynea   = 1'b1;
384
        8'b0101_xxxx : ynec   = 1'b1;
385
        default : ;//nop
386
      endcase // case(i_bus[7:0])
387
   end // always @ (...
388
 
389
   // Instruction decoder PLA OR logic
390
   always @(/*AS*/a10aac or a6aac or a8aac or alec or alem or amaac or br
391
            or call or cla or clo or comx or cpaiz or dan or dman or dyn or ia
392
            or imac or iyc or knez or ldp or ldx or mnez or rbit or retn
393
            or rstr or saman or sbit or setr or tam or tamiy or tamza or tay
394
            or tbit1 or tcmiy or tcy or tdo or tka or tma or tmy or tya or xma
395
            or ynea or ynec) begin
396
      //active in t1      
397
      ckp  = 1'b0;
398
      ytp  = 1'b0;
399
      mtp  = 1'b0;
400
      atn  = 1'b0;
401
      natn = 1'b0;
402
      mtn  = 1'b0;
403
      ftn  = 1'b0;
404
      ckn  = 1'b0;
405
      cin  = 1'b0;
406
      ne   = 1'b0;
407
      c8   = 1'b0;
408
      // acrive during t2
409
      sto = 1'b0;
410
      ckm = 1'b0;
411
      //active during t3 
412
      auta = 1'b0;
413
      auty = 1'b0;
414
      stsl = 1'b0;
415
      case(1'b1)
416
        // Fixded instructions
417
        br     : begin
418
        end
419
        call   : begin
420
        end
421
        clo    : begin
422
        end
423
        comx   : begin
424
        end
425
        ldp    : begin
426
        end
427
        ldx    : begin
428
        end
429
        sbit   : begin
430
        end
431
        rbit   : begin
432
        end
433
        retn   : begin
434
        end
435
        rstr   : begin
436
        end
437
        setr   : begin
438
        end
439
        tdo    : begin
440
        end
441
        //Programable instructions
442
        alec   : begin
443
           ckp  = 1'b1;
444
           natn = 1'b1;
445
           cin  = 1'b1;
446
           c8   = 1'b1;
447
        end
448
        alem   : begin
449
           mtp  = 1'b1;
450
           natn = 1'b1;
451
           cin  = 1'b1;
452
           c8   = 1'b1;
453
        end
454
        amaac  : begin
455
           mtp  = 1'b1;
456
           atn  = 1'b1;
457
           c8   = 1'b1;
458
           auta = 1'b1;
459
        end
460
        a6aac  : begin
461
           ckp  = 1'b1;
462
           atn  = 1'b1;
463
           c8   = 1'b1;
464
           auta = 1'b1;
465
        end
466
        a8aac  : begin
467
           ckp  = 1'b1;
468
           atn  = 1'b1;
469
           c8   = 1'b1;
470
           auta = 1'b1;
471
        end
472
        a10aac : begin
473
           ckp  = 1'b1;
474
           atn  = 1'b1;
475
           c8   = 1'b1;
476
           auta = 1'b1;
477
        end
478
        cla    : begin
479
           auta = 1'b1;
480
        end
481
        cpaiz  : begin
482
           natn = 1'b1;
483
           cin  = 1'b1;
484
           c8   = 1'b1;
485
           auta = 1'b1;
486
        end
487
        dan    : begin
488
           ckp  = 1'b1;
489
           atn  = 1'b1;
490
           cin  = 1'b1;
491
           c8   = 1'b1;
492
           auta = 1'b1;
493
        end
494
        dman   : begin
495
           mtp  = 1'b1;
496
           ftn  = 1'b1;
497
           c8   = 1'b1;
498
           auta = 1'b1;
499
        end
500
        dyn    : begin
501
           ytp  = 1'b1;
502
           ftn  = 1'b1;
503
           c8   = 1'b1;
504
           auty = 1'b1;
505
        end
506
        ia     : begin
507
           atn  = 1'b1;
508
           cin  = 1'b1;
509
           auta = 1'b1;
510
        end
511
        imac   : begin
512
           mtp  = 1'b1;
513
           cin  = 1'b1;
514
           c8   = 1'b1;
515
           auta = 1'b1;
516
        end
517
        iyc    : begin
518
           ytp  = 1'b1;
519
           cin  = 1'b1;
520
           c8   = 1'b1;
521
           auty = 1'b1;
522
        end
523
        knez   : begin
524
           ckp  = 1'b1;
525
           ne   = 1'b1;
526
        end
527
        mnez   : begin
528
           mtp  = 1'b1;
529
           ne   = 1'b1;
530
        end
531
        saman  : begin
532
           mtp  = 1'b1;
533
           natn = 1'b1;
534
           cin  = 1'b1;
535
           c8   = 1'b1;
536
           auta = 1'b1;
537
        end
538
        tam    : begin
539
           sto  = 1'b1;
540
        end
541
        tamiy  : begin
542
           ytp  = 1'b1;
543
           cin  = 1'b1;
544
           sto  = 1'b1;
545
           auty = 1'b1;
546
        end
547
        tamza  : begin
548
           sto  = 1'b1;
549
           auta = 1'b1;
550
        end
551
        tay    : begin
552
           atn  = 1'b1;
553
           auty = 1'b1;
554
        end
555
        tbit1  : begin
556
           ckp  = 1'b1;
557
           mtp  = 1'b1;
558
           ckn  = 1'b1;
559
           ne   = 1'b1;
560
        end
561
        tcy    : begin
562
           ckp  = 1'b1;
563
           auty = 1'b1;
564
        end
565
        tcmiy  : begin
566
           ytp  = 1'b1;
567
           cin  = 1'b1;
568
           ckm  = 1'b1;
569
           auty = 1'b1;
570
        end
571
        tka    : begin
572
           ckp  = 1'b1;
573
           auta = 1'b1;
574
        end
575
        tma    : begin
576
           mtp  = 1'b1;
577
           auta = 1'b1;
578
        end
579
        tmy    : begin
580
           mtp  = 1'b1;
581
           auty = 1'b1;
582
        end
583
        tya    : begin
584
           ytp  = 1'b1;
585
           auta = 1'b1;
586
        end
587
        xma    : begin
588
           mtp  = 1'b1;
589
           sto  = 1'b1;
590
           auta = 1'b1;
591
        end
592
        ynea   : begin
593
           ytp  = 1'b1;
594
           atn  = 1'b1;
595
           ne   = 1'b1;
596
           stsl = 1'b1;
597
        end
598
        ynec   : begin
599
           ytp  = 1'b1;
600
           ckn  = 1'b1;
601
           ne   = 1'b1;
602
        end
603
      endcase // case(1'b1)
604
   end
605
   //R-logic
606
   always @(/*AS*/r or rstr or setr or y) begin
607
       r_nx = r;
608
       if (setr | rstr)
609
         case (y)
610
 
611
              1 : r_nx[ 1] = setr & (~rstr);
612
              2 : r_nx[ 2] = setr & (~rstr);
613
              3 : r_nx[ 3] = setr & (~rstr);
614
              4 : r_nx[ 4] = setr & (~rstr);
615
              5 : r_nx[ 5] = setr & (~rstr);
616
              6 : r_nx[ 6] = setr & (~rstr);
617
              7 : r_nx[ 7] = setr & (~rstr);
618
              8 : r_nx[ 8] = setr & (~rstr);
619
              9 : r_nx[ 9] = setr & (~rstr);
620
             10 : r_nx[10] = setr & (~rstr);
621
         endcase
622
   end // always @ (...
623
 
624
   //Q output logic
625
   always @(/*AS*/o) begin
626
    case(o[3:0]) // abcd efg-
627
 
628
       1 : q = {7'b0110_000,o[4]};   // seven-seg 1                f   b
629
       2 : q = {7'b1101_101,o[4]};   // seven-seg 2                  g
630
       3 : q = {7'b1111_001,o[4]};   // seven-seg 3                e   c
631
       4 : q = {7'b0110_011,o[4]};   // seven-seg 4                  d
632
       5 : q = {7'b1011_011,o[4]};   // seven-seg 5
633
       6 : q = {7'b1011_111,o[4]};   // seven-seg 6
634
       7 : q = {7'b1110_000,o[4]};   // seven-seg 7
635
       8 : q = {7'b1111_111,o[4]};   // seven-seg 8
636
       9 : q = {7'b1111_011,o[4]};   // seven-seg 9
637
      10 : q = {7'b1110_111,o[4]};   // seven-seg A
638
      11 : q = {7'b1111_100,o[4]};   // seven-seg B
639
      12 : q = {7'b0111_001,o[4]};   // seven-seg C
640
      13 : q = {7'b1011_110,o[4]};   // seven-seg D
641
      14 : q = {7'b1111_001,o[4]};   // seven-seg E
642
      15 : q = {7'b0000_000,o[4]};   // seven-seg Blank
643
    endcase
644
   end // always @ (...
645
 
646
   //cki_bus logic
647
   always @ (/*AS*/i_bus or k_reg) begin
648
      if (i_bus[7:3] == 5'b00000|| i_bus[7:6] == 2'b01)
649
        cki_bus = {i_bus[0],i_bus[1],i_bus[2],i_bus[3]};
650
      else if (i_bus[7:3] == 5'b00001)
651
        cki_bus = k_reg;
652
      else if (i_bus[7:4] == 4'h3)
653
        case ({i_bus[0],i_bus[1]})
654
 
655
          1 : cki_bus = 4'b1101;
656
          2 : cki_bus = 4'b1011;
657
          3 : cki_bus = 4'b0111;
658
        endcase // case ({i_bus[0],i_bus[1]})
659
      else //if (i_bus[7:4] == 4'h2)
660
        cki_bus = 0;
661
   end
662
 
663
   // N-mux
664
   always @ (/*AS*/a or atn or cki_bus or ckn or ftn or mtn or natn or ram_do) begin
665
       n_mux = (a & {4{atn}}) | (~a & {4{natn}}) |
666
               (ram_do & {4{mtn}}) | ({4{ftn}}) |
667
               (cki_bus & {4{ckn}});
668
   end
669
 
670
   //P-mux
671
   always @ (/*AS*/cki_bus or ckp or mtp or ram_do or y or ytp) begin
672
       p_mux = (cki_bus & {4{ckp}}) | (y & {4{ytp}}) |
673
               (ram_do & {4{mtp}});
674
   end
675
 
676
   assign ram_wr = (sto | ckm | sbit | rbit) & t3;
677
   //write mux
678
   always @(/*AS*/a or cki_bus or ckm or ram_do or rbit or sbit or sto)begin
679
      ram_din = cki_bus & {4{ckm}} | (a & {4{sto}}) |
680
                {4{sbit}} & (~cki_bus | ram_do) |
681
                {4{rbit}} & (cki_bus & ram_do);
682
   end
683
   alu alu(
684
        // Outputs
685
        .sum (alu_out),
686
        .status (status),
687
        // Inputs
688
        .a (n_mux),
689
        .b (p_mux),
690
        .cin (cin),
691
        .cy_out (c8),
692
        .comp_out (ne)
693
        );
694
 
695
   rom rom (
696
            // Outputs
697
            .data (i_bus),
698
            // Inputs
699
            .address ({pa,pc})
700
            );
701
 
702
   ram ram (
703
            // Outputs
704
            .dout (ram_do),
705
            // Inputs
706
            .clk (clk),
707
            .reset_n (reset_n),
708
            .wr (ram_wr),
709
            .din (ram_din),
710
            .addr ({xx,y})
711
            );
712
   tms1000_pc tms1000_pc(
713
                         // Outputs
714
                         .pc  (pc),
715
                         // Inputs
716
                         .clk (clk),
717
                         .reset_n (reset_n),
718
                         .ld_pc ((w2pc | sr2pc) & t3),
719
                         .pc_en (t3),
720
                         .din   (({6{w2pc}} & i_bus[5:0]) | ({6{sr2pc}} & sr))
721
                         );
722
 
723
   // for debug
724
/* -----\/----- EXCLUDED -----\/-----
725
   //reg [100*8:1] instruction[0:2047];
726
   reg [100*8:1] instruction;
727
   reg [3:0]   imm;
728
   reg         imm_f;
729
   initial $readmemh("icalc.mem",instruction);
730
   always @(pa or pc) begin
731
       $write ($time,,"%x %0s\t",{pa,pc},instruction[{pa,pc}]);
732
   end
733
   always @(negedge t3) begin
734
       $display("x=%x y=%x a=%x m(%0d,%0d)=%x s=%b pa=%x pb=%x cl=%b", xx, y, a, xx, y, ram_do, s, pa, pb, cl);
735
   end
736
 
737
   always @(negedge clk) begin
738
       if (t1) begin
739
           case(1'b1)
740
               // Fixded instructions
741
               br     : begin instruction = "br    "; imm_f = 1; imm = i_bus[7:4];end
742
               call   : begin instruction = "call  "; imm_f = 1; imm = i_bus[7:4];end
743
               clo    : begin instruction = "clo   "; imm_f = 0; imm = 0;end
744
               comx   : begin instruction = "comx  "; imm_f = 0; imm = 0;end
745
               ldp    : begin instruction = "ldp   "; imm_f = 1; imm = {i_bus[0],i_bus[1],i_bus[2],i_bus[3]};end
746
               ldx    : begin instruction = "ldx   "; imm_f = 1; imm = {i_bus[0],i_bus[1]};end
747
               sbit   : begin instruction = "sbit  "; imm_f = 1; imm = {i_bus[0],i_bus[1]};end
748
               rbit   : begin instruction = "rbit  "; imm_f = 1; imm = {i_bus[0],i_bus[1]};end
749
               retn   : begin instruction = "retn  "; imm_f = 0; imm = 0;end
750
               rstr   : begin instruction = "rstr  "; imm_f = 0; imm = 0;end
751
               setr   : begin instruction = "setr  "; imm_f = 0; imm = 0;end
752
               tdo    : begin instruction = "tdo   "; imm_f = 0; imm = 0;end
753
               alec   : begin instruction = "alec  "; imm_f = 1; imm = {i_bus[0],i_bus[1],i_bus[2],i_bus[3]};end
754
               alem   : begin instruction = "alem  "; imm_f = 0; imm = 0;end
755
               amaac  : begin instruction = "amaac "; imm_f = 0; imm = 0;end
756
               a6aac  : begin instruction = "a6aac "; imm_f = 0; imm = 0;end
757
               a8aac  : begin instruction = "a8aac "; imm_f = 0; imm = 0;end
758
               a10aac : begin instruction = "a10aac"; imm_f = 0; imm = 0;end
759
               cla    : begin instruction = "cla   "; imm_f = 0; imm = 0;end
760
               cpaiz  : begin instruction = "cpaiz "; imm_f = 0; imm = 0;end
761
               dan    : begin instruction = "dan   "; imm_f = 0; imm = 0;end
762
               dman   : begin instruction = "dman  "; imm_f = 0; imm = 0;end
763
               dyn    : begin instruction = "dyn   "; imm_f = 0; imm = 0;end
764
               ia     : begin instruction = "ia    "; imm_f = 0; imm = 0;end
765
               imac   : begin instruction = "imac  "; imm_f = 0; imm = 0;end
766
               iyc    : begin instruction = "iyc   "; imm_f = 0; imm = 0;end
767
               knez   : begin instruction = "knez  "; imm_f = 0; imm = 0;end
768
               mnez   : begin instruction = "mnez  "; imm_f = 0; imm = 0;end
769
               saman  : begin instruction = "saman "; imm_f = 0; imm = 0;end
770
               tam    : begin instruction = "tam   "; imm_f = 0; imm = 0;end
771
               tamiy  : begin instruction = "tamiy "; imm_f = 0; imm = 0;end
772
               tamza  : begin instruction = "tamza "; imm_f = 0; imm = 0;end
773
               tay    : begin instruction = "tay   "; imm_f = 0; imm = 0;end
774
               tbit1  : begin instruction = "tbit1 "; imm_f = 1; imm = {i_bus[0],i_bus[1]};end
775
               tcy    : begin instruction = "tcy   "; imm_f = 1; imm = {i_bus[0],i_bus[1],i_bus[2],i_bus[3]};end
776
               tcmiy  : begin instruction = "tcmiy "; imm_f = 1; imm = {i_bus[0],i_bus[1],i_bus[2],i_bus[3]};end
777
               tka    : begin instruction = "tka   "; imm_f = 0; imm = 0;end
778
               tma    : begin instruction = "tma   "; imm_f = 0; imm = 0;end
779
               tmy    : begin instruction = "tmy   "; imm_f = 0; imm = 0;end
780
               tya    : begin instruction = "tya   "; imm_f = 0; imm = 0;end
781
               xma    : begin instruction = "xma   "; imm_f = 0; imm = 0;end
782
               ynea   : begin instruction = "ynea  "; imm_f = 0; imm = 0;end
783
               ynec   : begin instruction = "ynec  "; imm_f = 1; imm = {i_bus[0],i_bus[1],i_bus[2],i_bus[3]};end
784
           endcase // case(1'b1)
785
 
786
           if (imm_f)
787
             $display($time,,"%x %0s %d",{pa,pc},instruction, imm);
788
           else
789
             $display($time,,"%x %0s ",{pa,pc},instruction);
790
       end // if (t1)
791
   end // always @ (...
792
 -----/\----- EXCLUDED -----/\----- */
793
endmodule // tms1000
794
 
795
module alu (/*AUTOARG*/
796
   // Outputs
797
   sum, status,
798
   // Inputs
799
   a, b, cin, cy_out, comp_out
800
   );
801
   input [3:0] a;
802
   input [3:0] b;
803
   input       cin, cy_out, comp_out;
804
   output [3:0] sum;
805
   output       status;
806
   wire         cy;
807
   wire         ne = (a != b); //comparator
808
   assign       {cy, sum} = a + b + cin; // adder
809
   assign       status = (cy & cy_out) | (ne & comp_out);
810
endmodule // alu
811
 
812
module rom (/*AUTOARG*/
813
   // Outputs
814
   data,
815
   // Inputs
816
   address
817
   );
818
   input [9:0] address;
819
   output [7:0] data;
820
   reg [7:0]    memory [0:1023];
821
   initial $readmemh("icalc.mem", memory);
822
   assign       data = memory [address];
823
endmodule // rom
824
 
825
module ram (/*AUTOARG*/
826
   // Outputs
827
   dout,
828
   // Inputs
829
   clk, reset_n, wr, din, addr
830
   );
831
   input clk, reset_n;
832
   input wr;
833
   input [3:0] din;
834
   output [3:0] dout;
835
   input [5:0]  addr;
836
   reg [3:0]    ram_mem [0:63];
837
   assign       dout = ram_mem[addr];
838
   //For debug only Comment out if not required
839
/* -----\/----- EXCLUDED -----\/-----*/
840
   wire  [16*4-1:0]  Xreg_0 = {ram_mem[15], ram_mem[14], ram_mem[13], ram_mem[12], ram_mem[11], ram_mem[10], ram_mem[9], ram_mem[8], ram_mem[7], ram_mem[6], ram_mem[5], ram_mem[4], ram_mem[3], ram_mem[2], ram_mem[1], ram_mem[0]};
841
   wire  [16*4-1:0]  Xreg_1 = {ram_mem[31], ram_mem[30], ram_mem[29], ram_mem[28], ram_mem[27], ram_mem[26], ram_mem[25], ram_mem[24], ram_mem[23], ram_mem[22], ram_mem[21], ram_mem[20], ram_mem[19], ram_mem[18], ram_mem[17], ram_mem[16]};
842
   wire  [16*4-1:0]  Xreg_2 = {ram_mem[47], ram_mem[46], ram_mem[45], ram_mem[44], ram_mem[43], ram_mem[42], ram_mem[41], ram_mem[40], ram_mem[39], ram_mem[38], ram_mem[37], ram_mem[36], ram_mem[35], ram_mem[34], ram_mem[33], ram_mem[32]};
843
   wire  [16*4-1:0]  Xreg_3 = {ram_mem[63], ram_mem[62], ram_mem[61], ram_mem[60], ram_mem[59], ram_mem[58], ram_mem[57], ram_mem[56], ram_mem[55], ram_mem[54], ram_mem[53], ram_mem[52], ram_mem[51], ram_mem[50], ram_mem[49], ram_mem[48]};
844
/* -----/\----- EXCLUDED -----/\----- */
845
 
846
   always @(posedge clk or negedge reset_n) begin
847
       if (!reset_n ) begin
848
           begin : mem_init_loop
849
              integer i;
850
               for (i=0; i<64; i=i+1)
851
               ram_mem[i] <= i;
852
           end
853
       end else begin
854
           if (wr)
855
             ram_mem[addr] <= din;
856
       end
857
   end
858
endmodule // ram
859
 
860
 
861
module tms1000_pc (/*AUTOARG*/
862
   // Outputs
863
   pc,
864
   // Inputs
865
   clk, reset_n, ld_pc, pc_en, din
866
   );
867
   input clk, reset_n;
868
   input ld_pc, pc_en;
869
   input [5:0] din;
870
   output [5:0] pc;
871
   reg [5:0] pc;
872
   wire         a = ~&{~pc[5], pc[4:0]};
873
   wire         b = |pc[5:4];
874
   wire         c = ~&{(~&pc[3:0]),pc[5:4]};
875
   wire         sin = ~&{a, b, c};
876
   always @(posedge clk or negedge reset_n) begin
877
      if (!reset_n)
878
        pc <= 0;
879
      else
880
        if (ld_pc)
881
          pc <= din;
882
        else if (pc_en)
883
          pc <= {pc[4:0], sin};
884
   end
885
endmodule // tms1000_pc
886
 
887
 
888
 
889
 
890
 

powered by: WebSVN 2.1.0

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