Guidelines de indentado, nombres de variables, etc.:
----------------------------------------------------

Este es un pequeño fuente VHDL donde se muestran las convenciones de
indentado
, nombres de las variables y detalles similares.
SETEdit fue modificado para incorporar la mayor parte posible de ayudas
tendientes a facilitar estos guidelines
. En cada punto se explica que ayudas
provee el editor
.

Encabezado:
-----------

El encabezado elegido es compatible con los requerimientos de OpenCores.
A ese encabezado se le agregaron datos interesantes tomando como ideas las
recomendaciones de la ESA
(European Space Agency) y otras que se me
ocurrieron
.
SETEdit: pmacro "\h"
Duda: el $Log de CVS es requerido en todas las recomendaciones, pero es como
mucho a mi modo de ver
, es cuestión de probar.

Mayúsculas/minúsculas:
----------------------

En las palabras reservadas:
---------------------------
Mi gusto personal es que la primer letra sea mayúscula y el resto minúsculas,
por ejemplo:

Entity Prueba is
   Generic
(
          );
  
Port(
        );
End Entity Prueba;

Pero casi nadie usa esto y los guidelines de la ESA lo prohiben.

En las variables y demás:
-------------------------

La ESA recomienda identificadores con case mezclado. Pero OpenCores
recomienda single
case para signals.
Solución: entities, architectures, funciones, procedimientos, etc. mezclado.
         
signals, variables, types, etc. lower.
         
constants y generics upper.

Largos de identificadores:
--------------------------

Se recomienda no exceder los 15 caracteres en signals, ports, etc. y los 13
caracteres en constants. El bakalint usa estos valore por defecto pero pueden
cambiarse
.

Library/Use:
------------

Se colocan en líneas separadas y sin indentado.
Ejemplo:

library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;

SETEdit: pmacro "#i" (Library/Use)
        
pmacro "#I" (Use)
        
pmacro "li" (IEEE standard libraries)

Entity/Architecture:
--------------------

Se utiliza el indentado por defecto de 3 caracteres.
Las declaraciones de los generic y port también indentan así.
Ejemplo:

entity Prueba is
   generic
(
     
XXXX   :     std_logic:='0');
  
port(
     
yyyy_i : in  std_logic);
end entity Prueba;

architecture RTL of Prueba is
begin
  
código;
end architecture RTL; -- Entity: Prueba

Los port se declaran de a un valor por línea (no más) y se les agrega a sus
nombres
_i, _o o _io para indicar el sentido. No se puede usar tipo buffer.
Hay que intentar evitar usar _i, _o y _io para señales, es preferible quitar
el
_ en ese caso.
Las señales del bus wishbone agregan wb_ delante (además de _i o _o detrás).
Se deberá tratar de mantener alineados los ":" y los tipos de cada
declaración
.

SETEdit: pmacro "ma" (Entity/Architecture)
        
pmacro "en" (Entity)
        
pmacro "ar" (Architecture)
        
"Intelligent indent": entity, begin, generic y port indentan 3
        
espacios
        
"El tab indenta buscando huecos": ayuda a mantener el indentado de
         los
: y los tipos.

Process:
--------

Todos los process deben tener un label y el process en la misma línea del
mismo.
El label debe ser descriptivo y dar idea de que hace el proceso.

SETEdit: pmacro "ps" (Process)
        
pmacro "pc" (Process for clock)
        
pmacro "p1" (Process w/clock+async rst)
        
pmacro "p2" (Process w/clock+sync rst)
        
Nota: p<Ctrl>+<Space> lista los pmacros con "p"

End:
----

Todos los end deben ser autodocumentados. Eso implica que el end de la
entidad Prueba es
: end entity Prueba

SETEdit
: Todos los pmacros que generan cosas con un end lo completan en forma
         apropiada
.

if/else/elsif:
--------------

Siguen el indentado de 3 caracteres. La ventaja es que se genera una `columna
de corte
`:

  |
------ camino visual
 
v
if condición then
  
sentencia;
else
  
sentencia;
end if;

SETEdit: pmacro "i(" (If plus else)
        
pmacro "I(" (If, no else)
        
pmacro "ig" (If generate)
        
pmacro "if" (If/elsif/else/endif)
        
"Intelligent indent": if, else y elsif indentan 3 espacios
        
"El tab indenta buscando huecos": ayuda a mantener el hueco.

while:
------

También mantiene 3 espacios de indentado.

while condición loop
  
sentencia;
end loop;

SETEdit: pmacro "w(" (While loop)
        
"Intelligent indent": while indenta 3 espacios

for:
----

Para mantener el hueco visual se propone un indentado extra de 4 caracteres:

   |
