Co-simulação Heterogênea – Software e Hardware

Saudações!!! A ideia de escrever este artigo nasceu antes mesmo de colocar o conhecimento, adquirido profissionalmente anos antes, sobre este assunto na prancheta para o tornar um projeto prático e simplificado. À época, trabalhar num projeto que possibilitaria a integração entre software e hardware em ambiente totalmente simulado, para validar funcionalmente um sistema, me fascinou e este sentimento fez-me querer compartilhar tal conhecimento. Por este motivo, as características deste artigo estão muito mais relacionadas ao formato de um tutorial (DIY) do que explicar teoricamente os conceitos por trás desta técnica.

 

Mas afinal, o que será tratado aqui? Trata-se de um projeto que dará a possibilidade de realizar  troca de informação entre software e hardware, escritos em linguagem C e VHDL, respectivamente. Ao final deste artigo você terá o direcionamento para baixar o código fonte para realizar seus estudos ou adaptá-lo para seu projeto de sistemas embarcados.

 

Aplicação

 

Para simular um sistema eletrônico composto por tecnologias diferentes e com grau de abstração distinto, como sistemas compostos por microcontroladores/processadores e FPGAs, pode-se recorrer à uma estratégia de simulação onde cada componente do sistema é avaliado de maneira isolada e/ou recorrer à uma análise integrada destes componentes. Recorrendo à segunda opção, pode-se minimizar a necessidade de desenvolvimento extra de componentes exclusivos para ambientes de teste (mock, stub, geração de dados de entrada, etc.) e obter uma validação e verificação funcional do sistema de modo virtual.

 

Uma das dificuldades encontradas em um ambiente co-simulado é definir uma arquitetura para o canal de comunicação entre os componentes de hardware. Para os componentes analógicos e/ou sensores inteligentes, faz-se a necessidade de geração de uma massa de dados que seja o mais fiel possível à especificação destes componentes, esta parte não será coberta neste artigo. Quanto à comunicação entre os componentes digitais (microcontroladores, processadores, DSPs, FPGAs, etc.) apresentarei aqui uma possível solução que cria um mecanismo de comunicação que “emula” as interfaces digitais.

 

Descrição do Projeto

 

O projeto apresentado para exemplificar a co-simulação é um somador completo de 8 bits, onde a operação de soma é executada pelo hardware (FPGA) enquanto que o software é responsável por passar dois valores para a soma. Uma vez executada a operação, o software pode requisitar a o valor da soma. A troca de informação entre software e hardware é feita através de arquivos de buffer. Abaixo, a arquitetura simplificada do projeto. 

Figura 1: Diagrama de blocos exemplificando a arquitetura da co-simulação.

Este projeto é composto por dois executáveis e dois arquivos para buffer de comunicação. Os dois executáveis gerados são: 1) Gerado à partir de programa escrito em linguagem C que interage diretamente com o usuário e; 2) Gerado à partir da simulação do projeto de hardware, descrito em VHDL, através do ambiente de simulação Isim da Xilinx e é composto pelo somador completo de 8 bits. Os dois arquivos de buffer são: 1) Para a escrita do software e leitura do hardware e; 2) Para escrita do hardware e leitura do software.

 

A troca de informação entre estes dois executáveis é realizada através de arquivos do tipo named pipe ou FIFO (First In First Out).

 

Buffer

 

Os arquivos de buffer servem para troca de informação entre software e hardware, como citado anteriormente. Estes arquivos são gerados automaticamente após build do projeto através do script run.sh, dentro deste script é executado o comando mkfifo para criação dos arquivos de bufffer. Abaixo, as características destes arquivos podem ser verificadas através do comando ls.

Figura 2: Características dos arquivos do tipo named pipe, identificados com a letra p.

Como característica principal estes arquivos possuem o comportamento de apagar automaticamente a informação contida neles logo após a sua leitura. Com isso, facilita em muito o processo de handler da informação e a criação de um protocolo de comunicação entre software e hardware. Como teste, pode-se executar os comandos abaixo em dois consoles diferentes:

 

Console 1:

 

Console 2:

 

Através deste teste, será possível observar que mesmo tentando fazer uma nova leitura do conteúdo do buffer, no segundo comando cat < test, já não é possível encontrar nenhuma informação justamente porque os dados foram apagados logo após a primeira leitura.

 

