Um domingo com Verilog

Bom pessoal, estou oficialmente iniciando meus estudos numa nova HDL: o Verilog.
A um tempo atrás fiz um seminario sobre HDL onde eu mostrei algumas das mais conhecidas HDL's. Para quem tiver interesse os slides da minha apresentação estão aqui:

http://pet.inf.ufsc.br/node/265

Para quem não sabe, HDL significa Hardware Description Language, ou, Linguagem de Descrição de Hardware.
Elas servem, como o próprio nome sugere, para descrever hardware.
A algum tempo eu mencioneu a VHDL (VHSIC HDL ou Very Large Scalable  Integrated Circuit HDL) em dois dos meus posts:

http://tarcisiof.blogspot.com/2010/04/sistemas-digitais-vhdl-quartus-2.html
Onde eu declaro estar iniciando estudos na linguagem VHDL.

http://tarcisiof.blogspot.com/2010/04/vhdl-projeto-componentenbits.html
Onde eu comento sobre a criação de um componente N bits em VHDL.

Agora, estou tirando um tempo para aprender um pouco de Verilog, por, principalmente, 3 motivos simples:

  • Alguns amigos indicaram, dizendo que é mais simples de se trabalhar.
  • Aprender uma nova linguagem, já que verilog é, também, muito usada pelo mundo afora.
  • Pela diversão :D

Estou atualmente usando o Ubuntu Linux 10.04 (ainda não atualizei para o 10.10), para proceder com os testes eu instalei o iVerilog (Icarus Verilog) e o gtkwave. Para instalar esses programas pode-se usar o Synaptic do ubuntu
ou abrir o terminal, virar root e digitar:

apt-get install iverilog - Para instalar o Icarus Verilog
apt-get install gtkwave  - Para instalar o GTKWave

Para quem usa windows provavelmente o Altera Quartus ou o Xilinx Ise são boas opções. Existe uma versão gratuita para estudante de cada um deles.

http://www.altera.com/products/software/quartus-ii/web-edition/qts-we-index.html
http://www.xilinx.com/tools/webpack.htm

Finalmente, mãos a massa!
Estou usando gedit e/ou o vim para escrever os códigos.
Farei meu trabalho em dois posts, na tentativa de organizar as coisas.
Nesse, irei deixar registrado passo a passo de como criar um projeto da forma que eu achei mais simples e organizada.
Até porque, se daqui a uns dias eu esquecer, posso eu mesmo consultar meu post a fim de obter alguma ajuda.

Em primeiro lugar, criei uma pasta chamada PortasLogicas. Dentro dela criei os arquivos PortasLogicas.v e PortasLogicas_tb.v.
Onde .v é a extensão de um arquivo do verilog. PortasLogicas.v é a descrição do hardware em si e o PortasLogicas_tb.v é o "test bench" ("bancada de testes", daí o "tb") do hardware, onde iremos gerar algumas saídas de teste.

Importante dizer que, até agora, ao que me parece, as ferramentas que eu escolhi são meramente comportamentais, ou seja, não levam em conta o atraso das portas logicas. Portanto, não teremos como saber qual o atraso real dos sistemas digitais que criarmos. Até porque, não sabemos onde esse hardware vai ser colocado (FPGA?). Mas de qualquer forma, isso é um detalhe para o futuro.

Voltando ao PortasLogicas.v, nossa brincadeira vai ser simples: criar um pequeno componente que se comporta da seguinte forma:

Entradas: A e B
Saidas: C e D, onde C = "A ou B" e D = "A e B"
Obviamente estou contando que o leitor saiba o basico de lógica booleana, caso contrario, leia isso:
http://pt.wikipedia.org/wiki/L%C3%B3gica_bin%C3%A1ria

Para escrever o que queremos em Verilog, precisamos primeiro definir um "module":

module PortasLogicas(a, b, c, d);

Isso, até onde eu entendi, significa que temos um componente chamado "PortasLogicas" que conhece "a, b, c e d".
Agora, precisamos definir o que são a, b, c e d. Assim:

input a, b;
output c, d;
   
Ou seja, estamos dizendo que a e b são ENTRADAS do nosso componente e c e d são SAIDAS.
Devemos agora descrever o comportamento interno do componente, para que ele conheça que valores colocar nas saídas c e d:

assign c = a | b;
assign d = a & b;

c = a | b significa que c vai ter o valor do resultado da operação lógica "a ou b".
d = a & b significa que d vai ter o valor do resultado da operação lógica "a e b".

Finalmente, terminamos nosso "module" escrevendo:

endmodule

Pronto :)
O verilog completo está abaixo:

module PortasLogicas(a, b, c, d);
    input a, b;
    output c, d;

    assign c = a | b;
    assign d = a & b;
endmodule

Mas... E agora? Como sabemos se isso está funcionando?
Agora entra aquele outro arquivo, PortasLogicas_tb.v.
É nele que descreveremos a bancada de testes para esse componente.
É simples, iniciamos com:

module PortasLogicas_tb;

Então descrevemos as variaveis que vamos usar:

reg a, b;
wire c, d;

Fui obrigado a usar "reg" para a e b, para poder "jogar" valores na entrada do componente.
O Verilog não permite fazer a = 1 ou a = 0 num "bloco" quando se trata de um "wire".
Logo falarei sobre "blocos".
Continuando, temos:

PortasLogicas dut (a, b, c, d);

Que instancia um componente do "tipo" PortasLogicas (aquele que criamos agora a pouco) com o nome dut.
Dut significa "Device Under Test", me pareceu um padrão pelos sites que consultei na internet.
Dentro dos parenteses coloca-se, na ordem correspondente, as entradas e saidas do componente.
No caso, as entradas são meus "reg"s a e b e as saidas meus "wire"s c e d.
Agora criamos um bloco "initial". Um "bloco" contém uma sequencia de comandos que serão executados em ordem. O bloco "initial" será executado apenas uma vez.

initial
begin
    $dumpfile("saida.vcd");
    $dumpvars;
   
    a = 0;
    b = 0;
    #10
   
    a = 0;
    b = 1;
    #10
   
    a = 1;
    b = 0;
    #10
   
    a = 1;
    b = 1;
    #10
   
    $finish;
end

Os comandos $dumpfile("saida.vcd") e $dumpvars preparam o verilog para jogar as saídas para um arquivo VCD, que, posteriormente, será usado com o programa GTKWave para mostrar as formas de onda.
(VCD = Value Change Dump - http://en.wikipedia.org/wiki/Value_Change_Dump).
Comandos #10 significam "aguarde 10 unidades de tempo".
O que eu estou fazendo alí é setar a e b como 0, esperar 10 unidades de tempo, trocar os valores, esperar mais 10 unidades de tempo, trocar os valores, e assim por diante, até alcançar $finish.

Temos então nosso test banch completo como segue:

module PortasLogicas_tb;

reg a, b;
wire c, d;

PortasLogicas dut (a, b, c, d);

initial
begin
    $dumpfile("saida.vcd");
    $dumpvars;
   
    a = 0;
    b = 0;
    #10
   
    a = 0;
    b = 1;
    #10
   
    a = 1;
    b = 0;
    #10
   
    a = 1;
    b = 1;
    #10
   
    $finish;
end

endmodule

Tudo pronto :D
Para testar, no linux, fazemos assim:

"Compilar" os arquivos:
iverilog PortasLogicas.v PortasLogicas_tb.v
Executar os testes
./a.out
Mostrar formas de onda no GTKWave
gtkwave saida.vcd
Excluir arquivos
rm -f a.out saida.vcd

Claro que fazer tudo isso é um pouco trabalhoso. Imagine ter que ficar digitando esses quatro comandos a cada vez que for testar alguma coisa.
Por isso é muito mais facil fazer isso (no linux) com um Makefile :D
Makefile, pra quem não sabe, é um arquivo "especial" linux que, se vc estiver no terminal em uma pasta que tenha um arquivo chamado Makefile, vc pode escrever "make" e apertar enter e os comandos do makefile vão ser executados.
Pra quem tiver interesse: http://orion.lcg.ufrj.br/compgraf1/downloads/MakefileTut.pdf

Meu Makefile ficou assim:

PortasLogicas:
    iverilog PortasLogicas.v PortasLogicas_tb.v
    ./a.out

onda:
    gtkwave saida.vcd
   
clean:
    rm -f a.out saida.vcd   

Então quando eu executo

make PortasLogicas onda clean

ele compila, executa, me mostra as formas de onda e limpa a pasta atual :)
Por enquanto é só, pessoal. Esse post ficou maior do que eu pensei que ficaria, então não tenho certeza se posto outro ainda hoje. Mas já adiantando, no próximo post eu vou mostrar um SomadorNBits e algumas coisas mais legais que pode-se fazer nas bancadas de teste. Pra quem quiser, vou deixar o arquivo zipado com a pasta PortasLogicas e seus arquivos logo abaixo, além de uma imagem com o meu resultado do GTKWave.


Arquivos
Pacote PortasLogicas

