Verilog scalars en vectors begrijpen: Bits, registers en nettypes
Verilog moet individuele bits en groepen bits kunnen voorstellen. Een enkel bit sequentieel element is een flipflop. Een 16-bit sequentieel element is een register dat 16 bits kan opslaan. Hiervoor heeft Verilog scalar en vector nets en variabelen.
Scalar en Vector
Een net- of reg-declaratie zonder bereikspecificatie is 1-bit breed en heet een scalar. Als een bereik gespecificeerd is, wordt het een multibit-entiteit genaamd vector.
wire o_nor; // single bit scalar net
wire [7:0] o_flop; // 8-bit vector net
reg parity; // single bit scalar variable
reg [31:0] addr; // 32 bit vector variable voor adresopslagHet bereik geeft de mogelijkheid om individuele bits in een vector te adresseren. De meest significante bit (MSB) moet links in het bereik worden gespecificeerd, de minst significante bit (LSB) rechts.
wire [msb:lsb] name;
integer my_msb;
wire [15:0] priority; // msb = 15, lsb = 0
wire [my_msb: 2] prior; // illegaalEen 16-bit breed net priority wordt gecreëerd. MSB en LSB moeten een constante expressie zijn, geen variabele. Ze kunnen wel elke integerwaarde zijn (positief, negatief, nul), en LSB mag groter, gelijk of kleiner zijn dan MSB.
Bit-selects
Elk bit in een vector-variabele kan individueel geselecteerd en een nieuwe waarde toegewezen krijgen. Dit heet een bit-select. Als de bit-select out-of-bounds is of x of z, wordt x geretourneerd.
reg [7:0] addr; // 8-bit reg variabele [7,6,5,4,3,2,1,0]
addr[0] = 1; // wijst 1 toe aan bit 0 van addr
addr[3] = 0; // wijst 0 toe aan bit 3 van addr
addr[8] = 1; // illegaal: bit8 bestaat niet in addrPart-selects
Een bereik van aaneengesloten bits kan geselecteerd worden, een part-select. Er zijn twee typen: constante part-select en geïndexeerde part-select.
reg [31:0] addr;
addr[23:16] = 8'h23; // bits 23 tot 16 vervangen door nieuwe waarde 'h23 -> constante part-selectEen variabele part-select stelt in staat om effectief in lussen delen van de vector te selecteren. Hoewel het startbit kan varieren, moet de breedte constant zijn.
[+: ] // part-select incrementeert vanaf start-bit [ -: ] // part-select decrementeert vanaf start-bit
module des;
reg [31:0] data;
int i;
initial begin
data = 32'hFACE_CAFE;
for (i = 0; i < 4; i++) begin
$display ("data[8*%0d +: 8] = 0x%0h", i, data[8*i +: 8]);
end
$display ("data[7:0] = 0x%0h", data[7:0]);
$display ("data[15:8] = 0x%0h", data[15:8]);
$display ("data[23:16] = 0x%0h", data[23:16]);
$display ("data[31:24] = 0x%0h", data[31:24]);
end
endmodule Simulation Log ncsim> run data[8*0 +: 8] = 0xfe data[8*1 +: 8] = 0xca data[8*2 +: 8] = 0xce data[8*3 +: 8] = 0xfa data[7:0] = 0xfe data[15:8] = 0xca data[23:16] = 0xce data[31:24] = 0xfa ncsim: *W,RNQUIE: Simulation is complete.
Veelvoorkomende fouten
module tb;
reg [15:0] data;
initial begin
$display ("data[0:9] = 0x%0h", data[0:9]); // Fout: Reversed part-select index expression ordering
end
endmodule
Verilog
- Verilog beheersen: Complete tutorial voor digitale schakelingontwerp
- Verilog concatenatie beheersen: Een praktische gids
- Verilog-toewijzingen begrijpen: types, syntax en best practices
- Verilog Blocking vs. Non-Blocking: belangrijkste verschillen uitgelegd
- Verilog-functies beheersen voor efficiënt RTL-ontwerp
- Verilog Tasks begrijpen: Functions vs Tasks, Syntax en Gebruik
- Inter- en Intra-Assignment Delays in Verilog begrijpen
- Verilog Clock Generator: Ontwerp & Implementatie Gids
- Verilog Math Functions beheersen voor efficiënt Hardware-ontwerp
- Verilog $timeformat beheersen: Precisie en Weergave-controle
- Verilog Timescales begrijpen en printen in elke Scope