Advertisement
If you have a new account but are having problems posting or verifying your account, please email us on hello@boards.ie for help. Thanks :)
Hello all! Please ensure that you are posting a new thread or question in the appropriate forum. The Feedback forum is overwhelmed with questions that are having to be moved elsewhere. If you need help to verify your account contact hello@boards.ie

Barrel Shifter using Multiplexers in C

Options
  • 26-12-2014 12:28pm
    #1
    Closed Accounts Posts: 66 ✭✭


    I need help synthesising a 32-bit Barrel Shifter using Multiplexers with just C bitwise operators in order to perform arithmetic/logical shift operations.

    The bitwise operators NOT, XOR, OR, AND can be implemented using NAND gate.
    // All other gates can be constructed from NAND
    // NOT, AND
    unsigned int nand (unsigned int x, unsigned int y)
    {
      return ~(x & y);
    }
    
    // NOT operation
    unsigned int not (unsigned int x) {
      return nand (x, x);
    }
    
    // NAND(-1, NAND(x, y)
    // NAND (NAND(x, y), NAND(x, y))
    // NOT (NOT(x) OR NOT(y))
    unsigned int and (unsigned int x, unsigned int y)
    {
      return nand (nand (x, y), nand (x, y));
      //return ~(~x | ~y);
    }
    
    // AND, NOT
    // NOT (NOT(x) AND NOT(y))
    unsigned int or (unsigned int x, unsigned int y)
    {
      return nand (nand (x, x), nand (y, y));
      //return ~(~x & ~y);
    }
    
    // OR, AND, NOT
    unsigned int xor (unsigned int x, unsigned int y)
    {
      return nand ((nand (x, (nand (x, y) ) )), (nand (y, (nand (x, y) ) )) );
      //return (~x & y) | (x & ~y);
    }
    

    This is a software project so I can't use << or >> operators for addition with carry.
    I cannot use arithmetic operators like ADD, SUB, MUL, DIV -- only NAND gate.

    This code would be used for binary division and as you can see from comments, each logical shift would be replaced with barrel shifter.
    
    unsigned int sub (unsigned int x, unsigned int y)
    {
      x = ~x;
      
      while (y != 0)
      {
        unsigned int carry = (x & y);  
        x = x ^ y;
        y = carry << 1;    // replace with barrel shifter
      }
      return ~x;
    }
    
    // divide and get remainder.
    void divmod (unsigned int dividend, unsigned int divisor, 
      unsigned int *quotient, unsigned int *remainder) {
      
      unsigned int r, q, t, i;
      
      *quotient  = 0;
      *remainder = 0;
      
      r = 0;
      q = 0;
      t = dividend;
      
      for (i = 0; i < sizeof (unsigned int) * CHAR_BIT; i++)
      {
        r <<= 1;  // replace with barrel shifter
        q <<= 1;  // replace with barrel shifter
        r |= (t & INT32_MIN) >> (sizeof (unsigned int) * CHAR_BIT)-1;
        
        if (r >= divisor) {
          r = sub (r, divisor);
          q |= 1; 
        }
        t <<= 1;  // replace with barrel shifter
      }
      *quotient  = q;
      *remainder = r;
    }
    


Advertisement