How do I make a passcode FSM when the inputs are buttons? - verilog

I am trying to write a FSM in System Verilog that acts as a password detector. The password will be inputted using 4 buttons labeled b1, b2, b3, b4. The correct passcode is b1-b2-b3-b4. This is my logic and code for the first two states:
module FSM(
input b1, b2, b3, b4,
output logic unlock
typedef enum {STA, STB, STC, STD, STE} STATES;
STATES NS, PS = STA;
always_ff#(posedge clock)
begin
PS <=NS;
end
always_comb
begin
unlock = 0;
case(PS)
STA:
begin
if (b1 == 1'b1) // If button one is pressed
begin
NS = STB;
else:
NS = STA;
STB:
begin
if (b2 == 1'b1) // If button two is pressed
begin
NS = STC;
else if (b1 == 1 | b3 == 1 | b4 == 1) // if any other button is pressed go to stateA
begin
NS = STA;
else // stay in state B until a button is pressed
begin
NS = STB;
end
My FSM goes from STA to STB fine, but after inputting the correct button to go from STB to STC, the FSM goes back to STA. If I hold all the buttons down in the correct sequence at once, it will go to the last state. Could someone explain the error in my logic or if there is a better way to implement this?

If your pseudo-code is right, then it should work even if you just keep all the buttons pushed. Your first case branch will first look at b1, ignoring all the other buttons, your second will first look at b2, ignoring or others etc; every time, the "correct" NS will be chosen, and the password will be accepted. Presumably, want your if condition for the first branch to be (b1 && !b2 && !b3 && !b4) -- and similar for the rest of the branches.
Further, you probably need a way to ensure that the fsm waits for a button to be unpressed, before looking for the next one. Otherwise, keeping, say, b1 pressed will give you STA->STB->STA.

Related

Can you combine a while statement and an If statement together into one line?

I am creating a game where it plays to 10 points to win and you can also win if a player reaches 7 points without the other player receiving any.
I have an if statement inside a while statement and was wondering if there was a way to combine them into one general statement.
I have tried combining them with an extra set of parenthesis on for the if portion as well as tried to change up the and/or boolean values to see if I got those wrong.
while (count1 <= 10 and count2 <= 10):
if (count1 == 7 and count2 == 0) or (count2 == 7 and count1 == 0):
Happy Path: The while and if loops combine into one statement, while still keeping the rules stated in the summary.
Currently: I have tried a bunch of combinations but they all go to an else statement or go beyond the 10 point limit, which tells me that the while parameters are wrong.
Try:
while (count1 <= 10 and count2 <= 10) or ((count1 != 7 or count2 != 0) and (count2 != 7 or count1 != 0)):
I'm using following logic laws in here:
not (a or b) <=> not a and not b
and
not (a and b) <=> not a or not b

how to run timer function multiple times in parallel in matlab

This is a matlab code that uses guide to run a timer. The timer function counts 10 numbers starting from the number provided in the text field. I would like to know how to enter two numbers successively and make matlab counts 10 numbers for both values in parallel.
let's say I entered 0 then I pressed the start button, then I immediately entered 10 and pressed the start button again. what happens now is that it counts only from 0 to 10. I would appreciate if you can share a way to make my code count from 0 to 10 and from 10 to 20 simultaneously in parallel.
guide code :
function startbutton_Callback(hObject, eventdata, handles)
t=timer;
t.TimerFcn = #counter;
t.Period = 15;
t.ExecutionMode = 'fixedRate';
t.TasksToExecute = 1;
start(t);
stop (t);
delete (t);
timer callback function:
function counter(~,~)
handles = guidata(counterFig);
num = str2double(get(handles.edit1,'String'));
for i = 0:10
disp (num);
num = num+1;
pause (1);
end
you can use parrallel toolbox for real parallel computation.
but if you dont have that , you can create another timer object that count from 10 to 20
and run it

why does the code stuck in the while loop even though i try to break on the loop?(matlab)

The code
ite = 5 ;
cell = 5;
MRJIT = xlsread('5 Node.xlsm',1,'L62: P67');
max_col = 5 ;
for m=1:ite
for n=1:max_col
a = randi(cell)
b = randi(cell)
while (eq(a,b) ||(MRJIT(a,n)==0 && MRJIT(b,n)==0))
if (a~=b)&&(MRJIT(a,n)> 0 || MRJIT(b,n)>0)
break;
end
a = randi(cell)
b = randi(cell)
end
MRJIT([a,n b,n]) = MRJIT([b,n a,n]) %swap value
end
end
Code explanation
there are 5 column on this table, 5 node.xls
the point of this code is to swap values between 2 cell on each column from the table above that are selected by choosing 2 random number that is a and b but only if one of the selected cell value is not zero, if both of the cell values equal to zero, it will need to select another 2 random number until the one of the selected cells values is not equal to zero
The Question
1.why does the code stuck in the while loop? when i try to force stop the program, it shows some of the a and b values are not the same or equal to zero, but it kept stuck on the while loop
Why does the program only run on column 1 and not the others?
This statement
MRJIT([a,n b,n]) = MRJIT([b,n a,n])
does not swap two values. [a,n b,n] is the same as [a,n,b,n]. That is, you are addressing three values using linear indexing (one of them twice). Alternatives: use sub2ind to compute linear indices to your two values, so you can swap them in one statement like you tried, or use a temporary variable to store the one value, and swap them indexing one item at the time. There is no direct way in MATLAB to index two elements in one operation, unless the elements are on the same row or column (except using linear indices, of course).
Using the sub2ind alternative, you could write:
a = sub2ind(a,n);
b = sub2ind(b,n)
MRJIT([a,b]) = MRJIT([b,a]);
Note the difference between MRJIT([a,b]) and MRJIT(a,b).
The other alternative is:
tmp = MRJIT(a,n);
MRJIT(a,n) = MRJIT(b,n);
MRJIT(b,n) = tmp;
--
As an aside, you might be able to improve (speed up) the way you find a and b by (not tested):
a = 0;
while(MRJIT(a,n)==0)
a = randi(cell);
end
b = 0;
while (a==b || MRJIT(b,n)==0)
b = randi(cell);
end

having trouble in visual basic

Module Module1
Sub Main()
'program to display whether first number is divisible by second
Dim a, b As Integer
Console.WriteLine("enter first number ::")
Console.ReadLine(a).ToString()
Console.WriteLine("enter second number ::")
Console.ReadLine(b).ToString()
If a Mod b = 0 Then
Console.WriteLine("numbers are divisible!")
Else
Console.WriteLine("numbers are not divisible!")
End If
Console.ReadLine()
End Sub
End Module
I am having trouble getting past the first if statement. When I execute the program it doesn't display further information it just inputs the values and freezes. I am a newbie in visual basic, but I don't under stand whats going on.
Change if a Mod b=0 to if a Mod b==0
By using single = you are basically assigning the value instead of checking

Calculating in input

I want to count the number of 1's in an 8-bit input and output how many ones are in it. The way I am finding this is very crude and redundant. I want to know if there is any easy and good way of finding them. My code looks like:
module my_8to4bit(in,out);
input [7:0]in;
output [3:0]out;
assign out=(input == 1 || input == 2 || input == 4 || input == 8 || input == 16 || input == 32 || input == 64 || input == 128)?1:
(input == 3 || input == 5 || input == 6 || input == 9 || input == 10 || input == 12 || input == 24 || input == 128)?2:0;
... same goes upto all 1's in 8bit input.
Is there an easy way of finding them?
How about
always #* begin
out = 0;
for(i=0;i<8;i=i+1) begin
out = out + in[i];
end
end
Should just synthesize to 8 adders, one for each bit.
If you don't need to synthesize the code, and your simulator supports SystemVerilog syntax, you can use the $countones system function. Refer to the IEEE Std 1800-2009, for example.
You can look up answers in Bit Twiddling Hacks. If speed is important and space is not an issue, you might consider a 256-byte lookup table. Otherwise, probably use Brian Kernighan's way (and measure whether it is actually slower than the lookup table; it may be faster than the lookup table if memory is slow and the CPU is fast).

Resources