Obtendo FPGA em Python

A tecnologia FPGA (FPGA) está atualmente ganhando grande popularidade. O número de aplicativos está crescendo: além de processar sinais digitais, os FPGAs também são usados ​​para acelerar o aprendizado de máquina, em tecnologias de blockchain, processamento de vídeo e na Internet das coisas.

Essa tecnologia tem um ponto negativo significativo: para programação, são usadas linguagens de descrição bastante complexas e específicas dos equipamentos digitais Verilog e VHDL. Isso complica a entrada de um recém-chegado ao FPGA e é difícil para um empregador encontrar um especialista com esse conhecimento específico no mercado de trabalho. Por outro lado, a popular linguagem de programação Python de alto nível com a estrutura MyHDL torna a programação FPGA simples e agradável. Além disso, as pessoas que conhecem Python são uma ordem de magnitude mais especialistas em Verilog / VHDL. Com uma série de artigos, quero mostrar como é fácil entrar no campo do FPGA conhecendo o Python e começar a fazer projetos FPGA complexos reais nessa linguagem. Observo que o python não é executado diretamente no FPGA, mas é uma ferramenta para gerar firmware.

Primeiro, precisamos da versão 3.6 do python (a seguir, todas as operações são realizadas no Ubuntu 18.04 OS).

Instale o myhdl:

pip3 install myhdl 

Como "Olá, mundo!" Escreveremos um programa simples que acende os LEDs quando um botão é pressionado. No mundo dos microprocessadores "Hello World!" Este é um programa que pisca com um LED. No mundo do FPGA, o Hello World é o piscar de mil LEDs. Existem apenas quatro LEDs na placa, portanto, piscaremos apenas, dependendo do pressionamento do botão. É importante observar que todo o código no FPGA, ao contrário dos microcontroladores, é executado ao mesmo tempo, todos os diodos acendem e apagam ao mesmo tempo. E não sequencialmente no caso de microcontroladores. O teste usa a placa WaveShare OpenEPM1270 com as placas Altera Max II EPM1270T144C5.



Crie um novo arquivo python:

 from myhdl import * from random import randrange def led_blinker(input1, led1, led2, led3, led4): @always_comb def on_off_led(): if input1 == 1: led1.next = 1 led2.next = 1 led3.next = 0 led4.next = 0 else: led1.next = 0 led2.next = 0 led3.next = 1 led4.next = 1 return on_off_led 

Para descobrir se nosso código funciona corretamente, você precisa de uma ferramenta de verificação. De fato, qualquer programa para FPGA é um processador de sinal digital; portanto, o desenvolvedor precisa ter certeza de que ele indicou corretamente o que fazer com o chip. Isso é feito através de simulação, para isso você precisa instalar um programa que exibirá os sinais processados. Existem muitos desses programas, mas, na minha opinião, o melhor GTKWave gratuito no momento. É colocado a partir do terminal:

 sudo apt-get install gtkwave 

Em seguida, no arquivo com o firmware, o ambiente de teste deve ser descrito. Esta também é uma função python:

 def test(): input1, led1, led2, led3, led4 = [Signal(bool(0)) for i in range(5)] test = led_blinker(input1, led1, led2, led3, led4) @always(delay(10)) def gen(): input1.next = randrange(2) return test, gen 

Aqui, o ambiente de teste gera uma sequência aleatória de zeros e uns (o módulo Python aleatório é usado).

 def simulate(timesteps): tb = traceSignals(test) sim = Simulation(tb) sim.run(timesteps) 

E inicializamos o simulador, arrastando a função de ambiente test_inverter para lá. Assim, obtemos o inversor de bonecas russo → test_inverter → simular (tempo em unidades arbitrárias).

Após executar o script na pasta de trabalho, crie um arquivo .vcd e execute-o no gtkwave, no terminal: gtkwave test_invereter.vcd.



Como resultado, uma sequência aleatória dos sinais de entrada input1 foi gerada e como a função led_blinker processou esses sinais.

Depois de termos certeza de que a lógica funcionava exatamente como queríamos, devemos lançar essa função no FPGA. Estou acostumado a trabalhar com chips da Intel (anteriormente Altera), essa sequência de operações é semelhante para chips de outros fabricantes com sistemas CAD apropriados. Um arquivo binário é criado no chip FPGA, criado pelo compilador do fabricante do chip; para a Intel é Quartus, para o Xilinx Vivado. Os compiladores só podem trabalhar com código em VHDL / Verilog; portanto, o código Python deve ser traduzido para qualquer um desses idiomas (não importa qual).

 def convert(): input1, led1, led2, led3, led4 = [Signal(bool(0)) for i in range(5)] toVerilog(led_blinker, input1, led1, led2, led3, led4) convert() 

