Tutorial sa mga Array ng Verilog: Mula sa mga Pangunahing Kaalaman hanggang sa mga Advanced na Teknik sa SystemVerilog

目次

1. Panimula

Ang Verilog ay malawakang ginagamit bilang isang hardware description language (HDL) at hindi mapapalitan sa disenyo ng circuit para sa pag-develop ng FPGA at ASIC. Upang magdisenyo nang epektibo gamit ang Verilog, mahalaga ang matibay na pag-unawa sa arrays. Sa pamamagitan ng paggamit ng arrays, maaari mong pamahalaan ang mga koleksyon ng data sa isang maikli at madaling maintindihang paraan, na nagpapabuti sa nababasa at napapanatiling mga paglalarawan ng iyong circuit. Ang mga arrays ay lalo na epektibo kapag nag-grupo ng maraming signal o nagrerepresenta ng mga estruktura ng memorya tulad ng RAM. Ang artikulong ito ay nakatuon sa salitang-ugat na “Verilog arrays” at nagbibigay ng komprehensibong paliwanag mula sa mga batayan ng pagdeklara ng array hanggang sa mga praktikal na teknik sa aplikasyon. Tatalakayin namin ang mga uri ng array, mga pagpapahusay ng SystemVerilog, mga karaniwang error, at mga FAQ upang mapalalim ang iyong pag-unawa. Maging ang mga baguhan ay makakahanap ng gabay na ito na madaling maintindihan, dahil naglalaman ito ng mga praktikal na halimbawa ng code sa kabuuan. Basahin hanggang sa huli para sa kumpletong pangkalahatang-ideya.

2. Pangunahing Uri ng Data sa Verilog

Bago magtrabaho sa mga arrays sa Verilog, mahalagang maunawaan ang pangunahing uri ng data. Ang Verilog ay nagbibigay ng ilang mahahalagang uri ng data para sa paghawak ng mga logic signal na ginagamit sa disenyo ng circuit.

Pagkakaiba sa pagitan ng reg at wire

Ang pinakaginagamit na mga uri ng data sa Verilog ay ang “reg” (register) at “wire.” Dapat silang gamitin nang tama depende sa pag-uugali ng mga logic signal.
  • wire type Ang wire ay ginagamit bilang linya ng koneksyon sa pagitan ng mga module o circuit. Dapat ito ay laging pinapagana ng ibang signal, at ang mga assignment ay ginagawa gamit ang assign statement. Angkop para sa mga output ng combinational circuit. Halimbawa:
  wire a;
  assign a = b & c;
  • reg type Ang reg ay ginagamit bilang variable para pansamantalang maglaman ng mga halaga. Ito ay ina-assign sa loob ng mga process block tulad ng always, at karaniwang ginagamit upang magmodelo ng mga storage element (latches o flip-flops). Halimbawa:
  reg q;
  always @(posedge clk) begin
      q <= d;
  end

Mga Uri ng Data na Maaaring Gamitin sa Arrays

Sa Verilog, kadalasang dine-define ang mga arrays gamit ang uri na reg, bagaman maaari ring gamitin ang wire arrays sa ilang kaso. Gayunpaman, ang mga naunang bersyon ng Verilog ay hindi sumusuporta sa multidimensional arrays. Ang limitasyong ito ay malaki ang pagbuti sa SystemVerilog. Narito ang isang simpleng halimbawa ng syntax ng array:
reg [7:0] data_array [0:15];  // An array storing 16 elements, each 8 bits wide
Sa pag-unawa sa mga batayang uri ng data, maiiwasan mo ang kalituhan sa pagdeklara at paggamit ng mga arrays. Ang maling paggamit ng reg at wire ay maaaring magdulot ng mga error sa simulation o synthesis, kaya mag-ingat.

3. Pangunahing Konsepto ng Arrays

Sa Verilog, ang array ay ginagamit kapag nais mong pamahalaan nang sabay-sabay ang maraming signal na pareho ang uri. Ang mga arrays ay nagpapadali sa pag-aayos ng mga signal, na nagpapabuti sa nababasa at muling magamit na code.

