SystemVerilog error 10748 - verilog

I am using SystemVerilog to handle a 3-dimensional array. My code is as follows.
module sub_bytes();
reg [7:0] word_stream_reg [0:1][0:1]= '{'{8'hFF,8'hA4},'{8'h50,8'hC6}};
reg [7:0] test = word_stream_reg[0][1][7:0];
endmodule
I get this error:
Error (10748): Verilog HDL error at sub_bytes.v(6): expression in variable declaration assignment to test must be constant
I spent about 4 hours but could not find the reason for this error. I would be grateful if anyone could assist me in this.

Even if some tools allow it, it is a very bad programming practice to initialize a static variable with a another static variable. This is refereed to the "static initialization fiasco" in many programming languages. Outside of a procedural context, there is no defined ordering of static initializers.
Assigning a constant value to a variable does not make that variable a constant. It's still a variable as far as the compiler is concerned.
What you probably want to do is use a parameter instead of a variable.
parameter logic [7:0] word_stream_reg [0:1][0:1]= '{'{8'hFF,8'hA4},'{8'h50,8'hC6}};
Note: Since you are using SystemVerilog, use logic instead of reg.

As #Qui say referencing another variable for initialisation does not work with some simulators.
Why not use:
reg [7:0] word_stream_reg [0:1][0:1]= '{'{8'hFF,8'hA4},'{8'h50,8'hC6}};
wire [7:0] test = word_stream_reg[0][1][7:0];

Related

Continus assignment to verilog module instance

Is it possible to use assign keyword with module instances?
Lets assume I have a module logarithm which works as it's intended. In some other module, I want to have: A = log(B) + log(C).
Is there any efficient way other than the following to do so?
wire [3:0] logB;
wire [3:0] logC;
Logarithm log(logB, B);
Logarithm log(logC, C);
assign A = logB + logC;
And is it known as a gate-level design or a data-flow one?
If it is not data-flow, would you please present a data-flow alternative to this code?
Well your assign keyword in the code is not working on module instances. Rather, it is working on the outputs of those module instances.
The way you are assigning to A should help you get the desired output provided you have set its width accordingly. And it is a data flow representation
There is one mistake in your given lines of code though. You can not use the same instance name log for both the instantiations of the module Logarithm. They have to be unique.

Verilog multiplication through repeated addition

I need help with a Verilog design I'm doing.
the idea is to do multiplication through repeated addition every time the M bit is set to 1/true. then I need to output that value. The assignment statement F=P; is throwing the error.
This is the error I'm getting
Error (10044): Verilog HDL error at Design2.v(13): expression cannot reference entire array "P"
It is my understanding that I can assign a register to an output if they are the same size. If I'm wrong then how can I implement this?
module Design2(A, N, M, F);
input A[7:0];
input N[3:0];
input M;
reg P[15:0];
output F[15:0];
always #(M) begin
repeat(N) begin
P = P + A;
end
F=P;
end
endmodule
Keeping apart the logic side, I can see two issues with your design.
As the comments pointed out, you have used unpacked arrays at wrong place.
Declaration of output port F.
For the first issue, the design needs a 16-bit vector for all the ports and variables. Here, the design takes a bunch of 8-bits as input A which must be declared as input [7:0] A, which is a packed array. Also, P needs to be a vector of size 16-bit in order to have contiguous operations.
This is to be done so that, when the statement P=P+A executes, the addition operation is done with all the variables taken with their respective sizes (size if P=16 and A=8). The overall addition is to be done with 16-bits, padding zeros in MSB side of A.
Hence, convert all the variables to packed array as follows:
input [7:0] A;
input [3:0] N;
input M;
reg [15:0] P;
output reg [15:0] F;
For the second issue, the design assigns output in a procedural always block.
wire elements must be continuously driven by something, and cannot store a value. Henceforth, they are assigned values using continuous assignment statements.
reg can be used to create registers in procedural blocks. Thus, it can store some value.
When an input port is connected, it has to be driven through continuous assignments from parent module, hence input ports are always wire. While output from a module can be driven continuously through a wire, or can be driven through procedural assignments through reg. Following image shows the port connection rules.
To accomplish this in current design, the output port must be declared as output reg [15:0] F. This is the cause of compilation error shown.
Either way, you can have output [15:0] F with no reg and make continuous assignment to F as follows. This will synthesize F to wire:
output [15:0] F;
assign F=P;
SystemVerilog adds a logic datatype to remove confusion between usage of wire and reg declaration. A logic can be driven by both continuous assignment or blocking/non blocking assignment.
// Either continuous assignment
output logic [15:0] F;
assign F=P;
// Or procedural assignment
output logic [15:0] F;
// Inside always block
F=P;
For more information on packed and unpacked array, refer SystemVerilog Arrays link. Regarding port declarations, refer Wire and Net pdf. Refer SystemVerilog IEEE 1800-2012 for more information on logic datatype.

