I have a simple code:
module test (
input a,
output b
);
assign a=0;
assign b=0;
endmodule
As you can see a is input, which assigned, thats wrong.. but no warning is shown; my script for compile.do:
set work work
vlib -type directory $work
vlog -work $work +acc ../src/test.sv +incdir+../inc
and sim.do:
set work work
vlib -type directory $work
vlog -work $work +acc ../src/test.sv +incdir+../inc
How can I see the warning?
In case I do assign a=b; (also error should be since b is output)
also no error, just a is h'x;
You must be coming from VHDL. 😏 This is specifically allowed by Verilog when dealing with nets (which you have implicitly specified)
Section 23.3.3.1 Port coercion of the IEEE 1800-2017 LRMA port that is declared as input (output) but used as an output (input) or inout may be coerced to inout.
SystemVerilog can enforce port direction when using variables instead of nets because only there can only be one continuous driver to a variable. However, there is nothing from preventing you from reading the value of a module output from within the module.
Related
I am kinda new to verilog and struggling with all the basic concepts.
I am trying to display the timing waveform in ModelSim, where is simply throws "# (vish-4014) No objects found matching '/tb/*'. "(in my case).
Whereas when I simulate the testbench in VSCode, using icarus & gkwave, it displays the necessary waveforms I require. In VS Code, I run
iverilog -o tb.vvp tb.v
vvp tb.vvp
gtkave
GTKwave pops up and shows the waveforms. The hardware I am testing out takes 2 numbers as inputs and returns the small and large number (cnsmodule attached below). The testbench I am simulating is named "tb.v" and goes as:
module tb();
reg a0,a1,a2,a3;
wire s0,s1,s2,s3;
level uu(.*);
always begin
$dumpfile("tb.vcd");
$dumpvars(0,tb);
a0=2'b01;a1=2'b00;a2=2'b11;a3=2'b10;
#10;
$finish;
end
endmodule
The relevant modules I am instantiating are:
// Instantiates 3 cnsmodules to input 4 numbers and return them from small to large
module level(a0,a1,a2,a3,s0,s1,s2,s3);
input a0,a1,a2,a3;
output s0,s1,s2,s3;
wire s0,s1,s2,s3;
wire temp1,temp2;
cnsmodule tvz1(a0,a1,s0,temp1);
cnsmodule tvz2(temp1,a2,s1,temp2);
cnsmodule tvz3(temp2,a3,s2,s3);
endmodule
and:
module cnsmodule (a0,a1,sn,ln);
input a0,a1;
output sn,ln;
reg sn,ln;
always#(*) begin
if (a0>a1) begin
sn=a1; ln=a0;
end
else begin
sn=a0; ln=a1;
end
end
endmodule
I suspect that your problem lies with the optimization ModelSIM does to the design, Try the following and tell me if that works in the top bar click on simulate and then followed by optimization options and then click on "Apply full visibillity to all modules(full debug mode)" and then choose your testbench and try to add your signals now
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.
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
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.
I have created two different Verilog Modules (shiftByImm and immShifter). What I want to do is to select only the output of one of the two as the output of this little multiplexer module I am creating.
module superShifter(input [0:31] in, input select, input [0:4] shift_value, input[0:1] shift, output reg [0:31] out);
shiftByImm shift0(in, shift_value, shift, out);
immShifter shift1(in, shift_value, out);
assign {out} = select == 1'b0 ? shift0 : shift1;
endmodule
However, this gives me two perfectly understandable errors:
Illegal reference to interface "shift0"andIllegal reference to interface "shift1"
I know that there is something missing here. How do I select the output of the SuperShifter module to be the same output of one of the pre-made modules?
You're issue is with your naming conventions. You have 2 modules (I'm guessing) with 2 different outputs, but you give them the same name. In this example, you are using the port order method. The names in the parentheses are associated implicitly by order and do not need to be the same as what they are inside the instantiation. The other way is to connect the ports by name. In the example I show both methods. From that point, you would have to use the wires declared to choose an output with your "little mux".
module superShifter(input [0:31] in, input select, input [0:4] shift_value, input[0:1] shift, output reg [0:31] out);
wire [0:31] temp_out_0;
wire [0:31] temp_out_1;
shiftByImm shift0(in, shift_value, shift, temp_out_0);
immShifter shift1(.in(in), .shift_value(shift_value), .out(temp_out_1));
assign {out} = select == 1'b0 ? temp_out_0 : temp_out_1;
endmodule
Following on from #N8TROs answer it looks like you are trying to 'call' the modules and have them generate the output.
Modules are not equivalent to tasks which are called when required they represent physical blocks of hardware. The mux needs to select the output which you want not the module you wish to be active.
As you have both modules driving the same output you will likely see xs When one module drives 1 and the other 0 the wire or net will end up in conflict.
I really agree with N8TROs recommendation to use ANSI style named ports, this really helkps debugging and code maintenance.
but for brevity and to see minimal changes in the code to make it work:
shiftByImm shift0(in, shift_value, shift, out0); //<-- Unique output
immShifter shift1(in, shift_value, out1); //<-- Unique output
assign {out} = select == 1'b0 ? out0: out1; //<-- select output