dpcnt001s.vmd 3.42 KB

/**************************************************************/
/*    Verilog module of datapath cell dpcnt001s              */
/*    Designed by    Chunling Liu   Compass       Aug. 7, 92  */
/*                                                            */
/*    The following is the port description                   */
/*    Data ports                                              */
/*        D    : the input port                               */
/*        Q    : the output port                              */
/*        QN   : the output port                              */
/*    Control ports                                           */
/*        INST_CP    : the clock signal                       */
/*        INST_CLEAR : the clear signal                       */
/*        INST_CIN   : the carry input                        */
/*        INST_COUT  : the carry output                       */
/*        INST_LOAD  : the load enable signal                 */
/*        INST_COUNT : the count enable signal                */
/*        INST_ID    : the increment/decrement control signal */
/*    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 dpcnt001s(D, Q, QN, INST_CP, INST_CLEAR, INST_CIN,
                  INST_COUT, INST_LOAD, INST_COUNT, INST_ID);

  parameter WORDSIZE = 8, DELAY = 3, SETUP = 1, HOLD = 1, BF = 1;
  input  [WORDSIZE-1:0] D;
  output [WORDSIZE-1:0] Q, QN;
  input  INST_CP, INST_CLEAR, INST_CIN;
  output INST_COUT;
  input  INST_LOAD, INST_COUNT, INST_ID;

  reg    [WORDSIZE-1:0] dff;
  reg    cout;
  reg    cp;

  function [WORDSIZE:0] cnt;
  input  [WORDSIZE-1:0] d;

  reg flag;

    begin

      if (INST_LOAD == 1)
           cnt = d;
      else if (INST_LOAD == 0)
      begin
          case ({INST_COUNT,INST_CIN,INST_ID})
            3'b 101 : cnt = dff + 'b1;
            3'b 100 : cnt = dff + {WORDSIZE{1'b1}};
            3'b 000 ,
            3'b 001 ,
            3'b 010 ,
            3'b 011 ,
            3'b 110 ,
            3'b 111 : cnt = dff;
            default cnt = {WORDSIZE{1'b x}};
          endcase
      end
      else
          cnt[WORDSIZE-1:0] = {WORDSIZE{1'bx}};

      if(INST_ID == 1)
         cnt[WORDSIZE] = & cnt[WORDSIZE-1:0] & (~INST_CIN);
      else if (INST_ID == 0)
         cnt[WORDSIZE] = ^ cnt[WORDSIZE-1:0] & (~INST_CIN);
      else
         cnt[WORDSIZE] = 'bx;

      if ( !BF )
      case(WORDSIZE)
      4,5,6,
      11,12,13,14,15,
      22,23,24,25,26,27,28,
      37,38,39,40,41,42,43,44,45,
      55,56,57,58,59,60,61,62,63,64: cnt[WORDSIZE] = ~cnt[WORDSIZE];
     endcase
    end
  endfunction

  always @ INST_CP
           if (!INST_CP)
              cp = INST_CP;
           else if (INST_CP)
              cp = INST_CP;

  always @ (posedge cp)
         {cout, dff} = cnt(D);

  always @ (INST_CLEAR)
              if (! INST_CLEAR)
                 begin
                 assign dff = {WORDSIZE{1'b0}};
                 assign cout = 0;
                 end
              else
                 begin
                 deassign dff;
                 deassign cout;
                 end

  assign #DELAY INST_COUT = cout, Q = dff, QN = ~dff;

endmodule