Advertisement
Help Keep Boards Alive. Support us by going ad free today. See here: https://subscriptions.boards.ie/.
If we do not hit our goal we will be forced to close the site.

Current status: https://keepboardsalive.com/

Annual subs are best for most impact. If you are still undecided on going Ad Free - you can also donate using the Paypal Donate option. All contribution helps. Thank you.
https://www.boards.ie/group/1878-subscribers-forum

Private Group for paid up members of Boards.ie. Join the club.

Barrel Shifter using Multiplexers in C

  • 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