mikrocontroller.net

Forum: FPGA, VHDL & Co. Vivado Simulation stoppt vor Ende der Simulationszeit


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
Autor: Alex K. (alexk99123)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

die Simulation zu meinem Quellcode, der einen FIR Filter implementieren 
soll, stoppt weit vor Ablauf der angegebenen Simulationszeit. Ich habe 
bereits in anderen Beiträgen gelesen, dass wahrscheinlich mein Quellcode 
verantwortlich ist, jedoch finde ich den Fehler nicht.
Ich weiß, dass mein Code noch weit davon entfernt ist, perfekt zu sein, 
allerdings wollte ich in der Simulation nachvollziehen, ob meine 
Statemachine so hinhaut, wie sie soll. Vivado zeigt auch eine Warnung 
an, diese lautet:
"[filemgmt 56-199] Attempt to get parsing info during refresh. 
"On-the-fly" syntax checking information may be incorrect. 
["D:/Programme/Xilinx/Vivado/projects/FIR_eigen/FIR_eigen.srcs/sources_1 
/new/fir_tiefpass.vhd":]"
Damit kann ich allerdings nicht wirklich was anfangen. Zusätzlich hänge 
ich noch die Simulation an.
Mein Ansatz wäre jetzt natürlich dort nachzusehen, wo die Simulation 
abbricht. In meinem Fall ist das im state "filter". Hier werden die 
Verschiebe- und Multiplikationsoperationen durchgeführt und eine Counter 
Variable wird hochgezählt. Ich verstehe allerdings nicht, wo hier der 
Fehler liegt.

Zunächst der Code des Moduls:
--
--Implementierung der Direktform eines FIR - Tiefpasses
--Kennwerte: Abtastrate: 50 kHz
--f_Durchlass = 0,8kHz
--f_stopp: 5kHz bei delta_s = 20dB Absenkung
--passband Ripple = 0,1db

library IEEE;
use IEEE.Std_logic_1164.all;
use IEEE.Numeric_Std.all;
use IEEE.math_real.all;


entity FIR_Test is
    generic(N   :   integer := 10); --(Anzahl der Koeffizienten - 1)
    port
    (
        x_in    :   in std_logic_vector(11 downto 0);   --Input 12 Bit vom AD Wandler
        clk     :   in std_logic;                       --Input Clk mit hoher Frequenz
        rst     :   in std_logic;                       --Reset Active Low
        enable_data :   in  std_logic;                  --next Sample von ADC
        data_acknowledged   :   in std_logic;           --DA hat Daten erhalten
        
        filter_rdy  :   out std_logic;                  --Signalisiere dem DA ready.
        y       :   out std_logic_vector(11 downto 0)   --Output 12 Bit an den DA - Wandler
    );
end FIR_Test;

architecture FIR_Test_arch of FIR_Test is
    
    type    tap_line is array(0 to (N - 1)) of std_logic_vector(12 downto 0);    --Typenerklärung: Array zum Verschieben 
                                                                                -- =(Zeitverzögern) des Inputs
                                                                                    
    type    table is array(0 to N) of signed(12 downto 0);  --Typenerklärung: Array aus Filterkoeffizienten,
                                                            
                                                            
    --States
    type states is  (                
                        waitForADC,
                        readData,
                        filter,
                        shiftToDA     
                    );
    
    signal x    :   tap_line;
    constant coeff  : table:= (
                                "0" & X"085",
                                "0" & X"07F",
                                "0" & X"0A9",
                                "0" & X"0CD",
                                "0" & X"0E6",
                                "0" & X"0EE",
                                "0" & X"0E6",
                                "0" & X"0CD",
                                "0" & X"0A9",
                                "0" & X"07F",
                                "0" & X"085"
                               );  --Koeffiziententabelle, von a_10 bis a_0
                                   --Darstellung: signed 1.12
                                   
   signal current_state :   states := waitForADC;   --Enthält den aktuellen Status, initialisiert mit "waitForADC"
   signal filter_rdy_intern :   std_logic := '0';   --Internes Signal für die fertige Filteroperation
   signal data_read_ready   :   std_logic := '0';   --Daten einlesen fertig
   signal DA_acknowledged   :   std_logic := '0';   --DA hat Daten erhalten
--   signal counter_filter    :   integer range 0 to 50;
   
begin
    
    --Schreiben der Statemachine
    write_statemachine  :   process(clk, rst)
    begin
        --Reset aktiv low
        if (rst = '0') then
            current_state <= waitForADC;
        --Signaländerung bei steigender Flanke des 125MHz Clocks
        elsif (rising_edge(clk)) then
            if (enable_data = '1' and data_read_ready = '0' ) then  --Nur 1x lesen
                current_state <= readData;
            elsif (data_read_ready = '1') then
                current_state <= filter;
            elsif (filter_rdy_intern = '1') then
                current_state   <=  shiftToDA;
            elsif (data_acknowledged = '1') then
                current_state <= waitForADC;
            else
                NULL;
            end if;
        end if;
    end process write_statemachine;  
    
    --Durchführen der Operationen abhängig vom State
    statemachine    :   process(clk)
    variable sop    :   signed(25 downto 0);    --Variable für Zwischenergebnis der Multiplikation, Darstellung 2.22
    variable counter_filter :   integer range 0 to 20;
    begin
        if (rising_edge(clk)) then
            case (current_state) is
                when waitForADC =>
                    filter_rdy_intern <= '0';
                    data_read_ready   <=  '0';
                    sop := (others => '0');
                    counter_filter := 0;
                when readData =>
                    x(0) <= "0" & x_in;   --Neues Datum einlesen
                    data_read_ready <= '1';         
                when filter =>
                    if (counter_filter < 12) then                         
                        sop := sop + coeff(counter_filter - 1) * signed(x(counter_filter - 1)); --Durchführung einer Multiplikation und einer Addition
                        x(counter_filter) <= x(counter_filter - 1); --Zeitverschiebung
                    else
                        filter_rdy_intern <= '1';
                    end if;
                    counter_filter := counter_filter + 1;
                when shiftToDA =>
                    y <= std_logic_vector(sop(22 downto 11)); 
                    filter_rdy <= '1';
            end case;
        else
            NULL;
        end if;
                                    
    end process statemachine;  
    
end FIR_Test_arch;

Hier der Code des Simulationsfiles
----------------------------------------------------------------------------------
-- Company: 
-- Engineer: 
-- 
-- Create Date: 06.08.2019 14:33:09
-- Design Name: 
-- Module Name: sim_fir - sim_fir_arch
-- Project Name: 
-- Target Devices: 
-- Tool Versions: 
-- Description: 
-- 
-- Dependencies: 
-- 
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
-- 
----------------------------------------------------------------------------------


library IEEE;
use IEEE.Std_logic_1164.all;
use IEEE.Numeric_Std.all;

-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;

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

entity sim_fir is
--  Port ( );
end sim_fir;

architecture sim_fir_arch of sim_fir is
    
    component FIR_Test is
        generic(N   :   integer := 10); --(Anzahl der Koeffizienten - 1)
        port
        (
            x_in    :   in std_logic_vector(11 downto 0);   --Input 12 Bit vom AD Wandler
            clk     :   in std_logic;                       --Input Clk mit hoher Frequenz
            rst     :   in std_logic;                       --Reset Active Low
            enable_data :   in  std_logic;                  --next Sample von ADC
            data_acknowledged   :   in std_logic;           --DA hat Daten erhalten
            
            filter_rdy  :   out std_logic;                  --Signalisiere dem DA ready.
            y       :   out std_logic_vector(11 downto 0)   --Output 12 Bit an den DA - Wandler
        );
    end component FIR_Test;
    
    signal sign_x_in    :   std_logic_vector(11 downto 0) := "100010001000";   --Input 12 Bit vom AD Wandler
    signal sign_clk     :   std_logic := '0';                       --Input Clk mit hoher Frequenz
    signal sign_rst     :   std_logic := '1';                       --Reset Active Low
    signal sign_enable_data :   std_logic := '1';                  --next Sample von ADC
    signal sign_data_acknowledged   :   std_logic := '1';           --DA hat Daten erhalten
    
    signal sign_filter_rdy  :   std_logic;                  --Signalisiere dem DA ready.
    signal sign_y       :   std_logic_vector(11 downto 0);   --Output 12 Bit an den DA - Wandler    
begin
    dut :   FIR_Test
    
    port map
    (
        x_in => sign_x_in,
        clk =>  sign_clk,
        rst =>  sign_rst,     
        enable_data=>sign_enable_data, 
        data_acknowledged=>sign_data_acknowledged,  
        
        filter_rdy=>sign_filter_rdy, 
        y=>sign_y    
    );
    
    clk_gen :   process
    begin
        wait for 4ns;
        sign_clk    <=  '1';
        wait for 4ns;
        sign_clk    <= '0';
    end process clk_gen;
    
    enable_gen  :   process
    begin
        wait for 20us;
        sign_enable_data <= '1';
        wait for 1us;     
        sign_enable_data <= '0';
    end process enable_gen;
end sim_fir_arch;

: Bearbeitet durch User
Autor: Tobias B. (Firma: www.elpra.de) (ttobsen)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Da muss t schon den ganzen Log mit anhaengen. XSim wird ja nicht einfach 
aufhoeren mit simulieren ohne irgendeinen Grund zu nennen warum 
aufgehoert wird.

: Bearbeitet durch User
Autor: Alex K. (alexk99123)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sorry, dämlicher Post... Ich wusste nicht, dass der Konsolenoutput so 
explizit auf Fehler hinweist.
if (counter_filter < 12) then                         
    sop := sop + coeff(counter_filter - 1) * signed(x(counter_filter - 1)); --Durchführung einer Multiplikation und einer Addition
    x(counter_filter) <= x(counter_filter - 1); --Zeitverschiebung
else
    filter_rdy_intern <= '1';
end if;
    counter_filter := counter_filter + 1;

In dem Codeschnipsel zählt counter_filter zu weit. Der Index des Arrays 
"x" ist gar nicht so groß

Autor: Tobias B. (Firma: www.elpra.de) (ttobsen)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Perfekt, das ist DER typische Fehler wenn Simulationen ploetzlich 
stoppen. :-)

Autor: Elbi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Es gibt noch einen Punkt: Wenn sie zu lange dauert und die Anzahl der 
Zeitpunkte zu gross wird. Da gibt es ein Limit.

Ansonsten säuft ModelSIM gerne mal ab, wenn es zuviel Speichern muss.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [vhdl]VHDL-Code[/vhdl]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.