dpmlt033m.vmd 3.85 KB
/**************************************************************/
/*    Verilog module of datapath cell dpmlt033m              */
/*    Designed by    Lin Yang    VLSI Technology  Jan. 25, 91 */
/*    Designed by    Chunling Liu  Compass        June 30, 92 */
/*    Modified by    Linda J. Xu   Compass        Nov. 2 , 92 */
/*                                                            */
/*    The following is the port description                   */
/*    Data ports                                              */
/*        X    : the input port                               */
/*        Y    : the input port                               */
/*        MSB  : the output port                              */
/*        LSB  : the output port                              */
/*    Control ports                                           */
/*        INST_CP  : the clock signal                         */
/*        CLEAR : the reset signal                         */
/*    Parameters                                              */
/*        WORDSIZE   : the word size of the datapath cell     */
/*        Number_Of_Columns    : the word size of the datapath cell     */
/*        UNSIGNED     : the unsigned boolean/2's complement    */
/*        number_of_pipes    : the number of pipeline statge          */
/*        Cycle_Length      : the delay time from input to output    */
/**************************************************************/
module dpmlt033m(X, Y, MSB, LSB, INST_CP, CLEAR);

  parameter WORDSIZE = 8, Number_Of_Columns = 8,
            UNSIGNED = 1,number_of_pipes = 1,
            Cycle_Length = 30, BF = 1;
  input  [WORDSIZE-1:0] X, Y;
  output [WORDSIZE-1:0] MSB, LSB;
  input INST_CP, CLEAR;

  reg [WORDSIZE-1:0] MSB, LSB;
  reg [WORDSIZE-1:0] px[1:number_of_pipes];
  reg [Number_Of_Columns-1:0] py[1:number_of_pipes];
  reg [WORDSIZE-1:0] tx[1:number_of_pipes];
  reg [Number_Of_Columns-1:0] ty[1:number_of_pipes];
  reg [WORDSIZE-1:0] ix, sx;
  reg [Number_Of_Columns-1:0] iy, sy;
  reg [WORDSIZE+Number_Of_Columns-1:0] Z;

  task mlt;
    integer n;

    begin
// update pipeline registers
      tx[1] = X;
      ty[1] = Y;
      for (n=2; n<=number_of_pipes; n=n+1)
      begin
        tx[n] = px[n-1];
        ty[n] = py[n-1];
      end

      if (UNSIGNED == 0)
      begin
        ix = tx[number_of_pipes];
        iy = ty[number_of_pipes];
        if (ix[WORDSIZE-1] ^ iy[Number_Of_Columns-1])
        begin
          if (ix[WORDSIZE-1] == 1)
          begin
            sx = ~ix + 1;
            sy = iy;
          end
          else if (iy[Number_Of_Columns-1] == 1)
          begin
            sx = ix;
            sy = ~iy + 1;
          end
          Z = ~(sx * sy) + 1;
        end
        else if (ix[WORDSIZE-1] ^~ iy[Number_Of_Columns-1])
        begin
          if (ix[WORDSIZE-1])
          begin
            sx = ~ix + 1;
            sy = ~iy + 1;
          end
          else
          begin
            sx = ix;
            sy = iy;
          end
          Z = sx * sy;
        end
        else
          Z = {WORDSIZE+Number_Of_Columns{1'bx}};
      end
      else
         Z = tx[number_of_pipes] * ty[number_of_pipes];

      #Cycle_Length update;
    end
  endtask

  task update;
    integer n;

    begin
      for (n=1; n<=number_of_pipes; n=n+1)
        begin
          px[n] = tx[n];
          py[n] = ty[n];
        end

// do the multiplication
      LSB = {{WORDSIZE-Number_Of_Columns{1'b0}},Z[Number_Of_Columns-1:0]};
      MSB = Z[WORDSIZE+Number_Of_Columns-1:Number_Of_Columns];
    end
  endtask

  task reset;
    integer n;
    begin
      for (n=1; n<=number_of_pipes; n=n+1)
      begin
        px[n] = {WORDSIZE{1'b0}};
        py[n] = {Number_Of_Columns{1'b0}};
      end
      assign LSB = {WORDSIZE{1'b0}};
      assign MSB = {WORDSIZE{1'b0}};
    end
  endtask

  always @( posedge CLEAR & INST_CP == 1) reset;

  always @(posedge INST_CP) mlt;

endmodule