Docsity
Docsity

Prepare-se para as provas
Prepare-se para as provas

Estude fácil! Tem muito documento disponível na Docsity


Ganhe pontos para baixar
Ganhe pontos para baixar

Ganhe pontos ajudando outros esrudantes ou compre um plano Premium


Guias e Dicas
Guias e Dicas


Processador 16bits em C++, Manuais, Projetos, Pesquisas de Automação

Projeto e simulação de uma processador 16 bits em C++

Tipologia: Manuais, Projetos, Pesquisas

2015

Compartilhado em 07/12/2015

jaime-2
jaime-2 🇧🇷

5

(9)

13 documentos

1 / 15

Toggle sidebar

Esta página não é visível na pré-visualização

Não perca as partes importantes!

bg1
Universidade Federal do Rio Grande do Norte
Centro de Tecnologia
Departamento de Engenharia de Computação e
Automação
SIMULAÇÃO DE PROCESSADOR
16 BITS
Segunda Avaliação
Discente: Jaime Cristalino Jales Dantas
Matricula: 2011008771
Disciplina: Arquitetura de Computadores
Natal, 28 de novembro de 2015
pf3
pf4
pf5
pf8
pf9
pfa
pfd
pfe
pff

Pré-visualização parcial do texto

Baixe Processador 16bits em C++ e outras Manuais, Projetos, Pesquisas em PDF para Automação, somente na Docsity!

Universidade Federal do Rio Grande do Norte

Centro de Tecnologia

Departamento de Engenharia de Computação e

Automação

SIMULAÇÃO DE PROCESSADOR

16 BITS

Segunda Avaliação

Discente: Jaime Cristalino Jales Dantas

Matricula: 2011008771

Disciplina: Arquitetura de Computadores

Natal, 2 8 de novembro de 2015

Descrição do Processador

Esse trabalho consiste no desenvolvimento de um processador didático inspirado

na arquitetura do IAS de Von Neumann. O nosso processador incorpora registradores

com funções similares aos efetuados pelo MBR, MAR, IR, AC e PC de Von Neumann. O

processador manipula somente dados inteiros de 16 bits, no formato de complemento a

dois. Além disso, o nosso processador possui uma conexão com uma memória de 1024

posições, onde em cada posição armazena-se um único dado inteiro. Esta memória serve

tanto para armazenamento de instruções quanto de dados. Ela é uma memória

particionada, sendo do endereço 0 ao 499 tem-se uma partição para instruções e nos

endereços restantes (500 ao 1023), o armazenamento é de dados.

A figura a seguir mostra a arquitetura do IAS de Von Neumann

Figura 1 -­‐ Arquitetura do IAS

Nessa arquitetura de Von Neumann podemos notar uma unidade de controle

(CC) que interpreta e executa a instrução em si. Além disso, existe a unidade lógica e

aritmética (CA) que é responsável pela realização das operações binarias, uma memória

principal (M) que guarda dados e instruções, e por fim os equipamentos de entrada e

saída (I/O) que é responsável pela troca de informação com o meio externo.

Na figura abaixo podemos vizualizar como os diferentes registradores da

arquitetura de Von Neumann.

  • Contador de programa(PC): Contém o endereço da próxima instrução

que será buscada na memória

  • Acumulador(AC): Usado para operações temporárias pela CPU.

Seguindo essa arquitetura, montamos nosso processador como mostrado na figura

abaixo. Foi usado algumas simplificações, e também foi feito o uso de três registradores

de uso geral.

Figura 3 -­‐ Arquitetura do processador projetado

Para simplificarmos a implementação desse processador, não existe o tratamento

de interrupções nem o uso de pipeline. O diagrama abaixo mostra como nosso

processador funciona.

Figura 4 -­‐ Funcionamento de nosso processador

Em nossa simulação, nos definimos três diferentes “flags” de controle, sendo uma

que indica se houve ou não overflow na operação de soma com os registradores, outra

que indica se ouve ou não underflow na operação de subtração com os registradores e por

fim uma flag que indica se o programa esta ou não em execução. Se algum erro ocorrer,

o programa informará na tela qual erro ocorreu.

Não foi implementado os sinais de controle em nosso programa pois utilizamos

uma linguagem de programação de alto nível fazendo as operações diretamente.

Entretendo, alguns sinais de controle merecem ser mencionados devido a sua importância

na construção de um projeto de um processador. O primeiro sinal de controle é o

“ EnableWrite ” que ativa a escrita nos registradores de uso geral, e ele será ativo em todas

as operações excerto na operação END. O segundo sinal de controle é o “ EnableRead ”

que ativa a leitura nos registradores de uso geral e será ativo em todas as operações

