Icarus Verilog simulation : Scope index expression is not constant: i - verilog

I am simulating a 16 bit MIPS netlist in Icarus Verilog.
This is the error i get in testbench
mips_16_core_top_tb_0.v:144: error: Scope index expression is not constant: i
mips_16_core_top_tb_0.v:144: error: Unable to bind wire/reg/memory `uut.register_file_inst.reg_array[i]' in `mips_16_core_top_tb_0_v.display_all_regs'
Related code :
task display_all_regs;
begin
$display("display_all_regs:");
$display("------------------------------");
$display("R0\tR1\tR2\tR3\tR4\tR5\tR6\tR7");
for(i=0; i<8; i=i+1)
$write("%d\t",uut.register_file_inst.reg_array[i]); <--- error points to this line
$display("\n------------------------------");
end
endtask
I do get this same error when i simulate the RTL too but i still get the vcd file dumped out.In case of the netlist,I dont even get the vcd file generated.
Would be glad to hear your thoughts.

Your code looks fine, and I've just tested cross-module variable indexing of arrays in Icarus (the current version, from git) and it works.
I suspect your problem is that you're compiling mips_16_core_top_tb_0.v by itself - Icarus will give this message if you do. All source files need to be compiled together in Icarus. Some other simulators will allow you to compile this file by itself, and then only check for errors during elaboration (ie. when you run the simulation), but the way Icarus does it is how Verilog was originally intended to be used.

Your index in register[index] must be constant in this situation. In reg_array[i], i is a variable and not fixed. To simulate using this code you must remodel the design so that it doesn't require a variable indexed register. It may be a simulator-specific lack of support for this feature. If that is the case, you should try a different simulator.

Related

SystemVerilog input signal being Z extended

