Forum Discussion
Altera_Forum
Honored Contributor
8 years agoFPGA 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
Honored Contributor
Thanks for pointing it out .. I agree with ak6dn. My bad. His code should work. Try it out.
- Altera_Forum
Honored Contributor
--- Quote Start --- Why not just add the statement:
into the main loop, so it looks like this:led <= circle_count == 4'd0 ? BASE_LED_SEQUENCE : led << 1;
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?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 - Altera_Forum
Honored 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
Honored 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
Honored Contributor
--- Quote Start --- Code example:
--- 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.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