I'm creating a sudoku game in verilog(2001) to eventually be put onto an FPGA, I found code for it in java and have been trying to convert it but have run into some errors.
Here's the link for the java code
www.geeksforgeeks.org/program-sudoku-generator
I have very little verilog experience and am learning as I go.
task automatic removeKDigits()
reg count = K;
while (count != 0)
begin
integer cellId = randomGenerator(N*N-1);
// System.out.println(cellId);
// extract coordinates i and j
i = (cellId/N);
j = cellId%9;
// System.out.println(i+" "+j);
if (mat[i][j] != 0)
begin
count = count-1;
mat[i][j] = 0;
end
else
count=count;
end
endtask
K is the amount of digits to be removed from the mat[i][j] board, N=9 since its a 9x9 sudoku board. For the lines containing "count=count-1" and "count=count" I'm getting the error
syntax error, unexpected '=', expecting IDENTIFIER
what does it mean? how do I fix it?
Unfortunately, it's unlikely you'll be able to port java code to synthesizable Verilog code, without at least a decent knowledge of the principles behind RTLs (Register transfer languages).
Programming languages like Java are a high level descriptions of some logic, that will get converted into machine instructions, and run on a processor. They operate sequentially, one line at a time, in a particular order.
RTLs on the other hand, describe actual hardware. They tend to operate in parallel, on a trigger, typically a clock. Instead of 'variables', you tend to work with 'registers' representing actual flip flops, and the Verilog programme will describe the transfer of data between these registers.
As for the actual issues with your code, it's impossible to point out the errors, because it simply isn't Verilog.
I recommend this answer: https://stackoverflow.com/a/5121853/10719567, for a more eloquent description of the differences between programming languages and RTLs, and why it's not that easy to port between the two.
Related
I am currently developing a Verilog based Testbench model for a DUT,
I have experience with System Verilog TB and Verification IPs and this is my first time developing a pure verilog TB.
I have completed the basic blocks for running the simulation and its working as expected.
But I am stuck at implementing the Functional Coverage(which I want to do in Sample Monitor block).I have extracted the Functional Coverage from the specifications but how do I implement it in Verilog code ?
We have below(example code to show the syntax) support in System verilog for functional coverage,
covergroup example_group # (posedge en);
parity : coverpoint par {
bins even = {0};
bins odd = {1};
}
endgroup
Is there a way to implement functional coverage as bins,points and groups(in System verilog) to track overall functional coverage in verilog based code?
Edit :
I understood that there is no alternative syntax for coverage in verilog and I don't want to complicate and spend more time by implementing coverage counters. Also I can't convert my verilog TB to System Verilog due to some internal agreement issues.
Yes, the covergroup is equivalent to this Verilog code
always #(posedge en) begin : example_group
integer even=0;
integer odd=0;
if (par == 0) even = even + 1;
if (par == 1) odd = odd + 1;
end
But the real time consuming part is writing the code that collects all these counters, merges the data from different tests, and generates the reports. Seems silly to re-invent this. Most tools give you this capability in SystemVerilog.
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 coded something like the following:
always #(state or i1 or i2 or i3 or i4) begin
next = 5'bx;
err = 0; n_o1 = 1;
o2 = 0; o3 = 0; o4 = 0;
case (state) // synopsys full_case parallel_case
IDLE: begin
if (!i1) next = IDLE;
else if ( i2) next = S1;
else if ( i3) next = S2;
else next = ERROR;
end
S1: begin
if (!i2) next = S1;
else if ( i3) next = S2;
else if ( i4) next = S3;
else next = ERROR;**strong text**
...
My manager, of course I don't want to argue with him before I have some strong argument, but he reviewed my code and said writing
next = 5'bx;
err = 0; n_o1 = 1;
o2 = 0; o3 = 0; o4 = 0;
in a combinational logic without putting the right side in the sensitivity list will cause problems in synthesis.By not having these 3 lines, I need to explicitly write the else part inside each individual case, and he said yes.
I am wondering is there anything wrong with this coding style? And will it cause a synthesis problem or any sort of problem(maybe some version or old synthesis tool won't synthesize?) by initializing these values in the combinational logic? What he said does make sense to me and I actually never thought about it because he said this is software logic, and every wire gets its initial value from the logic before it with the initial condition. I told him school taught us this, he was like school cares less any synthesis but industry does.
Thank you for your help! Guess I am not trying to convince him anything even I have a answer, since the team need to stick with one style anyways, but i am confused by him since I have seen others doing this all the time and he is also a guy with tons of experience, so...confused
First of all, you should be using always #(*) from Verilog-2001 or even better always_comb from SystemVerilog so the sensitivity list get constructed automatically for you.
The problem with your code is the use of the full case synthesis pragma as described in this paper. Your coding style removes the need for full case as long as you are sure you made assignments to every variable in the always block for all possible flows through the block.
I think what your boss means by "software logic" is that your coding style requires the designer to think sequentially. In other words, when I read your always block, I am first forced to think about all the values being initialized to their default values, then I must evaluate the case logic. In reality, the logic will synthesize into the equivalent of a default case. This causes a disparity between the logic that represents the RTL and the logic of how I evaluate your expression in my mind. If you know what your doing, then this should be fine most of the time. But you are working for a company, so your code should be considerate of the other engineers working on a project. Each different team in the design flow is going to view the same logic through a potentially different lens (for example, the physical design team is not concerned with Verilog but the synthesized RTL). If we write our Verilog to reflect the final RTL (i.e. "hardware logic"), then everyone is analyzing the logic in a similar fashion. If I look at an output in a circuit and I know all the values of the inputs at a given time step, then I can visually trace the output through the circuit and determine its value without giving any consideration to the other logic. Your Verilog code should be written in the same way.
To summarize, your initialization statements are nothing more than another case in the selection mux in the RTL. So, you should write it that way. Use a default case and explicitly assign every output of the block in each case. This is generally considered best practice. It may not be the most clever or elegant way to write Verilog, but it is the most readable and results in far fewer errors (and in industry, people are more concerned with design verification to reduce costs than the cleverness of Verilog).
Also, as #dave_59 brought up, if you use the full_case Synopsis directive, then it will create default output drivers for you where the outputs are set to "don't cares." This is not a result that anyone wants, and it would be flagged by the verification team. To fix it, you would need to make sure every output is being assigned by adding them to all the cases like your boss mentioned. If you are forced to do this anyways, then full_case is redundant because you have explicitly made the case statement full. As for older synthesis tools, I don't see that being as big of an issue for this particular subject, but it is a consideration that is always given in industry. What would be more of an issue is if your company has configured downstream tools to force older constructs in an effort to reduce verification costs.
Trust your manager's experience on this issue. Coding style in industry is largely affected by collaboration with other engineers, costs, and legacy than by technical details. This is where your manager's experience will be valuable.
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.
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.