Pagdeklara ng Arrays

Ang Verilog ay pangunahing sumusuporta sa one-dimensional arrays. Ang syntax ay ganito:
reg [bit-width] array_name [index-range];
Halimbawa:
reg [7:0] data_array [0:15];  // An array of 16 elements, each storing 8-bit data
Sa kasong ito, ang data_array ay may 16 na elemento na may index mula 0 hanggang 15, kung saan ang bawat elemento ay nag-iimbak ng 8-bit na halaga (1 byte).

Pag-access sa mga Elemento ng Array

Maaari mong i-access ang bawat elemento ng isang array sa pamamagitan ng pagbanggit ng kanyang index number. Katulad ng C, ang mga index ng array ay nagsisimula sa 0.
data_array[0] = 8'hFF;   // Assign hexadecimal FF to the first element
data_array[1] = 8'd12;   // Assign decimal 12 to the second element
Maaari mo ring gamitin ang isang loop sa loob ng always block upang i-initialize o manipulahin ang mga arrays.
integer i;
always @(posedge clk) begin
    for (i = 0; i < 16; i = i + 1) begin
        data_array[i] <= 8'd0;
    end
end

Mga Bentahe ng Arrays

  • Batch processing : Sa pamamagitan ng for loop, maaari mong ilapat ang parehong operasyon sa maraming signal nang sabay.
  • Structured circuits : Tinutulungan ng mga array na ayusin ang maraming rehistro o signal, pinananatiling malinaw ang representasyon ng circuit.
  • Memory modeling : Maaari kang magpatupad ng simpleng estruktura ng memorya tulad ng RAM o ROM (ipinaliwanag sa susunod na kabanata).

Mga Dapat Tandaan

Sa Verilog, hindi mo maaaring mag-assign ng halaga sa buong array nang direkta (hal., data_array = value). Sa halip, kailangang gawin ang mga operasyon elemento-por-elemento. Gayundin, tanging one-dimensional na mga array lamang ang opisyal na sinusuportahan sa maagang bersyon ng Verilog, kaya para sa multidimensional na mga array kailangan mo ng Verilog 2001 o SystemVerilog.

4. Paggamit ng Multidimensional na mga Array

Ang mga array sa Verilog ay nagpapadali ng disenyo at tumutulong sa pag-aayos ng mga estruktura ng circuit. Sa pamamagitan ng paggamit ng multidimensional na mga array, maaari mong epektibong pangasiwaan ang mas kumplikadong mga istruktura ng datos. Gayunpaman, tandaan na ang lumang Verilog (IEEE 1364-1995) ay hindi sumusuporta sa multidimensional na mga array. Ito ay opisyal na ipinakilala sa Verilog 2001. Para sa mas malaking kakayahang magamit, inirerekomenda ang SystemVerilog.

Pagdeklara ng Multidimensional na mga Array

Mula sa Verilog 2001, maaari kang magtakda ng multidimensional na mga array sa pamamagitan ng pagtukoy ng maraming indeks para sa isang variable. Ang pangunahing syntax ay:
reg [7:0] matrix [0:3][0:3];  // Defines a 4×4 matrix of 8-bit elements
Ang deklarasyong ito ay lumilikha ng 2D na array na tinatawag na matrix, na may 16 na elemento, bawat isa ay 8 bits ang lapad.

Pag-access at Pag-assign ng mga Elemento

Maaari mong i-access at i-assign ang mga tiyak na elemento ng isang multidimensional na array gamit ang mga indeks:
matrix[0][0] = 8'hA5;
matrix[2][3] = 8'd255;

Paggamit ng for Loops

Ang mga multidimensional na array ay maaaring manipulahin gamit ang nested na for loops. Halimbawa ng inisyal na pag-set:
integer i, j;
always @(posedge clk) begin
    for (i = 0; i < 4; i = i + 1) begin
        for (j = 0; j < 4; j = j + 1) begin
            matrix[i][j] <= 8'd0;
        end
    end
end

