System Verilog attaching vector [10..0] to integer - verilog

module rocket_move (
input logic clk,
input logic resetN,
input logic signed [10:0] spaceship_X,
input logic signed [10:0] spaceship_Y,
output logic signed [10:0] rocket_topLeftX, // output the top left corner
output logic signed [10:0] rocket_topLeftY // can be negative
);
// a module used to generate the rocket trajectory.
int x = spaceship_X[10:0];
int y = spaceship_Y[10:0];
Im trying to attach a rocket bitmap to the center of spaceship bitmap which i've already build and works,
spaceship_[10..0] is vector that holds position on axis X and Y of a spaceship, im trying to use a variable for future calculations but i get error every time, i've tried to do calculations straigh with spaceship_X[10..0], in that case i dont get an error but cant see the rocket bitmap either. thanks in advance
"Error (10748): Verilog HDL error at rocket_move.sv(26): expression in variable declaration assignment to x must be constant"

Assigning an int at its declaration will give it an initial value at time zero. At the time off assignment the spaceship X/Y value is still its type’s default value.
Assuming x/y are only driven by spaceship X/Y you code do the following:
int x,y;
always_comb begin
x = spaceship_X[10:0];
y = spaceship_Y[10:0];
end
Or:
int x,y;
assign x = spaceship_X[10:0];
assign y = spaceship_Y[10:0];
If x/y have mutual assignment, then handle all the assignment conditions within the always_comb. If the variables are synchronous, then use always_ff #(posedge clk) block with non-blocking assignment (<=).

Related

Why is wire variable causing illegal left-hand side in continuous assignment?

I have read through all similar posts, but none address the issue I'm having, namely that line 41 assign Y[b]=~Y[b]; causes error "Illegal left-hand side in continuous assignment."
I haven't assigned any regs so I don't see what the issue is. If I replace b with an actual number (say, 3) it works fine. But I need b as a variable here.
// Hamming code 1-bit error correction
module HCG(I,e,O);
input [4:1] I; // input BCD
input [7:1] e; // noise simulation
wire [7:1] X; // Hamming code
wire [7:1] Y; // Hamming code after addition of noise
wire [3:1] P; // Parity at start
wire [3:1] S; // Parity at end
wire b; // the error bit
output [4:1] O; // corrected output
assign X[1]=I[1]^I[2]^I[4]; // Hamming code generator
assign X[2]=I[1]^I[3]^I[4];
assign X[3]=I[1];
assign X[4]=I[2]^I[3]^I[4];
assign X[5]=I[2];
assign X[6]=I[3];
assign X[7]=I[4];
assign P[1]=X[1]; // Parity at start
assign P[2]=X[2];
assign P[3]=X[4];
assign Y[1]=e[1]^X[1]; // noise added
assign Y[2]=e[2]^X[2];
assign Y[3]=e[3]^X[3];
assign Y[4]=e[4]^X[4];
assign Y[5]=e[5]^X[5];
assign Y[6]=e[6]^X[6];
assign Y[7]=e[7]^X[7];
assign S[1]=Y[3]^Y[5]^Y[7]; // Parity at end
assign S[2]=Y[3]^Y[6]^Y[7];
assign S[3]=Y[5]^Y[6]^Y[7];
assign b=(S[1]!=P[1])? b:b+1; // if parity of 2^0 not the same, add 1 to b
assign b=(S[2]!=P[2])? b:b+2; // if parity of 2^1 not the same, add 2 to b
assign b=(S[3]!=P[3])? b:b+4; // if parity of 2^2 not the same, add 4 to b
assign Y[b]=~Y[b]; // correct the incorrect bit
assign O[1]=Y[3]; // assigning outputs
assign O[2]=Y[5];
assign O[3]=Y[6];
assign O[4]=Y[7];
endmodule
The lines between module and endmodule are executed concurently. (It seems like you think they are executed sequentially.) Therefore, you are driving all the bits of Y in these lines
assign Y[1]=e[1]^X[1]; // noise added
assign Y[2]=e[2]^X[2];
assign Y[3]=e[3]^X[3];
assign Y[4]=e[4]^X[4];
assign Y[5]=e[5]^X[5];
assign Y[6]=e[6]^X[6];
assign Y[7]=e[7]^X[7];
and then are driving one of the bits of Y again in this line:
assign Y[b]=~Y[b]; // correct the incorrect bit
So (a) you have a short circuit and (b) which bit has the short circuit? That depends on b. So, the position of the short circuit depends on the state of one of the internal wires. You have described a circuit that can reconfigure itself depending on its inputs. Verilog won't let you do that. Verilog is a hardware description language. Conventional digital hardware can't reconfigure itself depending on the state of its inputs.
The problem is the continuous assignment you are doing. To quote from the IEEE Std 1800-2012. (Section 10.3) on continuous assignments:
Continuous assignments shall drive values onto nets or variables, both vector (packed) and scalar. This assignment shall occur whenever the value of the right-hand side changes. Continuous assignments provide a way to model combinational logic without specifying an interconnection of gates.
When you do assign Y[b]=~Y[b], the assignment itself automatically causes the right-hand side to change again, which triggers the assignment again.
Verilog standard lists legal lhs values for the continuous assignment as the following (Table 10-1):
Net or variable (vector or scalar)
Constant bit-select of a vector net or packed variable
Constant part-select of a vector net or packed variable
Concatenation or nested concatenation of any of the above left-hand sides
in your case Y[b] is not a constant selection, because b is not a constant. Therefore syntactically your lhs is illegal and you get this message from the compiler.
On a side note you have a zero-delay loop here. See other answers for explanation.

