How to use two events in an "always" block in verilog - verilog

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.

Related

Blocking assignments in always block verilog?

now I know in Verilog, to make a sequential logic you would almost always have use the non-blocking assignment (<=) in an always block. But does this rule also apply to internal variables? If blocking assignments were to be used for internal variables in an always block would it make it comb or seq logic?
So, for example, I'm trying to code a sequential prescaler module. It's output will only be a positive pulse of one clk period duration. It'll have a parameter value that will be the prescaler (how many clock cycles to divide the clk) and a counter variable to keep track of it.
I have count's assignments to be blocking assignments but the output, q to be non-blocking. For simulation purposes, the code works; the output of q is just the way I want it to be. If I change the assignments to be non-blocking, the output of q only works correctly for the 1st cycle of the parameter length, and then stays 0 forever for some reason (this might be because of the way its coded but, I can't seem to think of another way to code it). So is the way the code is right now behaving as a combinational or sequential logic? And, is this an acceptable thing to do in the industry? And is this synthesizable?
```
module scan_rate2(q, clk, reset_bar);
//I/O's
input clk;
input reset_bar;
output reg q;
//internal constants/variables
parameter prescaler = 8;
integer count = prescaler;
always #(posedge clk) begin
if(reset_bar == 0)
q <= 1'b0;
else begin
if (count == 0) begin
q <= 1'b1;
count = prescaler;
end
else
q <= 1'b0;
end
count = count - 1;
end
endmodule
```
You should follow the industry practice which tells you to use non-blocking assignments for all outputs of the sequential logic. The only exclusion are temporary vars which are used to help in evaluation of complex expressions in sequential logic, provided that they are used only in a single block.
In you case using 'blocking' for the 'counter' will cause mismatch in synthesis behavior. Synthesis will create flops for both q and count. However, in your case with blocking assignment the count will be decremented immediately after it is being assigned the prescaled value, whether after synthesis, it will happen next cycle only.
So, you need a non-blocking. BTW initializing 'count' within declaration might work in fpga synthesis, but does not work in schematic synthesis, so it is better to initialize it differently. Unless I misinterpreted your intent, it should look like the following.
integer count;
always #(posedge clk) begin
if(reset_bar == 0) begin
q <= 1'b0;
counter <= prescaler - 1;
end
else begin
if (count == 0) begin
q <= 1'b1;
count <= prescaler -1;
end
else begin
q <= 1'b0;
count <= count - 1;
end
end
end
You do not need temp vars there, but you for the illustration it can be done as the following:
...
integer tmp;
always ...
else begin
q <= 1'b0;
tmp = count - 1; // you should use blocking here
count <= tmp; // but here you should still use NBA
end

Does the following style of coding makes any difference while synthesis?

I am trying to implement a module in my project for which i need the final value to be stable for a while, hence implemented as below. both of them are showing the same result in simulation. will the tool generate same hardware or different one?
always #(posedge clk) begin
if(en)
count <= count + 1;
else
begin
a <= count;
count <= 0;
end
if(count == 0) b <= a;
end
what is the difference between above coding style and the one below? Does it make any difference while synthesis?
always #(posedge clk) begin
if(en)
count <= count + 1;
else
begin
a <= count;
count <= 0;
end
end
always #(posedge clk) begin
if(count == 0)
b <= a;
end
And I am using Vivado 2015.4 tool for synthesis.
It will generate the same hardware output. It doesn't matter if you split clocked statements into one or multiple always-statements, as long as they are functionally identical.
will the tool generate same hardware or different one?
Click "open elaborated design" in Vivado and see for yourself!
But what you'll find is: they're equivalent. No difference whatsoever.

how to average the mem values in verilog

