Verilog [dot] meaning? - verilog

What does this " .depth_log2(7) " and .i_wclk mean in Verilog code?
asynch_fifo #(.depth_log2(7),
.data_width(22),
.rd_flop1_megedge(1'b1),
) USB2_ASYNCH_FIFO (
.i_wclk(i_usb2_sieclockin_ip),
);
I'm not able to understand what that .depth_log2 and .rd_flop1_megedge means

When you instantiate a module, such module might have some parameters. You can leave them at default, or you can initialize them at the values you prefer. In your example you are setting the depth at 7, the data width at 22 etc..
In general, if you have a verilog module like this:
module my_module
#( parameter P1 = 2,
parameter P2 = 0)
( input clk,
output reg [P1-1:0] out);
// Module logic
endmodule
You can instantiate it with the dot notation
wire wire_clk;
wire [2-1:0] wire_out;
my_module #(.P1(2),
.P2(3) ) u0
( .clk(wire_clk),
.out(wire_out);

This is called instantiation. Using this "." notation you are basically saying that you want to connect a constant 7 to depth_log2 parameter of your component asynch_fifo.

Related

Masking input unpacked array

I want to "mask" an input unpacked array given a specific signal. If that signal is 1, I want the input to be all zeroes instead of the given array.
module thing (
input clk,
input rst,
input packedBits[`PB_SIZE]
);
// ...
endmodule
module top (
input clk,
input rst
);
logic packedBits[`PB_SIZE];
mod_i thing (
.clk(clk),
.rst(rst),
// I can manually put `PB_SIZE zeroes, but I want the compiler to do it for me
.packedBits(rst ? {0,...,0} : packedBits)
)
endmodule
Putting just {0,0,0,0} when `PB_SIZE is 4 works, but how could I do it in a more generic way?
You can use the replication operator:
.packedBits(rst ? '{`PB_SIZE{0}} : packedBits)
Refer to IEEE Std 1800-2017, section 5.11 Array literals.
Here is a complete example on EDA playground. It runs on Cadence and Synopsys, but there are errors on Mentor. It seems Mentor does not support this syntax yet.
Simulators sometimes struggle with complex expressions connected to module ports. It is usually a good idea to simplify the connection using a separate signal.
`define PB_SIZE 5
module thing (input packedBits [`PB_SIZE]);
initial #1 $display("%m %p", packedBits);
endmodule
module tb;
bit rst = 1;
logic packedBits [`PB_SIZE];
logic packedBitsGated [`PB_SIZE] = rst ? '{`PB_SIZE{0}} : packedBits;
thing mod_i (.packedBits(packedBitsGated));
initial begin
packedBits = '{`PB_SIZE{1}};
#1 $display("%m %p", packedBits);
end
endmodule
This works on all 3 simulators on EDA playground.
You can use a default in an assignment patterns. Then there is no need to know its size.
.packedBits(rst ? '{default:0} : packedBits)

Passing parameters between modules in Verilog

I am trying to learn how to pass parameters in Verilog. So far I've learned that the declaration looks like this:
module funct #(parameter n = 32)
(input clk, input [n-1:0]in, input reset, input L,
input load, input shift, output reg[n-1:0] out);
I instantiate another module within that module that depends on the parameter, so I defined the parameter there as well.
module funct2 #(parameter n = 32) (
input clk,
input [n-1:0] in,
input rst,
input L,
output [n-1:0] out
);
My question is how to call funct2 within funct?
I was also wondering how I can instantiate funct within the testbench folder. Without the parameter, it looked like this
funct uut(.clk(clk),.in(in), .reset(reset),.L(L), .load(load), .shift(shift), .out(out));
The following syntax is used to instantiate funct2 within funct, passing the parameter into the module:
funct2 #(.n(n)) i1 (.clk(clk), .in(in), .rst(reset), .L(L), .out(out));
Refer to IEEE Std 1800-2017, section 23.3.2 Module instantiation syntax.
The syntax you used to instantiate funct inside the testbench is valid, as you've discovered. The default value of 32 is used in this case. Optionally, you could use the #(.n(n)) syntax to explicitly show that you are passing a parameter.

How to "publish" a module property in Verilog?

Verilog beginner's question: Is there a way a module can publish its static/constant property such as width of the address bus slice or number of internal registers? It it not a parameter, rather information inherent to the module being instantiated. Neither it is module output data.
Something like the (improper) .addr( addr[amod.AMOD_ADDR_W-1:0] ) below
module top_mod #(parameter ADDR_W = 32)
(input [ADDR_W-1:0] addr);
amod amod( .addr( addr[amod.AMOD_ADDR_W-1:0] ) );
endmodule
// ---
module amod(
input [AMOD_ADDR_W-1:0] addr
);
// AMOD_ADDR_W is amod's intrinsic property
localparam AMOD_ADDR_W = 2;
endmodule
Global defines don't seem the way to go to me.
I'd also appreciate links to some useful Verilog coding hints.
Thank you.
Verilog's elaboration process prevents parameter values from flowing up the hierarchy. In this case, there is no need to match the port width; Verilog will truncate or pad the connection as needed. So there is no need for you to do this.
In SystemVerilog, a package is the way to share parameter values between modules.
package amod_pkg;
parameter ADDR_W=2;
endpackage
module amod import amod_pkg::*; (
input [ADDR_W-1:0] addr
);
// ADDR_W is amod's intrinsic property
endmodule
// ---
module top_mod #(parameter ADDR_W = 32)
(input [ADDR_W-1:0] addr);
amod amod( .addr( addr[amod_pkg::ADDR_W-1:0] ) );
endmodule

what is the purpose #(10) in verilog instance?

Now I'm trying to understand some verilog code as the below,
dataproc #(10) proc01
(
.dout (dout01[9:0]),
.clk (clkin01),
.rst_n (rst_in01_n),
.din (dout[9:0])
);
actually I didn't get the purpose of this
#(10)
what is this? and what is the purpose in the verilog?
I'm usually using as the below way
dataproc u_dataproc
(
...
...
)
But I never been seen the before
#(10)
update
I've update the module.
module dataproc
#(parameter w = 1)
(
input clk,
input rst_n,
input [w-1:0] din,
output wire [w-1:0] dout
);
reg [w-1:0] NP_dout;
assign dout = NP_dout;
endmodule
It's a parameter, which you are overriding while making the instance of the module.
Suppose you have a module like below.
module temp();
parameter a = 2;
bit [a-1:0] b1;
endmodule
Now if you take instance of the above module and want to change the default parameter value (which in turn change the underlying hardware of that module), then you can do something like follow.
module abc();
temp t1();
temp #(4) t2(); // Changes the default parameter value
initial
begin
$display("Size of t1.b1 - %0d", $size(t1.b1));
$display("Size of t2.b1 - %0d", $size(t2.b1));
end
endmodule
// Output
Size of t1.b1 - 2
Size of t2.b1 - 4
Please note that parameters must be having a value before runtime or
in elaboration time. So you can't change parameters during simulation
run.

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.

Resources