I'm actually trying for 3 days to make my code works. I have an dev board with multiplexed 7-seg display - it's working. The problem is, when I'm trying to increment a variable. I written code below:
assign buttons = debouncedL | debouncedR;
always #(posedge buttons or negedge RES) begin
if(~RES) number <= 0;
else if(debouncedL) number <= (number + 10);
else if(debouncedR) number <= (number + 1);
end
And it's not working. When I'm pressing R button, variable is incremented by 1, but when I'm pressing L nothing happens. After changing positions of both else if, L button still not work and displayed number is toggling between 0000 and 0001 after pressing R button. It might be newbie question, but I can't find solution in book and on Internet. Can you help me? Thank you in advance.
Your design is asynchronous, you have metastability on buttons signal.
In synchronous design (and all FPGA design should be synchronous) only clock can be used for always #posedge() process. In your design you are using button signal as a clock.
To detect raising edge on button you have to save the old state of button signal and compare it to current state like this :
always #(posedge clock or posedge rst) begin
// detect rising edge
if (button_old != button && button == 1'b1)
button_raise <= 1'b1
button_old <= button;
// increment number
if(button_raise == 1b'1)
begin
if(~RES) number <= 0;
else if(debouncedL) number <= (number + 10);
else if(debouncedR) number <= (number + 1);
end
end
Related
I wrote the program for blink 8 raw LEDs and code has not any errors and it is properly loaded. But blinking LEDs is not happen properly.
I checked pin planner and it was correct and clock I used is 50MHz. I am using the DE10 lite board.
module LED_blink(clk,led);
input clk;
output reg[7:0] led;
reg[31:0] count = 0;
always #(posedge clk)
begin
count <= count + 1;
led <= (count<50000000) ? 8'b11111111 : 0;
count <= (count<50000000) ? count : 0;
end
endmodule
There are no error messages but it is not working the way I assumed.
You should get the habit of simulating your code with a testbench before running it on an FPGA. But in this case even a simple Rubber Duck Debugging shows the errors.
When you execute count<=(count<50000000)?count:0; you override the previous count<=count+1;, thus the count will never increment.
This can be easily fixed by changing the 2 lines to:
count<=(count<50000000)?count+1:0;
The second problem is that led will be 0 only for one clock cycle (when count is equal to 50000000), practically you won't see any blinking.
This can be easily fixed by changing the line to:
led<=(count<25000000)?8'b11111111:0;
The problem is not syntactical, but there are some other problems in your code.
The first is the way you use nonblocking assignments (<=). In your code, all assignments will only be evaluated at the end of the clock cycle. Thus, the first line of your always block (count<=count+1) does not affect the last line of your always block (count<=(count<50000000)?count:0). Also, only the last line will be evaluated.
The second problem is that you don't have a reset state for count. The value is never explicitly set to 0, and you can therefore not know it's state.
If you fix these problems, there will be a third problem in your logic. You describe that your variable led should be 8'b11111111 if count is smaller than 50000000. However, as soon as the counter exceeds this value, you reset it to 0. In other words, your counter would always be smaller than 50000000, and led would never be set to 0.
I wrote down a small fix:
module LED_blink(clk,led);
input clk;
output reg[7:0] led;
reg[31:0]count=0;
always #(posedge clk or negedge rst_n)
begin
if (~rst_n) begin
count <= 32'b0;
led <= 8'b0;
end
else begin
count <= (count < 100000000) ? count + 1 : 0;
led <= (count < 50000000) ? 8'b11111111 : 0;
end
end
endmodule
Alternatively, you could write in your always block:
count <= (count < 50000000) ? count + 1 : 0;
led <= (count == 50000000) ? ~led : led;
I'm trying to learn verilog having done C++ before. As a learning exercise I'm trying to flash turn an LED on after seeing 10 button presses. I also have an additional reset button that starts the 10 count again. What ever I try I can't get it to compile. Can anyone point me in the right direction?
My code is:
module led_counter (button, nreset, led);
input button, nreset;
output led;
reg counter[4:0]; // to hold the current count
always # (negedge nreset) begin
counter <= 0; // Just reset counter
end
always # (negedge button) begin
if (counter == 10) begin // see if the button has been pressed 10 times
led_state <= 1; // turn the led on
end
else begin
led_state <= 0; // the led is off
counter <= counter + 1;
end
end
assign led = led_state;
endmodule
led_state is not declared, it should be a reg.
To have something more concise I would also regroup the two processes into one. It would make it look like a synchronous process with asynchronous reset, i.e. triggered by a clock and reseted on falling edge of a reset.
always # (posedge button or negedge nreset) begin
if(~nreset) //reset counter when nreset is low
counter <= 0;
else begin //do something on posedge of button
//Do something//
end //end process
It would also be more likely to be synthesized.
I'm an FPGA beginner and have trouble understanding how VGA control
signals and VGA interact, and how to correctly generate VGA control
signals (with Verilog) for more complicated specifications:
Seemingly, the low portions in horizontal- and vertical- sync signals
correspond to transitioning from one row to the next, and transitioning
from the bottom-right corner to the upper-left corner, respectively. But
is the VGA "controlled" by those low signals? Do those low signals
"tell" the VGA to switch to next row or jump back to the starting point?
Are the back porch and front porch there to satisfy setup time and
hold time? Are the durations of porches given in VGA timing table only
required minima (i.e. can I set the porches to be much longer than the
given values in the timing table?)
This is what confuses me the most: From the two continuous
horizontal- and vertical- sync signals, how on earth does the VGA know
(or do I know) exactly which point on screen it is displaying? If timing
is the only factor, does that mean I must pay a lot of attention to
match RPG control signals and h-sync and v-sync signals perfectly? If
the answer is yes, then I have even more problems which I can only
describe using my assignment as an example:
In this assignment we use a built-in 50MHz clock of an FPGA (Spartan starter board) and the pixels of the VGA is specified to be 800x600. The framerate is specified to be 72Hz.
The VGA timing table gives the following sync signal structures:
h-sync:
| 0---back-porch(104)---103 | 104---display(800)---903 | 904---front-porch(16)---919 | 920__pulse width(120)__1039 |
v-sync:
| 0---back-porch(23)---22 | 23---display(600)---622 | 623---front-porch(37)---659 | 660__pulse width(6)__665 |
This seems to mean that for each pixel in a row on screen I spend 1
clock cycle (20ns) on it. However, for many complicated cases, I would
want to control the color of a pixel depending on its location on screen
and perhaps a lot of additional conditions such as the relation of
current position with another location, certain states, etc. Now, if the location of the pixel depends on horizontal and vertical pixel counters, and the color depends further on the location, how can I match them in time? Also, what if my logic has to spend more than 20ns to decide the color of a pixel? Will that completely crash the image on the VGA screen?
Actually I've somehow completed my assignment, but I find my code messy
and I totally have no idea why it worked:
For example, a portion of the assignment required us to show a star that
changes its color every 0.5sec. My implementation looks like:
//----------------pixel counters----------------
always#(posedge CLK or posedge RESET) begin
if(RESET) h_count <= 11'd 0;
else if (h_count >= 11'd 1039) h_count <= 11'd 0;
else h_count <= h_count + 11'd 1;
end
always#(posedge CLK or posedge RESET) begin
if(RESET) v_count <= 10'd 0;
else if (v_count >= 10'd 665) v_count <= 10'd 0;
else if (h_count == 11'd 1039) v_count <= v_count + 10'd 1;
else v_count <= v_count;
end
//----------------h- and v- sync----------------
always#(posedge CLK or posedge RESET) begin
if(RESET) VGA_HSYNC <= 1'b 0;
else VGA_HSYNC <= (h_count >= 11'd 0) & (h_count <= 11'd 919);
end
always#(posedge CLK or posedge RESET) begin
if(RESET) VGA_VSYNC <= 1'b 0;
else VGA_VSYNC <= (v_count >= 10'd 0) & (v_count <= 10'd 659);
end
//----------------a frame counter and a flag----------------
always#(posedge CLK or posedge RESET) begin
if(RESET) frame_count <= 6'd 0;
else if (frame_count >= 6'd 49) frame_count <= 6'd 0;
else if(v_count == 10'd 665) frame_count <= frame_count + 6'd 1;
else frame_count <= frame_count;
end
always#(posedge CLK or posedge RESET) begin
if(RESET) color_flag <= 1'd 0;
else if (frame_count == 6'd 49) color_flag <= ~(color_flag);
else color_flag <= color_flag;
end
//----------------RGB control----------------
always#(posedge CLK or posedge RESET) begin
if(RESET) VGA_RGB <= 3'b 000;
else if(display) begin //display is high when counters in valid range
casez({tree, star, snow}) //these are outputs from submodules that decides the "shapes" of objects on screen
3'b ??1: VGA_RGB <= 3'b 111; //white snow
3'b ?10: VGA_RGB <= (color_flag) ? (3'b 110) : (3'b 111);
//switching between yellow and white
3'b 100: VGA_RGB <= 3'b 010; //green tree
default: VGA_RGB <= 3'b 001; //blue background
endcase
end
else VGA_RGB <= 3'b 000; //for transitions
end
It seems to me that my h_count and v_count directly decides my VGA_HSYNC and VGA_VSYNC. But my VGA_RGB depends at least on color_flag, which further depends on frame_count, which depends on h_count and v_count. Shouldn't that cause delay of a few clock cycles? The code was synthesizable and did produced what I wanted to display. But how on earth did my VGA_RGB sync with VGA_HSYNC and VGA_VSYNC in time??? Am I overthinking this issue? Or was I just lucky? What did I miss?
Most of your questions can be explained by the fact that VGA is an analog standard which was originally designed to run on analog devices. The h-sync and v-sync pulses simply trigger their respective deflection coils back to their start positions while the front and back porches account for the fact that the beam starts and ends outside the visible portion of the screen.
With respect to accuracy, it's better than it used to be: sending a badly timed VGA signal to an analog monitor in years-gone-by could actually damage it. That's all changed now with LCDs etc whose drive circuits are able to detect and display a wide range of resolutions at arbitrary refresh rates. In my experience though the amount of leeway you have is smaller than you'd think and is very dependent on the make and model of the display device...many of them even list slightly different timings in their user manuals! If you want to be sure that your circuit will work on the equipment that your tester runs it on then you should stick to one of the "official" resolutions as accurately as you can.
As far as per-pixel timing goes yes, an 800x600x72Hz signal needs a 50MHz clock and you thus have 20nS in which to fetch your pixel data (that said I'm not 100% sure your sync and porch timings are correct, they're different to the ones at VGA Timings which I've used successfully myself in the past). If 20nS isn't enough then you'll need to use multiple circuits e.g. one for odd pixels and another for evens. Alternatively you can implement pipeline stages, e.g. for the pixel you output at cycle X you read its value from ROM at cycle X-1 and calculate the address to read at cycle X-2. Another trick I've used in the past is to double-buffer the display with 2 lines of RAM i.e. on any given line you are drawing directly from one buffer whilst simultaneously writing to the next; this gives you more time to render each line but typically adds the additional complexity of separate clock domains between rendering and display.
I have two push buttons (using Basys2 rev C board) and I want to increment a register (counter) when I push one of them. I used this:
always #( posedge pb1 or posedge pb2 )
begin
if(count2==9) count2=0;
else count2= count2+1;
end
but when I implemented it (using ISE 9.2), an error appeared:
The logic for does not match a known FF or Latch template.
However when I tried it using just one event (posedge pb1), it worked.
So why did that happen?
The error message means that the target technology (I am guessing in your case is an FPGA or CPLD) doesn't have the physical circuit required to implement the functionality you described with this behavioural code.
One of the important things to consider when writing synthesizable RTL (verilog or VHDL) is you are describing an electronic circuit. You should understand what real world logic you are trying implement (combinatorial logic, registers) before you start coding. In this case, you are describing a register with two separate clocks--something that doesn't exist in any FPGA or ASIC library I've seen. If you can't figure out what you're trying to implement, the chances are the synthesizer can't either.
In other words, not everything you can describe in Verilog can be translated into an actual circuit.
The solution depends on what you want to do - if you require that the counter increments on both pb1 and pb2 rising edges, irrespective of the other pbs state, I would look into solutions which use another (independent) clock (clk in the code below) - something like this:
reg old_pb1, old_pb2;
always # (posedge clk) begin
if (old_pb1 == 0 && pb1 == 1)
if(count2==9) count2 = 0;
else count2 <= count2 + 1;
if (old_pb2 == 0 && pb2 == 1)
if(count2==9) count2 = 0;
else count2 <= count2 + 1;
old_pb1 <= pb1;
old_pb2 <= pb2;
end
If you have no other clock, you could also combine both input signals like in this example:
wire pbs = pb1 | pb2;
always # (pbs) begin
if(count2==9) count2 <= 0;
else count2 <= count2 + 1;
end
Another option would be to use independent counters for the inputs:
always # (posedge pb1)
begin
if(count_pb1==9) count_pb1 <= 0;
else count_pb1 <= count_pb1 + 1;
end
always # (posedge pb2)
begin
if(count_pb2==9) count_pb2 <= 0;
else count_pb2 <= count_pb2 + 1;
end
wire [4:0] count2 = count_pb1 + count_pb2;
All options have their own restrictions, limitations and drawbacks, therefore it depends heavily on what you want to do. Corner cases matter.
Note that I put these example codes together without testing them - please let me know in a comment if you are having trouble with any of them and I look into it.
I have the following button press logic in my code. I have tried debouncing it using a wait delay, but the compiler will not allow this. I have four push buttons on my FPGA, which the "key" array below reflects:
process(clock)
begin
if rising_edge(clock) then
if(key(3)/='1' or key(2)/='1' or key(1)/='1' or key(0)/='1') then --MY ATTEMPT AT DEBOUNCING
wait for 200 ns; ----MY ATTEMPT AT DEBOUNCING
if (key(3)='1' and key(2)='1' and key(1)='0' and last_key_state="1111" and key(0)='1') then
...
elsif (key(3)='1' and key(2)='1' and key(1)='1' and key(0)='0' and last_key_state="1111") then
...
elsif (key(3)='0' and key(2)='1' and key(1)='1' and key(0)='1' and last_key_state="1111") then
...
elsif (key(3)='1' and key(2)='0' and key(1)='1' and key(0)='1' and last_key_state="1111") then
...
end if;
last_key_state<=key;
end if;
end if;
end process;
Can anyone give some really simple example code showing how I could debounce a setup like the one I have above?
Well if you think about how you would do this with real electronics you would probably use a capacitor.. which has a charging time. Same idea applies here, just figure out the time your switch is bouncing (usually a function of clock speed) and then actually set the register.
Simple Example With a 4-Bit Shift Register
So you'd put this between your switch and any other logic blocks
process
begin
if rising_edge(clock) then --You're clock
SHIFT_PB(2 Downto 0) <= SHIFT_PB(3 Downto 1); --Shifting each cycle
SHIFT_PB(3) <= NOT PB; --PB is the pre-bounced signal
If SHIFT_PB(3 Downto 0)="0000" THEN --once the bounce has settled set the debounced value
PB_DEBOUNCED <= '1';
ELSE
PB_DEBOUNCED <= '0';
End if;
end process;
Its basically delaying your signal 4 clock cycles (what you were trying to do with the wait).
Others have shown the way with counters... you also need to synchronise the signal to the clock before feeding it to the counter, otherwise occasionally, the signal will get to different parts of the counter at different times, and the counter will count incorrectly.
Whether this matters depends on the application - if correct operation is important, it is important to synchronise correctly!
You get the error because of wait ... wait is not synthesizeable.
I would do it with a simple counter. So you can use the same code for different clock speeds by adjusting the counter.
-- adjust the counter to you special needs
-- depending on how good your buttons are hardware debounced
-- you can easily think in ms
signal counter : std_logic_vector(7 DOWNTO 0) := "10000000";
process
begin
if rising_edge(clock) then --You're clock
if(key(3) = '0') or (key(2) = '0') or (key(1) = '0') or (key(0) = '0') then
start_debouncing <= '1';
key_vector_out <= key(3) & key(2) & key(1) & key(0);
end if;
if(start_debouncing = '1') then
key_vector_out <= "0000";
counter <= std_logic_vector(unsigned(counter) - 1);
end if;
if(counter = "00000000") then
counter <= "10000000";
start_debouncing <= '0';
end if;
end process;
Your code can produce another problem.
What will happen if you button is released so your input is .. key = "0000" .. right you never get you output. Perhaps it will work 99 out of 100 times but you can get an really hard to find error.