Aula 4: Aumentando a Funcionalidade da Instrução

Questão: Como adicionar mais informação às instruções?

Objetivos

  1. Projetar um decodificador de instruções com suporte a instruções que utilizem dados da memória e de valores imediatos (constantes).

Contextualização

Até agora, o nosso computador possui as seguintes limitações:

Circuito Atual para Equação de Primeiro Grau com Decodificador de Instruções
Circuito Atual para Equação de Primeiro Grau com Decodificador de Instruções

Essas limitações serão resolvidas através de uma reorganização do formato das instruções, do nosso computador, que permita uma maior versatilidade na utilização de operandos.

Como exemplo, vamos analisar a execução da seguinte operação: A = B + 8. Atualmente, as constantes e variáveis devem ser obtidas através das chaves e armazenadas no acumulador (registrador A) ou entrando diretamente na entrada B da ULA. Não temos uma instrução que tenha uma constante definida internamente ou mesmo uma instrução que faça acesso à uma memória externa - que poderia ser utilizada como rascunho.

Isso é devido ao formato da instrução que, atualmente, possui somente o opcode (código da operação a ser executada). Uma forma mais genérica seria uma instrução que tivesse um campo para o opcode e um, ou mais, campos para os operandos necessários.

Para resolver A = B + 8, considerando que as variáveis estão em uma memória externa (chamada M) e que a constante está embutida na instrução, poderíamos ter o seguinte código:

    LDI  8                          # Carrega Acumulador com 8
    SOMA  M[enderecoVariavelB]      # Soma Acumulador com Variável B
    STA M[enderecoVariavelA]        # Armazena resultado na posição de memória da Variável A

Onde: M = Memória externa; SOMA = soma acumulador com conteúdo da posição de memória; LDI = Load Imediato: operação de carga de uma constante (definida dentro do campo da instrução); STA = Store Acumulador: operação de armazenamento em posição de memória

A instrução LDI, que carrega o acumulador com uma constante, precisaria de uma organização do tipo:

Organização dos Campos da Instrução LDI
opCode Constante Embutida na Instrução
X bits K bits

No caso, o valor X é o número de bits necessário para codificar todas as instruções existentes no processador. O valor K é o número de bits necessário para representar a faixa de valores utilizados para constantes.

Porém, a instrução LDI precisa que o valor contido no campo imediato da instrução passe pela ULA e vá para o acumulador. Isso necessita de uma nova operação na ULA, em que a saída da ULA será o valor da entrada B da ULA. Para poder selecionar essa função na ULA, precisaremos de mais um bit no ponto de controle da operação.

A instrução STA, que salva o valor do acumulador em uma posição de memória, teria uma organização do tipo:

Organização dos Campos da Instrução STA
opCode Endereço de Memória
X bits Y bits

Novamente, o valor X é o número de bits necessário para codificar todas as instruções existentes no processador. Já o valor Y é o número de bits necessário para endereçar todas as posições de memória e periféricos que existem no computador.

A instrução LDA (carrega um valor de memória para o acumulador), que é simétrica à instrução STA, teria uma organização igual à da STA. Porém, a instrução LDA, de forma similar ao LDI, precisa que o valor contido na memória passe pela ULA e vá para o acumulador. Para tanto, pode usar a mesma operação da ULA utilizado na instrução LDI, em que a saída da ULA será o valor da entrada B da ULA.

A instrução SOMA (soma um valor de memória com o acumulador e armazena no acumulador), funciona de forma similar ao LDA.

No nosso processador, a instrução CLRA pode ser substituída por LDI 0, que carrega o acumulador com o valor zero.

Para que essa modificação funcione, precisamos adicionar, ao nosso processador, um barramento de endereços (para endereçar a memória) e um barramento de dados (para ler ou escrever na memória). O espaço de endereçamento do processador é a quantidade de posições endereçáveis pelos bits (2 elevado ao número de bits) que formam o barramento de endereços. Dessa forma, um barramento de endereços com 8 bits cria um espaço de endereçamento de 256 posições, enquanto um barramento de 16 bits cria um espaço de endereçamento de 65536 posições. Esses endereços podem ser para memória e/ou periféricos, mesmo assim, o espaço total é chamado de espaço de endereçamento de memória.

