How to implement a special selector - verilog

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.

Related

Verilog select bit depending on input

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

how to implement verilog divisible by 6?

I wanna create divisible by 6 module in verilog using divisible by 2 module and divisible by 3 module, I grasped the idea, but maybe my verilog grammar is wrong.
the module structure i want to implement is below,
module Divisible_6(input [3:0] a, output out);
using
module Divisible_2(
input [3:0] a,
output out
);
module Divisible_3(
input [3:0] a,
output out
);
and if input is 6(0110), then both divisible_2 and divisible_3 output 1,
and both 1 goes in to the AND gate, then came out with 1.
1 = true, 0 = false.
how can I implement the idea in verilog language?
and help is appreciated, thanks.
input: 1~15
Since I understand question a little bit different than #Morgan, I'd rather try this code:
module Divisible_6(
input [3:0] a,
output out
);
wire out_1, out_2;
assign out = out_1 & out_2;
Divisible_2(
.a (a),
.out(out_1)
);
Divisible_3(
.a (a),
.out(out_2)
);
endmodule
I assume that both Divisible_2 and Divisible_3 take 4-bit input and return boolean value (divisible (1) or not (0)).
You need divisible by 6 design, which can only be obtained, if your input is both divisible by 2 and divisible by 3.
Hence you can use both modules, like the following code.
// Defining the nets
logic out1, out2;
// Continuous Assignment
assign out = out1 & out2;
// Instantiation of 2 modules with instance name d1 & d2
divisible_2 d1 (a, out1);
divisible_3 d2 (a, out2);

Verilog module cannot calculate a&b and a|b

I am creating the verilog module that calculate either one of a+b, a-b, a & b or a | b.
The problem is that it does calculate for a+b and a-b.
but it cannot calculate a & b and a | b and return nothing.
input [31:0] a, b;
input [2:0] op;
output [31:0] z;
output ex;
wire[31:0]a0,a1,a2,a3;
assign a0 = a & b;
assign a1 = a | b;
assign a2 = a + b;
assign a3 = a - b;
assign z=a0;
//assign z=a1;
//assign z=a2;
//assign z=a3;
endmodule
the module basically calculate a+b, a-b, a&b, and a|b and assign its calculated value to z.
And it does successfully calculate for a+b and a-b and put calculated value to z.
But for a&b and a|b, it doesn't assign anything to z.
How can I solve this?
Thank you very much if you can help me.
I'm sure it does assign something to z. The problem is that you are trying to assign too much to z.
Each assign statement represents some hardware, which in this case drives the wire z. So, you are driving z 4 times in parallel from 4 separate lumps of hardware. If you like, you have a short circuit. (Remember Verilog is a hardware description language. You are designing hardware here, not writing software. If you assign to a wire from more than one place, you have shorted the outputs of some lumps of hardware together.)
I notice there is an input [2:0] op. This looks like homework to me and I guess you have been asked to design an ALU. An ALU is a lump of hardware (combinational logic in this case) that can perform various operations on it's inputs (its operands), which in this case are a and b. Which operation it performs needs to be selected by some other control input, which in this case is almost certainly supposed to be op.
So, you need some code that tests op and drives z with either a+b, a-b, a&b or a|b. The obvious construct to me for this job is a case statement:
case (op)
3'b000:
z = // some expression, eg a + b, it depends on what op code 000 is supposed to mean
3'b001:
z = // some other expression here
// etc etc
default: // perhaps...
z = // ...something to drive z if none of the other branches are used
endcase
A case statement should go inside an always block. As I suspect this is homework, I won't feed you the answer, I'll let you work out how to do that.
Finally, I see that op is 3 bits wide. This suggests that you ALU has more than 4 different operations to carry out. I also see there is an ex output, which presumably needs to do something.
There's some confusion here. Your original posted code is fine; z will be assigned as you want. The other answer is incorrect - there are no multiple drivers; they're commented out. The delay suggestion is also incorrect - a delay will make no difference whatever to your logic.

How to write a module with variable number of ports in Verilog