excerto na etapa de busca da instrução e na operação END. Temos também o

“ WriteMemory ” que habilita a escrita na memoria e que só será ativo na operação STOR,

pois é nela que armazenamos os dados na memória. Outro sinal de controle é o

“ ReadMemory ” que habilita a leitura da memoria principal e será ativo nas etapas de

busca da instrução e na operação LOAD. E por fim, temos o sinal que incrementa o

contador de programa “ contPC ” que será ativo toda vez que for necessário incrementar o

PC, ou seja, em todas as operações exceto a de busca e END.

Também se faz necessário a especificação de sinais de controle para leitura e

escrita no AC, MBR, MAR e IR. Para esses registradores, sabemos que os sinais de

controle do MBR, MAR e IR poderão ser ativos (leitura ou escrita, logo se faz necessário

o uso de dois bits de controle) apenas na etapa de busca, já para o AC, seu sinal de

controle poderá ser ativo (escrita ou leitura, também de dois bits) nas operações de ADD

e SUM, e por fim ele poderá ser lido apenas nas operações STOR, LOAD e TEST.

Figura 6 -­‐ Valores armazenados na memória

Para cara execução de instrução foi imprimido na tela qual tipo de instrução esta

sendo feita e o valor dela. A figura abaixo mostra algumas das execuções de instruções.

Figura 7 -­‐ Execução de instruções

Como solicitado no problema, foram inseridos alguns valores diretamente na

memória pra que fosse feito o cálculo dos três últimos termos da série de Fibonacci. O

resultado final que nosso programa obteve foi de 89, 144 e 233 como mostrado na figura

abaixo.

Figura 8 -­‐ Saída do programa

Código em C++

Processador JAIME DANTAS - Arquitetura de Computadores Created by Jaime Dantas on 2015- 11 - 27. Copyright © 2015 Jaime Dantas. All rights reserved. Esse Codigo foi baseado em "Write your own Virtual CPU (in C++ Code) - May, 2012- " disponivel em http://megalomaniacbore.blogspot.com.br/2012/05/write-your-own-virtual-cpu-in-c-code.html?m= */ #include #include #include #include #include #include <stdio.h> #include #include #include #include #include //biblioteca para converter string para short #include #define Tamanho_Memoria 1024 //aqui o usuario define o tamanho da memoria using namespace std; //Definicao dos OPCODES ( sets de instrucoes de nosso processador) short STOR_X = 0x8400; //Copia o conteúdo do AC na memória de dados, no endereço X short LOAD_X = 0x400; ////Copia conteúdo da memória de dados, no endereço X, no AC short TEST_X = 0x3C00; //Copia endereço da próxima instrução a ser executada no PC, caso uma condição de teste sobre AC seja atendida. Caso contrário, a próxima instrução na sequência é que será executada. short ADD_X = 0x1400; //Soma o conteúdo do AC com o conteúdo da memória no endereço X e grava o resultado em AC short SUB_X = 0x1800; //Subtrai o conteúdo da memória no endereço X do AC e grava o resultado em AC. short END_X = 0x00; //Representa o fim da execucao da instrucao //--------------------------------------Definicao dos registradores------------------------------------------------- //OBS: Usaremos o tipo de variavel short por ser int de 16 bits com diferenciacao de sinal, exatamente o que queremos em nosso processador //Usaremos tres registradores de uso geral: //Tambem inicializaremos com 0 todos os registradores short REG0 = 0;//registrador 0 short REG1 = 0;//registrador 1 short REG2 = 0;//registrador 2 //demais registradores seguindo a nossa arquitetura short MBR = 0;//registrador de buffer de memoria short MAR = 0;//registrador de endereco de memoria short IR = 0;//registrador de instrucao short AC = 0;//acumulador short PC = 0;//contador de programa //flags do pocessador(basicamente so tres flags, ja que nao tem interrupcoes) bool overflowFLAG = false;//flag que representa overflow nas operacoes dos registradores bool underflowFLAG = false;//flag que representa underflow nas operacoes dos registradores bool execucaoFLAG = true;//diz se o processador esta ou nao executando algunha instrucao //memoria de execucao de nosso processador: //criacao de uma memoria de 1024 posicoes unsigned short * memoria = new unsigned short (Tamanho_Memoria);