I am trying to read the values of memory after 5 cycles into an output register in verilog. How do I do that?
For example if i have a code which looks like this,
reg[31:0] mem[0:5];
if(high==1)
begin
newcount1<=count2;
mem[i]<=newcount1;
i<=i+1;
count2=0;
end
After the 5 cycles of operation whatever mem values i get, how do i read them in another output register? and can i perform averaging operation on those 5 cycles? and get a nominal value?
Say Your Memory Data Out is mem_data and you want it Read out in mem_data_out with Latency of 5 Cycles.
parameter MDP_Latency = 4;
reg [31:0] mem_data_out;
reg [31:0] [MDP_Latency - 1 : 0] mem_data_out_temp;
always#(posedge clk) begin
if(!reset) begin
for(int i = 0; i < MDP_Latency; i ++)
begin
mem_data_out <= 'd0;
mem_data_out_temp[i] <= 'd0;
end
end
else
begin
for(int i = 0; i < MDP_Latency; i ++)
begin
if(i == 0)
begin
mem_data_out_temp[i] <= mem_data;
end
else
begin
mem_data_out_temp[i] <= mem_data_out_temp[i - 1];
end
end
mem_data_out <= mem_data_out_temp[MDP_Latency];
end
end
`
Lets have a look at the posted code:
reg[31:0] mem[0:5];
if(high==1)
begin
newcount1<=count2;
mem[i]<=newcount1;
i<=i+1;
count2=0;
end
The lack of indentation makes it hard to read, i is not declared. The memory is actually 6 locations, 0 to 5.
You have conditionals and assignment not insides and initial or always block.
I am not sure what you are doing with count2 but mixing blocking and non-blocking is considered bad practise, it can be done but you must be really careful to not cause RTL to gates mismatch.
User1932872 Has posted an answer using for loops it looks like a valid answer but I think loops at this stage over complicate learning and understanding what you are creating in HDLs. While learning I would avoid such features and only uses them once comfortable with the whole flow.
reg[31:0] mem[0:4]; //5 Locations
always #(posedge clk) begin //Clked process assignmnets use non-blocking(<=)
mem[0]<=newcount1;
mem[1]<=mem[0];
mem[2]<=mem[1];
mem[3]<=mem[2];
mem[4]<=mem[3];
end
With this structure we can see the pipeline of data though mem[0] to mem[4]. We are implying 5 flip-flops where the output of the first drives data into the next. A combinatorial sum of them all could be:
reg [31+4:0] sum; //The +4 allows for bitgrowth you may need to truncate or limit.
always #* begin // Combinatorial use blocking (=)
sum = mem[0] + mem[1] + mem[2] + mem[3] + mem[4];
end

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.

Verilog design: Where should my counter live?

I am coding in Verilog a typical count-to-n-then-reset-to-0 counter. My module has the logic to increment and reset the counter.
My issue is that I don't know where the counter itself should be defined.
I could pass the counter (as inout?) to the module. That's ok, but the counter still has to be defined somewhere so it this doesn't do me any good.
Nothing else except this module should touch the counter, so I'd like to have the counter created within this module, and not passed in or out.
Is this reasonably standard, and if so, will someone point to a reference please on how to instantiate the counter?
(I'm on day 2 of Verilog, so be afraid, heh)
EDIT - here's the code. As far as I can tell, it works. I haven't implemented DIR == REVERSE yet.
Couple of interesting gotchas. The (now commented out) STEPPER=0 line was causing an error in a schematic; it thought that STEPPER was tied to ground as well as other logic.
Also, I use = instead of <= in some places involving counter - I was getting timing problems (I suppose.) The procedural assignment removed (hid?) the problem.
module cam(
input [7:0] DIVISOR,
input DIR,
input SPINDLE,
output reg STEPPER
);
parameter FORWARD = 1'b1;
parameter REVERSE = !FORWARD;
reg[7:0] counter = 0;
always #(posedge SPINDLE) begin
// STEPPER = 0;
if (DIR == FORWARD) begin
counter = counter + 1;
if (counter == DIVISOR) counter = 0;
end
else begin
// counter <= counter - 1;
// if (counter == (-1)) counter <= DIVISOR;
end
end
always #(negedge SPINDLE) begin
STEPPER = (counter == 0) ? 1 : 0;
end
endmodule
Should just be defined as a register within the module. Here's an example from some of my code.
module trigger(clk, rxReady, rxData, txBusy, txStart, txData);
input clk;
input [7:0] rxData;
input rxReady;
input txBusy;
output reg txStart;
output reg[7:0] txData;
integer count81; // Number of cells received over serial (start solving after 81)
reg[8:0] data[0:8][0:8];
integer state;
always #(posedge clk) begin
case (state)
read:
if (rxReady) begin
data[count81 % 9][count81 / 9] = rxData ? 1<<(rxData-1) : -1;
if (count81 < 80) count81 <= count81 + 1;
else begin
count81 <= 0;
state <= solving;
end
end
etc....
endcase
end
endmodule
Congrats on getting out of the Java world for the time being. FPGAs are the only thing that seems exciting anymore.

Resources