Organizamos a interação entre PC e DAC / ADC usando FPGA

No mundo digital moderno, a necessidade de DAC / ADC ( conversores digital-analógico / conversores analógico-digital ) não está em dúvida: eles são usados ​​para processar sinais de vários sensores, em equipamentos de som, sintonizadores de TV, placas de entrada de vídeo, câmeras de vídeo, etc.



No entanto, usar ou depurar um DAC / ADC pode ser difícil devido às limitações definidas pelo fabricante do hardware, por exemplo, no software usado ou em como o dispositivo pode ser controlado. Isso sugere projetar seu próprio modelo de interação.



Neste artigo, consideraremos a possibilidade de organizar a interação entre um PC e um DAC / ADC usando FPGAs.









Prefácio



O objetivo principal deste artigo é descrever a solução para um problema específico, bem como familiarizar-se com as interfaces de interação de circuitos integrados (CIs). O objetivo principal do DAC / ADC não é considerado aqui.



Este artigo requer algum conhecimento de programação e circuitos orientados a objetos, portanto, se você não estiver familiarizado com esses conceitos, é recomendável começar com eles.



Espero que a experiência de uma pessoa que se depara pela primeira vez com o problema de comunicação de dispositivos eletrônicos seja útil para alguém.



Boa sorte e novas conquistas a todos!



Um pequeno programa educacional sobre interfaces



aviso Legal



Se você está familiarizado com o design das principais interfaces usadas para comunicação IC, pode pular este ponto com segurança.



Programa educacional



, .



, (, .) . , .



, . , , , .. , . . – , . , . , .



, .





( ), :



  • «-»;
  • «»;
  • «» («»).


«-» — , . , — .







«» (, « » «») , . . , , , . .







( «») . , , , - . .









:



  • ;
  • ;
  • -.


, . . . , .







, . , , .







(-/)





:



  • ();
  • ();
  • ().


. .







, .

: , «» .







. .









:



  • ;
  • .


. . . ( – , – , , ). « » ( ). .







, , .







?



() SPI I2C UART.



I2C



I2C – . I2C . I2C «-», .



, , . , . 7- 16 . , 112 . I2C (SDA) (SCL).





I2C



SPI



SPI – , .



SPI «-». MOSI SCLK, . MISO, . SS.





SPI



UART



UART – – , .

RxD ( ) TxD ( ).



UART TxD . . UART , , UART , . , . 8 ( ), , .

UART «-». , UART . « » «».





UART





O que é esse DAC?





Parece que não é este.



Primeiro, vamos definir o DAC / ADC usado: A



placa de depuração Analog Devices AD9993-EBZ é um dispositivo que combina quatro ADCs de 14 bits e dois DACs de 14 bits.



Os modos de operação deste IC são controlados pela alteração do estado de seus registros internos. O AD9993 usa 66 registradores com um tamanho de palavra armazenado (processado) de 8 bits, os endereços dos quais são descritos por valores hexadecimais de três dígitos (12 bits de dados). Dois tipos de comandos são suportados - comando de leitura e comando de gravação. Em outras palavras, para corrigir o funcionamento do IC, é necessário enviar um comando para escrever algum valor válido de 8 bits para um endereço de registro específico. O acesso aos registros deste IC é feito através da interface periférica serial (SPI), cuja conexão na placa de depuração é realizada através do conector FIFO_0 de 40 pinos ou através de um grupo de contatos adicionalmente instalado.





Como este (FIFO_0 - conector cinza superior)



Requisitos básicos para parâmetros de limite SPI:



  • Frequência máxima de transmissão de dados - 25 MHz;
  • A duração dos níveis superior e inferior na linha de geração do sinal de sincronização é de 10 ns;
  • Tempo de ajuste de nível nas linhas de transmissão de dados e nas linhas de resolução - 2 ns;
  • Tempo de espera de nível nas linhas de transmissão de dados e na linha de resolução - 2 ns;
  • O tempo de validade garantido de um bit de dados na linha de transmissão do escravo é de 2 ns.