Is there a mandate for the variable to be of data type "integer" for arithmetic operations "+" and "-"?

Following is the code for finding factorial of a number. If I declare "i" as "register", the output (z) remains 1, irrespective of the input. If it is declared as "integer", I get the proper result. Why is it so? Please explain.
module Factorial_calc(n, z);
input [5:0] n;
output reg [64:0] z;
reg i;
// integer i;
always #(n)
begin
i=0;
z=1;
while(i<n)
begin
i=i+1;
z=i*z;
end
end
endmodule
Because your integer is 32 bits wide and your reg is only one bit wide. Your simulation should not finish for most values of n, let alone produce a result.
HDL is not like any other programming language. Beware that even if your code simulates it does not mean it will work in hardware. In your case it will not synthesize. You value of n is undefined at compile time.
Last be not least do NOT use x or z for variables, They are too easily confused with 'x or 'z.

Verilog data types

I am studying verilog as part of my university course however my module lecturer left so I was hoping for some help here,
An example we have been given for a parametric n-bit gray to binary code converter, as follows:
module bin_n_gray #(parameter n=4) (input [n-1 : 0] gray, output [n-1 : 0] bin);
integer i;
always # (*)
for(i = 0; i < n; i = i+1)
bin[i] = ^(gray >> i);
endmodule
My question:
As the bin[i] variable is on the left hand side of an assignment statement within an # always block shouldn't this variable be declared as output reg [n-1 : 0] bin?
As I thought that a variable on the left hand side of an assignment statement of a process block i.e always / initial should be declared as a reg datatype?
As the bin[i] variable is on the left hand side of an assignment statement within an '# always' block shouldn't this variable be declared as 'output reg [n-1 : 0] bin?
Yes, it should require the reg as you say, at least according to Xilinx XST. The code as given in your question errs when synthesizing using that tool (and is missing an unrelated semicolon).
First let's begin by understanding what a procedural block in Verilog is, exactly (with the assumption that we're using Verilog to develop hardware, such as an FPGA design). Procedural blocks are always blocks (of two types, combinational and sequential) as well as few other types of blocks we won't cover here. The first thing to know is that in a procedural block, the only assignments allowed are those that have a reg on the left hand side.
This doesn't necessarily mean that a physical register/flipflop will be created. In this case, one will not be. The reason is the declaration of the block as always # (*). This declaration means that the process is combinational (i.e. not sequential, not having any internal state or clock signal). As a result, no physical flip-flops are created.
Alternatively, you can have a procedural block declared as always # (posedge some_clock_signal). This means that sequential logic is created, and physical flip-flops (or other means of storage such as the distributed memory in FPGA lookup tables) may be used. The takeaway is that you're still declaring as reg there, but now you're actually creating registers.
There is one case where you use wire (or output), which is by continuous assignment (for example, assign a = b & c), which falls outside a procedural block. In this example, I'm using generate to do the same thing as the loop in your original code:
module bin_n_gray #(parameter n=4) (input [n-1 : 0] gray, output [n-1 : 0] bin);
genvar i;
generate
for (i=0; i < n; i=i+1)
begin: graydecoder // arbitrary label needed by generate syntax
assign bin[i] = ^(gray >> i);
end
endgenerate
endmodule

