Error: Syntax in assignment statement l-value - verilog

This is the Verilog code.
module Problem1(x,y,z,F1,F2,F3);
input [1:0] x,y;
input wire z;
output F1, F2;
reg F1 , F2;
output wire [1:0] F3;
assign F3 = x&y;
always #* begin
if(z)
assign F1 = x[0];
else
assign F1 = x[1];
sub(z,F2);
end
endmodule
module sub(F,x);
task sub;
output reg F;
input x;
always #* begin
case(x)
0:F = 1;
1:F = 0;
endcase
end
endtask
endmodule
I'm getting the following errors. Can you help me understand how to fix them?
$iverilog -o main *.v
main.v:25: syntax error
main.v:27: Syntax in assignment statement l-value.
main.v:28: syntax error
main.v:28: Syntax in assignment statement l-value.
main.v:29: syntax error
I give up.

There are a few syntax errors with your code.
Do not use the assign keyword to make an assignment to a reg (F1).
Do not place a module instance (sub) inside an always block.
Use an instance name for your sub module instance.
Do not create a task with the same name as a module (sub). There is no need for the task/endtask in this case.
Here is a version which compiles cleanly for me:
module Problem1(x,y,z,F1,F2,F3);
input [1:0] x,y;
input wire z;
output F1, F2;
reg F1 , F2;
output wire [1:0] F3;
assign F3 = x&y;
always #* begin
if(z)
F1 = x[0];
else
F1 = x[1];
end
sub sub (z,F2);
endmodule
module sub(F,x);
output reg F;
input x;
always #* begin
case(x)
0:F = 1;
1:F = 0;
endcase
end
endmodule

Related

4-bit register using D flip-flop with enable and asynchronous reset

