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

Subversion Repositories tms1000

[/] [tms1000/] [trunk/] [rtl/] [tms1000.v] - Rev 5

Go to most recent revision | Compare with Previous | Blame | View Log

// This file is part of TMS1000 CPU
// 
// tms1000.v -  Hadrware description of the TMS1000 processor
//
// Written By -  Nand Gates (2021)
//
// This program is free software; you can redistribute it and/or modify it
// under the terms of the GNU General Public License as published by the
// Free Software Foundation; either version 2, or (at your option) any
// later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// In other words, you are welcome to use, share and improve this program.
// You are forbidden to forbid anyone else to use, share and improve
// what you give them.   Help stamp out software-hoarding!
 
module tms1000(/*AUTOARG*/
   // Outputs
   r, q, 
   // Inputs
   clk, reset_n, k
   );
   input clk, reset_n;
   output [10:0] r;
   input [3:0]   k;
   output [7:0]  q;
 
   reg [7:0]  q;
   reg [10:0] r, r_nx;
   reg [3:0]   pa, pa_nx; // Page address register
   reg [3:0]   pb, pb_nx; // Page buffer register
   //reg [5:0]   pc, pc_nx; // Program counter
   reg [5:0]   sr, sr_nx; // Subroutine return register
   reg         cl, cl_nx; //  Call latch
   reg [1:0]   xx, xx_nx; //  
   reg [3:0]   y , y_nx ; // pointer/storage register 
   reg         s , s_nx ; // Logic status
   reg         sl, sl_nx; // Conditional branch status
   reg [3:0]   a , a_nx ; // Accumulator
   reg [3:0]   k_reg;
 
   reg [7:0]   out_pla [0:31]; // simulation of output PLA
   //microinstructions
   reg ckp  ;
   reg ytp  ;
   reg mtp  ;
   reg atn  ;
   reg natn ;
   reg mtn  ;
   reg ftn  ;
   reg ckn  ;
   reg cin  ;
   reg ne   ;
   reg c8   ;
   reg sto  ;
   reg ckm  ;
   reg auta ;
   reg auty ;
   reg stsl ;
 
   reg [3:0] n_mux; // Multiplexer downto adder
   reg [3:0] p_mux; // Multiplexer downto adder
 
   reg       br    ;
   reg       call  ;
   reg       clo   ;
   reg       comx  ;
   reg       ldp   ;
   reg       ldx   ;
   reg       sbit  ;
   reg       rbit  ;
   reg       retn  ;
   reg       rstr  ;
   reg       setr  ;
   reg       tdo   ;
   reg       alec  ;
   reg       alem  ;
   reg       amaac ;
   reg       a6aac ;
   reg       a8aac ;
   reg       a10aac;
   reg       cla   ;
   reg       cpaiz ;
   reg       dan   ;
   reg       dman  ;
   reg       dyn   ;
   reg       ia    ;
   reg       imac  ;
   reg       iyc   ;
   reg       knez  ;
   reg       mnez  ;
   reg       saman ;
   reg       tam   ;
   reg       tamiy ;
   reg       tamza ;
   reg       tay   ;
   reg       tbit1 ;
   reg       tcy   ;
   reg       tcmiy ;
   reg       tka   ;
   reg       tma   ;
   reg       tmy   ;
   reg       tya   ;
   reg       xma   ;
   reg       ynea  ;
   reg       ynec  ;
   //T state generator
   reg [2:0] count;
   wire      t1 = count[0];
   wire      t2 = count[1];
   wire      t3 = count[2];
   //wire      t4 = count[3];
 
   wire [3:0] ram_do;
   wire [5:0] pc;
 
   reg  w2pc  ;
   reg  sr2pc ;
   reg  ld_sr ;
   reg  ld_pa ;
   reg  ld_pb ;
   reg  cl_set;
   reg  cl_reset;
   reg  set_s;
   reg [4:0] o, o_nx;
 
   wire      status;
   wire [3:0] alu_out;
   wire [7:0] i_bus;
   reg [3:0]  cki_bus;
   reg [3:0]  ram_din;
   wire       ram_wr;
 
   always @(posedge clk or negedge reset_n)
     if (!reset_n)
       count <= 0;
     else
       count <= {count[1:0],~|count[1:0]};
