[VHDL][GHDL] Contador generico de n bits

735 views
Skip to first unread message

Carlos

unread,
Sep 22, 2017, 6:06:49 PM9/22/17
to FPGAwars: explorando el lado libre
Que tal,
Estoy tratando de escribir un modulo (¿tambien se llaman modulos en VHDL?) para un contador generico de n_bits.Tengo un par de dudas, ojala me puedan ayudar.

Código:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity contador
is
    generic
(
        n_bits
: integer := 3);
    port
(
        clk
: in std_logic;
        rst
: in std_logic;
        Q  
: inout std_logic_vector(n_bits downto 0));
end contador;

architecture synth of contador
is
begin

process
(clk) begin
   
if(rising_edge(clk)) then
       
if(rst='1') then
            Q
<= "0000";
       
else
            Q
<= Q + 1;
       
end if;
   
end if;
end process;

end synth;

Primero estoy revisando si la sintaxis es la correcta:
$ ghdl -s contador.vhdl

y obtengo el siguiente error:
contador.vhdl:22:20:error: no function declarations for operator "+"

¿El operador + no deberia añadirse cuando indico que estoy usando numeric_std?

Cuando rst='1' le asigno 0 al vector Q, en el código lo hago con "0000" porque estaba trabajando con un vector de 4bits, ¿existe alguna forma de volver esa asignación generica?
Con verilog creo que podria hacer {0{n_bits}}.
Tambien trate con Q <= 0 , pero obtengo el siguiente error:
can't match integer literal with type array type "std_logic_vector"

Saludos

Carlos

unread,
Sep 23, 2017, 3:31:50 PM9/23/17
to FPGAwars: explorando el lado libre
Al parecer ya quedo bien el código:

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;


entity counter
is
    generic
(
        N_BITS
: integer := 3

   
);
    port
(
        clk
: in std_logic;
        rst
: in std_logic;

        Q  
: inout std_logic_vector((N_BITS-1) downto 0)
   
);
end counter;

architecture synth of counter
is

begin

process
(clk) begin
   
if(rising_edge(clk)) then
       
if(rst='1') then

            Q
<= (others => '0');
       
else
            Q
<= std_logic_vector(unsigned(Q) + 1);

       
end if;
   
end if;
end process;

end synth;

* Para asignarle 0 al vector Q sin importar su ancho se usa Q <= (others => '0')
* Con respecto al error del operador + era porque estaba sumando un entero con un vector, hay que hacer cast, Q <= std_logic_vector(unsigned(Q)+1)

Me base en un ejemplo que tiene obijuan en ghdlsynth :)

Y el testbench
library ieee;
use ieee.std_logic_1164.all;

entity counter_tb
is
end entity counter_tb;

architecture test of counter_tb
is

    constant COUNTER_BITS
: integer := 3;

   
-- instance of the counter
    component counter
    generic
(
        N_BITS
: integer := COUNTER_BITS
   
);

    port
(
        clk
: in std_logic;
        rst
: in std_logic;

        Q  
: inout std_logic_vector((N_BITS-1) downto 0)
   
);
   
end component;

    signal clk    
: std_logic := '0';
    signal rst    
: std_logic := '0';
    signal Q    
: std_logic_vector((COUNTER_BITS-1) downto 0) := (others => '0');

begin
   
-- signal => component port
    counter_uut
: counter port map(clk => clk, rst => rst, Q => Q);

   
-- generate the clock
    clock
: process begin
        clk
<= '1';
        wait
for 1 ns;
        clk
<= '0';
        wait
for 1 ns;
   
end process clock;
   
    process
begin
        rst
<= '1';
        wait
for 1 ns;
        rst
<= '0';
        wait
for 20 ns;
        rst
<= '1';
        wait
for 1 ns;
        rst
<= '0';
       
assert false report "Reached end of test";
        wait
;
   
end process;

end test;

No se como hacer para que la simulacion termine y no quede esperando, eso lo dejo para despues.

Saludos


Carlos

unread,
Sep 23, 2017, 3:34:55 PM9/23/17
to FPGAwars: explorando el lado libre
Olvidaba adjuntar los archivos y los comandos para replicar el proyecto:

$ ghdl -s counter.vhdl counter_tb.vhdl
$ ghdl -a counter.vhdl counter_tb.vhdl
$ ghdl -e counter_tb
$ ghdl -r counter_tb --vcd=counter.vcd
$ gtkwave counter.vcd
counter.vhdl
counter_tb.vhdl

Carlos

unread,
Sep 27, 2017, 12:32:44 PM9/27/17
to FPGAwars: explorando el lado libre
Añadi un assert para comprobar que el valor asignado a N_BITS a la hora de instanciarlo sea valido.
Por desgracia no es posible sintetizarlo usando ghdlsynth-beta, alguien recomienda alguna tarjeta (pensaba en un CPLD) y un IDE gratuito (puede ser con limitaciones) y que corra nativo en Ubuntu?

--! @file
--! @brief n bits counter
--! the counts wraps to 0 when all the bits
--! on the vector are equal to logic 1.


library ieee
;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity counter
is

    generic
(
        N_BITS
: integer := 3
   
);

    port
(
        clk
: in std_logic;
        rst
: in std_logic;

        Q  
: out std_logic_vector((N_BITS-1) downto 0)

   
);

end counter;

architecture synth of counter
is
--! internal counter
signal Q_in
: unsigned((N_BITS-1) downto 0);
begin

assert (N_BITS > 0)
    report
"N_BITS should be bigger than 0"
severity failure
;

-- Set the count to 0 when the rst input is 1,
-- otherwise increment the count by one.

process
(clk) begin
   
if(rising_edge(clk)) then
       
if(rst='1') then

            Q_in
<= (others => '0');
       
else
            Q_in
<= Q_in + 1;

       
end if;
   
end if;
end process;

-- Assign the current count to the Q output
process
(clk) begin
   
if(rising_edge(clk)) then
        Q
<= std_logic_vector(unsigned(Q_in));
Reply all
Reply to author
Forward
0 new messages