[blog] Synchronous versus asynchronous reset on ASIC Design

Reset is about getting a system back to a known initial state. Temporary data is flushed. Everything will be put to a known state so the circuit starts up. Sounds important.

When we go for synchronous or asynchronous reset, active low, our HDL code will look like one of these:

module synch_reset_pipeline(in1, in2, ..., out1, out2,...);
// #1 module with synchronous reset
always @(posedge clk) 
begin
  if (!rst) begin
   // reset logic: put this module to known state 
  end
  else begin
  // functional logic: processes data
  end
end
endmodule
module asynch_reset_pipeline(in1, in2, ..., out1, out2,...);
// #2 module with asynchronous reset
always @(posedge clk or negedge rst) 
begin
  if (!rst) begin
   // reset logic 
  end
  else begin
  // functional logic
  end
end
endmodule

To simplify, firstly, think about a single sequential element (a flip-flop). Then, imagine it is starting up, catching the very first data signal arriving on the input and propagating it to other pipeline stages. How would be a desirable reset signal? I would say:

  • it resets the circuit to a known state
  • not prone to any metastability
  • the duty cycle is just long enough to meet the above criteria

Given the above bullets what is the go for approach? Whatever fits the system better, on area, timing and power. On module #1, we are telling the tool that the reset signal is under the domain of the clock, and the reset logic will take place when reset level is low. So when the clock positive edge triggers and reset is asserted, the flops that are connected to that logic will reset. Therefore, the reset signal is pretty much another data signal (like: assign current_input = (!rst_sel) ? reset_value : next_input), selecting between the next value to be sampled or the reset data value, when a reset happens. And we should make sure it will be filtered from glitches and never prone to any meta-stability – but this is valid to any other external input too. It cannot take the fastest way through the datapath when asserted, otherwise it might reset the logic violating setup requirements, and therefore put it to a unknown state, that will be sampled and propagated. The deassertion by its turn need to respect the hold time of the signals that were propagated through the pipeline. As data and reset are on the same clock domain, the work relies pretty much on the clock tree synthesis. It costs more circuitry in general. (Although flops are smaller, they say)

On #2, the asynchronous reset is a high priority interruption, per say. The or inside the sensitivity list changes everything. Whenever reset is low (asserted) it comes to bring everything down and up again. If the pulse has a very low duty cycle, maybe the flop will not be stable yet, and will put the the circuit to an unknown state when reset is released; maybe a very bad combination (boom). That is, we need to model this asynchronous path to respect a time after asserting and before deasserting the signal, so we make sure every pipeline stage is at a known state. To prevent timing violation when asserting, we need to make sure the reset will take place respecting the (worst) removal time, so the initial data to be sampled is valid. For deasserting, we need to make sure the clock samples a stable value, by respecting the (worst) recovery time. Besides, you need to tell the tool that the signal that multiplex the input to your flops between operation data and reset data is a false path – that is the clock must ignore the impact of this signal on the data path, and not make any efforts to support setup and hold timings of the sequential elements. You will take care by yourself by controlling the reset behavior. A technique could be to model the buffers safely enough to charge and discharge on a determined relative time, so the reset removal and recovery time are always safe. That is you fix a positive delay for reset assertion and a negative delay for deassertion, regarding the active clock edge. You will need to synchronize the input reset signal to a common in both aproaches to mitigate metastability. Asynchronous reset costs less circuitry, but is also more complex: a very critical asynchronous control signal is on the game.

Low-power 3/3: microarquitetura e RTL

6 Abordagens para redução de consumo em RTL

As ferramentas de síntese e back-end detectam oportunidades para salvar energia diretamente do RTL, portanto a microarquitetura e, consequentemente o estilo de codificação tem um grande impacto no consumo. A medida que o fluxo avança, menores são as intervenções que podem ser feitas para reduzir a energia dinâmica e estática. Um bom design low-power começa nos níveis arquiteturais como já foi discutido e, ainda antes da síntese, durante a escrita do código em linguagem de descrição de hardware. É dito que 80% do consumo em um ASIC estará definido no momento em que o RTL é finalizado. Somente os outros 20% dependerão do back-end. [1]