Uma descrição completa dos recursos do dispositivo pode ser encontrada em sua documentação .



O que o fabricante diz?



Esquema de controle recomendado



Com base na documentação AD9993-EBZ, a maneira recomendada de controlar o IC é usar a placa de depuração Analog Devices HSC-ADC-EVALC conectada ao IC por uma porta de 40 pinos e a um PC por meio da interface USB.



SPIController é usado como software de controle. Circuito HSC-ADC-EVALC de dispositivos analógicos





recomendados





(com base em Xilinx Virtex-4 FPGA)



contras:



  • Preço Alto. A placa de depuração HSC-ADC-EVALC no site oficial da Analog Devices é oferecida por $ 698,28.
  • Interface de usuário inconveniente. O software SPIController, além da função principal de escrever e ler registros, não oferece a capacidade de salvar ou iniciar o agendamento de comandos.
  • . SPI SPIController, . Analog Devices, SPI.




SPIController



:



  • .


HSC-ADC-EVALC



Deve-se notar que o uso da placa Analog Devices HSC-ADC-EVALC como um dispositivo de controle DAC / ADC não é seu objetivo principal.



O HSC-ADC-EVALC é usado principalmente como um cartão de memória buffer para o ADC, porém também tem a funcionalidade de configurar cartões de depuração via SPI se os cartões conectados suportarem.



Modelo de interação próprio



Razão para usar um dispositivo intermediário



É óbvio que a interação entre o DAC / ADC e o PC não pode ser organizada diretamente, já que o SPI, com o qual o AD9993-EBZ é programado, não é uma interface típica de um PC moderno.



Para resolver este problema, foi necessário utilizar um dispositivo intermediário que converteria os dados da interface USB enviados do computador para o formato de interface SPI suportado pelo IC.



No decorrer das opções, optou-se pela utilização da placa de depuração Terasic DE10-Nano, baseada no FPGA Cyclone V.





Modelo de interação próprio



Por que o FPGA é tão legal?



As principais vantagens de usar FPGAs:



  • . DE10-Nano , , , . IDE, Verilog.
  • . DE10-Nano HSC-ADC-EVALC ($110 $698.28). DE10-Nano , .
  • . , .
  • . FPGA- (FPGA – field-programmable gate array – , ), ( ). rocketboards c .




...



Durante a concepção do modelo de interação, decidiu-se implementar a interface SPI baseada em GPIO (pinos de uso geral), cuja base de contato está disponível no DE10-Nano. A implementação do controlador SPI baseado em FPGA não deveria ter criado nenhum problema especial devido à grande quantidade de materiais sobre um tópico semelhante.



No entanto, a implementação da conexão do FPGA ao computador via interface USB causou dificuldades.



DE10-Nano tem as seguintes portas USB:



  • USB mini-B alimentado por chip FT232R, realizando conexão UART para USB.
  • USB mini-B controlado pelo chip SMSC USB3300, que implementa a camada física da interface USB e também é usado para programar FPGAs.


O uso dessas portas é complicado pelo fato de que o DE10-Nano se comunica com essas portas através do chamado HPS ( sistema de processador rígido ) - uma parte do chip Cylone V, que contém um módulo de microprocessador, um processador ARM Cortex, controladores de memória flash e muito mais. A principal diferença entre HPS e FPGAs é que HPS são blocos de uma estrutura invariável, otimizados para uma função específica e não possuem suas ferramentas de programação (e portanto rígidas).



As partes HPS e FPGA do chip Cyclone V têm seus próprios pinos. Esses pinos não são compartilhados livremente entre o HPS e o FPGA. Os contatos HPS são configurados pelo software em execução no HPS. Os pinos FPGA são programados usando uma imagem de configuração FPGA por meio do HPS ou qualquer outra fonte externa compatível.



A fim de organizar a interação da lógica programável do chip Cyclone V com essas portas, é necessário criar um bootloader Linux especial rodando no HPS, e também é necessário desenvolver um programa que seja capaz de transmitir sinais dos controladores das portas USB disponíveis aos contatos livres do FPGA.