Retomando ao projeto, os dois arquivos usados para a troca de dados entre software e hardware simulado recebem os dados referente ao protocolo de comunicação demonstrado na próxima imagem. Toda a ação é iniciada e controlada por parte do software, neste caso, pois a origem das parcelas para a operação de soma se dá neste componente.

Figura 3: Diagrama de sequência da comunicação usando buffer do tipo "named pipe".

É possível observar na imagem anterior que nunca haverá uma operação de escrita do componente software no buffer do componente hardware e vice-versa. Após escrita dos dois valores pode-se requisitar o resultado da soma.

 

Hardware UUT (Unit Under Test)

 

O hardware apresentado neste projeto é um somador completo de 8 bits com bit de carry. Este projeto foi adaptado à partir do projeto apresentado no livro VHDL – Descrição e Síntese de Circuitos Digitais, autor Roberto D’Amore.

Figura 4: Somador completo de 8 bits.

O hardware descrito em VHDL recebe dois valores (unsigned) compreendidos entre 0 e 255, realiza a soma destes valores e retorna o valor da soma e um sinal de carry que será “0” para o caso em que a soma não ultrapasse 255 e “1” caso a soma ultrapasse 255.

 

Não me aprofundarei na descrição deste hardware porque o intuito deste artigo é focar no mecanismo de comunicação entre software e hardware simulado, sendo assim abaixo o trecho de código em VHDL (arquivo pipeBus.vhd) que trata os dados recebidos do buffer.

 

Este é o trecho de código em que a simulação permanece até que tenha algum comando válido enviado pelo software, ou seja, se não estiver no fim do arquivo (arquivo vazio ou lido até o último caractere) a simulação permanece no loop aguardando uma entrada válida. Nota-se também que os caracteres ‘ ‘ e ‘,’ são delimitadores de um novo campo de entrada/comando e que o caractere ‘;’ representa que o comando chegou ao fim e deverá ser executado, este controle é feito através da variável booleana “exec”.

 

Os campos que serão tratados como entrada são separados dentro do “switch case” aninhado, ou seja, no trecho de código onde os operadores OperA_v, OperB_v e OperC_v recebem os valores lidos do buffer. Um comando de escrita válido para o projeto de simulação do hardware seria “W,10,1”, onde “W” seria o comando de escrita, “10” o valor de entrada em decimal e “1” o endereço definido como sendo a referência para a parcela “A” do somador completo de 8 bits.

 

No trecho de código à seguir é possível ver o endereçamento de cada parcela de entrada do do simulador:

 

A escrita dos dados no buffer de saída, por parte do hardware, é realizada por dois “procedures” que possuem o mesmo nome e que se diferem na quantidade de dados que serão escritos no buffer de saída são eles: 

(A).

 

(B).

 

Sendo que (A) escreve apenas uma string no buffer enquanto que (B) escreve duas strings.

 

A identificação dos comandos é realizada dentro do processo principal do projeto de hardware descrito em VHDL, nele é possível ver que os comando são filtrados pelas seguintes tags: “W” ou “w” para escrita dos dados no buffer de entrada do hardware; “R” ou “r” para leitura dos dados do buffer de saída do hardware; “N” ou “n” para comando inócuo, comando escrito no buffer de entrada do hardware; “Q” ou “q” para encerrar a simulação, comando escrito no buffer de entrada do hardware, e; qualquer outro comando como sendo inválido, comando escrito no buffer de entrada do hardware.

Figura 5: Carta de tempo do circuito somador completo.

Na carta de tempo acima vemos que em 400ns o valor 20 foi escrito na entrada “B” do somador e que neste mesmo instante o valor da soma passou a valer 30, pois a entrada “A” já havia registrado o valor 10 anteriormente. Outro ponto importante que pode ser notado nesta carta está em 800ns, neste momento a entrada “A” recebe o valor 250 e, com isso, o bit de carry passa a ser “1” porque a soma estoura.

 

Software

 

O projeto de software, escrito em linguagem C, é responsável por fazer a aquisição de dois valores de entrada: A ou B. Estes valores devem ser menor ou igual à 255, abaixo o output para o comando help.

Figura 6: Opções de uso do software.

A troca de informação entre software e hardware é feita, por farte do software, através de duas principais funções: PIPE_WriteToBus e PIPE_ReadFromBus. Para o caso de escrita dos valores A e B é usada a função PIPE_WriteToBus e para o caso de leitura do valor da soma “sum” é executada a função PIPE_ReadFromBus.

 