/* -----\/----- EXCLUDED -----\/-----
RETN
   pa = pb;
   if (cl == 1)
      pc = sr;
      cl = 0;
   else if (cl = 0) 
      pc = pc + 1;
 
BR
  if (s == 1)
     pc = w;
     if (cl==0)
       pa = pb;
  else if (s == 0)
     pc = pc+1;
     s = 1;
 
CALL
    if (s == 1) & (cl == 0)
       sr = pc + 1;
       pc = w;
       pb = pa;
       pa = pb;
       cl = 1;
     else if (s == 1) & (cl == 1)
       pc = w;
       pb = pa;
     else if (s == 0)
       pc = pc + 1;
       s = 1;
 -----/\----- EXCLUDED -----/\----- */
 
   always @(/*AS*/br or call or cl or ldx or retn or s) begin
      //PC select
      w2pc = (br | call) & s;
      sr2pc = retn & cl;
      //sr select
      ld_sr = call & s & ~cl;
      //pa select
      ld_pa = retn | (((br & ~cl)|call) & s);
      //pb select
      ld_pb =  (call & s);
      //cl select
      cl_set   = call & s & ~cl;
      cl_reset = retn & cl;
      //s
      set_s = br | call | ldx | comx |
              tam | tamza | tka | tdo | clo |
              rstr | setr | ia | retn | ldp |
              tamiy | tma | tmy | tya | tay |
              xma | cla | sbit | rbit | ldx |
              tcy | tcmiy;
   end
 
   // Main registers
   always @(posedge clk or negedge reset_n) begin
       if (!reset_n) begin
          pa <= 4'b1111;//4'b1111;
          pb <= 4'b1111;//4'b1111;
          sr <= 6'b00_0000;
          r  <= 11'b00000000000;
          o  <= 5'b00000;
          cl <= 1'b0;
          s  <= 1'b1; // s=0 on power on
          sl <= 1'b0; 
          a  <= 4'b0000;
          y  <= 4'b0000;
          xx <= 2'b00;
          k_reg <= 4'b0000;
       end else begin // if (!reset_n)
          pa <= pa_nx;
          pb <= pb_nx;
          sr <= sr_nx;
          r  <= r_nx;
          o  <= o_nx;
          a  <= a_nx;
          y  <= y_nx;
          xx <= xx_nx;
          sl <= sl_nx;
          cl <= cl_nx;
          s  <= s_nx;
          k_reg <= k;
       end
   end // always @ (posedge clk or negedge reset_n)
 
   //pa pb sr cl
   always @(/*AS*/c8 or cl or cl_reset or cl_set or ld_pa or ld_pb or ld_sr
            or ne or pa or pb or pc or s or set_s or sr or status or t3 or t3) begin
      pa_nx = pa;
      pb_nx = pb;
      sr_nx = sr;
      cl_nx = cl;
      s_nx = s;
 
      if (ld_sr & t3)
        sr_nx = {pc[4:0], !((pc != 31) && (|pc[5:4]) && ((pc[3:0] == 15) || (pc[5:4] != 3)))};
 
      if (ld_pa & t3)
        pa_nx = pb;
 
      if (ld_pb & t3)
        pb_nx = pa;
      else if (ldp & t3)
        pb_nx = {i_bus[0],i_bus[1],i_bus[2],i_bus[3]};
 
      if (cl_set & t3)
        cl_nx = 1'b1;
      else if (cl_reset & t3)
        cl_nx = 1'b0;
 
      if (t3 & (c8 | ne))
        s_nx = status;
      else if (set_s & t3)
        s_nx = 1'b1;
   end // always @ (...
 
   always @(/*AS*/a or alu_out or auta or t3) begin
       a_nx = a;
       if (auta & t3)
         a_nx = alu_out;
   end
 
   always @(/*AS*/alu_out or auty or t3 or y) begin
      y_nx = y;
      if (auty & t3)
        y_nx = alu_out;
   end
 
   always @ (/*AS*/status or sl or stsl) begin
      sl_nx = sl;
      if (stsl)
        sl_nx = status;
   end
 
   always @(/*AS*/comx or i_bus or ldx or t3 or xx) begin
      xx_nx = xx;
      if (ldx & t3)
        xx_nx = {i_bus[0],i_bus[1]};
      else if (comx & t3)
        xx_nx = ~xx;
   end
 
   always @(/*AS*/a or clo or o or sl or tdo) begin
       o_nx = o;
       if (clo)
         o_nx = 0;
       else if (tdo)
         o_nx = {sl, a};
   end
 
   // Instruction decoder CPLD and logic
   always @(/*AS*/i_bus) begin
      br     = 1'b0;
      call   = 1'b0;
      clo    = 1'b0;
      comx   = 1'b0;
      ldp    = 1'b0;
      ldx    = 1'b0;
      sbit   = 1'b0;
      rbit   = 1'b0;
      retn   = 1'b0;
      rstr   = 1'b0;
      setr   = 1'b0;
      tdo    = 1'b0;
      alec   = 1'b0;
      alem   = 1'b0;
      amaac  = 1'b0;
      a6aac  = 1'b0;
      a8aac  = 1'b0;
      a10aac = 1'b0;
      cla    = 1'b0;
      cpaiz  = 1'b0;
      dan    = 1'b0;
      dman   = 1'b0;
      dyn    = 1'b0;
      ia     = 1'b0;
      imac   = 1'b0;
      iyc    = 1'b0;
      knez   = 1'b0;
      mnez   = 1'b0;
      saman  = 1'b0;
      tam    = 1'b0;
      tamiy  = 1'b0;
      tamza  = 1'b0;
      tay    = 1'b0;
      tbit1  = 1'b0;
      tcy    = 1'b0;
      tcmiy  = 1'b0;
      tka    = 1'b0;
      tma    = 1'b0;
      tmy    = 1'b0;
      tya    = 1'b0;
      xma    = 1'b0;
      ynea   = 1'b0;
      ynec   = 1'b0;
      casex(i_bus[7:0])
        //Fixed instructions
        8'b10xx_xxxx : br   = 1'b1;
        8'b11xx_xxxx : call = 1'b1;
        8'b0000_1011 : clo  = 1'b1;
        8'b0000_0000 : comx = 1'b1;
        8'b0001_xxxx : ldp  = 1'b1;
        8'b0011_11xx : ldx  = 1'b1;
        8'b0011_00xx : sbit = 1'b1;
        8'b0011_01xx : rbit = 1'b1;
        8'b0000_1111 : retn = 1'b1;
        8'b0000_1100 : rstr = 1'b1;
        8'b0000_1101 : setr = 1'b1;
        8'b0000_1010 : tdo  = 1'b1;
        // Programable instructions
        8'b0111_xxxx : alec   = 1'b1;
        8'b0010_1001 : alem   = 1'b1;
        8'b0010_0101 : amaac  = 1'b1;
        8'b0000_0110 : a6aac  = 1'b1;
        8'b0000_0001 : a8aac  = 1'b1;
        8'b0000_0101 : a10aac = 1'b1;
        8'b0010_1111 : cla    = 1'b1;
        8'b0010_1101 : cpaiz  = 1'b1;
        8'b0000_0111 : dan    = 1'b1;
        8'b0010_1010 : dman   = 1'b1;
        8'b0010_1100 : dyn    = 1'b1;
        8'b0000_1110 : ia     = 1'b1;
        8'b0010_1000 : imac   = 1'b1;
        8'b0010_1011 : iyc    = 1'b1;
        8'b0000_1001 : knez   = 1'b1;
        8'b0010_0110 : mnez   = 1'b1;
        8'b0010_0111 : saman  = 1'b1;
        8'b0000_0011 : tam    = 1'b1;
        8'b0010_0000 : tamiy  = 1'b1;
        8'b0000_0100 : tamza  = 1'b1;
        8'b0010_0100 : tay    = 1'b1;
        8'b0011_10xx : tbit1  = 1'b1;
        8'b0100_xxxx : tcy    = 1'b1;
        8'b0110_xxxx : tcmiy  = 1'b1;
        8'b0000_1000 : tka    = 1'b1;
        8'b0010_0001 : tma    = 1'b1;
        8'b0010_0010 : tmy    = 1'b1;
        8'b0010_0011 : tya    = 1'b1;
        8'b0010_1110 : xma    = 1'b1;
        8'b0000_0010 : ynea   = 1'b1;
        8'b0101_xxxx : ynec   = 1'b1;
        default : ;//nop
      endcase // case(i_bus[7:0])
   end // always @ (...
 
   // Instruction decoder PLA OR logic
   always @(/*AS*/a10aac or a6aac or a8aac or alec or alem or amaac or br
            or call or cla or clo or comx or cpaiz or dan or dman or dyn or ia
            or imac or iyc or knez or ldp or ldx or mnez or rbit or retn
            or rstr or saman or sbit or setr or tam or tamiy or tamza or tay
            or tbit1 or tcmiy or tcy or tdo or tka or tma or tmy or tya or xma
            or ynea or ynec) begin
      //active in t1      
      ckp  = 1'b0;
      ytp  = 1'b0;
      mtp  = 1'b0;
      atn  = 1'b0;
      natn = 1'b0;
      mtn  = 1'b0;
      ftn  = 1'b0;
      ckn  = 1'b0;
      cin  = 1'b0;
      ne   = 1'b0;
      c8   = 1'b0;
      // acrive during t2
      sto = 1'b0;
      ckm = 1'b0;
      //active during t3 
      auta = 1'b0;
      auty = 1'b0;
      stsl = 1'b0;
      case(1'b1)
        // Fixded instructions
        br     : begin
        end
        call   : begin 
        end
        clo    : begin 
        end
        comx   : begin 
        end
        ldp    : begin 
        end
        ldx    : begin
        end
        sbit   : begin
        end
        rbit   : begin
        end
        retn   : begin
        end
        rstr   : begin
        end
        setr   : begin
        end
        tdo    : begin
        end
        //Programable instructions
        alec   : begin
           ckp  = 1'b1;
           natn = 1'b1;
           cin  = 1'b1;
           c8   = 1'b1;
        end
        alem   : begin
           mtp  = 1'b1;
           natn = 1'b1;
           cin  = 1'b1;
           c8   = 1'b1;
        end
        amaac  : begin
           mtp  = 1'b1;
           atn  = 1'b1;
           c8   = 1'b1;
           auta = 1'b1;
        end
        a6aac  : begin
           ckp  = 1'b1;
           atn  = 1'b1;
           c8   = 1'b1;
           auta = 1'b1;
        end
        a8aac  : begin
           ckp  = 1'b1;
           atn  = 1'b1;
           c8   = 1'b1;
           auta = 1'b1;
        end
        a10aac : begin
           ckp  = 1'b1;
           atn  = 1'b1;
           c8   = 1'b1;
           auta = 1'b1;
        end
        cla    : begin
           auta = 1'b1;
        end
        cpaiz  : begin
           natn = 1'b1;
           cin  = 1'b1;
           c8   = 1'b1;
           auta = 1'b1;
        end
        dan    : begin
           ckp  = 1'b1;
           atn  = 1'b1;
           cin  = 1'b1;
           c8   = 1'b1;
           auta = 1'b1;
        end
        dman   : begin
           mtp  = 1'b1;
           ftn  = 1'b1;
           c8   = 1'b1;
           auta = 1'b1;
        end
        dyn    : begin
           ytp  = 1'b1;
           ftn  = 1'b1;
           c8   = 1'b1;
           auty = 1'b1;
        end
        ia     : begin
           atn  = 1'b1;
           cin  = 1'b1;
           auta = 1'b1;
        end
        imac   : begin
           mtp  = 1'b1;
           cin  = 1'b1;
           c8   = 1'b1;
           auta = 1'b1;
        end
        iyc    : begin
           ytp  = 1'b1;
           cin  = 1'b1;
           c8   = 1'b1;
           auty = 1'b1;
        end
        knez   : begin
           ckp  = 1'b1;
           ne   = 1'b1;
        end
        mnez   : begin
           mtp  = 1'b1;
           ne   = 1'b1;
        end
        saman  : begin
           mtp  = 1'b1;
           natn = 1'b1;
           cin  = 1'b1;
           c8   = 1'b1;
           auta = 1'b1;
        end
        tam    : begin
           sto  = 1'b1;
        end
        tamiy  : begin
           ytp  = 1'b1;
           cin  = 1'b1;
           sto  = 1'b1;
           auty = 1'b1;
        end
        tamza  : begin
           sto  = 1'b1;
           auta = 1'b1;
        end
        tay    : begin
           atn  = 1'b1;
           auty = 1'b1;
        end
        tbit1  : begin
           ckp  = 1'b1;
           mtp  = 1'b1;
           ckn  = 1'b1;
           ne   = 1'b1;
        end
        tcy    : begin
           ckp  = 1'b1;
           auty = 1'b1;
        end
        tcmiy  : begin
           ytp  = 1'b1;
           cin  = 1'b1;
           ckm  = 1'b1;
           auty = 1'b1;
        end
        tka    : begin
           ckp  = 1'b1;
           auta = 1'b1;
        end
        tma    : begin
           mtp  = 1'b1;
           auta = 1'b1;
        end
        tmy    : begin
           mtp  = 1'b1;
           auty = 1'b1;
        end
        tya    : begin
           ytp  = 1'b1;
           auta = 1'b1;
        end
        xma    : begin
           mtp  = 1'b1;
           sto  = 1'b1;
           auta = 1'b1;
        end
        ynea   : begin
           ytp  = 1'b1;
           atn  = 1'b1;
           ne   = 1'b1;
           stsl = 1'b1;
        end
        ynec   : begin
           ytp  = 1'b1;
           ckn  = 1'b1;
           ne   = 1'b1;
        end
      endcase // case(1'b1)
   end
   //R-logic
   always @(/*AS*/r or rstr or setr or y) begin
       r_nx = r;
       if (setr | rstr)
         case (y)
              0 : r_nx[ 0] = setr & (~rstr);
              1 : r_nx[ 1] = setr & (~rstr);
              2 : r_nx[ 2] = setr & (~rstr);
              3 : r_nx[ 3] = setr & (~rstr);
              4 : r_nx[ 4] = setr & (~rstr);
              5 : r_nx[ 5] = setr & (~rstr);
              6 : r_nx[ 6] = setr & (~rstr);
              7 : r_nx[ 7] = setr & (~rstr);
              8 : r_nx[ 8] = setr & (~rstr);
              9 : r_nx[ 9] = setr & (~rstr);
             10 : r_nx[10] = setr & (~rstr);
         endcase
   end // always @ (...
 
   //Q output logic
   always @(/*AS*/o) begin
    case(o[3:0]) // abcd efg-
       0 : q = {7'b1111_110,o[4]};   // seven-seg 0                  a
       1 : q = {7'b0110_000,o[4]};   // seven-seg 1                f   b
       2 : q = {7'b1101_101,o[4]};   // seven-seg 2                  g
       3 : q = {7'b1111_001,o[4]};   // seven-seg 3                e   c
       4 : q = {7'b0110_011,o[4]};   // seven-seg 4                  d
       5 : q = {7'b1011_011,o[4]};   // seven-seg 5
       6 : q = {7'b1011_111,o[4]};   // seven-seg 6
       7 : q = {7'b1110_000,o[4]};   // seven-seg 7
       8 : q = {7'b1111_111,o[4]};   // seven-seg 8
       9 : q = {7'b1111_011,o[4]};   // seven-seg 9
      10 : q = {7'b1110_111,o[4]};   // seven-seg A
      11 : q = {7'b1111_100,o[4]};   // seven-seg B
      12 : q = {7'b0111_001,o[4]};   // seven-seg C
      13 : q = {7'b1011_110,o[4]};   // seven-seg D
      14 : q = {7'b1111_001,o[4]};   // seven-seg E
      15 : q = {7'b0000_000,o[4]};   // seven-seg Blank
    endcase
   end // always @ (...
 
   //cki_bus logic
   always @ (/*AS*/i_bus or k_reg) begin
      if (i_bus[7:3] == 5'b00000|| i_bus[7:6] == 2'b01)
        cki_bus = {i_bus[0],i_bus[1],i_bus[2],i_bus[3]};
      else if (i_bus[7:3] == 5'b00001)
        cki_bus = k_reg;
      else if (i_bus[7:4] == 4'h3)
        case ({i_bus[0],i_bus[1]})
          0 : cki_bus = 4'b1110;
          1 : cki_bus = 4'b1101;
          2 : cki_bus = 4'b1011;
          3 : cki_bus = 4'b0111;
        endcase // case ({i_bus[0],i_bus[1]})
      else //if (i_bus[7:4] == 4'h2)
        cki_bus = 0;
   end
 
   // N-mux
   always @ (/*AS*/a or atn or cki_bus or ckn or ftn or mtn or natn or ram_do) begin
       n_mux = (a & {4{atn}}) | (~a & {4{natn}}) |
               (ram_do & {4{mtn}}) | ({4{ftn}}) |
               (cki_bus & {4{ckn}});
   end
 
   //P-mux
   always @ (/*AS*/cki_bus or ckp or mtp or ram_do or y or ytp) begin
       p_mux = (cki_bus & {4{ckp}}) | (y & {4{ytp}}) |
               (ram_do & {4{mtp}});
   end
 
   assign ram_wr = (sto | ckm | sbit | rbit) & t3;
   //write mux
   always @(/*AS*/a or cki_bus or ckm or ram_do or rbit or sbit or sto)begin
      ram_din = cki_bus & {4{ckm}} | (a & {4{sto}}) |
                {4{sbit}} & (~cki_bus | ram_do) | 
                {4{rbit}} & (cki_bus & ram_do);
   end
   alu alu(
        // Outputs
        .sum (alu_out), 
        .status (status),
        // Inputs
        .a (n_mux), 
        .b (p_mux), 
        .cin (cin), 
        .cy_out (c8), 
        .comp_out (ne)
        );
 
   rom rom (
            // Outputs
            .data (i_bus),
            // Inputs
            .address ({pa,pc})
            );
 
   ram ram (
            // Outputs
            .dout (ram_do),
            // Inputs
            .clk (clk), 
            .reset_n (reset_n), 
            .wr (ram_wr), 
            .din (ram_din), 
            .addr ({xx,y})
            );
   tms1000_pc tms1000_pc(
                         // Outputs
                         .pc  (pc),
                         // Inputs
                         .clk (clk), 
                         .reset_n (reset_n), 
                         .ld_pc ((w2pc | sr2pc) & t3), 
                         .pc_en (t3), 
                         .din   (({6{w2pc}} & i_bus[5:0]) | ({6{sr2pc}} & sr))
                         );
 
   // for debug
/* -----\/----- EXCLUDED -----\/-----
   //reg [100*8:1] instruction[0:2047];
   reg [100*8:1] instruction;
   reg [3:0]   imm;
   reg         imm_f;
   initial $readmemh("icalc.mem",instruction);
   always @(pa or pc) begin
       $write ($time,,"%x %0s\t",{pa,pc},instruction[{pa,pc}]);
   end
   always @(negedge t3) begin
       $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);
   end
 
   always @(negedge clk) begin
       if (t1) begin
           case(1'b1)
               // Fixded instructions
               br     : begin instruction = "br    "; imm_f = 1; imm = i_bus[7:4];end 
               call   : begin instruction = "call  "; imm_f = 1; imm = i_bus[7:4];end
               clo    : begin instruction = "clo   "; imm_f = 0; imm = 0;end
               comx   : begin instruction = "comx  "; imm_f = 0; imm = 0;end
               ldp    : begin instruction = "ldp   "; imm_f = 1; imm = {i_bus[0],i_bus[1],i_bus[2],i_bus[3]};end
               ldx    : begin instruction = "ldx   "; imm_f = 1; imm = {i_bus[0],i_bus[1]};end
               sbit   : begin instruction = "sbit  "; imm_f = 1; imm = {i_bus[0],i_bus[1]};end
               rbit   : begin instruction = "rbit  "; imm_f = 1; imm = {i_bus[0],i_bus[1]};end
               retn   : begin instruction = "retn  "; imm_f = 0; imm = 0;end
               rstr   : begin instruction = "rstr  "; imm_f = 0; imm = 0;end
               setr   : begin instruction = "setr  "; imm_f = 0; imm = 0;end
               tdo    : begin instruction = "tdo   "; imm_f = 0; imm = 0;end
               alec   : begin instruction = "alec  "; imm_f = 1; imm = {i_bus[0],i_bus[1],i_bus[2],i_bus[3]};end
               alem   : begin instruction = "alem  "; imm_f = 0; imm = 0;end
               amaac  : begin instruction = "amaac "; imm_f = 0; imm = 0;end
               a6aac  : begin instruction = "a6aac "; imm_f = 0; imm = 0;end
               a8aac  : begin instruction = "a8aac "; imm_f = 0; imm = 0;end
               a10aac : begin instruction = "a10aac"; imm_f = 0; imm = 0;end
               cla    : begin instruction = "cla   "; imm_f = 0; imm = 0;end
               cpaiz  : begin instruction = "cpaiz "; imm_f = 0; imm = 0;end
               dan    : begin instruction = "dan   "; imm_f = 0; imm = 0;end
               dman   : begin instruction = "dman  "; imm_f = 0; imm = 0;end
               dyn    : begin instruction = "dyn   "; imm_f = 0; imm = 0;end
               ia     : begin instruction = "ia    "; imm_f = 0; imm = 0;end
               imac   : begin instruction = "imac  "; imm_f = 0; imm = 0;end
               iyc    : begin instruction = "iyc   "; imm_f = 0; imm = 0;end
               knez   : begin instruction = "knez  "; imm_f = 0; imm = 0;end
               mnez   : begin instruction = "mnez  "; imm_f = 0; imm = 0;end
               saman  : begin instruction = "saman "; imm_f = 0; imm = 0;end
               tam    : begin instruction = "tam   "; imm_f = 0; imm = 0;end
               tamiy  : begin instruction = "tamiy "; imm_f = 0; imm = 0;end
               tamza  : begin instruction = "tamza "; imm_f = 0; imm = 0;end
               tay    : begin instruction = "tay   "; imm_f = 0; imm = 0;end
               tbit1  : begin instruction = "tbit1 "; imm_f = 1; imm = {i_bus[0],i_bus[1]};end
               tcy    : begin instruction = "tcy   "; imm_f = 1; imm = {i_bus[0],i_bus[1],i_bus[2],i_bus[3]};end
               tcmiy  : begin instruction = "tcmiy "; imm_f = 1; imm = {i_bus[0],i_bus[1],i_bus[2],i_bus[3]};end
               tka    : begin instruction = "tka   "; imm_f = 0; imm = 0;end
               tma    : begin instruction = "tma   "; imm_f = 0; imm = 0;end
               tmy    : begin instruction = "tmy   "; imm_f = 0; imm = 0;end
               tya    : begin instruction = "tya   "; imm_f = 0; imm = 0;end
               xma    : begin instruction = "xma   "; imm_f = 0; imm = 0;end
               ynea   : begin instruction = "ynea  "; imm_f = 0; imm = 0;end
               ynec   : begin instruction = "ynec  "; imm_f = 1; imm = {i_bus[0],i_bus[1],i_bus[2],i_bus[3]};end
           endcase // case(1'b1)
 
           if (imm_f)
             $display($time,,"%x %0s %d",{pa,pc},instruction, imm);
           else
             $display($time,,"%x %0s ",{pa,pc},instruction);
       end // if (t1)
   end // always @ (...
 -----/\----- EXCLUDED -----/\----- */
endmodule // tms1000
 
module alu (/*AUTOARG*/
   // Outputs
   sum, status, 
   // Inputs
   a, b, cin, cy_out, comp_out
   );
   input [3:0] a;
   input [3:0] b;
   input       cin, cy_out, comp_out;
   output [3:0] sum;
   output       status;
   wire         cy;
   wire         ne = (a != b); //comparator
   assign       {cy, sum} = a + b + cin; // adder
   assign       status = (cy & cy_out) | (ne & comp_out);
endmodule // alu
 
module rom (/*AUTOARG*/
   // Outputs
   data, 
   // Inputs
   address
   );
   input [9:0] address;
   output [7:0] data;
   reg [7:0]    memory [0:1023];
   initial $readmemh("icalc.mem", memory);
   assign       data = memory [address];
endmodule // rom
 
module ram (/*AUTOARG*/
   // Outputs
   dout, 
   // Inputs
   clk, reset_n, wr, din, addr
   );
   input clk, reset_n;
   input wr;
   input [3:0] din;
   output [3:0] dout;
   input [5:0]  addr;
   reg [3:0]    ram_mem [0:63];
   assign       dout = ram_mem[addr];
   //For debug only Comment out if not required
/* -----\/----- EXCLUDED -----\/-----*/
   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]};
   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]};
   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]};
   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]};
/* -----/\----- EXCLUDED -----/\----- */
 
   always @(posedge clk or negedge reset_n) begin 
       if (!reset_n ) begin 
           begin : mem_init_loop
              integer i;
               for (i=0; i<64; i=i+1)
               ram_mem[i] <= i;
           end
       end else begin
           if (wr)
             ram_mem[addr] <= din;
       end
   end
endmodule // ram
 
 
module tms1000_pc (/*AUTOARG*/
   // Outputs
   pc, 
   // Inputs
   clk, reset_n, ld_pc, pc_en, din
   );
   input clk, reset_n;
   input ld_pc, pc_en;
   input [5:0] din;
   output [5:0] pc;
   reg [5:0] pc;
   wire         a = ~&{~pc[5], pc[4:0]};
   wire         b = |pc[5:4];
   wire         c = ~&{(~&pc[3:0]),pc[5:4]};
   wire         sin = ~&{a, b, c};
   always @(posedge clk or negedge reset_n) begin
      if (!reset_n)
        pc <= 0;
      else
        if (ld_pc)
          pc <= din;
        else if (pc_en)
          pc <= {pc[4:0], sin};
   end   
endmodule // tms1000_pc
 
 
 
 
 
 

Go to most recent revision | Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

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