Automatize o desenvolvimento de FPGA com Jenkins, Vivado e GitHub em um VPS Linux
* Este artigo contém um link de anúncio para UpCloud VPS
A entrega contínua e a integração contínua são metodologias ágeis de desenvolvimento de software que encurtam o tempo de ciclo entre a mudança do código e a implantação. Ao usar a automação para verificar alterações de código e criar arquivos de lançamento, as equipes podem se tornar mais produtivas e eficientes.
As empresas de software praticam o desenvolvimento contínuo há muito tempo, mas você também pode usar os métodos para seus projetos FPGA. Este tutorial ensina como configurar um servidor de automação em um servidor virtual privado (VPS) usando Jenkins, Xilinx Vivado e o sistema de gerenciamento de controle de origem (SCM) Git/GitHub.
O que é Jenkins?
O servidor de automação Jenkins é um programa gratuito e de código aberto escrito em Java. Ele roda em Windows ou Linux. Usaremos Linux nesta postagem do blog porque essa é a plataforma mais comum para servidores headless.
Jenkins é executado como um processo daemon no Linux ou como um serviço no Windows. Um servidor web integrado que o Jenkins inicia quando é iniciado fornece a interface do usuário. A maioria dos usuários interagirá com Jenkins usando a interface da web. Você pode adicionar novos projetos de automação e gerenciar os existentes por meio da GUI da web.
A imagem acima mostra a página principal do servidor Jenkins que iremos configurar hoje. Por padrão, apenas usuários logados podem acessar o Jenkins, mas para este artigo, habilitei o acesso público a partes do meu servidor *demo.
* Atualização:desativei o servidor de demonstração em 13 de maio de 2020
O que você vê na página principal é uma lista de empregos. Esses trabalhos podem conter qualquer tarefa e podem ser acionados manualmente a partir da GUI da web. Ou podem ser acionados automaticamente por meio de scripts, webhooks ou como resultado da conclusão de outros trabalhos. Daí o termo servidor de automação .
Em nosso exemplo, cada trabalho corresponde a um módulo VHDL mantido em um repositório GitHub separado. Faremos Jenkins executar uma simulação e construir o projeto sempre que um desenvolvedor enviar código para um dos repositórios Git monitorados. Se um testbench falhar ou se a construção falhar, Jenkins marcará o trabalho como falhado na interface web e enviará automaticamente um e-mail para a pessoa que cometeu o código defeituoso.
O projeto de exemplo
Os servidores de automação são mais úteis para equipes que trabalham em projetos maiores. Portanto, construí um projeto FPGA de exemplo que consiste em oito repositórios Git. O projeto é o display de 7 segmentos do curso Fast-Track portado para o Xilinx ZedBoard.
Links para os oito repositórios no GitHub:
- pacotes (pacotes VHDL)
- bcd_encoder (Módulo)
- contador (Módulo)
- seletor de dígitos (Módulo)
- output_mux (Módulo)
- redefinir (Módulo)
- seg7_encoder (Módulo)
- seg7 (Módulo superior)
Cada repositório contém um módulo VHDL e seu testbench. Uma exceção são os pacotes repo, que contém apenas três pacotes VHDL que definem constantes e tipos. Além disso, o seg7 O módulo top contém um arquivo de restrições que define a velocidade do clock e as atribuições de pinos da implementação física.
A maioria dos projetos VHDL de grande escala utiliza módulos de mais de um repositório. As empresas normalmente possuem uma biblioteca de pacotes e módulos que reutilizam em muitos projetos. É isso que estou emulando ao dividir esse design bastante simples em vários módulos.
Em nosso exemplo, todos os módulos dependem do repositório de pacotes, e o módulo superior também depende de todos os submódulos. Eu resolvi isso importando-os conforme necessário usando submódulos Git padrão. O gráfico acima mostra o conteúdo e as dependências de todos os repositórios neste projeto.
Os repositórios Git também contêm vários arquivos que não são de design, como a configuração do Jenkins e scripts de construção. Falaremos sobre eles nas próximas seções deste artigo.
Servidor virtual privado (VPS)
Embora o Jenkins possa ser executado em qualquer computador Windows ou Linux, para todos os efeitos práticos, você gostaria de executá-lo em um servidor dedicado. O servidor de automação deve estar sempre funcionando e acessível a todos os membros da sua equipe. Se você tiver um servidor físico com capacidade suficiente disponível, isso é ótimo. Mas para a maioria de nós, uma solução mais rápida e barata é usar um servidor virtual privado (VPS).
Um VPS é um computador virtual que você aluga de uma empresa de hospedagem pela Internet. Ele aparece como um computador Windows ou Linux real com o qual você pode interagir e instalar qualquer software que desejar. Usaremos um computador Linux porque é o que faz mais sentido para o nosso caso de uso.
O site VHDLwhiz está rodando em um VPS, como tem acontecido nos últimos dois anos. Já tive o trabalho de encontrar o melhor e mais rápido provedor de VPS, que é o UpCloud. Naturalmente, usaremos o UpCloud para configurar o VPS do nosso servidor de automação.
Receba o bônus UpCloud de US$ 25
Se você quiser experimentar o UpCloud, tenho um código de referência que dará a você US$ 25 em crédito ao se inscrever.
>> Clique aqui para obter o bônus UpCloud de $ 25 <<
Ou use meu código promocional durante a finalização da compra:NV78V6
Ao usar o código, você receberá o bônus e suporte ao VHDLwhiz ao mesmo tempo. Posso receber alguns fundos creditados em minha conta UpCloud para cada cliente que a utilizar.
Ok, chega de conversa de vendas. Vamos prosseguir com a configuração do servidor.
Implantando o VPS UpCloud
Depois de fazer login em sua nova conta UpCloud, você pode iniciar o processo de criação de uma nova instância VPS navegando até Servidores → Deploy server .
UpCloud possui muitos data centers em todo o mundo. Selecione o local mais próximo de você para hospedar seu novo servidor. Então você deve selecionar um plano para quantos recursos fornecer à sua máquina virtual. Jenkins não usa muitos recursos, mas Xilinx Vivado é um verdadeiro consumidor de RAM. Portanto, você deve escolher pelo menos o plano com 4 GB de RAM, conforme mostra a imagem abaixo.
Eu recomendo dar uma olhada na página de recomendações de memória da Xilinx porque o uso de memória está intimamente relacionado à complexidade do FPGA de destino. A página lista o pico de uso de memória para o FPGA Zynq-7000 XC7Z045 que estou usando como 1,9 GB. Descobri que o plano de 2 GB era pouco para rotear o design. O Vivado travou e a seguinte mensagem apareceu no dmesg registro:
[807816.678940] Sem memória:processo eliminado 22605 (vivado) total-vm:2046684kB, anon-rss:782916kB, arquivo-rss:308kB, shmem-rss:0kB
Observe que você sempre pode atualizar facilmente os recursos de RAM e CPU do seu servidor de dentro da sua conta UpCloud. Você não obterá automaticamente o espaço extra no disco rígido que vem com os pacotes mais caros sem reparticionar o sistema de arquivos do VPS, mas ele funcionará. Para referência, comecei no plano com 50 GB de armazenamento e usei 61% disso depois de concluir todo o servidor de automação. Só o Vivado ocupa 24 GB de espaço.
Eu recomendo que você selecione a distribuição CentOS Linux mais recente como sistema operacional, conforme mostrado na imagem abaixo. Xilinx Vivado suporta oficialmente apenas Red Hat Linux, que não é gratuito. Mas o CentOS é uma distribuição Linux gratuita e apoiada pela comunidade que segue de perto o Red Hat.
Depois, há algumas opções de rede que você pode deixar nos padrões. Há também uma seção na página da web onde você pode fazer upload de suas chaves SSH para login sem senha. Você sempre pode configurar essas coisas posteriormente usando o método convencional do Linux para fazer upload de chaves SSH.
Por fim, você precisa especificar o nome do host e o nome do servidor, conforme mostrado na imagem abaixo. O nome do host é o domínio público que os usuários inserirão no navegador para acessar o servidor Jenkins. Se você não tiver um domínio ou subdomínio pronto, poderá sempre acessar o servidor usando seu endereço IP. Quando estiver satisfeito com as configurações, pressione o botão Implantar botão para criar o servidor.
Depois de criar o servidor, a senha gerada automaticamente será exibida como uma notificação. Você pode alterar isso mais tarde, usando o Linux passwd comando. Se você forneceu sua chave SSH antes de implantar o servidor, não precisará da senha. Caso você perca o acesso ao seu servidor, você pode fazer login na sua conta UpCloud clicando em Abrir a conexão do console , conforme mostrado na imagem abaixo.
Configurações de zona DNS
O novo servidor recebe endereços IPv4 e IPv6 permanentes, encontrados em sua conta UpCloud em Servidores->Rede . Você pode acessar o servidor por meio de SSH na conta root do endereço IPv4 público.
Usando o exemplo de endereço IP da imagem abaixo, o comando apropriado para inserir em seu computador doméstico Linux seria:
Não há problema em usar apenas o endereço IP se você estiver fazendo isso apenas como um experimento. Mas uma solução mais prática é atribuir um nome de domínio permanente ao servidor. Para fazer isso, você precisa comprar um domínio de um dos muitos registradores disponíveis online.
Como já possuo o domínio vhdlwhiz.com, decidi criar um subdomínio para o servidor Jenkins chamado jenkins.vhdlwhiz.com . Configuramos o nome de domínio corretamente no servidor UpCloud quando o implantamos. A próxima coisa que precisamos fazer é apontar o subdomínio para o endereço IPv4 público.
A imagem abaixo mostra as configurações que estou inserindo no arquivo de zona DNS do meu registrador de nomes de domínio. Se eu quisesse que o servidor estivesse no domínio principal (vhdlwhiz.com), teria deixado o campo do nome do host em branco. Mas quero que esteja no subdomínio “jenkins” de vhdlwhiz.com. Portanto, insiro o nome do subdomínio.
Depois de alterar as configurações de DNS, levará algum tempo antes que você possa usar o nome de domínio para acessar seu site. Normalmente, não leva mais de 20 minutos, mas em casos extremos, pode levar até 48 horas para que as alterações sejam propagadas para todos os cantos da Internet.
Quando as alterações entrarem em vigor, você poderá usar o nome de domínio em vez do endereço IP ao fazer login no servidor por SSH:
02Instalando Jenkins
A primeira coisa que você deve fazer após fazer login na conta root em seu novo servidor Linux é atualizar todos os pacotes instalados. No CentOS Linux, yum é o gerenciador de pacotes padrão. Vamos usar o yum comando para instalar a maior parte do software.
Emita o seguinte comando para atualizar todos os pacotes instalados para as versões mais recentes:
Agora que sabemos que nosso sistema está atualizado, podemos prosseguir com a instalação. Mas antes de emitir o yum comando para instalar o Jenkins, vamos instalar o Java versão 11, explicitamente. Isso nos poupará alguns problemas mais tarde, quando instalarmos o Xilinx Vivado.
Atualmente, não há nenhum interpretador Java presente em nosso servidor, e se dissermos ao yum para instalar o Jenkins, ele instalará o Java versão 8. Isso funciona bem para o Jenkins, mas criará problemas para nós mais tarde porque o Vivado depende do Java versão 11.
Instale o Java 11 usando este comando antes de instalar o Jenkins:
11
Jenkins não está disponível no repositório de software padrão que acompanha o CentOS. Felizmente, podemos importar o repositório Jenkins do Red Hat usando os seguintes comandos:
29
Finalmente, podemos prosseguir e instalar o Jenkins:
O servidor Jenkins será iniciado automaticamente após a próxima inicialização, mas você pode iniciar o servidor sem reinicializar assim:
Você sempre pode verificar o status do servidor Jenkins usando o systemctl comando:
Ele imprimirá o status do servidor junto com quaisquer mensagens de erro:
Jenkins sobre HTTP inseguro
Neste ponto, o Jenkins está sendo executado na porta 8080 do VPS, mas você não tem como se conectar a ele com seu navegador. Isso ocorre porque o firewall CentOS bloqueia a porta 8080 e a porta 80 (HTTP) por padrão. O que podemos fazer para corrigir isso é abrir a porta 80 no firewall e redirecioná-la para a porta 8080 usando iptables .
Mas antes de fazer isso, você precisa decidir se deseja proteger seu site com HTTPS. O problema de usar apenas HTTP e porta 80 é que seu site ficará inseguro. Se você estiver acessando-o usando um Wi-Fi público, uma pessoa mal-intencionada no mesmo Wi-Fi com um laptop e software de hacking prontamente disponível pode espionar sua conexão e roubar suas credenciais de login do Jenkins.
Se você quiser evitar o risco de segurança do HTTP não criptografado, pule para a próxima seção sobre como configurar HTTPS para Jenkins. Caso contrário, continue lendo.
Habilitar o acesso HTTP inseguro ao Jenkins é tão fácil quanto emitir os seguintes comandos:
33
Em seguida, você pode inserir seu nome de domínio em seu navegador favorito e o Jenkins Introdução página deve aparecer. Pelo menos no Google Chrome, o aviso “Não seguro” será exibido na barra de endereço, conforme mostra a imagem abaixo.
Vá para a seção Configurando o Jenkins seção se você estiver satisfeito com isso.
Jenkins sobre HTTPS seguro
Ter um site inseguro e acessível ao público é um enorme risco de segurança. Jenkins pode acessar seu código-fonte, assim como qualquer hacker que invadir o servidor com sucesso. Felizmente, proteger o site está a apenas alguns comandos copiados e colados.
Jenkins não consegue lidar com HTTPS sozinho. Portanto, temos que instalar um servidor web genérico para redirecionar as solicitações que chegam pelo canal seguro para o servidor Jenkins inseguro. Usarei o Nginx, que é um dos servidores web gratuitos e de código aberto mais populares da atualidade.
Emita o seguinte comando para instalar e iniciar o Nginx:
41
Então precisamos abrir as portas HTTP e HTTPS no firewall. Estaremos atendendo apenas solicitações HTTPS, mas também precisamos manter a porta HTTP aberta porque configuraremos o Nginx para redirecionar todas as solicitações inseguras para a porta segura.
Estes comandos abrirão o firewall para tráfego da web:
59
A próxima etapa é instalar um certificado que os navegadores da web possam usar para certificar que é o seu site com o qual estão interagindo e não um impostor. Usaremos a autoridade de certificação gratuita Let’s Encrypt para proteger nosso site. As etapas individuais são complicadas, mas, felizmente, o certbot fornece um script que pode fazer isso automaticamente.
Baixe e prepare o script com os seguintes comandos:
62
Em seguida, execute o script, que instalará o certificado e fará as alterações necessárias no arquivo de configuração do Nginx:
À medida que o script é executado, ele solicitará informações. Responda afirmativamente (Sim, Aceitar) a todas as perguntas até ser solicitado a escolher se deseja ou não redirecionar o tráfego HTTP para HTTPS. A listagem abaixo mostra as perguntas e minha resposta sugerida (2). Permitir que o Nginx redirecione solicitações inseguras garante que ninguém possa inserir explicitamente http:// seusite.com e acesse a versão insegura do Jenkins. O Nginx irá redirecioná-los para a versão segura.
74
Finalmente, você deve habilitar um cron job para renovar o certificado periodicamente. Caso contrário, ele expirará e os navegadores se recusarão a abrir o seu site.
Emita o seguinte comando de uma linha para adicionar o cron job diário:
81
O daemon cron executará o script de renovação diariamente à meia-noite. Você pode listar os cron jobs com o crontab -l comando e edite-os com o crontab -e comando. Se você visitar seu site agora, verá a página de teste do Nginx, e não do Jenkins. Corrigiremos isso em breve, mas certifique-se de que o aviso “Não seguro” tenha desaparecido da barra de endereço do Chrome, como mostra a imagem abaixo.
Para fazer o Nginx servir Jenkins, você precisa fazer algumas alterações no /etc/nginx/nginx.conf arquivo. O crédito por este trecho de código vai para o blog de Kerren no Medium. Usar o editor nano é provavelmente a maneira mais fácil de editar o arquivo de configuração:
91
Localize o bloco do servidor que lista seu nome de domínio e adicione as linhas destacadas da listagem abaixo ao seu arquivo nginx.conf. Observe que a primeira das três novas linhas vai acima do bloco do servidor e o restante vai para o bloco de localização raiz.
Depois de atualizar o arquivo de configuração, você precisa recarregar o Nginx para que as alterações tenham efeito. Opcionalmente, você pode testar o arquivo de configuração antes de recarregar usando o comando:
O Nginx imprimirá OK ou informará em qual linha do nginx.conf arquivo o erro é. Quando estiver satisfeito com as alterações, você pode recarregar o servidor web dando o seguinte comando:
Ao visitar o site do Jenkins em seu navegador, você deverá ver a página de primeiros passos do Jenkins, conforme mostrado na imagem abaixo. Desta vez, ele é servido por meio de uma conexão segura e podemos continuar a configurar o Jenkins com segurança a partir da interface web GUI.
Configurando o Jenkins
Na primeira vez que você visitar o site Jenkins, ele solicitará uma senha encontrada em um arquivo no sistema de arquivos Linux. Enquanto estiver logado via SSH, use o comando abaixo para mostrar a senha. Copie e cole no navegador para obter acesso à GUI da web:
108
Na próxima tela, Jenkins perguntará se você deseja instalar os plugins sugeridos ou se deseja especificar quais instalar. Basta ir com Instalar plug-ins sugeridos opção por enquanto. Você sempre pode adicionar ou remover plug-ins posteriormente.
Na próxima página, você deve criar um usuário administrador. Preencha seus dados e crie uma senha forte para usar com sua nova conta. Por padrão, apenas usuários logados podem acessar o servidor Jenkins. Usuários anônimos só verão a caixa de diálogo de login se se aventurarem no seu site. A única razão pela qual você poderia acessar meu *site de demonstração jenkins.vhdlwhiz.com é que fiz alterações no servidor. Usei o plugin Matrix Authorization Strategy para conceder acesso anônimo a algumas visualizações.
* Atualização:retirei o site de demonstração do ar em 13 de maio de 2020
Quando o Jenkins terminar de instalar os plug-ins, você verá a mensagem “Jenkins está pronto!” mensagem, conforme mostrado na imagem acima. Clique no botão que o levará para a página de visão geral vazia de sua nova instalação do Jenkins.
Instalando plug-ins do Jenkins
A primeira coisa que você precisa fazer é instalar vários plug-ins. Jenkins possui um gerenciador de plug-ins integrado que você pode usar para instalar, atualizar e remover extensões. Você encontrará plug-ins que podem atender à maioria das suas necessidades. Basta usar a função de pesquisa no gerenciador de plugins quando precisar adicionar funcionalidades ao Jenkins.
Vamos instalar os plug-ins que usei ao configurar o servidor Jenkins de exemplo. Na barra lateral, escolha Gerenciar Jenkins->Gerenciar plug-ins->Disponíveis . Observe que nenhum plug-in é listado, a menos que você insira algo no campo de pesquisa. Depois de digitar, eles aparecerão.
Oceano Azul
O primeiro plugin que recomendo instalar chama-se Blue Ocean. Este plugin é uma modernização do fluxo de trabalho do Jenkins, bem como da interface do usuário. Ele também traz vários outros plug-ins úteis para que você não precise instalá-los individualmente. Procure por “oceano azul” no gerenciador de plugins e selecione-o para instalação, conforme imagem abaixo.
Na página de progresso da instalação que aparece depois de clicar em instalar, você tem a opção de selecionar Reiniciar o Jenkins quando a instalação for concluída e nenhum trabalho estiver em execução . Se você marcar a caixa ao lado, o Jenkins será reiniciado após a conclusão da instalação do plugin. Outra forma de reiniciar o Jenkins é fazer login no servidor via SSH e executar o seguinte comando:
116
Além da longa lista de outros plugins instalados pela Blue Ocean, não há nenhuma mudança perceptível à primeira vista. Mas haverá um novo item de menu na barra lateral, conforme mostrado na imagem abaixo. Quando clicado, você será direcionado para a GUI do Blue Ocean, que parece bem diferente da interface Normal Jenkins. Experimente!
Bolas Verdes
O próximo plugin que sempre instalo é puramente estético. O plugin Green Balls não requer nenhuma configuração. Basta procurar por “bola verde” no gerenciador de plugins e instalá-lo conforme mostrado na imagem abaixo.
Por padrão, Jenkins usa bolas azuis na página de visão geral para indicar que o status de um trabalho foi bem-sucedido. A razão tem algo a ver com o fato de o inventor do Jenkins ser japonês. Curiosamente, no Japão, a cor azul é intercambiável com o verde quando se trata de indicar um status OK. Mais sobre isso neste artigo, onde você poderá ouvir o autor explicar o motivo em primeira mão.
Usuários de muitas outras partes do mundo provavelmente prefeririam bolas de status verdes. Isso é facilmente corrigido pelo plugin Green Balls, conforme mostrado na imagem abaixo.
Plugin de localidade
O próximo plugin que instalei se chama Locale. Pesquise “localidade” em Disponível guia no gerenciador de plug-ins. Instale o plugin, conforme mostrado na imagem abaixo.
O plugin permite forçar o Jenkins a usar a mesma linguagem na GUI para todos os usuários. Por padrão, o Jenkins traduz a interface do usuário para o idioma que seu navegador está usando. Sou norueguês, mas prefiro Jenkins em inglês. A tradução foi um pouco inadequada. Além disso, é muito mais fácil procurar respostas em inglês no Google se você precisar descobrir como fazer algo no Jenkins.
Claro, depende inteiramente de você se deseja este plugin. Se você instalá-lo, você precisa navegar até Gerenciar Jenkins->Configurar Sistema e encontre a seção chamada Locale . Em seguida, você precisa digitar “en_US” (ou o idioma que desejar) e marcar a caixa abaixo para forçar esse idioma a todos os usuários, conforme mostrado na imagem abaixo. Não se esqueça de rolar até o final da página e clicar em Salvar .
O plugin final que você precisa para clonar minha configuração é o plugin Sidebar Link. Ele permite adicionar links personalizados à barra lateral do Jenkins. Iremos usá-lo mais tarde para adicionar um link para as versões do FPGA (bitfiles). Procure por “barra lateral” no gerenciador de plugins e instale o plugin, conforme mostrado na imagem abaixo.
Conectando Jenkins ao GitHub
Independentemente de o seu repositório ser público ou privado, você precisa conceder algumas permissões ao Jenkins na sua conta GitHub. Pelo menos se você quiser fazer isso da maneira mais fácil possível, deixe o plugin Jenkins GitHub gerenciar a interface com o GitHub para você. A Blue Ocean já instalou o plugin GitHub. Estas são as etapas para configurá-lo.
Primeiro, você deve instalar o Git em seu sistema. O plugin GitHub não precisa dele estritamente, mas quando você começa a trabalhar com trabalhos do Jenkins, você precisa dele. Emita este comando para instalar o Git no CentOS Linux:
Token de acesso pessoal no GitHub
Faça login no GitHub, clique na foto do seu perfil no canto superior direito, escolha configurações e vá para Configurações do desenvolvedor . Em seguida, escolha Tokens de acesso pessoal no menu da barra lateral esquerda ou clique neste link que o levará diretamente até lá.
Aqui, você precisa clicar em Gerar novo token , conforme mostrado na imagem abaixo. O GitHub solicitará sua senha mais uma vez. O que você está fazendo agora é essencialmente criar uma nova senha específica do aplicativo. Isso é melhor do que compartilhar sua senha real porque você pode revogá-la e limitar as permissões concedidas ao token. É o que faremos na página que se abre.
Depois de inserir sua senha, você precisa dar um nome ao token. O nome é só para você. Pode ser qualquer coisa, “Jenkins”, por exemplo. Então, você deve habilitar pelo menos o admin:org_hook , admin:repo_hook e repo permissões, conforme mostrado na imagem abaixo. Você pode deixar todas as outras caixas desmarcadas.
Finalmente, quando você clica em Gerar token , o código de acesso aparecerá. Você precisa copiá-lo antes de sair da página porque não é possível vê-lo novamente. Se você esquecer, exclua o token e recrie-o.
Inserindo as credenciais do GitHub no Jenkins
Depois de copiar o token, vá para Jenkins, selecione Gerenciar Jenkins->Configurar Sistema e encontre a seção chamada GitHub , conforme mostrado na imagem abaixo. No menu suspenso, selecione Adicionar Servidor GitHub->Servidor GitHub .
Na nova seção do GitHub Server que aparece, marque a caixa chamada Gerenciar ganchos . Ao fazer isso, o Jenkins instalará webhooks no GitHub para repositórios que você está monitorando. Veremos mais tarde que isso é particularmente útil porque os usaremos para acionar uma simulação ou construção no Jenkins quando um usuário enviar o código para o repositório GitHub associado.
Selecione Credenciais (Adicionar)->Jenkins depois de marcar a caixa, conforme mostrado na imagem abaixo.
Na janela que se abre, altere o Tipo menu suspenso para Texto secreto . Em seguida, cole o token de acesso pessoal que você gerou anteriormente no GitHub na seção Segredo campo. Escreva “GitHub” no campo ID e pressione Adicionar .
Finalmente, quando você voltar ao menu de configuração principal, após adicionar o texto secreto, selecione o novo GitHub chave das Credenciais menu. Em seguida, pressione Testar conexão para verificar se Jenkins pode se comunicar com GitHub usando o token de acesso. Se tudo correu bem, você deverá ver uma mensagem como a mostrada na imagem abaixo.
Certifique-se de rolar até o final da página e clicar em Salvar antes de sair da página de configuração.
Se você tiver problemas e acabar adicionando várias credenciais, poderá excluí-las acessando Gerenciar Jenkins->Gerenciar usuários e clique em seu nome de usuário. Agora, na barra lateral esquerda, haverá um item de menu chamado Credenciais . A partir daí, você pode visualizar e editar todas as chaves armazenadas pelo Jenkins.
Enviando e-mail do Jenkins
Vamos configurar o Jenkins para enviar e-mails automatizados quando algo quebrar em seu código. Para que isso aconteça, precisamos fazer algumas alterações no Manage Jenkins->Configure System menu.
A primeira coisa que você deve fazer é inserir o endereço de origem que Jenkins usará ao enviar e-mails automatizados. Encontre o endereço de e-mail do administrador do sistema campo na página de configuração e insira o endereço de onde você gostaria que o Jenkins enviasse.
Apenas uma observação rápida:é melhor inserir um endereço que termine com o nome de domínio Jenkins. Isso minimiza a chance de o e-mail acabar na pasta de spam. O servidor Jenkins não tem permissão para enviar e-mails em nome de outros domínios, mas a maioria dos serviços de e-mail aceita endereços de origem com o mesmo domínio do servidor de envio. Leia mais sobre isso neste artigo da Wikipedia. Na imagem abaixo, inseri um endereço de origem que termina com o mesmo domínio do servidor Jenkins.
Em seguida, precisamos dar ao Jenkins uma maneira de enviar e-mails. A maneira mais simples de fazer isso é instalar um servidor SMTP (correio) no VPS. Você pode fazer isso fazendo login e emitindo os seguintes comandos:
121
Depois de instalar o sendmail , volte para a configuração do sistema Jenkins e digite “localhost” no servidor SMTP campo, conforme mostrado na imagem abaixo.
Neste ponto, você também pode marcar a caixa para permitir o envio para usuários não registrados. Isso significa usuários que não possuem uma conta de usuário Jenkins. Posteriormente, configuraremos o Jenkins para enviar um e-mail a qualquer pessoa que enviar código defeituoso ao GitHub. Jenkins obterá o endereço de e-mail do culpado no GitHub, mas isso só funcionará se a pessoa tiver uma conta Jenkins correspondente ou se marcarmos esta caixa.
Por fim, você pode testar a configuração, conforme mostrado na imagem acima. Depois de pressionar Testar configuração , a mensagem “E-mail enviado com sucesso” deverá aparecer e o e-mail deverá chegar à sua caixa de entrada. Verifique sua pasta de spam se não receber o e-mail em cinco minutos.
Instalando Xilinx Vivado em modo lote
Estou usando o Xilinx Vivado para simular, compilar e implementar o código neste projeto de exemplo. O dispositivo alvo é o FPGA Xilinx Zynq-7000 na placa de desenvolvimento ZebBoard. Nesta seção mostrarei como instalar o Vivado no VPS usando a licença WebPACK gratuita.
O primeiro passo é baixar o Xilinx Unified Installer:Linux Self Extracting Web Installer, mostrado na imagem abaixo. Você precisará fazer login ou criar uma nova conta Xilinx para baixar o instalador.
Quando o download for concluído, você deverá copiá-lo do seu computador desktop para o servidor Jenkins. Se você tiver acesso a um shell Linux em sua área de trabalho, sugiro usar uma cópia segura de arquivo como no seguinte comando:
Antes de executar o instalador, você precisa instalar alguns pacotes para satisfazer as dependências do Vivado. Execute os seguintes comandos para fazer isso:
135
Em seguida, execute o instalador Xilinx Unified assim:
147
O arquivo .bin descompactará os arquivos de instalação em um novo diretório chamado Xil_installer . Se você receber o erro listado abaixo, é porque você não instalou o tar .
150
O instalador Xilinx Unified pode instalar muitas ferramentas Xilinx diferentes em seu sistema. Portanto, devemos executar o xsetup arquivo no Xil_installer diretório para especificar em qual software estamos interessados:
167
O xsetup script solicita quais ferramentas você gostaria de ter. Digite “2” para Vivado e depois “1” para Vivado HL WebPACK , conforme mostrado na listagem abaixo.
170
Para instalar a edição Xilinx WebPACK, você deve fazer login em sua conta Xilinx durante a instalação. Em um computador desktop, a GUI do instalador orienta você nesse processo, mas no servidor não há GUI, então temos que autenticar usando o xsetup roteiro. Execute o seguinte comando para gerar o token de autenticação:
Tive que executar o comando algumas vezes antes de funcionar. A princípio, o script parava com o erro “Conexão com a Internet validada, pode conectar-se à Internet”. No entanto, depois de algumas tentativas, consegui entrar e consegui fazer login. O script solicitará seu ID de usuário e senha. Esse é o e-mail e a senha que você usou para baixar o instalador em xilinx.com.
Finalmente, você está pronto para instalar o Vivado em modo batch. Ao chamar o script de configuração, você deve especificar o arquivo de configuração de instalação para que xsetup sabe quais ferramentas baixar. O arquivo de configuração está em .Xilinx pasta no diretório inicial do usuário root. Execute o seguinte comando para iniciar a instalação usando o arquivo de configuração:
187
O processo de instalação levará muito tempo para ser concluído. A instalação do Vivado utiliza 24 GB de espaço. Tudo isso agora está sendo baixado do servidor Xilinx relativamente lento. Para mim, o download demorou pouco mais de duas horas.
Após a conclusão da instalação, você deve testar se o Vivado inicia com sucesso no modo em lote. Xilinx fornece um script de shell que configura o ambiente para você. Antes de executar o Vivado, você precisa usar o fonte comando para carregar o conteúdo do script em seu shell ativo:
198
Então, você está pronto para executar o Vivado. Mas não há ambiente GUI instalado em seu servidor, então temos que iniciá-lo em modo batch usando este comando:
If Vivado starts and exists immediately without printing any errors, it’s an indication that Vivado has everything it needs, and you are ready to go. Note that if you are getting the error listed below, it’s because you haven’t installed the ncurses-compat-libs package, as we talked about at the start of this section.
203Integrating Vivado in Jenkins
To prepare Jenkins for Vivado, we need to make some changes to the general settings. Head to Manage Jenkins->Configure System and check that all the default settings make sense for you.
As I mentioned earlier, Vivado uses a lot of RAM. The resource usage depends on your target FPGA, and you can get an indication of how much you need from the Xilinx Memory Recommendations page. Therefore, I recommend that you change the default number of parallel jobs that can run from 2 to 1. Unless you allocated vast RAM resources on your VPS, you probably want to set # of executors to 1, as shown in the image below.
Instead of defining the environment variables in every Jenkins job, we will specify the PATH globally for all jobs. That makes it easier for you to swap to a newer version of Vivado in the future. Then you can refer to the ‘vivado’ executable in your scripts, and it will always point to the latest version, or whichever you decide.
Scroll to the Global properties section and check Environment variables . Click Add to get a new entry. Make sure to include the standard Linux PATH também. I used “PATH=/tools/Xilinx/Vivado/2019.2/bin:/sbin:/usr/sbin:/bin:/usr/bin”, as shown in the image below.
Don’t forget to scroll to the bottom of the page and click Save .
Vivado GUI projects in batch mode
I chose to manage the Vivado projects in GUI mode. For each repository, I created a new project from within the regular Vivado GUI, adding source files, setting libraries, and all of that. However, the .xpr project files are binary and depend on a lot of other temporary files in the project directory.
Binary files are not suitable for SCMs like Git. Fortunately, Xilinx has thought of this and written a guideline (XAPP1165) for how to use Vivado with version control systems. What we do is to use the write_project_tcl command in Vivado to export the entire project into a Tcl script. The script contains human-readable Tcl code suitable for Git.
I’ve organized all of the Git repos so that all files that belong to the Vivado projects are in a subfolder named “vivado”, while the VHDL source files are in the parent directory. Check out the demo packages project on my GitHub to see what I mean. For each repo, we will put the Vivado Tcl scripts in the vivado pasta. You will also find the create_vivado_proj.tcl file, which is the human-readable version of the Vivado project.
To create the create_vivado_proj.tcl file, start by setting up the Vivado project as you wish in the Vivado GUI. Make sure that the Vivado project resides within a vivado subfolder. When you’re happy with the project, export it by entering the following commands in the Vivado Tcl console:
216
Add the create_vivado_proj.tcl file to Git, and set up the gitignore to ignore the rest of the Vivado project. Here’s the content of my .gitignore file which ignores everything but Tcl scripts in the vivado folder:
Opening the Vivado project in batch mode
It’s a good idea to test the Vivado project manually on the VPS before you start creating Jenkins jobs. By default, the daemon runs from a user account named jenkins on the Linux server. Therefore, you should test the Vivado project using the jenkins user.
Make sure that you have Git installed on the Linux server before you start this experiment. Run this command to install Git after logging in as root:
You can’t log in to the jenkins user directly, but you can change to it from the root user like this:
If you now run a pwd command, you will see that you are at /var/lib/jenkins :
226
That’s because this isn’t a regular user account that has the home directory under /home , as is the norm on Linux systems. It’s only for running the Jenkins daemon, but we can log in to perform a manual walkthrough of the build process in the Jenkins environment.
The home folder is full of all the dynamic data like logs, user settings, and plugins that you have downloaded. When we later start running jobs in the Jenkins GUI, they will appear in the jobs pasta.
Let’s go to the jobs folder to perform our experiment:
234
You can clone your Git repository directly into the jobs pasta. Your Git repo has to be accessible without using a password. Either because it’s public, or because you have set up passwordless login as described on the GitHub help pages.
If you don’t have a Git repository with the Vivado project ready, feel free to clone one of my repos like this:
248
Then, cd into the new directory of the Git repository, and further into the vivado folder:
257
If you downloaded my example, you would find two Tcl files:create_vivado_proj.tcl and check_syntax.tcl . The first one is the Vivado project converted to a Tcl file, and the second one is a script that we haven’t talked about yet. It’s for checking the syntax of VHDL files in the Vivado project.
Before we can run any Vivado command, we need to set the PATH environment variable in the current shell. In Jenkins, we solved this by using Global properties , but now we are not coming through Jenkins, so we have to source the setup script from Xilinx like this:
262
Now that the vivado executable is in our path, let’s start by recreating the project. This is the command for doing that when running Vivado in batch mode:
276
After you hit Enter, you should see a whole lot of Tcl code echoed to the console. It’s the code for recreating the Vivado project that’s executing. If you didn’t see any obvious errors, type the command “echo $?” in the terminal before you do anything else. The output should be 0 if everything went well, as we can see from the listing below.
281
The “echo $?” command shows you the exit status from the previous command that you executed in Linux. An exit status of 0 means that everything is OK, no error. Any other exit status than 0 is an indication of error. Those are old Unix conventions that you can read more about here. Anyway, the exit status is important for Jenkins because that’s how it decides if a job stage is a success or a failure.
If you now do a directory listing, you will see that Vivado has recreated the project’s binary files:
292
Let’s try another experiment with running Tcl scripts in Vivado batch mode. Create a one-liner Tcl script by using the following command:
Now, run the script in Vivado batch mode:
301
After Vivado closes, check the exit code once more using the “echo $?” command:
313
It’s 1, which means exit failure in Unix. If you change the content of the test.tcl script to “exit 0”, and run Vivado once again, you will see that the exit status is now 0, indicating success. Experimente!
The exit keyword is standard Tcl. We are going to use it as the interface between Vivado and Jenkins. Jenkins runs whatever Tcl script we create in Vivado, and looks at the exit status to determine if it shall mark the job stage as success or failure.
Remember to delete our little test project from the jobs folder when you are happy with the experiment:
324Tcl script for checking code syntax in Vivado
This Tcl script runs a syntax check of the VHDL files in the project. If you are going to simulate or implement the code, you won’t need this script because any syntax errors will break the compilation. But for my packages project, it doesn’t make any sense to create a testbench for it. The files just contain constant and types declarations. I still want to catch any coding errors pushed to this repo, and that’s where the syntax check comes in handy.
In the script that is listed below, we start by opening the project file. Then, we call the Vivado check_syntax command while telling it to save the output to a variable called msg . After the check has completed, we look at the output message to see if there were any errors reported. If check_syntax reported anything at all, we set the exit status to 1 (failure). If there were no errors, we exit 0 (success).
check_syntax.tcl:
337
Vivado supports all of the standard Tcl keywords, and there are also a lot of built-in commands like check_syntax. I recommend taking a look at these two Xilinx documents that cover the Tcl scripting capabilities in great detail:
Vivado Design Suite Tcl Command Reference Guide (UG835)
Vivado Design Suite User Guide Using Tcl Scripting (UG894)
Tcl script for simulating in Vivado
The next script that I created is for running the testbench in batch mode. For this to work, you have to configure the simulation sets in the Vivado GUI before you export the project to Tcl. Go ahead and recreate one of the simulation projects on your desktop computer using the create_vivado_proj.tcl script to see how I set it up beforehand. You can open the reconstructed projects in the Vivado GUI.
As you can see from the listing below, I start by opening the project. Then, I set the name of the simulation fileset to a variable (usually sim_1 ). After we launch the simulation, we also have to close it. Otherwise, the status of the simulation won’t get written to the log files.
run_simulation.tcl:
341
Now, I struggled to find a good way of getting the simulation status. My VHDL testbenches terminate on a VHDL finish keyword on success. Errors will result in a VHDL assertion failure. There’s no obvious way to find out why the simulator stopped by using Tcl commands in Vivado.
Fortunately, Tcl is a powerful scripting language. My workaround is to open the simulation log and look for the string “Failure:”, which indicates a VHDL assertion failure. Finally, we exit 1 if the word is in the log, or 0 if it isn’t.
Tcl script for synthesizing in Vivado
In the Tcl script for synthesizing in Vivado batch mode, we start by opening the project file. Then, We assign the run name to a variable. You must have added the design files to the Vivado project before you exported it to Tcl. If you didn’t change the name of the synthesis run in the GUI, it’s will probably be “synth_1”.
You should set the CPU count variable to the number of logical processors that your server has. This number controls the degree of multithreading that Vivado uses. I opted for the VPS with 4 CPUs on UpCloud, and therefore set the CPU count to 4.
run_synthesis.tcl :
351
The launch_runs command is non-blocking, meaning that it will complete before the actual synthesis. If we try to read the status right after calling launch_run , it will be “Running”. To pause the script until the synthesis completes, we call the wait_on_run command.
Finally, we get the run status and exit 0 or 1, depending on the status message.
Tcl script for running the implementation in Vivado
The script for running Place and Route (PAR) in Vivado batch mode is similar to the synthesis script. The difference is that the run name is now “impl_1”, and that we are looking for another success message.
run_implementation.tcl :
363Tcl script for generating the bitstream in Vivado
Finally, after if the implementation completes successfully, we can generate a bitstream for programming the FPGA. The script is similar to the previous one, but the launch_runs command is slightly different. And of course, we are looking or a different status in the end.
generate_bitstream.tcl :
375Setting up the Jenkins jobs
A job in Jenkins refers to a set of grouped software tasks. Jenkins displays jobs and their current status as items listed on the overview page. You can start jobs manually from the web interface, or they can be triggered automatically, for example, when someone pushes code to a repo, or as a result of another job completing. We will do both.
Jenkins offers several ways of managing jobs. The traditional method is the Freestyle project , where you specify every action from within the Jenkins web GUI. The more modern way of managing Jenkins jobs is to use a pipeline script that stores all of the information about the execution flow. The pipeline scripts have the benefit that you can add them to your SCM.
To create a new pipeline script, select New item from the Jenkins sidebar. In the dialog that opens, select the Pipeline option and click OK, as shown in the image below.
The first thing we have to do in the job configuration is to add the GitHub repository that contains the source code. In this example, I am using the packages repo, but the procedure is the same for all the other jobs and repos. Check the GitHub project box and enter the address in the Project url field that appears, as shown in the image below.
After that, we can set up the build triggers for this job. I want this job to start when someone pushes code to the GitHub repo. To do that, we check the box that says GitHub hook trigger for GITScm polling , as shown in the image below. Note that this will only work if you have checked the Manage hooks box in the global settings, as we did earlier.
At the bottom of the job configuration page is the Pipeline section. Here, you have to option to enter the pipeline script directly into the config page. But we want to version control the pipeline script. Therefore, we chose the Pipeline script from SCM opção. Make sure that Git is selected, as shown in the image below.
Paste in the URL of your GitHub repository, and select your credentials if it’s a private repo. Ours is public, so we will leave the credentials blank. We will also go with the default master branch selection.
Finally, we have to select the path to the Jenkins script within the Git repository. I have created a file named Jenkinsfile at the root of each repo. Don’t forget to click Save before you leave the page.
Jenkins pipeline scripts
Pipeline scripts follow the same syntax rules as the Apache Groovy programming language, which I must admit I had never heard of before. Nevertheless, you won’t have a hard time understanding pipeline scripts if you’ve done any kind of modern programming. At first glance, it looks like a JSON schema without the commas separating the data items.
The scripts are quite versatile, and there are many options for things like executing stages in parallel or running tasks on multiple Jenkins servers. I suggest that you take a look at the official Jenkins pipeline documentation if you want to dig deeper into the matter.
Fortunately, you don’t need to know everything about them to benefit from pipeline scripts. We will use the format below as a template for all of your scripts. We will add as many stages as we need to split the job into logical steps.
384
If somebody pushes faulty code to the repo, we want the culprit to receive an automated email with information about the failed job. To do that, we use a failure section within a post section. This part of the script will only execute if any of the stages fail. Then, the job will stop. Jenkins won’t go to the next stage if one fails. Instead, it will jump into the failur e section. Jenkins then lifts the email addresses from the latest Git commits and sends them an email with a link to the broken build.
VHDL syntax checking job
The only repo in our design that doesn’t have a testbench is the packages repo—instead, we user our check_syntax.tcl script to verify that the code is at least valid VHDL.
In the first step of our pipeline script, we call deleteDir() . That’s one of the basic commands available in Jenkins pipeline scripts. It cleans the working directory by removing any leftover from previous builds.
On the next line, we call git . Note that this is not the git Linux command, but a command referencing the git Jenkins plugin. We tell it to clone the repository into the workspace.
Finally, on the third line of the Create project stage, we use the sh keyword to call a Linux shell command. Here, we change to the vivado directory and run the create_vivado_proj.tcl script in Vivado batch mode to recreate the Vivado project.
Jenkinsfile:
390
In the second stage, the one named Check VHDL syntax , the Vivado project already exists, so we can jump to running our Tcl script. We use the shell command again to run the check_syntax.tcl file, which will exit 0 on success, or 1 on error, causing Jenkins to mark the build as a failure.
VHDL simulation jobs
For all other jobs than the packages repo, the git one-liner command won’t work for checking out the code from GitHub. The problem is that these repos have dependencies in the form of submodules. The submodules reference other Git repositories, which the simple git command doesn’t pull by default. But that’s OK; we can fix the issue by using the more versatile checkout call, also well-documented on the Git plugin page.
Jenkinsfile;
403
Finally, we run the run_simulation.tcl script in Vivado in the next stage.
The above listing shows the script used in the bcd_encoder repo. Identical scripts, only with different repo URLs, are used for the counter, digit_selector, output_mux, reset, and seg7_encoder repos as well.
FPGA implementation job
The seg7 repo contains the top module for our FPGA project. It pulls in all of the other repos as submodules. The pipeline script is similar to the one used for the simulation-only jobs, but with four added stages:Run simulation , Run implementation , Generate bitstream , and Release bitfile .
The first two stages create the project and run the simulation. I have already covered how they work in the previous sections of this article. The next three stages work the same way as the simulation stage, but with the Tcl script replaced with the ones that are relevant for the task.
Jenkinsfile:
416
The final stage of the implementation job is named Release bitfile . It contains a shell script that copies the newly generated FPGA programming file to a release folder. The shell command renames the file to include the name of the project and a timestamp.
To maintain traceability, we also generate a text file that contains the Git hash of the main repo (seg7 ) and all of the submodules. When working with Git submodules, it’s not enough to store the hash of the main repo. To generate a hash for the main repo that includes changes in all submodules, we would have to commit the main repo after pulling and updating all submodules. We don’t want to do that automatically from Jenkins.
Note that implementing the FPGA for every single push, like I am doing in the example, is probably not what you want for a real-life Jenkins project. It can take hours to build a large-scale FPGA project, and that wouldn’t work when you have a team of developers pushing multiple times per day. Instead of building after each push to the repo, you can configure Jenkins to route the FPGA only once a day. For example, at midnight, as shown by the screenshot below from the job configuration page.
Triggering builds after other jobs complete
Our example project consists of several Git repositories, but they are all tied together as Git submodules. Except for packages, all the other repos depend on at least one other repository. Most depend on the packages repository. Have a look at the dependency graph that I presented earlier in this article to see how it all fits together.
Therefore, we should trigger jobs not only by pushes to the repo in question but also after any of the submodules are touched. We can achieve this in Jenkins by visiting every job and setting the Build after other projects are built option accordingly.
The image below shows the trigger for the bcd_encoder project. It will start after the packages repo, which it depends on, completes a build successfully.
The top module depends on all other repos. I have added them as watch projects in a comma-separated list, as shown in the image below. Note that you may not want to do this for the FPGA implementation job if it takes a long time to route, as I mentioned in the previous section.
Serving the bitfiles using Nginx
Since we already have a web server running, we can use if for serving the release files over HTTP. I want all new bitfiles to appear on the URL jenkins.vhdlwhiz.com/releases . Let’s see how we can use Nginx for this.
Our implementation job already copies new bitfiles to a directory on the Nginx HTML root, but we haven’t created it yet. Create the release dir and give the Jenkins user write permissions by issuing the following commands:
420
Then we have to make a change to the /etc/nginx/nginx.conf arquivo. Find the server section in the config file with a name equal to your domain. Add the following location section inside of it, directly below the root (‘/’) location section:
434
Finally, after you have saved the file, test the configuration file, and reload the Nginx server:
443
If everything worked, you should be able to list the content of the release directory, as shown in the screenshot below from Google Chrome.
To tie the Jenkins web interface to the release dir, I want to create a link to if from the Jenkins sidebar. We have already installed the Sidebar Link plugin that enables custom links in the sidebar.
The next step is to go to Manage Jenkins->Configure System and scroll down to the Additional Sidebar Links section. Here, we can specify the name and URL of the new link, as shown in the image below. The link icon field is optional. I reused one of the icons that came with the Jenkins server.
After completing the previous step, you should now have a custom link to the bitfile releases in the sidebar, complete with a nice-looking folder icon, as you can see from the image below.
Resumo
Jenkins can be a valuable tool also for FPGA teams. Automating tasks can save your company time and improve the quality of your code. By using automatic build triggers and automated job pipelines, fewer coding errors will go unnoticed.
As we have seen from the example project presented in this article, Jenkins can implement a complete suite of regression tests for your VHDL code. It shows the current health of your project in a pleasant graphical web interface, suitable for even the most VHDL-illiterate project manager.
If you wish to try out Jenkins for FPGA development, I recommend following the steps in this article on an UpCloud VPS instance. I thoroughly researched all VPS providers a few years ago before moving VHDLwhiz to a VPS. I found that UpCloud was the fastest and best alternative. I’m still 100% pleased with the service.
If you decide to open an account on UpCloud, I kindly ask that you use my referral link or code:NV78V6 . Not only do you support VHDLwhiz, but you also get $25 of credit on UpCloud when using the promo code.
Como visualizar variáveis VHDL no Modelsim durante a simulação Controlador de display duplo VHDL de 7 segmentos para SSD Pmod – Fácil integração com FPGA
VHDL
- Como visualizar variáveis VHDL no Modelsim durante a simulação
- Controlador de display duplo VHDL de 7 segmentos para SSD Pmod – Fácil integração com FPGA
- Como usar uma função em VHDL
- Como usar um while-loop em VHDL
- Gerar exemplo de debouncer de declaração
- Imagem de bitmap de arquivo BMP lida usando TEXTIO
- Como instalar um simulador e editor VHDL gratuitamente
- Como usar assinado e não assinado em VHDL
- Tutorial:Seu primeiro programa FPGA:um LED piscando
- Exemplos de conversões de VHDL