No estágio atual do conhecimento, essa questão se mostrou avassaladora, então decidiu-se por outro caminho. No entanto, para pessoas que enfrentam um problema semelhante e decidem resolvê-lo, pode ser útil ler um artigo sobre uma possível solução.



Existe uma saída!



Depois de vasculhar completamente a Internet, decidiu-se usar um controlador UART externo.



O controlador UART externo é uma pequena placa baseada no chip FT232RL. A placa possui conectores miniUSB-B para comunicação com um computador e um conector de 6 pinos para comunicação com microcontroladores e dispositivos.

O controlador é conectado via interface USB ao PC e via base de contato GPIO ao DE10-Nano.





O próprio controlador do Waveshare (usado no projeto)



Usar uma interface UART sobre USB para transferir dados de um PC praticamente elimina a necessidade de lidar com o complexo dispositivo de protocolo USB de várias camadas. A partir de agora, a interação via interface USB não é mais nossa preocupação, já que esta tarefa é atribuída aos drivers pré-instalados no sistema ou instalados de forma independente pelo usuário.



Além das linhas de força e terra, bem como das linhas de transmissão e recepção de dados, existem pinos na placa, assinados como RTS e CTS. Esses contatos são usados ​​para o chamado controle de fluxo - mecanismo projetado para sinalizar a prontidão para receber dados do dispositivo mestre ou escravo, dependendo do estado das linhas. Não é necessário o uso destas linhas, portanto, para desabilitar o mecanismo, é necessário indicar nas configurações do driver do computador que não é utilizado o controle de fluxo (esta geralmente é a configuração padrão).



Quando conectado a um PC com Windows, o controlador UART é detectado como uma porta serial virtual. Portanto, o desenvolvimento de um esquema de interação com um PC se resume a criar um software com a funcionalidade de interagir com uma porta serial virtual, bem como desenvolver um projeto para um FPGA que implemente a recepção / transmissão de dados via interface UART.



O controlador UART externo é de fato um análogo absoluto do controlador já existente no DE10-Nano, mas sua única vantagem é a capacidade de se conectar diretamente aos pinos livres do FPGA. O custo de tal dispositivo varia de $ 5 a $ 10.



Desenvolvimento de software



informação geral



Como já mencionado, o desenvolvimento de software para PC se reduz à criação de um programa que suporte a troca de informações com uma porta serial virtual. Durante a análise das ferramentas de software disponíveis para desenvolvimento de software, a escolha recaiu sobre a linguagem de programação Java 8ª edição utilizando a biblioteca RTXT.



Java é uma linguagem de programação orientada a objetos fortemente tipada com uma série de recursos-chave. Em particular, os programas escritos na linguagem de programação Java são traduzidos em um bytecode especial, o que permite que eles sejam executados em qualquer arquitetura de computador para a qual haja uma implementação da máquina virtual Java.



As bibliotecas padrão Java não têm a capacidade de interagir com a porta serial virtual. É para isso que a biblioteca RTXT foi usada. RTXT é distribuído sob uma licença de software livre. A biblioteca usa a implementação do sistema de interação com interfaces e fornece classes para análise, conexão, leitura e gravação de operações usando a porta serial. Mais sobre esta biblioteca pode ser encontrada aqui .



A antiga, mas confiável, biblioteca Swing interna é usada como uma ferramenta para desenvolver a interface do usuário. Devido à capacidade de mudar os temas, uma IU simples no Swing pode não parecer feia mais ou menos moderna.



O programa em si é espartana e simples e usa principalmente os recursos documentados da biblioteca RTXT.



A principal funcionalidade do programa



É assim que as portas disponíveis são determinadas:



    public String[] getPorts() {
        ports = CommPortIdentifier.getPortIdentifiers();
        while (ports.hasMoreElements()) {
            CommPortIdentifier curPort = (CommPortIdentifier) ports.nextElement();

            if (curPort.getPortType() == CommPortIdentifier.PORT_SERIAL) {
                portMap.put(curPort.getName(), curPort);
            }
        }
        return portMap.keySet().toArray(new String[0]);
    }


