For loop in `define Macro - verilog

I searched on SO, and on web, no where found the ans.
I have following code, where It success fully parsed `define and generate expected results, but if number of times calling of macro is large then, Can we using Looping Construct?.
`define myreg(name) \
addr_``name
`define para(i) \
parameter `myreg(i) = i
module register;
`para(1);
`para(2);
`para(3);
`para(4);
initial
begin
$display("ADDR1 = %d, ADDR2 = %d", addr_1, addr_2);
$display("ADDR3 = %d, ADDR4 = %d", addr_3, addr_4);
#100 $finish;
end
endmodule
Simulation Result:
// # Loading work.register(fast)
// # run -all
// # ADDR1 = 1, ADDR2 = 2
// # ADDR3 = 3, ADDR4 = 4
// # ** Note: $finish : reg.v(18)
Now, when I use for loop, like in below code,
`define myreg(name) \
addr_``name
`define para(i) \
parameter `myreg(i) = i
module register;
genvar i;
generate
for (i = 1; i<=4; i=i+1)
begin
`para(i);
end
endgenerate
initial
begin
$display("ADDR1 = %d, ADDR2 = %d", addr_1, addr_2);
$display("ADDR3 = %d, ADDR4 = %d", addr_3, addr_4);
#100 $finish;
end
endmodule
In that case, It shows an error while displaying or using it,
Simulation Result:
// # vsim -lib work register -c -do "run -all; quit -f" -appendlog -l qverilog.log -vopt
// # ** Note: (vsim-3813) Design is being optimized due to module recompilation...
// # ** Error (suppressible): (vopt-7063) reg.v(24): Failed to find 'addr_1' in hierarchical name '/addr_1'.
// # ** Error (suppressible): (vopt-7063) reg.v(24): Failed to find 'addr_2' in hierarchical name '/addr_2'.
// # ** Error (suppressible): (vopt-7063) reg.v(25): Failed to find 'addr_3' in hierarchical name '/addr_3'.
// # ** Error (suppressible): (vopt-7063) reg.v(25): Failed to find 'addr_4' in hierarchical name '/addr_4'.
// # Optimization failed
// # Error loading design
It is asked more times but proper solution is not given by any one, any help appreciated a lot.

For any simulation, following sequence of events takes place:
Compilation Phase ==> Elaboration Phase ==> Run Phase (Simulation Phase)
At compile time, the syntax error checking and macros text substitution is performed. Memory for all the variables is calculated and an executable is build. During compile time, which a program's source code is being translated into executable code.
At elaboration time, the instances and connection between instances is formed. By connectivity, I mean checking port widths and ports existence etc. Since, the actual instances are created, parameters are also evaluated at elaboration time.
At run time, of course, the actual simulation starts running from zero time on wards.
Macros are evaluated at compile time (hence known as compiler directives), while generate block evaluates at elaboration time.
Referring to IEEE 1800-2012, Section 27.3:
Generate schemes are evaluated during elaboration of the design.
...
They are evaluated at elaboration time, and the result is determined before simulation begins. Therefore, all expressions in generate schemes shall be constant expressions, deterministic at elaboration time.
The first example runs because everything is done at compile time. All the variables are declared at compile time itself. Hence the code works fine.
In the second example, you are trying to declare variables at elaboration time which is not allowed. No more memory to variables is allocated at elaboration time.
Refer IEEE 1800-2012 section 3.12 for more information on compilation and elaboration time.

The problem is actually much simpler than as sharvil111 explains.
The directives `defines, `ifdefs and `includes all get handled by a preprocessor that produces a stream of text and is fed into a compiler. The preprocessor does not know anything about Verilog syntax and the compiler does not see any of those directives because they have been processed away.
You can actually see this intermediate stream of text by adding the vlog -E <filename> option which writes the output of the preprocessor to
There is no looping directive in Verilog/SystemVerilog. Some options for you are:
write the macros out by hand. Perhaps you can find some function in your text editor to help you do this
use some other macro preprocessor to generate your code. This can make debugging difficult as you have to manage two sets of source code files.
Restructure your code to use an array instead of having separately named parameters

Related

Why does this for loop containing a delay not run to completion?

