Introdução à ferramenta de gerenciamento `hdlmake`

Posted on dom 13 fevereiro 2022 in sistemas digitais • 6 min read

O desenvolvimento de projetos de hardware cresce em complexidade rapidamente, dada tanto a necessidade de se descrever sistemas empregando uma semântica de mais baixo nível do que linguagens de programação de software quanto a ausência de abstrações organizacionais de alto nível, como classes. De fato, é usual a complexidade ser tão maior quão maior o uso de boas práticas pelo projetista (por exemplo, criando componentes modularizados e testbenches para cada componente). Além disso, a presença de diversas ferramentas de análise, simulação e síntese, bem como de seus respectivos arquivos de configuração, podem dificultar a análise e iteração rápida sobre descrições mesmo de complexidade baixa. Como exemplo, uma implementação parcial de um jogo da memória desenvolvido para a disciplina de Laboratório Digital 1 já possuía 20 arquivos de descrição de hardware - entre descrições de componentes e testbenches - e empregava três ferramentas distintas: ModelSim e Questa Intel FPGA para simulação e Quartus Prime Lite para síntese.

Assim, percebe-se a necessidade de se organizar e de se fornecer uma interface comum pela qual diferentes ferramentas possam ser empregadas de forma transparente em projetos de hardware. Nesse contexto, o hdlmake se mostra uma ferramenta útil e poderosa para o desenvolvimento de projetos de médio porte, fornecendo uma estrutura organizacional clara a ser seguida por projetos e uma interface extensível de configuração e geração de Makefiles para o desenvolvimento completo do ciclo de vida de um sistema digital.

O hdlmake é uma ferramenta de linha de comando desenvolvida em Python pelo CERN sobre a licença GPLv3 de código aberto. Sua utilização é baseada na escrita de arquivos de configuração (todos com o nome Manifest.py, porém em diretórios diferentes) que são processados pela ferramenta para gerar Makefiles que realizam simulação ou síntese com algum das diversas ferramentas suportadas, representadas na tabela abaixo. O sistema é capaz de processar dependências entre descrições de hardware que combinam mais de uma linguagem de descrição, bem como gerenciar módulos externos hospedados em repositórios Git ou SVN.

Ferramenta Síntese Simulação
Xilinx ISE Sim -
Xilinx PlanAhead Sim -
Xilinx Vivado Sim Sim
Altera Quartus Sim -
Microsemi (Actel) Libero Sim -
Lattice Semi. Diamond Sim -
Project IceStorm Verilog -
Xilinx ISim - Sim
Mentor Graphics Modelsim - Sim
Mentor Graphics Questa - Sim
Aldec Active-HDL - Sim
Aldec Riviera-PRO - Sim
Icarus Verilog - Sim
GHDL - VHDL

A organização do hdlmake empregada no jogo de memória, representada abaixo, será utilizada como exemplo neste relatório; ela emula aquela presente na documentação e nos casos de teste presentes no repositório da ferramenta.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
.
├── README.md
├── modules
   ├── Manifest.py
   ├── comparador_85.vhd
   ├── contador_163.v
   ├── edge_detector.vhd
   ├── fluxo_dados.vhd
   ├── hexa7seg.vhd
   ├── ram_16x4.vhd
   ├── ram_conteudo_jogadas.mif
   ├── registrador_173.vhd
   └── unidade_controle.vhd
├── simulation
   ├── Manifest.py
   └── write_vsim_do.py
├── software
├── synthesis
   └── Manifest.py
├── testbenches
   ├── Manifest.py
   ├── circuito_exp3_tb.vhd
   ├── comparador_85_tb.vhd
   ├── contador_163_tb.v
   ├── fluxo_dados_tb.vhd
   ├── ram_16x4_tb.vhd
   ├── registrador_173_tb.vhd
   ├── unidade_controle_tb.vhd
   └── utils.vhd
└── toplevel
    ├── Manifest.py
    ├── circuito_exp3.csv
    ├── circuito_exp3.vhd
    └── plan_pins.py

Instalação

O hdlmake é publicado no Python Package Index e pode ser instalado como outras bibliotecas pelo gerenciador de pacotes pip por meio do comando python -m pip install hdlmake em uma instalação de Python com versões superiores à 2.7. É necessário adicionar o caminho de instalação da ferramenta (em sistemas Unix, geralmente $HOME/.local) à variável de ambiente PATH para ser possível chamar o hdlmake diretamente da linha de comando como exemplificado neste documento.

Configuração

Toda a configuração do hdlmake é realizada a partir de arquivos Manifest.py, que permitem não só adicionar configurações, mas também lógica condicional sobre essas configurações. Os arquivos presentes nos diretórios modules, testbenches e toplevel são simples e somente listam os arquivos presentes no diretório e os diretórios em que suas dependências residem. O arquivo do diretório toplevel é reproduzido abaixo como exemplo.

1
2
3
4
5
6
7
8
9
files = [
    "circuito_exp3.vhd"
]

modules = {
    "local" : [
        "../modules"
    ],
}