Conectando-se à porta selecionada:



    public void connect() {
        String selectedPort = (String)gui.ports.getSelectedItem();
        selectedPortIdentifier = portMap.get(selectedPort);
        CommPort commPort;
        try{
            commPort = selectedPortIdentifier.open("UART controller", TIMEOUT);
            serialPort = (SerialPort)commPort;
            serialPort.setSerialPortParams(BAUD_RATE, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);
            gui.writeLog(selectedPort + " opened successfully.");
        }catch (PortInUseException e){
            gui.writeLogWithWarning(selectedPort + " is in use. (" + e.toString() + ")");
        }catch (Exception e){
            gui.writeLogWithWarning("Failed to open " + selectedPort + " (" + e.toString() + ")");
        }
    }


Processo de transferência de dados:



    public boolean writeData(byte[] bytes){
        boolean successfull = false;
        try {
            gui.writeLog("WRITING: " + HexBinUtil.stringFromByteArray(bytes));
            output.write(bytes);
            output.flush();
            successfull = true;
        }
        catch (Exception e) {
            gui.writeLogWithWarning("Failed to write data. (" + e.toString() + ")");
        }
        return successfull;
    }


Recebendo dados:



    public void serialEvent(SerialPortEvent serialPortEvent) {
        if (serialPortEvent.getEventType() == SerialPortEvent.DATA_AVAILABLE) {
            try {
                byte singleData = (byte)input.read();
                gui.writeLog("READING: " + HexBinUtil.stringFromByteArray(singleData));
            }
            catch (Exception e) {
                gui.writeLogWithWarning("Failed to read data. (" + e.toString() + ")");
            }
        }
    }


Como já mencionado, o DAC / ADC é controlado enviando um comando para gravar algum valor válido de 8 bits em um endereço de registro específico descrito na documentação. Para determinar o estado atual do registro, você deve enviar o comando de leitura e especificar o endereço do registro solicitado. Descrição completa como sempre na documentação .



Transmissão de dados UART



Durante o estudo do AD9993-EBZ, descobriu-se que apenas 8 bits de dados são usados ​​no espaço de endereço de registro de 12 bits disponível. Além disso, o valor transmitido do estado do registro é descrito por 8 bits. Para determinar o tipo de transferência de dados (gravação / leitura), é necessário transferir 1 bit de dados.



Como a limitação atual do tamanho máximo de uma mensagem na interface UART é de 8 bits de dados, decidiu-se transmitir 3 mensagens consecutivas de 8 bits durante o processo de escrita e 2 mensagens durante o processo de leitura.



O primeiro pacote conterá o tipo de transmissão de dados, duplicado para todo o tamanho do pacote. Portanto, pode haver apenas dois valores possíveis: 00000000 para leitura e 11111111 para escrita, respectivamente. O uso de um burst inteiro para a transmissão de um bit de dados foi feito para simplificar o processamento posterior dos sinais recebidos.

Em seguida, o endereço do registro solicitado e o valor transmitido do estado do registro durante o processo de gravação são transmitidos.





Oscilograma do pacote UART desenvolvido



Interface de usuário







Os principais elementos da interface de usuário do software são botões para conectar / desconectar das portas seriais disponíveis (elementos 3,4), campos para inserir o endereço e valores de registro (elementos 7,8), uma janela de registro (elemento 6). O software foi projetado para interagir com ele em dois estados: "conectado à porta" e "desconectado da porta". Os estados determinam a atividade de alguns elementos na interface do programa e também restringem a execução de certos métodos para reduzir a probabilidade de erros e uso incorreto do software. Quando ativado, o programa está no estado "desconectado da porta". Além disso, para facilitar o trabalho com o programa (o que eu era um dos principais objetivos do projeto), foi adicionada a funcionalidade de conectar arquivos com comandos já salvos no formato JSON (elemento 10).



Processo de carregamento de comandos: interface de comandos de





seleção de arquivos





A



funcionalidade permite que você classifique os comandos carregados em seções (elemento 12), personalize o processo de trabalho com comandos conectados (seja para enviar um comando para a porta serial imediatamente quando pressionado, ou preencher os campos de endereço e valores de acordo com o comando selecionado) ...



