Montando o circuito do registrador de saída (OPR), o circuito de reset (RST) e executando o primeiro programa!
Fala pessoal, tudo bem?
Dando continuidade à montagem e estudo do computador de 8-bits, o post de hoje vai tratar do circuito de reset, do registrador de saída (OPR - Output Register) e do primeiro programa de teste para certificar a montagem e o funcionamento dos circuitos que temos até agora.
Visão geral do computador de 8 bits
Primeiramente, falaremos do circuito de reset, que é bem simples.
Ele consiste basicamente de um push-button, um resistor de 10k Ohms, 3 portas NOT e 1 porta NAND. Vou deixar o esquema abaixo (como é de costume, feito à mão :P ).
O grande lance aqui é o resistor de 10k fazendo um pull-down na entrada de uma das portas NOT e, já que falei delas, as portas NOT são usadas aqui como buffers e, como precisamos dos dois estados de reset (RESET e /RESET), utilizamos outra porta NOT na saída da anterior para inverter seu valor.
Por enquanto, não se preocupem em entender a outra parte do circuito (a porta NAND e a outra NOT que trabalham com os sinais /CYCLE_END e /CYCLE_RST). Essa parte será tratada mais para frente. ;)
Os sinais de reset gerados por este circuito foram ligados aos respectivos pinos de reset de todos os circuitos que o possuem (ACC, B, PC, IR, MAR e do próprio OPR).
Até aqui, nada demais né?
Então, vamos tratar de algo mais interessante: o registrador de saída (OPR - Output Register). Este registrador, por mais simples que seja, é um componente fundamental no funcionamento do computador de 8 bits (na verdade, no funcionamento dos computadores em geral).
Ele é responsável por armazenar informações ou valores vindos da memória ou de outros registradores (ACC, B, etc), etc. Enfim, ele armazena algum valor que precisamos exibir e com isso, libera os outros registradores para continuar fazendo seus trabalhos.
No nosso computador de 8 bits, ele funciona da seguinte maneira: recebe um byte vindo do BUS, o armazena e, como possui um canal de comunicação direta com o circuito de exibição que montaremos utilizando displays de 7 segmentos, exibe o valor armazenado na forma de números decimais.
Eletronicamente falando, ele tem o funcionamento muito parecido com os outros registradores do computador (pelo fato de reter informação para uso posterior). Tratando-se do circuito, sua implementação também é muito parecida. Só não é igual ao registrador B, por exemplo, pelo fato de não possuir o 74LS245 (transceptor de barramento de oito bits, tri-state), pois não necessita escrever seu conteúdo no barramento. Ele possui somente os dois 74LS173 (registrador de 4 bit, tipo D, com saídas tri-state) para armazenar o valor vindo do BUS e repassá-lo ao circuito de display decimal.
Eletronicamente falando, ele tem o funcionamento muito parecido com os outros registradores do computador (pelo fato de reter informação para uso posterior). Tratando-se do circuito, sua implementação também é muito parecida. Só não é igual ao registrador B, por exemplo, pelo fato de não possuir o 74LS245 (transceptor de barramento de oito bits, tri-state), pois não necessita escrever seu conteúdo no barramento. Ele possui somente os dois 74LS173 (registrador de 4 bit, tipo D, com saídas tri-state) para armazenar o valor vindo do BUS e repassá-lo ao circuito de display decimal.
Ele possui também um conjunto de 8 LEDs amarelos ligados à sua saída para que possamos ver, na forma binária, seu conteúdo. Isso é muito útil quando estamos debugando um programa.
Como você já deve imaginar, nosso computador tem pouca capacidade de armazenamento e processamento. E isso, claro, deve ser respeitado (também, não tem para onde correr né... rs).
Isso quer dizer que ele roda programas simples com operações lógicas e artméticas de tamanho limitado (lembre-se: temos somente 16 bytes de memória RAM :P ).
Para testes, eu peguei um pequeno programa proposto pelo Eng. Wagner Rambo, da WR Kits, e o executei, passo a passo, no nosso computador. Já adianto que funcionou maravilhosamente bem!
O enunciado do programa proposto é o seguinte:
"Escreva um programa em Assembly para o computador de 8 bits que salve valores de, no máximo, 15 (em decimal) no registrador de saída (OPR - Output Register), independente do dado de entrada no acumulador (ACC)."
Para resolver o problema, foi escrito o seguinte programa:
.ORG 0h
LDA [Ah]
AND [9h]
OUT
.END
Como implementaremos cada uma das instruções do computador, os OPCODES definidos para cada uma delas foram:
Instrução OPCODE
--------- ------
LDA 0001
AND 0110
OUT 1110
Sendo assim, compilando manualmente o programa, temos:
Endereço (RAM) Dado
-------------- ------------
0h 0000 00011010
1h 0001 01101001
2h 0010 11100000
(...) (...)
9h 1001 00001111 (máscara de bits)
Ah 1010 10100101 (165 >> 15; para testar a lógica
)
Com essa compilação em mãos, chegou a hora de gravar o programa na memória RAM. Para isso, foi implementado um pequeno circuito para dar o pulso de gravação na memória, estando esta no modo de operação de escrita.
Vou deixar abaixo o script de gravação e execução do programa. Como eu queria verificar cada passo, em cada pulso de clock, para cada instrução, utilizei modo de clock manual.
.INÍCIO
1. entrar no modo de programação (escrita) da memória RAM e armazenar o programa compilado acima
2. ativar o modo de execução (leitura) da memória RAM
3. com o computador resetado (todos os contadores e registradores zerados), iniciar o ciclo de busca e execução da instrução LDA
4. buscar LDA [Ah] no endereço 0000:
- habilitar:
PC_OUT
MAR_IN
CLK (pulso de clock)
- desabilitar:
PC_OUT
MAR_IN
- nesse momento, temos o valor 0000 gravado no registrador de endereço de memória - MAR
5. disponibilizar o conteúdo do endereço 0000 no BUS e gravá-lo no IR:
- habilitar:
RAM_OUT
IR_IN
PC_INC
CLK
- desabilitar:
RAM_OUT
IR_IN
PC_INC
- neste ponto, o valor do endereço 0000 da memória (00011010) está gravado em IR e PC foi incrementado em 1
6. executar a instrução LDA:
- habilitar:
IR_OUT (somente o nibble menos significativo - LSN vai para o BUS)
MAR_IN
CLK
- desabilitar:
IR_OUT
MAR_IN
- neste momento, temos o endereço do BUS (LSN = 1010 = Ah) em MAR e, na RAM, o dado salvo previamente já selecionado
- habilitar:
RAM_OUT
ACC_IN
CLK
- desabilitar:
RAM_OUT
ACC_IN
- neste momento, temos o dado da RAM salvo em ACC (aqui termina o ciclo de busca e execução de LDA)
7. buscar AND [9h] no endereço 0001:
- habilitar:
PC_OUT
MAR_IN
CLK
- desabilitar
PC_OUT
MAR_IN
- nesse momento, temos o valor 0001 gravado no registrador de endereço de memória - MAR
8. disponibilizar o conteúdo do endereço 0001 no BUS e gravá-lo no IR:
- habilitar:
RAM_OUT
IR_IN
PC_INC
CLK
- desabilitar:
RAM_OUT
IR_IN
PC_INC
- neste ponto, o valor do endereço 0001 da memória (01101001) está gravado em IR e PC tem o valor 2
9. configurar a ALU para a operação AND:
- habilitar:
ALU_0
- na execução normal, neste passo, o circuito de controle identificaria a operação AND através de IR e configuraria a ALU para tal operação
10. executar a instrução AND:
- habilitar:
IR_OUT (somente LSN vai para o BUS)
MAR_IN
CLK
- desabilitar:
IR_OUT
MAR_IR
- neste momento, temos o endereço do BUS (LSN = 1001 = 9h) em MAR e, na RAM, o dado salvo previamente já selecionado
- habilitar:
RAM_OUT
BR_IN
CLK
- desabilitar:
RAM_OUT
BR_IN
- neste momento, temos o dado da RAM salvo em B (aqui termina o ciclo de busca e execução de AND). O resultado da operação já pode ser visto na ALU (5h)
11. salva o resultado da operação no ACC:
- habilitar:
ALU_OUT
ACC_IN
CLK
- desabilitar:
ALU_OUT
ACC_IN
- neste ponto, o valor da operação da ALU está salvo em ACC
12. buscar OUT no endereço 0010:
- habilitar:
PC_OUT
MAR_IN
CLK
- desabilitar
PC_OUT
MAR_IN
- nesse momento, temos o valor 0010 gravado no registrador de endereço de memória - MAR
13. disponibilizar o conteúdo do endereço 0010 no BUS e gravá-lo no IR:
- habilitar:
RAM_OUT
IR_IN
PC_INC
CLK
- desabilitar:
RAM_OUT
IR_IN
PC_INC
- neste ponto, o valor do endereço 0010 da memória (11100000) está gravado em IR e PC tem o valor 3
14. salva o valor de ACC em OPR:
- habilitar:
ACC_OUT
OPR_IN
CLK
- desabilitar:
ACC_OUT
OPR_IN
- e, finalmente, neste ponto, temos o valor de ACC (5h) salvo em OPR
.FIM
Como podem ver nas fotos abaixo, todas as operações executaram com sucesso! Com isso, temos certeza de que podemos avançar.
Valor 00011010 gravado no endereço 0000 da RAM
Valor 01101001 gravado no endereço 0001 da RAM
Valor 11100000 gravado no endereço 0010 da RAM
Valor 00001111 gravado no endereço 1001 da RAM
Valor 10100101 gravado no endereço 1010 da RAM
Aqui, pode-se ver o valor final da operação (05h) sendo exibido na ALU
E finalmente nesta, o resultado final (05h) sendo exibido nos LEDs do registrador de saída (OPR) :D
Então, é isso. No próximo post trataremos do circuito do display decimal.
Bons estudos à todos!
Comentários
Postar um comentário