I am working with an DE2-70 board and I am trying to use some of it's buttons as inputs. The buttons are activated at 0, and I need to check if two buttons in particular are being pressend separatly, in order to increase/decrease a number.
I tried doing the following, where iKEY are the buttons and position is the number i am trying to modify:
reg [4:0] position;
position = 5'b0;
output wire enable = !(iKEY[3] && iKEY[2]);
always #(posedge enable) begin
if(iKEY[3] == 0)
position = position + 5'b00001;
if(iKEY[2] == 0)
position = position - 5'b00001;
end
I tried several differences of this implementation, such as tring to change the ifs conditions or changing the logic function when setting the enable signal, but I always get stuck in some problem.
I am new to hardware logic, so maybe I am thinking in it in the wrong way
Edit:
If both buttons are pressed at the same time I expect the hardware to neither increment nor decrement the number
Summary of the chat discussion:
Missing key background information:
iKEY is 4-bit active low input. Input source is from physical buttons,
A operation should happen on a one-cold (inverse of one-hot) iKEY,
There are clocks available, such as the 50MHz iCLK_50
Solution for operations executing unexpectedly:
Move all the all the iKEY into one always block and decode the operation with a case statement. Ex:
case(iKEY[3:0]) // one-cold, full-case
4'b1110: /* operation 0 */
4'b1101: /* operation 1 */
4'b1011: /* operation 2 */
4'b0111: /* operation 3 */
default: /* default behavior */
endcase
If using iKEY as a clocking event, then perform a bit-wise NAND operation: wire enable = ~&iKEY[3:0];
If using using the iCLK_50 clock, then add a reg to watch for button release to insure one operation per button press. Ex:
if (allow_op) begin // value from past clock event
/* case statement defined above */
end
// value for next clock event
allow_op = &iKEY[4:0]; // bit-wise AND
You probably should be looking for a CHANGE in the button press. The code below looks for a falling edge on the iKEY[3] input. Otherwise, as soon as IKEY is pushed, that counter will go NUTS and start incrementing or decrementing like crazy.
reg iKEY3_LAST;
output wire enable = !(iKEY[3] && iKEY[2]);
always #(posedge enable) begin
iKEY3_LAST = iKEY[3];
if(iKEY[3] == 0 && iKEY3_LAST == 1)
position = position + 5'b00001;
First, you have a combinational loop on signal position. When enable=1 position will change and then change again and again. Simulations will usually get stuck in this case, as for the real world, it depends on how your tools implemented it; I guess most of them will just break the loop. Look for any errors or warnings in the logs.
You want position to be a flop, so it will not be a loop, but will increment by 1 every clock cycle:
always #(posedge clock or posedge reset)
if (reset)
position <= 5'h0;
else
position <= position + iKEY[3] - iKey[2];
Now you must take into account that buttons introduce the bouncing effect. Look here for more information. You'll probably want to implement the Digital Switch Debouncing.
And as Russell wrote, you might consider changing the position only on falling edge of the buttons, otherwise the counter will overflow/underflow like crazy.
Related
I have some variables in an initial block
initial
begin
i = 32'b0;
j = 32'b1;
end
I want to initialize them with initial values like this every time I press a pushbutton
always #(posedge btn)
begin
i = 32'b0;
j = 32'b1;
end
Doing it like this gives the error "can't resolve multiple constant driver" and I know why it happens but, is there another way around??
It sounds like you are creating synthesizable code (based on your need to press a button). Initial blocks do not synthesize to logic, they are only used for simulation. Typically you use a reset signal to set initial values.
Also you generally want to keep the logic for any one signal in a single block, instead of separating it into separate blocks. (again, this is for synthesizeable code, for simulation this is not important)
Finally, You generally do not want to use outside async signals to clock some logic (unless you know what you are doing). You would instead code something like:
//---- detect rising edge of btn ----
reg btn_prev;
wire rising_edge_btn;
always #(posedge clk)
btn_prev <= btn;
assign rising_edge_btn = ~btn_prev & btn;
// ---- i and j logic --------------
always #(posedge clk) begin
if( rst || rising_edge_btn) begin
i <= 0;
j <= 1;
end
else
//some other logic here
end
end
the code above uses a synchronous reset signal "rst". You can also find designs with an asynchronous reset. It would be good practice to also synchronize your outside async btn signal with with 2 flip flops to avoid metastability.
I am trying to use the 8 switches on my basys2 board to control the frequency of a square wave, yet I'm having trouble with the input part of it, as I do not know how to divide the clock using the binary value of the register that I have collected the states of the switches in.
I know that I need to divide 25000000/[input value] in order to get the correct value for the counter. My question is:
how can I divide 25000000 by the register which has the switch states stored inside of it such, as input [7:0] SW?
If you can assume your input is always a power of two, you can use shifting to the right. But if you want the full 255 possible resolutions, you need to implement a divider.
Some synthesis tools just synthesize a divider when you simply write 25000000/inputValue. For some others, you may have to do it yourself.
Alternatively, if you don't want to waste time for dividing, you can pre-calculate the values beforehand and use a counter:
case (inputValue)
8'b0000_00010: counterMax = 25000000/2 ; //Where 25000000/2 can be calculated at compile time or by you
8'b0000_00011: counterMax = 25000000/3 ; //Where 25000000/3 can be calculated at compile time or by you
...
endcase
and then just count to the counterMax:
always #(posedge clock)
begin
counter <= counter + 1;
if(counter == counterMax) begin
out <= ~out;
counter <= 0;
end
end
Instead of dividing by input, can you just increment your counter by SW each clock cycle? Then if SW is for example, '15', then your period is reduced by 15x, but you avoid an expensive division circuit.
I Want to Design a Verilog code for Interfacing 16*2 LCD. As in LCD's to give "command" or "data" we have to give LCD's Enable pin a "High to low Pulse " pulse that means
**E=1;
Delay();//Must be 450ns wide delay
E=0;**
This the place where I confuse I means in Verilog for synthesis # are not allowed so how can I give delay here I attached my code below. It must be noted that I try give delay in my code but I think delay not work so please help me to get rid of this delay problem......
///////////////////////////////////////////////////////////////////////////////////
////////////////////LCD Interfacing with Xilinx FPGA///////////////////////////////
////////////////////Important code for 16*2/1 LCDs/////////////////////////////////
//////////////////Coder-Shrikant Vaishnav(M.Tech VLSI)/////////////////////////////
///////////////////////////////////////////////////////////////////////////////////
module lcd_fpgashri(output reg [7:0]data,output reg enb,output reg rs,output reg rw ,input CLK);
reg [15:0]hold;
reg [13:0]count=0;
//Code Starts from here like C's Main......
always#(posedge CLK)
begin
count=count+1; //For Delay
//For LCD Initialization
lcd_cmd(8'b00111000);
lcd_cmd(8'b00000001);
lcd_cmd(8'b00000110);
lcd_cmd(8'b00001100);
//This is a String "SHRI" that I want to display
lcd_data(8'b01010011);//S
lcd_data(8'b01001000);//H
lcd_data(8'b01010010);//R
lcd_data(8'b01001001);//I
end
//Task For Command
task lcd_cmd(input reg [7:0]value);
begin
data=value;
rs=1'b0;
rw=1'b0;
enb=1'b1; //sending high to low pulse
hold=count[13]; //This is the place where I try to design delay
enb=1'b0;
end
endtask
//Task for Data
task lcd_data(input reg [7:0]value1);
begin
data=value1;
rs=1'b1;
rw=1'b0;
enb=1'b1; //sending high to low pulse
hold=count[13]; //This is the place where I try to design delay
enb=1'b0;
end
endtask
endmodule
You seem to be stuck in a software programming mindset based on your code, you're going to have to change things around quite a bit if you want to actually describe a controller in HDL.
Unfortunately for you there is no way to just insert an arbitrary delay into a 'routine' like you have written there.
When you write a software program, it is perfectly reasonable to write a program like
doA();
doB();
doC();
Where each line executes one at a time in a sequential fashion. HDL does not work in this way. You need to not think in terms of tasks, and start thinking in terms of clocks and state machines.
Remember that when you have an always block, the entire block executes in parallel on every clock cycle. When you have a statement like this in an always block:
lcd_cmd(8'b00111000);
lcd_cmd(8'b00000001);
lcd_cmd(8'b00000110);
lcd_cmd(8'b00001100);
This does you no good, because all four of these execute simultaneously on positive edge of the clock, and not in a sequential fashion. What you need to do is to create a state machine, such that it advances and performs one action during a clock period.
If I were to try to replicate those four lcd_cmd's in a sequential manner, it might look something like this.
always #(posedge clk)
case(state_f)
`RESET: begin
state_f <= `INIT_STEP_1;
data = 8'b00111000;
end
`INIT_STEP_1: begin
state_f <= `INIT_STEP_2;
data = 8'b00000001;
end
`INIT_STEP_2: begin
state_f <= `INIT_STEP_3;
data = 8'b00000110;
end
`INIT_STEP_3: begin
state_f <= `INIT_STEP_4;
data =8'b00111000;
end
`INIT_STEP_4: begin
state_f <= ???; //go to some new state
data = 8'b00000110;
end
endcase
end
Now with this code you are advancing through four states in four clock cycles, so you can start to see how you might handle writing a sequence of events that advances on each clock cycle.
This answer doesn't get you all of the way, as there is no 'delay' in between these as you wanted. But you could imagine having a state machine where after setting the data you move into a DELAY state, where you could set a counter which counts down enough clock cycles you need to meet your timing requirements before moving into the next state.
The best way to introduce delay is to use a counter as Tim has mentioned.
Find out how many clock cycles you need to wait to obtain the required delay (here 450ns) w.r.t your clock period.
Lets take the number of clock cycles calculated is count. In that case the following piece of code can get you the required delay. You may however need to modify the logic for your purpose.
always # (posedge clk) begin
if (N == count) begin
N <= 0;
E = ~E;
end else begin
N <= N +1;
end
end
Be sure to initialize N and E to zero.
Check the clock frequency of your FPGA board and initialize a counter accordingly. For example, if you want a delay of 1 second on an FPGA board with 50MHz clock frequency, you will have to write a code for a counter that counts from 0 to 49999999. Use the terminalCLK as clk for your design. Delayed clock input will put a delay to your design. The psuedo code for that will be:
module counter(count,terminalCLK,clk)
parameter n = 26, N = 50000000;
input clk;
output reg [n-1:0] count;
output reg terminalCLK;
always#(posedge clk)
begin
count <= count + 1;
if (count <= N/2)
terminalCLK <= ~terminalCLk;
if (count == N)
terminalCLK <= ~terminalCLk;
end
Below is a simple 3-bit counter.
When reset(rst) is 0, counter value is "000", else it increments by 1 for rising edge of each clock.
LIBRARY ieee;
USE ieee.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;
use IEEE.numeric_std.all;
---------------------------------------------
ENTITY counter IS
PORT (clk : IN STD_LOGIC;
rst : in std_logic;
digit : out std_logic_vector (2 downto 0)
);
END counter;
---------------------------------------------
ARCHITECTURE counter OF counter IS
BEGIN
count: PROCESS(clk,rst)
VARIABLE temp : std_logic_vector(2 downto 0);
BEGIN
IF (clk'EVENT AND clk='1') THEN
if (rst = '1') then
temp := temp + "001";
else
temp := "000";
END IF;
END IF;
digit <= temp;
END PROCESS count;
END counter;
Below is the simulation result I got :
In the result, output is correct. But there is an one clock delay between the time rst = 1 and output='001'. ie counter doesn't increment instantaneously when rst = '1'.
As per my understanding, whenever a change in clk or rst happens, process is executed. So when rst changes from low to high, an event occurs. Process checks if rising edge of clk, YES. Then check if rst = 1, YES. So normally counter has to increment in that clk itself. But it doesn't.
Questions:
Why one clock period delay between reset = 1 and output = 001?
And what is wrong in my understanding?
The most likely cause in that "rst" is generated by a clocked process, clocked by the same "clk" signal.
So "rst" occurs one delta cycle after "clk". When "rst" changes it will wake the process up, but "clk'event" was on the previous delta cycle, therefore the "if" statement will not execute.
On the next clock edge, rst = 1 so the counter works as expected.
Three minor points:
it would be worth naming the reset signal rst_n to make it clearer that it is an
active-low reset!
rst really doesn't need to be in the sensitivity list
there is no need for parentheses around the boolean expressions
(Disclaimer: It's been long time since I programmed in VHDL, so this only answers to generic logic design.)
Anyway, one can't expect the result of addition to be ready immediately when a process is triggered. The point is, that calculating even the first bit of 000 + 001 is affected by the propagation delay equivalent to one xor operation. The second bit is calculated from the first bit's carry (if both bits were 1) and xor operation of the second bits. And so on.
If one would probe the 'temp' variable asynchronously, one would see something like this:
^ ________________
result_bit_0 __________|
0123456789
_____________
result_bit_1 ^ |____________
0123456789
____________ _____
result_bit_2 ^ |_| |________
0123456789abcde
________
clock: ________| |______|
The figure tries to illustrate in more detail the waveforms of a generic add operation.
At time 0 the process of adding is started.
After a small delay '2' the first bit stabilizes to 1.
At time '5' the second bit stabilizes to 0 and at time '9' the third bit stabilizes to 0.
But also it's quite common, that as in result_bit_2, the output toggles between various states.
It's the total / maximum delay of each temporary variable to take to stabilize, that determines the minimum clock period. At this case the time instant 'e' is that one, where we have decided that the result of counter increment is available.
Still, from the perspective result (which is a vector), everything happens instantly at the next clock cycle.
the "issue" is in the way you have described your "rst".
The way you did it would result in a "synchronous" reset, i.e. the reset would take effect only after a rising edge of the clock.
In general this is just a matter of coding style/preferences.
I usually prefer asynchronous reset (with maybe a reset synchronizer at top-level to avoid meta-stability when releasing the reset), but there is nothing wrong in adopting a synchronous reset approach.
In case of an asynchronous reset, you would need to change your code to something like this:
PROCESS (clk, rst_n) BEGIN
IF rst_n = '0' THEN
...
ELSIF rising_edge(clk) THEN
...
END IF;
END PROCESS;
I'm trying to learn Verilog using Pong P. Chu's book. I have a question about how an always block is evaluated and implemented. A style in the authors code is confusing me.
In this example he codes an FSM with two output registers 'y1' and 'y2'. The part I'm confused about is in the NEXT STATE LOGIC AND OUTPUT LOGIC always block, where after the begin statement and always#* y1 and y0 are set to 0. I seems that regardless of state, y1 and y0 will toggle to 0 on every clock cycle and signal change. According to state diagram in the book reg y1 should be equal to 1 while in state 0 or 1.
So does y1 toggle to 0 every clock cycle then back to what ever its value at the present state?? I assume that's not the case and that I'm just confused about how the block is evaluated. Can someone explain what that part of the code is doing. I'm lost. Thanks
module fsm_eg_2_seg
(
input wire clk, reset, a, b,
output reg y0, y1
);
//STATE DECLARATION
localparam [1:0] s0 =2'b00,
s1=2'b01,
s2=2'b10;
// SIGNAL DECLARATION
reg [1:0] state_reg, state_next ;
//STATE REGISTER
always #(posedge clk, posedge reset)
if (reset)
state_reg <= s0;
else
state_reg <= state_next;
//NEXT STATE LOGIC AND OUTPUT LOGIC
always #*
begin
state_next = state_reg; // default next state: the same
y1 = 1'b0; // default output: 0
y0 = 1'b0; // default output: 0
case (state_reg)
s0: begin
y1 = 1'b1;
if (a)
if(b)
begin
state_next = s2;
y0 = 1'b1;
end
else
state_next = s1;
end
s1: begin
y1 = 1'b1;
if (a)
state_next = s0;
end
s2: state_next = s0;
default: state_next = s0;
endcase
end
endmodule
The expression
always #* begin : name_of_my_combinational_logic_block
// code
end
describes combinational logic. Typically the clk and rst signals are not read from inside of this type of always block, so they don't appear in the sensitivity list like wisemonkey says. It is best practice to use #* for the sensitivity lists of combinational logic so that you don't forget to include a signal, which would infer some memory and it would no longer be combinational logic.
Inside a combinational logic block, you should use what are called blocking assignments. These look like regular variable assignments in most programming languages and use a single equals. The value that you assign to a variable (a reg) inside of a combinational logic block happens immediately with respect to other statements and expressions in that same combinational logic block, but does not propagate outside of this combinational logic block until you reach the end. The always block must reach the end before any changes are seen outside of the block. Paul S is right that you want to always assign something to your variables whenever the always block is executed, otherwise you will infer memory.
Have to say I disagree with aqua. What he (and wisemonkey) says about #* is right, but the rest is wrong.
Those two lines have nothing to do with an idle state. Those statements are there as good coding practise. They ensure that those two outputs are always assigned to when that always block is evaluated. Let's see why this is important:
Imagine that those two statements aren't there.
Next suppose that state_reg = S0, and a = b = 0
As we evaluate the always block, we enter the case statement, s0 half, and assign 1 to y1
a is zero so we don't enter the if statement, and we drop out of the case, and end the block
At the end of the block y1 == 1 and y0 == ... erm, hang on what does y0 get? I guess it has to keep it's old value. It didn't get a new one.
That means it's possible y0 has to remember it's value from one cycle to the next. That would mean it needs to have some kind of memory involved, like a register or a latch. In this case it would be a latch as it's written in a style that sometimes drives the output and sometimes holds it.
...but we don't want that. y1 and y0 were meant to be simple wires. Therefore we must make sure each of them are always assigned to, no matter what the state or inputs are. We could do that by having assignments in all the branches of the logic, but that becomes a lot of work. Alternatively we can have a default assignment which we later override if necessary.
The reason these statements don't introduce y1 going to 0 in s0 or s1 is because everything that happens inside an always block happens with no time passing. No time passes between the 0 being assigned at the top and the 1 in s0 or s1. All that's visible is the final state.
You'll note the code does exactly the same thing with the state variable. It has a default assignment that the next state is the current state, and then overrides that it the correct conditions are met.
Nice clean state machine. Nothing wrong with it.
This is a poor example of an FSM. I'm not surprised that you are confused. The way I understand it, an always block is scheduled to run only when the inputs in its sensitivity list change.
So for the first always block, it is scheduled to run every clock transition from 0 to 1, and reset is asynchronous.
The second always block has the #* notation, which basically creates a sensitivity list for you based on the logic within the block. Recall that only inputs matter in a sensitivity list. Therefore, this always block will be scheduled if a, b, or state_reg change.
In this example, the
y1 = 1'b0; // default output: 0
y0 = 1'b0; // default output: 0
is trying to model an IDLE state, a state where the FSM is outputting 0. If you do a quick study of how the FSM operates, you'll see that once it starts transitioning through the states, (the case statements) it won't come back out.
Ideally you want your IDLE information within a state of its own, not floating outside the state logic, but I suppose this works as a trivial example.
I don't think other answers directly and correctly addresses the question of whether y0 and y1 toggle to 0 and back on every clock cycle.
Let's say that the state machine changes from s0 to s1. In both states the end value of y1 is 1 but in re-evaluating the always block y1 is first assigned 0. This toggling may happen multiple times per clock, or not at all on a clock cycle depending how many times a, b, and state_reg change. Whether this toggling propagates to the wire attached to output y1 is simulator dependent. Port assignments are treated as continuous assignments in Verilog, which are separately running threads of execution. It is perfectly legal for the simulator to suspend execution of the always block after the y1=0 assignment is made, assign 0 to the wire attached to output y1, and resume execution of the always block afterwards. Practically speaking, it doesn't matter IF good coding styles are practiced because the value of y1 won't get latched into any registers until the next clock cycle, long after all the toggling is done and the final value of y1 is available.
In simulation the toggling happens in zero time but it also happens in real hardware when multiple inputs change. It takes special design practices to build logic that doesn't "glitch" like this.