I've been using Verilog and SystemVerilog for many years, but I just came across something which seems weird.
I don't know if it's something I just never noticed or if there is something special about this I am missing.
Basically I have a module which has a 16-bit input, to which I connected an 8-bit signal. This seems like no big deal to me, in fact it's one of the things I love about Verilog/SystemVerilog, since unlike VHDL, you are allowed to do things like that.
I would expect the signal connected to the input port of my module to be right-aligned and zero-padded on the left, but instead it is being padded with Zs.
That causes my simulation to not work, because for example I use that signal to initialize a counter after substracting one from it, which leads XXXX.
Is this behaviour expected? Can I change something in my code to get the behaviour I expected?
This behavior seems reasonable. I ran a simulation on several simulators on EDA Playground, and I got a mix of results: some had the MSBs as 0, others had them as z.
The best approach is to explicitly drive the inputs with the value you desire. For example, if you want the MSBs to be 0, use something like:
module tb;
reg [7:0] data;
// ...
dut i1 ({ {8{1'b0}}, data });
endmodule
This creates a 16-bit expression which is connected to the module input port. The expression is a concatenation of an 8-bit constant and the 8-bit data signal.
If there is a size mismatch happening in your design or testbench, there should be a warning (if not an error) raised from your compiler/simulation tool. There is no default behavior defined to pad with 0 or undriven z, therefore it can be 0-padded or unknown depending on your tool, and you are on your own risk. The best practice is to watch carefully if there is such warning/error already reported, and try to resolve it during compilation/elaboration phase, or better to run a linting tool before compilation.

Compilation errors due to operands in if statement

This is a system verilog file .The below code when run gives an error "Illegal operand for constant expression" at "if(m_val !==0) and if(div_val)"
Have tried without generating statements but still the same error. Any help on what is wrong with the code?
logic m_ref_clk,mul_ref_clk,div_ref_clk,mixed_ref_clk;
real clk_period = ((1.0/(freq*BASE_GHz_CLK_FREQ))*1s);
generate
if(m_val !== 0) begin
if(div_val == 0)begin
initial begin
clk_period = clk_period*m_val;
forever begin
#(clk_period) mul_ref_clk = ~mul_ref_clk;
end
end
end
end
endgenerate
assign multiply_clk = mul_ref_clk;
Generate statements are evaluated during elaboration which occurs before t = 0 in a simulation. Therefore normal variables (updated dynamically as the RTL runs) can't be used a arguments to generate statements.
Elaboration from 1800 2012 section 3:
Elaboration occurs after parsing the source code and before simulation;
and it involves expanding instantiations, computing parameter values, resolving hierarchical names,
establishing net connectivity and in general preparing the design for simulation.
Generate statements from IEEE 1800 2012 section 27:
Generate schemes are evaluated during elaboration of the design. Although generate schemes use syntax that
is similar to behavioral statements, it is important to recognize that they do not execute at simulation time.
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. For more
details on elaboration, see 3.12

How to create buffer gate with Vivado Schematic?

I am learning Verilog with Vivado for the first time. I am trying to create simple buffer gate with it.
Here is the code I've tried. The first one is Design Source file with name 'inv.v'.
`timescale 1ns / 1ps
module inv(
input a,
output x
);
IBUF buffer(x, a);
endmodule
This code does create buffer gate, but it creates 2 of them.
I've also tried the following code.
`timescale 1ns / 1ps
module inv(
input a,
output x
);
assign x = a;
endmodule
However, this creates nothing. What I want is to create only one buffer gate, which is shown in above image. Does anyone know how?
p.s. I am using Vivado 2017.3 HLx Edition.
IBUF and OBUF are IO buffers: one drives into the logic array from the input pin; the other drives the output pin from the logic array. These are put in by the tool, because they are necessary for electrical reasons (ie reasons of voltage, current etc rather than reasons of boolean arithmetic).
This is why you are struggling to put in your own buffer. A buffer has no function at the boolean level, it is only necessary for electrical reasons. Your Verilog does not concern itself with such detail: such things are added automatically by logic synthesis/layout tools should they feel they are necessary for these electrical reasons (eg to drive a long track or to drive many inputs).
If you want to try something basic to see how your Verilog gets turned into (ie synthesised to) real gates, you'll need to try something that has some function at the boolean level, for example an AND gate. Or, if you want to make it as basic as possible, an invertor.
See the 7-series libraries guide for more info on ibuf & obuf primitives.
https://www.xilinx.com/support/documentation/sw_manuals/xilinx2018_3/ug953-vivado-7series-libraries.pdf
Here is a quote from around page 341 of the file at the link.
"In general, IBUFs are inferred by the synthesis tool for top-level input ports to the design, so it is not necessary to specify them in the source code. However, if desired, they can be manually instantiated by copying the code from the appropriate Libraries Guide HDL template and it into the top-level of your code.
Your first example is the instantiation referred to in the libraries guide. For your second example, there is no component instance and Vivado determined no buffer is needed.

Verilog module instantiation

I am having a bit of trouble instantiating a module in verilog. I am using the Altera Quartus platform to develop and simulate the verilog code.
I have followed this example (among several others):
http://www.asic-world.com/verilog/verilog_one_day4.html
I have written a module (maximum) which finds the maximum between two signed inputs.
Another module I am developing is a systolic array for genetic sequence alignment. The details are not important, however when I try to instantiate a maximum module I get an error.
This is my code so far:
module maximum (a, b, out);
input signed [15:0] a;
input signed [15:0] b;
output reg signed [15:0] out;
always #* begin
if (a>b)
assign out = a;
else
assign out = b;
end
endmodule
and I instantiate in another module systolic_PE (all of this is in the same file seqalign.v)
maximum m0(.a(tempB), .b(diag), .out(tempA));
And I get the error :
'Verilog HDL syntax error at seqalign.v(139) near text "m0"; expecting
"<=" or "="'
I checked everything I have done so far, and I cant seem to see anything I have missed out on.. could anyone be kind enough to guide me?
Also on a side note:
Instantiation of a module in verilog
I was trying to instantiate my module in a if statement, so I tried outside of the if statement in a always #(posedge clk) block, and I get the error
HDL syntax error at seqalign.v(88) near text "("; expecting ";"
Looking over the code you posted in your comment, the issue is from instantiating your module inside your always #(posedge clk) block on line 70. You never instantiate modules inside of procedural blocks (always, initial, etc).
As Verilog is a Hardware Descriptive Language, you have to be in the mindset of designing hardware when writing your code. Module instantiation is like soldering a chip onto a PCB, at design time you either do it, or you dont, and that component stays there for all time. You dont say, well, I want this chip here some of the time, but take it off the PCB when the system gets into these states. In your code, you conditionally instantiate your module if state is 3. However, state changes over time. So that is akin to saying, when the register containing state reads 3, place down this chip into the system, otherwise, it doesnt exist and take it out. On a code level, think of instantiated modules as their own procedural blocks, just as you dont put always inside of other always, dont put modules in always blocks (of course, module definitions/declarations can have always blocks inside them).
Modules are persistent and compile time constant, so you can use generates to conditionally instantiate modules at compile time (ie, decide whether or not to include the module in the design when building the system). But in your code, you are conditionally instantiating at simulation time, which is not allowed as described above.
You can do one of two things to solve your problem. One would be to move your task from your submodule maximum into the systolic_PE module and use it to get the maximum of your variables tby calling it (line 123 would become something like tempA <= convert(.a(0), .b(diag+match)); with a and b added as inputs to your task). Or, instantiate the module outside the always block, but youll need to change your task to be a procedural block like you have in the actual post.

Verilog design - input is "unused" warning

When attempting to synthesize a Verilog design (I want to generate a schematic), I get the following warning:
Synthesizing Unit <rising>.
Related source file is "C:\PPM\PPM_encoder\detectors.v".
WARNING:Xst:647 - Input <in> is never used. This port will be preserved and left unconnected if it belongs to a top-level block or it belongs to a sub-block and the hierarchy of this sub-block is preserved.
Summary:
no macro.
Unit <rising> synthesized.
The relevant module is simply:
module rising (in, out);
output out;
input in;
not #(2,3) (ininv, in);
and #(2,3) (out, in, ininv);
endmodule
And I call it in several different locations, including:
rising startdetect(
.in(start),
.out(or01a));
When I complete the synthesis and then choose to "View schematic", only one component is actually present. Expanding that component, I see only the output being connected to ground, which is the initial condition. Nothing else is present. This is with my testbench as my "top module".
When I select my actual main project (below the testbench, it's called ppmencode) as the top module, I get those same warnings, plus additional warnings for every single module instance:
WARNING:Xst:1290 - Hierarchical block <startdetect> is unconnected in block <ppmencode>.
It will be removed from the design.
What is the cause of these two warnings, and how can I fix them and be able to generate a correct schematic?
Edited to add: The whole thing simulates perfectly, it's just when trying to make a schematic (to try to explain this thing that I just made to my team) that I run into problems. This image shows the schematic that I get.
It's not enough to have a signal named as an input to a module...it needs to actually be connected to a pin on the FPGA. On the other hand, your rising module is taking the AND of the input and its complement...the synthesizer might have figured out a way to simplify that logic that is contrary to your wishes.
Synthesis is optimizing all the logic out because it ignores the delays. Functionally you have in & ~in which is always 0. What you intend is a pulse generator. One way to achieve this is to use the dont_touch attribute, which tell the synthesizer that it must keep a particular module instantiation in the design. See this Properties Reference Guide for more.
module rising (in, out);
output out;
input in;
(* DONT_TOUCH = "TRUE" *)
not #(2,3) (ininv, in);
and #(2,3) (out, in, ininv);
endmodule
Be warned that even with the dont_touch your synthesize result may not match simulation. Synthesis ignores the artificial timing in your netlist. The actual pulse width could be longer, more likely shorter or to small to be registered. Check your standard cell library and look for a delay cell to apply to ininv, this will increase the pulse width. The library may already have a pulse generator cell already defined.

Resources