Error while checking syntax - verilog

module mult(a, b, p);
input [16:0] a;
input [16:0] b;
output p;
wire [31:0] p;
reg i;
wire pv;
wire bp;
assign pv = 32'b0;
assign bp = {16'b0,b} ;
initial begin
for (i = 0; i < 32 ; i = i + 1)
begin
if (a[i] == 1'b1)
begin
pv <= pv + bp;
end
bp <= bp << 1 ;
end
end
assign p = pv;
endmodule
I get the following error while compiling the code,
line 37 Reference to scalar wire 'pv' is not a legal reg or variable lvalue
line 37 Illegal left hand side of nonblocking assignment
line 39 Reference to scalar wire 'bp' is not a legal reg or variable lvalue
line 39 Illegal left hand side of nonblocking assignment
Pls help.

Left hand side of assignment in always and initial blocks must be registers. pv and bp are wires instead of registers.
you cannot put a variable in left hand side of assign and always block at the same time. Because always needs registers and assign needs wires.
I see obvious semantic mistakes in your code . You need to study basics of Verilog. You put assign which means you expect a continuous assignment but an initial block is executed just once in the beginning of simulation.
By the way output is wire by default. you can declare it as output [31:0] p;

Related

Why is this line getting the error : Expecting a left parenthesis ( '(' ) [12.1.2][7.1(IEEE)]?

I have a Verilog code for a simple multiplier as shown below, which takes two 32-b inputs which are split into two (16-b MSB and 16-b LSB) and multiplied:
parameter WordLen1 = 32, WordLen2 = 16;
output [WordLen2-1:0] M;
input clk;
input signed [WordLen1-1:0] X, W1;
reg signed [WordLen1-1 :0] X_reg, W1_reg, M;
wire signed [WordLen2-1:0] mul1, mul2, M_out;
assign mul1 = X_reg[31:16] * W1_reg[31:16]; <--- 16-b MSB
assign mul2 = X_reg[15:0] * W1_reg[15:0]; <--- 16-b LSB
assign M_out = mul1 + mul2;
always#(posedge clk)
begin
X_reg <= X;
W1_reg <= W1;
M <= M_out;
end
endmodule
The testbench for the code is below:
Note : The inputs are read from two external text files having 32-b values each.
module testbench;
reg clk;
parameter WL1 = 32, WL2 = 16;
reg [WL1-1:0] Xinarray [0:1]; // define memory arrays to hold inputs
reg [WL1-1:0] W1inarray [0:1];
logic signed [WL1-1:0] X,W1; <------ Error : Expecting a left parenthesis
endmodule
I am getting the following error in my test bench:
logic signed [WL1-1:0] X,W1;
|
ncvlog: *E,EXPLPA (../src/mult_hidden_tb.v,9|11): expecting a left parenthesis ('(') [12.1.2][7.1(IEEE)].
logic signed [WL1-1:0] X,W1;
|
ncvlog: *E,EXPLPA (../src/mult_hidden_tb.v,9|17): expecting a left parenthesis ('(') [12.1.2][7.1(IEEE)].
logic signed [WL1-1:0] X,W1;
|
ncvlog: *E,EXPLPA (../src/mult_hidden_tb.v,9|24): expecting a left parenthesis ('(') [12.1.2][7.1(IEEE)].
logic signed [WL1-1:0] X,W1;
|
ncvlog: *E,EXPLPA (../src/mult_hidden_tb.v,9|27): expecting a left parenthesis ('(') [12.1.2][7.1(IEEE)].
I'm not sure what I'm doing wrong.
You need to check ncverilog tool compile the code as system verilog code, not as verilog.
"logic" data type is defined in system verilog.
But in Verilog, "logic" is not defined.
In Verilog, you can use "wire" or "reg".
So if you want to compile the code as verilog, "logic" must changed into "reg" or "wire".
But then the variable cannot be used in "always"(or "initial") and "assign" together.
In case of input port(you defined X and W1 as input at your top module), you may use "reg" used at "initial" or "always" block.

Verilog: Store bits into a specific range of bits of an initialized module

So I have been following a guide provided by EmbeddedMicro on producing a simple 16 bit CPU using their HDL Lucid. My goal is to convert this over to Verilog in Quartus II. The problem I am having is trying to store the bits allocated for the destination of my data into a specific range of bits inside the designated register. The second problem I am having is using a global Constant as one of case values. I was able to get around this by just replacing with the constant value. I have already added the include file into the project settings. I am still new to Verilog so their might be an abundant of bad code.
The error recieved is on line 57
shift_r.D[DEST] = DIN; //supposed to be storing the data coming in into register
Error Readout: Verilog Syntax Error, near text: "=". Check for and fix any syntax errors that appear immediately before or at the specified keyword
`include "CPU_8/my_incl.vh"
module CPU(CLK,RST,WRITE,READ,ADDRESS,DOUT,DIN);
input RST,CLK;
input [0:7] DIN; //DATA in
output reg [0:7] ADDRESS;
output reg [0:7] DOUT; //DATA OUT
output reg WRITE,READ;
reg [0:15] INST;
//I am not sure if i set up the array for my registers correctly either
shiftreg shift_r[0:15] (RST, CLK, D, Q); //initialize shift_r and create array of 16 registers.
//Implicit net is created for the D and Q above when generating block file
instRom_16 instRoms(ADDRESS, INST); //intialize InstRom_16 module
reg [0:3]OP; // opcode
reg [0:3]ARG1; // first arg
reg [0:3]ARG2; // second arg
reg [0:3]DEST; // destination arg
reg [0:7]CONSTANT; //Constant
always#(posedge CLK)
begin
WRITE = 0; // don't write
READ = 0; // don't read
ADDRESS = 8'b0; // don't care
DOUT = 8'b0; // don't care
instRoms.ADDRESS = shift_r.D[0]; //Set shift_reg to be program counter
shift_r.D = shift_r.Q[0] + 1; //increment program counter.
OP = instRoms.INST[15:12]; // opcode first 4 bits
DEST = instRoms.INST[11:8]; // destination one 4 bits
ARG1 = instRoms.INST[7:4]; // argument2 is next 4 bits
ARG2 = instRoms.INST[3:0]; // ARGUMENT2 is last 4 bits
CONSTANT = instRoms.INST[7:0];
//PERFORM OPERATIONS
case (OP)
4'd1: //tried to use `LOAD but that wouldn't point to the value in my include file
READ = 1; // request a read
//line that is failing
shift_r.D[DEST] = DIN; //supposed to be storing the data coming in into register
//4'd2:
endcase
end
endmodule
This is my include file
`ifndef _my_incl_vh_
`define _my_incl_vh_
`define NOP = 4'd0; // 0 filled
`define LOAD = 4'd1; // load
`endif
You made a little mistake:
shiftreg shift_r[0:15] (RST, CLK, D, Q);
Instantiates an array of shift_r, each instance of which has a RST, CLK, D and Q.
So shift_r.D[DEST] should become shift_r[DEST].D and shift_r.Q[0] should become shift_r[0].Q.
For shift_r.D, is guess you want a 0:15 vector. You will need to assign all 16 bits to an intermediate wire of 15 bits using e.g. a for loop.

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

how can i used the output of the instentiated module in verilog?

This is LSFR of 10 bits. I instentiated LSFR module in verilog. you can see in the given code below . the output of LSFR is Current State. i want to access each of its individual bits. but here i am getting 0 for Current_State. it is not updating. please any one can help me ..
module LSFR_counter #(parameter n=6)( output Reg, input clk, input reset);
//parameter n=10; // Change more than n to change LFSR length.
reg [n:1]Reg; //All procedure outputs must be registered
reg [n:1] counter ;
initial
counter =0 ;
always #(posedge clk or posedge reset)
if
(reset) Reg <=1;
else
begin
counter <= counter+1 ;
Reg <= {Reg[n-1:2], Reg[n]^Reg[1], Reg[n]};
end
endmodule
module Main( output Reg input Clock , input reset
);
reg Fgf8,Emx2,Pax6,Coup_tfi,Sp8; // Genes
reg F,E,P,C,S; // Proteins
reg [10:1] Current_State ;
LSFR_counter #(.n(10)) lsfr ( .Reg (Current_State), .clk (Clock ), .reset(reset) ) ;
Fgf8 <= Current_State[N-0] ; // Gene
F <= Current_State[N-1] ; // Protein
Emx2 <= Current_State[N-2] ;
E <= Current_State[N-3] ;
Pax6 <= Current_State[N-4] ;
P <= Current_State[N-5] ;
Coup_tfi <= Current_State[N-6] ;
C <= Current_State[N-7] ;
Sp8 <= Current_State[N-8] ;
S <= Current_State[N-9] ;
endmodule ;
Several problems in the code presented:
The Main module has an output named Reg, which is not assigned any signal. So if you are expecting to get any value out of it, you won't.
The signals Fgf8, F.. and friends are assigned, but not used. Update: Actully the assignment is incorrect. If they are supposed to be assigned synchronously (on clock cycles), it should be wrapped in always block. If you mean to have a combinatorial circuit instead, you should use the assign statement.
The variable/signal N is not defined. Verilog is case-sensitive, so n != N.
in the LSFR_counter module, the counter is not reset to initial value.
These are problems that can be seen so far.
In LSFR_counter: you are mixing ANSI and non-ANSI header styles. This is illegal syntax. Maybe your simulator/synthesizer is allowing it, but it is not supported and a bad practice.
You should use ANSI: IEEE Std 1800-2012 § 23.2.2.2 ANSI style list of port declarations
module LSFR_counter #(parameter n=6)( output reg [n:1] Reg, input clk, input reset);
reg [n:1] counter;
// ...
or non-ANSI: IEEE Std 1800-2012 § 23.2.2.1 Non-ANSI style port declarations
module LSFR_counter #(parameter n=6)( Reg, clk, reset);
output Reg;
input clk;
input reset;
reg [n:1] Reg;
reg [n:1] counter;
// ...
Non-ANSI is for IEEE Std 1364-1995 and backward comparability with In later versions of IEEE 1364 and all versions of IEEE 1800. Support for ANSI existed since IEEE Std 1364-2001.
In Main: Nothing is driving Reg. The other signals (eg: Fgf8, F, Emx2, etc.) are never declared and have illegal assignment. N is also never defined. I'll assume it is a parameter. You may declare them as reg and assign in a combinational block:
parameter N=10;
reg Fgf8,F, ... ,Sp8,S;
always #* begin
Fgf8 = Current_State[N-0] ; // Gene
F = Current_State[N-1] ; // Protein
// ...
Sp8 = Current_State[N-8] ;
S = Current_State[N-9] ;
end
Or declare as wires and assign with continuous assignment:
parameter N=10;
wire Fgf8 = Current_State[N-0] ; // Gene
wire F = Current_State[N-1] ; // Protein
// ...
wire Sp8 = Current_State[N-8] ;
wire S = Current_State[N-9] ;
Both with synthesize the same.

Two's complement in verilog

I've been trying to build a module which returns the two's complement representation of the (3-bit) input (first bit being the sign). I think that the following code is correct conceptually, but I am probably missing something about it's structure: when I try to compile, I get the following errors:
(vlog-2110) Illegal reference to net "f_o".
(vlog-2110) Illegal reference to net "f_o".
(vlog-2110) Illegal reference to net "f_o".
Searching for that error showed it is usually seen when using a variable as input and output at the same time, but that's not my case. Could you point where the error is?
module ca2 (a_i,f_o);
input [2:0] a_i;
output [2:0] f_o;
always #(a_i[2:0] or f_o[2:0])
begin
if (a_i[2] == 1)
begin
f_o[2] = a_i[2];
f_o[1:0] = (~a_i[1:0] + 'b1);
end
else
begin
f_o = a_i;
end
end
endmodule
In Verilog, undeclared identifiers are considered implicit wire declarations in most circumstances. Since f_o has not been declared the compiler considers it a wire, not a variable. This causes the compiler to complain about all the assignments.
// What was typed
module ca2 (a_i,f_o);
input [2:0] a_i;
output [2:0] f_o;
// What the compiler implicitly declares
wire [2:0] a_i;
wire [2:0] f_o;
To fix it you can declare the variable or declare both the port and the variable.
module ca2 (a_i,f_o);
input [2:0] a_i;
output [2:0] f_o;
reg [2:0] f_o;
module ca2 (a_i,f_o);
input [2:0] a_i;
output reg [2:0] f_o;
f_o needs to be declared as a reg. output reg [2:0] f_o.
Also I am not sure what you are calculating, that is not a standard twos complement.
module ca2 (
input [2:0] a_i,
output [2:0] twos_comp,
output [2:0] also_twos_comp
);
assign twos_comp = ~a_i + 1'b1;
assign also_twos_comp = -a_i ;
endmodule
You may be dealing with an encoded input, but twos_complement is to negate the number I would expect the sign bit (MSB) to change. Although we refer to it as a sign bit it also contains information about the value and therefore can not just be stripped off and leave the number unchanged.
The first solution -> In sequential circuits, the output must be in the form of a reg.
and Next we need to know that in two's complement we start from bit zero to get to the end so the condition is incorrect.
If the zero bit is one, then the zero bit is unchanged and the rest of the bits change to not.
module ca2 (input [2:0] a_i,output reg [2:0] f_o);
always #(a_i[2:0] or f_o[2:0]) begin
if (a_i[0] == 1'b1) begin
f_o[0] = a_i[0];
f_o[2:1] = (~a_i[2:1]);
end
else
if(a_i[1]==1'b1) begin
f_o[1:0] = a_i[1:0];
f_o[2] = (~a_i[2]);
end
else
if(a_i[2] == 1'b1) begin
f_o = a_i ;
end
end
endmodule
The second solution -> In binary numbers, if we subtract the number from zero, we get two's complement .
module ca2 (input [2:0] a_i,output reg [2:0] f_o);
always #(a_i[2:0] or f_o[2:0]) begin
f_o = 3'b000 - a_i ;
end
endmodule
The third solution -> all bits change to not and Finally, they are added to the number one (3'b000 = 3'b0)
module ca2 (input [2:0] a_i,output reg [2:0] f_o);
reg [2:0] finish ;
always #(a_i[2:0] or f_o[2:0]) begin
finish = (~a_i);
f_o = finish + 3'b001 ;
end
endmodule

Resources