Verilog: Reg is not declared - verilog

Here is the declaration of the reg assignment
reg [5:0]R = {bi7 ,[15:11]RGB}; //bi7 is a parameter
but at the last line of the module i get this error where it points at the same reg assignment.
ERROR:HDLCompiler:69 - "path.v" Line 58: <R> is not declared.
Can anyone help me with this , cause my whole experience with verilog is just a book :(

In verilog, you can only assign a value to a reg in always or initial blocks. You've also got the bit range for stripping bits from you RGB bus on the wrong side of the bus name.
reg [5:0] r;
always #(RGB) begin
r = {bi7, RGB[15:11]};
end
Note that in verilog, parameter names such as bi7 in your code, are usually defined and written in UPPER CASE to make them easy to pick out.

Related

Bit by bit comparison between two variables in Verilog

Currently, I am beginning to write the firmware by Verilog for one idea. It is comparing bit by bit between two variables and then using one binary counter to count the number of different bits.
For example:
I have two variables in verilog
A : 8'b00100001;
B : 8'b01000000;
Then I give the condition to compare bit by bit between two variables. If there is difference between 1 bit of A and 1 bit of B at same bit position, binary counter will count.
This is my verilog code:
module BERT_test(
input CLK,
input RST,
input [7:0] SIG_IN,
input [7:0] SIG_OUT,
output [7:0] NUM_ERR
);
integer i;
reg[7:0] sign_in;
reg[7:0] sign_out;
always #(posedge CLK) begin
sign_in[7:0] <= SIG_IN[7:0];
sign_out[7:0] <= SIG_OUT[7:0];
end
reg [15:0] bit_err;
// Combinational Logic
always #* begin
bit_err = 8'b0;
for (i=0;i<8;i=i+1) begin
if (sign_in[i] == sign_out[i]) begin
bit_err = bit_err + 8'b0;
end else begin
bit_err = bit_err + 8'b1;
end
end
assign NUM_ERR = bit_err;
end
endmodule
Then I had a mistake
Reference to vector wire 'NUM_ERR' is not a legal reg or variable lvalue
I do not know how to solve this problem. Are there any solutions for this problem or how I need to modify my firmware, please suggest me.
You are driving NUM_ERR (a net) from an always block. It is not permitted to drive nets from always blocks (or initial blocks). You need to move this line:
assign NUM_ERR = bit_err;
outside the always block.
You should not use an assign statement inside an always block. This is legal but is deprecated and means something weird. If you have included this line inside the always block by mistake, then indenting you code properly would have shown it up.
You have an assign WITHIN an always block. Move it outside.
Adding zero to bit error if the bits are the same is superfluous.
if (sign_in[i] != sign_out[i])
bit_err = bit_err + 8'b1;
Also bit error is 16 bits so it is not wrong to add 8'b1 but misleading.

Verilog Module Instantiation and empty begin end

I have made two verilog modules. The first one takes a nine-bit number and returns the position of first occurrence of 1 in it.
module findPositionOf_1(
input [8:0] data,
output reg [3:0] position
);
always #(data)
begin
if(data==9'b0000_00000)
position=4'b0000;
else if(data[0]==1)
position=4'b0000;
else if(data[1]==1)
position=4'b0001;
else if(data[2]==1)
position=4'b0010;
else if(data[3]==1)
position=4'b0011;
else if(data[4]==1)
position=4'b0100;
else if(data[5]==1)
position=4'b0101;
else if(data[6]==1)
position=4'b0110;
else if(data[7]==1)
position=4'b0111;
else if(data[8]==1)
position=4'b1000;
end
endmodule
The second module is returning the second occurrence of 1. It is calling the first module first changing that bit to zero and again finding the occurrence of 1.
module findPositionOf_2nd_1(
input [8:0] r1_data,
output [3:0] position1
);
reg [3:0] pos,pos2;
reg [8:0] temp;
integer i;
always #(r1_data)
begin
findPositionOf_1 f1(.data(r1_data), .position(pos));
i=pos;
temp=r1_data;
temp[i]=0;
findPositionOf_1 f2(temp,pos2);
if(pos2==4'b0000)
position1=0;
else
position1=pos2;
end
endmodule
I am getting the following errors during compilation. Please help.
Checker 'findPositionOf_1' not found. Instantiation 'f1' must be of a
visible checker.
A begin/end block was found with an empty body. This
is permitted in SystemVerilog, but not permitted in Verilog. Please
look for any stray semicolons.
By the way you write code it seems like you've not completely grasped how verilog(and other HDL languages) is different from "normal", procedural, coding.
You seem to assume that everything inside your always# block will execute from top to bottom, and that modules are similar to functions. This is not the case. You need to think about how you expect the hardware to look when you've designed your module.
In this case you know that you want two findPositionOf_1 modules. You know that you want the result from the first (u_f1) to affect the input of the second (u_f2). To do this, instantiate the two modules and then determine the interconnect between them.
We can create a vector with a 1 in position pos by left-shifting '1 pos number of times (1<<pos). By xor-ing the bits together, the statement r1_data ^ 1<<pos will remove the unwanted 1.
module findPositionOf_2nd_1(input [8:0] r1_data, output [3:0] position1 );
wire [3:0] pos,pos2;
wire [8:0] temp;
findPositionOf_1 u_f1(.data(r1_data), .position(pos));
findPositionOf_1 u_f2(.data(temp), .position(pos2));
assign temp = r1_data ^ (1<<pos);
assign position1 = pos2;
endmodule
You have instantiated your module inside an always block which is a procedural block, which is syntactically incorrect. Secondly, you have used your first module as a function call, which is not permitted. As said, you need to have a separate testbench, where you can connect your both modules and check. Make the position of occurance of 1st one as input to the findPositionOf_2nd_1 module. For your question, perhaps this should help
Why can't I instantiate inside the procedural block in Verilog

How do you manipulate input arrays in an always block (verilog)?

I'm very new to verilog and i'm just starting to understand how it works.
I want to manipulate an input to a module mant[22:0], in an always block but I am not sure how to go about it.
module normalize(mant,exp,mant_norm,exp_norm);
input [22:0]mant;
input [7:0]exp;
output [22:0]mant_norm;
output [7:0]exp_norm;
reg mantreg[22:0];
reg count=0;
always#(mant or exp)
begin
mantreg<=mant; //this gives an error
if(mant[22]==0)
begin
mant<={mant[21:0],1'b0};//this also gives an error
count<=count+1;
end
end
endmodule
so i have to shift the mant register if the bit22 is zero and count the number of shifts. I am so confused about when to use reg and when to use wire and how to do the manipulation. please help let me know how to go about it.
As you can see in your code you are assigning vector value (mant) to array of 23(mantreg). Instead you should declare mantreg as reg [22:0] mantreg (which is vector of 23 bit).
Wire type variable can not be assigned procedurally. They are used only in continues assignment. Other way around reg varible can only be procedural assigned.
For that try to read out LRM of Verilog .

Designing a 3-bit counter using T-flipflop

module tff(t,i,qbprev,q,qb);
input t,i,qbprev;
output q,qb;
wire q,qb,w1;
begin
assign w1=qbprev;
if(w1==1)begin
not n1(i,i);
end
assign q=i;
not n2(qb,i);
end
endmodule
module counter(a,b,c,cin,x0,x1,x2);
input a,b,c,cin;
output x0,x1,x2;
reg a,b,c,x0,x1,x2,temp,q,qb;
always#(posedge cin)
begin
tff t1(.t(1) ,.i(a),.qbprev(1),.q(),.qb());
x0=q;
temp=qb;
tff t2(.t(1) ,.i(b),.qbprev(temp),.q(),.qb());
x1=q;
temp=qb;
tff t3(.t(1) ,.i(c),.qbprev(temp),.q(),.qb());
x2=q;
a=x0;
b=x1;
c=x2;
end
endmodule
This is my code in verilog. My inputs are - the initial state - a,b,c and cin
I get many errors with the first of them being "w1 is not a constant" What doesn this mean?
I also get error "Non-net port a cannot be of mode input" But I want a to be an input!
Thank you.
Modules are instantiated as pieces of hardware. They are not software calls, and you can not create and destroy hardware on the fly therefore:
if(w1==1)begin
not n1(i,i);
end
With that in mind I hope that you can see that unless w1 is a constant parameter, and this is a 'generate if' What your describing does not make sense.
instance n1 is not called or created as required, it must always exist.
Also you have the input and output connected to i. i represent a physical wire it can not be i and not i. these need to be different names to represent different physical wires.
In your second module you have :
input a,b,c,cin;
// ...
reg a,b,c; //...
Inputs can not be regs as the warning says, just do not declare them as regs for this.
input a,b,c,cin;
output x0,x1,x2;
reg x0,x1,x2,temp,q,qb;

Initialization of array error in Verilog

When I initialize an array sbox, I am getting syntax errors. Please help me out.
reg [7:0] sbox[15:0];
sbox = '{
8'h63, 8'h7c, 8'h77, 8'h7b,
8'hf2, 8'h6b, 8'h6f, 8'hc5,
8'h30, 8'h01, 8'h67, 8'h2b,
8'hfe, 8'hd7, 8'hab, 8'h76
};
This is actually sbox. Error it was showing:
near "=": syntax error, unexpected '=', expecting IDENTIFIER or
TYPE_IDENTIFIER
I was using modelsim simulator
The syntax you are using for the array assignment is only valid in SystemVerilog, not Verilog.
So your compiler needs to support this, and you need to tell the compiler that the file is SystemVerilog. Most compilers (including modelsim) will assume the file type based on the extension, e.g. .v == Verilog and .sv == SystemVerilog, while others required a switch.
In addition, as pointed out in the answer from toolic, you need to place the assignment in an initial block, or you could combine the declaration with the assignment, like this:
reg [7:0] sbox[15:0] = '{
8'h63, 8'h7c, 8'h77, 8'h7b,
8'hf2, 8'h6b, 8'h6f, 8'hc5,
8'h30, 8'h01, 8'h67, 8'h2b,
8'hfe, 8'hd7, 8'hab, 8'h76
};
The assignment should be inside an initial or always block:
module tb;
reg [7:0] sbox[15:0];
initial begin
sbox = '{
8'h63, 8'h7c, 8'h77, 8'h7b,
8'hf2, 8'h6b, 8'h6f, 8'hc5,
8'h30, 8'h01, 8'h67, 8'h2b,
8'hfe, 8'hd7, 8'hab, 8'h76
};
end
endmodule

Resources