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

Subversion Repositories zet86

[/] [zet86/] [trunk/] [cores/] [zet/] [rtl/] [alu.v] - Diff between revs 49 and 55

Show entire file | Details | Blame | View Log

Rev 49 Rev 55
Line 1... Line 1...
 
/*
 
 *  Copyright (c) 2008  Zeus Gomez Marmolejo <zeus@opencores.org>
 
 *
 
 *  This file is part of the Zet processor. This processor is free
 
 *  hardware; 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 3, or (at your option) any later version.
 
 *
 
 *  Zet is distrubuted 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.
 
 *
 
 *  You should have received a copy of the GNU General Public License
 
 *  along with Zet; see the file COPYING. If not, see
 
 *  <http://www.gnu.org/licenses/>.
 
 */
 
 
 
`timescale 1ns/10ps
 
 
 
module alu (
 
    input  [31:0] x,
 
    input  [15:0] y,
 
    output [31:0] out,
 
    input  [ 2:0] t,
 
    input  [ 2:0] func,
 
    input  [15:0] iflags,
 
    output [ 8:0] oflags,
 
    input         word_op,
 
    input  [15:0] seg,
 
    input  [15:0] off,
 
    input         clk,
 
    output        div_exc
 
  );
 
 
 
  // Net declarations
 
  wire [15:0] add, log, shi, rot;
 
  wire  [8:0] othflags;
 
  wire [19:0] oth;
 
  wire [31:0] cnv, mul;
 
  wire af_add, af_cnv;
 
  wire cf_cnv, cf_add, cf_mul, cf_log, cf_shi, cf_rot;
 
  wire of_cnv, of_add, of_mul, of_log, of_shi, of_rot;
 
  wire ofi, sfi, zfi, afi, pfi, cfi;
 
  wire ofo, sfo, zfo, afo, pfo, cfo;
 
  wire flags_unchanged;
 
  wire dexc;
 
 
 
  // Module instances
 
  addsub add1 (x[15:0], y, add, func, word_op, cfi, cf_add, af_add, of_add);
 
 
 
  conv cnv2 (
 
    .x      (x[15:0]),
 
    .func   (func),
 
    .out    (cnv),
 
    .iflags ({afi, cfi}),
 
    .oflags ({af_cnv, of_cnv, cf_cnv})
 
  );
 
 
 
  muldiv mul3 (
 
    .x       (x),
 
    .y       (y),
 
    .o       (mul),
 
    .f       (func),
 
    .word_op (word_op),
 
    .cfo     (cf_mul),
 
    .ofo     (of_mul),
 
    .clk     (clk),
 
    .exc     (dexc)
 
  );
 
 
 
  bitlog log4 (x[15:0], y, log, func, cf_log, of_log);
 
  shifts shi5 (x[15:0], y[4:0], shi, func[1:0], word_op, cfi, ofi, cf_shi, of_shi);
 
  rotate rot6 (x[15:0], y[4:0], func[1:0], cfi, word_op, rot, cf_rot, ofi, of_rot);
 
  othop  oth7 (x[15:0], y, seg, off, iflags, func, word_op, oth, othflags);
 
 
 
  mux8_16 m0(t, {8'd0, y[7:0]}, add, cnv[15:0],
 
             mul[15:0], log, shi, rot, oth[15:0], out[15:0]);
 
  mux8_16 m1(t, 16'd0, 16'd0, cnv[31:16], mul[31:16],
 
             16'd0, 16'd0, 16'd0, {12'b0,oth[19:16]}, out[31:16]);
 
  mux8_1  a1(t, 1'b0, cf_add, cf_cnv, cf_mul, cf_log, cf_shi, cf_rot, 1'b0, cfo);
 
  mux8_1  a2(t, 1'b0, af_add, af_cnv, 1'b0, 1'b0, 1'b0, afi, 1'b0, afo);
 
  mux8_1  a3(t, 1'b0, of_add, of_cnv, of_mul, of_log, of_shi, of_rot, 1'b0, ofo);
 
 
 
  // Flags
 
  assign pfo = flags_unchanged ? pfi : ^~ out[7:0];
 
  assign zfo = flags_unchanged ? zfi
 
             : ((word_op && (t!=3'd2)) ? ~|out[15:0] : ~|out[7:0]);
 
  assign sfo = flags_unchanged ? sfi
 
             : ((word_op && (t!=3'd2)) ? out[15] : out[7]);
 
 
 
  assign oflags = (t == 3'd7) ? othflags
 
                 : { ofo, iflags[10:8], sfo, zfo, afo, pfo, cfo };
 
 
 
  assign ofi = iflags[11];
 
  assign sfi = iflags[7];
 
  assign zfi = iflags[6];
 
  assign afi = iflags[4];
 
  assign pfi = iflags[2];
 
  assign cfi = iflags[0];
 
 
 
  assign flags_unchanged = (t == 3'd4 && func == 3'd2
 
                         || t == 3'd5 && y[4:0] == 5'h0
 
                         || t == 3'd6);
 
 
 
  assign div_exc = func[1] && (t==3'd3) && dexc;
 
 
 
endmodule
 
 
 
module addsub (
 
    input  [15:0] x,
 
    input  [15:0] y,
 
    output [15:0] out,
 
    input  [ 2:0] f,
 
    input         word_op,
 
    input         cfi,
 
    output        cfo,
 
    output        afo,
 
    output        ofo
 
  );
 
 
 
  // Net declarations
 
  wire [15:0] op2;
 
 
 
  wire ci;
 
  wire cfoadd;
 
  wire xs, ys, os;
 
 
 
  // Module instances
 
  fulladd16 fa0 ( // We instantiate only one adder
 
    .x  (x),      //  to have less hardware
 
    .y  (op2),
 
    .ci (ci),
 
    .co (cfoadd),
 
    .z  (out),
 
    .s  (f[2])
 
  );
 
 
 
  // Assignments
 
  assign op2 = f[2] ? ~y
 
             : ((f[1:0]==2'b11) ? { 8'b0, y[7:0] } : y);
 
  assign ci  = f[2] & f[1] | f[2] & ~f[0] & ~cfi
 
             | f[2] & f[0] | (f==3'b0) & cfi;
 
  assign afo = f[1] ? (f[2] ? &out[3:0] : ~|out[3:0] )
 
                    : (x[4] ^ y[4] ^ out[4]);
 
  assign cfo = f[1] ? cfi /* inc, dec */
 
             : (word_op ? cfoadd : (x[8]^y[8]^out[8]));
 
 
 
  assign xs  = word_op ? x[15] : x[7];
 
  assign ys  = word_op ? y[15] : y[7];
 
  assign os  = word_op ? out[15] : out[7];
 
  assign ofo = f[2] ? (~xs & ys & os | xs & ~ys & ~os)
 
                    : (~xs & ~ys & os | xs & ys & ~os);
 
endmodule
 
 
 
module conv (
 
    input  [15:0] x,
 
    input  [ 2:0] func,
 
    output [31:0] out,
 
    input  [ 1:0] iflags, // afi, cfi
 
    output [ 2:0] oflags  // afo, ofo, cfo
 
  );
 
 
 
  // Net declarations
 
  wire        afi, cfi;
 
  wire        ofo, afo, cfo;
 
  wire [15:0] aaa, aas;
 
  wire [ 7:0] daa, tmpdaa, das, tmpdas;
 
  wire [15:0] cbw, cwd;
 
 
 
  wire        acond, dcond;
 
  wire        tmpcf;
 
 
 
  // Module instances
 
  mux8_16 m0(func, cbw, aaa, aas, 16'd0,
 
                   cwd, {x[15:8], daa}, {x[15:8], das}, 16'd0, out[15:0]);
 
 
 
  // Assignments
 
  assign aaa = (acond ? (x + 16'h0106) : x) & 16'hff0f;
 
  assign aas = (acond ? (x - 16'h0106) : x) & 16'hff0f;
 
 
 
  assign tmpdaa = acond ? (x[7:0] + 8'h06) : x[7:0];
 
  assign daa    = dcond ? (tmpdaa + 8'h60) : tmpdaa;
 
  assign tmpdas = acond ? (x[7:0] - 8'h06) : x[7:0];
 
  assign das    = dcond ? (tmpdas - 8'h60) : tmpdas;
 
 
 
  assign               cbw   = { { 8{x[ 7]}}, x[7:0] };
 
  assign { out[31:16], cwd } = { {16{x[15]}}, x      };
 
 
 
  assign acond = ((x[7:0] & 8'h0f) > 8'h09) | afi;
 
  assign dcond = (x[7:0] > 8'h99) | cfi;
 
 
 
  assign afi = iflags[1];
 
  assign cfi = iflags[0];
 
 
 
  assign afo = acond;
 
  assign ofo = 1'b0;
 
  assign tmpcf = (x[7:0] < 8'h06) | cfi;
 
  assign cfo = func[2] ? (dcond ? 1'b1 : (acond & tmpcf))
 
             : acond;
 
 
 
  assign oflags = { afo, ofo, cfo };
 
endmodule
 
 
 
 
 
module muldiv (
 
    input  [31:0] x,  // 16 MSb for division
 
    input  [15:0] y,
 
    output [31:0] o,
 
    input  [ 2:0] f,
 
    input         word_op,
 
    output        cfo,
 
    output        ofo,
 
    input         clk,
 
    output        exc
 
  );
 
 
 
  // Net declarations
 
  wire as, bs, cfs, cfu;
 
  wire [16:0] a, b;
 
  wire [33:0] p;
 
  wire div0, over, ovf, mint;
 
 
 
  wire [33:0] zi;
 
  wire [16:0] di;
 
  wire [17:0] q;
 
  wire [17:0] s;
 
 
 
  // Module instantiations
 
  mult signmul17 (
 
    .clk (clk),
 
    .a   (a),
 
    .b   (b),
 
    .p   (p)
 
  );
 
 
 
  div_su #(34) dut (
 
    .clk  (clk),
 
    .ena  (1'b1),
 
    .z    (zi),
 
    .d    (di),
 
    .q    (q),
 
    .s    (s),
 
    .ovf  (ovf),
 
    .div0 (div0)
 
  );
 
 
 
  // Sign ext. for imul
 
  assign as  = f[0] & (word_op ? x[15] : x[7]);
 
  assign bs  = f[0] & (word_op ? y[15] : y[7]);
 
  assign a   = word_op ? { as, x[15:0] }
 
                       : { {9{as}}, x[7:0] };
 
  assign b   = word_op ? { bs, y } : { {9{bs}}, y[7:0] };
 
 
 
  assign zi  = f[2] ? { 26'h0, x[7:0] }
 
               : (word_op ? (f[0] ? { {2{x[31]}}, x }
 
                               : { 2'b0, x })
 
                       : (f[0] ? { {18{x[15]}}, x[15:0] }
 
                               : { 18'b0, x[15:0] }));
 
 
 
  assign di  = word_op ? (f[0] ? { y[15], y } : { 1'b0, y })
 
                       : (f[0] ? { {9{y[7]}}, y[7:0] }
 
                               : { 9'h000, y[7:0] });
 
 
 
  assign o   = f[2] ? { 16'h0, q[7:0], s[7:0] }
 
               : (f[1] ? ( word_op ? {s[15:0], q[15:0]}
 
                                : {16'h0, s[7:0], q[7:0]})
 
                    : p[31:0]);
 
 
 
  assign ofo = f[1] ? 1'b0 : cfo;
 
  assign cfo = f[1] ? 1'b0 : !(f[0] ? cfs : cfu);
 
  assign cfu = word_op ? (o[31:16] == 16'h0)
 
                       : (o[15:8] == 8'h0);
 
  assign cfs = word_op ? (o[31:16] == {16{o[15]}})
 
                       : (o[15:8] == {8{o[7]}});
 
 
 
  // Exceptions
 
  assign over = f[2] ? 1'b0
 
              : (word_op ? (f[0] ? (q[17:16]!={2{q[15]}})
 
                                : (q[17:16]!=2'b0) )
 
                        : (f[0] ? (q[17:8]!={10{q[7]}})
 
                                : (q[17:8]!=10'h000)));
 
  assign mint = f[0] & (word_op ? (x==32'h80000000)
 
                                : (x==16'h8000));
 
  assign exc  = div0 | (!f[2] & ovf) | over | mint;
 
endmodule
 
 
 
module bitlog(x, y, out, func, cfo, ofo);
 
  // IO ports
 
  input  [15:0] x, y;
 
  input  [2:0]  func;
 
  output [15:0] out;
 
  output        cfo, ofo;
 
 
 
  // Net declarations
 
  wire [15:0] and_n, or_n, not_n, xor_n;
 
 
 
  // Module instantiations
 
  mux8_16 m0(func, and_n, or_n, not_n, xor_n, 16'd0, 16'd0, 16'd0, 16'd0, out);
 
 
 
  // Assignments
 
  assign and_n  = x & y;
 
  assign or_n   = x | y;
 
  assign not_n  = ~x;
 
  assign xor_n  = x ^ y;
 
 
 
  assign cfo = 1'b0;
 
  assign ofo = 1'b0;
 
endmodule
 
 
 
//
 
// This module implements the instructions shl/sal, sar, shr
 
//
 
 
 
module shifts(x, y, out, func, word_op, cfi, ofi, cfo, ofo);
 
  // IO ports
 
  input  [15:0] x;
 
  input  [ 4:0] y;
 
  input   [1:0] func;
 
  input         word_op;
 
  output [15:0] out;
 
  output        cfo, ofo;
 
  input         cfi, ofi;
 
 
 
  // Net declarations
 
  wire [15:0] sal, sar, shr, sal16, sar16, shr16;
 
  wire [7:0]  sal8, sar8, shr8;
 
  wire ofo_shl, ofo_sar, ofo_shr;
 
  wire cfo_sal8, cfo_sal16, cfo_sar8, cfo_sar16, cfo_shr8, cfo_shr16;
 
  wire cfo16, cfo8;
 
  wire unchanged;
 
 
 
  // Module instantiations
 
  mux4_16 m0(func, sal, sar, shr, 16'd0, out);
 
 
 
  // Assignments
 
  assign { cfo_sal16, sal16 } = x << y;
 
  assign { sar16, cfo_sar16 } = (y > 5'd16) ? 17'h1ffff
 
    : (({x,1'b0} >> y) | (x[15] ? (17'h1ffff << (17 - y))
 
                                     : 17'h0));
 
  assign { shr16, cfo_shr16 } = ({x,1'b0} >> y);
 
 
 
  assign { cfo_sal8, sal8 } = x[7:0] << y;
 
  assign { sar8, cfo_sar8 } = (y > 5'd8) ? 9'h1ff
 
    : (({x[7:0],1'b0} >> y) | (x[7] ? (9'h1ff << (9 - y))
 
                                         : 9'h0));
 
  assign { shr8, cfo_shr8 } = ({x[7:0],1'b0} >> y);
 
 
 
  assign sal     = word_op ? sal16 : { 8'd0, sal8 };
 
  assign shr     = word_op ? shr16 : { 8'd0, shr8 };
 
  assign sar     = word_op ? sar16 : { {8{sar8[7]}}, sar8 };
 
 
 
  assign ofo = unchanged ? ofi
 
             : (func[1] ? ofo_shr : (func[0] ? ofo_sar : ofo_shl));
 
  assign cfo16 = func[1] ? cfo_shr16
 
               : (func[0] ? cfo_sar16 : cfo_sal16);
 
  assign cfo8  = func[1] ? cfo_shr8
 
               : (func[0] ? cfo_sar8 : cfo_sal8);
 
  assign cfo = unchanged ? cfi : (word_op ? cfo16 : cfo8);
 
  assign ofo_shl = word_op ? (out[15] != cfo) : (out[7] != cfo);
 
  assign ofo_sar = 1'b0;
 
  assign ofo_shr = word_op ? x[15] : x[7];
 
 
 
  assign unchanged = word_op ? (y==5'b0) : (y[3:0]==4'b0);
 
endmodule
 
 
 
module othop (x, y, seg, off, iflags, func, word_op, out, oflags);
 
  // IO ports
 
  input [15:0] x, y, off, seg, iflags;
 
  input [2:0] func;
 
  input word_op;
 
  output [19:0] out;
 
  output [8:0] oflags;
 
 
 
  // Net declarations
 
  wire [15:0] deff, deff2, outf, clcm, setf, intf, strf;
 
  wire [19:0] dcmp, dcmp2;
 
  wire dfi;
 
 
 
  // Module instantiations
 
  mux8_16 m0(func, dcmp[15:0], dcmp2[15:0], deff, outf, clcm, setf,
 
                   intf, strf, out[15:0]);
 
  assign out[19:16] = func ? dcmp2[19:16] : dcmp[19:16];
 
 
 
  // Assignments
 
  assign dcmp  = (seg << 4) + deff;
 
  assign dcmp2 = (seg << 4) + deff2;
 
  assign deff  = x + y + off;
 
  assign deff2 = x + y + off + 16'd2;
 
  assign outf  = y;
 
  assign clcm  = y[2] ? (y[1] ? /* -1: clc */ {iflags[15:1], 1'b0}
 
                         : /* 4: cld */ {iflags[15:11], 1'b0, iflags[9:0]})
 
                     : (y[1] ? /* 2: cli */ {iflags[15:10], 1'b0, iflags[8:0]}
 
                       : /* 0: cmc */ {iflags[15:1], ~iflags[0]});
 
  assign setf  = y[2] ? (y[1] ? /* -1: stc */ {iflags[15:1], 1'b1}
 
                         : /* 4: std */ {iflags[15:11], 1'b1, iflags[9:0]})
 
                     : (y[1] ? /* 2: sti */ {iflags[15:10], 1'b1, iflags[8:0]}
 
                       : /* 0: outf */ iflags);
 
 
 
  assign intf = {iflags[15:10], 2'b0, iflags[7:0]};
 
  assign dfi  = iflags[10];
 
  assign strf = dfi ? (x - y) : (x + y);
 
 
 
  assign oflags = word_op ? { out[11:6], out[4], out[2], out[0] }
 
                           : { iflags[11:8], out[7:6], out[4], out[2], out[0] };
 
endmodule
 
 
 No newline at end of file
 No newline at end of file

powered by: WebSVN 2.1.0

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