I have two test benches:
// test_a.v
module test_a;
initial
begin
for (int i = 0; i < 128; i++) begin
$display("hello");
#10;
end
end
endmodule
// test_b.v
module test_b;
initial
begin
#50;
$finish();
end
endmodule
I build and run this like so:
iverilog -g2012 -o icarus.out test_a.v test_b.v
vvp icarus.out
...and then see this output:
hello
hello
hello
hello
hello
hello
But it stops there. Why do I not get 128 "hello"s? I guess the $finish() in test_b.v causes test_a.v to quit early but is that expected?
https://www.edaplayground.com/x/JjJR
Most likely a problem with a piece of code you have not shown. Adding a final block after the initial block might give some clues.
final $display($realtime);
It is unfortunate that Icarus Verilog does not notify you that it has hit a $finish and just prints Done. So you might wanna search for other $finish tasks and put a $display statement just before it.
UPDATE:
Based on your updated code, all modules share the same global concept of simulation time, beginning and end-of-time. When one module executes a $finish, that is the end-of-time for the entire simulation. The way you have coded it, there is a race condition whether you would see 5 or 6 "hello"s.

$readmemh doesn't read the values from data file

I'm using readmemh like:
reg [11:0] rom [0:121];
initial $readmemh("x.data", rom);
My x.data file looks like:
line 1: 1
line 2: 10
.
.
.
line 118: 1110101
line 119: 1110110
line 120: 1110111
When I try to use rom[20] during the simulation, I see XXX value. Also, I have checked all rom data values during the simulation, and I saw XXX,XXX,..,XXX
I'm not sure that I used $readmemh in proper way.
When I use your code to read the file, I get warning messages with 2 different simulators. In both cases, the simulator fails to read the file and load the data into the rom variable. If I add the following code:
integer i;
initial for (i=0; i<=121; i=i+1) $displayb(rom[i]);
I see x for all locations in rom. You declared rom as a reg type, and reg types default to x.
The problem is that Line 1:, Line 2:, etc., are incorrect syntax. You need to remove them from the x.data file. Your file should look something like this:
1
10
1110101
1110110
1110111
However, I still get simulator warnings because the simulator interprets 1110101 as a hexadecimal value. Since this value is too large for the 12-bit variable, the simulator does not load it into rom, leaving the value as the default x.
My guess is that your data is really binary format instead of hex. In that case, use $readmemb instead of $readmemh:
initial $readmemb("x.data", rom);
When I make that change, I no longer see x.
Refer to IEEE Std 1800-2017, section 21.4 Loading memory array data from a file for detailed syntax.
Try using the full path to your file. Likely your simulator is not in the same directory as your file.

Is it possible to use $display to print some values when proving with yosys-smtbmc?

In verilog $display() function is usefull in simulation to see the value of constants or macro like this example :
/* Display parameters in simulation */
initial
begin
$display("CLK_PER_NS : %d", CLK_PER_NS );
$display("PULSE_PER_NS : %d", PULSE_PER_NS);
$display("MAX_COUNT : %x", `MAX_COUNT);
$display("MAX_COUNT_SIZE : %x", `MAX_COUNT_SIZE);
end
But when I launch yosys-smtbmc with cover, bmc or prove, nothing is displayed in console.
Is it possible to do it ?
My sby script (example is from my github project here):
[options]
#mode cover
mode bmc
#mode prove
depth 150
[engines]
smtbmc
[script]
read -formal per2bpm.v
prep -top per2bpm
[files]
../../hdl/per2bpm.v
No, this isn't supported at the moment. In general formal verification with Yosys gives you a similar feature set to synthesis (what it presents to the solver is essentially a circuit) with the addition of assert/assume/cover etc. Adding display would be possible using something that read the solver output, but would also be quite a substitantial piece of work to implement properly.

Quartus Prime throwing an error at a $error command

