Search code examples
verilogsystem-verilogvivadotest-bench

Can someone explain me ,how this code works, shifting led, chaser?


I have code like this, describing shifting led like chaser, i can't find information in books or google to understand , how that code works,

> led <= (led == 7'b1000000) ? 7'b0000001 :
              (led <= 7'b0000001) ? 7'b0000010 :
              (led <= 7'b0000010) ? 7'b0000100 :
              (led <= 7'b0000100) ? 7'b0001000 :
              (led <= 7'b0001000) ? 7'b0010000 :
              (led <= 7'b0010000) ? 7'b0100000 :
              (led <= 7'b0100000) ? 7'b1000000 : 7'b0000000;

i thought, that we first compare does led equal to 7'b10000_000 and then if false, we assign led = 7'b0000_001 and then we compare does it equal to 7'b0000010 and (led <= 7'b0000010),bc it not equal to 7'b0000010 we assign led to (led <= 7'b0000010) and so on, so because we never use 7'b0000010, 7'b0000100, 7'b0001000, 7'b0010000,7'b0100000 ,7'b1000000 and only compare like if not equal to this results we chose sentence in braces, but if it is no matter what the firse number we will use to compare bc its no matter, we can type whatever number that we want, but in testbench, every number is important, so can someone explain me, how this code actually work, sorry, if i explain not good my question.


Solution

  • The conditional operator ? : has right to left associativity which means the precedence of these operators is effectively

          led <=  // <= this is a non-blocking assignment operator
                 (led == 7'b1000000) ? 7'b0000001 :
                 ( (led <= 7'b0000001) ? 7'b0000010 : // <= is a less than or equal operator 
                 ( (led <= 7'b0000010) ? 7'b0000100 :
                 ( (led <= 7'b0000100) ? 7'b0001000 :
                 ( (led <= 7'b0001000) ? 7'b0010000 :
                 ( (led <= 7'b0010000) ? 7'b0100000 :
                 ( (led <= 7'b0100000) ? 7'b1000000 : 7'b0000000 ) ) ) ) ) );
    

    This is the same as using an if-else-if-else-... branching tree

    if (led == 7'b1000000)
      led <= 7'b0000001; // <= is a non-blocking assignment statement
    else if (led <= 7'b0000001) // <= is a less than or equal operator
      led <= 7'b0000010; // <= is a non-blocking assignment statement
    ...
    else // anything else 
      led <= 7'b0000000;
    

    The comparisons are <= which is less than or equal. And I'm guessing the first comparison == might have been a mistake and should have been <= like the others. This makes the logic simpler, and the main benefit of writing it this way versus a shift register is that if the led register is ever has more than one bit set (like at power-up), it will get back into a single bit rotation.