------ camino visual
  
v
for i in 0 to 7 loop
   
sentencia;
end loop;

SETEdit: pmacro "f(" (For loop)
        
pmacro "fg" (For generate)
        
"Intelligent indent": for indenta 4 espacios
        
"El tab indenta buscando huecos": ayuda a mantener el hueco.

case/when:
----------

Para mantener el hueco visual se propone un indentado extra de 5 caracteres:

    |
------ camino visual
   
v
case sig is
     when
'0' =>
         
sentencia;
    
when others =>
         
sentencia;
end case;

Lo mismo aplica al when.

SETEdit: pmacro "s(" (Case) Nota: por ser el equivalente al switch de C/C++
        
pmacro "c:" (Case element (when)) Nota: por ser el equivalente al
        
case de C/C++
        
"Intelligent indent": case y when indentan 5 espacios
        
"El tab indenta buscando huecos": ayuda a mantener el hueco.

with/select:
------------

Para mantener el hueco visual se propone un indentado extra de 5 caracteres:

    |
------ camino visual
   
v
with a & b select destino <=
    
'0' when "00",
    
'1' when "11",
    
'Z' when others;

Esta construcción es compleja y se propone el indentado de arriba aunque
también podríamos adoptar
:

with a & b select
    
destino <= '0' when "00",
               
'1' when "11",
               
'Z' when others;

El problema en este caso es que mantener el indentado es más complejo si el
nombre
"destino" cambia.

SETEdit: pmacro "se" (Select signal (With))
        
"Intelligent indent": with indenta 5 espacios
        
"El tab indenta buscando huecos": ayuda a mantener el hueco.

Sentencias con paréntesis anidados que ocupan más de una línea:
---------------------------------------------------------------

Mantienen indentada la condición hasta que los paréntesis se cierran:

if (a>b and
   
c<d and
   
q>0) then
  
sentencia;
end if;

Se busca alinear todas las condiciones.

SETEdit: "Intelligent indent": mantiene el indentado.

Instanciación de componentes:
-----------------------------

El label y el nombre del componente van en la misma línea. El generic y el
port indentan usando 3 espacios:

Decenas: L7490
  
generic map(
     
a => q, ....)
  
port map(
     
a => g, ....);

SETEdit: pmacro "ci" (Component instantiation)
        
"Intelligent indent": generic y port indentan 3 espacios

------------------------------------------------------------------------------
------------------------------------------------------------------------------
------------------------------------------------------------------------------
------------------------------------------------------------------------------
------------------------------------------------------------------------------
------------------------------------------------------------------------------
------------------------------------------------------------------------------

<*** Este header es compatible con OpenCores
     Se puede lograr con el pmacro
"\h"
------------------------------------------------------------------------------
----                                                                      ----
----  WISHBONE Handler                                                    ----
----                                                                      ----
----  Internal file, can't be downloaded.                                 ----
----                                                                      ----
----  Description:                                                        ----
----  That's a module used to easily write testbenches that uses          ----
----  Wishbone modules.                                                   ----
----                                                                      ----
----  To Do:                                                              ----
----  -                                                                   ----
----                                                                      ----
----  Author:                                                             ----
----    - Salvador E. Tropea, salvador@inti.gov.ar                        ----
----                                                                      ----
------------------------------------------------------------------------------
----                                                                      ----
---- Copyright (c) 2005 Salvador E. Tropea <salvador@inti.gov.ar>         ----
----                                                                      ----
---- For internal use, all rights reserved.                               ----
----                                                                      ----
------------------------------------------------------------------------------
<*** Esta sección agrega datos interesantes pedidos por la ESA y otros que
     a mi me gusta poner
.
----                                                                      ----
---- Design unit:      WBHandler(simulator) (Entity and architecture)     ----
---- File name:        Guidelines.vhdl                                    ----
---- Note:             None                                               ----
---- Limitations:      None known                                         ----
---- Errors:           None known                                         ----
---- Library:          WBHandler_Lib                                      ----
---- Dependencies:     IEEE.std_logic_1164                                ----
----                   IEEE.numeric_std                                   ----
---- Target FPGA:      Spartan II (XC2S100-5-PQ208)                       ----
---- Language:         VHDL                                               ----
---- Wishbone:         MASTER (rev B.3)                                   ----
---- Synthesis tools:  Xilinx Release 6.2.03i - xst G.31a                 ----
---- Simulation tools: GHDL [Sokcho edition] (0.1x)                       ----
---- Text editor:      SETEdit 0.5.x                                      ----
----                                                                      ----
------------------------------------------------------------------------------
--
-- CVS Revision History
--
-- $Log$
--

