Modelagem de Arquiteturas Superescalares usando HDL
Guilherme P. Assunção, Renata C. L. Silva, Ronaldo A. L. Gonçalves Departamento de Informática - Universidade Estadual de Maringá Zona 07 - Av. Colombo 5790 - CEP 87020-900 - Maringá – PR
{guilherme.assuncao,renatals,ronaldo}@din.uem.br
Abstract. Commercial processors are designed as superscalar architectures, being able to predict branches, execute instructions speculatively and extract the implicit instruction level parallelism. These architectures arise as the evolution of the pipeline architectures, which are the evolution of the sequential model of Von Neumann. Thus, the investigation of superscalar architectures involves the investigation of their precursory architectures consequently. In this context, the hardware description languages (HDL) have been used successfully. HDL allows describing digital circuits, hardware components and complete architectures, in a software level. The present work has the main objective of proposing an evolutionary modeling of superscalar architectures using HDL, going through their precursory models. The HDL prototypes are presented and compared.
Resumo. Os computadores comerciais atuais são projetados como arquiteturas superescalares, sendo capazes de prever desvios, executar instruções especulativamente e extrair o paralelismo implícito em nível de instruções. Estas arquiteturas surgiram com a evolução das arquiteturas em pipeline, que por sua vez surgiram com a evolução do modelo seqüencial de Von Neumann. Assim, a investigação das arquiteturas superescalares envolve por conseqüência a investigação das arquiteturas precursoras. Neste contexto, as linguagens de descrição de hardware (HDL) têm sido utilizadas com êxito. HDL permite descrever circuitos digitais, componentes de hardware e até mesmo arquiteturas completas, em nível de software. O presente trabalho tem como objetivo principal propor uma modelagem evolutiva das arquiteturas superescalares usando HDL, passando por seus modelos precursores. Os protótipos HDL são apresentados e comparados.
1. Introdução
A partir do modelo de Von Neumann diversas modificações foram propostas visando melhorar o desempenho dos processadores, tais como a utilização de pipelines e caches. Porém, mesmo com esses avanços, a execução das instruções ainda mantinha-se centralizada. Surgiu então a idéia da execução de diversas instruções simultaneamente, caracterizada pelas as arquiteturas superescalares. Este modelo visa extrair o paralelismo em nível de instrução, existente implicitamente nos códigos seqüenciais convencionais, sem a necessidade da intervenção por compiladores ou programadores.
Visando o domínio do conhecimento na área de projeto de processadores superescalares, o presente trabalho propõe uma modelagem evolutiva para observar o comportamento de tais processadores, usando uma linguagem de descrição de hardware (HDL – Hardware Description Language). A modelagem evolutiva aqui proposta se caracteriza pela descrição e comparação dos protótipos de Von Neumann, pipeline e superescalar, os quais formam uma cadeia evolutiva dos processadores.
O presente trabalho está organizado da seguinte forma. A seção 2 apresenta os conceitos para os modelos arquiteturais de Von Neumann, pipeline e superescalar. A seção 3 apresenta e resume a linguagem HDL usada neste trabalho. A seção 4 apresenta o estado da arte na área de projeto de componentes e arquiteturas de computadores usando HDL. Os protótipos HDL são descritos na seção 5 e os resultados analisados na seção 6. A última seção apresenta as referências bibliográficas utilizadas.
2. Arquiteturas de Computadores: De Vo n Neumann à Superescalar
Arquiteturas de computadores são organizações de componentes em mesmo sistema computacional [3], envolvendo processadores, memória e dispositivos de entrada/saída, entre outros, levando em consideração os tipos, as características e as conexões. Pode-se dizer que a arquitetura fundamental é a de Von Neumann [1], a qual foi a precursora dos computadores superescalares atuais tais como o Pentium da Intel [4] e o PowerPc da Motorola [5].
O modelo de Von Neumann foi proposto por John Von Neumann em 1946 e traz os elementos principais para a execução de programas seqüenciais. Neste modelo, as instruções são armazenadas na memória, pois mais remotamente elas eram lidas de cartões perfurados. Esta arquitetura é baseada em três componentes principais: a memória, a unidade de controle (UC) e a unidade central de processamento (CPU).
As instruções são armazenadas na memória e executadas seqüencialmente. A Unidade de Controle decodifica cada instrução, controla sua execução e atualiza o conteúdo dos registradores. A ULA é responsável pela execução dos cálculos sobre os dados dos registradores. O primeiro computador eletrônico a seguir esse modelo foi o Edvac [6] em 1951. A partir do modelo de Von Neumann, diversos modelos surgiram visando aumentar o desempenho dos computadores.
Nos anos 80, com o surgimento dos computadores pessoais, apareceram as arquiteturas RISC [7], que visam a utilização de um conjunto reduzido de instruções, formado pelas mais freqüentemente usadas, e a eliminação do uso de micro-códigos. Estas arquiteturas usam um grande conjunto de registradores e o acesso à memória é limitado as instruções do tipo load/store. Neste caminho evolutivo, as arquiteturas superescalares surgiram como soluções mais agressivas para aumentar o desempenho.
As arquiteturas superescalares começaram a ser implantadas em processadores comerciais a partir de 1988, como o Intel i960 [8]. Essas arquiteturas são caracterizadas por extrair o paralelismo em nível de instrução. Um processador superescalar é dotado de diversas unidades funcionais especializadas e de um circuito responsável por escalonar dinamicamente aquelas que podem ser executadas em paralelo.
Para a execução de instruções em paralelo, algumas funcionalidades são necessárias [9], como a determinação das dependências entre elas, estratégias para determinar quais delas estão prontas, técnicas para renomeá-las e recursos de hardware para executar múltiplas instruções ao mesmo tempo. Os estágios e componentes básicos de uma arquitetura superescalar podem ser observados na Figura 1. Uma instrução passa por cinco estágios básicos: busca, decodificação/despacho, remessa, execução e conclusão da instrução.
I-Cache BUSCA I-FILA DECODIFICAÇÃO REMESSA EST-RES CONCLUSÃO FILA-REORD EXEC D-Cache REGs
Figura 1. Arquitetura Superescalar
As limitações das arquiteturas superescalares recaem nas dependências que podem existir durante a execução das instruções. Essas dependências são classificadas em três tipos: de dados, de controle e de recursos. A dependência de dados ocorre quando duas instruções tentam ler/escrever o mesmo registrador. Uma dependência de controle ocorre quando uma instrução de desvio é alcançada, pois o resultado da execução dessa instrução, que determinará a próxima instrução a ser executada, somente será conhecido no final do
pipeline. Para minimizar este problema, técnicas de previsão de desvios são utilizadas para
antever se esses desvios serão tomados ou não-tomados.
mesmo recurso, como as portas de acesso à memória ou de dispositivos de entrada/saída ou as unidades funcionais. Uma maneira de minimizar esse problema é aumentar os recursos disponíveis ou organizá-los em blocos separados que permitam o acesso simultâneo.
3. Linguagem de Descrição de Hardware
Linguagens de Descrição de Hardware (HDL) são linguagens de programação utilizadas para descrever formalmente circuitos eletrônicos. Além da descrição, elas também são utilizadas para projetar, experimentar e avaliar tais circuitos. As HDLs possibilitam a simulação de componentes de hardware com características reais, em nível de software, antes de serem realmente construídos, permitindo detectar e corrigir erros e assim reduzir o custo do projeto. As HDLs são muito semelhantes às linguagens de programação comuns, entretanto, apresentam certas facilidades adicionais para expressar tempo e concorrência, características fundamentais em um circuito.
Para a realização do presente trabalho foi utilizado a linguagem de descrição de
hardware VHSIC (Very High Speed Integrated Circuit), acrônimo VHDL [10], a qual é
fortemente tipificada. Ela possui padronização IEEE e sintaxe similar a das linguagens Pascal e Ada. Além da documentação de hardware, a VHDL pode ser utilizada para síntese, simulação, teste, verificação e compilação de software.
Um programa em VHDL pode ser composto por diversos módulos. Cada módulo descreve o comportamento de um componente específico, sendo formado por entidade e arquitetura. As entradas e saídas do módulo são descritas na entidade e o funcionamento do componente em si na arquitetura. Para a simulação do código é necessário associar valores às entradas. Para isso é necessária a utilização de bancadas de testes denominadas testbenchs. Estas bancadas são associadas ao projeto e determinam os valores iniciais que serão assumidos pelas entradas. Para compilar um código em VHDL é necessária a utilização de um simulador, já que as HDLs não geram código executável. Esses simuladores são capazes de ler um arquivo de entrada e executá-lo adequadamente.
O simulador adotado neste trabalho foi o VHDL Simili Tool Set, versão 3.0 [11,12], fabricado pela Symphony EDA. Dentre as quatro edições existentes dessa ferramenta, a edição free foi utilizada. A ferramenta é formada por um compilador, um simulador e uma interface gráfica. Os resultados são apresentados em um gráfico em forma de onda, onde é possível observar o comportamento do circuito especificado.
4. Trabalhos Relacionados
unidade de remessa pode possuir. Tais parâmetros podem variar em relação à largura da unidade, número de operandos por instrução e portas de registradores disponíveis.
Kukenska e Simeonov [15] descreveram o comportamento e estrutura dos processadores Intel Pentium para executar programas teste dentro do conjunto de instruções do processador especificado e simular seu modelo de memória. Todavia, o modelo desenvolvido contém apenas um processo, o qual implementa o comportamento do processador como um algoritmo seqüencial. Brisolara e Pilla [16] desenvolveram uma descrição VHDL do processador MIPS com pipeline de 5 estágios. As perdas causadas pelas dependências de dados aqui são minimizadas com a utilização do mecanismo de
forwarding, onde o resultado da execução de uma instrução é passado para as instruções
que dela dependem antes do estágio de finalização.
As HDLs também podem ser utilizadas para a descrição de componentes de hardware isolados, como por exemplo Aziz [17] que desenvolveu um multiplicador de propósito geral, que multiplica até 22 números em seqüência e Cistear [18] que projetou uma arquitetura de controle baseada em redes neurais.
5. Desenvolvimento
Esta seção apresenta o desenvolvimento de 3 modelos arquiteturais: Von Neumann, pipeline e superescalar. O formato das instruções e dos registradores, a memória de instruções, a memória de dados e a Unidade Lógica e Aritmética foram definidos iguais para todas as arquiteturas. Para o armazenamento temporário de dados foi criado um banco de registradores com capacidade de armazenamento de 256 registradores, cada um com capacidade de 32 bits, tamanho utilizado para os dados. Para o armazenamento das instruções e dos dados, foram projetadas memórias de 1KB cada, capazes de armazenar 32 instruções e 32 palavras de dados. A capacidade de armazenamento é configurada através de uma constante facilitando a expansão da memória caso necessária.
Para a descrição das arquiteturas, foram consideradas instruções de 32 bits compostas por opcode e três operandos. O opcode contém o código da operação a ser realizada, o primeiro operando indica o registrador destino do resultado da operação e os dois outros operandos indicam os registradores fontes dos dados de entrada. Cada um destes campos possui 8 bits de tamanho, que são suficientes para endereçar 256 registradores e decodificar 256 operações distintas.
Instruções que realizam operações de desvio, de acesso à memória e transferência de dados foram especificadas. A unidade de execução lógica e aritmética é capaz de realizar operações de adição, subtração, divisão e multiplicação. As instruções de desvios podem ser
BEQ (Branch if Equal) e BNE (Branch if not Equal). Após o desenvolvimento dos
Figura 2. Código em VHDL dos Circuitos Somador e Subtrator
5.1 Arquitetura de Von Neumann
A memória de instruções e o sinal de clock são as entradas deste modelo arquitetural. A cada pulso de clock uma operação é realizada. No primeiro pulso uma instrução é buscada da memória e armazenada no registrador de instruções (RI). No segundo pulso ela é decodificada e no terceiro pulso ocorre a execução da instrução. No quarto pulso ocorre o armazenamento do resultado em um dos registradores ou na memória de dados. Assim, uma instrução leva quatro pulsos (ciclos de clock) para ser executada no modelo de Von Neumann. A Figura 3 mostra o comportamento seqüencial desta arquitetura. Pode-se observar que para o RI guarda a instrução que está sendo executada correntemente, sendo que para cada ciclo de clock somente uma instrução é executada.
Figura 3. Execução de Instruções na Arquitetura Von Neumann
5.2 Arquitetura Pipeline
Na arquitetura pipeline, a execução das instruções ocorre em estágios concorrentes, a saber: busca, decodificação, execução e finalização. Para implementar a concorrência entre os estágios do pipeline, a modelagem em VHDL de cada um foi feito por de um processo HDL independente, sincronizados pelos sinais de clock.
caminho natural do código, e a técnica tomado, a qual sempre prevê que os desvios saltarão para o endereço alvo.
Na fase de decodificação, o código de operação é decifrado, os registradores identificados e os operandos de entrada são resgatados do banco de registradores. É nesta fase que as dependências de dados são determinadas. Assim, se a instrução em decodificação requer o dado de um registrador fonte que ainda não foi produzido por uma instrução precedente que ainda está nos estágios seguintes do pipeline, o pipeline é bloqueado na decodificação e bolhas são inseridas nos estágios seguintes até que a dependência seja resolvida, ou seja, até que o registrador em questão seja atualizado.
Na fase de execução, já de posse dos dados de entrada, a operação indicada no
opcode da instrução é realizada. Ao final deste estágio, a instrução é enviada para a última
fase do pipeline, a finalização. É nesta etapa que o resultado obtido na execução é escrito no banco de registradores, modificando assim o estado do processador. A Figura 4 apresenta o funcionamento da arquitetura pipeline. É possível notar que a cada início de clock (valor de
clk igual a ‘1’), as instruções são passadas de um estágio para outro, até alcançarem a fase de
finalização (ifin), onde a execução é encerrada e uma nova instrução é inserida no pipeline.
Figura 4. Execução de Instruções na Arquitetura Pipeline
5.3 Arquitetura Superescalar
As arquiteturas superescalares surgiram com a replicação do hardware existente nas arquiteturas pipeline [19]. Elas são dotadas da capacidade de executar múltiplas instruções dentro de uma mesma fase do pipeline durante um mesmo ciclo do clock. Para a descrição da arquitetura superescalar, os registradores contêm um bit de ocupação, denominado busy, e um campo denominado tag_exec, que armazena a identificação (tarja) da instrução que irá escrever no registrador. Estas novas inclusões, aliadas a um novo conjunto de registradores junto as unidade funcionais, denominado de estações de reserva, permitem a simulação de um algoritmo de escalonamento de instruções baseado no algoritmo de Tomasulo [20]. O modelo arquitetural do processador superescalar proposto apresenta um pipeline de cinco estágios: busca, decodificação/despacho, remessa, execução e finalização.
O processador superescalar é iniciado pela fase de busca das instruções, responsável por fornecer instruções para o restante do pipeline superescalar. A cada ciclo de clock instruções são buscadas e armazenadas no buffer de busca, que comporta até 8 instruções. A quantidade de instruções buscadas da memória, por ciclo, depende da capacidade livre deste
buffer, sendo que quatro é o número máximo. Durante o estágio de busca, as instruções são
previsão de desvio é realizada. As técnicas de previsão empregadas são as mesmas descritas na arquitetura pipeline.
A fase seguinte é a de decodificação, onde as instruções são movidas do buffer de busca e colocadas no buffer de decodificação, até o número máximo de quatro instruções por ciclo. Antes de inserir no buffer de decodificação, as instruções são decodificadas da seguinte forma: o campo do registrador de destino, que indica qual instrução deve atualizar seu conteúdo, denominado tag_exec, recebe o identificador da instrução e o bit de ocupação é marcado.
Caso os registradores apontados pelos operandos de entrada possuam o bit busy marcados, os dados dos registradores ainda não podem ser lidos e a instrução corrente deve aguardar até que a instrução indicada no campo tag_exec seja processada. Isso resolve a dependência direta, causada quando uma instrução tem o seu registrador fonte ocupado. Ainda neste estágio ocorre o despacho, onde as instruções que estão prontas no buffer de decodificação são escalonadas e movidas para as estações de reserva. Para cada unidade funcional há um conjunto de estações de reserva. A largura de despacho équatro, mesmo valor utilizado pelos processadores R10000, AMD K5 e PowerPC 620.
Caso as estações de reserva estejam ocupadas para determinada instrução, o despacho não ocorrerá e a mesma permanecerá no buffer de decodificação. Sempre que uma instrução for analisada pela primeira vez nesta fase, uma entrada para esta instrução é inserida no final da fila de reordenação. Assim, mesmo com a execução ocorrendo fora de ordem, os resultados são obtidos na ordem do código original. As estações de reserva são especializadas, sendo que cada conjunto associado a determinada unidade funcional possui quatro posições de armazenamento de instruções. Estas instruções ficam aguardando a disponibilidade de recursos ou dados para serem executadas.
A Figura 5 mostra a simulação de uma dessas estações, inicialmente com uma instrução armazenada. Novas instruções chegam e são armazenadas nas posições vagas. Quando uma instrução é carregada para a unidade funcional, ela é retirada e a estação de reserva é liberada para que outra instrução ocupe seu lugar. Esta mesma figura mostra que isso ocorre aos 10ns quando a primeira instrução é substituída pela segunda, e assim sucessivamente. Outras figuras foram geradas para todos os estágios superescalar, mas não são aqui mostradas devido as restrições de espaço.
Figura 5. Simulação das Estações de Reserva
A fase da remessa é responsável por retirar as instruções prontas das estações de reserva e enviá-las para a execução nas unidades funcionais associadas. Até seis instruções podem ser retiradas, sendo somente uma instrução para cada unidade funcional. Para que a instrução possa ser executada, este estágio verifica se os dados dos operandos estão prontos. Se não estão, a próxima estação de reserva é analisada até que seja encontrada uma instrução pronta ou todo o conjunto de estação tenha sido percorrido. A política de remessa usa prioridade fixa, onde a busca por uma instrução pronta sempre se inicia pela primeira posição de cada conjunto de estações de reserva.
As arquiteturas superescalares possuem unidades funcionais especializadas que possibilitam a execução de instruções diferentes simultaneamente em um mesmo ciclo. A arquitetura descrita possui seis unidades funcionais, sendo uma para cada operação aritmética, uma para calcular desvios e outra para executar as operações de acesso à memória e transferência de dados. A fase de execução recebe as instruções prontas para o processamento, executando-as em sua respectiva unidade funcional, sendo capaz de processar até seis instruções simultâneas. Após a execução de cada instrução, seu resultado é inserido na fila de reordenação, na entrada associada a respectiva instrução, sendo esta marcada como pronta para a finalização. O resultado da execução também é repassado para as estações de reserva que contém instruções aguardando este resultado.
O último estágio do pipeline na arquitetura superescalar é a finalização, também chamado de commit. Nesta etapa, o conteúdo da fila de reordenação é examinado. A análise começa sempre pela primeira posição da fila e pára quando é encontrada a primeira instrução não-pronta. Se a instrução estiver pronta para ser finalizada, sua entrada na fila de reordenação será retirada e seu resultado gravado no registrador destino. O bit de ocupação deste registrador é desmarcado caso a instrução em questão tenha sido a última a ocupar tal registrador, ou seja, quando o valor do campo tag_exec do registrador é igual ao identificador da instrução que está sendo finalizada.
Caso a instrução seja de desvio, o resultado do desvio é examinado: se o desvio foi previsto corretamente a análise da fila prossegue normalmente a partir da próxima posição. Mas, caso a previsão de desvio tenha sido incorreta, todas as instruções buscadas posteriormente à do desvio são descartadas. O descarte ocorre em todos os estágios do
pipeline. Então, o endereço de busca correto é passado para a fase da busca, que
6. Experimentação e Resultados
Para a validação dos modelos descritos em VHDL foram utilizados testes que representam trechos básicos de código fonte em linguagem de máquina. O propósito é comparar o desempenho das arquiteturas em diferentes casos de testes. Para tanto, os testes foram desenvolvidos procurando atender as diversas situações enfrentadas pelo computador durante a execução das instruções, como a ocorrência de dependência dos dados e desvios mal previstos. Para as arquiteturas pipeline e superescalar os testes ocorreram em duas etapas: a primeira utilizando a técnica de previsão de desvios sempre tomada e a segunda o previsor sempre não tomado.
Todos os modelos foram experimentados sob uma freqüência de 133 MHz, pois para os propósitos deste trabalho, os resultados relativos é que importam e não os resultados absolutos. Os experimentos iniciaram pelo modelo de Von Neumann, o qual não sofreu penalidades com a ocorrência de dependência de dados ou pela existência de desvios, já que sua execução é seqüencial e cada instrução é tratada separadamente. O modelo de pipeline obteve, obviamente, resultados melhores que o modelo de Von Neumann, mesmo sofrendo com a ocorrência constante de dependências.
Muitas bolhas são inseridas no pipeline para cada dependência ser resolvida. Percebe-se que o problema se agrava quando a previsão de desvio é feita de forma incorreta, devido ao descarte das instruções especulativas. Este modelo, quando usando a técnica de previsão não-tomado, reduziu o tempo de execução em aproximadamente 29% sobre a Von Neumann. Já com a técnica de previsão tomado, os resultados foram mais satisfatórios, reduzindo o tempo de execução sobre a Von Neumann em 43% e 19,5 % em relação ao pipeline com previsão não-tomado. Este desempenho superior da técnica tomado sobre a
não-tomado se deve ao fato da primeira técnica ser bem mais precisa em termos de acerto
(90%), o que evita descartes e redirecionamentos.
A arquitetura superescalar demonstrou o melhor desempenho dentre as analisadas, possibilitado pela utilização de diversas unidades funcionais e uma busca ampla de diversas instruções simultaneamente. Entretanto, como o número de instruções que trafegam a arquitetura superescalar é muito maior e, o número de desvios previstos incorretamente também é maior e acaba prejudicando o desempenho destas arquiteturas. Assim, faz-se necessário o emprego de técnicas de previsão de desvios eficientes, onde um pequeno aumento no acerto traz grandes benefícios [21].
Utilizando a técnica de previsão de desvio não-tomado, o modelo demonstrou-se duas vezes mais rápido que a arquitetura de Von Neumann, o que se transformaria em uma diferença maior ainda dado um conjunto de instruções mais amplo. A arquitetura superescalar obteve um ganho em torno de 28% em relação à arquitetura pipeline de mesma técnica de previsão de desvio e de 12% se comparada com a arquitetura pipeline com técnica tomado.
arquitetura foi 3.4 vezes mais rápida, com 70,6% de ganho. A Tabela 1 apresenta os resultados obtidos para um determinado conjunto de instruções do teste.
Tabela 1. Resultados de Processamento com Freqüência de Clock em 133 MHz Arquitetura Qtde de Ciclos Previsão Tempo de Execução
Von Neumann 260 - 1.950 ns 184 Não-tomado 1.380 ns Pipeline 148 tomado 1.110 ns 130 Não-tomado 975 ns Superescalar 76 tomado 570 ns
7. Conclusões e Trabalhos Futuros
Os modelos implementados em VHDL permitem comparar e analisar do desempenho de cada um dos modelos propostos e evidenciar a evolução da computação com o passar dos anos. O modelo de Von Neumann apresentou características iguais em todos os testes realizados, pois o comportamento da execução de cada instrução é semelhante, sempre utilizando uma quantidade fixa de ciclos.
A evolução para o pipeline provoca um ganho razoável no desempenho. No pior caso, quando existem dependências entre todas as instruções, o tempo de resposta da execução das instruções é igual ao do modelo de Von Neumann. São justamente essas dependências que prejudicam o funcionamento das arquiteturas pipeline, pois a inserção de bolhas atrasa a execução de algumas instruções, prejudicando o desempenho.
Já a utilização de diversas unidades funcionais, existentes nas arquiteturas superescalares, representou um ganho de desempenho maior ainda. Os testes mostraram que a busca e decodificação em paralelo acelera o tempo final de resposta, principalmente para um conjunto grande de instruções. A perda de desempenho ocorre quando muitas operações iguais são executadas, pois as estações de reserva ficam cheias e causam a parada das instruções subseqüentes nos buffers de decodificação e busca.
De uma forma geral, a VHDL permitiu a descrição do funcionamento das arquiteturas propostas, possibilitando testes e análises comportamentais de tais modelos em nível de software e viabilizando a pesquisa na área. Como trabalhos futuros, o modelo da arquitetura superescalar deverá ter mais funcionalidades e recursos de forma a se aproximar de um processador real. Novas instruções também serão implementadas.
Referências Bibliográficas
[1] Godfrey, M. D., Hendry, D. F., “The Computer as Von Neumann Planned It”, Annals of the
History of Computing, IEEE, volume 15, Nº 1, p. 11-21, 1993.
[2] Aspray, W., “The Stored Program Concept”, IEEE Spectrum, Volume 27, Edição 9, 1990, p. 51-57.
[4] Gwennap, L., “Intel's P6 Uses Decoupled Superscalar Design”, Microdesign Resources, Vol.6, N° 2, 1995.
[5] Diep, T., Nelson, C., and Shen, J., “Performance Evaluation of the PowerPC 620 Microarchitecture”, Proceedings of the 22nd Annual International Symposium on Computer
Architecture, p. 163-175, 1995
[6] Von Neumann, J., “First Draft of a Report on the EDVAC”, Annals of the History of
Computing, Volume 15, Edição 4, 1993, p. 27-75.
[7] Stalling, W., “Reduced Instruction Set Computer Architecture”, Proceeding of the IEEE, Volume 76, Edição 1, 1988, p. 38-55.
[8] Garbus, E., “Designing Performance Into i960 Superscalar Microprocessors”, Proceedings of
the Thirty-Seventh IEEE Computer Society International Conference, p. 354-357, 1992.
[9] Smith, J.E., Sohi, G.S., “The Microarchitecture of Superscalar Processors”, Proceedings of
the IEEE, Vol. 83, 1995, p.1609-1624.
[10] Shahdad, M., “An Overview of VHDL Language and Technology”, Proceedings of the 23rd
Design Automation Conference, 1986, p. 320-326.
[11] Symphony Eda, VHDL User’s Manual, versão 3.0, EUA, 2005. 87p.
[12] VHDL Simili Tool Set, versão 3.0. Acessado <www.symphnyeda.com> em 04/2006.
[13] Alcântara, J.M.S., et al, “Designing the Dispatch Stage of a Superscalar Microprocessor”, Proceedings of the XI Brazilian Symposium on Integrated Circuit Design, 1998, p. 150-153.
[14] Gavin, M.T., Using VHDL Synthesis and VLSI Layout Tools for Cost Estimation of Superscalar Issue Units, Tese de Mestrado, Universidade de Illinois, 1995.
[15] Kukenska, V.S., Simeonov, I.S., “VHDL Models of Processor Intel Pentium”, Proceedings of the 6th International Conference on Telecommunications in Modern Satellite, Cable and Broadcasting Service, 2003, p.769-772.
[16] Brisolara, L.B., Pilla, M.L., Descrição em VHDL do MIPS Pipeline, Relatório de Projeto, Universidade Federal do Rio Grande do Sul, 2000, 21p.
[17] Aziz, S.M., Basheer, C.N, Kamruzzaman, J., “A Synthesizable VHDL Model For An Easily Testable Generalized Multiplier”, Proceedings of the first International Workshop on Electronic Design, Test and Applications, 2002, p. 504-506.
[18] Cistear, M., et al, “A VHDL Success Story: Electric Drive System Using Neural Controller”, Proceedings of the VHDL International Users Forum Fall Workshop, 2000, p. 118-122.
[19] Gonçalves, R.A.L., “Arquiteturas Multi-Tarefas Simultâneas – Sempre: Arquiteturas SMT com Capacidade de Execução e Escalonamento de Processos”, Tese de Doutorado, Universidade Federal do Rio Grande do Sul, 2000, 136p.
[20] Tomasulo, R.M., “An Efficient Algorithm for Exploiting Multiple Arithmetic Units”, IBM Journal of Research and Development, pp. 25-33, January 1967