Use of wire inside an always block? - verilog

Can I use a wire inside an always block?
Like for example:
wire [3:0]a;
assign a=3;
always #(c)
begin
d=a+c;
end
It got compiled without throwing any error. Why?

Yes, you can use a wire's value inside an always block, you just can not assign a value to a wire in always or initial block.
The only real difference between a wire and reg is the syntax for assigning values.
In the above example d could also have been created as a wire, these are equivalent:
reg [3:0] answer_reg;
always #* begin
answer_reg = a + c;
end
wire [3:0] answer_wire;
assign answer_wire = a + c;

Related

I am getting unknown value when doing a 4 bit shifter verilog (gate level)

I am trying to implement a 4 bit right shifter using gate level but i got unknown result for some reason, my mux work ok but when i try testbench for my shifter it give back something like this:
a=0010 b=01 c=0000
a=1111 b=01 c=00xx
Please help!!!! Thank you very much
module mux2(a,b,sel,c);
output c;
input a,b,sel;
wire net0,net1,net2;
not m1(net0,sel);
and m2(net1,a,net0);
and m3(net2,b,sel);
or m4(c,net1,net2);
endmodule
module mux4(a,sel,c);
output c;
input [1:0]sel;
input[3:0]a;
wire mux_1,mux_2;
mux2 m1(a[3],a[2],sel[0],mux_1);
mux2 m2(a[1],a[0],sel[0],mux_2);
mux2 m3(mux_1,mux_2,sel[1],c);
endmodule
module shift4bitright(c,a,b);
output [3:0]c;
input [3:0]a;
input [1:0]b;
wire [3:0]d=4'h0,d1=4'h0,d2=4'h0,d3=4'h0;
assign d[0]=a[3];
assign d1[0]=a[2]; assign d1[1]=a[3];
assign d2[0]=a[1]; assign d2[1]=a[2]; assign d2[2]=a[3];
assign d3[0]=a[0]; assign d3[1]=a[1];assign d3[2]=a[2];assign d3[3]=a[3];
mux4 m1(d,b,c[3]);
mux4 m2(d1,b,c[2]);
mux4 m3(d2,b,c[1]);
mux4 m4(d3,b,c[0]);
endmodule
`timescale 10ns/1ns
module shift4bitright_tb;
wire [3:0]c;
reg [3:0]a;
reg [1:0]b;
shift4bitright s1(.c(c),.a(a),.b(b));
initial begin
$monitor("a=%b b=%b c=%b",a,b,c);
a=4'h2;
b=2'd1;
#50
a=4'hf;
b=2'd1;
end
endmodule
This statement declared a wire type signal d as well as its driver cone (NOT initial value), which is a constant 0 in this case:
wire [3:0]d=4'h0;
Just below it, there's another a[3] driving d[0]:
assign d[0]=a[3];
This creates a multi-driven logic, hence x occurs.
To solve it, change it similar to:
wire [3:0] d;
assign d = {3'h0, a[3]};

How do we declare wires (interconnections in a digital circuit) when we want to use them in an always block?

I want to declare a wire and also i want to use it in an always block. This wire is the output of a bcd adder which goes to a decoder as an input. How should I declare it? wire reg A, reg A, Output reg A, input reg A?
declare it as Output reg A. It will work.
If it is a wire having a value driven on to it then you can not override the value.
You can use the value in an always block. If you are setting a value from and only from the always block declare as a reg.
wire dout;
reg dat;
modulex instance_1 (.dout( dout) );
always #* begin
dat = dout ;
end
NB: in modulex dout may be declared as a wire or a reg, it is specific to the module and does not have to maintain 'type' across hierarchy.

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.

Problems assigning to LEDs in a case block [duplicate]

This question already has an answer here:
Using a continous assignment in a Verilog procedure?
(1 answer)
Closed 10 months ago.
When I enter something like this:
always #* begin
case(SW[17])
1'b0: assign LEDG = SW[7:0];
1'b1: assign LEDG = SW[15:8];
endcase
end
where LEDG is set of [7:0] green LEDs, I get the error:
Error (10137): Verilog HDL Procedural Assignment error at
part2.v(20): object "LEDG" on left-hand side of assignment must have a
variable data type
upon trying to compile. However, when I put a similar assignment statement outside the case block, such as:
assign LEDG = SW[7:0];
it assigns just fine. I can't seem to figure out the issue.
My guess is you have declared LEDG as
wire [7:0] LEDG;
Change it to
reg [7:0] rLEDG;
wire [7:0] LEDG;
assign LEDG = rLEDG;
Your always block should now assign rLEDG.
Basically, always blocks cannot assign to wires, only regs. assign statements on the other hand, assign to wires not regs.
Assign statements can't be used inside an always block. Remove 'assign' from the line and change your 'output [7:0] LEDG' array to 'output reg [7:0] LEDG' . A reg data type must be used inside always blocks.
Using an assign like that you are most likely not doing what you expect. See using-a-continous-assignment-in-a-verilog-procedure for an explanation of what your currently doing.
To expand in DJZygotes answer, LEDG must be a wire for continuous assign or reg for assignment in an always or initial block.
wire [7:0] LEDG;
assign LEDG = SW[7:0];
Or:
reg [7:0] LEDG;
always #* begin
case(SW[17])
1'b0: LEDG = SW[7:0];
1'b1: LEDG = SW[15:8];
endcase
end

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