Desenvolvimento de projeto para FPGA



informação geral



Antes de começar a desenvolver um projeto para um FPGA, você precisa decidir a tarefa que ele deve resolver.



É mais ou menos assim: o projeto do FPGA deve suportar a seguinte conversão de dados:





Diagrama de conversão de dados



O DE10-Nano recebe sinais da linha Tx da interface UART (sinal superior). Em seguida, o FPGA precisa determinar corretamente os dados recebidos de três mensagens de 8 bits cada e convertê-los para o formato de mensagem SPI correspondente à documentação (apresentada em 4 linhas).



Os principais módulos necessários para implementar esta conversão são um módulo controlador UART e um módulo controlador SPI. É a eles que o restante do capítulo é atribuído.



Ao desenvolver projetos para FPGAs, foi usada a 17ª versão do IDE Qartus Prime Lite Edition.

Se você não tem experiência no uso do Quartus ou não programou FPGAs, é recomendável começar com um exemplo claro (na minha opinião) do primeiro projeto no Quartus.



Gostaria de destacar que todos os trechos do código Verilog descritos a seguir são uma compilação de soluções encontradas na Internet, que não pretendem ser nenhuma originalidade. Novamente, o principal objetivo deste projeto é resolver um problema específico.



Controlador UART



Descrição



O controlador UART consiste em três módulos:



  • gerador de pulso;
  • módulo de gravação;
  • módulo de leitura.


Recomenda-se consultar este artigo , do qual foi retirada a maior parte das informações. Além disso, vou me concentrar apenas nos detalhes de implementação mais importantes (na minha opinião).



Gerador de pulso



Como a interface UART é assíncrona, para a correta recepção do sinal transmitido, o receptor precisa gerar seu próprio sinal de referência, o que permite determinar corretamente o início de um novo bit de informação.



Existe uma faixa geralmente aceita de taxas de transmissão UART padrão: 300; 600; 1200; 2400; 4800; 9600; 19200; 38400; 57600; 115200; 230400; 460800; 921600 baud Em nosso caso, a transferência de dados ocorre a 9600 baud. Em seguida, precisamos obter um gerador com uma frequência 16 vezes a taxa do símbolo. Isso é necessário para detectar corretamente o nível do sinal transmitido.



Para gerar pulsos, um gerador de 50 MHz é usado no chip. Para obter a frequência desejada, é necessário levar em consideração cada 325º pulso do gerador.

É assim que vai ficar no Verilog:



input           Clk;                   //   50
input           Rst_n;               //    
input [15:0]    BaudRate;      //   ,  325
output          Tick;                //  
reg [15:0]      baudRateReg; // 

always @(posedge Clk or negedge Rst_n)
    if (!Rst_n) baudRateReg <= 16'b1;
    else if (Tick) baudRateReg <= 16'b1;
         else baudRateReg <= baudRateReg + 1'b1;
assign Tick = (baudRateReg == BaudRate);
endmodule


Módulo leitor



O leitor converte o sinal de entrada da linha RX em uma matriz de dados de 8 bits de saída.



Ler e transferir diretamente os dados lidos para a saída:



input Clk, Rx,Tick;  //   50,  Rx,   
input [3:0]NBits;                  //     ,  8
output RxDone;	         //     
output [7:0]RxData;                         //  

reg  read_enable = 1'b0;                   //   
reg  RxDone = 1'b0;                         //   
reg [3:0] counter = 4'b0000;            //   
reg  start_bit = 1'b1;	                      //     
reg [4:0]Bit = 5'b00000;                  //    
reg [7:0] RxData;                            //    
reg [7:0] Read_data= 8'b00000000; //    