I would like to write a module with a variable number of inputs, i.e. depending on some parameter, the result would be:
module my_module #(LENGTH)(
input clk,
input rst_n,
input [LENGTH-1:0] data_1
);
//...
endmodule
or
module my_module #(LENGTH)(
input clk,
input rst_n,
input [LENGTH-1:0] data_1,
input [LENGTH-1:0] data_2,
input [LENGTH-1:0] data_3
);
//...
endmodule
Would it be possible to do this in Verilog or Systemverilog or would I have to write a script, let's say in Python, in order to generate the code for a specific module with fixed number of inputs? (it might be more than 1000 inputs)
There are no variable number of ports in SystemVerilog, but you could use a port that is a parameterized array.
module my_module #(int LENGTH, DEPTH)(
input clk,
input rst_n,
input [LENGTH-1:0] data[DEPTH]
);
//...
endmodule
Otherwise, you would need to use a script to generate the code.
Use a two dimensional input with a parameterized size. Added a generate for loop that can be used to set signals individually. Although many operations can be done with smart array operations.
module my_module #(SIZE, LENGTH)(
input clk,
input rst_n,
input [SIZE-1:0][LENGTH-1:0] data_in_array,
output [SIZE-1:0][LENGTH-1:0] data_out_array
);
genvar N;
generate for (N=0; N<SIZE; N++) begin :la_coolOps
//Do cool operations here. For example instantiate a module for every data_in
end
//...
endmodule
Edit:
As Mehran Torki points out: The syntax above will work for SystemVerilog only. Verilog does not allow for multiple packed arrays. Use input [LENGTH*SIZE-1:0] data_in_array.
I would add to these other answers that ports are just groupings of wires. While having 3, 1-bit wires named a, b, and c might be easier to read and understand, there is no physical/logical difference between a single, 3-bit wire abc, where abc[0] corresponds to a, abc[1] corresponds to b, and abc[2] corresponds to c.
So, you can always just expand or shrink a single (or multiple) signal(s) to get however many bits you need. It may not be as neat, but it will work. In the receiving module, you can then part-select the bus in whatever manner you like. So, you could have one really long wire the shrinks or expands (wire [(SOME_PARAM*8)-1:0] my_input_wire), or with SystemVerilog an array (wire [7:0] my_input_wire[0:SOME_PARAM-1])
If this is just testbench/verification code, the other thing you could do in SystemVerilog is use a dynamic array
As others said, there is no direct way to do this, but another workaround is to use SystemVerilog interfaces, where you define all the inputs that you want in the interface definition and inside the module only use the ones that correspond to the parameter. Below is a sample:
module my_module #(LENGTH)(
input clk;
input rst_n;
output o;
interface i_data;
);
logic outValue;
generate
case (LENGTH) //Based on the value of LENGTH, use corresponding data
1: outValue = i_data.data_1;
2: outValue = i_data.data_1 + i_data.data_2;
3: outValue = i_data.data_1 + i_data.data_2 + i_data.data_3;
endcase
endgenerate
always #(posedge clk) begin
if (~rst_n)
o <= '0;
else
begin
o <= outValue;
end
endmodule
You can still use a parameterized array for data and a for-generate loop if your outputs are similar.
With System verilog we can import a package instead of having parameterization and define types in the package to be used in the portlist.
module mymodule
import mymodule_pkg::*;
(
input portlist_t portlist
);
endmodule
And define multiple copies of the package with different variants of the port list and compile whichever version is required. eg
package mymodule_pkg;
localparam LENGTH=5;
typedef struct packed {
logic [LENGTH-1:0] data_1,
logic [LENGTH-1:0] data_2,
logic [LENGTH-1:0] data_3
} portlist_t;
endpackage
As with the interface solution there will be situations where you run into issues, like having different iterations of the module instantiated together.

How to handle the output and input bus trans by one input in verilog?

I'd like to make a simple module in verilog
The scheme is this.
If(en)
A=B;
else
B=A;
I want to implement to verilog without clock.
Could it be possible to implement the above logic?
update
I want to sum of 2 inout ports.
But I'm not sure how. Would you let me know how can I make sum of 2 inout ports?
Module test1(
en,
A,
B,
C
);
input en;
inout [1:0] A;
inout [1:0] B;
output [3:0] C;
...
What can I do ?
...
endmodule
If(en)
A=B;
else
B=A;
You can't sum the two inout ports A and B. en determines the direction.
Consider this code:
assign A = (en) ? B : 1'bz;
assign B = (~en) ? A : 1'bz;
When en is low, B will be your output and A will be your input.
When en is high, A will be your output and B will be your input.
Your output C will be undefined when you assign the sum of A and B since either of the input is 1'bz.
assign C = A + B; // will cause undefined behavior

Resources