6.1 Máquinas de estado – codificação e decomposição

Minimizar a inversão de bits nas transições entre um estado e outro, naturalmente minimiza o consumo de uma máquina de estados. Codificação Grey, onde somente um bit inverte durante uma transição entre estados, é um cliché para a redução de consumo.

Figura 6.1 Codificação Binária versus Grey em uma FSM de 5 estados (Figura retirada de [1])

Ainda, pode-se considerar uma abordagem mais ad hoc, ao identificar os caminhos mais frequentes exercitados pela máquina, e codificá-los de forma que menos bits transicionem entre um estado e outro.

Na Figura 6.1, numa máquina de 5 estados, há 32 transições possíveis. Neste caso, somente 6 podem acontecer de fato. Na codificação binária, 2 bits invertem nas transições B->C e E->B. Se 30% das transições na operação normal forem E->B (ou B->C), a economia de energia com o Grey code fica em 15% somente na inversão dos bits dos registradores, e ainda haverá redução de consumo na lógica combinatória, na mesma proporção ou ainda mais [1].

Uma outra forma de economizar energia é decompor uma FSM em diferentes sub-máquinas, garantindo que as submáquinas em conjunto tenham o mesmo STG (grafo de transição de estados) da máquina original. Durante a operação, exceto se houver transições entre uma submáquina e outra, somente uma precisa estar ativa. Um problema desta abordagem é que os STGs crescem exponencialmente com o número de registros e as técnicas para decompor a máquina também tornam-se mais complicadas [3].

6.2 Representação binária

Já foi discutido neste site a representação e operação de números negativos em circuitos digitais. Para a maioria das aplicações, complemento de 2 é mais adequada que sua representação por sinal-magnitude [1]. Entretanto, para algumas aplicações bastante especificas, pode ser vantajoso o uso de sinal-magnitude. Numa transição de “0” para “-1”, a representação em complemento de 2 inverte todos os bits, ao contrário da lógica sinal-magnitude:

// complemento de 2:
"0" : 00000000
"-1": 11111111

// sinal-magnitude
"0" : 00000000
"-1": 10000001

6.3 Inferência para clock-gating

Abaixo duas possíveis descrições em Verilog para um banco de flip-flops (reg_bank_ff) registrar um novo dado somente (reg_bank_nxt) quando o sinal de seleção load_sel estiver alto. O próximo valor ainda depende de um sinal de seleção deadbeef_sel:

Código 1. Inferência de clock-gating

No “mau exemplo” o sinal i_load_sel_w não foi colocado diretamente sob o domínio do clock, e sim em um bloco de lógica puramente combinacional. É ainda possível que a ferramenta infira o clock-gating após o flattening, mas não é boa prática contar com isso. No “bom exemplo” a ferramenta de síntese prontamente infere que i_load_sel_w é o controle da célula de clock-gating que será integrada (linha 47), economizando 32 multiplexadores que seriam controlados por i_load_sel_w, como descrito no código de “mau exemplo”.

6.4 Multiplexadores One-Hot

Multiplexadores são descritos/inferidos normalmente a partir de cases e ifs [1]:

// Mux 4:1 (linha de seleção em código binário)  
case (SEL)     
2'b00: out = a;    
2'b01: out = b;    
2'b10: out = c;    
2'b11: out = d; 
endcase  
//Mux 4:1  (linha de seleção em código one-hot)  
case (SEL)    
4'b0001: out = a;    
4'b0010: out = b;    
4'b0100: out = c;    
4'b1000: out = d;    
default: out = out;  
endcase

Se as linhas de seleção de um multiplexador são barramentos de vários bits, o chaveamento pode ser significante.

Na Figura 6.3, à direita, os barramentos não selecionados são prontamente mascarados pela lógica AND na entrada do gate OR, diminuindo ainda o atraso da entrada selecionada para a saída.

Figura 6.3 – Muxes N:1 – Binário x One Hot [1]