Mga Aplikasyon ng Multidimensional na mga Array

  • Kapaki-pakinabang sa mga disenyo na nangangailangan ng matrix operations o filter processing.
  • Maaaring ilapat sa image processing o digital signal processing (DSP), para sa paghawak ng data sa antas ng pixel.
  • Ginagamit sa ROM/RAM block structures at sa pag-aayos ng address-data pairs.

Mga Limitasyon at Pagsasaalang-alang

  • Suriin ang compatibility ng synthesis tool, dahil maaaring hindi ganap na suportahan ng ilang tool ang multidimensional na mga array.
  • Maaaring may mga restriksyon kapag pinagsama sa mga instantiation o interface.
  • Unawain ang mga pagkakaiba mula sa SystemVerilog upang maiwasan ang mga isyu sa compatibility (ipinaliwanag mamaya).

5. Pagmomodelo ng Memorya gamit ang mga Array

Sa Verilog, maaari kang magmodelo ng simpleng estruktura ng memorya gamit ang mga array. Pinapayagan ka nitong ilarawan at i-simulate ang mga storage circuit tulad ng RAM at ROM sa isang maikli at flexible na paraan. Lalo na, ang mga one-dimensional na memory model na batay sa array ay karaniwang ginagamit sa disenyo ng CPU at mga communication system.

Pangunahing Syntax para sa mga Memory Model

Ang sumusunod na halimbawa ay kumakatawan sa isang simpleng RAM na may 32-bit na mga salita at 1024 na address (0–1023):
reg [31:0] memory [0:1023];  // 32-bit × 1024-word memory
Ang deklarasyong ito ay lumilikha ng isang array na tinatawag na memory, kung saan ang bawat index (address) ay nag-iimbak ng 32-bit na salita.

Pagsusulat at Pagbabasa mula sa Memorya

Ang mga operasyon ng pagbabasa/pagsusulat sa memorya gamit ang mga array ay maaaring ilarawan tulad ng sumusunod:
// Write operation
always @(posedge clk) begin
    if (we) begin
        memory[addr] <= data_in;
    end
end

// Read operation
assign data_out = memory[addr];
Mga mahahalagang punto:
  • Ang mga operasyon ng pagsulat ay synchronous sa posedge clk at kondisyonal (kinokontrol ng we, write enable).
  • Ang mga operasyon ng pagbabasa ay karaniwang ipinatupad gamit ang assign para sa combinational (asynchronous) reads.

Inisyal na Pag-setup ng Memorya

Para sa mga testbench o initial state setup, maaari mong i-initialize ang mga array sa loob ng isang initial block:
integer i;
initial begin
    for (i = 0; i < 1024; i = i + 1) begin
        memory[i] = 32'd0;
    end
end
Maaari mo ring mag-load ng mga paunang halaga mula sa isang panlabas na file gamit ang $readmemh o $readmemb:
initial begin
    $readmemh("rom_init.hex", memory);  // Initialize from a hex file
end

Praktikal na Mga Halimbawa ng Paggamit

  • Mga register file sa mga CPU o microcontroller
  • Behavioral simulation ng Block RAM (BRAM) sa loob ng mga FPGA
  • Pagpapatunay ng pag-uugali ng cache memory
  • Simulasyon ng pagbasa ng ROM data

Mga Punto na Dapat Tandaan

  • Habang lumalaki ang sukat ng array, oras ng simulation at mga resources ng synthesis ay lumalaki rin.
  • Pumili ng timing ng pagbasa ( synchronous vs. asynchronous ) nang maingat batay sa mga espesipikasyon ng disenyo at mga tool.
  • Kapag nagta-target ng synthesis, sundin ang mga tiyak na patakaran sa memory inference na inirerekomenda ng vendor ng tool.

6. Mga Pagpapahusay ng Array sa SystemVerilog

Hanggang Verilog 2001, limitado ang functionality ng array, na madalas nagiging magulo ang mga disenyo. Upang tugunan ito, nagpakilala ang SystemVerilog ng mahahalagang pagpapahusay, na nagbibigay-daan sa mas flexible at makapangyarihang paghawak ng array. Ipinaliwanag ng seksyong ito ang tatlong pangunahing uri ng array na available sa SystemVerilog: dynamic arrays, associative arrays, at queues. Tatalakayin namin ang kanilang mga tampok at mga halimbawa ng paggamit.