O trecho de código à seguir apresenta o que é comum no protocolo de comunicação entre hardware e software, pois está presente tando na função de escrita quanto na função de leitura do buffer. É fácil que notar que para ambos os casos é esperado que a resposta ao comando seja aceita, não aceita ou que o comando esteja em execução, respectivamente nas condições “Not Acknowledge”, “Acknowledge” e “Waiting Answer”.

 

A representação deste trecho de código também pode ser conferida através do diagrama de sequência apresentado anteriormente neste artigo, onde o comando de escrita dos valores A ou B são executados.

 

Na imagem à seguir apresento um teste realizado para simular a comunicação entre hardware e software, no prompt à esquerda vemos as leituras do buffer, realizadas pelo software. No prompt superior direito, vemos que a resposta do hardware aos comando advindos do software são simuladas, através do comando “echo” e no prompt inferior direito vemos a resposta para cada comando de hardware simulado.

 

Este cenário de teste foi realizado da seguinte maneira, primeiramente executa-se o software de teste (test_pipeBus.c) da comunicação do software, este software encontra-se  no seguinte caminho “CoSimulation/CoSimulation/cosim/sw/utest/”, sem hardware conectado. A seguir entra-se com o comando “cat bus_sw2hw.txt” que serve para monitorar a escrita no buffer por parte do software e, em seguida, simula-se os comando que deveriam ser retornados pelo hardware para cada comando executado pelo software.

 

Os comandos “S, X;”, “A;” e “D;” são comando referente à um hand shake de comunicação entre hardware e software, enquanto que o comando “F, XXXX;” é referente à escrita do valor XXXX no buffer de entrada do hardware. Neste caso de teste em específico podemos ver que inicialmente um comando de sincronismo é enviado (S,0;) e que o hardware responde com o mesmo valor, em seguida o hardware envia uma confirmação (A;), na sequência uma operação de leitura é solicitada e, o hardware simulado através do comando “echo”, escreve um valor (A5A5) no buffer de transferência. Imediatamente após esta entrada, o software realiza o valor da leitura.

Figura 7: Teste do mecanismo de comunicação do ponto de vista do software.

Na imagem abaixo abaixo é possível observar a operação do software, já com o hardware simulado através do ISim Xilinx.

Figura 8: Execução do software e interação com simulação.

 

 

Construção (Build) e Execução do Projeto

 

Maiores informações do projeto são fornecidas na página do projeto no GitHub, assim como os detalhes das dependências para executá-lo. 

 

Conclusão

 

Este tem o objetivo de facilitar o desenvolvimento de projetos de sistemas embarcados em que possuam em sua arquitetura processadores ou controladores que fazem interface direta com FPGAs, ou seja, onde o processamento é compartilhado. Desta maneira, possuindo um ambiente totalmente simulado em ambiente desktop, pode-se validar funcionalmente um projeto. 

 

Espero que se divirtam assim como foi divertido para mim trabalhar neste projeto. Saudações!!!

 

Referência do Projeto

(https://github.com/dr-kino/CoSimulation)

 

Referências

 

VHDL – Descrição e Síntese de Circuitos Digitais. D’Amore, Roberto. Rio de Janeiro: LTC, 2005

Co-Simulação Distribuída de Sistemas Heterogêneos. De Mello, Braulio Adriano. Porto Alegre: PPGC da UFRGS, 2005.

Co-Simulação. Augusto de Oliveira, Leandro. De Morais Amory, Alexandre. Porto Alegre: PUCRS, SDD. (https://corfu.pucrs.br/tikiwiki/tutorials/cosim.pdf)

NEWSLETTER

Receba os melhores conteúdos sobre sistemas eletrônicos embarcados, dicas, tutoriais e promoções.

Obrigado! Sua inscrição foi um sucesso.

Ops, algo deu errado. Por favor tente novamente.

Licença Creative Commons Esta obra está licenciada com uma Licença Creative Commons Atribuição-CompartilhaIgual 4.0 Internacional.

Rafael Cavalcanti
Engenheiro eletricista com ênfase em eletrônica e mestrando em controle (on hold). Atua principalmente nas áreas de defesa e segurança (security), sempre com sistemas embarcados (software e hardware digital).

2
Deixe um comentário

avatar
 
1 Comment threads
1 Thread replies
0 Followers
 
Most reacted comment
Hottest comment thread
2 Comment authors
Rafael CavalcantiFabio Santos Recent comment authors
  Notificações  
recentes antigos mais votados
Notificar
Fabio Santos
Visitante
Fabio Azola

Excelente artigo parabéns