Bibliografia (Na verdade perdi alguns links :( Mas ta tudo no google)
http://www.icarus.com/eda/verilog/
http://gtkwave.sourceforge.net/
http://www.asic-world.com/tidbits/wire_reg.html
http://www-inst.eecs.berkeley.edu/~cs150/Documents/Nets.pdf
http://www.asic-world.com/verilog/vbehave1.html
http://en.wikipedia.org/wiki/Verilog#Initial_and_Always
http://en.wikipedia.org/wiki/Value_Change_Dump
http://orion.lcg.ufrj.br/compgraf1/downloads/MakefileTut.pdf

Configurando Apache + PHP + MySQL no Slackware

Primeiramente devo ressaltar que esse post não é um tutorial. É apenas a minha saga na instalacão desses pacotes no meu Slackware.

Eu ainda não configurei o teclado direito no Slackware também, então, não fiquem assustados se eu escrever coisas como "instalacão", "acão", etc... Pois o meu Slackware ainda não sabe o que é cedilha hehehe... Talvez num próximo post eu faca isso.

Informacões talvez (ir)relevantes:
OS: Slackware 13.1
Linux: 2.6.33.4-smp

Na tentativa mais basica, fui até o slackbuilds.com e procurei por Apache. Não encontrei o que eu queria. Tudo bem, fui até o google, digitei apache e achei isso:

http://httpd.apache.org/download.cgi

Fiz o download, extrai o pacote (tar -xvf nomedopacote), dei um ./configure, um make e um make install. Deve ter instalado, mas tentei excecutar e não consegui.
Ai de mim, fui até o google novamente e achei esse tutorial:

http://www.vivaolinux.com.br/artigo/Instalando-o-Apache-+-PHP-+-MySQL-no-Slackware/

Baixei os pacotes, pensei "mas eu já instalei o Apache. Devo instalar denovo?"
Fiquei em dúvida. sim? não? pensei em desinstalar o outro primeiro, mas aí fiquei com preguica. Entrei em tentacão e... su... installpkg ./apache-1.3.28....

Juro que nunca mais faco isso.

Bom, instalei os outros pacotes e segui o tutorial para a parte 2: configuracão.
Acredito que o MySQL esteja OK, mas ao tentar iniciar o apache eu recebo:

apachectl start
/usr/sbin/httpd: error while loading shared libraries: libdb.so.2: cannot open shared object file: No such file or directory
/usr/sbin/apachectl start: httpd could not be started

Lá vamos nós atrás da libdb.so.2 u,u
Primeira opcão do google é essa:

http://www.rpmfind.net/linux/rpm2html/search.php?query=libdb.so.2

Mas quando tento baixar, ganho uma mensagem de "550 failed to change directory" na cara :(

Ok, depois de algumas tentativas... Hora da gambiarra!
Encontrei esse blog

http://support.zeus.com/zws/faqs/2005/09/19/libdb

Que sugeriu esse link

http://hany.sk/~hany/RPM/doors2.4/jr/db1-1.85-0.3.i386.html

Que tem um RPM do libdb.
Baixei ele, dei um

rpm2tgz ./db1-1.85-0.3.i386.rpm
installpkg db1-1.85-0.3.i386.tgz
apachectl start

e.... Mesmo erro.
Ok, vamos entrar num nível ainda maior de gambiarrice:

tar -xvf ./db1-1.85-0.3.i386.tgz
cd ./usr/lib/
ls
libdb1.so.2

Aí está o desgracado!

ln ./libdb1.so.2 /usr/lib/libdb.so.2
apachectl
[Thu Aug 5 21:31:55 2010] [warn] module mod_php4.c is already added, skipping
/usr/sbin/apachectl start: httpd started

Seila que diabo é esse warning, mas vou no meu firefox e digito 127.0.0.1 e ganho um "It Works!"

Beleza, agora um teste de verdade:

cd /var/www/htdocs
vim teste.php

$nome = "Tarcisio";
echo "Ola mundo. Meu nome é " . $nome;
?>

firefox > 127.0.0.1/teste.php

Ola mundo. Meu nome é Tarcisio

Coisa linda :D
Agora vamos "limpar" as coisas:

apachectl stop
/usr/sbin/apachectl stop: httpd stopped
rm /usr/lib/libdb.so.2
cp /home/tarcisio/downloads/usr/lib/libdb1.so.2 /usr/lib/libdb.so.2
apachectl start
[Thu Aug 5 21:43:21 2010] [warn] module mod_php4.c is already added, skipping
/usr/sbin/apachectl start: httpd started

Tudo bem. Dei uma pesquisada e dizem que esse warning é "normal". Eu não gostei muito dele, mas por hoje chega. Agora posso brincar com PHP no meu slackware em paz :)

Fui.