Hey so I'm basically brand new to Verilog and not quite sure how the syntax works and things like this.
The assignment is as below
Use a push button and a switch on the Altera board to increment or decrement a 4 bit counter. The value of the counter should be displayed using the on board LEDs. Use the switch to control the direction of the counter and the push button to change the counter value.
This is what I got so far, I have no idea if its right or not, I know how to assign the inputs and outputs on the board when I get to that point but just cant get the code to compile. I keep getting:
Error (10043): Verilog HDL unsupported feature error at Lab2pt2.v(11): Procedural Continuous Assignment to register is not supported.
Below is the code:
module counter(A,B,F);
input A,B;
output reg [3:0] F;
always #(A or B)
begin
if (A == 1 & B==1)
assign F = F+1;
else(A == 0 & B==1)
assign F = F-1;
end
endmodule
You're the 2nd person trying to use procedural assigns (a rather obscure language feature) today!
The quick answer is to simply drop the 'assign' in your... assignments and things will be happier. This construct will work in simulators but in physical hardware would imply some unusual logic. It's really meant for testbenches (if then).
There are a some other problems with what you've got going here. You're missing an 'if' before the condition in your if/else expression for one.
More generally you need to start thinking of Verilog as describing hardware. Your increment/decrement statements use F on the RHS. What was F before? What does 'before' even mean in this context? What was the 1st value of F?
How does the circuit know when to move from one state to the next? If you can answer these questions you'll be well on your way to a solution.
Related
I have written the below code for a simple multiplication of 2 n-bit numbers(here n=16). It is getting simulated with desired output waveform but the problem is, it is not getting synthesized in vivado 17.2 even though I have written a static 'for loop'(ie., loop iteration is constant). I am getting below mentioned error.
[Synth 8-3380] loop condition does not converge after 2000 iterations
Note: I have written
for(i=i;i<n;i=i+1)
instead of
for(i=0;i<n;i=i+1)
because the latter one was executing once again after i reached n. So that is not a mistake. Kindly someone help. Thank you for your time
//unsigned integer multiplier
module multiplication(product,multiplier,multiplicand,clk,rset);
parameter n = 16;
output reg [(n<<1)-1:0]product;
input [n-1:0]multiplier, multiplicand;
input clk,rset;
reg [n:0]i='d0;
always #( posedge clk or posedge rset)
begin
if (rset) product <= 'd0;
else
begin
for(i=i;i<n;i=i+1)
begin
product =(multiplier[i] == 1'b1)? product + ( multiplicand << i ): product;
$display("product =%d,i=%d",product,i);
end
end
end
endmodule
First of all, it is not a good practice to use for, while kind of loops if you really want to implement your design on FPGA (Vivado is optimized to be used to implement your design on FPGA). Even if you can successfully synthesize your design, you might face with timing problems or unexpected bugs.
I think you can find your answer here.
Edit: I just wanted to inform you that generally controlling timing is very important in HW design, especially when you want to integrate your design with other system, loops can be nightmare for that.
Go back to using your original for (i=0 loop.
Your error is that you assume i=0 because of reg [n:0]i='d0; That is only true the very first time. Thus only once, at the start of the simulation.
because the latter one was executing once again after i reached n.
Yes, the loop will repeat again and again for every clock cycle. That is what #( posedge clk ...) does.
More errors:
You are using blocking assignment in the clock section, use non-blocking:
product <=(multiplier[i] == 1'b1)? product + ( multiplicand << i ): product;
Your product is only correct the first time after a reset (when it starts at zero). The second clock cycle after a reset you do the multiplication again but start with the previous value of product.
Your i is a bit big you use 17 bits to count to 16. Also global loop variables have pitfalls. I suggest you use the system Verilog syntax of: `for (int i=0; ....)
The error message is not about the iterations of your loop, but about the iterations of the internal algorithm of your synthesis program. It tells you that Vivado failed to create a circuit that could actually be implemented on your FPGA of choice at your clock speed of choice and which actually does what you're asking for.
Let me elaborate, after I mention two items of general import: don't use blocking assignments (=) inside always #(posedge clk) blocks. They almost never do what you want. Only non-blocking assignments (<=) should be clocked. Secondly, the correct way to synthesize a for loop is with generate, even though Vivado seems to accept the simple for.
You are building a fairly large block of combinatorial logic here. Remember that when you synthesize combinatorial logic you are asking for a circuit that can evaluate the expression that you've written within a single clock cycle. The actual expression taken into consideration is the one after the for loop has been unrolled. I.e., you are (conditionally) adding a 16bit number to a 32bit number 16 times, each times shifted one bit further to the left. Each of these additions has a carry bit. So each of these additions will actually have to look at all of the upper 16bits of the result of the previous addition, and each will depend on all but the lowest bit of the previous addition. An adder for one bit + carry needs O(5) gates. Each addition is conditional, which adds at least one more gate for each bit. So you are asking for at minimum of 16*16*6 = 1300 interdependent gates that all have to stabilize within a single clock cycle. Vivado is telling you that it cannot fulfill these requirements.
One way of mitigating this problem will be to synthesize for a lower clock frequency, where the gates have more time to stabilize, and you can thus build longer logic chains. Another option would be to pipeline the operation, say by only evaluating what corresponds to four iterations of your loop within a single clock cycle and then building the result over several clock cycles. This will add some bookkeeping logic to your code, but it is inevitable if one wants to evaluate complex expressions with finite resources at high clock frequencies. It would also introduce you to synchronous logic, which you will have to learn anyway if you want to do anything non-trivial with an FPGA. Note that this kind of pipelining wouldn't affect throughput significantly, because your FPGA would then be doing several multiplications in parallel.
You may also be able to rewrite the expression to handle the carry bits and interdependencies in a smarter way that allows Vivado to find its way through the expression (there probably is such a way, I assume it synthesizes if you simply write the multiplication operator?).
Finally, many FPGAs come with dedicated multiplier units because multiplication is a common operation, but implementing it in logic gates wastes a lot of resources. As you found out.
I initialize a register
reg[1:0] yreg;
and manipulate it a bit, i.e., value from prev. iteration of program is shifted to 1 spot when I add in the new value in the 0 spot
yreg = SIGNAL; //here SIGNAL is an input to the program
And then I want to access the values at the 0 and 1 spots in the register later for a calculation. How can I do this? My initial reaction was yreg[0] and yreg[1] (I normally program in python =) but this is producing an error (line 35 is the line of code that has yreg[0] and yreg[1] in it):
ERROR:HDLCompiler:806 - "/home/ise/FPGA/trapezoid/trapverilog.v" Line 35: Syntax error near "[".
My assumption when I saw this was that it's not the right syntax to use the brackets to access a certain index of the register. How do you properly access the information in an index of a register? I'm having trouble finding information on this.
Sorry for the probably ridiculous question, this is my first time ever using verilog or FPGAs in general.
Full Code
module trapverilog(
input CLK,
input SIGNAL,
input x,
output OUT
);
reg[1:0] yreg;
float sum = 0;
always #(posedge CLK)
begin
yreg = SIGNAL; //should shift automatically...?
sum = ((reg[0] + reg[1])*x/2) + sum; //this is effectively trapezoidal integration
OUT = sum;
end
endmodule
You have a fundamental misunderstanding of how Verilog signals work.
By default, all Verilog signals are single bits. For example, in your code, SIGNAL, x, and out are all one bit wide. They cannot store a number (other than 0 or 1).
Specifying a width when you define a signal (like reg [1:0] yreg) controls how many bits are used to represent that signal. For instance, yreg is a two-bit signal. This does not mean that it "shifts automatically"; it just means that the signal is two bits wide, allowing it to be used to represent numbers from 0 to 3 (among other things).
I would strongly advise that you work through a course in digital electronics design. Verilog programming is very different from procedural programming languages (such as Python), and you will have a hard time making sense of it without a solid understanding of what you are actually building here.
Apparently as per this answer using brackets to get a certain index of a register is correct. I just forgot to call the variable properly - I was calling reg[0] instead of yreg[0]. Changing this fixed the error.
Hi I have a simple verilog statements where I want to transfer value at real net to a wire using assign statement. However I see a wire at "x" all the time regardless of the value of a real variable. Here is a snapshot of a sample code with values annotated at time zero:
QN is a wire and real_QN is of type real.
Any ideas why QN is at "x" even though real_QN is at "0" ?
So for reference, the "real" type in not synthesizeable. Only mentioning it because it might be relevant. As such, this solution isn't synthesizeable either. But it should work in simulation. You can not just assign one to the other in this case. But there is a function that will do it for you.
real someReal;
reg [63:1]someReg;
initial begin
someReal = 21.0 ;
$display("someReal---->%f",someReal);
$display("someReg---->%b",someReg);
#1
someReg = $realtobits(someReal);
$display("someReg---->%b",someReg);
Let me know if that does not work for you.
I am writing a Verilog code for synthesis of an algorithm, I am a little confused on what cases might cause latches to be inferred. Below is one such section of the code, though it works fine in simulation, I am worried it might cause problems on hardware.
always#(b1 or b2)
.....
// b1_map,b2_map,m1_map & m2_map are derived from combinational functions using b1 & b2
.....
if(b1_map<=20 && m2_map<=20 && b1_map>=0 && m2_map>=0)
begin
accumulator1[b1_map][m2_map]= accumulator1[b1_map][m2_map] + 1;
end
if(b2_map<=20 && m2_map<=20 && b2_map>=0 && m2_map>=0)
begin
accumulator2[b2_map][m2_map]= accumulator2[b2_map][m2_map] + 1;
end
//accumulator1 & accumulator2 are 2d registers mapped like 2d arrays
So, In this case I want the data to be mapped only if it is in the specified limits. Will a latch be inferred because there is no "else" scenario defined? I didn't add an else statement because there is nothing I want to do with that data if it's not in the limits.
If you write your if statements correctly, you will be fine. Latches are generated when there are paths through the if statement that do not update one or more of the outputs. Code like the following will generate a latch:
always #* begin
if (a) begin
b <= c & d;
e <= f;
end else begin
b <= c | d;
end
end
Notice that e is assigned only when a is true? This requires a latch to implement correctly.
Another posibility that will generate a latch is when the sensitivity list does not contain a signal used in the code.
always #(a) begin
if (a) begin
b <= c & d;
end else begin
b <= c | d;
end
end
This code will generate latches on c and d or on b because it will only allow b to be updated when a changes.
You've misunderstood your problem (and you shouldn't have accepted an answer)
- the issue isn't fundamentally related to 'latches'. Your code doesn't make
sense (for synthesis). Quartus knows this, and it's basically telling you to
rewrite your code.
You've got a combinatorial block that increments a number (immediately) when a
signal changes. Two problems: (1) this is certainly not what you want in real
hardware, and (2) the number must remain the same, and not increment, when b1
and b2 don't change. The second isue is the one Quartus is reporting - your
circuit needs memory of some sort, which it's reporting as a 'latch'. It's not
smart enough to report the first problem, which is the real issue.
Try to draw your circuit as a schematic with real hardware. What does 'any
change on b1 or b2' actually mean? How are you going to maintain the value of
the accumulators when b1 and b2 don't change? The circuit isn't impossible,
but it's way beyond an SO question.
Make you circuit synchronous, triggering on a clock edge, with only a clock
(and possibly a reset) in the sensitivity list, and keep the innards exactly
the same. There's nothing wrong with your if statement, since you actually
want the accumulator to remain unchanged if nothing interesting is happening
on b1/b2.
Inferred latches can come from an incomplete sensitivity list or incomplete assignments.
Sensitivity lists for combinatorial blocks should generally be written with always #*. This avoid coding bugs when updating code. Combinatorial blocks (those not including an edge sensitivity) are once synthesised will perform in the manner of always #*. Specifically naming signals adds more work and will likely lead to RTL to gate level (post synthesis) errors.
Incomplete assignments which imply the value has to be held will infer a latch. Latches are not inherently bad but require careful consideration. Inferred one in this manner removes the thought fullness and control you would otherwise have over it. This can lead to complex timing issues. As the latch is level sensitive rather than edge sensitive. Ideally you want the latch to be open for the first have of the clock cycle so that it is closed when the data will be read from it. Inferred latches remove this control.
Completing if statements with an else, of default for case castanets which sets a sensible value (0's) can help avoid these accidental latches.
I just want to use some if else statement in verilog.
So I have to use always block.
integer count,index;
reg a=0;
always#(a) begin
a=1;
for(count=0;count<7;count=count+1) begin
index=4*count;
if((significand[index]==1'b0)&&(significand[index+1]==1'b0)&&
(significand[index+2]==1'b0) &&(significand[index+3]==1'b0))
lzero=lzero+1;
end
end
This code does make some sense now. I was able to get the correct simulation result, but I failed to get the correct synthesis on the board. Please help
This is a very typical problem with people who know how to program in C or C++ but forget that Verilog and VHDL are not the same as those.
EVERY signal line of Verilog code inside the ALWAYS block are 'executed' at the same time. The same goes with the combinatorial logic outside of the ALWAYS block.
In your code, both the
assign a=1'b1;
assign a=1'b0;
Will happen at the same time, no matter what.
The only way to change that is to put the last line inside your always block,after the end statement of the for loop.
One page that will give you some help on understanding the difference between C and Verilog is the page:EE-Times: The C Programmers Guide to Verilog
Neither assign 1'b1; nor assign 1'b0; are valid assignments. If you want to constantly drive some net with 1'b1, then you have to write something like assign myvar = 1'b1;.
Also, if your intent was to actually assign to a, then always block doesn't make sense since a is the only thing in its sensitivity list meaning that that block must be executed whenever a changes its value. Since a will essentially never change its value, that block should never be executed.
It is hard to help you out unless you provide a minimal working example demonstrating your problem. The only thing that I can recommend is to use ternary operator in assign right hand side statement. That way you can model a behavioural logic without using always block. For example:
assign a = (b == 1'b1 ? c : 1'b0);
Hope it helps.
UPDATE:
Your second code example is neither complete nor legal as well. You cannot have two combinatorial assignments for the same net.
However, a sensitivity list in always block is now a star, which is Verilog 2001 notation to include all right hand side operands into a sensitivity list automatically. In your case, the block will get executed every time significand or lzero changes.