A maior parte da lógica em um design pode consistir em multiplexadores, portanto, evitar ou mascarar falsas transições deve diminuir o consumo significativamente [1, 2]. Note que a codificação one-hot também é um bom padrão de escolha para máquinas de estado.

6.5 Evitar transições redundantes

Analise a microarquitetura da Figura 6.4. O sinal load_op ativa os 4 operandos a_in, b_in, c_in e d_in. O sinal sel_in seleciona qual operação terá o resultado carregado na saída. Perceba que se o sinal load_op não precisa – ou não deveria – estar ativo se o sinal load_out não for ativado também, visto que as operações nas nuvens lógicas não terão efeito na saída.

Figura 6.4 – Microarquitetura que permite transições redundantes (inúteis) [1]

Na figura abaixo, a microarquitetura é modificada para evitar transições inúteis. A adição de portas AND na entrada dos operandos a_in e b_in faz com que estes sejam habilitados somente quando sel_in é ‘0’; c_in e d_in por sua vez, somente quando sel_in é ‘1’.

Figura 6.5 – Supressão das transições redudantes [1]

6.6 Compartilhamento de recursos

Observe as seguintes lógicas combinatórias descrita em Verilog [adaptado de 1]:

// Codigo #1 
// sem compartilhar recursos
always @(*) begin
 case(SEL) 
   3'b000: OUT = 1'b0;
   3'b001: OUT = 1'b1;
   3'b010: OUT = (value1 == value2); //equals
   3'b011: OUT = (value1 != value2);  //different
   3'b100: OUT = (value1 >= value2); // greater or equal
   3'b101: OUT = (value1 <= value2); // less or equal
   3'b110: OUT = (value1 < value2); // less
   3'b111: OUT = (value1 > value2); // greater
endcase
// Codigo #2
// compartilhando recursos
assign cmp_equal = (value1 == value2);
assign cmp_greater = (value1 > value2);
always @(*) begin
 case(SEL) 
   3'b000: OUT = 1'b0;
   3'b001: OUT = 1'b1;
   3'b010: OUT = cmp_equal;
   3'b011: OUT = !cmp_equal;
   3'b100: OUT = cmp_equal || cmp_greater;
   3'b101: OUT = !cmp_greater || cmp_equal ;
   3'b110: OUT = !cmp_greater;
   3'b111: OUT = cmp_greater;
endcase

O Código #1 faz uma operação aritmética para cada seleção de entrada SEL. Estas operações têm em comum a comparação entre 2 operandos, value1 e value2. No código #2, duas lógicas de comparação foram assinaladas às nets cmp_equal e cmp_greater. Estas, por sua vez, foram utilizadas nas saídas da seleção em operações lógicas para evitar a replicação de operações de comparação (mais custosas) que envolvem os mesmos operandos e operadores.

6.7 Inversão de barramento

Quando a Distância de Hamming entre o dado atual e o próximo é maior que N/2 (sendo N o tamanho do barramento) é possível invertê-los para minimizar o número de transições:

Figura 6.6 – Para um barramento de 8 bits, quando a distância de hamming entre um dado e o próximo é maior que 4, o número de transições é reduzido ao aplicarmos a inversão (Adaptado de [1]).

Note que um sinal de controle INV é necessário para indicar ao receptor que os dados foram invertidos. Note que mesmo que adicionemos um encoder em Tx e um decoder em Rx, o barramento e portanto as maiores capacitâncias transitaram menos. As maiores correntes são evitadas e a transmissão dos dados consome menos energia.

O texto desta publicação é original. As seguintes fontes foram consultadas: [1] The Art of Hardware Architecture, Mohit Ahora (ISBN 978-1-4614-0397-5)􀀤
[2] Ultra-Low Power Integrated Circuit Design, Niaxiong Nick Tan et al (ISBN 978-1-4419-9973-3)
[3] FSM decomposition by direct circuit manipulation applied to low power design, JC Monteiro et. al. DOI: 10.1109/ASPDAC.2000.835123