- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
As a simple demo, I wrote verilog code for an updown counter on the DE10-Lite board using buttons, LEDs and switches. KEY[1] is used as clock and KEY[0] is used as synchronous reset.
The counter has a bug when programmed into the DE10. When the three LSB are '111' the next count (up) will always be '001' instead of '000'. We've tried various changes to the updown counter code and the problem remains. It appears to be some kind of clock skew problem. It's not a debounce problem because it only happens when the LSB are '111'. Otherwise, it always counts correctly. It works correctly counting down. Is there a good way to fix this so a button can reliably be used as a clock for simple finite state machines? The problem can be fixed using the 50 MHz clock and generating an enable signal based on a rising edge of KEY[1], but I'm looking for directly clocking a FSM. Thanks. Here is the verilog: //======================================================= // This code is generated by Terasic System Builder //======================================================= module updown( //////////// SEG7 ////////// output [7:0] HEX0, output [7:0] HEX1, output [7:0] HEX2, output [7:0] HEX3, output [7:0] HEX4, output [7:0] HEX5, //////////// KEY ////////// input [1:0] KEY, //////////// LED ////////// output [9:0] LEDR, //////////// SW ////////// input [0:0] SW ); //======================================================= // REG/WIRE declarations //======================================================= wire Clock, Reset_n, Updown; reg [15:0] Count; reg [15:0] next_Count; //======================================================= // Structural coding //======================================================= assign Clock = KEY[1]; assign Reset_n = KEY[0]; assign Updown = SW[0]; assign LEDR = Count[9:0]; assign HEX0 = 8'b11111111; assign HEX1 = 8'b11111111; assign HEX2 = 8'b11111111; assign HEX3 = 8'b11111111; assign HEX4 = 8'b11111111; assign HEX5 = 8'b11111111; always @(Updown, Reset_n, Count) begin if (Reset_n == 0) next_Count <= 0; else if (Updown) next_Count <= Count + 1; // if Updown, increment Count else next_Count <= Count - 1; // else decrement Count end always @(posedge Clock) // flip-flops Count <= next_Count; // count on rising clock edge endmodule- Tags:
- de10-lite
Link Copied
2 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
If you haven't done so, set a clock constraint like:
create_clock -name clk -period 1000 [ get_ports KEY[0] ] ; Constraining as a 1 MHz clock; TimeQuest can't (couldn't?) handle very low frequency clocks Then run TimeQuest and see if the meets timing of if you have failing paths.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Your code:always @(Updown, Reset_n, Count)
begin
if (Reset_n == 0)
next_Count <= 0;
else if (Updown)
next_Count <= Count + 1; // if Updown, increment Count
else
next_Count <= Count - 1; // else decrement Count
end
always @(posedge Clock) // flip-flops
Count <= next_Count; // count on rising clock edge
reg UpDownSync1, UpDownSync2;
always @(posedge Clock)
begin
UpDownSync1 <= UpDown;
UpDownSync2 <= UpDownSync1;
end
always @(posedge Clock or negedge Reset_n)
begin
if (Reset_n == 0)
Count <= 0;
else if (UpDownSync2)
Count <= Count + 1; // if Updown, increment Count
else
Count <= Count - 1; // else decrement Count
end
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