90% dos meus designs em VHDL seguem um padrão, eles tem uma máquina de estados, dois processes sendo um para a parte combinacional e outra para a parte sequencial do design, bibliotecas básicas de aritmética (numeric.std) e lógica (1164) a parte combinacional recebendo a sequencial e etc. Esse estilo de codificação segue muito do que o Pong. P Chu propõe em seu livro RTL Hardware Design using VHDL. E quando algo é padrão nada melhor do que fazer um script para diminuir a parte burocrática de escrever um novo módulo em VHDL e ir direto ao que interessa.
Para ficar simples me limitei a geração automática da interface da entidade (sinais de entrada/saída), maquina de estados, processo combinacional e sequencial e registradores a partir de um arquivo .txt.
Pensei em automatizar muita coisa mas a complexidade tanto do .txt responsável por gerar o VHDL quanto a do software em Python iria aumentar muito e não ficaria mais algo simples de se utilizar, perderia o "charme".
Funcionamento
A sintaxe do arquivo .txt é bem simplificada, a primeira linha é o nome do projeto, a segunda o clock e a terceira o reset. As demais linhas são sinais de entrada ou saída da entidade até chegar no "#" após o símbolo "#" as linhas viram sinais dentro do design.
Para rodar o script basta executar o arquivo vhdl_gen.py e passar o caminho para o arquivo .txt como parâmetro.
Exemplo
A partir deste arquivo blink_led.txt de 8 linhas:
blink_led
sysclk-in-1
reset_n-in-1
enable-in-1
leds-out-16
#
timer-16
leds-16
É gerado este arquivo .vhd de 74 linhas:
------------------------------------------------------
-- Name : aprado
-- Created at : 01-08-2013 12:01
------------------------------------------------------
--Libraries and use clauses
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity blink_led is
port (
sysclk : in std_logic;
reset_n : in std_logic;
enable : in std_logic;
leds : out std_logic_vector(15 downto 0)
);
end blink_led;
------------------------------------------------------
architecture rtl of blink_led is
type STATE_MACHINE_TYPE is (S0,S1,S2,S3);
attribute SYN_ENCODING : string;
attribute SYN_ENCODING of STATE_MACHINE_TYPE : type is "safe";
signal state : STATE_MACHINE_TYPE;
signal state_next : STATE_MACHINE_TYPE;
signal timer_reg : std_logic_vector(15 downto 0);
signal timer_next : std_logic_vector(15 downto 0);
signal leds_reg : std_logic_vector(15 downto 0);
signal leds_next : std_logic_vector(15 downto 0);
begin
-- Sequential process
process(sysclk, reset_n) is
begin
if (reset_n = '0') then
state <= S0;
elsif rising_edge(sysclk) then
timer_reg <= timer_next;
leds_reg <= leds_next;
state <= state_next;
end if;
end process;
-- Combinational process
process(state, timer_reg, leds_reg) is
begin
timer_next <= timer_reg;
leds_next <= leds_reg;
state_next <= state;
case state is
when S0 =>
null;
when S1 =>
null;
when S2 =>
null;
when S3 =>
null;
when OTHERS =>
null;
end case;
end process;
end rtl;
Conclusões
Em um livro que li devido a muitas recomendações (The Pragmatic Programmer) há capítulos dedicados a geradores de códigos e aos benefícios proporcionados ao utilizar um gerador de código, alguns deles:
- Expressar a mesma informação somente uma vez (DRY do not repeat yourself);
- Menor tempo de desenvolvimento pois não é necessário escrever tanto;
- Menos sucessível a erros de sintaxe;
- Padronização no código fonte de um projeto e etc.
Aliás também recomendo o livro, apesar de não ser direcionado a desenvolvedores de hardware ele possui uma linguagem muito boa e dicas gerais de desenvolvimento que também podem ser aproveitadas para o desenvolvimento de hardware.
Logo que comecei a desenvolver postei a ideia na lista sis embarcados do google (que aliás recomendo MUITO para qualquer um da área). O pessoal curtiu a ideia e falou para disponibilizar no GitHub para que a comunidade tivesse acesso e pudesse contribuir. Foi meu primeiro contato como desenvolvedor em um projeto Open Source e foi uma experiência MUITO legal! Agradeço ao Fabio, Vinicius e o Vitor pelas contribuições no projeto, que o deixaram muito melhor. Estou até procurando uns projetos para dar fork e contribuir.
E por último fica aqui o link para o gerador de VHDL feito em Python! Funciona em Windows e Linux, fiquem a vontade para usar, "forkar" e dar feedback. Recomendo ler o README com atenção.
https://github.com/andrecp/vhdl_gen/
Poxa André! Parabéns! Bastante interessante a sua padronização...
ResponderExcluirVocê já pensou, ou conhece, algum gerador de código automático de VHDL baseado em modelo? Especialmente baseado na teoria do controle supervisório (TCS)?
Parabéns pelo Blog!
Obrigado! Não conheço não, se quiseres discorrer mais sobre o assunto sinta-se a vontade. Quem sabe não pensamos em algo.
ExcluirMas a complexidade de fazer e utilizar o gerador tem que ser menor do que a de fazer o VHDL hehe.
abs