- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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!
Link Copied
15 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
Is your board an Altera/terasic dev board or a custom one based on Cyclone IV ? If its the Altera/terasic one, then most likely the LEDs are all active low , meaning, a writing a '0' will turn ON the LED and '1' will turn OFF the LED.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- Quote Start --- Hi, Is your board an Altera/terasic dev board or a custom one based on Cyclone IV ? If its the Altera/terasic one, then most likely the LEDs are all active low , meaning, a writing a '0' will turn ON the LED and '1' will turn OFF the LED. --- Quote End --- Looks like custome Dev Board ZEOWAA A-C4E6E10. Main problem in the part:
led <= (led << 1);
if I use explicit form like:
led <= (12'b000111011010 << 1);
it work pretty well on Dev Board.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
There are a few issues in the code. 1. You cannot use initial blocks and $display tasks in RTL code for synthesis as these constructs are non-synthesizable . These are used only for simulation 2. The code does not have a reset value or initial value. Use an asynchronous reset input and in the always block check for its negedge. When reset is asserted, initialize the count and output to '0'. 3. The reason why led is always 0, is due to the fact that for the first case item (case 0) it will get the value from the parameter. For the next case items (case 1,2,3,4).. You are left shifting the value in the register which is always at 0. This is due to the fact that, after the case is hit, its value will get updated outside the always block. So the next time the code comes back to the case and hits the next one, the value of the led variable is 0. The previous value of led variable is not stored. You can accomplish this by modifying the default condition..
default : led <= led;
Although this will infer a latch that will store the last value of the register led.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- Quote Start --- Hi, There are a few issues in the code. --- Quote End --- Thank you for the response! Point 1,2 - thank you very much for remarks! 3. I really can't understand why:
1: led <= led; // will get previous value
but
1: led <= (led << 1); // can't get previous value
Additionally, the default block never invoked. Am I understand correctly that I should implement simple latch for storing previous value?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
You should ideally, store the previous value or initial value of the led in a register/flop. Then have it shifted out in the case. The default case may not work, but worth a try. You will understand what I mentioned if you look at how an always block will be executed.
What you need to do is to latch in or register in the default value of the led (parameter) then use this value to shift left and get your corresponding outputs. For this to happen, the value of led register should be latched or stored, then used again in the case to update for the next case item.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Try this code out. I just modified it to add the reset and logic to store initial value.
module LED4(clk, reset, led);
parameter BASE_LED_SEQUENCE = 12'b000011101101;
input clk;
input reset;
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 or negedge reset)
begin
if (!reset)
begin
count <= 28'd0;
circle_count <= 4'd0;
end
else begin
count <= count + 1;
count <= 0;
circle_count <= circle_count + 1;
if (circle_count == 12)
circle_count <= 0;
end
end
always @(circle_count)
begin
led <= BASE_LED_SEQUENCE;
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- Quote Start --- Try this code out. I just modified it to add the reset and logic to store initial value.
1,2,3,4: led <= (led << 1);
--- Quote End --- Same result: 1,2,3,4 = 0; With D-latch same result:
module led4_reg(
input clk,
input rst,
output reg led
);
parameter BASE_LED_SEQUENCE = 12'b000011101101;
reg led_value;
reg circle_count;
reg count;
always @(posedge clk or negedge rst)
begin
if (!rst) begin
count <= 0;
circle_count <= 0;
end else begin
count <= count + 1'b1;
if (count == 1) begin
count <= 1'b0;
circle_count <= circle_count + 1'b1;
end
if (circle_count == 12)
circle_count <= 0;
end
end
always @(led) begin
led_value <= led;
end
always @(circle_count or led_value)
begin
case (circle_count)
0: led <= BASE_LED_SEQUENCE;
1,2,3,4: led <= (led_value << 1);
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_000_000_000;
endcase
end
endmodule
if I use:
1,2,3,4: led <= led_value;
it will get previous data.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- Quote Start --- Try this code out. I just modified it to add the reset and logic to store initial value. --- Quote End --- Same result.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Try this one and check, it runs in my simulations..
module led4_reg(clk, reset, led);
parameter BASE_LED_SEQUENCE = 12'b000011101101;
input clk;
input reset;
output led;
reg led;
reg circle_count;
//wire led_tmp;
//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 or negedge reset)
begin
if (!reset)
begin
count <= 28'd0;
circle_count <= 4'd0;
end
else begin
count <= count + 28'd1;
circle_count <= circle_count + 4'd1;
if (circle_count == 4'd12)
circle_count <= 4'd0;
end
end
always@(circle_count or led) begin
if (circle_count == 4'd0) begin
led = BASE_LED_SEQUENCE;
end
else begin
led = led << 1;
end
end
endmodule
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
reg led;
reg circle_count;
...
always@(circle_count or led) begin
if (circle_count == 4'd0) begin
led = BASE_LED_SEQUENCE;
end
else begin
led = led << 1;
end
end
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'b1)
begin
count <= 28'd0;
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks for pointing it out .. I agree with ak6dn. My bad. His code should work. Try it out.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- 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?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- 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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- 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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- 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.
Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page