short MAXIMO = 32767;//valor maximo possivel short MINIMO = - 2;//valor minimo possivel para controle de underflow //funcao de soma X void facaADD (){ REG2 = AC + memoria[REG0]; if(REG2 >= MAXIMO){ cout<< "\n Overflow no registrador REG1! \n" ; overflowFLAG = true; } else{ AC = REG2; REG0 = PC; PC = REG0 + 0x01; } } //funcao de subtracao X void facaSUB (){ REG2 = AC - memoria[REG0]; if(REG2 <= MINIMO){ cout<< "\n Underflow no registrador REG1! \n" ; underflowFLAG = true; } else{ AC = REG2; REG0 = PC; PC = REG0 + 0x01; } } //funcao que copia o contudo da memoria no endereco X void facaLOAD (){ AC = memoria[REG0]; REG1 = PC; PC = REG1 + 0x01; } //usado pra debugacao e limpeza de memoria void LimparMemoria (){ for (int i=0; i<500; i++){ memoria[i] = 0; } underflowFLAG = false; overflowFLAG = false; } //funcao q copia o valor do registrador na memoria void facaSTOR (){ memoria[REG0] = AC; REG1 = PC; PC = REG1 + 0x01; } //funcao teste como no pdf void facaTEST (){ if (AC >= 0){

else if(opcode== " SUB " ){ opcode_binario = SUB_X; str_valor = line.replace(0, 3, "" ); stringstream(str_valor) >> valor; //converte de string pra tipo short bin = ( unsigned short)((opcode_binario<<10) | valor); memoria[cont] = bin; } //comando END else{ opcode_binario = END_X; memoria[cont] = 0x00; } //cout <<"\nOpcode "<<opcode<<" Memoria "<<memoria[cont]<<endl; cout<< "\n opcode binario " <<opcode_binario; cout<< "\t memoria " <<memoria[cont]; opcode_final = opcode_binario + memoria[cont]; cout<< "\t opcode final " <<opcode_final; memoria[cont] = ( short)opcode_final; cout<< "\t MEMORIA FINAL " <<memoria[cont]; cout<< "\n --------------------------------------------------------------------------------- \n" ; cont++; } cout<< " Interpretado com sucesso! " <<endl; myfile.close(); } //caso nao consiga abrir o programa else { cout << "\n Erro ao abrir o txt, por favor tente novamente! \n" ; } } void Busca (){ MAR = PC; MBR = memoria[MAR];//Vai procurar na memoria no endereco de MAR //cout <<"\n\n\t\ok!!\n\n";//para debugacao IR = MBR & 0xFC00;//esse &0xFC00 vai separar os 6 primeiros bits dos ultimos 10 bits REG0 = MBR & 0x3FF; if (IR == STOR_X){ //cout <<"\n\n\t\ok!!\n\n"//debucagao cout<< "\n Processador executando a instrucao STOR_X " <<REG0<<endl; facaSTOR(); } else if (IR == ADD_X){ cout<< "\n Processador executando a instrucao ADD_X " <<REG0<<endl; facaADD(); } else if (IR == SUB_X){ cout<< "\n Processador executando a instrucao SUB_X " <<REG0<<endl; facaSUB(); } else if (IR == LOAD_X){ cout<< "\n Processador executando a instrucao LOAD_X " <<REG0<<endl; facaLOAD(); } else if (IR == TEST_X){

cout<< "\n Processador executando a instrucao TEST_X " <<REG0<<endl; facaTEST(); } else{ cout<< "\n Processador executando a instrucao END_X " <<endl; facaEND(); } } int main (int argc, const char * argv[]) { cout << "\n Processador 16 bits Jaime Dantas \n" ; //LimparMemoria();//para debugacao //Esses valores foram passados no pdf e correspondem aos valores iniciais da serie de fibonnaci memoria[500] = 10; //Número de termos da série memoria[501] = 0; //Posição do menor número dos três últimos da série memoria[502] = 1; //Posição do valor intermediário dos três últimos da série memoria[505] = 1;//Posição que armazena valor para decremento do laço Copilador();//pega o txt e converte todos os opcodes //procedimento de busca e execucao de instrucao while (execucaoFLAG == true && overflowFLAG == false && underflowFLAG == false){ Busca();//vai executar todas as operacoes } cout<< "\n Valor de AC = " <<AC<<endl; cout<< " Valor de PC = " <<PC<<endl; cout<< " Valor de REG0 = " <<REG0<<endl; cout<< " Valor de REG1 = " <<REG1<<endl; cout<< " Valor de REG2 = " <<REG2<<endl; cout<< " Valor de MAR = " <<MAR<<endl; cout<< " Valor de MBR = " <<MBR<<endl; cout<< " Valor de IR = " <<IR<<endl; //Impressao da serie de fibonaci dos tres primeiro termos cout<< " Saida com os tres ultimos termos da serie de fibonnaci: " <<memoria[501]<< " , " <<memoria[502]<< " , " <<memoria[503]; return 0; }