Search code examples
mathverilogcycleshiftintel-fpga

Correct arithmetic(cycle) shift in verilog


I'm new to verilog and am stuck on one curious moment. I'm trying to do a cycled leds blinking(green lights from left to right and red ones from right to left). I have 12 leds and am synchronizing my program with clock(CLK).

I wanted to use arithmetic shift for this, but for some reason <<< and >>> behave like << and >>, so the shift is not cyclic. Why is this so? Am I doing something wrong?

I'm putting the whole code just in case it's necessary, its very short:

module test1(
  input CLK,
  output [11:0] MLED 
); 
reg [11:0] tmp; 
reg [11:0] tmpred;
reg [11:0] tmpgreen;
assign MLED = tmp; 
reg [1:0] COUNTER;
wire [1:0] COUNTER_WIRE;  
assign COUNTER_WIRE=COUNTER; 

wire  LOG; 
assign LOG=(COUNTER_WIRE==2'd3) ? 1'b1 : 1'b0;  

initial 
  begin 
    tmp<=12'b100000000001;
    tmpred<=12'b000000000001;
    tmpgreen<=12'b100000000000;
  COUNTER<=0; 
  end 

always@(posedge CLK) 
  begin 
    if (LOG) 
      begin 
        tmpred <= $signed(tmpred) <<< 2;
        tmpgreen <= $signed(tmpgreen) >>> 2;
        tmp <= tmpred | tmpgreen;
      end 
    COUNTER <= COUNTER + 1'b1; 
  end 
endmodule 

Solution

  • <<< and >>> are signed shift operators - ie 0xF0 >>> 1 = 0xF8 vs 0xF0 >> 1 = 0x78. Right shifting will beahve differently, but the <<< will be the same as <<.

    To do a cyclic right shift, use tempred <= {tempred[0],tempred[11:1]}; instead.