Verilog select bit depending on input - verilog

I am writing a behavioral verilog module where a different bit is selected based upon one of the input variables. I wrote the following code to reference the 3-S position in the D vector:
module Part4(input [3:0] D, input [1:0] S, output F);
always #(D, S)
F = D[3-S];
endmodule
This gives the following errors: "ERROR:HDLCompilers:247 - "Part4.v" line 5 Reference to scalar wire 'F' is not a legal reg or variable lvalue
ERROR:HDLCompilers:44 - "Part4.v" line 5 Illegal left hand side of blocking assignment"
How do I go about selecting a different bit based upon the input S?

If F is a wire, then you can't assign to it inside an always # block. Either change it to a reg, or do the assignment outside of an always # block like this:
module Part4(input [3:0] D, input [1:0] S, output F);
assign F = D[3-S];
endmodule

Related

wire output can be used as an inside variable?

i am learning verilog and i am doing practice questions on https://hdlbits.01xz.net/wiki.
one of the questions is:
so my answer was:
module top_module(
input a,
input b,
input c,
input d,
output out,
output out_n );
wire and_ab;
wire and_cd;
wire or_out;
and(and_ab,a,b);
and(and_cd, c, d);
or(or_out, and_ab, and_cd);
assign out= or_out;
not(out_n,or_out);
endmodule
which is correct without any doubt, but their answer is:
module top_module (
input a,
input b,
input c,
input d,
output out,
output out_n );
wire w1, w2; // Declare two wires (named w1 and w2)
assign w1 = a&b; // First AND gate
assign w2 = c&d; // Second AND gate
assign out = w1|w2; // OR gate: Feeds both 'out' and the NOT gate
assign out_n = ~out; // NOT gate
endmodule
my question is how can it be possible they use 'output' wire as an 'input' to an assign in the same module? its not reg to hold it value, not that i know if you can do it with reg as an 'output' type.
Verilog and SV allow the reading of outputs from within a module.
It is different than VHDL which does not allow the same.

Verilog: Interface Module Input With a Reg

In the following code:
wire a;
reg b;
assign a = b;
ModuleName foo(a, other wire inputs, ... , wire outputs);
Assume that they are part of a top level module.
I wanted to run an always# block but make changes in the input of a module instantiated in this module.
always#(*) b = c^d; //Some Logic
The thing is, they are wires and cannot be on the LHS in an always# block. Can I make changes to band expect to see them in a i.e. the input of the Module foo.
Yes. Every time you change b, a will change too. That is what an assign statement does. Remember this is hardware. The statement
assign a = b;
means 'drive wire a with whatever value reg b has for all time'.

How do you manipulate input arrays in an always block (verilog)?

I'm very new to verilog and i'm just starting to understand how it works.
I want to manipulate an input to a module mant[22:0], in an always block but I am not sure how to go about it.
module normalize(mant,exp,mant_norm,exp_norm);
input [22:0]mant;
input [7:0]exp;
output [22:0]mant_norm;
output [7:0]exp_norm;
reg mantreg[22:0];
reg count=0;
always#(mant or exp)
begin
mantreg<=mant; //this gives an error
if(mant[22]==0)
begin
mant<={mant[21:0],1'b0};//this also gives an error
count<=count+1;
end
end
endmodule
so i have to shift the mant register if the bit22 is zero and count the number of shifts. I am so confused about when to use reg and when to use wire and how to do the manipulation. please help let me know how to go about it.
As you can see in your code you are assigning vector value (mant) to array of 23(mantreg). Instead you should declare mantreg as reg [22:0] mantreg (which is vector of 23 bit).
Wire type variable can not be assigned procedurally. They are used only in continues assignment. Other way around reg varible can only be procedural assigned.
For that try to read out LRM of Verilog .

How to implement a special selector

Is it possible to write a module with 3 wires a,b,c that would output either :
z (disconnected) if a=b=c=z
a if a=(0 or 1) and b=c=z
b if b=(0 or 1) and a=c=z
c if c=(0 or 1) and a=b=z
x (dont care) otherwise
In verilog?
If you have three nets all driving the same wire then this will get what you want in simulation:
module three_drive(
input a,
input b,
input c,
output d);
assign d=a;
assign d=b;
assign d=c;
endmodule
However, I don't know what the synthesis would do with that.
It sounds to me like what you really want is to take these three signals and short them together on the input to your FPGA.
If you don't care what the result is if no one is driving it, then nguthrie has the correct answer. If it needs to be x if it's not driven, then you can do:
module three_drive(
input a,
input b,
input c,
output d);
wire temp;
assign temp=a;
assign temp=b;
assign temp=c;
assign d = (temp === 1'bz) ? 1'bx : temp;
endmodule
The above is not synthesizable, but it would get the simulation behavior you are looking for.

adder in verilog

I am designing an adder in Verilog. It will have two inputs of size N and two outputs. The first output has a size of 2N and the second has a size of K.
This is what I have so far:
module adder(
out,
CCR,
inA,
inB
);
parameter N=8,CCR_size=8;
parameter M=2*N;
input [N-1:0] inA,inB;
output [M-1:0] out;
output [CCR_size-1:0] CCR;
reg [N:0] temp;
always #(inA or inB)
begin
temp = inA+inB;
CCR[0] = temp[N];
out[N-1:0]= temp[N-1:0];
out[M-1:N]= 'b0;
end
endmodule
Moved from comment:
However this didn't compile. I have errors in line
CCR[0],out[N-1:0] and out[M-1:N]
# Error: VCP2858 adder.v : (16, 20): CCR[0] is not a valid left-hand side of a procedural assignment.
# Error: VCP2858 adder.v : (17, 28): out[N-1:0] is not a valid left-hand side of a procedural assignment.
# Error: VCP2858 adder.v : (18, 20): out[M-1:N] is not a valid left-hand side of a procedural assignment.
What is wrong with the above code?
Register data types are used as variables in procedural blocks.
A register data type must be used when the signal is on the left-hand side of a procedural assignment.
Since the default type of ports is wire you get an error.
Changing your output ports to type reg should solve the problem.
output reg[M-1:0] out;
output reg[CCR_size-1:0] CCR;
Including the answer from #damage declaring the outputs as reg types, you also have CCR defined as 8 bits wide and then only assign the LSB.
The Bit growth from an Adder is 1 bit over the largest input.
I would implement as:
module adder(
parameter N =8,
parameter CCR_size=8
)(
input [N-1:0] inA,
input [N-1:0] inB,
output [2*N-1:0] out,
output reg [CCR_size-1:0] CCR,
);
reg [n:0] sum;
always #* begin
{CCR, sum} = inA + inB;
end
assign out = sum; //Will Zero pad
endmodule

Resources