Pagina 1 di 2

GHDL e librerie

MessaggioInviato: 13 ago 2010, 16:35
da elettronico-bis
Salve a tutti,

sto cercando di simlare un contatore a 3 bit con ghdl ( vedi VHDL per linux).

Il problema è che quando cerco di incrementare l'output ( output <= output + "001" ), mi dice che non riconosce il segno +;

ho provato a caricare le librerie per i calcoli aritmetici ma nada (non trova std_logic_arith).

Qualcuno ha qualche idea?

Grazie mille

Re: GHDL e librerie

MessaggioInviato: 13 ago 2010, 20:18
da xyz
GHDL non è solo per Linux ma è multi piattaforma e anche open source.

elettronico-bis ha scritto:Il problema è che quando cerco di incrementare l'output ( output <= output + "001" ), mi dice che non riconosce il segno +;

Come hai definito output ?

elettronico-bis ha scritto:ho provato a caricare le librerie per i calcoli aritmetici ma nada (non trova std_logic_arith).

Non specifichi quando ti capita o con quale esatto comando.

Re: GHDL e librerie

MessaggioInviato: 13 ago 2010, 20:32
da denisrn
In effetti, come gia' fatto presente da xyz, senza contesto si puo' fare ben poco. Comunque provo a dare 2 consigli.

Fossi in te' inizierei con l' includere numeric_std:

Codice: Seleziona tutto
library ieee;
use ieee.numeric_std.all;


Dove puoi trovare utilissime cose, tipo:

Codice: Seleziona tutto
  -- Id: A.5
  function "+" (L: UNSIGNED; R: NATURAL) return UNSIGNED;
  -- Result subtype: UNSIGNED(L'LENGTH-1 downto 0).
  -- Result: Adds an UNSIGNED vector, L, with a non-negative INTEGER, R.


Cosi', presumendo che la tua variabile counter sia un array di std_logic (cioe' di tipo std_logic_vector), puoi riscrivere quel trancio di codice come:

Codice: Seleziona tutto
output <= std_logic_vector(unsigned(output)+1);



Hope it helps.

PS: ma che strano nome per una variabile (output), non e' che e' un segnale di uscita che hai dichiarato come inout? Se si' sostituisci con una variabile, e' preferibile, meglio evitare porte inout se non sono necessarie

Re: GHDL e librerie

MessaggioInviato: 15 ago 2010, 14:44
da elettronico-bis
Grazie per le risposte.
In effetti, senza specificare il tutto è un po' difficile compprendere il problema.
Comunque, questo è il codice di un contatore a 3 bit:


Codice: Seleziona tutto
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;

entity counter is
 
  port (
    clk : in std_logic;                             -- clock
    start : in std_logic;                          -- start input
    OUTA :out std_logic_vector(0 to 2)); -- output vector

end counter;


architecture arch_counter of counter is

signal t : std_logic_vector(0 to 2) := "000";   -- output provvisorio

begin

