dpcnt002h.vmd 3.21 KB

/**************************************************************/
/*    Verilog module of datapath cell dpcnt002h              */
/*    Designed by    Lin Yang    VLSI Technology  Nov. 5, 90  */
/*    Designed by    Chunling Liu   Compass       July 6, 92  */
/*                                                            */
/*    The following is the port description                   */
/*    Data ports                                              */
/*        D    : the input port                               */
/*        Q    : the output port                              */
/*        UP   : the up count enable signal                   */
/*        DOWN : the up count enable signal                   */
/*    Control ports                                           */
/*        INST_CP    : the clock signal                       */
/*        INST_CLEAR : the clear signal                       */
/*        INST_LOAD  : the load enable signal                 */
/*        INST_CUP   : the carry out signal when up counting  */
/*        INST_CDOWN : the carry out signal when down counting*/
/*    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 dpcnt002h(D, Q, UP, DOWN, INST_CP, INST_CLEAR, INST_LOAD,
                  INST_CUP, INST_CDOWN);

  parameter WORDSIZE = 8, DELAY = 3, SETUP = 1, HOLD = 1, BF = 1;
  input  [WORDSIZE-1:0] D;
  output [WORDSIZE-1:0] Q;
  input  [WORDSIZE-1:0] UP, DOWN;
  input  INST_CP, INST_CLEAR, INST_LOAD;
  output INST_CUP, INST_CDOWN;

  reg INST_CUP, INST_CDOWN;
  reg    [WORDSIZE-1:0] Q;

  initial Q = {WORDSIZE{1'bx}};

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

  reg up1, down1, flag;

    begin
      flag = WORDSIZE-1;
      if (BF ==1)
        flag = 1'b0;

      if ((|UP) == (&UP))
        up1 = UP[0];
      else
        up1 = 1'bx;

      if ((|DOWN) == (&DOWN))
        down1 = DOWN[0];
      else
        down1 = 1'bx;

      if (INST_CLEAR == 0)
        cnt = {WORDSIZE{1'b0}};
      else if (INST_CLEAR == 1)
      begin
        if (INST_LOAD == 1)
           cnt = ~(~d);
        else if (INST_LOAD == 0)
        begin
          case ({up1,down1})
            2'b 00 ,
            2'b 11 :
                begin
                  cnt[WORDSIZE-1:0] = Q;
                end
            2'b 10 :
                begin
                  cnt[WORDSIZE-1:0] = Q + 1'b1;
                end
            2'b 01 :
                begin
                  cnt[WORDSIZE-1:0] = Q + {WORDSIZE{1'b1}};
                end
            default cnt[WORDSIZE-1:0] = {WORDSIZE{1'b x}};
          endcase
        end
        else
          cnt[WORDSIZE-1:0] = {WORDSIZE{1'bx}};
      end
      else
        cnt[WORDSIZE-1:0] = {WORDSIZE{1'bx}};

      cnt[WORDSIZE] = flag ^~ (|cnt[WORDSIZE-1:0]);
      cnt[WORDSIZE+1] = flag ^ (&cnt[WORDSIZE-1:0]);
    end
  endfunction

  always @ ( posedge INST_CP or negedge INST_CLEAR)
         {INST_CUP, INST_CDOWN, Q} = #DELAY cnt(D);

endmodule