Synthesis error on a CASE statement in Verilog

I m new in Verilog and I would like to know your opinion about an error I get when trying to synthesize the part of my code cited below:
input [31:0] A;
reg [31:0] X,Y;
reg [15:0] width;
input action;
always#*
begin
width= A [31:16];
if (action==1)
begin
case (width)
16'b0: X=0;
default:
begin
for (i=32; i>=width+1 ; i=i-1)
X[i]=0;
for (i=width; i>=0; i=i-1)
X[i]=1;
end
endcase
Y=X >> 1;
end
end
I m using Cadence synthesis tool and the error that i get is in this part of my code saying :
Index 'X[-1]' is not within the valid range of the declaration [31:0]
which i don't understand because even if width=0 i have a special case that should not involve the for loop. i also tried increasing the limits to width +2,width +1 and then shift the quantity X by 2 ..but also got the same error.
Thank you in advance!
I don't see how i could be -1, but it is possible for it to be greater than 31 which is out of range. There are couple of synthesis issues:
i=32 is already out of range for X[31:0]. Its MSB is 31.
i will go out of range when width > 31. width is a 16-bit unsigned value, meaning its maximum value is 65535 (i.e. 216-1) and its minimum is 0.
Synthesis requires loops to static unroll. This means the number of loops must be constant. Variables such as width cannot be in the loops condition.
A synthesis-able for loop will look as follows:
for (i=31; i>=0; i=i-1)
X[i] = (width>=i);
I'm assuming the width= A [31:16]; above the always block is a copy past typo as it is illegal syntax. I'm also assuming there are no additional assignments on width, X, Y, or i outside of the always block. Otherwise there are additional errors.
It's unclear exactly why you're hitting the -1 condition, but it looks like you are trying to create a mask of width "width", which would be more easily accomplished as:
always #*
begin
X = ((1 << width[4:0]) - 1)
end
Edit: Added width specifier to shift, this may reduce synthesis area

Displaying numbers in 7 Seg Decoder using Verilog

This code should display number 0 -15. I am trying to make this code to work, but I tried everything and nothing works...
reg number;
number[3] = Qd;
number[2] = Qc;
number[1] = Qb;
number[0] = Qa;
wire circuitB;
reg[3:0] tenth;
comparator cm (circuitB,number);
always#(circuitB)
if(circuitB)begin
number[3] = 0;
number[2] = 0;
number[1] = number[3]&number[2]&number[1];
number[0] = ~(number[1]^number[0]);
tenth[0] = 1;
end
Dec7SegDisp big (HEX0,number);
Dec7SegDisp big1 (HEX1,tenth);
Qa,Qb,Qc,Qd are output from a counter.
So, things I tried :
using number and tenth as wire - I will get errors such as left hand assignment must have a variable data type etc.
using numer and tenth as reg - I get errors saying that assigng Qa,Qb,Qc and Qd to them are illegal, as Error (10170): Verilog HDL syntax error at partII.v(22) near text "="; expecting ".", or an identifier
And I don't know what else I can do. Thanks for reading.
Here are a few things you need to fix:
you define number as a single scalar variable, but use it as an array. It should be either reg [3:0] number or wire [3:0] number.
You should either use continuous assignments to number: assign number[3] = Qd; or only assign to it in an always block. The way you have it now at the beginning of the code is wrong. Why not putting all assignments to number in one single always block?
You can't assign to number twice. Currently, you are assigning to it both at the beginning and also in the always block.
You don't show all of your code and the description of the comparator and QA,..,QD. Perhaps you can post a more complete code here: http://www.edaplayground.com/

Resources