Instrução de atribuição Verilog
Sinais do tipo
wire
ou um tipo de dados semelhante a um fio requer a atribuição contínua de um valor. Por exemplo, considere um fio elétrico usado para conectar peças em uma placa de ensaio. Contanto que a bateria de +5V seja aplicada a uma extremidade do fio, o componente conectado à outra extremidade do fio obterá a tensão necessária. Em Verilog, este conceito é realizado pelo
assign
declaração onde qualquer wire
ou outros tipos de dados semelhantes a fios podem ser acionados continuamente com um valor. O valor pode ser uma constante ou uma expressão composta por um grupo de sinais. Atribuir sintaxe
A sintaxe de atribuição começa com a palavra-chave
assign
seguido pelo nome do sinal que pode ser um único sinal ou uma concatenação de diferentes redes de sinais. A força motriz e atraso são opcionais e são usados principalmente para modelagem de fluxo de dados do que para sintetizar em hardware real. A expressão ou sinal do lado direito é avaliada e atribuída à rede ou expressão de redes do lado esquerdo.
assign <net_expression> = [drive_strength] [delay] <expression of different signals or constant value>
Os valores de atraso são úteis para especificar atrasos para portas e são usados para modelar o comportamento de temporização em hardware real porque o valor determina quando a rede deve ser atribuída com o valor avaliado.
Regras
Existem algumas regras que precisam ser seguidas ao usar um
assign
declaração:- O LHS deve ser sempre uma rede escalar ou vetorial ou uma concatenação de redes escalares ou vetoriais e nunca um registrador escalar ou vetorial.
- RHS pode conter registradores escalares ou vetoriais e chamadas de função.
- Sempre que qualquer operando no RHS mudar de valor, o LHS será atualizado com o novo valor.
assign
instruções também são chamadas de atribuições contínuas e estão sempre ativas
Exemplo nº 1
No exemplo a seguir, uma rede chamada é acionada continuamente por uma expressão de sinais. i1 e i2 com a lógica AND
&
formar a expressão. Se os fios forem convertidos em portas e sintetizados, obteremos um esquema RTL como o mostrado abaixo após a síntese.
A instrução de atribuição contínua pode ser usada para representar portas combinacionais em Verilog.
Exemplo nº 2
O módulo mostrado abaixo recebe duas entradas e usa um
assign
instrução para conduzir a saída z usando seleção de parte e concatenações de vários bits. Trate cada caso como o único código no módulo, senão muitos assign
declarações no mesmo sinal definitivamente farão com que a saída se torne X.
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
Atribuir variáveis reg
É ilegal dirigir ou atribuir
reg
variáveis de tipo com um assign
declaração. Isso ocorre porque um reg
variável é capaz de armazenar dados e não precisa ser acionada continuamente. reg
sinais só podem ser conduzidos em blocos procedurais como initial
e always
. Atribuição Contínua Implícita
Quando um
assign
A instrução é usada para atribuir algum valor à rede fornecida, ela é chamada de explícita atribuição. Verilog também permite que uma atribuição seja feita quando a rede é declarada e é chamada de implícita atribuição.
wire [1:0] a;
assign a = x & y; // Explicit assignment
wire [1:0] a = x & y; // Implicit assignment
Projeto de lógica combinatória
Considere o seguinte circuito digital feito de portas combinatórias e o código Verilog correspondente.
A lógica combinacional exige que as entradas sejam continuamente acionadas para manter a saída, ao contrário de elementos sequenciais, como flip-flops, onde o valor é capturado e armazenado na borda de um relógio. Portanto, um
assign
A instrução se ajusta ao propósito do poço porque a saída o é atualizada sempre que qualquer uma das entradas do lado direito muda.
// 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
Esquema de hardware
Após a elaboração e síntese do projeto, conseguimos ver um circuito combinacional que se comportaria da mesma maneira que modelado pelo
assign
declaração. Veja que o sinal o torna-se 1 sempre que a expressão combinacional no RHS se torna verdadeira. Da mesma forma, o torna-se 0 quando RHS é falso. A saída o é X de 0ns a 10ns porque as entradas são X durante o mesmo tempo.
Clique aqui para uma apresentação de slides com exemplo de simulação!
Verilog