Ele mostra que o diretório possui o arquivo circuito_exp3.vhd como descrição de hardware a ser analisada, cujas dependências se encontram em diretório local (isto é, no sistema de arquivos local e não em um repositório Git ou SVN remoto) denominado modules, visível na estrutura de pastas representada anteriormente.

O controle dos processos de simulação e síntese é realizado por meio dos Manifest.pys de seus respectivos diretórios, e exigem um detalhamento maior para entender seu funcionamento.

Em primeiro lugar, as configurações de simulação são analisadas; elas estão reproduzidas a seguir.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
TOPLEVEL = 'fluxo_dados'
VCD_NAME = TOPLEVEL
VIEW_WAVE = False # TODO fix; does nothing

###################################################

action = "simulation"
sim_tool = "modelsim"
sim_top = TOPLEVEL + "_tb"

sim_pre_cmd = "python write_vsim_do.py " + VCD_NAME+" "+str(VIEW_WAVE)
sim_post_cmd = "vsim -do vsim.do -i " + sim_top

modules = {
    "local" : [
        "../testbenches/",
    ],
}

As variáveis requisitadas pelo hdlmake estão abaixo da linha com #, e indicam que o Manifest.py desse diretório foi configurado para realizar simulação (action = "simulation") usando o ModelSim (sim_tool = "modelsim"). Como o arquivo de configuração é escrito na linguagem Python, podemos realizar operações geralmente não possíveis em arquivos de configuração usuais. Como exemplo, o nome da entidade toplevel de simulação é designado como a concatenação da variável TOPLEVEL e a string _tb. As diretivas sim_pre_cmd e sim_post_cmd designam comandos arbitrários de linha de comando que podem ser executados antes e depois da realização da simulação, respectivamente. Nesse caso, antes da simulação, é executado o script Python write_vsim_do.py que gera o arquivo vsim.do, escrito pelo grupo para gerar arquivos VCD automaticamente da simulação; os comandos nesse arquivo são então executado após a simulação.

Em segundo lugar, as configurações de síntese são analisadas; elas estão reproduzidas a seguir.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
PROCESS_PINS = True

TOPLEVEL = "circuito_exp3"
PINS_CSV = "../toplevel/circuito_exp3.csv"
PINS_READ_MODE = "quartus"

############################################

target = "altera"
action = "synthesis"

syn_family = "Cyclone V"
syn_device = "5ceba4"
syn_package = "f23"
syn_grade = "c7"
syn_top = TOPLEVEL
syn_project = TOPLEVEL
syn_tool = "quartus"

if PROCESS_PINS:
    syn_pre_project_cmd = "python ../toplevel/plan_pins.py "+TOPLEVEL+" "+ PINS_CSV+" "+PINS_READ_MODE
    syn_post_project_cmd = "quartus_sh -t pins.tcl compile "+TOPLEVEL+" "+TOPLEVEL
syn_post_bitstream_cmd = "quartus_sh --archive "+TOPLEVEL

modules = {
    "local" : [
        "../toplevel"
    ],
}

As variáveis requisitadas pelo hdlmake estão abaixo da linha com #, e indicam que o Manifest.py desse diretório foi configurado para realizar síntese (action = "synthesis") para uma placa da Altera (target = "altera") com FPGA Cyclone V de modelo 5CEBA4F23C7 (linhas 12 a 15) utilizando o Quartus Prime Lite (syn_tool = "quartus"). Na síntese, existem mais diretivas do que na simulação. Podem ser executados comandos imediatamente antes ou depois da criação do projeto do Quartus Prime Lite ou do final da síntese. No arquivo de configuração empregado, antes da criação do projeto, é executado um script Python que gera um arquivo pins.tcl, o qual é executado após a criação do projeto para designar os pinos configurados segundo o arquivo CSV fornecido no diretório toplevel; ainda é executado, ao final da síntese, um comando para gerar automaticamente o arquivo QAR de arquivamento do projeto.

Uma descrição mais extensa das diretivas e possibilidades de configuração, além das empregadas neste projeto, pode ser encontrada na documentação do hdlmake.

Execução

Uma vez configurado, o hdlmake permite a execução das diretivas especificadas para simulação e síntese de forma simples por sua interface de linha de comando. O procedimento explicado a seguir é idêntico tanto para síntese quanto para simulação, reforçando o valor de se possuir uma interface única para gerenciar projetos de hardware.

É necessário primeiramente navegar à pasta que contém o Manifest.py de simulação ou síntese. Em seguida, o comando hdlmake makefile deve ser executado, gerando um arquivo Makefile que executa a ação pedida; é necessário se atentar aos avisos impressos no terminal nesse passo, já que podem indicar erros de configuração. Tendo o Makefile correto, basta executar make para que todas as ações necessárias sejam tomadas e os comandos especificados sejam executados. Um exemplo dessa execução para o projeto do jogo de memória está ilustrado nas figuras abaixo.

Aqui um exemplo de como é simular usando o hdlmake, nesse caso com o simulador Questa Intel FPGA:

Simulação no projeto de exemplo usando hdlmake

E aqui um exemplo de síntese com o Quartus Prime Lite:

Síntese do projeto de exemplo usando hdlmake

### Contribuições * 13/fev/2022: Tomaz Maia Suller escreveu este post.