Verilog Muliple if else not working as expected - verilog

I am using three buttons on the Altera DE0 Board.
I declare it as
input [2:0] Button;
reg [2:0] y;
parameter [2:0] S0 = 3'b000, S1 = 3'b001, S2 = 3'b010, S3 = 3'b011, S4 = 3'b100, S5 = 3'b101;
I have a nested if-else statement based on the values of the three buttons
always#(negedge (&Button))
//if(&Button == 0)
begin
if(Button == 3'b011) // Button 2 is pressed
begin
if(y == S0)
begin
y = S1;
end
end
else if(Button == 3'b101) // Button 1 is pressed
begin
if (y == S1)
begin
y = S2;
end
else if (y == S2)
begin
y = S3;
end
end
else if(Button == 3'b110) //This is the check on button 0, but this conditional statement does not work.
begin
if(y == S2)
begin
y = S3;
end
end
end
assign z = (y == S0); // z,z1,z2,z3 are LED's on the board
assign z1 = (y == S1);
assign z2 = (y == S2);
assign z3 = (y == S3);
When I use the first two buttons of the if-else statement (button == 3'b011 and button == 3'b101) labeled BUTTON2 and BUTTON1 on the DE0 board, the code works and y changes to the proper value as expected.
But when I try the third button in the if-else, Button == 3'b011, labeled BUTTON0 on the DE0, nothing happens, y does not get the expected value. I used 2 different DE0 boards and the same issue arises.
I think it has something to do with the
always#(negedge (&button))
in that the third button press is just not being detected. But when I use code like
always#(negedge button[0] or negedge button[1] or negedge button[2])
other issues arise that I haven't been able to resolve.

You need to think about what hardware you are trying to model. always #(negedge or more generally edge triggered always blocks, are used to imply flip-flops which are generally driven by a clock and reset.
Data signals can be used as clocks as you would in a Frequency Divider. However your use of a unary & a combinatorial reduction operator will result in a glitchy clock in real hardware.
I mentioned thinking about what hardware you are implying because you have this construct:
always#(negedge button[0] or negedge button[1] or negedge button[2])
Which has no equivalent in hardware.
You may find this Altera FSM example helpful. You likely what to implement edge detection from this question so you only change state once per button press.

Related

Implementing combinational lock in verilog

Problem Statement:
Design and implement a control unit for a digital lock. The digital
lock has the passcode “1010”. The code should be entered via 2 Push
Buttons: one button for entering 1’s (B1) and another for entering 0’s
(B0). Use a third push button (Reset) to add reset functionality.
Based on the entered code, glow an LED for the following outputs
LED_0 will glow indicating PASS, if the entered 4-digit binary code is correct
LED_1 will glow indicating FAIL, if the entered 4-digit binary code is incorrect
We need to make sure output is given only after all four inputs are taken.
Error: My coded module won't ever show a pass or fail output.
FSM State diagram to be implemented
module lock_FSM(
input B0,
input B1,
input Reset,
input Clk,
output reg PASS,
output reg FAIL
);
reg [3:0] present_state, next_state;
parameter S0 = 4'b0000, S1 = 4'b0001, S2 = 4'b0010, S3 = 4'b0011, S4 = 4'b0100;
parameter E1 = 4'b0101, E2 = 4'b0110, E3 = 4'b0111, E4 = 4'b1000;
//State register
always #(posedge Clk, posedge Reset)
begin
if(Reset == 1)
present_state = S0;
end
always #(posedge B0, posedge B1)
begin
present_state = next_state;
end
//Input block
always # (present_state, B0, B1)
begin
if(B0 == 0 && B1 == 0)
next_state = present_state;
else
case (present_state)
S0 : next_state = B1 ? S1 : E1;
S1 : next_state = B0 ? S2 : E2;
S2 : next_state = B1 ? S3 : E3;
S3 : next_state = B0 ? S4 : E4;
E1 : next_state = E2;
E2 : next_state = E3;
E3 : next_state = E4;
endcase
end
//Output
always#(present_state)
begin
case(present_state)
S4: begin PASS = 1; FAIL = 0; end
E4: begin PASS = 0; FAIL = 1; end
default : begin PASS = 0; FAIL = 0; end
endcase
end
endmodule
The output should have been PASS = 1 after 4th posedge in (B0 or B1) and stayed there until Reset is pressed.
I need to update the states only when one of B0 or B1 is pressed (as B1 and B0 are push buttons).
There is a problem with how you coded your state register. All assignments to a signal should be made within a single always block, not from 2 blocks. Change:
always #(posedge Clk, posedge Reset)
begin
if(Reset == 1)
present_state = S0;
end
always #(posedge B0, posedge B1)
begin
present_state = next_state;
end
to:
always #(posedge Clk, posedge Reset) begin
if (Reset == 1) begin
present_state <= S0;
end else begin
present_state <= next_state;
end
end
In a typical FSM, updating the present state should be unconditional (not dependent upon signals like B0). You should account for those conditions in your next_state logic. Also, good coding practices recommend nonblocking (<=) assignments in sequential always blocks.
Another issue is that you have no way to exit the E4 state (aside from an asynchronous reset). Perhaps you should add a case to your case statement for that. Also, since you declared only 9 of the possible 16 states, the convention is to use a default statement to handle the undefined states.

How to connect enable port to 4x1 MUX in verilog?

I am trying to implement 4x1 multiplexer in Verilog. I want to connect enable (en) as a port which input '1'(high) can ON the MUX and '0'(low) turn OFF this multiplexer.
Please suggest some modifications in my code.
Thanks in Advance.
module mux_4_to_1(
input d,c,b,a, //Inputs
input s1,s0, //Select Lines
input en, //enable
output reg y //output
);
always # (*)
begin
case (s0 | s1)
2'b00 : y <= a;
2'b01 : y <= b;
2'b10 : y <= c;
2'b11 : y <= d;
default : y <= 0;
endcase
end
endmodule
You want en to act as a global switch to turn on or off the mux, so it gets the highest priority.
always # (*)
begin
if (en) begin
case ({s0, s1}) // pay attention here
2'b00 : y = a;
2'b01 : y = b;
2'b10 : y = c;
2'b11 : y = d;
default : y = 0;
endcase
end
else begin
y = 1'b0; // your question didn't specify the expected output when OFF
end
end
Please notice I've changed case (s0 | s1) to case ({s0, s1}).
s0 | s1 returns a 1-bit wide result, while you need the concatenation of s0 and s1.
Also, I replaced all NBA <= by BA =.
And, the default branch actually couldn't happen in silicon because you've specified all possible combinations. But if you think it maybe helpful in simulation, you may leave it.

To make output LED blink in moore machine

What I'm designing is a moore machine that gives particular color for each state.
Here's a part of my code.
always #(*) begin
case (state)
S0 : led = 6'b111111;
S1 : led = 6'b010100; // have to blink //
S2 : led = 6'b100010;
S3 : led = 6'b110110;
default : led_output = 6'b000000;
endcase
end
endmodule
Before the code shown above, there are codes about assigning state corresponding to the input.
The code shown above is to determine the output value of moore machine. (Therefore the condition is *)
What I left is to assign led output value for each state.
However the condition for S1 is not only particular color but it has to 'blink' for period of 1s.
I already googled for 'blink LED' verilog code but they were little bit different from my situation.
I have no idea of coding block that is needed.
Can you give me some advice or answer for what to add to make S1 to blink?
To make it blink, you need to distinguish 2 states. So create a 1-bit signal, say sel, which toggles in S1 state, and its toggle speed as well as its duty meet your requirement in 'blink' for period of 1s. This is basically implemented with the help of a counter.
reg [3:0] cnt; // assume 4-bit long
reg sel;
// counter to determine the HIGH / LOW time of sel.
always#(posedge clk or negedge resetn)begin
if(!resetn)begin
cnt <= 4'h0;
end
// since you can exit S1 state at any time using push_button,
// make sure cnt is always ZERO when entering S1 state next time.
// also to save power when using clock gating, because this statement
// is only active for 1 cycle.
else if((state == S1) & ((push_button == 2'b01) | (push_button == 2'b10)))begin // S1 exit condition
cnt <= 4'h0;
end
else if(state == S1)begin
// sel HIGH lasts <HIGH_MAX_VAL>+1 cycles
// sel LOW lasts <LOW_MAX_VAL>+1 cycles
if(cnt == (sel ? <HIGH_MAX_VAL> : <LOW_MAX_VAL>))begin
cnt <= 4'h0;
end
else begin
cnt <= cnt + 4'h1;
end
end
end
always#(posedge clk or negedge resetn)begin
if(!resetn)begin
sel <= 1'h0;
end
else if((state == S1) & ((push_button == 2'b01) | (push_button == 2'b10)))begin
sel <= 1'h0;
end
else if(state == S1)begin
if(cnt == (sel ? <HIGH_MAX_VAL> : <LOW_MAX_VAL>))begin
sel <= ~sel;
end
end
end
Use sel to select between 2 led values.
always#(*)begin
case(state)
....
S1 : led = sel ? 6'b010100 : <ANOTHER_VALUE>;
....
endcase
end

Increment and Decrement using verilog codes in quartus

My project is to design a verilog code that gives an output on the 7segments (HEX0,HEX1,HEX2,HEX3) and output must increase when the button KEY0 is pressed on the board 1 by 1, and decrease when the button KEY1 is pressed using Altera Board (Cyclone II-EP2C35F672).
I achieve to increase 1 by 1 but when I try to decrease with the same logic, I take irrelevant outputs. Is it possible to give me a way solving the problem.
My verilog code is that:
module sevensegment (KEY,HEX0,HEX1,HEX2,HEX3);
input [3:0]KEY;
output [0:6]HEX0;
output [0:6]HEX1;
output [0:6]HEX2;
output [0:6]HEX3;
counter D1(~KEY,HEX0,HEX1,HEX2,HEX3);
endmodule
module counter(in,out,out1,out2,out3);
input [3:0]in;
output [6:0]out;
output [6:0]out1;
output [6:0]out2;
output [6:0]out3;
reg[15:0] tmp;
always #(posedge in)
begin
if(~in[0])
begin
tmp <= tmp + 1'b1;
end
else if(~in[1])
begin
tmp <= tmp - 1'b1;
end
end
displaysevensegment first_digit(tmp[3:0],out);
displaysevensegment second_digit(tmp[7:4],out1);
displaysevensegment third_digit(tmp[11:8],out2);
displaysevensegment fourth_digit(tmp[15:12],out3);
endmodule
module displaysevensegment(in,out);
// abcdefg
parameter BLANK = 7'b1111111;
parameter ZERO = 7'b0000001;
parameter ONE = 7'b1001111;
parameter TWO = 7'b0010010;
parameter THREE = 7'b0000110;
parameter FOUR = 7'b1001100;
parameter FIVE = 7'b0100100;
parameter SIX = 7'b0100000;
parameter SEVEN = 7'b0001111;
parameter EIGHT = 7'b0000000;
parameter NINE = 7'b0000100;
parameter TEN = 7'b0001000;
parameter ELEVEN = 7'b1100000;
parameter TWELVE = 7'b0110001;
parameter THIRTEEN = 7'b1000010;
parameter FOURTEEN = 7'b0110000;
parameter FIFTEEN = 7'b0111000;
input [3:0]in;
output [6:0]out;
assign out = (in == 0) ? ZERO:
(in == 1) ? ONE:
(in == 2) ? TWO:
(in == 3) ? THREE:
(in == 4) ? FOUR:
(in == 5) ? FIVE:
(in == 6) ? SIX:
(in == 7) ? SEVEN:
(in == 8) ? EIGHT:
(in == 9) ? NINE:
(in == 10) ? TEN:
(in == 11) ? ELEVEN:
(in == 12) ? TWELVE:
(in == 13) ? THIRTEEN:
(in == 14) ? FOURTEEN:
(in == 15) ? FIFTEEN:BLANK;
endmodule
The simulate will not recognize the raising edge of in[1] when the sensitivity list is describes as posedge in. Only the LSB will be monitored. Instead use a bitwise operation to detect when a key is pressed and use this as the clocking signal.
wire gen_clk = |in; // bitwise OR
always #(posedge gen_clk) begin
if (in[0]) tmp <= tmp + 1'b1;
else if (in[1) tmp <= tmp - 1'b1;
end
wire gen_clk = &in; // bitwise AND
always #(posedge gen_clk) begin
if (in[0]) tmp <= tmp + 1'b1;
else if (in[1) tmp <= tmp - 1'b1;
end
Side note: Deep nested muxes often result in lower performance more area then a case statement. This is because most synthesizer will not optimize inline muxes (?:). Recommend re-coding displaysevensegment with a case statement like:
input [3:0] in;
output [6:0] out;
reg [6:0] out; // out needs to be a reg
always #* begin
case(in)
4'h0 : out = ZERO;
4'h1 : out = ONE;
// ...
4'hE : out = FOURTEEN;
4'hF : out = FIFTEEN;
default: out = BLANK;
endcase
end

The states in this FSM machine are changing too quickly due to an issue with the clock updating the present state

I'm in the process of implementing a finite state machine in verilog, and I've encountered an issue. However, I know what the problem is, but I'm not sure how to fix it.
This is my current code:
module moore_SM(clk, rstn, btn, z, rstLED, state);
//Port Assignments
input clk, rstn;
input [2:0] btn;
output z;
output reg rstLED;
output reg [5:0] state;
//Internal Port Assignments
reg [1:0] w, x; //NOTE: This is typically the input in FSM,
//but it is internal because there is a conversion from btn to w.
reg [2:0] y, Y; //Present state and next state respectively
reg [2:0] pstBtn;
reg [31:0] cnt;
//Define some parameters
//Input Type (i.e. A, B or C)
parameter [1:0] A = 2'b00, B = 2'b01, C = 2'b11, DC = 2'b10; //DC => don't care - shouldn't affect FSM
//State (i.e. S1, S2, S3, S4, S5 or S6)
parameter [2:0] S1 = 3'b000, S2 = 3'b001, S3 = 3'b010, S4 = 3'b011, S5 = 3'b100, S6 = 3'b101;
initial begin
state = 0;
end
//Determine which button is active
always #(*)
begin
case(btn)
3'b110: begin w = A; end
3'b101: begin w = B; end
3'b011: begin w = C; end
// default: w = DC;
endcase
end
//Define the next state and output combinational circuits
always #(w,y)
begin
case(y)
S1: begin
state = 6'b000001;
if(w == A) begin Y = S2; end
else begin Y = S1; end
end
S2: begin
state = 6'b000010;
if(w == B) begin Y = S3; end
else begin if(w == A) begin Y = S2; end
else Y = S1; end
end
S3: begin
state = 6'b000100;
if(w == A) begin Y = S2; end
else begin if(w == B) begin Y = S4; end
else Y = S1; end
end
S4: begin
state = 6'b001000;
if(w == A) begin Y = S5; end
else begin Y = S1; end
end
S5: begin
state = 6'b010000;
if(w == A) begin Y = S2; end
else begin if(w == B) begin Y = S3; end
else Y = S6; end
end
S6: begin
state = 6'b100000;
if(w == A) begin Y = S2; end
else begin Y = S1; end
end
//default: Y = 3'b111;
endcase
end
//assign z = (Y == S2);
//Define the sequential block
always #(posedge clk)
begin
y <= Y;
end
endmodule
This code is supposed to identify the pattern ABBAC. I believe the logic accomplishes this purpose.
However, I've encountered a problem. When I press one of the three buttons, the first always block - always #(*) - executes and evaluates the change. The state of the button is encoded and saved into w. At the same time, the next always block - always #(w,y) - senses a change and determines in which state to reside. Like I expected, if I send input A, the machine moves from S1 into S2.
Now if I send input B, the machine moves back into state S1. After I changed a few things around, I identified what I believe to be the problem. Note the last always block: always #(posedge clk). This always block continuously updates the present state, y. When I press a button, I assume what is happening is that the second always block, always #(w,y), is receiving an updated y at 50mHz (in my case), which is obviously much faster than I can press and release a button. Assuming I'm pressing the B button while in state S2, the state quickly changes to S3 to S4 and then to S1 because of the continuous update.
That said, I'm having some trouble coming up with a way to fix this issue. I basically need some way to change only one state per button press.
Note that I'm primarily testing this code on an experimental board. I did write a testbench, but the simulation does not seem to match what I'm seeing on the design board. In case anyone wants to see the testbench code, I posted it below:
`timescale 1ns/1ns
module moore_SM_TB();
reg clk;
reg [2:0] btn;
wire [5:0] state;
wire z;
wire rstLED;
initial begin
clk = 1;
#0 btn = 3'b111;
#50 btn = 3'b110;
#50 btn = 3'b111;
#50 btn = 3'b101;
#50 btn = 3'b111;
#50 btn = 3'b011;
#50 btn = 3'b111;
end
always begin
#20 clk = ~clk;
end
//MUT
moore_SM MUT (clk, 0, btn, z, rstLED, state);
endmodule
NOTE: I believe the solution will ultimately involve modifying how the buttons are handled. When I release a button, this also registers as a change. Hence, I had to comment out the default case because it would also mess up which state the machine is in.
UPDATE: I wrote a reduced version of the FSM I posted above to try and debug the code. It tries to detect the sequence AB.
module moore_SM(clk, btn, rstN, state, rstLED);
//Port assignments
input clk;
input rstN;
input [2:0] btn;
output reg rstLED;
output reg [5:0] state;
//Internal Port Assignments
reg [1:0] w;
reg [2:0] y, Y;
reg [2:0] pstBtn;
//Define some parameters
parameter [1:0] A = 2'b00, B = 2'b01, C = 2'b11, DC = 2'b10;
parameter [2:0] S1 = 3'b000, S2 = 3'b001, S3 = 3'b010, S4 = 3'b011, S5 = 3'b100, S6 = 3'b101;
//Initialize some values to prevent Quartus from doing
initial
begin
y = S1;
Y = y;
state = 0;
rstLED = 0;
end
always #(*)
begin
if(btn == pstBtn) begin w = DC; end
else begin
case(btn)
3'b110: w = A;
3'b101: w = B;
3'b011: w = C;
default: w = DC;
endcase
end
end
always #(*)
begin
case(y)
S1: begin
state = 6'b000001;
if(w == A) begin Y = S2; end
else begin Y = S1; end
end
S2: begin
state = 6'b000010;
if(w == B) begin Y = S3; end
if(w == DC) begin Y = S2; end
else begin Y = S1; end
end
S3: begin
state = 6'b000100;
if(w == DC) begin Y = S3; end
else begin Y = S1; end
end
default: begin state = 6'b100000; Y = S1; end
endcase
end
//Update state and check for reset signal
always #(posedge clk, negedge rstN)
begin
pstBtn <= btn;
if(rstN == 0) begin y <= S1; rstLED <= 1; end
else begin y <= Y; rstLED <= 0; end
end
endmodule
Note that I'm trying to "sample" the button state in the last always block. I've used this method in the past, but it does not seem to work here. Whenever I press a button, there is no change in state. I'm wondering if this is a timing issue now.
If the button input is coming a switch rather than test stimulus it will be asynchronous and so should be put through 2 meta-stability flip-flops. To change one state per button press create an edge detection.
Edge detection will create a 1 clock period wide pulse, resulting in 1 transition per press.
reg [2:0] btn0_meta;
always #(posedge clk or negedge rstN) begin
if (~rstN) begin
btn0_meta <= 'b0;
end
else begin
btn0_meta <= {btn0_meta[1:0], btn[0]};
end
end
reg btn0_posedge;
always #* begin
btn0_posedge = btn0_meta[1] & ~btn_meta[2];
end
Do this for all button inputs and use the btnX_posedge in your state machine.

Resources