I am modelling a 4-bit register using D flip-flops with enable and asynchronous reset. It contains 4 D FF and 4 2:1 Mux. I used structural Verilog to model the circuit.
My design is shown below.
module DFlipFlop(D,clk,reset,Q);
input D;
input clk,reset;
output Q;
reg Q;
always #(posedge clk or posedge reset)
begin
if(reset==1'b1)
Q <= 1'b0;
else
Q <= D;
end
endmodule
module m21(D0, D1, S, Y);
output Y;
input D0, D1, S;
assign Y=(S)?D1:D0;
endmodule
module DFF_with_Enable(D,clk,enable,reset,Q);
input D,clk,reset,enable;
output Q;
reg Q;
wire in;
m21 mux(D,in,enable,in);
DFlipFlop DFF(in,clk,reset,Q);
endmodule
module fourbitreg(D,clk,reset,enable, Q);
input[0:3] D; // Data input
input clk,reset,enable;
output [3:0]Q;
reg [3:0]Q;
wire d0,d1,d2,d3;
wire q0,q1,q2,q3;
d0 = D[0];
d1 = D[1];
d2 = D[2];
d3 = D[3];
DFF_with_Enable df0(d0,clk,reset,enable,q0);
DFF_with_Enable df1(d1,clk,reset,enable,q1);
DFF_with_Enable df2(d2,clk,reset,enable,q2);
DFF_with_Enable df3(d3,clk,reset,enable,q3);
assign Q = {q0,q1,q2,q3};
endmodule
I used iverilog for simulation. How do I fix the following errors during compilation?
design.sv:37: syntax error
design.sv:37: error: Invalid module instantiation
design.sv:38: error: Invalid module instantiation
design.sv:39: error: Invalid module instantiation
design.sv:40: error: Invalid module instantiation
The circuit of 1 DFF MUX pair is shown below.
There are multiple compile errors.
Inside DFF_with_Enable and fourbitreg, do not declare Q as a reg because you make continuous assignments to Q.
You need to use the assign keyword to make continuous assignments to d0, etc.:
assign d0 = D[0];
assign d1 = D[1];
assign d2 = D[2];
assign d3 = D[3];
You should also try different simulators on edaplayground to get more meaningful error messages.

Absolute value module in Verilog returning only unknown values

I am trying to implement a simple 16-bit absolute value module; however, I am only getting unknown values as output.
Below is the code that I've written:
module refabs(b, a);
input wire [15:0] a;
output reg signed [15:0] b;
always #* begin
b = ((a < 0) ? -a : a);
end
endmodule
module testbench;
reg [15:0] a;
wire [15:0] b;
refabs abs(b, a);
initial begin
a = -30000;
begin
$display("refabs(%x) = %x", a, b);
end
end
endmodule
The output I get is:
refabs(8ad0) = xxxx
In your example, the initial block executes with 0 delay without giving the always #* a chance to execute.
Either change your $display to $strobe, or add a delay before the $display statement.

Verilog: Assigning a localparam to a bit vector wire

I have the following Verilog code snippet:
module (...)
input wire [7:0] sw;
output wire [6:0] LED4;
output wire [6:0] LED3;
output wire [6:0] LED2;
output wire [6:0] LED1;
localparam charA = 7'b1110111;
localparam charB = 7'b0011111;
localparam charC = 7'b1001110;
localparam charD = 7'b0111101;
always # (sw)
begin
if (sw[7] == 1'b1)
begin
LED4 = charA;
LED3 = charB;
LED2 = charC;
LED1 = charD;
end
end
endmodule
On using ISPLever to compile, an error is thrown:
Assignment target LED4 must be of type reg or genvar
Assignment target LED3 must be of type reg or genvar
Assignment target LED2 must be of type reg or genvar
Assignment target LED1 must be of type reg or genvar
I am not allowed to change the type of the variables. What other way can I use to assign local parameters to the bit vector wires?
I find the constraint that you are not allowed to change the type of the variables very weird. Making them 'output reg[6:0] ...' would get rid of your errors and this would have no effect of any other part of the circuit. e.g. the code that calls your module does not care if it is a wire or reg.
But!
Even with using 'reg' your code is still wrong as you are making latches. The always(sw) is combinatorial and you should put a 'else' section in there.
To work with wires you can then use:
assign LED4 = sw[7] ? charA : <your else code>;
assign LED3 = sw[7] ? charB : <your else code>;
assign LED2 = sw[7] ? charC : <your else code>;
assign LED1 = sw[7] ? charD : <your else code>;

verilog compile error - "variable not constant"

Why am I getting error "q is not constant"?
module prv(
input [7:0]x,
input [7:0]y,
output [49:0]z
);
wire [24:0]q;
assign z=1;
genvar k;
for (k=50; k<0; k=k-1)
begin
wire [25:0]a;
assign a=0;
assign q= x;
genvar i;
for(i=0; i<8; i=i+1)
begin
if(q[0]==1)
begin
assign a=a+z;
end
assign {a,q}={a,q}>>1;
end
assign z={a[24:0],q};
end
endmodule
I'm afraid that you are trying to use Verilog the wrong way. q is a wire, not a variable (a reg) so it cannot be assigned with a value that includes itself, because that would cause a combinational loop. You are using the assign statement as if it were a regular variable assignment statement and it's not.
Declare a and q as reg, not wire. i and k don't need to be genvars variables, unless you are trying to generate logic by replicating multiple times a piece of code (description). For for loops that need to behave as regular loops (simulation only) use integer variables.
Besides, behavioral code must be enclosed in a block, let it be combinational, sequential, or initial.
A revised (but I cannot make guarantees about its workings) version of your module would be something like this:
module prv(
input wire [7:0] x,
input wire [7:0] y,
output reg [49:0] z
);
reg [24:0] q;
reg [25:0] a;
integer i,k;
initial begin
z = 1;
for (k=50; k<0; k=k-1) begin
a = 0;
q = x;
for (i=0; i<8; i=i+1) begin
if (q[0] == 1) begin
a = a + z;
end
{a,q} = {a,q}>>1;
end
z = {a[24:0],q};
end
endmodule

Signal EXCEPTION_ACCESS_VIOLATION received xilinx

I'm trying to make an arithmetic logic unit in verilog and I received the following error when I tried to simulate in ISim Simulator (No errors reported at Behavioral Check Syntax):
ERROR:Simulator:754 - Signal EXCEPTION_ACCESS_VIOLATION received
Here is the code:
module alu(
input [3:0] right,
input [3:0] left,
input [2:0] sel,
input CarryIn,
output reg CarryOut,
output reg [3:0] out
);
function [3:0] add;
input [3:0] a;
input [3:0] b;
input CarryIn;
assign add = a + b + CarryIn;
endfunction
function [3:0] substract;
input [3:0] a;
input [3:0] b;
input CarryIn;
assign subtract = a - b + (~CarryIn);
endfunction
function [3:0] AND;
input [3:0] a;
input [3:0] b;
assign AND = {1'b0 , a & b};
endfunction
function [3:0] OR;
input [3:0] a;
input [3:0] b;
assign OR = {1'b0 , a | b};
endfunction
function [3:0] XOR;
input [3:0] a;
input [3:0] b;
assign XOR = {1'b0 , a ^ b};
endfunction
function [3:0] increment;
input [3:0] a;
assign increment = a + 1;
endfunction
function [3:0] left_shift;
input [3:0] a;
assign left_shift = a << 1;
endfunction
function [3:0] right_shift;
input [3:0] a;
assign right_shift = a >> 1;
endfunction
always # (left or right or sel) begin
case (sel)
0 : {CarryOut , out} = add(left,right,CarryIn);
1 : {CarryOut , out} = substract(left,right,CarryIn);
2 : {CarryOut , out} = AND(left,right);
3 : {CarryOut , out} = OR(left,right);
4 : {CarryOut , out} = XOR(left,right) ;
5 : {CarryOut , out} = increment(left);
6 : begin
CarryOut = left[3];
out = left_shift(left);
end
7 : begin
CarryOut = left[0];
out = right_shift(left);
end
default : {CarryOut , out} = {1'b0,left};
endcase
end
endmodule
Any ideas ?
Remove the keyword assign from all your functions. assign statements are for continuous assignments that should only be declared in a module; not a task, function, initial or always.
There is a typo too. A couple places you have "substract" and should be "subtract".
You are also missing CarryIn from your sensitivity list. If your sensitivity list is not complete it will infer complex latching logic. Better yet, switch to a IEEE 1364-2001 coding style and use always #(*) or always #* instead of always # (left or right or sel or CarryIn). They auto construct the sensitivity list for combinational logic.
One of the reasons for happening this is that the simulator does not understand a syntax.
I had run into similar problem in VIVADO for a silly mistake while writing a verilog syntax. For a concatenation in verilog, mistakenly i used ":" instead of ",". That caused the same problem. To find out exactly which module is causing the problem it is good to look at the tcl console message. The module causing the problem is simply after compiling which module this message shows.
This is silly but sometimes it may take a lot of time to figure out.

Resources