process (clk, start)
  begin

  if start = '0' then OUTA <= "000";                  -- asynchronous reset (active low)
   
  elsif (clk'event and clk = '1') then                  -- rising clock edge
   t <= t + "001";
    end if;





E questo è l'errore che ottengo:


Codice: Seleziona tutto
counter.vhdl:37:12: no function declarations for operator "+"
/usr/lib/ghdl/bin/ghdl: compilation error

Re: GHDL e librerie

MessaggioInviato: 16 ago 2010, 0:11
da xyz
Forse il problema è questo:

http://tams-www.informatik.uni-hamburg. ... .html#4.11

cambia "IEEE.numeric_std.all" in "IEEE.std_logic_unsigned.all" e quando lanci il compilatore aggiungi l'opzione "--ieee=synopsys".

Re: GHDL e librerie

MessaggioInviato: 16 ago 2010, 9:22
da denisrn
Sinceramente eviterei IEEE.std_logic_unsigned, e' una roba vecchia e non standard, ormai sostituita con numeric_std:

Per maggiori informazioni dai un occhiata QUI

Io risolverei cosi':

Codice: Seleziona tutto
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;

entity counter is

  port (
    clk : in std_logic;                             -- clock
    start : in std_logic;                          -- start input
    OUTA :out std_logic_vector(0 to 2)); -- output vector

end counter;


architecture arch_counter of counter is

   signal t : std_logic_vector(0 to 2) := "000";   -- output provvisorio

begin

   process (clk, start)
   begin

      if start = '0' then
         OUTA <= "000";                  -- asynchronous reset (active low)
      
      elsif (clk'event and clk = '1') then                  -- rising clock edge
         t <= std_logic_vector(unsigned(t) + "001");
      end if;
      
   end process;
   
end arch_counter;


E non avere paura dei cast, VHDL e' uno "strongly typed language" :)


PS: L' errore che commettevi era richiedere un' "operator +" tra oggetti di tipo std_logic_vector, cosa che non ha ragione di esistere. Questo perche' il compilatore non sa come eseguire la somma (con o senza segno?), quindi devi esplicitare il tipo (nell' esempio sopra unsigned()). Poi, dato che il risultato e' di tipo unsigned e stai assegnando un signal di tipo std_logic_vector, serve un ulteriore cast (std_logic_vector()).

[Risolto]Re: GHDL e librerie

MessaggioInviato: 16 ago 2010, 9:24
da elettronico-bis
Grande,
grazie mille.
Il programma non fa ancora quello che deve fare ma probabilmente c'è un errore nel codice.
Adesso riesce a compilare senza darmi più l'errore dovuto al +.

Ora pian pianino cercherò di risolvere ogni cosa.


Grazie mille per l'aiuto.

Buona giornata

Re: [Risolto]Re: GHDL e librerie

MessaggioInviato: 16 ago 2010, 9:33
da denisrn
Che comportamento ti aspetti e cosa ottieni invece ?

Re: [Risolto]Re: GHDL e librerie

MessaggioInviato: 16 ago 2010, 9:46
da denisrn
Vabbe, comunque volendo mettere un po' a posto quel codice:

Codice: Seleziona tutto
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;

entity counter is

  port (
    clk : in std_logic;                             -- clock
    start : in std_logic;                          -- start input
    OUTA :out std_logic_vector(0 to 2)); -- output vector

end counter;


architecture arch_counter of counter is

   signal t : std_logic_vector(0 to 2) := "000";   -- output provvisorio

begin

   process (clk, start)
   begin

      if start = '0' then
         t <= "000";                  -- asynchronous reset (active low)      
      elsif (clk'event and clk = '1') then                  -- rising clock edge
         t <= std_logic_vector(unsigned(t) + "001");
      end if;
   end process;
   
   OUTA <= t;
   
end arch_counter;


Questa e' la simulazione di un testbench con il componente sopra citato e start forzato a 1:

sim.PNG
sim.PNG (22.44 KiB) Osservato 10690 volte



Questo invece e' un' altro esempio di contatore con reset asincrono e CE, piu' utile perche' piu' generico:
Codice: Seleziona tutto
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

---- Uncomment the following library declaration if instantiating
---- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;

entity nbit_counter is
    generic( n_bits: integer );
    port(  clk: in std_logic;
           async_rst: in  std_logic;
           ce: in  std_logic;
           count: out std_logic_vector(n_bits-1 downto 0) );
end nbit_counter;

architecture Behavioral of nbit_counter is

begin
   
   process (clk)
      variable count_var: std_logic_vector(n_bits-1 downto 0) := (others => '0');
   begin
      if async_rst = '1' then
         count_var := (others => '0');
      elsif falling_edge(clk) then
         if ce = '1' then
            count_var := count_var+1;
         end if;
      end if;
      count <= count_var;
   end process;
   
end Behavioral;


BTW attento all' istante in cui molli il reset asincrono, assicurati di essere lontano dal fronte in cui il contatore commuta!

Re: GHDL e librerie

MessaggioInviato: 16 ago 2010, 11:39
da elettronico-bis
Ciao e grazie per le dritte.


Ora o sistemato il codice (gli chiedevo di farmi vedere l'output fuori dal process e quindi non vedevo tutti gli scatti).

Questo è il codice che gira bene.

library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;


entity counter is

port (
clk : in std_logic; -- clock
start : in std_logic; -- start input
OUTA :out std_logic_vector(0 to 2)); -- output vector

end counter;


architecture arch_counter of counter is

signal t : std_logic_vector(0 to 2) := "000"; -- output provvisorio



begin

process (clk, start)
begin

if start = '0' then t <= "000";OUTA <= "000"; -- asynchronous reset (active low)

elsif (clk'event and clk = '1') then -- rising clock edge


t <= t + "001";

OUTA <= t;

end if;
end process;



end arch_counter;




Ovviamente ci sarà un modo meno complicato per farlo.
Stasera mi metto sotto e guardo le tue dritte (ora sono a lavoro, in pausa, ma al lavoro...).
Domani ti faccio sapere come è andata.
Grazie mille per i consigli (sai, uno alle prime armi scrive codici arzigogolati anche per le cose più semplici..)

A domani!