Thanos snaps his fingers to understand Verilog multidimensional arrays [Verilog Advanced Tutorial]

Chip design verification community, gathering place for chip enthusiasts, hardware-related discussion community, digital verifier planet
The four communities jointly recommend ! Nearly 500 digital IC boutique articles are included !
[Digital IC boutique article collection] learning route · basic knowledge · bus · script language · chip job search · EDA tool · low power design Verilog · STA · design · verification · FPGA · architecture · AMBA · books

[Verilog] multidimensional array

1. Write in front

This column is the fourth independent column opened by the author in addition to [Digital IC Hand Tear Code] [Digital IC Written Interview Sharing] [Digital IC Tool Analysis] . Knowledge of advanced grammar features , due to the unique positioning of its own column, the author will not involve basic Verilog language such as blocking non-blocking assignment, procedure blocks, data types, etc.; at the same time, limited by the author’s limited knowledge, this column will not Regarding the related content of System Verilog, according to the relevant IEEE standards, this column will focus on Verilog-2005, that is, “IEEE Std 1364™-2005” and the related content before , and provide relevant syntax characteristics in the field of IC design. The following is an advanced block diagram of Verilog. Readers with more learning needs can search for relevant English standards for learning.

Second, the introduction and requirements of the [array]

Usually, when we design verilog, the declaration of the port is one-dimensional, such as

input [31:0] data_in ;

Here we declare a one-dimensional variable, a 32-bit input port data_in

  • So if we need variables with two or more dimensions, is there a corresponding way to help us declare them?

The answer is yes, and it’s not meaningless. We can declare it in the following way to set up a [multidimensional array] .

input [31:0] data_in [0:127];

It should be noted that when declaring multidimensional arrays, you need to use “constant integer expressions” , which means that we cannot use decimal fractions, nor can we use non-fixed quantities such as functions to declare multidimensional arrays. At the same time, unlike most people To imagine the difference, we can use negative numbers to declare multidimensional arrays like

input [31:0] data_in [-1:127];

Although this method will not report an error , it is clear that the author does not advocate this method, and readers are welcome to discuss the reasons in the comment area.
At the same time , it should be noted that the assignment of multi-dimensional arrays is stipulated in “IEEE Std 1364™-2005”: we can assign values ​​to individual elements of the array, but we cannot assign partial or complete assignments to the array at one time . Therefore, the following ideas To mass assignment method, it is wrong

reg arrayb[7:0][0:255];
arrayb[1] = 0;
// Illegal Syntax - Attempt to write to elements
// [1][0]..[1][255]
arrayb[ 1 ][ 12:31 ] = 0;
// Illegal Syntax - Attempt to write to
// elements [1][12]..[1][31]

The correct assignment method is as follows

reg arrayb[7:0][0:255];
arrayb [ 7 ][ 1 ] = 0;

reg [31:0] data_in [0:127]
data_in[1] = 32'h010x;

  • Why is the assignment to arrayb[1]=0 wrong, but the assignment to data_in[1] is correct? Readers are also welcome to express your views in the comments section

Three, wire array

The net-type array has a strong practical significance for connecting the ports in the generate statement. The following example can illustrate the problem. The multidimensional array “t” defined here, in the instantiation process of the generate statement, uses the gate circuit form to connect.

module addergen1(co, sum, a, b, ci);
parameter SIZE = 4;
output [SIZE-1:0] sum;
output co;
input [SIZE-1:0] a, b;
input ci;
wire [SIZE :0] c;
wire [SIZE-1:0] t [1:3];
genvar i;
assign c[0] = ci;
// Hierarchical gate instance names are:
// xor gates: bit[0].g1 bit[1].g1 bit[2].g1 bit[3].g1
// bit[0].g2 bit[1].g2 bit[2].g2 bit[3].g2
// and gates: bit[0].g3 bit[1].g3 bit[2].g3 bit[3].g3
// bit[0].g4 bit[1].g4 bit[2].g4 bit[3].g4
// or gates: bit[0].g5 bit[1].g5 bit[2].g5 bit[3].g5
// Generated instances are connected with
// multidimensional nets t[1][3:0] t[2][3:0] t[3][3:0]
// (12 nets total)
generate
for(i=0; i<SIZE; i=i+1) 
begin:bit
xor g1 ( t[1][i], a[i], b[i]);
xor g2 ( sum[i], t[1][i], c[i]);
and g3 ( t[2][i], a[i], b[i]);
and g4 ( t[3][i], t[1][i], c[i]);
or g5 ( c[i+1], t[2][i], t[3][i]);
end
endgenerate
assign co = c[SIZE];

endmodule

Fourth, reg type array

The reg-type array also has a strong meaning in circuit design. Taking the register description of the RISC-V CPU as an example, it will be applied to the reg-type multi-dimensional array. Some of the registers are used to temporarily store the calculation data, and the other One part is used to configure the CPU, describe error states or save addresses and pointers.

At the same time, here we make the following distinctions. The following two arrays represent different meanings. The first one represents an n-bit register, but has only one dimension, while the second describes a 1-bit register, but has n dimensions . Different forms of description will have an impact on our assignments, and I hope readers can distinguish them well.

reg [n:1] rega; // An n-bit register is not the same
reg mema [1:n]; // as a memory of n 1-bit registers

Five, other types of arrays

In addition to the comprehensive reg type and wire type arrays, “IEEE Std 1364™-2005″ also provides other types of array declarations, ” integer, time, real, realtime” can also be declared in the form of arrays

integer inta[1:64]; // an array of 64 integer values
time chng_hist[1:1000] // an array of 1000 time values

Six, previous [Verilog] advanced tutorial articles

Leave a Comment

Your email address will not be published. Required fields are marked *