Dynamic Arrays

Mga Tampok

  • Maaaring baguhin ang sukat ng array habang tumatakbo.
  • Kapaki-pakinabang kapag ang sukat ay hindi alam nang pauna o nagbabago habang isinasagawa.

Deklarasyon at Halimbawa

int dyn_array[];             // Declare a dynamic array
dyn_array = new[10];         // Initialize with 10 elements
dyn_array[0] = 100;

Mga Halimbawa ng Paggamit

  • Pansamantalang pag-iimbak ng data sa mga testbench
  • Pamamahala ng mga buffer na may variable na sukat

Associative Arrays

Mga Tampok

  • Ang mga index ay maaaring arbitraryong halaga (integers, strings, atbp.).
  • Gumagana tulad ng hash table.

Deklarasyon at Halimbawa

int assoc_array[string];     // Associative array using strings as keys
assoc_array["id_001"] = 42;

Mga Halimbawa ng Paggamit

  • Pag-iimbak ng mga configuration value para sa mga parameter
  • Paghahanap ng mga halaga ayon sa ID o pangalan

Queues

Mga Tampok

  • Kumilos tulad ng FIFO (First-In, First-Out) na istruktura.
  • Sumusuporta sa madaling pagpasok at pag-alis, perpekto para sa mga dynamic na data stream.

Deklarasyon at Halimbawa

int queue_array[$];          // Declare a queue array

queue_array.push_back(10);   // Add element at the end
queue_array.push_front(5);   // Add element at the front
int val = queue_array.pop_front();  // Remove element from the front

Mga Halimbawa ng Paggamit

  • Pansamantalang pag-iimbak ng data (FIFO buffers)
  • Paghawak ng mga pangyayari at pamamahala ng transaksyon

Paghahambing at Paggamit

Uri ng ArrayResizableUri ng IndexPinakamahusay Para
Dinamikong ArrayOoIntegerKapag hindi kilala o variable ang sukat
Kakabit na ArrayOoAnumang (int, string, atbp.)Mga paghahanap na katulad ng hash table
QueueOoOtomatiko (harapan/likod)Madaling pagpasok/pag-alis

Mga Punto na Dapat Tandaan

  • Ang mga pinahusay na array na ito ay mga tampok na eksklusibo sa SystemVerilog at hindi available sa Verilog.
  • Ang lawak ng suporta sa synthesis ay nakadepende sa tool, at ito ay karaniwang ginagamit para sa mga testbench.
  • Kung nagta-target ng FPGA o ASIC, laging suriin kung sinusuportahan ang mga tampok na ito bago mag-implement.

7. Mga Pinakamainam na Kasanayan para sa Operasyon ng Array

Kapag nagtatrabaho sa mga array sa Verilog o SystemVerilog, ang pagtutok sa epektibo at nababasang pag-coding ay direktang nagdudulot ng mas mataas na kalidad ng disenyo ng hardware. Itong kabanata ay naglalahad ng mga pinakamainam na kasanayan para sa ligtas at epektibong paghawak ng mga array.

Linawin ang Layunin gamit ang mga Komento at Pangalan

Bagaman ang mga array ay scalable at maginhawa, hindi palaging halata kung ano ang kinakatawan ng bawat elemento. Upang maiwasan ang kalituhan, sundin ang mga gabay na ito:
  • Gumamit ng makabuluhang pangalan para sa mga array: reg [7:0] sensor_data [0:7];
  • Magdagdag ng mga komento upang ilarawan ang layunin o mga yunit:
// Stores 8-bit data from 8 sensors
reg [7:0] sensor_data [0:7];

Mag-ingat sa mga Hangganan ng Loop

Kapag gumagamit ng for loops upang manipulahin ang mga array, kritikal na tukuyin nang tama ang mga hangganan ng index:
  • Maling itaas na limitasyon → out-of-range na pag-access (mga error sa lohika o babala ng simulator)
  • Maingat na magpasya kung gagamit ng < o <= para sa pagtatapos ng loop