Neste exemplo, o código é traduzido para o Verilog. O resultado está no arquivo led_blinker.v e o Quartus precisará fornecer para gerar o firmware FPGA:

 module led_blinker ( input1, led1, led2, led3, led4 ); input input1; output led1; reg led1; output led2; reg led2; output led3; reg led3; output led4; reg led4; always @(input1) begin: LED_BLINKER_ON_OFF_LED if ((input1 == 1)) begin led1 = 1; led2 = 1; led3 = 0; led4 = 0; end else begin led1 = 0; led2 = 0; led3 = 1; led4 = 1; end end endmodule 

Nesta abordagem ao desenvolvimento do firmware FPGA, você pode ignorar esse arquivo e simplesmente soltá-lo no Quartus.

Você pode baixar o Quartus em fpgasoftware.intel.com , precisamos de uma versão gratuita do Lite, será o suficiente para nós. Baixe o tamanho da versão básica de 9 GB.

Instalar o Quartus não deve ser um problema para o usuário médio do Linux. Após a instalação, você precisa definir alguns parâmetros no sistema para poder usar o dispositivo para exibir o programa FPGA - o programador:

1. Crie uma regra do udev. Para fazer isso, crie um novo arquivo /etc/udev/rules.d/51-altera-usb-blaster.rules com o seguinte conteúdo:

 # USB-Blaster SUBSYSTEM=="usb", ATTR{idVendor}=="09fb", ATTR{idProduct}=="6001", MODE="0666" SUBSYSTEM=="usb", ATTR{idVendor}=="09fb", ATTR{idProduct}=="6002", MODE="0666" SUBSYSTEM=="usb", ATTR{idVendor}=="09fb", ATTR{idProduct}=="6003", MODE="0666" # USB-Blaster II SUBSYSTEM=="usb", ATTR{idVendor}=="09fb", ATTR{idProduct}=="6010", MODE="0666" SUBSYSTEM=="usb", ATTR{idVendor}=="09fb", ATTR{idProduct}=="6810", MODE="0666" 

Reinicie o udev usando o udevadm:

 sudo udevadm control --reload 

2. Permita acesso não raiz ao dispositivo USB-Blaster. Para fazer isso, crie o arquivo /etc/udev/rules.d/altera-usb-blaster.rules com a linha:

 ATTR{idVendor}=="09fb", ATTR{idProduct}=="6001", MODE="666" 

Isso dá acesso rw-rw-rw- ao programador.

3. Configure o jtagd. O Quartus usa o daemon jtagd para funcionar, que associa o software a um dispositivo programador. Copie a descrição do seu diretório com o Quartus:

 sudo mkdir /etc/jtagd sudo cp <Quartus install path>/quartus/linux64/pgm_parts.txt /etc/jtagd/jtagd.pgm_parts 

Execute o Quartus e crie um novo projeto "Arquivo" - "Assistente de novo projeto", digite o nome do projeto.

Em seguida, clique em Avançar. E no menu Adicionar arquivos, conectamos o arquivo verilog gerado à extensão .v. Assim, se o arquivo verilog for editado a partir de um arquivo python, ele será automaticamente capturado pelo Quartus.Em seguida, chegamos ao menu de seleção de dispositivos, no nosso caso, é MAX II EMP1270T144C5 e no próximo par de vezes. O projeto é criado.

No Navegador de projeto, acesse o menu Arquivo e clique com o botão direito do mouse em nosso arquivo de verificação "Definir como entidade de nível superior".

Nós compilamos o projeto. Agora, no menu "Assignments-Pin Planner", configure os pinos no chip:



Compile novamente. Agora tudo está pronto para a programação: Ferramentas-Programador. Conectamos o programador e a alimentação à placa. Na Configuração do hardware, selecionamos o nosso USB-Blaster, marque as caixas de seleção conforme mostrado na figura e Iniciar.



Depois que o programador relatou com êxito. Você pode ver o resultado no quadro:



Conclusão


Esta lição descreve como criar um ambiente de trabalho e o primeiro projeto FPGA simples na linguagem de programação Python.

Considerado:

  • como instalar:
    • myHDL;
    • GTKWave;
    • Quartus;
  • Programador USB Blaster configurado no Ubuntu;
  • FPGA Projeto FPGA desenvolvido;
  • Teste e verificação do projeto;
  • Compilou um projeto para FPGA;
  • Projeto carregado no FPGA.

Source: https://habr.com/ru/post/pt439638/


All Articles