What is the difference between reg and wire in a verilog module?

When are we supposed to use reg and when are we supposed to use wire in a verilog module?
I have also noticed sometimes that a output is declared again as a reg. E.g reg Q in a D flip flop. I have read this somewhere - "The target output of procedural assignment statements must be of reg data type."
What are procedural assignment statements?
I have thoroughly googled this but was not able to find a clear explanation.
Wire:-
Wires are used for connecting different elements. They can be treated as physical wires. They can be read or assigned. No values get stored in them. They need to be driven by either continuous assign statement or from a port of a module.
Reg:-
Contrary to their name, regs don't necessarily correspond to physical registers. They represent data storage elements in Verilog/SystemVerilog. They retain their value till next value is assigned to them (not through assign statement). They can be synthesized to FF, latch or combinatorial circuit. (They might not be synthesizable !!!)
Wires and Regs are present from Verilog timeframe. SystemVerilog added a new data type called logic to them. So the next question is what is this logic data type and how it is different from our good old wire/reg.
Logic:-
As we have seen, reg data type is bit mis-leading in Verilog. System Verilog's logic data type addition is to remove the above confusion. The idea behind is having a new data type called logic which at least doesn't give an impression that it is hardware synthesizable. Logic data type doesn't permit multiple drivers. It has a last assignment wins behavior in case of multiple assignments (which implies it has no hardware equivalence). Reg/Wire data types give X if multiple drivers try to drive them with different values. Logic data type simply assigns the last assignment value. The next difference between reg/wire and logic is that logic can be both driven by assign block, output of a port and inside a procedural block like this
logic a;
assign a = b ^ c; // wire style
always (c or d) a = c + d; // reg style
MyModule module(.out(a), .in(xyz)); // wire style
Procedural blocks refers to always, always_ff, always_comb, always_latch, initial etc. blocks. While procedural assignment statements refers to assigning values to reg, integer etc., but not wires(nets).
wire elements must be continuously driven by something, and cannot store a value. Henceforth, they are assigned values using continuous assignment statements.
reg can be used to create registers in procedural blocks. Thus, it can store some value.
reg elements can be used as output within an actual module declaration. But,reg elements cannot be connected to the output port of a module instantiation.
Thus, a reg can drive a wire as RHS of an assign statement. On the other way round, a wire can drive a reg in as RHS of a procedural block.
For clear idea about declaration of reg or wire, refer the image below:
So, whenever inferring to sequential logic, which stores/holds some value, declare that variable/port as reg. Here, Q is a reg inside a module, but while instantiating this module inside some other module, then this port must be connected to a wire.
Remember, wire can only infer to combinational logic, while reg can infer to either combinational or sequential logic.
Dave's blog is a good source for detailed information. For further information, refer to synthesizing difference and Verilog wire-reg links.
Simple difference between reg and wire is, the reg is used in combinational or sequential circuit in verilog and wire is used in combinational circuit
reg is used to store a value but wire is continuely driven some thing and wire is connected to outport when module initialization but reg is con not connected

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 wire is not assigned

I was wondering that if a wire is declared in a Verilog code, but it is not assigned any value, does Verilog treat its value as ZERO ?
For example, I see a code where:
wire start;
module_if my_module_if(.clk(in_clk), .start(start));
Can I assume that the value of "start" will be zero?
Is this an acceptable style for Verilog?
Nets (including wire) without an assignment will be initialized to 'z' (aka high-impedance).
But if you are trying to use "start" as some kind variable or state, then you should probably declare it as "reg" or "logic" (System-Verilog) rather than "wire" (which tends to be used more for interconnect).
Style-wise, it may be less error-prone for you and for the reader of the code to be explicit about the initialization of your logic. For example ...
logic start;
initial begin
start = 1'b0;
end

Resources