Halimbawa:
integer i;
always @(posedge clk) begin
    for (i = 0; i < 8; i = i + 1) begin
        sensor_data[i] <= 8'd0;
    end
end

Laging I-initialize nang Hayagan

Ang pag-iwan ng mga array na hindi na-inisyalisa ay maaaring makaimpluwensya sa mga resulta ng simulasyon. Ito ay lalong kritikal para sa mga array na nagmo-model ng RAM o register banks. Palaging i-inisyalisa nang eksplisito:
initial begin
    for (i = 0; i < 256; i = i + 1)
        mem[i] = 32'd0;
end
Sa SystemVerilog, ang mga constructor o foreach loops ay nagbibigay-daan sa mas simple na inisyalisasyon pa rin.

I-Disenyo ang Mga Modyul na Maaaring I-reuse

Ang mga disenyo batay sa array ay maaaring umangkop nang malinaw sa mga pagbabago sa bilang ng instance o bit width. Upang mapakinabangan ang reusability, isaalang-alang:
  • Ang paggamit ng parameter upang gawing configurable ang mga sukat ng array:
parameter DEPTH = 16;
reg [7:0] buffer [0:DEPTH-1];
  • Ang pagpapahintulot ng external parameter passing ay nagpapabuti sa reusability ng module.

Isaalang-alang ang Synthesizability

Kapag gumagamit ng mga array, palaging isaalang-alang ang compatibility ng synthesis tool:
  • Verilog one-dimensional reg arrays: karaniwang synthesizable
  • SystemVerilog dynamic/associative/queue arrays: hindi synthesizable (para sa simulation lamang)
Kaya naman, para sa mga synthesizable na circuit, manatili sa tradisyunal na reg arrays.

Gamitin ang Mga Array vs. Modules nang Angkop

Habang ang mga array ay maaaring mabawasan ang sukat ng code, ang sobrang komplikadong disenyo ay maaaring makikinabang nang higit mula sa paghihiwalay ng functionality sa magkakahiwalay na module para sa maintainability.
  • Maliliit, parehong operasyon → arrays na may for loops
  • Magkaibang functionality o malaking sukat na disenyo → modular at hierarchical design

8. Mga Madalas Itanong (FAQ)

Kapag gumagamit ng mga array sa Verilog o SystemVerilog, ang mga beginner hanggang intermediate users ay madalas na nakakaharap ng parehong mga hadlang. Dito kami tumutugon sa tatlong karaniwang tanong tungkol sa “Verilog arrays,” na nagbibigay ng praktikal na sagot at insights mula sa totoong karanasan sa disenyo.

Q1. Nagkakaroon ako ng error kapag gumagamit ng multidimensional arrays sa Verilog. Bakit?

A1.

Ito ay nangyayari dahil ang Verilog 1995 at mas nauna na bersyon ng Verilog 2001 ay walang suporta sa multidimensional arrays o sinusuportahan lamang ang mga ito nang limitado. Halimbawa, ang sumusunod na code ay magdudulot ng compile error sa Verilog 1995:
reg [7:0] matrix [0:3][0:3];  // Supported only in Verilog 2001 or later
Solusyon:
  • Siguraduhing ang iyong development environment ay compliant sa Verilog 2001 o mas bago .
  • Kung nananatili ang mga limitasyon, muling isulat gamit ang one-dimensional arrays na may calculated indices.
reg [7:0] matrix_1d [0:15];  // Flattened 4x4 array, accessed with (i*4 + j)

Q2. Kung ilalathala ko ang RAM gamit ang arrays sa Verilog, gagana ba ito sa hardware?

A2.

Oo. Ang RAM na inilalarawan gamit ang arrays sa Verilog ay sinusuportahan ng karamihan ng synthesis tools. Isang karaniwang halimbawa:
reg [31:0] mem [0:255];  // 32-bit × 256-word RAM
Mga punto na dapat bantayan:
  • Ang synthesis tool ay dapat makilala ang deskripsyong ito bilang block RAM inference .
  • Ang read/write timing (synchronous vs. asynchronous) at access style ay dapat sumunod sa mga tiyak na template o hindi maaaring ma-infer ng tool ang memory nang tama.