Isso nos permite transferir a entrada por chaves para uma posição de memória e a saída para os LEDs para outra posição de memória.

Vamos alterar o nosso computador para que ele tenha as seguintes características:

Note que o endereço da memória e o valor imediato são utilizados por instruções diferentes. Isso permite que esses campos se sobreponham e seu significado será analisado conforme a instrução decodificada.

Fluxo de Dados Alterado
Fluxo de Dados Alterado

No FD acima, a memória está dividida em dois blocos de 256 bytes cada com a seleção feita através da linha de endereçamento A8.


Responder o quiz de participação, no blackboard, em:

Conteúdos > Participação > Aula_4_Quiz-P1



Atividade: Expandindo o Computador com Valores Imediatos e Acesso à Memória

Para adicionar essas funcionalidades, precisaremos definir novos opcodes para as novas instruções. Para tanto, utilizaremos a tabela abaixo:

Instruções
Instrução Mnemônico Código Binário Sel MUX Habilita A Operação (2 bits) habLeituraMEM habEscritaMEM
Sem Operação NOP 0000
Carrega valor da memória para A LDA 0001
Soma A e B e armazena em A SOMA 0010
Subtrai B de A e armazena em A SUB 0011
Carrega valor imediato para A LDI 0100
Salva valor de A para a memória STA 0101

As saídas que estão indicadas como X ou XX devem ser implementadas como 0 ou 00. Isso facilita o processo de debug do projeto.

Vamos aplicar esse novo formato de instruções ao nosso computador e adicionar/modificar as instruções como visto acima.

Lembre de utilizar a tabela com os pontos de controle, adicionando os novos pontos, para criar as instruções desejadas.

Será necessário alterar o decodificador de instruções para atender a esse novo formato.

Também devemos adicionar uma nova funcionalidada à ULA, chamada de passa: a transferência do valor presente na entrada B para a saída da ULA.

Por fim, vamos implementar o circuito do computador. Para simplificar, vamos utilizar uma versão somente com uma memória, mapeada entre os endereços 256 e 511, como visto na figura abaixo.

Fluxo de Dados Com RAM Mapeada entre as Posições 256 e 511
Fluxo de Dados Com RAM Mapeada entre as Posições 256 e 511

Programação da ROM

Para fazer o programa para resolver a equação S = 3x - 4, precisaremos iniciar as variáveis na memória do computador.

No programa abaixo, consideramos que a variável x vale 3 e está armazenada na posição 256 de memória.

A constante será armazenada na posição 257 de memória.

LDI $4         ; Acumulador = 4
STA @257       ; Armazena 4 na posição 257
LDI $3         ; Acumulador = 3
STA @256       ; Armazena 3 na posição 256
Soma @256      ; Soma acumulador com conteúdo de 256
...

O caractere arroba (@) indica um endereço da memória RAM enquanto que o caractere cifrão ($) indica um valor constante (imediato).

Agora, precisamos completar o programa e fazer os testes.

O resultado da compilação será o circuito, em RTL, mostrado no diagrama abaixo.

RTL do Computador
RTL do Computador

Para fazer a simulação, reagrupe os sinais de entrada e saída conforme o mostrado na figura abaixo.

Além disso, repare nos valores da entrada de dados, mostrados abaixo.

Reagrupamento dos Sinais de Entrada e Saída
Reagrupamento dos Sinais de Entrada e Saída

Considerando o valor de X como sendo 3, o resultado da simulação está mostrado abaixo.

Simulação da Equação 3X -4, com X = 3
Simulação da Equação 3X -4, com X = 3

Esta Atividade deverá ser entregue através do Blackboard!




Ferramentas