Flip-Flops, Memórias RAM e Latches

Circuitos lógicos são simples: Não passam um monte de portas lógicas (AND, OR, NOT ou XOR) ligadas de maneira a obedecerem uma equação lógica… Neste texto eu não vou explicar o funcionamento de uma porta lógica e sequer como montar ou simplificar uma equação lógica. O que nos interessa é uma classe de circuitos lógicos chamados flip-flops.

Um flip-flop pode ser entendido como sendo uma espécie de “memória” de apenas um bit. Ele armazena um estado lógico e o mantém estável até que este estado seja modificado. No jargão da eletrônica analógica eles são conhecidos como mutivibradores biestáveis (porque podem assumir dois estados estáveis: 0 ou 1). Na eletrônica digital receberam esse ridículo nome, suspeito eu, porque na gíria, em inglês, pessoas que mudam de ideia facilmente são “flip-floppers” (a alternativa é usar a gíria para “chinelo”, que também é “flip-flop”!).

Do ponto de vista do desenvolvedor de software apenas um dos tipos de flip-flops é interessante: O flip-flop tipo D:

D-FF

Aqui tenos duas entradas (D e E, de Data e Enable, respectivamente) e duas saídas (Q e Q#). Na realidade, podemos considerar as saídas como uma só: Q. O sinal Q# é apenas o complemento do outro… Esse cara ai em cima funciona assim: Quando a entrada E (pode-se achar essa entrada nomeada como T de Trigger ou “gatilho”, na literatura técnica) estiver setada (1), a saída Q será colocada no mesmo valor da entrada D. Mas, quanto a entrada E estiver zerada, a saída Q não se altera, seja qual for o valor em D. Ou seja, se E for zero, o último estado de D (quanto E era 1) terá sido armazenado.

Note que a saída depende do nível de E. Enquanto E estiver em nível alto, a saída Q será uma cópia da entrada D. Apenas quando E for zerada é que a última entrada D estará “armazenada”. A maioria dos circuitos lógicos micro-processados não funciona assim. Neles, o armazenamento é feito de uma maneira mais rápida, no pequeno período de transição entre um nível e outro do sinal de E. Ou, se preferir, no “canto” (edge) do pulso de “clock”. Abaixo mostro como um flip-flop D com gatilho na descida do pulso de clock funciona.

Quem disse que escravidão era uma coisa ruim?

O circuito lógico abaixo faz a mágica do armazenamento na transição  da “descida do pulso de clock”:

D-FF-edge

Se você reparar bem, existem dois flip-flops neste circuito: As duas portas AND e as duas portas NOR, à esquerda, formam um flip-flop mestre do tipo D e as mesmas portas, à direita, formam um flip flop escravo (do tipo RST, mas isso não é importante aqui!).

A ideia aqui é que o flip-flop mestre altera o estado de suas saídas quando o sinal CLK estiver em nível alto. Essas saídas são os pontos na saída das portas lógicas NOR, mais à esquerda… Para esse flip-flop o sinal CLK funciona do mesmo jeito que o sinal E citado anteriormente. Repare que, quanto CLK for 1, a porta inversora ligada a ele colocará um valor zero nas portas AND mais à direita. Ou seja, o sinal E do flip-flop escravo será zero.

Quando o sinal de CLK pular do nível alto para o baixo, o flip-flop mestre estabilizará sua saída de acordo com o último valor em D, da mesma maneira que citei lá em cima… Mas, o flip-flop escravo mudará a saída Q de acordo com suas entradas (ou as saídas do mestre). Até aqui nada ficou muito diferente do flip-flop D comum, mas observe que quanto CLK “sobe” (passa de 0 para 1) o flip-flop escravo terá sua saída estabilizada e o flip-flop mestre, agora, terá sua saída “desestabilizada”. Isso quer dizer que, de maneira global, o flip-flop só alterará a saída Q na descida do pulso de clock, mantendo-o estável no resto do tempo!

O flip-flop, acima, continua sendo um tipo D e é simbolizado, num diagrama de blocos, como abaixo:

JK-MS-from-D

Repare no pequeno triângulo e na inversão do sinal CK… O triângulo diz “transição de clock” e a “bolinha” diz “descida”… Sem a “bolinha” o flip-flop funcionaria na “subida do pulso”…

Memória RAM não funciona assim!!!

Você poderia ficar tentado a acreditar que a memória RAM do seu PC funciona dessa maneira. Nah! Não é bem assim…

Repare que precisamos de 10 portas lógicas para o armazenamento de apenas 1 bit, usando um único flip-flop tipo D. Num PC atual, com uns 8 GiB de RAM, precisaríamos de uns 68 bilhões de flip-flops tipo D, com 10 portas lógicas cada um e, com cada porta com uns 8 transístores (em média), ou seja, apenas para a memória do sistema teríamos 5,5 trilhões de transístores… O circuito ficaria enorme e caro.

De fato, existe um tipo de RAM que funciona à base de flip-flops tipo D, chamada memória RAM estática (SRAM de Static RAM). Mas, a RAM do seu PC é dinâmica (DRAM de Dynamic RAM) e os bits armazenados correspondem à carga de pequeníssimos capacitores:

M78On

O esquema acima, é claro, é simplificado. Essencialmente temos que fornecer o “endereço” da linha e da coluna onde um capacitor se encontra numa matriz. Ele é carregado (escrita) ou “lido” através de um pequeno transístor… Infelizmente a carga destes capacitores rapidamente decaem e ai é que entra o processo de “refrescamento”. As memórias RAM dinâmicas precisam ser relembradas o tempo todo e elas funcionam assim desde sua criação, em 1968 (invenção da IBM).

Embora o circuito seja mais simples e há a desvantagem da lentidão (carga e descarga controlada de capacitores implicam em “constantes de tempo”) ele é bem mais barato e fácil de ser construído. Dando uma olhada na topografia de um DIE de uma DRAM genérica, vemos algo mais ou menos assim:

MT4C1024-HD

Essas áreas cinzentas, no meio do DIE, são aqueles pequenos FETs e capacitores. O resto do circuito correspondem à decodificação das linhas e colunas, bem como o condicionamento do sinais para leitura/escrita/refresh.

Compare agora o die acima, com um die da arquitetura Haswell-E, de 22 nm:

Core-i7-5960X (22nm Haswell)

Tenha em mente que a densidade (ou, se preferir, o “tamanho”) dos transístores, diodos, capacitores, resistores etc, é muito maior do que numa simples DRAM… Por exemplo, essa área central, com aqueles montes de “ilhas” retangulares de aspecto claro, é o cache L3 (20 MiB no i7-5960X), mas os outros caches não são facilmente identificáveis (estão, provavelmente do lado direito — naquela região rosada — e não são aquelas áreas verdes!). Abaixo e acima do cache L3 estão os 8 “cores” (cada um com 2 processadores lógicos) e, à esquerda do DIE, temos os circuitos de I/O.

O ponto aqui é que o processador não usa DRAM dentro de si, mesmo porque o tamanho dos capacitores teria que ser grande para conseguirem manter carga por tempo suficiente, o que aumentaria o tamanho do DIE consideravelmente… Assim, memória dentro de um processador tem que ser implementada como SRAM (Static RAM), ou seja, com flip-flops.

Externamente ao processador os flip-flops também são úteis como pequenas memórias. É o caso dos latches

Fechando a abrindo o trinco…

Um latch (trinco ou tranca, em inglês) nada mais é do que um conjunto de flip-flops tipo D com o pino E ou CLK em comum (dependendo se a trava acontece por nível ou transição de clock). As placas VGA, por exemplo, possuem latches que armazenam valores lidos da memória de vídeo (um latch de 8 bits para cada “plano”) e são usados para evitar acessos espúrios à memória de vídeo (quando alteramos um byte e o circuito estiver desenhando-o na tela)…Também são usados como memória temporária para operações de raster (ROP = Raster OPeration. Aliás, “raster” é um substantivo: “a rectangular pattern of parallel scanning lines followed by the electron beam on a television screen or computer monitor”), como, por exemplo, ao escrevermos um dado na memória de vídeo, uma operação lógica pode ser feita com o conteúdo de um ou mais latches — escreví sobre isso em meu velho curso de assembly…

Outro uso para latches é visto no circuito que decodifica endereços de memória vindos do processador… É comum (em processadores Intel) que o mesmo barramento seja usado para fornecer/receber endereços e para ler/escrever dados. O endereço é fornecido primeiro e “armazenado” em um latch. Depois que isso é feito, os dados serão lidos/gravados e o endereço será obtido do latch, pelo circuito de controle das memórias.

Esses trincos são, então, pequenas memórias que armazenam uma quantidade limitada de bits (8, 16, 24, 32, …). E latches são, óbviamente, muito mais rápidos que memórias dinâmicas e, por isso, e também por causa da quantidade limitadíssima de armazenamento, eles só são usados em casos especiais.

Outras memórias estáticas além do latch:

Ficou claro que os pentes de memória espetados na sua placa-mãe são lentos? Existe um tempo mínimo para carregar e descarregar os pequenos capacitores contidos no interior dos circuitos integrados… Para melhorar a performance, usamos pequenas memórias RAM estáticas, no interior do processador, que chamamos de cache!

Este é o motivo pelo qual o cache L1 e L2 são relativamente pequenos (o cache L1 tem, hoje em dia, 32 KiB de tamanho para cada um de seus “galhos”: L1I e L1D, por exemplo)… Elas não podem ser grandes, porque seriam caras ($$) demais para que você pudesse ter um microcomputador em cima de uma mesa ou na palma da sua mão!

Outros flip-flops

O mais importante aqui são os conceitos. Para os mais curiosos eu recomendaria a análise dos tipos de flip-flops pelo tipo RS, passando pelo D, pelo RST e indo parar no JK. Mas, essencialmente, tudo o que um desenvolvedor precisa saber é o funcionamento básico do tipo D e do modelo mestre-escravo.

Anúncios