dpmlt032m.vmd 3.45 KB
/**************************************************************/
/*    Verilog module of datapath cell dpmlt032m               */
/*    Designed by    Lin Yang    VLSI Technology  Jan. 25, 91 */
/*    Designed by    Chunling Liu Compass         June 16, 92 */
/*    Edited by      Paul Hyland    Compass       Feb. 10, 93 */
/*                                                            */
/*    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                         */
/*    Parameters                                              */
/*        WORDSIZE   : the word size of the datapath cell     */
/*        Y_Bus_Size : the Y input width (also known as the   */
/*                     number_of_columns                      */
/*        unsigned   : the unsigneded boolean/2's complement  */
/*        number_of_pipes  : the number of pipeline statge    */
/*        DELAY      : the delay time from input to output    */
/**************************************************************/
module dpmlt032m(X, Y, MSB, LSB, INST_CP);

  parameter WORDSIZE = 8, Y_Bus_Size = 8, unsigned = 1, number_of_pipes = 1, DELAY = 30, BF = 1;
  input  [WORDSIZE-1:0] X, Y;
  output [WORDSIZE-1:0] MSB, LSB;
  input INST_CP;

  reg [WORDSIZE-1:0] MSB, LSB;
  reg [WORDSIZE-1:0] px[1:number_of_pipes];
  reg [Y_Bus_Size-1:0] py[1:number_of_pipes];
  reg [WORDSIZE-1:0] tx[1:number_of_pipes];
  reg [Y_Bus_Size-1:0] ty[1:number_of_pipes];
  reg [WORDSIZE-1:0] ix, sx;
  reg [Y_Bus_Size-1:0] iy, sy;
  reg [WORDSIZE+Y_Bus_Size-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[Y_Bus_Size-1])
        begin
          if (ix[WORDSIZE-1] == 1)
          begin
            sx = ~ix + 1;
            sy = iy;
          end
          else if (iy[Y_Bus_Size-1] == 1)
          begin
            sx = ix;
            sy = ~iy + 1;
          end
          Z = ~(sx * sy) + 1;
        end
        else if (ix[WORDSIZE-1] ^~ iy[Y_Bus_Size-1])
        begin
          if (ix[WORDSIZE-1] == 0)
            begin
            sx = {1'b0, ix[WORDSIZE-2:0]};
            sy = {1'b0, iy[Y_Bus_Size-2:0]};
            Z = sx * sy;
            end
          else
            begin
            sx = ~ix +1;
            sy = ~iy +1;
            Z = sx * sy;
            end
        end
        else
          Z = {WORDSIZE+Y_Bus_Size{1'bx}};
      end
      else
         Z = tx[number_of_pipes] * ty[number_of_pipes];

      #DELAY 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-Y_Bus_Size{1'b0}},Z[Y_Bus_Size-1:0]};
      MSB = Z[WORDSIZE+Y_Bus_Size-1:Y_Bus_Size];
    end
  endtask

  always @(posedge INST_CP) mlt;

endmodule