File:  [gforth] / gforth / arch / misc / misc.v
Revision 1.5: download - view: text, annotated - select for diffs
Mon Dec 31 19:02:25 2007 UTC (14 years, 11 months ago) by anton
Branches: MAIN
CVS tags: v0-7-0, HEAD
updated copyright year after changing license notice

    1: // Copyright (C) 1998,2000,2003,2004,2007 Free Software Foundation, Inc.
    2: 
    3: // This file is part of Gforth.
    4: 
    5: // Gforth is free software; you can redistribute it and/or
    6: // modify it under the terms of the GNU General Public License
    7: // as published by the Free Software Foundation, either version 3
    8: // of the License, or (at your option) any later version.
    9: 
   10: // This program is distributed in the hope that it will be useful,
   11: // but WITHOUT ANY WARRANTY; without even the implied warranty of
   12: // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   13: // GNU General Public License for more details.
   14: 
   15: // You should have received a copy of the GNU General Public License
   16: // along with this program; if not, see http://www.gnu.org/licenses/.
   17: 
   18: /* Minimal Instruction Set Computer
   19:  \ sources                 destinations
   20: 
   21: $0 Constant PC		$0 Constant JMP
   22: $1 Constant PC+2	$1 Constant JS
   23: $2 Constant PC+4	$2 Constant JZ
   24: $3 Constant PC+6	
   25: 			$4 Constant JC
   26: 
   27:  
   28:  
   29: $8 Constant ACCU	$8 Constant ACCU
   30: $9 Constant SF		$9 Constant SUB
   31: $A Constant ZF		$A Constant SUBR
   32: 			$B Constant ADD
   33: $C Constant CF		$C Constant XOR
   34: 			$D Constant OR
   35: 			$E Constant AND
   36: 			$F Constant SHR
   37: */
   38: 
   39: `define L [0:l-1]
   40:  
   41: module misc(clock, data, addr, csel, rw);
   42:    parameter l=16, d=10;
   43:    input clock;
   44:    inout `L data;
   45:    output `L addr;
   46:    output csel;
   47:    output rw;
   48: 
   49:    reg `L inst, dtr, accu, pc;
   50:    reg [0:1] state;
   51:    reg carry, zero;
   52:    wire `L regs;
   53:    wire alusel, cout, zout, pccond;
   54:    wire `L alu1, alu2, aluout;
   55:    wire [0:2] aluop;
   56:    
   57:    initial
   58:     begin
   59:        state = 0;
   60:        pc = 'h10;
   61:        inst = 0;
   62:        dtr = 0;
   63:        accu = 0;
   64:        carry = 0;
   65:        zero = 1;
   66:     end
   67:    
   68:    assign
   69:     rw=~&state,
   70:     csel=~state[1] | |inst[0:l-5],
   71:     addr = state[1] ? inst : pc,
   72:     data = rw ? {l{1'bz}} : dtr;
   73: 
   74:    assign
   75:     alusel= inst[l-4],
   76:     pccond = ~|(inst[l-3:l-1] & ~{ carry, zero, accu[0] }),
   77:     regs = inst[l-4] ? (|inst[l-3:l-1] ? { {(l-1){1'b0}}, pccond } : accu)
   78:                      : aluout;
   79:    
   80:    always @(posedge clock)
   81:     begin
   82:        casez(state)
   83: 	 2'bz0 : begin
   84: 	    inst = data;
   85: 	    pc = aluout;
   86: 	 end
   87: 	 2'b01 : begin
   88: 	    dtr = csel ? data : regs;
   89: //	    $fwrite(2, "PC: %x : %x -( %x )->", pc-1'b1, inst, dtr);
   90: 	 end
   91: 	 2'b11 :
   92: 	  begin
   93: 	     if(~|inst[0:l-5])
   94: 	      if(alusel) { carry, zero, accu } = { cout, zout, aluout };
   95: 	      else
   96: 	       if (pccond) pc=dtr;
   97: //	     $fwrite(2, " %x ACCU: %x\n", inst, accu);
   98: 	  end
   99:        endcase /* 2 */
  100:        state = state + 1;
  101:     end
  102: 
  103:    assign
  104:     alu1 = &state ? accu : pc,
  105:     alu2 = ~state[1] ? {{l{1'b0}}, 1'b1 } :
  106:                        state[0] ? dtr : { inst[1:l-1], 1'b0 } - 1,
  107:     aluop = &state ? inst[l-3:l-1] : 3'b011;
  108:    
  109:    alu #(l,d) alu0(aluop, alu1, alu2, carry, aluout, cout, zout);
  110:    
  111: endmodule /* misc */
  112: 
  113: module alu(op, in1, in2, cin, out, cout, zout);
  114:    parameter l=16, d=10;
  115:    input [0:2] op;
  116:    input `L in1, in2;
  117:    input cin;
  118:    output `L out;
  119:    output cout, zout;
  120:    
  121:    reg `L out;
  122:    reg cout;
  123: 
  124:    initial
  125:     cout = 0;
  126:    
  127:    always @(in1 or in2 or op)
  128:     #d case(op)
  129:       3'b000 : { cout, out } = { cin, in2 };
  130:       3'b001 : { cout, out } = in1 - in2;
  131:       3'b010 : { cout, out } = in2 - in1;
  132:       3'b011 : { cout, out } = in1 + in2;
  133:       3'b100 : { cout, out } = { cin, in1 ^ in2 };
  134:       3'b101 : { cout, out } = { cin, in1 | in2 };
  135:       3'b110 : { cout, out } = { cin, in1 & in2 };
  136:       3'b111 : { cout, out } = { in2[l-1], cin, in2[0:l-2] };
  137:     endcase /* 3 */
  138: 
  139:    assign
  140:     zout = ~|out;
  141:    
  142: endmodule /* alu */

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>