CPU-1 Microprocessador
didático
descrito em VHDL
Tópicos ·
Arquitetura e Modos de
Endereçamento ·
Conjunto de
instruções ·
Interligação
e comunicação com
periféricos ·
Diagrama de blocos ·
Operação da
unidade de controle ·
Exemplos de
operação de algumas
instruções ·
Código VHDL do
microprocessador |
Objetivo ·
Propor um código
VHDL para uma
arquitetura de um microprocessador ·
Análise das
unidades operativas
frente ao código |
Arquitetura do
microprocessador ·
Procura explorar
situações diversas - Sinais de controle de
periféricos -
Instruções com um acesso à memória -
Instruções com dois acessos à
memória ·
Contém um conjunto
básico de
instruções com: - Diferentes modos de
endereçamento - 8 bits: Acesso Direto e
Acesso
Indireto - 8+8 bits: Aceso Imediato - Operações
com uma Unidade Lógica
Aritmética - Desvios condicionais - Chamadas de sub-rotinas ·
Permite ampliar o
conjunto de
instruções |
Arquitetura e Modos de
Endereçamento |
Conjunto de instruções: Load, Store e Aritméticas
[Pg & n] = conteúdo do endereço de memória apontado pelo valor de Pg concatenado com n [[Pg & n]]= conteúdo do
endereço
de memória apontado pelo endereço de memória
apontado pelo valor de
Pg & n |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||
Conjunto de
instruções: Desvio, Desvio
condicional e Subrotina
|
||||||||||||||||||||||||||||||||||||||||
Conjunto de
instruções: Pacote cpu_aux ·
Declaração
de tipo:
possíveis
estados da máquina (busca de instrução ou execução
de instrução) ·
Função de
conversão:
- valor numérico do código (dado em
memória) => mnemônico
correspondente
- instruções com código 4 bits + n: valores reservados => '0,n'
a 'E,n'
- instruções com código de 8 bits: valores reservados => 'F,0' a 'F,F'
|
|
Interligação e comunicação com periféricos
|
Diagrama
de blocos |
Operação da unidade de controle: duas máquinas seqüenciais |
Exemplos de
operação de algumas
instruções (próximas
imagens) ·
Carta de tempos ·
Unidades envolvidas |
Busca de Instrução: carta de tempos |
Instrução LDiA,n (Load Indirect Acc): carta de tempos |
Instrução
LDiA,n (Load
Indirect Acc): Unidades envolvidas Passo_op_cod=0 |
Instrução LDiA,n (Load Indirect Acc): Unidades envolvidas Passo_op_cod=1
|
Instrução STiA,n (Store Indirect Acc): carta de tempos |
Instrução
STiA,n (Store
Indirect Acc): Unidades envolvidas Passo_op_cod=0 |
Instrução
STiA,n (Store
Indirect Acc): Unidades envolvidas Passo_op_cod=1 |
Instrução Call,mm (Chamada de subrotina): carta de tempos |
Instrução Call,mm (Chamada de subrotina): Unidades envolvidas Passo_op_cod=0
|
Instrução
Call,mm (Chamada
de subrotina): Unidades envolvidas Passo_op_cod=1
|
Teste da
descrição (3 entidades: CPU,
Memória e Conjunto) ·
Memória
contem um pequeno programa para verificar a operação das
instruções ·
Compile: Declaração
do pacote cpu_aux,
Corpo
do pacote cpu_aux,
Declaração da entidade
cpu_8bits, Arquitetura teste de cpu_8bits
Declaração da entidade ram_8x8,
Arquitetura teste de ram_8x8
Declaração da entidade
conjunto_5 Arquitetura
teste de conjunto_5 · Para verificar a operação simule a entidade conjunto_5
|
Código
do microprocessador -- VHDL - Descricao e Sintese de Circuitos Digitais http://www.ele.ita.br/~damore/vhdl/ -- Roberto d'Amore -- Editora LTC - 2005 http://www.ltceditora.com.br -- -- -- Teste do conjunto CPU + Memoria -- Memoria contem um pequeno programa para verificar a operacao das instrucoes -- -- Compile o conjunto: Declaracao do pacote cpu_aux, Corpo do pacote cpu_aux, -- Declaracao da entidade cpu_8bits, Arquitetura teste de cpu_8bits -- Declaracao da entidade ram_8x8, Arquitetura teste de ram_8x8 -- Declaracao da entidade conjunto_5 e Arquitetura teste de conjunto_5 -- -- Para verificar a operacao simule a entidade conjunto_5 ---------------------------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------------------------- -- Pacote auxiliar -- Definicao de tipo contendo mnemonicos e funcao de valor numerioco para mnemonico ---------------------------------------------------------------------------------------------------------- ---->> Emprego do pacote 'textio': veja capitulo 13 <<---- ---->> Definicao e uso de pacotes: veja capitulo 9 <<---- Library IEEE; Use IEEE.Std_Logic_1164.All; Use IEEE.Std_Logic_arith.All; -- Biblioteca Synopsys necessaria conversoes com Std_Logic Package cpu_aux Is -- declaracao do pacote -- Tipo contendo os possiveis estados da maquina Type Tipo_estado Is (busca, LDmP, LDmS, LDmA, LDdA, LDiA, STdA, STiA, Jump, JP_Z , JPNZ, JPNG, ADdA, SBdA, Call, RETN, Halt); Function para_estado(dado : Std_Logic_Vector(7 Downto 0)) Return Tipo_Estado; End cpu_aux; Package Body cpu_aux Is -- corpo do pacote -- Funcao para converter um valor numerico no codigo do mnemonico correspondente. -- Entrada tipo Std_Logic_Vector. Retorna valor no tipo estado com o mnemonico decodificado Function para_estado(dado : Std_Logic_Vector(7 Downto 0)) Return Tipo_Estado Is Variable mnemonico : Tipo_Estado; -- Mnemonico interpretado Begin If (dado(7 Downto 4) /= x"f") Then -- Codigos entre "0" e "d". Mnemonico identificado pelos 4 bits mais significativos Case dado(7 Downto 4) Is When x"0" => mnemonico := LDmP; When x"1" => mnemonico := LDdA; When x"2" => mnemonico := LDiA; When x"3" => mnemonico := STdA; When x"4" => mnemonico := STiA; When x"a" => mnemonico := ADdA; When x"b" => mnemonico := SBdA; When Others => mnemonico := Halt; End Case; Else -- Codigos entre "f0" e "ff". Mnemonico identificado pelos 8 bits Case dado Is When x"f0" => mnemonico := Jump; When x"f1" => mnemonico := JP_Z; When x"f2" => mnemonico := JPNZ; When x"f3" => mnemonico := JPNG; When x"f6" => mnemonico := LDmS; When x"f7" => mnemonico := LDmA; When x"f8" => mnemonico := Call; When x"f9" => mnemonico := RETN; When Others => mnemonico := Halt; End Case; End If; Return mnemonico; End Function; End cpu_aux; ---------------------------------------------------------------------------------------------------------- -- Codigo da CPU ---------------------------------------------------------------------------------------------------------- ---->> Bibliotecas e Pacotes: veja capitulo 9 <<---- ---->> Padroes IEEE 1164 e IEEE 1076.e: veja capitulos 10 e 11 <<---- Library IEEE; Use IEEE.Std_Logic_1164.All; Use IEEE.Std_Logic_arith.All; -- Biblioteca Synopsys necessaria para a operacoes aritmeticas com Std_Logic Use IEEE.Std_Logic_unsigned.All; -- Biblioteca Synopsys necessaria para a operacoes aritmeticas com Std_Logic Use Work.cpu_aux.All; -- Pacote com definicao de tipos e funcoes ---->> Declaracao de Entidade: veja capitulo 2 <<---- Entity cpu_8bits Is ---->> Genericos: veja capitulos 2 e 10 <<---- Generic (ne : Integer := 8; -- ne = numero de linhas do barramento de endereco nd : Integer := 8); -- nd = numero de linhas do barramento de dado ---->> Clausula 'port' e modo das portas: veja capitulo 2 <<---- Port (ck : In Std_Logic; -- Entrada. Sinal de relogio: operacoes nas bordas de subida e descida rst_b : In Std_Logic; -- Entrada. Sinal de inicializacao sincrona, ativo nivel baixo (reset) mrq_n : Buffer Std_Logic; -- Saida. Sinal para requisicao de memoria, ativo nivel baixo wr_n : Buffer Std_Logic; -- Saida. Sinal de escrita, ativo nivel baixo rd_n : Buffer Std_Logic; -- Saida. Sinal de leitura, ativo nivel baixo Ed : Out Std_Logic_Vector(ne-1 Downto 0); -- Saida. Barramento de enderecos Dt : InOut Std_Logic_Vector(nd-1 Downto 0)); -- Entrada Saida. Barramento de dados End cpu_8bits; ---->> Corpo da Arquitetura: veja capitulo 2 <<---- Architecture teste Of cpu_8bits IS ---->> Classe de objetos: veja capitulo 2 <<---- Signal Estado : Tipo_estado; -- Estado da maquina: busca de instrucao ou execucao da instrucao Signal Passo_rd_wr : Integer Range 0 To 3; -- Passo da operacao de escrita ou leitura. Controlado por 'borda_descida' Signal Passo_op_cod : Integer Range 0 to 3; -- Passo da operacao de acesso indireto a memoria. Signal Ler, Escrever : Boolean; -- Sinais empregados para inicio das operacoes de leiutura e escrita na memoria -- Codigo não permite ainda alteracao nos valores de 'ne' e 'nd' Signal Pc : Std_Logic_Vector(ne-1 Downto 0); -- Registrador contador de programa. Signal pc_inc : Std_Logic_Vector(ne-1 Downto 0); -- Saida da unidade que incrementa o valor de Pc Signal St : Std_Logic_Vector(ne-1 Downto 0); -- Registrador endereco da pilha - "Stack Pointer". Signal st_novo : Std_Logic_Vector(ne-1 Downto 0); -- Saida da unidade que incrementa/decrementa o valor de St Signal End_mem : Std_Logic_Vector(ne-1 Downto 0); -- Registrador que armazena o valor imposto ao barramento de endereco Signal Pg : Std_Logic_Vector(3 Downto 0); -- Registrador de pagina de memoria Signal Ir : Std_Logic_Vector(nd-1 Downto 0); -- Registrador de instrucao Signal Acc : Std_Logic_Vector(nd-1 Downto 0); -- Acumulador Signal Aux : Std_Logic_Vector(nd-1 Downto 0); -- Registrador auxiliar para armazenar o valor do barramento de dado Signal Dado_escr : Std_Logic_Vector(nd-1 Downto 0); -- Registrador que armazena o valor imposto ao barramento de dado Signal alu_s, alu_b : Std_Logic_Vector(nd-1 Downto 0); -- Saida e operando 'b' da ALU Signal Alu_flags : Std_Logic_Vector(1 Downto 0); -- Registrador que armazena 'alu_n' e 'alu_z' Signal alu_n, alu_z : Std_Logic; -- Valor decodificado da saida da ALU Begin -- Maquina principal responsavel pela decodificacao das instrucoes e realizacao das operacoes -- Trabalha em conjunto com a maquina que realiza o acesso a memoria denominada: 'borda_descida' -- Informacoes enviadas para maquina 'borda_descida' via os sinas 'Ler' e 'Escrever' -- Informacoes recebidas da maquina 'borda_descida' via o sinal 'Passo_rd_wr' ---->> Comando 'process': veja capitulo 3 <<---- ---->> Lista de sensibilidade em processos: veja capitulo 4 <<---- borda_subida: Process (ck, rst_b) Variable salta : Boolean; -- Empregada para determinar a necessidade de desvio nas instrucoes Jump, JPNZ etc. Begin -- Preparacao: inicializacao assincronas ---->> Maquinas sequenciais sincronas: veja capitulo 6 <<---- ---->> Comando 'If': veja capitulo 4 <<---- If rst_b ='0' Then Ler <= False; Escrever <= False; -- Condicoes para maquina 'borda_descida' Estado <= busca; -- Estado inicial: busca de instrucao Passo_op_cod <= 0; -- Sinal empregado em operacoes de acesso indireto a memoria ---->> Agregado: veja capitulo 2 <<---- Pc <= (Others => '0'); End_mem <= (Others => '0'); -- Valor inicial do contador de programa e registrador de endereco -- Operacao normal ---->> Deteccao de borda de subida em sinais: veja capitulo 6 <<---- ElsIf ck'Event And ck='1' Then Case Estado Is -- Busca na memoria da proxima operacao When busca => If Passo_rd_wr = 0 Then Ler <= True; end_mem <= Pc; ElsIf Passo_rd_wr = 2 Then Ir <= Dt; ElsIf Passo_rd_wr = 3 Then Estado <= para_estado(Ir); Ler <= False; End If; -- Load Immediate Page: Pg <= Ir(3..0) When LDmP => Pg <= Ir(3 Downto 0); Pc <= pc_inc; Estado <= busca; -- Load Immediate Acc: Acc <= [Pc +1] When LDmA => -- Atualiza valor de Acc. Dado armazenado na proxima posicao de memoria If Passo_rd_wr =0 Then Ler <= True; End_mem <= pc_inc; -- Leitura do conteudo da prox. posicao de memoria: Pc+1 ElsIf Passo_rd_wr =2 Then Acc <= Dt; Pc <= pc_inc; -- Acc recebe novo valor. Contador de programa recebe valor: Pc+1 ElsIf Passo_rd_wr =3 Then Estado <= busca; Pc <= pc_inc; Ler <= False; -- Contador de programa recebe valor: Pc+2. Fim do ciclo de leitura. End If; -- Load Immediate Stack: St <= [Pc +1] When LDmS => -- Atualiza valor de St. Dado armazenado na proxima posicao de memoria If Passo_rd_wr =0 Then Ler <= True; End_mem <= pc_inc; -- Leitura do conteudo da prox. posicao de memoria: Pc+1 ElsIf Passo_rd_wr =2 Then St <= Dt; Pc <= pc_inc; -- St recebe novo valor. Contador de programa recebe valor: Pc+1 ElsIf Passo_rd_wr =3 Then Estado <= busca; Pc <= pc_inc; Ler <= False; -- Contador de programa recebe valor: Pc+2. Fim do ciclo de leitura. End If; -- Load Direct Acc: Acc <= [Pg & Ir(3..0)] When LDdA => -- Leitura do dado armazenado em [Pg & Ir(3..0)] If Passo_rd_wr = 0 Then Ler <= True; End_mem <= Pg & Ir(3 Downto 0); -- Leitura da posicao de memoria M[Pg & Ir(3..0)] ElsIf Passo_rd_wr = 2 Then Acc <= Dt; Pc <= pc_inc; -- Acc recebe novo valor. Contador de programa incrementado ElsIf Passo_rd_wr = 3 Then Estado <= busca; Ler <= False; -- Fim do ciclo de leitura End If; -- Store Direct: [Pg & Ir(3..0)] <= Acc When STdA => -- escrita do dado no endereco [Pg & Ir(3..0)] If Passo_rd_wr = 0 Then Escrever <= True; Dado_escr <= Acc; End_mem <= Pg & Ir(3 Downto 0); -- Escrita na posicao de memoria M[Pg & Ir(3..0)] ElsIf Passo_rd_wr = 2 Then Pc <= pc_inc; -- Contador de programa incrementado ElsIf Passo_rd_wr = 3 Then Estado <= busca; Escrever <= False; -- Fim do ciclo de escrita End If; -- Load Indirect: Acc <=[[Pg & Ir(3..0)]] When LDiA => -- Leitura do dado armazenado em [[Pg & Ir(3..0)]] If Passo_op_cod = 0 Then -- leitura do endereco armazenado em [Pg & Ir(3..0)] If Passo_rd_wr = 0 Then Ler <= True; End_mem <= Pg & Ir(3 Downto 0); -- Leitura da posicao de memoria M[Pg & Ir(3..0)] ElsIf Passo_rd_wr = 2 Then Aux <= Dt; -- Registrador Aux armazena endereco apontado ElsIf Passo_rd_wr = 3 Then Passo_op_cod <= 1; Ler <= False; -- Fim do primeiro ciclo de leitura End If; Else -- leitura do dado armazenado M[[Pg & Ir(3..0)]] If Passo_rd_wr = 0 Then Ler <= True; End_mem <= Aux; -- Leitura da posicao de memoria contida em Aux ElsIf Passo_rd_wr = 2 Then Acc <= Dt; Pc <= pc_inc; -- Acc recebe novo valor. Contador de programa incrementado ElsIf Passo_rd_wr = 3 Then Estado <= busca; Ler <= False; Passo_op_cod <= 0; -- Fim do segundo ciclo de leitura End If; End If; -- Store Indirect: [[Pg & Ir(3..0)]] <= Acc When STiA => -- Armazenamento do dado em [[Pg & Ir(3..0)]] If Passo_op_cod = 0 Then -- leitura do endereco armazenado em [Pg & Ir(3..0)] If Passo_rd_wr = 0 Then Ler <= True; End_mem <= Pg & Ir(3 Downto 0); -- Leitura da posicao de memoria M[Pg & Ir(3..0)] ElsIf Passo_rd_wr = 2 Then aux <= Dt; -- Registrador Aux armazena endereco apontado ElsIf Passo_rd_wr = 3 Then Passo_op_cod <= 1; Ler <= False; -- Fim do ciclo de leitura End If; Else -- escrita do dado no endereco M[[Pg & Ir(3..0)]] If Passo_rd_wr = 0 Then Escrever <= True; Dado_escr <= Acc; End_mem <= aux; -- Escrtia na posicao de memoria contida em Aux ElsIf Passo_rd_wr = 2 Then Pc <= pc_inc; -- Contador de programa incrementado ElsIf Passo_rd_wr = 3 Then Estado <= busca; Escrever <= False; Passo_op_cod <= 0; -- Fim do ciclo de escrita End If; End If; -- Instrucoes de salto. Salto, Salto se Zero, Salto se Nao Zero, Salto se Negativo ---->> Comando 'case' com delimitador '|': capitulo 4 <<---- When Jump |JP_Z | JPNZ | JPNG => -- Teste para determinar a necessidade de desvio para um novo endereco de memoria If Estado = Jump Then salta := True; -- Instrucao Jump. Sempre Pc <= [Pc+1]. ElsIf Estado = JP_Z And alu_flags(1) ='1' Then salta := True; -- Instrucao JP_Z. Se Z =1, Pc <= [Pc+1]. Se Z=0 Pc <= Pc+2; ElsIf Estado = JPNZ And alu_flags(1) ='0' Then salta := True; -- Instrucao JPNZ. Se Z =0, Pc <= [Pc+1]. Se Z=1 Pc <= Pc+2; ElsIf Estado = JPNG And alu_flags(0) ='1' Then salta := True; -- Instrucao JPNG. Se N =1, Pc <= [Pc+1]. Se N=0 Pc <= Pc+2; Else salta := False; End If; -- Executa o desvio ou nao If salta Then -- Desvio para novo endereco de memoria apontado pela proxima posicao de memoria If Passo_rd_wr =0 Then Ler <= True; end_mem <= pc_inc; -- Leitura do conteudo da prox. posicao de memoria ElsIf Passo_rd_wr =2 Then Pc <= Dt; -- Pc recebe novo valor ElsIf Passo_rd_wr =3 Then Estado <= busca; Ler <= False; -- Fim do ciclo de leitura End If; Else -- Incrementar o Pc duas vezes para busca da nova instucao em duas etapas If Passo_op_cod =0 Then Pc <= pc_inc; Passo_op_cod <= 1; -- Primeiro incremento Else Pc <= pc_inc; Estado <= busca; Passo_op_cod <= 0; -- Segundo incremento End If; End If; -- Operacoes com a ALU -- Add Direct 'ADdA': Acc <= Acc + [Pg & Ir(3..0)] bits de sinalizacao ativados (alu_flags <= zero, negativo) -- Subtract Direct 'SBdA': Acc <= Acc - [Pg & Ir(3..0)] bits de sinalizacao ativados (alu_flags <= zero, negativo) When ADdA | SBdA => -- leitura do dado armazenado em M[Pg & Ir(3..0)] If Passo_rd_wr = 0 Then Ler <= True; end_mem <= Pg & Ir(3 Downto 0); ElsIf Passo_rd_wr = 2 Then alu_b <= Dt; Pc <= pc_inc; ElsIf Passo_rd_wr = 3 Then Acc <= alu_s; alu_flags <= alu_z & alu_n; Estado <= busca; Ler <= False; End If; -- Operacoes com a pilha. Chamada de subrotina e retorno da subrotina When Call => -- Chama subrotina Pc <= [Pc+1]; [St] <= Pc +2; If Passo_op_cod = 0 Then -- leitura do endereco da subrotina If Passo_rd_wr = 0 Then Ler <= True; End_mem <= pc_inc; -- Leitura da proxima posicao de memoria: contem endereco da subrotina ElsIf Passo_rd_wr = 2 Then Aux <= Dt; Pc <= pc_inc; -- Endereco da subrotina armaz. em Aux. Contador de programa incrementado ElsIf Passo_rd_wr = 3 Then Passo_op_cod <= 1; Ler <= False; -- Fim do ciclo de leitura End If; Else -- Escrita do endereco de retorno na pilha; Decremento do ponteiro da pilha: St <= St -1; If Passo_rd_wr = 0 Then Escrever <= True; Dado_escr <= pc_inc; End_mem <= St; -- Escrita do endereco de retorno ElsIf Passo_rd_wr = 2 Then St <= st_novo; Pc <= Aux; -- Ponteiro da pilha decrementado. Pc recebe end. da subrotina ElsIf Passo_rd_wr = 3 Then Estado <= busca; Escrever <= False; Passo_op_cod <= 0; -- Fim do ciclo de escrita End If; End If; When RETN => -- Retorno da subrotina Pc <= [St+1]; [St] <= St +1 If Passo_rd_wr = 0 Then Ler <= True; End_mem <= st_novo; -- Leitura do endereco apontado por St ElsIf Passo_rd_wr = 2 Then Pc <= Dt; St <= st_novo; -- Endereco de retorno em Pc. Ponteiro da pilha incrementado ElsIf Passo_rd_wr = 3 Then Estado <= busca; Ler <= False; -- Fim do ciclo de leitura End If; -- Halt: parada de operacao When Halt => Estado <= Halt; End Case; End If; End Process; -- Maquina secundaria que realiza as operacoes de acesso a memoria. -- Ciclo de leitura tem inicio com Ler=verdairo. Ciclo de escrita tem inicio com Escrever=verdadeiro -- Opera em conjunto com a maquina 'borda_subida' -- Para operacao correta: apenas Ler ou Escrever ativos; uma vez iniciada a operacao devem ser manditidos ate Passo_rd_wr=3 borda_descida: Process (ck, rst_b) Begin If rst_b ='0' Then mrq_n <= '1'; wr_n <= '1'; rd_n <='1'; Passo_rd_wr <= 0; -- Acesso a memoria: passos para leitura e escrita -- Operacoes executadas caso Ler ou Escrever verdadeiros. ElsIf ck'Event And ck='0' Then Case Passo_rd_wr Is When 0 => If Ler Then Passo_rd_wr <= 1; mrq_n <= '0'; rd_n <= '0'; Elsif Escrever Then Passo_rd_wr <= 1; mrq_n <= '0'; End If; When 1 => If Ler Then Passo_rd_wr <= 2; Elsif Escrever Then Passo_rd_wr <= 2; wr_n <= '0'; End If; When 2 => If Ler Then Passo_rd_wr <= 3; mrq_n <= '1'; rd_n <= '1'; Elsif Escrever Then Passo_rd_wr <= 3; mrq_n <= '1'; wr_n <= '1'; End If; When 3 => Passo_rd_wr <= 0; End Case; End If; End Process; -- Comando da saida do barramento de enderecos Ed <= end_mem; -- Comando da saida do barramento de dados Dt <= dado_escr When (Escrever And mrq_n ='0') Else (Others => 'Z'); ---->> Comando 'Block': veja capitulo 3 <<---- -- Unidade Logica Aritmetica Unidade_Logica: Block Constant zero : Std_Logic_Vector(alu_s'Range) := (Others => '0'); Begin alu_s <= Acc + alu_b When (Estado = ADdA) Else -- alu executa operacao de soma Acc - alu_b; -- alu executa operacao de subtracao alu_z <= '1' When (alu_s = zero) Else '0'; -- resultado da op. na alu igual a zero alu_n <= '1' When (alu_s(alu_s'High) = '1') Else '0'; -- resultado da op. na alu negativo End Block; -- Incremento do endereco do contador de programa: Pc Contador_Programa: Block Begin pc_inc <= Pc +1; End Block; -- Incremento / Decremento do ponteiro da pilha pilha: Block Begin st_novo <= St -1 When (Estado = Call) Else -- ponteiro decrementado: chamada de subrotina St +1; -- ponteiro incrementado: retorno de subrotina End Block; End teste; ---------------------------------------------------------------------------------------------------------- -- Celula de memoria com programa para teste ---->> Sintese e descricao de memorias: veja capitulo 12 <<---- ---------------------------------------------------------------------------------------------------------- Library IEEE; Use IEEE.Std_Logic_1164.All; Use IEEE.Std_Logic_arith.All; Use IEEE.Std_Logic_unsigned.All; -- Biblioteca Synopsys necessaria para a funcao Conv_Integer Use Work.cpu_aux.All; -- Pacote com definicao de tipos e funcoes Entity ram_8x8 Is Port (ce_n, oe_n, wr_n: In Std_Logic; Ed : In Std_Logic_Vector(7 Downto 0); Dt : InOut Std_Logic_Vector(7 Downto 0)); End ram_8x8; Architecture teste Of ram_8x8 Is Type arranjo_memoria Is Array (Natural Range <>) Of Std_Logic_Vector(7 downto 0); Signal dados : arranjo_memoria(0 To 255) := -- endereco valor inicial da memoria (16#00# => x"0A", -- Load Immediate Page (LDmP) Pg <= A (Pg recebe o valor A) 16#01# => x"f6", -- Load Immediate Stack (LDmS) Sp <= FF (Sp recebe valor) 16#02# => x"FF", -- dado de LDmS 16#03# => x"10", -- Load Direct Acc (LDdA) Acc <=[Pg & 0] (Acc =77) (77 e' o valor contido no endereco A0) 16#04# => x"af", -- Add Direct Acc (ADdA) Acc <= Acc+[Pg & f] (Acc =77 +02) (02 e' o valor contido no endereco AF) 16#05# => x"31", -- Store Direct Acc (STdA) [Pg & 1] <= Acc (Endereco A1 recebe o valor 79) 16#06# => x"2E", -- Load Indirect Acc (LDiA) Acc <=[[Pg & E]] (Acc =25) (Acc recebe o valor contido no endereco apontado pelo endereco AE) 16#07# => x"BF", -- Subtract Direct Acc (SBdA) Acc <= Acc-[Pg & f] (Acc =25 -02) 16#08# => x"4C", -- Store Indirect Acc (STiA) [[Pg & C]] <= Acc (Endereco A3, apontado pelo endereco AC, recebe o valor 23) 16#09# => x"f0", -- Jump (Jump) Pc <= [Pc+1] (Salto para no endereco apontado no proximo endereco de memoria, no caso "3A") 16#0A# => x"3A", -- endereco de Jump 16#3A# => x"f7", -- Load Immediate Acc (LDmA) Acc <= fb (Acc recebe valor -5) 16#3B# => x"fb", -- dado de LDmA 16#3C# => x"a7", -- Add Direct Acc (ADdA) Acc <= Acc+[Pg & 7] (Acc recebe o valor -5+4=-1. Valor 4 armazenado em A7) 16#3D# => x"f3", -- Jump Negative (JPNG) Pc <=[Pc+1] (se N=1) (Salto para o endereco 25, resultado neg. na op. da Alu) 16#3E# => x"40", -- endereco de JPNG 16#40# => x"f8", -- Call Subrotine (Call) Pc <= [Pc+1] 16#41# => x"70", -- dado de Call 16#42# => x"ff", -- Halt 16#70# => x"f7", -- Load Immediate Acc (LDmA) Acc <=03 (Acc recebe o valor 3) 16#71# => x"03", -- dado de LDmA 16#72# => x"BB", -- Subtract Direct Acc (SBdA) Acc <= Acc-[Pg & B] (Acc recebe os valores 3-1, 2-1,1-1. Valor 1 armazenado em 3f 16#73# => x"f2", -- Jump Not Zero (JPNZ) Pc <= [Pc+1] (se Z=0) (Termina a iteracao se resultado da op. na alu igual a zero) 16#74# => x"72", -- endereco de JPNZ 16#75# => x"f9", -- Return (RETN) 16#A0# => x"77", -- dado para instrucao LDdA no endereco 03 (valor +77) 16#A1# => x"FF", -- local onde e' armazenado o resultado da operacao na linha 05 16#A2# => x"25", -- dado apontado pelo endereco AE na instrucao da linha 06 (valor +25) 16#A3# => x"FF", -- local onde e' armazenado o resultado da operacao na linha 08 16#A7# => x"04", -- dado para instrucao ADdA no endereco 3C (valor +4) 16#AB# => x"01", -- dado para instrucao SBdA no endereco 72 (valor +1) 16#AC# => x"A3", -- ponteiro instrucao STiA no endereco 08 16#AD# => x"03", -- dado para instrucao SBdA no endereco 07 (valor +3) 16#AE# => x"A2", -- ponteiro instrucao LDiA no endereco 06 16#AF# => x"02", -- dado para instrucao ADdA no endereco 04 (valor +2) Others => x"ff"); -- halt Begin Process(ce_n, oe_n, wr_n, dados, Dt, Ed) Begin -- operacao de escrita da memoria If rising_edge(wr_n) Then If ce_n = '0' Then dados(Conv_Integer(Ed)) <= Dt; End If; End If; -- tratamento da saida If ce_n = '0' And oe_n = '0' And wr_n = '1' Then Dt <= dados(Conv_Integer(Ed)) After 10 ns; -- leitura de dados Else Dt <= (Others => 'Z') After 10 ns; -- saida em alta impedancia End If; End Process; End teste; --------------------------------------------------------------------------------------------------------- -- Teste do conjunto: interligacao de cpu_8bits com ram_8x8 -- Geracao de estimulos contida no codigo -- Simule conjunto_5 --------------------------------------------------------------------------------------------------------- Library IEEE; Use IEEE.Std_Logic_1164.All; Use IEEE.Std_Logic_arith.All; Use IEEE.Std_Logic_unsigned.all; Entity conjunto_5 Is End conjunto_5; Architecture teste Of conjunto_5 IS ---->> Declaracao de componentes: veja capitulo 7 <<---- Component cpu_8bits Port (ck, rst_b : In Std_Logic; mrq_n, wr_n, rd_n : Buffer Std_Logic; Ed : Out Std_Logic_Vector(7 downto 0); Dt : InOut Std_Logic_Vector(7 Downto 0)); End Component; Component ram_8x8 Port (ce_n, oe_n, wr_n: In Std_Logic; Ed : In Std_Logic_Vector(7 Downto 0); Dt : InOut Std_Logic_Vector(7 Downto 0)); End Component; Signal ck, rst_b : Std_Logic := '0'; Signal mrq_n, wr_n, rd_n : Std_Logic; Signal ce_n, oe_n : Std_Logic; Signal Ed : Std_Logic_Vector(7 downto 0); Signal Dt : Std_Logic_Vector(7 Downto 0); Begin ce_n <= mrq_n; oe_n <= rd_n; ---->> Solicitacao de componentes: veja capitulo 7 <<---- x0: cpu_8bits Port Map(ck, rst_b, mrq_n, wr_n, rd_n, Ed, Dt); x1: ram_8x8 Port Map(ce_n, oe_n, wr_n, Ed, Dt); ck <= Not ck After 50 ns; rst_b <= '1' After 150 ns; End teste; |