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

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.

Related

Verilog reg assignment?

I'm totally new to Verilog programming and I do not understand where to initialize reg variables?
Let's have a look at the following snippets:
Edit:
Warning at synthesize
module test (
output LED0
);
reg led = 1'b1;
assign LED0 = led;
endmodule
or
module test (
output LED0
);
reg led;
initial begin
reg led <= 1'b1;
end
assign LED0 = led;
endmodule
Give me: Using initial value of led since it is never assigned at the line: reg led = 1'b1;
Are reg types only assigned in always# block?
Another example:
module fourBitCounter
(input clk,
output [3:0]counter
);
wire clk;
initial begin
reg[3:0] counter = 4'b1;
end
always# (posedge clk) begin
if(counter > 15)
counter <= 0;
else
counter <= counter + 1;
end endmodule
Here the reg has an initial value of 0 but I've set it before to 1... What's wrong? Thank you!
Are reg types only assigned in always# block?
No, reg types can be assigned in always blocks and initial blocks (plus task and function but I'll skip them in the scope of this question)
For your fourBitCounter, the reg[3:0] counter declared in the initial block creates a local variable also called counter that is only accessible within the scope of the block it was created in. You need to remove the reg[3:0] in the initial block so that the assignment get applied the the intended counter. But it will still not work because you declared counter as an inferred wire type and always/initial blocks cannot assign wires.
counter was declared as an output of a 4-bit inferred wire (output [3:0] counter is synonyms to output wire [3:0] counter). Since counter is assigned in an always block and initial block it needs to be a reg type. Therefore it should be declared as output reg [3:0] counter.
Also, you declared clk as in input and as a local wire, it cannot be both. Ports can be accessed locally, there is no reason to re-declare them as local nets.
FYI: for a 4-bit value, 15+1 equals 0 because there is nothing to store the MSB.
module fourBitCounter (
input clk,
output reg [3:0] counter // 'output reg', not 'output'
);
//wire clk; // do not do this, clk is an input
initial begin
counter = 4'b1; // no 'reg' here
end
always #(posedge clk) begin
if(counter > 15) // this will never evaluate as true with counter declared as 4-bit
counter <= 0;
else
counter <= counter + 1;
end
endmodule
For Verilog, assign statements can only be applied on net types (e.g. wire). This is legal:
module test ( output LED0 ); // LED0 is an inferred wire
assign LED0 = 1'b1;
endmodule
This is illegal:
module test ( output reg LED0 ); // Explicit reg
assign LED0 = 1'b1; // illegal, assign on a reg
endmodule
From your first code sample:
reg led; // <-- This declares one register called "led"
initial begin
reg led <= 1'b1; // <-- This declares a *separate* register called "led"
end // which is only valid in the initial block
The same issue exists in your second sample; you're declaring a separate register in the initial block. Don't use the keywords reg or wire if you're just trying to assign a value.

Verilog logical error

module ocircuit (ooutp,s0,s1 ,clk,write,raddA,raddB,wadd,wdata);
output [3:0] ooutp;
input clk, write,s0,s1;
input [2:0] raddA;
input [2:0] wadd;
input [2:0] raddB;
input [3:0] wdata;
reg [9:0] ooutp;
wire [3:0] dataA;
wire [3:0] dataB;
reg [9:0] inner;
regfile y (dataA,dataB,clk,write,raddA,raddB,wadd,wdata);
always #(posedge clk) begin
if (s0==0) begin
assign inner = dataA [3:0]*dataB [3:0];
end
else begin
assign inner = ((dataA [3:0]*dataB [3:0])+inner [9:0]);
end
//inner=inner1;
ooutp =s1?inner [9:0]:10'd0;
end
endmodule
This is the code. regfile is a simple register file. In the testbench, s0 = 0 during the first cycle and s0 = 1.
For subsequent cycles, this code should return the value of A*B+C*D by using one adder and one multiplier. In the first cycle, when c0 = 0, the answer that is saved in inner (a register) is right but in the second cycle, when c0 = 1 the answer is wrong.
Por example: A=1; B=2; C=1; D=1;
First cycle: x=A*B=2
Second cycle (C*D)+x=5
I think there is something wrong with this statement
assign inner = ((dataA [3:0]*dataB [3:0])+inner [9:0]);
Any help or hint will be appreciated.
Although assign can be used from within an always block, I think you just wanted to store a value into inner depending upon the value of s0. To do that, use non-blocking assignments ( <= ).
Also, you can directly output to ooutp instead of saving the final result in inner, avoiding a possible glitch in the multiplexer you instantiate here:
ooutp =s1?inner [9:0]:10'd0;
Which, by the way, it should be outside the always block, in an assign line:
assign ooutp = s1? inner [9:0]:10'd0;
module ocircuit (ooutp,s0,s1 ,clk,write,raddA,raddB,wadd,wdata);
output [3:0] ooutp;
input clk, write,s0,s1;
input [2:0] raddA;
input [2:0] wadd;
input [2:0] raddB;
input [3:0] wdata;
reg [9:0] ooutp;
wire [3:0] dataA;
wire [3:0] dataB;
reg [9:0] inner;
regfile y (dataA,dataB,clk,write,raddA,raddB,wadd,wdata);
always #(posedge clk) begin
if (s0==0) begin
inner <= dataA [3:0]*dataB [3:0];
end
else begin
ooutp <= ((dataA [3:0]*dataB [3:0])+inner [9:0]);
end
end
endmodule

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.

Register variable in port declaration in verilog

I want to make a module in Verilog which must get a 32 bit wide register variable in port. This variable will be used to count the clock cycle. Then this module will be instantiated in another module. For example: when I fix the value of counter this module must start count from that value.
When I simulate this code I get an error:
Non-net port count cannot be of mode input
module case_1( input clk , input [31:0] counter);
reg [31:0] counter;
always # (posedge clk)
begin
counter <=counter +1
end
endmodule
module counter (input clk , input [31:0] counter )
reg [31:0] counter;
case_1 h1 ( .clk(clk) , .counter(counter) )
endmodule
If a module is an input then you can not drive a value on to it. Driving a value on to an input does not make sense. It needs to be an output.
It think there might be some confusion over the reg and wire types in verilog. These types do not cross module interfaces. a lower (sub) module drives its output as a reg type. the next level up a wire is connected to the port.
From your example a clock received by counter which uses sub module case_1 to implement the counter. Counter value is then driven (first as a reg) then at the top level as a wire.
module case_1(
input clk ,
output reg [31:0] counter
);
initial begin
counter = 'b0;
end
always # (posedge clk) begin
counter <=counter +1;
end
endmodule
module counter (input clk , output wire [31:0] counter );
case_1 h1 ( .clk(clk) , . counter(counter) );
endmodule
Example on EDA Playground.

Can Verilog variables be given local scope to an always block?

I sometimes find it useful to use blocking assignments for "local variables" inside clocked always blocks. This can help cut down on repeated code.
To avoid accidentally using the same variable in a different always block (which can be non-deterministic for simulation), I'd like to give it local scope. Is there a nice synthesizable way of doing this?
Something like:
module sum3(
input clk,
input [7:0] in1,
input [7:0] in2,
input [7:0] in3,
output reg [7:0] result,
output reg [7:0] result_p1);
begin :sum
reg [7:0] sum_temp; // local variable
always #(posedge clk) begin
sum_temp = in1 + in2 + in3;
result <= sum_temp;
result_p1 <= sum_temp + 1;
end
end
endmodule
(ModelSim seems to be okay with this, but Synplify doesn't seem to like it.)
I'm not sure of the semantics in plain Verilog, but according to the SystemVerilog LRM section 6.21:
Variable declarations shall precede any statements within a procedural block.
Therefore the following is legal syntax in SystemVerilog:
module sum3(
input clk,
input [7:0] in1,
input [7:0] in2,
input [7:0] in3,
output reg [7:0] result,
output reg [7:0] result_p1);
always #(posedge clk) begin : sum
reg [7:0] sum_temp; // local variable (scope limited to process)
sum_temp = in1 + in2 + in3;
result <= sum_temp;
result_p1 <= sum_temp + 1;
end
endmodule
Note that I have moved the variable declaration sum_temp into the process, thereby limiting the scope and removing the need for the named sum block. This compiles on Modelsim and Riviera (example on EDA Playground).
If your tool doesn't support this syntax, raise a bug!
The standard sythesizable way is to use a continuous assignment with a wire:
module sum3(
input clk,
input [7:0] in1,
input [7:0] in2,
input [7:0] in3,
output reg [7:0] result,
output reg [7:0] result_p1);
wire [7:0] sum_temp = in1 + in2 + in3;
always #(posedge clk) begin
result <= sum_temp;
result_p1 <= sum_temp + 1;
end
endmodule
Despite the common guideline, using blocking assignments inside clocked always blocks is ok, and sometime as you mentioned useful. See here: https://stackoverflow.com/a/4774450/1383356
Some tools however, may not support local variables defined inside a begin-end block.
Alternatively, you can try putting some or all of the the body of the always block in a task:
task SUM_TASK();
reg [7:0] sum_temp; // local variable
sum_temp = in1 + in2 + in3;
result <= sum_temp;
result_p1 <= sum_temp + 1;
endtask
always #(posedge clk) begin
SUM_TASK();
end
Verilog tasks can have access to global variables as well as local ones. Also, they can include non-blocking assignments.

Resources