dpalu001h.vmd 4.18 KB
/**************************************************************/
/*    Verilog module of datapath cell dpalu001h              */
/*    Designed by    Chunling Liu Compass         July 31, 92 */
/*                                                            */
/*    The following is the port description                   */
/*    Data ports                                              */
/*        A    : the input port                               */
/*        B    : the input port                               */
/*        SO   : the output port                              */
/*    Control ports                                           */
/*        INST_CIN  : the carry input                         */
/*        INST     : the operation control input             */
/*        INST_COUT : the carry output                        */
/*        INST_OVR  : the carry overflow flag output          */
/*    Parameters                                              */
/*        WORDSIZE  : the word size of the datapath cell      */
/*        DELAY     : the delay time from input to output     */
/*        BF    : the  with/without buffer flag           */
/*                    0 for without buffer; 1 for with buffer */
/**************************************************************/
module dpalu001h(A, B, SO, INST_CIN, INST, INST_COUT, INST_OVR);

  parameter WORDSIZE = 8, DELAY = 15, BF = 1;
  input  [WORDSIZE-1:0] A, B;
  output [WORDSIZE-1:0] SO;
  input  INST_CIN;
  input  [4:0] INST;
  output INST_COUT, INST_OVR;

  reg [WORDSIZE:0] carry;

  reg  odd;

  function [WORDSIZE-1:0] alu;
     input [WORDSIZE-1:0] a,b;
     reg [WORDSIZE-1:0] c;
     reg  a1, b1, p, q;
     input cin;
     input [4:0]op;

     integer i;

     begin
       odd = WORDSIZE % 2;
       carry[0] = cin;
       c[0] = cin;
       for (i=0; i< WORDSIZE; i=i+1)
         begin
         a1 = a[i] ^ op[0];
         b1 = b[i] ^ op[1];
         p = a1 ^~ b1;
         q = a1 & b1;
         carry[i+1] = ((~p) & carry[i]) | (p & q);
         if ((i) % 2)
            begin
            c[(i)] = carry[(i)];
            carry[(i)] = ~c[(i)];
            end
         else
            c[(i)] = carry[(i)];
         end


       if (op[3:0] == 4'b1000)
                 alu = a ^ b;
       else if ( op[3:0] == 4'b1001)
                 alu  = a ^~ b;
       else if ( op[3:0] == 4'b1010)
                 alu  = a ^~ b;
       else if ( op[3:0] == 4'b1011)
                 alu  = a ^ b;
       else if ( op[3:0] == 4'b1100)
                 alu  = ~(a & b);
       else if ( op[3:0] == 4'b1101)
                 alu  = a | (~b);
       else if ( op[3:0] == 4'b1110)
                 alu  = (~a) | b;
       else if ( op[3:0] == 4'b1111)
                 alu  = a | b;
       else if ( op[4:0] == 5'b10000)
                 alu  = a ^~ b;
       else if ( op[4:0] == 5'b10001)
                 alu  = a ^ b;
       else if ( op[4:0] == 5'b10010)
                 alu  = a ^ b;
       else if ( op[4:0] == 5'b10011)
                 alu  = a ^~ b;
       else if ( op[4:0] == 5'b10100)
                 alu  = a & b;
       else if ( op[4:0] == 5'b10101)
                 alu  = (~a) & b;
       else if ( op[4:0] == 5'b10110)
                 alu  = a & (~b);
       else if ( op[4:0] == 5'b10111)
                 alu  = ~(a | b);
       else if (op[4:3] == 2'b00)
           case (op[2:0])
           3'b000 :
               alu = a ^ b ^ c;
           3'b001 :
               alu = (~a) ^ b ^ c;
           3'b010 :
               alu = (~ b) ^ a ^ c;
           3'b011 :
               alu = a ^ b ^ c;
           3'b100 :
               alu = ~(a & b) ^ c;
           3'b101 :
               alu = (a | (~ b)) ^ c;
           3'b110 :
               alu = ((~ a) | b) ^ c;
           3'b111 :
               alu = (a | b) ^ c;
           default
               alu = {WORDSIZE{1'bx}};
           endcase
      else
         begin
           alu = {WORDSIZE{1'bx}};
           carry = {WORDSIZE{1'bx}};
         end
     end
  endfunction

  assign #DELAY
     INST_COUT = ((BF == 1) & ~odd) ?
                 ~carry[WORDSIZE]: carry[WORDSIZE],
     INST_OVR = ((BF == 1) & odd) ?
                carry[WORDSIZE-1]: ~carry[WORDSIZE-1],
     SO = alu(A,B,INST_CIN,INST);

endmodule