Verilog toewijzingsinstructie
Signalen van het type wire
of een soortgelijk draadachtig gegevenstype vereist de continue toewijzing van een waarde. Denk bijvoorbeeld aan een elektrische draad die wordt gebruikt om stukken op een breadboard met elkaar te verbinden. Zolang de +5V-batterij op het ene uiteinde van de draad is aangesloten, krijgt het onderdeel dat is aangesloten op het andere uiteinde van de draad de vereiste spanning.
In Verilog wordt dit concept gerealiseerd door de assign
statement waar een wire
of andere soortgelijke draadachtige datatypes kunnen continu worden aangestuurd met een waarde. De waarde kan een constante zijn of een uitdrukking die bestaat uit een groep signalen.
Syntaxis toewijzen
De toewijzingssyntaxis begint met het trefwoord assign
gevolgd door de signaalnaam die een enkel signaal of een aaneenschakeling van verschillende signaalnetten kan zijn. De drijfkracht en vertraging zijn optioneel en worden meestal gebruikt voor dataflow-modellering dan voor synthese in echte hardware. De uitdrukking of het signaal aan de rechterkant wordt geëvalueerd en toegewezen aan het net of de uitdrukking van de netten aan de linkerkant.
assign <net_expression> = [drive_strength] [delay] <expression of different signals or constant value>
Vertragingswaarden zijn handig voor het specificeren van vertragingen voor poorten en worden gebruikt om timinggedrag in echte hardware te modelleren, omdat de waarde bepaalt wanneer het net moet worden toegewezen met de geëvalueerde waarde.
Regels
Er zijn enkele regels die moeten worden gevolgd bij het gebruik van een assign
verklaring:
- LHS moet altijd een scalair of vectornet zijn of een aaneenschakeling van scalaire of vectornetten en nooit een scalair of vectorregister.
- RHS kan scalaire of vectorregisters en functieaanroepen bevatten.
- Telkens wanneer een operand op de RHS in waarde verandert, wordt LHS bijgewerkt met de nieuwe waarde.
assign
uitspraken worden ook wel doorlopende opdrachten genoemd en zijn altijd actief
Voorbeeld #1
In het volgende voorbeeld wordt een opgeroepen net continu aangedreven door een expressie van signalen. i1 en i2 met de logische AND &
de uitdrukking vormen.
Als de draden in plaats daarvan worden omgezet in poorten en gesynthetiseerd, krijgen we na synthese een RTL-schema zoals hieronder weergegeven.
Doorlopende toewijzingsverklaring kan worden gebruikt om combinatiepoorten in Verilog weer te geven.
Voorbeeld #2
De hieronder getoonde module heeft twee ingangen en gebruikt een assign
statement om de uitvoer z aan te sturen met behulp van part-select en meervoudige bit-aaneenschakelingen. Behandel elk geval als de enige code in de module, anders veel assign
uitspraken op hetzelfde signaal zullen de uitvoer zeker X maken.
module xyz (input [3:0] x, // x is a 4-bit vector net
input y, // y is a scalar net (1-bit)
output [4:0] z ); // z is a 5-bit vector net
wire [1:0] a;
wire b;
// Assume one of the following assignments are chosen in real design
// If x='hC and y='h1 let us see the value of z
// Case #1: 4-bits of x and 1 bit of y is concatenated to get a 5-bit net
// and is assigned to the 5-bit nets of z. So value of z='b11001 or z='h19
assign z = {x, y};
// Case #2: 4-bits of x and 1 bit of y is concatenated to get a 5-bit net
// and is assigned to selected 3-bits of net z. Remaining 2 bits of z remains
// undriven and will be high-imp. So value of z='bZ001Z
assign z[3:1] = {x, y};
// Case #3: The same statement is used but now bit4 of z is driven with a constant
// value of 1. Now z = 'b1001Z because only bit0 remains undriven
assign z[3:1] = {x, y};
assign z[4] = 1;
// Case #4: Assume bit3 is driven instead, but now there are two drivers for bit3,
// and both are driving the same value of 0. So there should be no contention and
// value of z = 'bZ001Z
assign z[3:1] = {x, y};
assign z[3] = 0;
// Case #5: Assume bit3 is instead driven with value 1, so now there are two drivers
// with different values, where the first line is driven with the value of X which
// at the time is 0 and the second assignment where it is driven with value 1, so
// now it becomes unknown which will win. So z='bZX01Z
assign z[3:1] = {x, y};
assign z[3] = 1;
// Case #6: Partial selection of operands on RHS is also possible and say only 2-bits
// are chosen from x, then z = 'b00001 because z[4:3] will be driven with 0
assign z = {x[1:0], y};
// Case #7: Say we explicitly assign only 3-bits of z and leave remaining unconnected
// then z = 'bZZ001
assign z[2:0] = {x[1:0], y};
// Case #8: Same variable can be used multiple times as well and z = 'b00111
// 3{y} is the same as {y, y, y}
assign z = {3{y}};
// Case #9: LHS can also be concatenated: a is 2-bit vector and b is scalar
// RHS is evaluated to 11001 and LHS is 3-bit wide so first 3 bits from LSB of RHS
// will be assigned to LHS. So a = 'b00 and b ='b1
assign {a, b} = {x, y};
// Case #10: If we reverse order on LHS keeping RHS same, we get a = 'b01 and b='b0
assign {a, b} = {x, y};
endmodule
Reg-variabelen toewijzen
Het is illegaal om te rijden of reg
. toe te wijzen typ variabelen met een assign
uitspraak. Dit komt omdat een reg
variabele kan gegevens opslaan en hoeft niet continu te worden aangedreven. reg
signalen kunnen alleen worden aangestuurd in procedurele blokken zoals initial
en always
.
Impliciete doorlopende toewijzing
Wanneer een assign
statement wordt gebruikt om het gegeven net een bepaalde waarde toe te kennen, het wordt expliciet . genoemd opdracht. Verilog staat ook toe dat een toewijzing wordt gedaan wanneer het net is gedeclareerd en impliciet wordt genoemd opdracht.
wire [1:0] a;
assign a = x & y; // Explicit assignment
wire [1:0] a = x & y; // Implicit assignment
Combinationaal logisch ontwerp
Beschouw het volgende digitale circuit gemaakt van combinatiepoorten en de bijbehorende Verilog-code.
Combinatielogica vereist dat de ingangen continu worden aangestuurd om de uitvoer te behouden, in tegenstelling tot opeenvolgende elementen zoals flip-flops waarbij de waarde wordt vastgelegd en opgeslagen aan de rand van een klok. Dus een assign
verklaring past bij het doel, omdat de uitvoer o wordt bijgewerkt wanneer een van de invoer aan de rechterkant verandert.
// This module takes four inputs and performs a boolean
// operation and assigns output to o. The combinational
// logic is realized using assign statement.
module combo ( input a, b, c, d,
output o);
assign o = ~((a & b) | c ^ d);
endmodule
Hardwareschema
Na uitwerking en synthese van het ontwerp krijgen we een combinatorisch circuit te zien dat zich op dezelfde manier zou gedragen als gemodelleerd door de assign
verklaring.
Zie dat het signaal o 1 wordt wanneer de combinatorische uitdrukking op de RHS waar wordt. Evenzo wordt o 0 wanneer RHS onwaar is. Uitgang o is X van 0ns tot 10ns omdat de ingangen tegelijkertijd X zijn.
Klik hier voor een slideshow met simulatievoorbeeld!
Verilog