Solusyon:
  • Sundin ang synthesis guide na ibinigay ng iyong FPGA/ASIC vendor.
  • Kung magkaiba ang behavior sa pagitan ng simulation at hardware, suriin ang mga log at i-debug nang hakbang-hakbang.

Q3. Maaari ko bang gamitin ang dynamic arrays, associative arrays, o queues ng SystemVerilog sa aktwal na hardware?

A3.

Sa pangkalahatan, ang dynamic arrays, associative arrays, at queues ay hindi synthesizable (simulation lamang). Bagaman nagbibigay sila ng flexible na coding, hindi sila maaaring i-map nang direkta sa hardware logic. Kaya naman, ang mga array na ito ay pangunahing ginagamit para sa:
  • Pansamantalang storage ng data sa testbenches
  • Randomization o scoreboard implementations sa verification environments
  • Kompleks na deskripsyon ng transaksyon
Mga Tala sa Implementasyon:
  • Anumang design code na gumagamit ng mga uri ng array na ito ay ii-ignore o magdudulot ng error sa synthesis tools.
  • Kung kinakailangan ang hardware implementation, i-convert ang mga ito sa reg o fixed-length one-dimensional arrays.

9. Konklusyon

Sa artikulong ito, tumuon kami sa keyword na “Verilog arrays” at ipinaliwanag ang kanilang paggamit mula sa mga batayan hanggang sa mga advanced na aplikasyon. Ang pagmaster ng mga array sa disenyo ng circuit ay direktang nag-aambag sa kahusayan, kaliwanagan, at madaling mapanatili.

Mga Pangunahing Punto

  • Sa pamamagitan ng pag-unawa sa pangunahing uri ng data ng Verilog (reg at wire), maiiwasan mo ang mga error kapag nagtatrabaho sa mga array.
  • Ang one-dimensional arrays ay mahahalagang estruktura para sa pagsasama-sama ng data at pagmomodelo ng memorya.
  • Ang multidimensional arrays ay sinusuportahan simula Verilog 2001 pataas, na nagbibigay-daan sa mga disenyo na estilo ng matrix.
  • Ang SystemVerilog ay nagtatampok ng mga flexible na estruktura tulad ng dynamic arrays, associative arrays, at queues (pangunahing para sa simulation at verification).
  • Sa pagsunod sa best practices sa paghawak ng array (initialization, naming, reusability, synthesis considerations), makakagawa ka ng mas mataas na kalidad na code.

Praktikal na Mga Tip

Ang mga array ay makapangyarihan, ngunit hindi dapat gamitin nang walang pag-iisip sa lahat ng bagay. Kapag sumusulat ng synthesizable na code o nakikipagtulungan sa mga koponan, laging sundin ang mga limitasyon at gabay sa estilo. Ang mga advanced na tampok ng array ng SystemVerilog ay dapat gamitin na may pag-iisip sa simulation, upang mapakinabangan nang husto ang mga benepisyo nito. Ang mga magagaling na designer ay alam kung paano pumili ng tamang estruktura para sa tamang layunin.

Inirerekomendang Susunod na Mga Paksa

Kung nauunawaan mo na ngayon ang mga batayan ng mga array, inirerekomenda naming tuklasin ang mga sumusunod na kaugnay na paksa:
  • Paggamit ng mga generate statement para sa dynamic na pagbuo ng circuit gamit ang mga array
  • Pagsasama ng interface sa mga array para sa disenyo ng bus
  • Pagpapatupad ng FIFO, ring buffers, at mga optimisasyon ng ROM gamit ang mga array
Ang pagmaster ng mga array ay isang mahalagang unang hakbang bilang isang Verilog designer. Sa pamamagitan ng pagpapalalim ng iyong pag-unawa, magagawa mong hawakan ang patuloy na mas kumplikadong mga disenyo ng circuit nang may tiwala.