Always Blocks with multiple sensitivities - verilog

I am trying to implement an FSM that reacts to either one of two buttons being pressed. Let's call these buttons A and B. What I want is something like:
always#(posedge A or posedge B) begin
if(A) begin **do one thing**
end else if (B) begin **do another**
end
end
The situation I am scared of is the case when, for example, the user is holding down button A and then presses B. The if statement would detect that A is high, when the actual sensitive parameter I want a reaction to is B. How can I do this in Verilog?

One way or another, you need to keep track of the state of "A has been depressed and has not yet been released," etc. You can either track that state externally to your state machine, as in #wilcroft's answer, or as part of your state machine. To handle this as part of the state machine you would need to change the sensitivity list to respond to either presses or releases (i.e. not just posedge), and include state information for either or both buttons being on:
always #(A or B) begin
if (state == NONE_ON) begin
if(A) begin next_state = A_ON; **do one thing**
end else if (B) begin next_state = B_ON; **do another**
end
end
else if (state == A_ON) begin
if (!A) begin next_state = NONE_ON;
end else if (B) begin next_state = AB_ON; **do the B things***
end
end
else if (state == B_ON) begin
if (!B) begin next_state = NONE_ON;
end else if (A) begin next_state = AB_ON; **do the A things***
end
end
else if (state == AB_ON) begin
if (!A) begin next_state = B_ON;
end else if (!B) begin next_state = A_ON;
end
end
end
In some sense keeping track of state like this is the whole point of a state machine which is what you say you are trying to build, and this is a common motivation to build a state machine in the first place.
However if the state machine you were intending to build is at all complex, then adding further A/B information to the state table could significantly multiply your states and make the overall state machine a good deal more complex and spaghetti-like, since your intended states may end up as additional sub-states of A_ON, and of B_ON, and also of AB_ON.
On the other hand, depending on what you were trying to do, given that you were trying to build a state machine based on A or B being pressed it seems very likely that at least some of this information might already be implied (for example that at least some button was pressed) in the states you originally had in mind, so it might not change the complexity all that much.
(Note that if you're concerned about handling the possibility of both buttons being pressed or released simultaneously that would also make this implementation more complicated as well.)

One way would be to register the values of A and B, and compare them to their current values. This requires a system clock of some sort, but you're likely already using one for your FSM.
As an example:
input A, B;
input clk;
reg A_prev, B_prev;
always #(posedge clk)
begin
A_prev <= A;
B_prev <= B;
end
always #(*)
begin
if (A && !A_prev) **do whatever**
else if (B && !B_prev) **do whatever**
end
Since A and B are registered, the second always block will detect if A (or B) was low on the previous clock cycle and is now high.

Related

I'm writing some verilog code and I keep getting error code "Can't resolve multiple constant drivers"?

I'm trying to implement a morse code display on my FPGA. I've written a lot of code but I keep getting the same error message. Before I get into that though, please take a look at the assignment. To be clear, I'm not asking for someone to do the assignment for me. I just need help debugging my code.
"Part IV
In this part of the exercise you are to implement a Morse-code encoder using an FSM. The Morse code uses patterns of short and long pulses to represent a message. Each letter is represented as a sequence of dots (a short
pulse), and dashes (a long pulse). For example, the first eight letters of the alphabet have the following representation:
A • —
B — • • •
C — • — •
D — • •
E •
F • • — •
G — — •
H • • • •
Design and implement a Morse-code encoder circuit using an FSM. Your circuit should take as input one of
the first eight letters of the alphabet and display the Morse code for it on a red LED. Use switches SW2−0 and
pushbuttons KEY1−0 as inputs. When a user presses KEY1, the circuit should display the Morse code for a letter
specified by SW2−0 (000 for A, 001 for B, etc.), using 0.5-second pulses to represent dots, and 1.5-second pulses
to represent dashes. Pushbutton KEY0 should function as an asynchronous reset.
Here is the code I have written:
module part4 (SELECT, button, CLOCK_50, RESET, led);
input [2:0]SELECT;
input RESET, button, CLOCK_50;
output reg led=0;
reg [26:0] COUNT=0; //register that keeps track of count
reg [1:0] COUNT2=0; //keeps track of half seconds
reg halfsecflag=0; //goes high every time half second passes
reg dashflag=0; // goes high every time 1 and half second passes
reg [3:0] code; //1 is dot and 0 is dash. There are 4 total
reg [1:0] c3=2'b00; //keeps track of the index we are on in the code.
reg [2:0] STATE; //register to keep track of states in the state machine
wire done=0; //a flag that goes up when one morse pulse is done.
reg ending=0; //another flag that goes up when a whole morse letter has
flashed
reg [1:0] length; //This is the length of the morse letter. It varies from 1
to 4
wire i; // if i is 1, then the state machine goes to "dot". if 0 "dash"
assign i = code[c3];
assign done= (halfsecflag)&&(~ending)&&~led;
parameter START= 3'b000, DOT= 3'b001, DASH= 3'b010, DELAY= 3'b011, IDLE=
3'b100;
parameter A= 3'b000, B=3'b001, C=3'b010, D=3'b011, E=3'b100, F=3'b101,
G=3'b110, H=3'b111;
always #(posedge CLOCK_50 or posedge RESET) //making counter
begin
if (RESET == 1)
COUNT <= 0;
else if (COUNT==25'd25000000)
begin
COUNT <= 0;
halfsecflag <= 1;
end
else
begin
COUNT <= COUNT+1;
halfsecflag <=0;
end
end
always #(posedge CLOCK_50 or posedge RESET)
begin
if (RESET == 1)
begin
COUNT2 <= 2'd00;
dashflag<=1'b0;
end
else if ((COUNT2==2)&&(halfsecflag))
begin
COUNT2 <= 2'd0;
dashflag<=1'b1;
end
else if ((halfsecflag)&&(COUNT2!=2))
begin
COUNT2<= COUNT2+2'd1;
dashflag<=1'b0;
end
end
always #(posedge button or RESET) //asynchronous reset
begin
STATE<=IDLE;
end
always#(*) begin //State machine
case (STATE)
START: begin
led <= 1;
if (i) STATE <= DOT;
else STATE <= DASH;
end
DOT: begin
if (halfsecflag && ~ending) STATE <= DELAY;
else if (ending) STATE<= IDLE;
else STATE<=DOT;
end
DASH: begin
if ((dashflag)&& (~ending))
STATE <= DELAY;
else if (ending)
STATE <= IDLE;
else STATE <= DASH;
end
DELAY: begin
led <= 0;
if ((halfsecflag)&&(ending))
STATE<=IDLE;
else if ((halfsecflag)&&(~ending))
STATE<=START;
else STATE <= DELAY;
end
IDLE: begin
c3<=2'b00;
if (button) STATE<=START;
STATE<=IDLE;
end
default: STATE <= IDLE;
endcase
end
always #(posedge button)
begin
case (SELECT)
A: length<=2'b01;
B: length<=2'b11;
C: length<=2'b11;
D: length<=2'b10;
E: length<=2'b00;
F: length<=2'b11;
G: length<=2'b10;
H: length<=2'b11;
default: length<=2'bxx;
endcase
end
always #(posedge button)
begin
case (SELECT)
A: code<= 4'b0001;
B: code<= 4'b1110;
C: code<= 4'b1010;
D: code<= 4'b0110;
E: code<= 4'b0001;
F: code<= 4'b1011;
G: code<= 4'b0100;
H: code<= 4'b1111;
default: code<=4'bxxxx;
endcase
end
always #(*)
begin
if (c3==length)
begin
c3=2'b00; ending<=1;
end
else if (done)
c3= c3+2'b01;
end
endmodule
The error code I keep getting is Error (10028): Can't resolve multiple constant drivers for net "c3[1]" at part4.v(68)
Also in green above this error code, it says inferred latch a few different times. This doesn't seem good! Can you take a look at my code and see if you can figure out why I'm getting this error message?
Update: This is not a duplicate of my previous question. Before I was asking for tips on how to create a delay using verilog. In this question I was asking for help debugging my code. The error message I got was not making sense to me. I looked at the other answers on stack exchange regarding that error code but none of them made sense to me.
You're missing a couple of (very) basic principles - you can't code hardware without them. Note that I'm using VHDL terminology here ('signal'/'process'/etc), but the idea is exactly the same in Verilog, if a little harder to find the right words.
You can only drive a signal from a single process (if you're synthesising, anyway), or you get multiple drivers. Look at c3 - where is it driven? You're driving it from 2 combinatorial always blocks. The same is true of STATE.
In a combinatorial process, if you read one of your output (driven) signals before you assign to it (drive it), you're inferring memory. This is where your inferred latches are coming from. Think about it - a process "wakes up" when something it is sensitive to changes/fires. If it then reads the value of a signal that it itself drives, this must mean that the signal has to be recorded somewhere in order for it have a current value; it must know what value it had when the process last completed. This is what memory means. You do this for both STATE and c3 (if(c3==length) must read c3, case STATE must read state).
You fix (1) by recoding so that all signals are driven from only one 'owner' process.
Fixing (2) is more difficult. In a combinatorial process (alway #*) make sure you either give all outputs default values first, or make sure that you never read anything before you've written it, so that there's no confusion about whether memory is inferred. Your combinatorial process to derive STATE is wrong. You read STATE, and then write it. You should have 2 signals: current state, and next state. You should read the current state, and create the next one.
You've got other problems, but you need to fix those 2 first.

Dealing with lots of outputs in a finite state machine verilog

So I'm trying to implement my first FSM, and I'm getting very confused.
The codes a bit long, so let me summarize:
I start with declaring inputs and outputs
Then state declarations (I have five plus three placeholders)
Then Current state assignment, which is sequential
always #(posedge clk)
begin
if (rst == 1'b1)
Current_State <= MainGreen;
else
Current_State <= Next_state;
end
And then... I get lost. I originally just had one big ol' sequential circuit that assigned next_state and outputs, but this was messy/ probably had lots of errors.
What I have right now simply has next_state logic, but nothing to do with outputs:
always #*
begin
Next_state = Current_State;
case (Current_State)
MainGreen:
begin
if (count && expired)
begin
Next_state = MainYel;
end
end
MainYel:
begin
if (WR && expired)
Next_state = AllRed;
else if (expired)
Next_state = SideGreen;
end
AllRed:
begin
if (expired)
Next_state = SideGreen;
end
SideGreen:
begin
if(sensor && expired)
Next_state = SideYel;
end
SideYel:
begin
if(expired)
Next_state = MainGreen;
end
endcase
end
I have about eight outputs based on state alone and four based on state and input. How should I assign them?
You're 90% of the way there. There are two ways to proceed (well probably more than that, but I'll give you what I think are two of the best options):
First, do you have a lot of outputs that only get asserted for a small minority of the states? If so, I'd recommend something like this in your combinatorial always block:
always #*
begin
// default output values
output1 = 1'b0;
output2 = 1'b0;
output3 = 1'b0;
....
case (Current_State)
STATE1:
begin
output2 = 1'b1;
// calculate next state
...
end
STATE2:
begin
output4 = 1'b1;
// calculate next state
...
end
...
endcase
end
This is probably the most efficient way to code your state machine since you don't need to define every output in every state. Now if you have each output active in a lot of different states, it might be easier for you to define those outputs in every state in your case statement.
A final way, which I wouldn't recommend, is to derive the sm ouputs in separate assign statements. It will work just as well, but I think keeping the outputs together with the next state logic is much easier for code maintenance and a good habit to develop. It's one thing to hack out some code quickly for an assignment, it's another to develop code for a real product that may be getting updated several times over the life of a product, and maintainability is essential (something I had to learn on the job because no one taught it in university).

Verilog: functionality like always & synthesizable

Is there any other functionality like always (that would only run if the sensitive signal changes and won't iterate as long as signal stays the same) which can be cascaded, separately or within the always , but is synthesizable in Verilog.
While I don't think there's a construct specifically like this in Verilog, there is an easy way to do this. If you do an edge detect on the signal you want to be sensitive to, you can just "if" on that in your always block. Like such:
reg event_detected;
reg [WIDTH-1:0] sensitive_last;
always # (posedge clk) begin
if (sensitive_signal != sensitive_last) begin
event_detected <= 1'b1;
end else begin
event_detected <= 1'b0;
end
sensitive_last <= sensitive_signal;
end
// Then, where you want to do things:
always # (posedge clk) begin
if (event_detected ) begin
// Do things here
end
end
The issue with doing things with nested "always" statements is that it isn't immediately obvious how much logic it would synthesize to. Depending on the FPGA or ASIC architecture you would have a relatively large register and extra logic that would be instantiated implicitly, making things like waveform debugging and gate level synthesis difficult (not to mention timing analysis). In a world where every gate/LUT counts, that sort of implicitly defined logic could become a major issue.
The assign statement is the closest to always you you can get. assign can only be for continuous assignment. The left hand side assignment must be a wire; SystemVerilog also allows logic.
I prefer the always block over assign. I find simulations give better performance when signals that usually update at the same time are group together. I believe the optimizer in the synthesizer can does a better job with always, but this might depend on the synthesizer being used.
For synchronous logic you'll need an always block. There is no issue reading hardware switches within the always block. The fpga board may already de-bounce the input for you. If not, then send the input through a two phase pipe line before using it with your code. This helps with potential setup/hold problems.
always #(posedge clk) begin
pre_sync_human_in <= human_in;
sync_human_in <= pre_sync_human_in;
end
always #* begin
//...
case( sync_human_in )
0 : // do this
1 : // do that
// ...
endcase
//...
end
always #(posedge clk) begin
//...
if ( sync_human_in==0 ) begin /* do this */ end
else begin /* else do */ end
//...
end
If you want to do a hand-shake having the state machine wait for a human to enter a multi-bit value, then add to states that wait for the input. One state that waits for not ready (stale bit from previous input), and the other waiting for ready :
always #(posedge clk) begin
case(state)
// ...
PRE_HUMAN_IN :
begin
// ...
state <= WAIT_HUMAN__FOR_NOT_READY;
end
WAIT_HUMAN_FOR_NOT_READY :
begin
// ready bit is still high for the last input, wait for not ready
if (sync_human_in[READ_BIT])
state <= WAIT_HUMAN_FOR_NOT_READY;
else
state <= WAIT_HUMAN_FOR_READY;
end
WAIT_HUMAN_FOR_READY :
begin
// ready bit is low, wait for it to go high before proceeding
if (sync_human_in[READ_BIT])
state <= WORK_WITH_HUMAN_INPUT;
else
state <= WAIT_HUMAN_FOR_READY;
end
// ...
endcase
end

Combining Blocking and NonBlocking in Verilog

If I want statements to happen in parallel and another statement to happen when all other statements are done with, for example:
task read;
begin
if (de_if==NOP) begin
dp_op <= 3'b000;
dp_phase = EXEC;
end
else begin
if (de_if==EXEC_THEN) begin
dp_const <= de_src3[0];
dp_src <= de_src3;
dp_op <= {NOP,de_ctrl3};
dp_dest <= de_dest1;
end
else if (get_value(de_ctrl1,de_src1)==dp_mem[de_src2]) begin
dp_const <= de_src3[0];
dp_src <= de_src3;
dp_op <= {NOP,de_ctrl3};
dp_dest <= de_dest1;
end
else begin
dp_const <= de_src4[0];
dp_src <= de_src4;
dp_op <= {NOP,de_ctrl4};
dp_dest <= de_dest2;
end
#1 dp_phase=READ;
end
end
endtask
In this code I want the statement dp_phase = READ to only be executed after all other assignments are done, how do I do it?
As you can see what I did is wait 1 clock before the assignment but i do not know if this is how its done ...
You need a state machine. That's the canonical way to make things happen in a certain sequence. Try to remember that using a hardware description language is not like a regular programming language...you are just describing the kind of behavior that you would like the hardware to have.
To make a state machine you will need a state register, one or more flip-flops that keep track of where you are in the desired sequence of events. The flip-flops should be updated on the rising clock edge but the rest of your logic can be purely combinational.

Verilog Synthesis fails on if statement containing two variables

I encountered a problem with synthesis where if I had two variables in an if statement, Synthesis will fail (with a very misleading and unhelpful error message).
Given the code snippet below
case(state)
//other states here
GET_PAYLOAD_DATA:
begin
if (packet_size < payload_length) begin
packet_size <= packet_size + 1;
//Code to place byte into ram that only triggers with a toggle flag
next_state = GET_PAYLOAD_DATA;
end else begin
next_state = GET_CHKSUM2;
end
end
I get an error in Xilinx ISE during synthesis:
ERROR:Xst:2001 - Width mismatch detected on comparator next_state_cmp_lt0000/ALB. Operand A and B do not have the same size.
The error claims that next_state isn't correct, but if I take out payload_length and assign a static value to it, it works perfectly fine. As both packet_size and payload_length are of type integer, they are the same size and that is not the problem. Therefore I assume its a similar problem to for loops not being implementable in hardware unless it is a static loop with a defined end. But If statements should work as it is just a comparator between 2 binary values.
What I was trying to do here is that when a byte is received by my module, it will be added into RAM until the the size of the entire payload (which I get from earlier packet data) is reached, then change to a different state to handle the checksum. As the data only comes in 1 byte at a time, I recall this state multiple times until the counter reaches the limit, then I set the next state to something else.
My question is then, how do I achieve the same results of calling my state and repeat until the counter has reached the length of the payload without the error showing up?
EDIT:
Snippets of how packet_size and payload_length are declared, as requested in comments
integer payload_length, packet_size;
initial begin
//other stuff
packet_size <= 0;
end
always # (posedge clk) begin
//case statements with various states
GET_PAYLOAD_LEN:
begin
if (rx_toggle == 1) begin
packet_size <= packet_size + 1;
addr <= 3;
din <= rx_byte_buffer;
payload_length <= rx_byte_buffer;
next_state = GET_PAYLOAD_DATA;
end else begin
next_state = GET_PAYLOAD_LEN;
end
end
rx_byte_buffer is a register of the input data my module receives as 8 bits wide, while packet_size increments in various other states of the machine prior to the one you see above.
I have gotten around the error by switching the if statement conditionals around, but still want to understand why that would change anything.
There are some errors that stick out right away about the code, while they may not fix this problem, they will need to be corrected because it will cause a difference in simulation and hardware tests.
The nextstate logic needs to be in a different always block that does not change based on the posedge of clock. The sensitivity list needs to include things like "state" and/or "*". And if you wanted the nextstate logic to be registered like it is now (which you don't) you should use a nonblocking assignment, this is described in great deal in the cummings paper, provided below.
http://www.sunburst-design.com/papers/CummingsSNUG2000SJ_NBA_rev1_2.pdf
the code should look something like this:
always # (*) begin
//case statements with various states
GET_PAYLOAD_LEN:
begin
if (rx_toggle == 1) begin
packet_size_en = 1'b1;
//these will need to be changed in a similar manner
addr <= 3;
din <= rx_byte_buffer;
payload_length <= rx_byte_buffer;
/////////////////////////////////////////////////////
next_state = GET_PAYLOAD_DATA;
end else begin
next_state = GET_PAYLOAD_LEN;
end
end
always#(posedge clk) begin
if(pcket_size_en)
packet_size <= packet_size +1 ;
end
Also, the first thing I would try is to make these a defined length, by making them of type reg (I assume that you wont be needing a signed number so it should have no difference on simulation), outside of generate blocks, you should try to not let synthesis play around with integers.

Resources