Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
8 years ago

FPGA Development Board - strange shift operation behavior

My development board based on:

Cyclone IV EP4CE10E22C8N

Quartus: 17.0.0 Lite Edition

top-level entity code:


module led4_reg(clk, led);
parameter BASE_LED_SEQUENCE = 12'b000011101101;
input clk;
output  led;
reg  led;
reg  circle_count;
initial begin
    led = 0;
    count = 0;
    circle_count = 0;
    led <= ~led;
    $monitor($time, " led = %b count = %d", led, circle_count);
end
reg  count;
always @(posedge clk)
begin
    count <= count + 1;
    if (count == 1) begin    
        count <= 0;
        circle_count <= circle_count + 1;
    end
    if (circle_count == 12)
        circle_count <= 0;        
end
always @(circle_count)
begin
    case (circle_count)
        0: led <= BASE_LED_SEQUENCE;
        1,2,3,4: led <= (led << 1);
//        1:  led <= 12'b000111011010;
//        2:  led <= 12'b001110110100;
//        3:  led <= 12'b011101101000;
//        4:  led <= 12'b111011010000;
        5:  led <= 12'b110110100001;
        6:  led <= 12'b101101000011;
        7:  led <= 12'b011010000111;
        8:  led <= 12'b110100001110;
        9:  led <= 12'b101000011101;
        10: led <= 12'b010000111011;
        11: led <= 12'b100001110110;
        default: led <= 12'b000_111_111_111;
    endcase
end
endmodule

My test file:


`include "led4_reg.v"
module main();
    
reg clk;
wire  leds;
led4_reg reglight(clk, leds);
initial begin
    clk = 0;
    forever# 1 clk = ~clk; 
end
initial# 160_000_000 $finish; 
endmodule

And test results:


                 0 led = 000011101101 count =  0
            16777217 led = 000111011010 count =  1
            33554435 led = 001110110100 count =  2
            50331653 led = 011101101000 count =  3
            67108871 led = 111011010000 count =  4
            83886089 led = 110110100001 count =  5
           100663307 led = 101101000011 count =  6
           117440525 led = 011010000111 count =  7
           134217743 led = 110100001110 count =  8
           150994961 led = 101000011101 count =  9

But on the Dev Board LED for count item 1,2,3,4 always: 12'b000_000_000_000;

I don't understand why.

Additionally for some reason '0' - turn on light for LED. '1' - turn off for LED. Is it normal?

Any idea? ))

Thanks!

15 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Thanks for pointing it out .. I agree with ak6dn. My bad. His code should work. Try it out.

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    Why not just add the statement:

    led <= circle_count == 4'd0 ? BASE_LED_SEQUENCE : led << 1;

    into the main loop, so it looks like this:

    always @(posedge clk or negedge reset)
        begin
        if (!reset) 
            begin
            count <= 28'd0;
            circle_count <= 4'd0;
            led <= 12'b0;
            end
        else
            begin
            if (count == 1)
                begin    
                count <= 1'b0;
                circle_count <= circle_count == 4'd12 ? 4'd0 : circle_count + 4'd1;
                led <= circle_count == 4'd0 ? BASE_LED_SEQUENCE : led << 1;
                end
            else
                count <= count + 28'd1;
            end
        end
    

    which I think is a lot easier to follow.

    --- Quote End ---

    Thank you,

    It's pretty well working.

    But could you explain me why I can't get previous value for `led` in other always blocks?
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    Thank you,

    It's pretty well working.

    But could you explain me why I can't get previous value for `led` in other always blocks?

    --- Quote End ---

    Not sure what you mean by this. led[11:0] is a register, so you can access it at any time in any logic equation within that module. The value will only change when the always block that encloses it is triggered and the value is updated.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    Not sure what you mean by this. led[11:0] is a register, so you can access it at any time in any logic equation within that module. The value will only change when the always block that encloses it is triggered and the value is updated.

    --- Quote End ---

    Code example:

    
    reg  value;
    reg  circle_count;
    reg  count;
    always @(posedge clk)
    begin
        count <= count + 1'b1;
        if (count == 1) begin    
            count <= 0;
            circle_count <= circle_count + 1'b1;
            if (circle_count == 12)
                circle_count <= 0;        
        end
    end
    always @(circle_count)
    begin
        case (circle_count)
            0: value <= 5'b00101;
            1: value <= value; // 5'b00101
            2,3,4: value <= (value << 1); // always 0 - why? 
    // When I start simulation test - it will changes succesfully
    // On Board - it always ZERO when I try to shift it.
            default: value <= 12'b10101;
        endcase
    end
    endmodule
    
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    Code example:

    
    reg  value;
    reg  circle_count;
    reg  count;
    always @(posedge clk)
    begin
        count <= count + 1'b1;
        if (count == 1) begin    
            count <= 0;
            circle_count <= circle_count + 1'b1;
            if (circle_count == 12)
                circle_count <= 0;        
        end
    end
    always @(circle_count)
    begin
        case (circle_count)
            0: value <= 5'b00101;
            1: value <= value; // 5'b00101
            2,3,4: value <= (value << 1); // always 0 - why? 
    // When I start simulation test - it will changes succesfully
    // On Board - it always ZERO when I try to shift it.
            default: value <= 12'b10101;
        endcase
    end
    endmodule
    

    --- Quote End ---

    The highlighted code is just bad coding practice. Stop doing it. It will work in simulation but it produces a very poor implementation.