CPU-2 Microprocessador
didático
descrito em VHDL e Assembler descrito em VHDL Tópicos ·
Objetivos ·
Arquitetura e Modos de
Endereçamento ·
Conjunto de
instruções ·
Diagrama de blocos ·
Teste da
descrição |
Objetivos ·
Expansão do
código do
microprocessador CPU-1 ·
Teste da arquitetura de
um
microprocessador com auxílio um assembler ·
Assembler integrado
a um ambiente de simulação VHDL ·
Código VHDL
realiza as operações de
um assembler limitado: - leitura programa fonte
do
microprocessador escrito em linguagem assembly - detecção
de erros (alguns
erros podem ser não detectados) - geração
dos códigos hexadecimais
necessários para operação da cpu |
Arquitetura e Modos de Endereçamento (idêntico ao exemplo CPU-1) |
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: Aritméticas,
Deslocamento, Chamada sub-rotina
* Novas
instruções |
||||||||||||||||||||||||||||||||||||||||
Diagrama
de blocos (CPU-1:
alterações na ALU)
|
Teste da
descrição ·
O
processo principal: - executa a leitura de um arquivo em disco - interpreta os
mnemônicos e grava
os dados na memória dual - após a
programação, libera a
operação da CPU ('rst_b'=1) ·
Facilidades:
- alteração do programa da CPU não exige compilar
código, (basta alterar o arquivo
de dados e
reiniciar a simulação) - programa da CPU escrito
diretamente no formato de mnemônicos
|
Teste da
descrição (Exemplo de um arquivo de
entrada de dados) ·
Comentário:
inicio com '--' ou após a coluna 25 ·
Primeira
coluna:
endereço de um dado
Segunda coluna:
instrução ·
Instruções
com duas posições de memória: ('LDmS,mm', 'Jump,mm') reserve uma
posição de memória para
que o dado 'mm' seja armazenado ·
Dados
num endereço: identificados na forma: endereço H#valor (somente base hexadecimal) -------------------------------------------------------------------------------- -- Subrotina para a troca caso dado(j+1)< dado(j) -------------------------------------------------------------------------------- 30 LDmP,A 31 LDiA,7 -- Acc <= [[A7]] (endereco A7 aponta para dado(j)) 32 STdA,2 -- [A2] <= Acc 33 LDiA,8 -- Acc <= [[A8]] (endereco A8 aponta para dado(j+1)) 34 SBdA,2 -- Acc <= Acc-[A2] (Acc <= dado(j+1)- dado(j) 35 JP_O,40 -- (Se ocorreu transbordo dado(j+1)< dado(j)) 36 37 JPNG,40 -- (Se negativo: dado(j+1)< dado(j)) 38 39 Retn -- (Nao negativo: dado(j+1) > dado(j) posicao mantida) -- Dados para a subrotina de ordenacao A0 H#90 -- endereco inicial A1 H#A0 -- endereco final +1 |
Teste da
descrição (como simular) ·
Compile
o conjunto: - Declaração do pacote Pack_cpu_txt Corpo do pacote Pack_cpu_txt - Declaração do pacote Pack_cpu_ram Corpo do pacote Pack_cpu_ram - Declaração da entidade cpu_8bits_2 Arquitetura teste de cpu_8bits_2 - Declaração da entidade ram_dual1 Arquitetura teste de ram_dual1 - Declaração da entidade conj_arq2 Arquitetura teste de conj_arq2 ·
Pack_cpu_aux:
pacote com funções e definições de tipo da
cpu ·
Pack_cpu_txt:
Pacote com funções para interpretação dos
dados contidos em arquivo ·
Pack_cpu_ram:
Pacote de auxilio ao uso da Ram Dual
- crie um arquivo contendo o programa com mnemônicos (fonte_exe1.dat) - simule a entidade conj_arq2 ·
Para
alterar o programa: - reinicie a simulação da entidade conj_arq2 |
Código conjunto ---------------------------------------------------------------------------------------------------------- -- 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 -- -- -- Exemplo extra -- -- Teste do conjunto CPU + Memoria -- -- Dados da memoria carregados de um arquivo. -- Nome do arquivo definido pelo generico: 'nome_do_arquivo' na entidade 'conj_arq2' -- -- -- Compile o conjunto: Declaracao do pacote Pack_cpu_aux, Corpo do pacote Pack_cpu_aux, -- Nao presente neste quadro. Pacote com funcoes e definicoes de tipo da cpu -- Declaracao do pacote Pack_cpu_txt Corpo do pacote Pack_cpu_txt -- Nao presente neste quadro. Pacote com funcoes para interpretacao dos dados contidos em arquivo -- Declaracao do pacote Pack_cpu_ram Corpo do pacote Pack_cpu_ram -- Nao presente neste quadro.Pacote de auxilio ao uso da Ram Dual -- Declaracao da entidade cpu_8bits_2 Arquitetura teste de cpu_8bits_2 -- Declaracao da entidade ram_dual1 Arquitetura teste de ram_dual1 -- Nao presente neste quadro. -- Declaracao da entidade conj_arq2 e Arquitetura teste de conj_arq2 -- -- Para verificar a operacao simule a entidade conj_arq2 ---------------------------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------------------------- -- Para alterar o conjunto de instrucoes -- No pacote Pack_cpu_aux -- 1- No 'Tipo_estado', defina o mnemonico da nova instrucao -- 2- Na funcao 'mnemonico', defina o tamanho da instrucao: 4 ou 8 bits -- 3- Na funcao 'mnemonico', defina o codigo numerico correspondente da instrucao -- No pacote pack_cpu_txt -- 1- Na funcao 'Mnem_Para_Std_Logic_Vector', defina a correspondencia entre o mnemonico e o codigo numerico ---------------------------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------------------------- -- 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.Pack_cpu_aux.All; -- Pacote com definicao de tipos e funcoes ---->> Declaracao de Entidade: veja capitulo 2 <<---- Entity cpu_8bits_2 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_2; ---->> Corpo da Arquitetura: veja capitulo 2 <<---- Architecture teste Of cpu_8bits_2 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_b : Std_Logic_Vector(nd-1 Downto 0); -- Registrador operando 'b' da ALU Signal alu_s : Std_Logic_Vector(nd-1 Downto 0); -- Saida da ALU Signal Alu_flags : Std_Logic_Vector(3 Downto 0); -- Registrador que armazena 'alu_o','alu_c', 'alu_n' e 'alu_z' Signal alu_o,alu_c,alu_n,alu_z : Std_Logic; -- Valor decodificado da saida da ALU: Carry, Negativo, Zero 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) ---->> Variaveis: veja capitulo 5 <<---- 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 ---->> Comando 'Case': veja capitulo 4 <<---- 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)] ---->> Concatenacao de sinais '&': veja capitulo 2 <<---- 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 Overflow, Salto se Carry, Salto se Zero, Salto se Nao Zero, Salto se Negativo ---->> Comando 'case' com delimitador '|': capitulo 4 <<---- When Jump | JP_O | JP_C |JP_Z | JPNZ | JPNG => -- Teste para determinar a necessidade de desvio para um novo endereco de memoria ---->> Diferencas entre atribuicao de valores para variaveis e atribuicao de valores para sinais: veja capitulo 5 If Estado = Jump Then salta := True; -- Instrucao Jump. Sempre Pc <= [Pc+1]. ElsIf Estado = JP_O And alu_flags(3) ='1' Then salta := True; -- Instrucao JP_O. Se O =1, Pc <= [Pc+1]. Se C=0 Pc <= Pc+2; ElsIf Estado = JP_C And alu_flags(2) ='1' Then salta := True; -- Instrucao JP_C. Se C =1, Pc <= [Pc+1]. Se C=0 Pc <= Pc+2; 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 -- Alteram bits de sinalizacao (flags): (alu_flags <= overflow,carry,zero, negativo) -- Add Direct 'ADdA': Acc <= Acc + [Pg & Ir(3..0)] -- Subtract Direct 'SBdA': Acc <= Acc - [Pg & Ir(3..0)] -- Shift Left 'SLdA': Acc <= Alu_b(6..0) & '0' carry <= Acc(7) -- Shift Right 'SRdA': Acc <= '0' & Alu_b(7..1) carry <= Acc(0) When ADdA | SBdA | SLdA | SRdA => -- 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_o & alu_c & 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'); -- Unidade Logica Aritmetica -- ---->> Ocorrencia de Carry e Overflow: veja capitulo 11 <<---- -- -- Ocorrencia de Vai-Um ou Carry -- Sinal interno 'alu_s_c' com 1 bit a mais e' definido no bloco -- ALU gerada deste modo possui nd+1 bits. Bit mais significativo de 'alu_s_c' permite detectar a ocorrencia do vai-um -- -- Ocorrencia de Transbordo ou Overflow -- Operacao de soma Operacao de subtracao -- possivel problema no caso de operandos com sinais iguais possivel problema no caso de operandos com sinais diferentes -- Acc (0______) pos. (1______) neg. Acc (0______) pos. (1______) neg. -- Alu_b +(0______) pos. +(1______) neg. Alu_b -(1______) neg. -(0______) pos. -- ------------ ------------ ------------ ------------ -- alu_s (1______) neg. (0______) pos. alu_s (1______) neg. (0______) pos. -- resultado incorreto resultado incorreto resultado incorreto resultado incorreto -- ---->> Exemplos de deslocadores 'shift-register': veja capitulo 6 <<---- -- -- Deslocamentos: para esquerda para direita -- Alu_b: |7|6|5|4|3|2|1|0|__'0' Alu_b: '0'___ |7|6|5|4|3|2|1|0| -- / / / / / / / / / \ \ \ \ \ \ \ \ \____ -- alu_s_c |8|7|6|5|4|3|2|1|0| alu_s_ |8|7|6|5|4|3|2|1|0| | -- \_____________________| -- ---->> Comando 'Block': veja capitulo 3 <<---- Unidade_Logica: Block ---->> Atributo 'Range': veja capitulo 5 <<---- Constant zero : Std_Logic_Vector(alu_s'Range) := (Others => '0'); -- constante com valor zero Signal decide_o : Std_Logic_Vector(3 Downto 0); -- sinal para a decisao se ocorreu transbordo Signal alu_s_c : Std_Logic_Vector(alu_s'High+1 Downto 0); -- sinal com um bit extra para deteccao de vai-um Begin alu_s_c <= ('0'& Acc) + ('0'& Alu_b) When (Estado = ADdA) Else -- alu executa operacao de soma ('0'& Acc) - ('0'& Alu_b) When (Estado = SBdA) Else -- alu executa operacao de subtracao Alu_b & '0' When (Estado = SLdA) Else -- alu executa deslocamento para esquerda Alu_b(0) & '0'& Alu_b(Alu_b'High Downto 1); -- alu executa deslocamento para direita ---->> Atributo 'High': veja capitulo 5 <<---- alu_s <= alu_s_c(alu_s'High Downto 0); -- bit do carry descartado alu_c <= alu_s_c(alu_s_c'High); -- resultado do carry ---->> Atribuicao condicional de sinal 'When': veja capitulo 3 <<---- 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 decide_o <= ('0' & alu_s(alu_s'High) & Acc(Acc'High) & Alu_b(Alu_b'High)) When Estado = ADdA Else -- sinal para a decisao caso operacao de soma ('1' & alu_s(alu_s'High) & Acc(Acc'High) & Alu_b(Alu_b'High)); -- sinal para a decisao caso operacao de subtracao ---->> Atribuicao condicional de sinal 'With': veja capitulo 3 <<---- ---->> Atribuicao condicional de sinal 'With' com delimitador '|': capitulo 3 <<---- ---->> Atribuicao condicional de sinal 'With' com a palavra reservada 'Others': capitulo 3 <<---- With decide_o Select alu_o <= '1' When "0100" | "0011" | "1101" | "1010", '0' When Others; -- \\\\_____________sinal Alu_b -- \\\_____________sinal Acc -- \\_____________sinal alu_s End Block; -- \_____________soma =0 / subtracao =1 -- 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; --------------------------------------------------------------------------------------------------------- -- Teste do conjunto: interligacao de cpu_8bits_2 com ram_dual1 -- Geracao de estimulos contida no codigo -- Simule conj_arq2 ----------------------------------------------------------------------------------------------------------------------------------- ---->> Emprego do pacote 'textio': veja capitulo 13 <<---- ---->> Definicao e uso de pacotes: veja capitulo 9 <<---- Use STD.TEXTIO.All; Use Work.Pack_cpu_txt.All; -- Pacote com funcoes para interpretacao dos dados contidos em arquivo Use Work.Pack_cpu_ram.All; -- Pacote de auxilio ao uso da Ram Dual Library IEEE; Use IEEE.Std_Logic_1164.All; Use IEEE.Std_Logic_unsigned.All; -- Biblioteca Synopsys necessaria para operacoes aritimericas entre Std_Logic_Vector e Integer Entity conj_arq2 IS Generic (nome_do_arquivo : String := "fonte_ex1.dat"; -- Nome do arquivo contendo os dados ne : Integer := 8; -- Numero de bits do barramento de endereco nd : Integer := 8; -- Numero de bits do barramento de dados td : Time := 10 ns); -- Tempo para apresentacao dos dados End conj_arq2; Architecture teste Of conj_arq2 Is ---->> Declaracao de componentes e mapa de portas: veja capitulo 7 <<---- Component cpu_8bits_2 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; ---->> Operacoes com arquivos: veja capitulo 13 <<---- File arq_rd : TEXT; -- Sinais do microprocessador Signal ck, rst_b : Std_Logic := '0'; Signal mrq_n, wr_n, rd_n : Std_Logic; -- Sinais de controle da Ram Dual Signal ce1_n, wr1_n, oe1_n : Std_Logic := '1'; -- sinais controle 1 Signal ce2_n, wr2_n, oe2_n : Std_Logic := '1'; -- sinais controle 2 Signal ed1, ed2 : Std_Logic_Vector(ne-1 Downto 0); -- enderecos 1 e 2 Signal dt1, dt2 : Std_Logic_Vector(nd-1 Downto 0); -- dados 1 e 2 Signal Fim_carga_de_dados : Boolean := False; -- Indica o fim da programacao da memoria Ram com os dados Begin Principal: Process Variable linha : Line; -- Objeto tipo LINE para armazenar texto Variable leitura_ok : Boolean := TRUE; -- verificacao do procedimento READ Variable caractere : Character; -- Armazena o caractere lido na linha Variable i : Integer; -- Conta o numero de caracteres Variable linha_lida : String(1 To 25); -- Armazena todos os caracters lidos numa linha Variable ed : Std_Logic_Vector(ne-1 Downto 0); Variable dt : Std_Logic_Vector(nd-1 Downto 0); Variable dados : Integer; -- Codigo que representa o numero de dados encontrados na leitura de uma linha Variable ender : Std_Logic_Vector(7 Downto 0); Variable ext1, ext2 : Std_Logic_Vector(3 Downto 0); Variable mnem : String (1 To 4); Variable prox_ed : Std_Logic_Vector(ne-1 Downto 0); Variable prox_dt : Std_Logic_Vector(nd-1 Downto 0); Begin ---->> Abertura de arquivos: veja capitulo 13 <<---- File_Open(arq_rd, nome_do_arquivo,Read_Mode); ---->> Comando 'Loop' e esquema de iteracao 'While': veja capitulo 7 <<---- While Not EndFile(arq_rd) Loop -- Operacao de leitura do arquivo ReadLine (arq_rd, linha); -- Leitura de uma linha do aquivo leitura_ok := True; -- Habilita leitura de caracteres contidos numa linha (proximo laco While) i := 1; -- Inicia contador de caracteres contidos numa linha (proximo laco While) linha_lida := (Others => ' '); -- Limpa a variavel 'linha_lida'para a leitura de uma proxima linha While (i < linha_lida'Length) Loop -- Teste: numero maximo de caracteres previsto excedido ---->> Funcao 'Read' em arquivos texto: veja capitulo 13 <<---- Read(linha,caractere,leitura_ok); -- Leitura de um caractere na linha ---->> Comandos 'Exit' e 'Next': veja capitulo 7 <<---- Exit When Not leitura_ok; -- Termina a leitura da linha: fim da linha contendo caracteres Next When (caractere < ' ') Or (caractere > '~'); -- Caractere não é texto: descartado linha_lida(i) := caractere; -- Preenche com mais um caractere i := i +1; -- Incrementa o contador de caracteres End Loop; ---->> Subprogramas: procedimento (procedure): veja capitulo 8 <<---- Extrai_dados(linha_lida, dados, ender, mnem, ext1, ext2); -- Extracao dos dados recuperados numa linha lida no arquivo Case dados IS When 2 => Null; -- Linha contendo somente endereco. Exemplo: [02] When 6 => -- Linha contendo:[(endereco)(instrucao tipo Retn)] ou [(endereco) (dado tipo H#23)] If mnem(2) = '#' Then ---->> Subprogramas: funcao (function): veja capitulo 8 <<---- ed := ender; dt := Para_Std_Logic_Vector(mnem(3 To 4)); -- Linha cont. endereco e dado. Exemplo: [A0 H#77]. Caractere '#' identifica. Else ed := ender; dt := Mnem_Para_Std_Logic_Vector(mnem); -- Linha cont. endereco e instrucao. Exemplos: [75 Retn], [42 Halt] End If; When 7 => ed := ender; dt := Mnem_Para_Std_Logic_Vector(mnem) & ext1; -- Linha cont. endereco, instrucao e dado associado a instrucao. Exemplo: [06 LDiA,E] When 8 => ed := ender; dt := Mnem_Para_Std_Logic_Vector(mnem); -- Linha cont. endereco, instrucao e dado do prox. endereco. Exemplo: [40 Call,70] prox_ed := ender +1; prox_dt := ext1 & ext2; -- Dado para o endereco seguinte preparado. Exemplo: [41 70] When Others => Null; End Case; If (dados = 6) Or (dados = 7) Or (dados = 8) Then -- Linha contendo dados para serem escritos na memoria If dados =8 Then -- Linha contendo endereco, instrucao e do proximo endereco. Exemplo: [40 Call,70] Escreve_porta_2 (ed, dt, ce2_n, wr2_n, ed2, dt2); -- Dado 'dt' armazenado no endereco 'ed' ---->> Comando 'Wait': veja capitulo 4 <<---- Wait For 1 ns; -- Endereco e dado atualizados. Exemplo para a instrucao Call,70 no endereco 40: [ed=40 dt=F8] ed := prox_ed; dt := prox_dt; -- Preparara para o proximo endereco. Exemplo para a instrucao Call,70 no endereco 40: [ed=41 dt=70] End If; Escreve_porta_2 (ed, dt, ce2_n, wr2_n, ed2, dt2); -- Dado 'dt' armazenado no endereco 'ed' Wait For 1 ns; End If; End Loop; ---->> Funcao 'File_Close' em arquivos: veja capitulo 13 <<---- File_Close(arq_rd); -- Fecha o arquivo Fim_carga_de_dados <= True; -- Indica que a memoria Ram contem todos os dados ---->> Comando 'Report': veja capitulo 14 <<---- Report "Operacao de carga dos dados na memoria terminada" Severity Note; Wait; End Process; ---->> Clausula 'After': veja capitulo 5 <<---- ---->> Geracao de sinais periodicos: veja capiutlo 15 <<---- rst_b <= '1' After 150 ns When Fim_carga_de_dados Else '0'; ck <= Not ck After 50 ns; ce1_n <= mrq_n; oe1_n <= rd_n; wr1_n <= wr_n; ---->> Solicitacao de componentes, mapa de portas e mapa de genericos: veja capitulo 7 <<---- X0: cpu_8bits_2 Port Map(ck, rst_b, mrq_n, wr_n, rd_n, ed1, dt1); X2: ram_dual1 Generic Map (ne, nd, td) Port Map(ce1_n, wr1_n, oe1_n, ed1, dt1, ce2_n, wr2_n, oe2_n, ed2, dt2); End teste; |
Código do pacote Pack_cpu_aux ------------------------------------------------------------------------------------------------------------ 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 -- -- Exemplo extra -- Pacote auxiliar -- Definicao de tipo contendo mnemonicos e funcao de valor numerico para mnemonico ---------------------------------------------------------------------------------------------------------- ---->> 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 conversoes com Std_Logic ---->> Declaracao de pacote: veja capitulo 9 <<---- Package Pack_cpu_aux Is -- declaracao do pacote ---->> Declaracao de tipo: veja capitulo 12 <<---- -- Tipo contendo os possiveis estados da maquina Type Tipo_estado Is (busca, LDmP, LDmS, LDmA, LDdA, LDiA, STdA, STiA, Jump, JP_O, JP_C, JP_Z, JPNZ, JPNG, ADdA, SBdA, SLdA, SRdA, Call, RETN, Halt); ----> Declaracao de funcao: veja capitulo 8 <<---- ----> Lista de interface de um subprograma (parametros formal e real): veja capitulo 8 <<---- Function para_estado(dado : Std_Logic_Vector(7 Downto 0)) Return Tipo_Estado; End Pack_cpu_aux; ---->> Declaracao do corpo pacote: veja capitulo 9 <<---- Package Body Pack_cpu_aux Is -- corpo do pacote ---->> Declaracao do corpo da funcao: veja capitulo 8 <<---- -- 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 x"c" => mnemonico := SLdA; When x"d" => mnemonico := SRdA; 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"f4" => mnemonico := JP_C; When x"f5" => mnemonico := JP_O; 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 Pack_cpu_aux; |
Código do pacote Pack_cpu_txt -------------------------------------------------------------------------------------------------------------------------------------- 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 -- -- Pacote com operacoes para auxilio a leitura de arquivos - Necessita opcao VHDL-1993 -- ------------------------------------------------------------------------------------------------------------------------------------ ---->> 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 conversoes com Std_Logic ---->> Declaracao de pacote: veja capitulo 9 <<---- Package pack_cpu_txt Is -- declaracao do pacote ----> Lista de interface de um subprograma (parametros formal e real): veja capitulo 8 <<---- ----> Declaracao de funcao: veja capitulo 8 <<---- Function Para_minusculo(c: character) Return Character; Function Para_minusculo(s: string) Return String; Function Para_Std_Logic_Vector(c: Character) Return Std_Logic_Vector; Function Para_Std_Logic_Vector(s: String) Return Std_Logic_Vector; Function Mnem_Para_Std_Logic_Vector(dado : String(1 To 4)) Return Std_Logic_Vector; ----> Declaracao de procedimento: veja capitulo 8 <<---- Procedure Extrai_dados(s: In String; dados : Out Integer; endereco: Out Std_Logic_Vector(7 Downto 0); mnemonico: Out String(1 To 4); extra_1: Out Std_Logic_Vector(3 Downto 0); extra_2: Out Std_Logic_Vector(3 Downto 0)); End pack_cpu_txt; ---->> Declaracao do corpo pacote: veja capitulo 9 <<---- Package Body pack_cpu_txt Is -- corpo do pacote ----------------------------------------------------------------------------------------------------------------------------------- -- Converte caractere maiuculo para minusculo -- Caracteres como '[', '1' e '#' nao sao alterados. Para caracteres fora da faixa prevista retorna o valor ' '. ----------------------------------------------------------------------------------------------------------------------------------- Function Para_minusculo(c: Character) Return Character Is SubType caractere Is Character Range ' ' To '~'; -- Subtipo contendo os possiveis caracteres Type minusculo Is Array(caractere) Of Character; -- O indice do vetor do tipo minusculo e' definido por elementos do Subtipo 'caractere' Constant equivalencia : minusculo := -- Constante: vetor de elementos de 'A' ate' '~' (' '=>' ', '!'=>'!', '"'=>'"', '#'=>'#', '$'=>'$', '%'=>'%', '&'=>'&', '''=>''', '('=>'(', ')'=>')', '*'=>'*', '+'=>'+', ','=>',', '-'=>'-', '.'=>'.', '/'=>'/', '0'=>'0', '1'=>'1', '2'=>'2', '3'=>'3', '4'=>'4', '5'=>'5', '6'=>'6', '7'=>'7', '8'=>'8', '9'=>'9', ':'=>':', ';'=>';', '<'=>'<', '='=>'=', '>'=>'>', '?'=>'?', '@'=>'@', 'A'=>'a', 'B'=>'b', 'C'=>'c', 'D'=>'d', 'E'=>'e', 'F'=>'f', 'G'=>'g', 'H'=>'h', 'I'=>'i', 'J'=>'j', 'K'=>'k', 'L'=>'l', 'M'=>'m', 'N'=>'n', 'O'=>'o', 'P'=>'p', 'Q'=>'q', 'R'=>'r', 'S'=>'s', 'T'=>'t', 'U'=>'u', 'V'=>'v', 'W'=>'w', 'X'=>'x', 'Y'=>'y', 'Z'=>'z', '['=>'[', '\'=>'\', ']'=>']', '^'=>'^', '_'=>'_', '`'=>'`', 'a'=>'a', 'b'=>'b', 'c'=>'c', 'd'=>'d', 'e'=>'e', 'f'=>'f', 'g'=>'g', 'h'=>'h', 'i'=>'i', 'j'=>'j', 'k'=>'k', 'l'=>'l', 'm'=>'m', 'n'=>'n', 'o'=>'o', 'p'=>'p', 'q'=>'q', 'r'=>'r', 's'=>'s', 't'=>'t', 'u'=>'u', 'v'=>'v', 'w'=>'w', 'x'=>'x', 'y'=>'y', 'z'=>'z', '{'=>'{', '|'=>'|', '}'=>'}', '~'=>'~'); Begin If (c >= ' ') And (c <= '~') Then Return equivalencia(c); -- Faixa de caracteres validos Else Return ' '; -- Caso contrario retorna o valor ' ' End If; End Para_minusculo; ----------------------------------------------------------------------------------------------------------------------------------- -- Converte caracteres de um vetor para minusculo -- Sobrecarrega e emprega a funcao para_minusculo(c : Character) ----------------------------------------------------------------------------------------------------------------------------------- Function Para_minusculo(s: String) Return String Is Variable s_min : String(s'Range); Begin For i In s'Range Loop s_min(i) := Para_minusculo(s(i)); End Loop; Return s_min; End Para_minusculo; ----------------------------------------------------------------------------------------------------------------------------------- -- Converte valor representado por um caractere em um tipo Std_Logic_Vector -- Emprega a funcao Para_minuculo ----------------------------------------------------------------------------------------------------------------------------------- Function Para_Std_Logic_Vector(c: Character) Return Std_Logic_Vector Is Variable sl: Std_Logic_Vector(3 Downto 0); Variable c_minusculo : Character; Begin c_minusculo := Para_minusculo(c); Case c_minusculo Is When '0' => sl := x"0"; When '1' => sl := x"1"; When '2' => sl := x"2"; When '3' => sl := x"3"; When '4' => sl := x"4"; When '5' => sl := x"5"; When '6' => sl := x"6"; When '7' => sl := x"7"; When '8' => sl := x"8"; When '9' => sl := x"9"; When 'a' => sl := x"A"; When 'b' => sl := x"B"; When 'c' => sl := x"C"; When 'd' => sl := x"D"; When 'e' => sl := x"E"; When others => sl := x"F"; End case; Return sl; End Para_Std_Logic_Vector; ----------------------------------------------------------------------------------------------------------------------------------- -- Converte um conjunto de caracteres (que representam um valor Hexadecimal) em Std_Logic_Vector -- Sobrecarrega e emprega a funcao Para_Std_Logic_Vector(c: Character) -- Entrada: String ascendente (1 To n). Saida: Std_Logic_Vector decrescente -- Cada caracter acresce 4 bits no vetor de saida -- Exemplo de operacoes no laco para um string com 3 caracteres: -- h(11 Downto 8) := Para_Std_Logic_Vector(s(1)); -- h( 7 Downto 4) := Para_Std_Logic_Vector(s(2)); -- h( 3 Downto 0) := Para_Std_Logic_Vector(s(3)); ----------------------------------------------------------------------------------------------------------------------------------- Function Para_Std_Logic_Vector(s: String) Return Std_Logic_Vector Is Constant h_lgt : Integer := s'Length*4; -- cada caracter resulta em 4 bits no vetor Variable h : Std_Logic_Vector(h_lgt-1 Downto 0); Begin For i In 0 To s'Length-1 Loop h(h_lgt-(4*i+1) Downto h_lgt-(4*(i+1))) := Para_Std_Logic_Vector(s(s'Left+i)); End Loop; Return h; End Para_Std_Logic_Vector; ----------------------------------------------------------------------------------------------------------------------------------- -- Converte o codigo da instrucao em valor numerico no tipo Std_Logic_Vector -- Valor convertido pode ser um vetor de 4 ou 8 bits ----------------------------------------------------------------------------------------------------------------------------------- Function Mnem_Para_Std_Logic_Vector(dado : String(1 To 4)) Return Std_Logic_Vector Is Variable dado_minusculo : String(dado'Range); Begin dado_minusculo := para_minusculo(dado); Case dado_minusculo Is -- Mnemonicos que resultam num codigo de 4 bits When "ldmp" => Return x"0"; When "ldda" => Return x"1"; When "ldia" => Return x"2"; When "stda" => Return x"3"; When "stia" => Return x"4"; When "adda" => Return x"a"; When "sbda" => Return x"b"; When "slda" => Return x"c"; When "srda" => Return x"d"; -- Mnemonicos que resultam num codigo de 8 bits When "jump" => Return x"f0"; When "jp_z" => Return x"f1"; When "jpnz" => Return x"f2"; When "jpng" => Return x"f3"; When "jp_c" => Return x"f4"; When "jp_o" => Return x"f5"; When "ldms" => Return x"f6"; When "ldma" => Return x"f7"; When "call" => Return x"f8"; When "retn" => Return x"f9"; When "halt" => Return x"ff"; When Others => Report CR & LF & "ERRO NA LEITURA DO ARQUIVO! Mnemonico '" & dado & "' nao encontrado" & LF Severity Failure; Return x"ff"; End Case; End Mnem_Para_Std_Logic_Vector; ----------------------------------------------------------------------------------------------------------------------------------- -- Extrai dados de um conjunto de caracteres -- Entrada: String (1 To ...) Saida: dados endereco mnemonico extra_1 extra_2 -- Emprega as funcoes: Para_Std_Logic_Vector e Para_minuculo -- Exemplos de retorno: -- 03 dados=(2) endereco=(03) mnemonico=(nao altera) extra_1,2=(nao altera) -- 04 Retn dados=(6) endereco=(04) mnemonico=(retn) extra_1,2=(nao altera) -- 05 LDmP,7 dados=(7) endereco=(05) mnemonico=(ldmp) extra_1=(7) extra_2=(nao altera) -- 06 JPNZ,78 dados=(8) endereco=(06) mnemonico=(jpnz) extra_1=(7) extra_2=(8) -- 27 Hexa A7 dados=(8) endereco=(27) mnemonico=(hexa) extra_1=(A) extra_2=(7) ----------------------------------------------------------------------------------------------------------------------------------- Procedure Extrai_dados(s: In String; dados : Out Integer; endereco: Out Std_Logic_Vector(7 Downto 0); mnemonico: Out String(1 To 4); extra_1: Out Std_Logic_Vector(3 Downto 0); extra_2: Out Std_Logic_Vector(3 Downto 0)) Is Variable dado : Integer Range 1 To 9 :=1; Begin For i In 1 To s'Length Loop Exit When (s(i) = '-') And (s(i+1) = '-'); -- Detectado o indentificador de comentario: o restante e' descartado Next When (s(i) = ' ') Or (s(i) = ','); -- Espacos em branco e virgulas eliminados do conjunto de dados Case dado Is When 1 => dado := dado +1; endereco(7 Downto 4) := Para_Std_logic_Vector(s(i)); -- primeiro dado do endereco When 2 => dado := dado +1; endereco(3 Downto 0) := Para_Std_logic_Vector(s(i)); -- segundo dado do endereco When 3 => dado := dado +1; mnemonico(1) := Para_minusculo(s(i)); -- primeiro dado do mnemonico When 4 => dado := dado +1; mnemonico(2) := Para_minusculo(s(i)); -- segundo dado do mnemonico When 5 => dado := dado +1; mnemonico(3) := Para_minusculo(s(i)); -- terceiro dado do mnemonico When 6 => dado := dado +1; mnemonico(4) := Para_minusculo(s(i)); -- quarto dado do mnemonico When 7 => dado := dado +1; extra_1 := Para_Std_logic_Vector(s(i)); -- primeiro dado extra When 8 => dado := dado +1; extra_2 := Para_Std_logic_Vector(s(i)); -- segundo dado extra When 9 => Null; End Case; End Loop; dados := dado -1; End Extrai_dados; End pack_cpu_txt; |
Código do pacote Pack_cpu_ram ------------------------------------------------------------------------------------------------------------------------------------- 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 -- -- Pacote de auxilio da memoria ram dual -- Declaracao do componente 'ram_dual1' e procedimento de auxilio a escrita na porta 2 da Ram ----------------------------------------------------------------------------------------------------------------------------------- ---->> 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 conversoes com Std_Logic ---->> Declaracao de pacote: veja capitulo 9 <<---- Package pack_cpu_ram Is -- Declaracao do pacote ----------------------------------------------------------------------------------------------------------------------------------- -- Declaracao do componente 'Ram Dual Port'' para o armazenamento de dados ---------------------------------------------------------------------------------------------------------------------------------- ---->> Declaracao componentes em pacote: veja capitulo 9 <<---- Component ram_dual1 Generic(ne : Integer := 8; -- Numero de bits do barramento de endereco nd : Integer := 8; -- Numero de bits do barramento de dados td : Time := 10 ns); -- Tempo para apresentacao dos dados Port (ce1_n, wr1_n, oe1_n : In Std_Logic; -- sinais controle 1 Ei1 : In Std_Logic_Vector(ne-1 Downto 0); -- endereco 1 Dt1 : InOut Std_Logic_Vector(nd-1 Downto 0); -- dados: entrada e saida 1 ce2_n, wr2_n, oe2_n : In Std_Logic; -- sinais controle 2 Ei2 : In Std_Logic_Vector(ne-1 Downto 0); -- endereco 2 Dt2 : InOut Std_Logic_Vector(nd-1 Downto 0)); -- dados: entrada e saida 2 End Component; ----> Lista de interface de um subprograma (parametros formal e real): veja capitulo 8 <<---- ----> Declaracao de procedimento: veja capitulo 8 <<---- Procedure Escreve_porta_2 (ed_in : In Std_Logic_Vector; dt_in : In Std_Logic_Vector; Signal ce2_n : Out Std_Logic; Signal wr2_n : Out Std_Logic; Signal ed2 : Out Std_Logic_Vector; Signal dt2 : InOut Std_Logic_Vector); End pack_cpu_ram; Package Body pack_cpu_ram Is -- corpo do pacote ----------------------------------------------------------------------------------------------------------------------------------- -- Procedimento para executar uma operacao de escrita na memoria 'Dual Port' -- Dados presentes em 'ed_in' e 'dt_in' sao transferidos para 'ed2' e 'dt2' -- Pulsos de 1ns e 2ns sao gerados para a escrita dos dados ----------------------------------------------------------------------------------------------------------------------------------- Procedure Escreve_porta_2 ( ed_in : In Std_Logic_Vector; dt_in : In Std_Logic_Vector; Signal ce2_n : Out Std_Logic; Signal wr2_n : Out Std_Logic; Signal ed2 : Out Std_Logic_Vector; Signal dt2 : InOut Std_Logic_Vector) Is Variable dado : Integer Range 1 To 9 :=1; Begin ed2 <= ed_in; dt2 <= dt_in; -- Endereco e dado ce2_n <= '0'; wr2_n <= '0'; -- Prepara linhas de controle Wait For 1 ns; -- Ocorre uma iteracao dos sinais concorrentes wr2_n <= '1'; -- Operacao de escrita de escrita executada Wait For 1 ns; -- Ocorre uma iteracao dos sinais concorrentes ce2_n <= '1'; -- Fim da operacao de escrita Wait For 1 ns; -- Ocorre uma iteracao dos sinais concorrentes End Escreve_porta_2; End pack_cpu_ram; |
Código da entidade ram_dual1 --------------------------------------------------------------------------------------------------------------------------------------- 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 -- -- -- Exemplo extra -- -- Memoria Ram Dual - Sintese ok -- Composta de um componente: uma memoria Ram normal e um circuito externo de controle e selecao -- Operacao de escrita simultanea nao e' controlada -- Ce1_n =0 define selecao da informacao para os barramentos Ei e Di da memoria -- Generico ne = numero de linhas de endereco. Generico nd = numero de linhas de dados ------------------------------------------------------------------------------------------------------------------------------------- ------------------------------------------------------------------------------------------------------------------------------------- -- Nucleo da memoria Ram - entrada e saida de dados independentes ---->> Sintese e descricao de memorias: veja capitulo 12 <<---- ------------------------------------------------------------------------------------------------------------------------------------- Library IEEE; Use IEEE.Std_Logic_1164.All; Use IEEE.Std_Logic_unsigned.All; -- Biblioteca Synopsys necessaria para a operacao de conversao do tipo Std_Logic Entity ram_comp Is Generic (ne, nd : Integer); -- Numero de bits do barramento de endereco e dados -- Tempo para apresentacao dos dados Port (ce_n, wr_n: In Std_Logic; -- Sinais controle: habilitacao e escrita Ei : In Std_Logic_Vector(ne-1 Downto 0); -- Barramento de endereco Di : In Std_Logic_Vector(nd-1 Downto 0); -- Barranto de dados: entrada Do : Out Std_Logic_Vector(nd-1 Downto 0)); -- Barranto de dados: saida End ram_comp; Architecture teste Of ram_comp Is Type arranjo_memoria Is Array (Natural Range <>) Of Std_Logic_Vector(nd-1 downto 0); Signal dados : arranjo_memoria(0 To 2**ne-1); -- Numero posicoes de memoria Signal ced_n : Std_Logic; -- Sinal de habilitacao atrasado Begin ---->> Atraso delta: veja capitulos 3 e 5 <<---- -- Nota: ced_n atrasado 1 delta com relacao a wr_n: permite a escrita com transicao simultanea de wr e ce de 0 para 1 -- Este atraso tem efeito para simulacao somente. Para efeito de sintese, ced_n e' igual a ce_n -- Exemplo: -- wr_n: -------_______----- -- ce_n: ----__________------- -- ced_n <= ce_n; Process(ced_n, wr_n, dados, Ei, Di) Begin -- operacao de escrita da memoria If rising_edge(wr_n) Then If ced_n = '0' Then dados(Conv_Integer(Ei)) <= Di; -- Devido ao atraso de 1 delta o valor de ced_n = 0 mesmo com ce_n =1 End If; End If; Do <= dados(Conv_Integer(Ei)); End Process; End teste; ------------------------------------------------------------------------------------------------------------------------------------- -- Memoria Ram Dual Port -- Entidade que solicita ram_comp. Entrada e saida de dados no mesmo barramento ------------------------------------------------------------------------------------------------------------------------------------- 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 Entity ram_dual1 Is Generic (ne : Integer := 8; -- Numero de bits do barramento de endereco nd : Integer := 8; -- Numero de bits do barramento de dados td : Time := 10 ns); -- Tempo para apresentacao dos dados Port (ce1_n, wr1_n, oe1_n : In Std_Logic; -- Sinais controle 1 Ei1 : In Std_Logic_Vector(ne-1 Downto 0); -- Endereco 1 Dt1 : InOut Std_Logic_Vector(nd-1 Downto 0); -- Dados: entrada e saida 1 ce2_n, wr2_n, oe2_n : In Std_Logic; -- Sinais controle 2 Ei2 : In Std_Logic_Vector(ne-1 Downto 0); -- Endereco 2 Dt2 : InOut Std_Logic_Vector(nd-1 Downto 0)); -- Dados: entrada e saida 2 End ram_dual1; Architecture teste Of ram_dual1 IS Component ram_comp Generic (ne, nd : Integer); -- Numero de bits do barramento de endereco e dados Port (ce_n, wr_n: In Std_Logic; -- Sinais controle: habilitacao e escrita Ei : In Std_Logic_Vector(ne-1 Downto 0); -- Barramento de endereco Di : In Std_Logic_Vector(nd-1 Downto 0); -- Barranto de dados: entrada Do : Out Std_Logic_Vector(nd-1 Downto 0)); -- Barranto de dados: saida End Component; Signal wrx, cex : Std_Logic; Signal Eix,Eixx : Std_Logic_Vector(Ei1'Range); Signal Dix,Dixx : Std_Logic_Vector(Dt1'Range); Signal Dox : Std_Logic_Vector(Dt1'Range); Begin -- Sinais aplicados a memoria wrx <= wr1_n And wr2_n; -- Controle de escrita do nucleo cex <= ce1_n And ce2_n; -- Controle de habilitacao do nucleo Eixx <= Ei1 When ce1_n = '0' Else Ei2; -- Seletor do barramento de enderecos do nucleo Dixx <= Dt1 When ce1_n = '0' Else Dt2; -- Seletor do barramento de dados do nucleo Eix <= Eixx; Dix <= Dixx; -- Controle da saida de dados da porta 1 Dt1 <= Dox After td When (ce1_n = '0' And oe1_n = '0' And wr1_n = '1') Else -- Saida 1: leitura de dados (Others => 'Z'); -- Saida 1: em alta impedancia -- Controle da saida de dados da porta 2 Dt2 <= Dox After td When (ce2_n = '0' And oe2_n = '0' And wr2_n = '1') Else -- Saida 2: leitura de dados (Others => 'Z'); -- Saida 2: em alta impedancia X1: ram_comp Generic Map (ne, nd) Port Map(cex, wrx, Eix, Dix, Dox); End teste; |
Exemplos de
simulação: Códigos
e Cartas de tempo
Lembre: para
simulação, altere o nome do arquivo ".dat" ou
".txt" para "fonte_ex1.dat" |