<*** Personalmente prefiero Library, pero casi nadie usa esto y los guidelines
     de la ESA lo prohiben
. Se obtiene con el pmacro "li"
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;

<*** La ESA recomienda identificadores con case mezclado.
    
Pero OpenCores recomienda single case para signals.
    
Solución: entities, architectures, etc. mezclado.
              
signals, variables, types, etc. lower.
    
Esto se obtiene con "ma"
entity WBHandler is
  
<*** Este indentado es molesto pero simple: 3 caracteres por defecto
        El editor lo hace con
"Intelligent indent"
  
generic(
     
addr_w   : integer:=8;
     
data_w   : integer:=8);
  
port(
     
-- Simple port
     
<*** Cada signal en una línea, _i/_o/_io
     
addr_i   : in  std_logic_vector(addr_w-1 downto 0);
     
data_i   : in  std_logic_vector(data_w-1 downto 0);
     
data_o   : out std_logic_vector(data_w-1 downto 0):=(others => '0');
     
rd_i,
     
wr_i     : in  std_logic;
     
rde_o,
     
wre_o    : out std_logic:='0';
     
-- Wishbone side
     
<*** La de WB con wb_*_i/wb_o_i
      wb_rst_i
: in  std_logic;
     
wb_clk_i : in  std_logic;
     
wb_adr_o : out std_logic_vector(addr_w-1 downto 0):=(others => '0');
     
wb_dat_i : in  std_logic_vector(data_w-1 downto 0);
     
wb_dat_o : out std_logic_vector(data_w-1 downto 0):=(others => '0');
     
wb_we_o  : out std_logic:='0';
     
wb_stb_o : out std_logic:='0';
     
wb_cyc_o : out std_logic:='0';
     
awb_ck_i : in  std_logic);
end entity WBHandler;

architecture Simulator of WBHandler is
begin
  
<*** Todos los process con label y el process en la misma línea
        Es el
"ps"
  
write_p: process
   begin
      wait until
rd'event or wr'event or clk_i'event;
     
<*** Indentar buscando el hueco, esto se hace fácil con la opción 'El tab
           indenta buscando huecos
' de SETEdit y con 'Intelligent indent'
          
if/else es "i("
     
if wb_rst_i='1' then
        
wb_adr_o <= (others => '0');
        
wb_dat_o <= (others => 'Z');
        
wb_we_o  <= '0';
        
wb_stb_o <= '0';
        
wb_cyc_o <= '0';
        
data_o   <= (others => 'Z');
        
rde_o    <= '0';
        
wre_o    <= '0';
     
else
        
<*** El editor mantiene el indentado acá
        
if wr'event and wr='1' then
           
-- Write
           
wb_adr_o  <= addr;
           
wb_dat_o  <= idata;
           
wb_cyc_o  <= '1';
           
wb_stb_o  <= '1';
           
wb_we_o   <= '1';
           
-- Wait for clock
           
<*** Las funciones de la IEEE tienen _ por lo que parece que fueron
                 pensadas para usarse en un solo
"case", lamentablemente no es
                 coherente el uso
, pero en el package la escribieron así:
           
wait until rising_edge(wb_clk_i);
           
wait for 1 ns;
           
-- Wait for ack
           
if wb_ack_i='0' then
               wait until
wb_ack_i='1';
           
end if;
           
wait for 1 ns;
           
-- End of write
           
wb_adr_o  <= (others => '0');
           
wb_dat_o  <= (others => 'Z');
           
wb_cyc_o  <= '0';
           
wb_stb_o  <= '0';
           
wb_we_o   <= '0';
           
-- Tell it to our client
           
wre_o     <= '1';
        
else
           
wre_o     <= '0';
        
end if;
        
if rd'event and rd='1' then
           
-- Read
           
wb_adr_o  <= addr;
           
wb_cyc_o  <= '1';
           
wb_stb_o  <= '1';
           
-- Wait for clock
           
wait until rising_edge(wb_clk_i);
           
wait for 1 ns;
           
-- Wait for ack
           
if wb_ack_i='0' then
               wait until
wb_ack_i='1';
           
end if;
           
wait for 1 ns;
           
-- End of read
           
wb_adr_o  <= (others => '0');
           
data_o    <= dat_i;
           
wb_cyc_o  <= '0';
           
wb_stb_o  <= '0';
           
wb_we_o   <= '0';
           
-- Tell it to our client
           
rde_o     <= '1';
        
else
           
rde_o     <= '0';
        
end if;
     
end if;
  
<*** Autodocumentar usando así:
  
end process write_p;
end architecture Simulator;