I am having a problem with the following code which should simply throw an error at compilation
if my number of inputs is not divisible by my number of outputs.
module multiplexer #(parameter N_INPUTS, parameter N_OUTPUTS) (in, out, select);
generate
if (N_INPUTS % N_OUTPUTS != 0) begin
$error("%m ** Illegal Parameter ** NUMBER OF INPUTS(%d) does not divide into NUMBER OF OUTPUTS(%d)", N_INPUTS, N_OUTPUTS);
end
endgenerate
input wire [N_INPUTS-1:0] in;
input wire [$clog2(N_INPUTS/N_OUTPUTS) - 1:0] select;
output wire [N_OUTPUTS-1:0] out;
always # (select, in) begin
out = in[(select + 1) * N_OUTPUTS - 1:(select + 1) * N_OUTPUTS - N_OUTPUTS];
end
endmodule
But Quartus keep throwing me this error when I proceed to an Analysis:
Error (10170): Verilog HDL syntax error at multiplexer.v(5) near text: "$error"; expecting "end". Check for and fix any syntax errors that appear immediately before or at the specified keyword. The Intel FPGA Knowledge Database contains many articles with specific details on how to resolve this error. Visit the Knowledge Database at https://www.altera.com/support/support-resources/knowledge-base/search.html and search for this specific error message number.
I am beginning to wonder wether or not the compiler of Quartus supports the $error command (it's my first time using it).
I would greatly appreciate any help on the subject since I am still a beginner in the domain :)
Close your Quartus project and in the .qsf file, change the line pointing to your multiplexer module verilog file from:
set_global_assignment -name VERILOG_FILE multiplexer.v
To:
set_global_assignment -name SYSTEMVERILOG_FILE multiplexer.v
Edit:
Also set:
set_global_assignment -name VERILOG_INPUT_VERSION SYSTEMVERILOG_2009
Edit 2:
It's a SystemVerilog 2009 feature and Quartus Prime Standard and Quartus Prime Lite don't support VHDL 2008 or SystemVerilog 2009.
Quartus Prime Pro 19.4:
Quartus Prime Standard 19.1:
I found the problem...money...
If you look at the following image you'll notice that if you are poor you can't use
the latest version of SystemVerilog in the Lite and Standard version of Quartus Prime.
Well that explains it all.
If anyone as another solution to throw error at compile time that looks better than this please tell me:
generate
if (CONDITION > MAX_ALLOWED /* your condition check */ ) begin
illegal_parameter_condition_triggered_will_instantiate_an non_existing_module();
end
endgenerate
Note: this was taken from https://electronics.stackexchange.com/a/71226
I see other errors:
you are driving wire out from a procedural block (your always
block). You cannot do that, you can only drive a variable. ie out
must be a variable.
your code inside the square brackets is illegal. You will need to use
one of the +: or -: operators. See this answer here.

Verilog Error: Object on left-hand side of assignment must have a variable data type

I'm trying to write a top-level module in Verilog that will open a water valve whenever a sensor reads values below a certain number.
Here is my code:
module ProjectDSD(alteraClock, sensorInput, openValve);
input sensorInput, alteraClock;
output openValve;
always #(sensorInput)
begin
if(sensorInput < 100) //sensor value to irrigate at
begin
openValve <= 1; //here
end
else
begin
openValve <= 0; //here
end
end
endmodule
Im getting an error saying:
Object "openValve" on left-hand side of assignment must have a variable data type
What am I missing? Also, which pins can I use on an Altera DE2-155 board to output a digital signal of only 1's and 0's for the the valve to open/close?
s/output openValve/output reg openValve/
Outputs default to wire; you need a reg. See also this question.
openValve is currently inferred as a wire. Add reg openValve; below output openValve; and your code will work.
Suggestions: It looks like you are following the IEEE1364-1995 non-ANSI coding style. Will still legal, you might want to change to the ANSI coding style, supported in IEEE1364-2001 and above.
Non-ANSI:
module ProjectDSD(alteraClock, sensorInput, openValve);
input sensorInput, alteraClock;
output openValve;
reg openValve;
ANSI:
module ProjectDSD(
input alteraClock, sensorInput,
output reg openValve);
For combinational blocks, it is recommended to use always #* (or the synonymous always #(*)) instead of always #(sensorInput). #* is an auto sensitivity list also added in IEEE1364-2001
Try output reg openValve;.
For the second half of your question (which should really be a separate question) import this QSF file into your project. Any of the GPIO can be configured as outputs, and are accessible by the 40-pin header on the side.

Resources