Error (10734): Verilog HDL error at SWSelector.v(13): selector is not a constant - verilog

Referring to my previous post:
Error (10482): VHDL error: object "select_vector" is used but not declared
I converted my code from VHDL to verilog, but I'm getting this error now:
(Error (10734): Verilog HDL error at SWSelector.v(13): selector is not
a constant),
Any suggestions how do I deal with it? There are 8 possibilities for selector switch which are coming from a decoder. So whenever the value of selector matches 3'b000, I want rq to be assigned to requests. Here is my code:
module SWSelector(
input [7:0] rq,
input [2:0] selector,
output [7:0] request
);
localparam NUM=3'b000;
generate
genvar i;
for(i=0;i<7;i=i+1)
begin: label
if(selector == NUM)
begin
assign request[i] = rq[i];
end
else
begin
assign request[i]=0;
end
end
endgenerate
endmodule

Since your if-statement is in a generate, you're asking the tool to pre-evaluate what selector is set to in order to figure out selecter == NUM evaluates to, but your tool doesn't know because it's a signal, not a parameter.
You want to use the generate to create an always block that you can check the value of selector in, like so:
module SWSelector(
input [7:0] rq,
input [2:0] selector,
output reg [7:0] request
);
localparam NUM=3'b000;
generate
genvar i;
for(i=0;i<7;i=i+1)
begin: label
always #* begin
if(selector == NUM)
request[i] = rq[i];
else
request[i]=0;
end
end
endgenerate
endmodule
Or, as toolic said, you can use a ternary and an assign.
Edit:
Without generate:
module SWSelector(
input [7:0] rq,
input [2:0] selector,
output reg [7:0] request
);
localparam NUM=3'b000;
integer i;
always #* begin
for(i=0;i<7;i=i+1)
if(selector == NUM)
request[i] = rq[i];
else
request[i]=0;
end
endmodule

Related

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 error: not a valid l-value

I'm trying to test if a wire(s) is on or not to signify if there is an error/overflow in my alu code. Given this code:
output reg[3:0]x; // line 149
output wire error;
output wire overflow;
always #* begin
if(error || overflow) begin
assign x = 4'b1111; // line 155
assign error = ~error;
assign overflow = ~overflow;
end else begin
assign x = opcode;
end
end
I get following error messages:
uut is my instantiation unit in my testbench called main
The code in the example has several issues.
1) you tried to use 'procedural assignments' which is an advanced verilog topic. In other words assign statement inside of an always block. This is not synthesizable, can only be used on reg types, and is there in verilog for very special cases. Do not use it.
You error messages coming from the fact that error and overflow are declared as wire.
2) you are trying to assign inverted version of a value to itself in a non-clocked logic. It will not behave the way you expect. Depending on usage it can either not toggle or will cause an infinite zero-delay loop, or in your case it could just generate a glitch.
So, potentially, your code should look something like the following:
input wire clk; // << you need clock
output reg[3:0]x; // line 149
output wire error;
output wire overflow;
reg error_reg, overflow_reg;
always #(posedge clk) begin
if(error || overflow) begin
x <= 4'b1111; // line 155
error_reg <= ~error;
overflow_reg <= ~overflow;
end else begin
x <= opcode;
end
assign error = error_reg;
assign overflow = overflow_reg;
end
Your using the assign incorrectly. That can be used outside of a always process, but not inside of one.
Also, the type wire, is required for an assign
wire [3:0] x;
assign x = 4'b1111;
Inside the always process, remove the assign statement and just say
reg [3:0] x; // Note that this is assigned as a reg now
always #* begin
if(blah) begin
x = 4'b1111;
end else begin
x = opcode;
end
end

Error (10219): Verilog HDL Continuous Assignment error at Mux.v(19): object "muxout" on left-hand side of assignment must have a net type

I want to make Frequency Divider with Counter and MUX.
I make 3 module for project
// 4-bit Counter
module Counter (input clk, input reset, output reg[3:0] out);
always#(posedge clk or posedge reset)
begin
if(reset)
out = 4'b0000;
else
begin
if(clk)
if(out < 4'b1111)
out = out + 4'b0001;
else
out = 4'b0000;
end
end
endmodule
//module 4by1 Mux
module Mux (input [3:0] muxin , input [1:0] sel, output reg muxout);
function _4by1mux;
input [3:0] muxin;
input [1:0] sel;
case (sel)
2'b00 : _4by1mux = muxin[0];
2'b01 : _4by1mux = muxin[1];
2'b10 : _4by1mux = muxin[2];
2'b11 : _4by1mux = muxin[3];
endcase
endfunction
assign muxout = _4by1mux(muxin, sel);
endmodule
//module freqDivider
module freqDivider(input clk, input reset, input [1:0] sel, output reg muxout);
wire [3:0]counterbus;
Counter ct1 (clk, reset, counterbus);
Mux mux1 (counterbus, sel, muxout);
endmodule
module freqDivider is top, and I call module Counter and Mux
but module Mux has problem with
Error (10219): Verilog HDL Continuous Assignment error at Mux.v(19):
object "muxout" on left-hand side of assignment must have a net type
this error
ps. input sel will be changed by time
The error is a result of the muxout output having type reg instead of type wire. In verilog, lines can have two overarching types, either nets (like wire type) or variables (like reg types). To assign values/logic to net types, you need to use assign statements and not always blocks. To assign values/logic to variable types, you can only use always blocks and not assign statements. So, you can either make your assign in the Mux module an always block or, for an easier solution, don't make the muxout output a reg, just leave out the reg keyword and it will be a wire.
Error is that you have declared mux_out as reg type, instead of wire type. Default type of any port is wire. You are doing continuous assignment on that net through assign keyword. And on reg type nets, assignment can only be done inside procedural block (initial, always).
Change to mux_out from output reg to output only.

How to store input into reg from wire in verilog?

I' trying to store value from wire named 'in' into reg 'a'.
But, the problem is value of reg 'a' is showing 'xxxx' in simulator. However, value of wire 'in' is showing correctly.
My target is just to read value from input wire and store it into a register.
module test(
input [3:0] in,
output [3:0] out
);
reg [3:0] a;
initial
begin
a = in;
end
endmodule
The reason why the value of a is 'xxxx' in the simulation is probably that a is set to the value of in only a single time initially, and a may not yet have been set to any specific value at this time in the simulation.
Declaring a reg in Verilog does not necessarily mean that a hardware register is described by the code. That usually involves the use of a clock signal:
module test(
input clk,
input [3:0] in,
output [3:0] out
);
// this describes a register with input "in" and output "a"
reg [3:0] a;
always #(posedge clk) begin
a <= in;
end
// I assume you want "a" to be the output of the module
assign out = a;
endmodule
Here is a counter example where a reg is used to describe something which is not a register, but only a simple wire:
module not_a_register(
input in,
output out
);
reg a;
always #(in) begin
a <= in;
end
assign out = a;
endmodule
Also note that I have used the non-blocking assignment operator <= inside the always block, which is good practice when describing synchronous logic. You can read more about it here.

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