always @ (posedge Tick)  //        
	begin
	if (read_enable)
	begin
	RxDone <= 1'b0;			//   
	counter <= counter+1'b1;		// 
	

	if ((counter == 4'b1000) & (start_bit))	//   
	begin
	start_bit <= 1'b0;
	counter <= 4'b0000;
	end

	if ((counter == 4'b1111) & (!start_bit) & (Bit < NBits)) //  
	begin
	Bit <= Bit+1'b1;
	Read_data <= {Rx,Read_data[7:1]};
	counter <= 4'b0000;
	end
	
	if ((counter == 4'b1111) & (Bit == NBits)  & (Rx))  //  
	begin
	Bit <= 4'b0000;
	RxDone <= 1'b1;          //      
	counter <= 4'b0000;          //  
	start_bit <= 1'b1;		//   
	end
	end
	
end


always @ (posedge Clk)
begin

if (NBits == 4'b1000)            //  8  ,    
begin
RxData[7:0] <= Read_data[7:0];	
end

end


Módulo de transmissão





O módulo de transmissão converte o sinal de entrada de 8 bits em um pacote de dados serial UART.



Transferência direta de dados:



input Clk, Rst_n, TxEn;  // 50,  ,   
input Tick;                    //  
input [3:0]NBits;          //   
input [7:0]TxData;	

output Tx;
output TxDone;

reg  Tx;	
reg  TxDone = 1'b0;	
reg write_enable = 1'b0;
reg start_bit = 1'b1;	
reg stop_bit = 1'b0;	
reg [4:0] Bit = 5'b00000;	
reg [3:0] counter = 4'b0000;
reg [7:0] in_data=8'b00000000;

always @ (posedge Tick)  //        
begin

	if (!write_enable)	
	begin
	TxDone = 1'b0;
	start_bit <=1'b1;
	stop_bit <= 1'b0;
	end

	if (write_enable)
	begin
	counter <= counter+1'b1;	// 
	
	if(start_bit & !stop_bit)//        
	begin
	Tx <=1'b0;					
	in_data <= TxData;	

	if ((counter == 4'b1111) & (start_bit) )    //   
	begin		
	start_bit <= 1'b0;
	in_data <= {1'b0,in_data[7:1]};
	Tx <= in_data[0];
	end

	if ((counter == 4'b1111) & (!start_bit) &  (Bit < NBits-1))	//  
	begin		
	in_data <= {1'b0,in_data[7:1]};
	Bit<=Bit+1'b1;
	Tx <= in_data[0];
	start_bit <= 1'b0;
	counter <= 4'b0000;
	end	

	if ((counter == 4'b1111) & (Bit == NBits-1) & (!stop_bit))	//  
	begin
	Tx <= 1'b1;	
	counter <= 4'b0000;	
	stop_bit<=1'b1;
	end

	if ((counter == 4'b1111) & (Bit == NBits-1) & (stop_bit) )	// 
	begin
	Bit <= 4'b0000;
	TxDone <= 1'b1;
	counter <= 4'b0000;
	//start_bit <=1'b1;
	end
	
	end
		
end


Controlador SPI



Digressão importante



Como o controlador SPI, implementado com base em um FPGA, é uma estrutura lógica mais complexa que o controlador UART, a explicação adicional da lógica de operação é mais fácil de realizar no modelo de circuito do controlador.



Esquema geral do controlador







O modelo desenvolvido pode ser dividido em 3 módulos principais:



  • módulo de gravação sequencial;
  • módulo contador de bits;
  • módulo analisador de erros.


A divisão em módulos é bastante arbitrária, pois o circuito possui alta conectividade entre os elementos utilizados. A divisão é baseada nas tarefas executadas por grupos individuais de elementos, apresentados no diagrama geral.



O clock do circuito é fornecido por um sinal de 12,5 MHz fornecido através da linha CLK_125.



O início dos trabalhos do controlador na formação de uma mensagem de controle é feito através do sinal “START”. Por este sinal, todos os módulos do circuito são colocados em seu estado inicial e o início do ciclo de geração dos sinais necessários nas linhas de saída CLK, SS, MOSI da interface SPI é inicializado



Módulo de gravação sequencial







O módulo de gravação serial executará a tarefa principal do controlador SPI, ou seja, a saída de dados de bits paralelos para a linha serial MOSI. Isso se deve ao elemento RG_24_PI_SO, que opera no princípio de um registrador de deslocamento baseado em D-flip-flops.



O elemento RG_24_PI_SO possui 24 entradas de dados correspondentes à documentação AD9993-EBZ no formato de envio SPI. Eles incluem:



  • Dados de comando (DATA_0 - DATA_7);
  • Registrar dados de endereço (ADR_0 - ADR_12);
  • Bit de modo de gravação / leitura W / R.


Os sinais apresentados são escritos em paralelo em um nível lógico “1” na entrada LoadP_ShiftN. Além disso, no nível lógico "0" na entrada LoadP_ShiftN, em cada ciclo de clock na entrada CLK, o elemento reproduz alternadamente os dados registrados para a linha serial da saída MOSI.



Módulo contador de bits







O módulo contador de bits é necessário para determinar a duração do sinal de habilitação de gravação de dados na linha SS da interface SPI. Visto que, de acordo com a documentação AD9993-EBZ, a duração do sinal de habilitação deve ser igual à duração total dos dados transmitidos, torna-se necessário contar 24 pulsos de sincronismo desde o início da transmissão de dados para determinar a duração necessária do sinal de habilitação. A função de contagem é realizada pelo elemento ST_32 que, ao detectar o 24º sinal do relógio, reproduz um sinal que serve para zerar o contador, bem como para encerrar o sinal de habilitação transmitido.



Além da funcionalidade principal, o módulo contador de bits também é responsável por inicializar o processo de análise de erros, cuja ação inicial é enviar o comando de leitura do valor para o endereço do último registro registrado. Uma vez que o processo de análise de erro deve ser iniciado após um intervalo de tempo equivalente à duração de 23 pulsos de sincronização a partir do momento em que o último bit de dados transmitido foi transmitido (estabelecido experimentalmente), o contador de bits após o sinal de reinicialização muda para o modo de contagem de 23 pulsos de sincronização, o que garante a operação do processo de análise de erro.



Módulo de análise de erro







Conforme mencionado na explicação do módulo anterior, para fornecer a funcionalidade de análise de erros, foi desenvolvido um método baseado na leitura do valor do comando armazenado no CI no endereço do registrador utilizado no processo de registro dos dados. O processo de leitura é necessário para comparar o valor escrito com os dados lidos para identificar inconsistências e, portanto, para determinar o erro que ocorreu. O módulo de análise de erros é baseado no elemento RG_8_SI_PO, que opera no princípio de um shift register. O elemento converte os sinais recebidos pela porta serial MISO em uma saída paralela de 8 bits. Em seguida, os dados são comparados com o valor do comando usado durante o processo de gravação de dados. A funcionalidade de comparação é realizada pelo elemento CMP_8 com base na lógica exclusiva ou. Se uma discrepância for encontrada,o módulo envia um sinal para a saída do LED, que ficará no estado de unidade lógica até o próximo processo de gravação de dados. Presume-se que a saída do LED será conectada a um dos LEDs, um grupo dos quais está presente na placa de desenvolvimento DE10 Nano, que sinalizará visualmente a ocorrência de um erro.



Conclusão



Como resultado da solução deste problema, o esquema de interação entre o PC e o dispositivo DAC / ADC foi projetado e implementado fisicamente com uma série de vantagens importantes. No processo de implementação, foi solucionado o problema de conexão do FPGA e do PC. A solução para isso foi usar um módulo UART externo. O software para PC foi escrito na linguagem Java. O software possui uma interface com capacidades básicas de transmissão e recepção de dados no formato de envio UART desenvolvido, além disso, possui a função de carregar comandos salvos. Controladores UART e SPI baseados em FPGA foram desenvolvidos.



As questões consideradas no âmbito deste projeto permitem:



  • avaliar as formas de interação de circuitos integrados com dispositivos externos;
  • avaliar formas de usar FPGAs como um dispositivo compatível, um buffer para troca de dados;
  • explore uma das abordagens mais eficazes para desenvolver software para uso prático.


PS Terei todo o prazer em quaisquer acréscimos, comentários e indicações de erros.



All Articles