Forum: FPGA, VHDL & Co. Vivado Warnung, "Sequential element unused" warum tritt sie auf?


von Matze (Gast)


Lesenswert?

Hallo,

Ich habe ein an sich übersichtliches VDHL-Design, welches in der 
Behavorial-Simulation funktioniert.

Wird, es jedoch Synthetisiert, so erscheinen viele Warnungen der Sorte:

[Synth 8-3332] Sequential element (\SPI/timestamp_reg[47] ) is unused 
and will be removed from module Main.

Dabei werden alle Signale zu Beginn mittels reset initialisiert und 
ihnen vielfach Werte zugewiesen.

Durch Attribute wie "keep" oder "dont touch" ergibt sich keinerlei 
Ändeung, die Signale werden weiterhin als unused erkannt und entfernt.

Selbst wenn die Signale herausführt und direkt auf Pins gegeben werden, 
so sind sei weiterhin unused.

Habt ihr ideen woran es liegen könnte?

von Da D. (dieter)


Lesenswert?

Der Fehler ist in Zeile 42.

von Dussel (Gast)


Lesenswert?

Wahrscheinlich werden die Signale nicht benutzt -.-

Wenn du ein Signal hast, das immer 0 ist, wird der entsprechende Pin auf 
Masse gelegt und das Signal wegoptimiert.
Warum das so ist, ist nicht immer einfach herauszufinden. Ich hatte das 
Problem auch mal und habe relativ lange gesucht, bis ich rausgefunden 
habe, warum das Signal nicht geändert wird.

von Matze (Gast)


Lesenswert?

Dussel schrieb:
> Wenn du ein Signal hast, das immer 0 ist, wird der entsprechende Pin auf
> Masse gelegt und das Signal wegoptimiert.

Die betreffenden Signale ändern ihren Zustand in der 
Behavorial-Simulation, sonst könnte die Schaltung auch nicht 
funktionieren.

Wie kann die Synthese dann fest stellen dass sie ihren Zustand nicht 
ändern?

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Matze schrieb:
> Wie kann die Synthese dann fest stellen dass sie ihren Zustand nicht
> ändern?
Der Synthesizer bemängelt nicht, dass sie ihren Zustand nicht ändern, 
sondern, dass sie unbenutzt sind. Du kannst ein riesiges Design 
machen, aber wenn du keine Ausgänge hast, wird alles "wegoptimiert", 
denn egal was gemacht wird, aussen merkt es ja niemand, dass da was 
fehlt.

Matze schrieb:
> Ich habe ein an sich übersichtliches VDHL-Design, welches in der
> Behavorial-Simulation funktioniert.
Das sagt nicht viel. In der Simulation funktioniert sogar eine "wait for 
10 ms;" Anweisung tadellos.

> Dabei werden alle Signale zu Beginn mittels reset initialisiert und
> ihnen vielfach Werte zugewiesen.
Das sollte man mal mit eigenen Augen sehen. Oder andersrum: bisher hatte 
bei mir der Synthesizer mit solchen einfachen Behauptungen (...is 
unused...) immmer Recht...

Genauere Aussagen gibt es nur, wenn du die paar Quelldateien deines "an 
sich übersichtlichen" Desgins mal postest. So viele können das ja nicht 
sein.

von Bitwurschtler (Gast)


Lesenswert?

Matze schrieb:
> Dussel schrieb:
>> Wenn du ein Signal hast, das immer 0 ist, wird der entsprechende Pin auf
>> Masse gelegt und das Signal wegoptimiert.
>
> Die betreffenden Signale ändern ihren Zustand in der
> Behavorial-Simulation, sonst könnte die Schaltung auch nicht
> funktionieren.
>
> Wie kann die Synthese dann fest stellen dass sie ihren Zustand nicht
> ändern?

Wenn ich dich recht verstehe stellt die Synthese garnicht fest das deren 
Zustand konstant ist, sondern das dieser Zustand nirgends benutzt wird, 
also der Ausgang des FF o.ä. nicht verdrahtet ist.

Mglw führen deine Register ja auf ein SPI modul was nicht angeschlossen 
nach draussen verdrahtet ist.

Wenn du eine alternative synthesetool verwenden kannst (XST) dann 
versuch das mal mit diesem.

Im Zusammenhang mit Chipscope irrt sich die Synthese gelegentlich 
bezüglich des unused, da das chipscope-modul im design ohne ausgänge 
erscheint, der JTAG-Port steckt nur in der Netzliste. Aber das scheint 
hier nicht der Fall zu sein.

Problem ähnlicher Art könnte man bei SOC-FPGA's wie Zynq erwarten, wenn 
Module genutzt werden die nicht im FPGA-Anteil realisiert sind sondern 
als Hardcore bspw. Peripherals.

MfG,

von Dussel (Gast)


Lesenswert?

Lothar M. schrieb:
> Matze schrieb:
>> Wie kann die Synthese dann fest stellen dass sie ihren Zustand nicht
>> ändern?
> Der Synthesizer bemängelt nicht, dass sie ihren Zustand nicht ändern,
> sondern, dass sie unbenutzt sind. Du kannst ein riesiges Design
> machen, aber wenn du keine Ausgänge hast, wird alles "wegoptimiert",
> denn egal was gemacht wird, aussen merkt es ja niemand, dass da was
> fehlt.
Bei mir war damals das Problem, dass sich Signale wegen eines Fehlers 
nicht geändert haben. Deswegen wurde der entsprechende Ausgang auf einen 
festen Wert gelegt. Darauf hat der Synthesizer erkannt, dass der Ausgang 
auf einem festen Wert liegt und das entsprechende Signal unbenutzt ist 
und hat den ganzen Rest wegoptimiert. Da kam auch die Meldung mit dem 
unbenutzten Signal, aber die eigentliche Ursache war, dass das Signal 
konstant war.

Hier wurde ja das Signal auf einen Ausgang gelegt, wird aber trotzdem 
noch als unbenutzt wegoptimiert. Deshalb denke ich, dass hier der 
gleiche Fehler wie bei mir damals vorliegen könnte.

von Matze (Gast)


Lesenswert?

Lothar M. schrieb:
> Das sollte man mal mit eigenen Augen sehen. Oder andersrum: bisher hatte
> bei mir der Synthesizer mit solchen einfachen Behauptungen (...is
> unused...) immmer Recht...

Ja, sollte man:
Hier mal der Quellcode des SPI-Empfängers:
1
library IEEE;
2
use IEEE.STD_LOGIC_1164.ALL;
3
use ieee.std_logic_unsigned.all;
4
5
entity QSPI_Analyzer_Input is
6
    Port (  
7
            SYS_CLK         : in STD_LOGIC;                             -- 100MHZ-Clk
8
            SCLK            : in STD_LOGIC;                             -- clk des SPI-Bus
9
            DATA            : in STD_LOGIC_VECTOR (3 downto 0);         -- Daten des SPI-Bus
10
            CS              : in STD_LOGIC;                             -- CS-Leitung des SPI-Bus
11
            reset           : in Std_logic;                             -- Reset des QSPI-Interface
12
            out_reg         : out STD_LOGIC_VECTOR (7 downto 0);        -- 1 SPI-Word
13
            wren_out_reg    : out STD_LOGIC);                            -- ausgabe fuer "Daten gueltig"           
14
end QSPI_Analyzer_Input;
15
16
architecture Behavioral of QSPI_Analyzer_Input is                       -- um Aus 4 Datenleitungen + cs (5 Bit) einen 15-Bit Register wert zu machen,                                                      
17
begin
18
    SHIFT_PROC: process(SCLK, CS,  DATA, SYS_CLK, reset)                   -- Abtastung mit SPI-Clk, auch Aktiv mit SC, Mode, DATA, timetick
19
    begin
20
    if reset = '0' then
21
        if CS = '0' then-- cs_active                                         -- Beginned wenn CS Aktiviert wurde           
22
            if (rising_edge(SCLK)) then                                 -- Abtasten bei falling_edge wenn cs ausgelöst wurde     
23
                wren_out_reg <= '1';                                -- Nun sind die Daten nicht mehr gültig
24
                out_reg(0)<=DATA(0);                                -- Parallele Abtastung der 5 Eingangssignale
25
                out_reg(1)<=DATA(1);
26
                out_reg(2)<=DATA(2);
27
                out_reg(3)<=DATA(3);
28
                out_reg(4)<=CS;
29
            end if;
30
        else                                                                -- solange der CS nicht aktiv ist
31
            wren_out_reg <= '0';
32
        end if;
33
    else
34
        out_reg          <= x"00";                                --: out STD_LOGIC_VECTOR (15 downto 0);       -- 3 SPI-Worte in 1 16-Bit-Wort, Bit 15 ist frei
35
        wren_out_reg     <= '0';                                    --: out STD_LOGIC;                            -- ausgabe fuer "Daten gueltig"
36
    end if;
37
    end process;
38
39
end Behavioral;

Dazu kommt folgendes Main:
1
library IEEE;
2
use IEEE.STD_LOGIC_1164.ALL;
3
use ieee.std_logic_unsigned.all;
4
5
entity Main is
6
    Port (  CLK100MHZ   : in std_logic;
7
            SDATA       : in std_logic_vector(3 downto 0);
8
            SCS_IBUF    : in std_logic;
9
            SCLK_pin    : in std_logic;
10
            LED         : out Std_logic_vector(15 downto 0);
11
            RESET_PIN_N : in std_logic;
12
            C           : out std_logic_vector(7 downto 0);
13
            AN          : out std_logic_vector(7 downto 0);
14
            LED16_B     : out std_logic);
15
end Main;
16
17
architecture Behavioral of Main is
18
19
component Seg_Disp
20
    Port (  clk : in STD_LOGIC;
21
            disp_data : in STD_LOGIC_VECTOR (39 downto 0);
22
            led_out : out STD_LOGIC_VECTOR (7 downto 0);
23
            an_out : out STD_LOGIC_VECTOR (7 downto 0));
24
end component;
25
26
component Timetick
27
    Port (  clk                 : in STD_LOGIC;                         -- Systemoszillator
28
            reset               : in std_logic;            
29
            Sys_time            : out std_logic_vector (63 downto 0));  -- Systemzeit
30
end component;
31
32
component QSPI_Analyzer_Input
33
    Port (  
34
            SYS_CLK         : in STD_LOGIC;                             -- 100MHZ-Clk
35
            SCLK            : in STD_LOGIC;                             -- clk des SPI-Bus
36
            DATA            : in STD_LOGIC_VECTOR (3 downto 0);         -- Daten des SPI-Bus
37
            CS              : in STD_LOGIC;                             -- CS-Leitung des SPI-Bus
38
            reset           : in Std_logic;                             -- Reset des QSPI-Interface
39
            out_reg         : out STD_LOGIC_VECTOR (7 downto 0);       -- 3 SPI-Worte in 1 16-Bit-Wort, Bit 15 ist frei
40
            wren_out_reg    : out STD_LOGIC);                            -- ausgabe fuer "Daten gueltig"
41
end component;
42
43
signal aout_reg          : STD_LOGIC_VECTOR (7 downto 0);       -- 3 SPI-Worte in 1 16-Bit-Wort, Bit 15 ist frei
44
45
46
attribute dont_touch : string;
47
attribute dont_touch of aout_reg : signal is "true";
48
49
signal wren_out_reg : std_logic;
50
51
52
signal adisp_data    : std_logic_vector(39 downto 0);
53
signal reset_qspi_analyzer_input : std_logic;
54
55
begin   
56
57
    P1: process(RESET_PIN_N, CLK100MHZ, SCLK_pin, SDATA, SCS_IBUF)
58
    begin                     
59
        LED16_B                         <= NOT RESET_PIN_N;
60
        reset_qspi_analyzer_input       <= NOT RESET_PIN_N;
61
        if rising_edge(CLK100MHZ) then
62
            --disp_data(7 downto 0)       <= disp_data(7 downto 0) + '1';
63
            --disp_data(39 downto 8)       <= disp_data(39 downto 8) + '1';
64
            adisp_data(7 downto 0)     <= aout_reg;
65
            adisp_data(39 downto 8)    <= x"00000000";
66
            LED(7 downto 0)             <= aout_reg;
67
        end if;
68
    end Process;
69
70
    G1_1: QSPI_Analyzer_Input Port map (
71
            SYS_CLK           => CLK100MHZ,                 --!!! wird im Moment nicht benötigt
72
            SCLK              => SCLK_pin,                      --: in STD_LOGIC;                         -- clk des SPI-Bus
73
            DATA              => SDATA,                     --: in STD_LOGIC_VECTOR (3 downto 0);         -- Daten des SPI-Bus
74
            CS                => SCS_IBUF,                       --: in STD_LOGIC;                        -- CS-Leitung des SPI-Bus
75
            reset             => reset_qspi_analyzer_input, --: in Std_logic;                             -- Reset des QSPI-Interface
76
            out_reg           => aout_reg,                   --: out STD_LOGIC_VECTOR (15 downto 0);       -- 3 SPI-Worte in 1 16-Bit-Wort, Bit 15 ist frei
77
            wren_out_reg      => wren_out_reg);              --: out STD_LOGIC;                            -- ausgabe fuer "Daten gueltig"
78
79
    Disp: Seg_Disp Port map 
80
    (       clk             => CLK100MHZ,           --: in STD_LOGIC;
81
            disp_data       => adisp_data,
82
            led_out         => C,                    --: out STD_LOGIC_VECTOR (7 downto 0);
83
            an_out          => AN);                 --: out STD_LOGIC_VECTOR (7 downto 0));
84
85
end Behavioral;


Somit sollen die Daten wenn kein Reset anliegt, und der CS auf '0' ist 
sowohl auf die LED's als auch auf der 7-Seg-Anzeige ausgegeben werden.

Problem ist, dass die Fehlermeldung
1
[Synth 8-3332] Sequential element (\adisp_data_reg[0] ) is unused and will be removed from module Main.
für alle 8-Bits [0..7] des 7-Segment-Decoders erscheint.
Nicht jedoch für die LED's welche dann aber eigentlich auch "UNUSED" 
sein müssten.

Wird z.b. ein Counter auf die 7-Segment-Anzeige ausgegeben, dann treten 
die Warnungen nicht auf:
1
            disp_data(7 downto 0)       <= disp_data(7 downto 0) + '1';
2
            disp_data(39 downto 8)       <= disp_data(39 downto 8) + '1';
3
            --adisp_data(7 downto 0)     <= aout_reg;
4
            --adisp_data(39 downto 8)    <= x"00000000";

Wie kann es also sein, dass "aout_reg" für die LED's "used" ist, bei 
Anzeige auf 7-Segment jedoch keine zustandsänderung erfolgen soll?

Wiederspricht sich dass nicht?

von Achim S. (Gast)


Lesenswert?

Matze schrieb:
> Problem ist, dass die Fehlermeldung[Synth 8-3332] Sequential element
> (\adisp_data_reg[0] ) is unused and will be removed from module Main.
> für alle 8-Bits [0..7] des 7-Segment-Decoders erscheint.
> Nicht jedoch für die LED's welche dann aber eigentlich auch "UNUSED"
> sein müssten.

erst mal zur Begriffsklärung: deine Ausgänge "LED" hängen nicht von 
adisp_data ab sondern nur von areg. Wenn DispData auf etwas einen 
Einfluss haben sollte, dann auf die Ausgänge "C".

Ob Dispdata einen wirklichen Einfluss auf C hat sieht man nicht, weil 
das in der nicht gezeigten Komponente Seg_Disp festgelegt wird. Also: 
wie sieht Seg_Disp intern aus? Bei den Warnings sind Bits 39..4 von 
disp_data immer auf 0, beim Beispiel mit dem Counter ist das nicht der 
Fall. Macht das den Unterschied für Seg_Disp?

Noch eine Anmerkung zu deiner SPI-Komponente: deine Beschreibung mit 
rising_edge(sclk) ist unsauber (gibt es hierzu keine Warnings? Evtl. 
steckt schon hier der Grund für deine Warnung bei disp_data). Nutze 
lieber die 100MHz-Clock um sauber mit getakteten FlipFlops zu arbeiten, 
und machen an SCLK eine Flankenerkennung, wann die Werte von Data 
übernommen werden sollen.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Achim S. schrieb:
> deine Beschreibung mit rising_edge(sclk) ist unsauber (gibt es hierzu
> keine Warnings?
Ich würde hier wenigstens eine Meldung in Richtung "this is no good 
design practice" erwarten.
Man kann das mit dem lokalen Takt schon so machen. Allerdings sollte man 
sich dann ausführlich Gedanken zur Übergabe der Daten an die 100MHz 
Clock-Domäne machen.

Wenn im vorigen Absatz zu viele unbekannte Worte waren, dann empfehle 
ich streng synchrones Design (im gesamten Design nur 1 einziger Takt: 
der Oszillatortakt), wo alle externen Eingänge (auch die, die einen 
Namensteil "-clock" haben) einfach erst mal einsynchronisiert werden.

von Achim S. (Gast)


Lesenswert?

Lothar M. schrieb:
> Man kann das mit dem lokalen Takt schon so machen. Allerdings sollte man
> sich dann ausführlich Gedanken zur Übergabe der Daten an die 100MHz
> Clock-Domäne machen.

Ist in diesem Fall imho noch etwas problematischer, weil das 
"rising_edge(sclk)" innerhalb eines geschachtelten if-then-else steht 
(ein äußeres Konstrukt für den asynchronen Reset, aber drunter noch eine 
Abfrage für das CS und erst abhängig davon kommt das rising_edge). Ich 
bin mir nicht sicher, ob die geschachtelten if-then-else in die 
Generierung eines Reset-Signals zusammengefasst werden können (für 
wren_out ein Reset abhängig vom externen Signal Reset, für outreg ein 
Reset abhängig von den externen Signalen Reset und CS).

Wenn das nicht passiert, macht er mit SCLK hier nicht nur eine zweite 
Taktdomäne auf, sondern es wird noch verwickelter.

von Matze (Gast)


Lesenswert?

Danke für eure bisherigen Ratschläge ;)

Achim S. schrieb:
> Ob Dispdata einen wirklichen Einfluss auf C hat sieht man nicht, weil
> das in der nicht gezeigten Komponente Seg_Disp festgelegt wird. Also:
> wie sieht Seg_Disp intern aus?

Hier ist es, ein gewöhnlicher Multiplexer für 7Segment-Anzeigen:
1
library IEEE;
2
use IEEE.STD_LOGIC_1164.ALL;
3
use ieee.std_logic_unsigned.all;
4
5
entity Seg_Disp is
6
    Port (  clk : in STD_LOGIC;
7
            disp_data : in STD_LOGIC_VECTOR (39 downto 0);
8
            led_out : out STD_LOGIC_VECTOR (7 downto 0);
9
            an_out : out STD_LOGIC_VECTOR (7 downto 0));
10
end Seg_Disp;
11
12
architecture Behavioral of Seg_Disp is
13
signal count : std_logic_vector (19 downto 0); 
14
15
16
component Bcd_Dec 
17
    Port (  hex : in STD_LOGIC_VECTOR (3 downto 0);
18
            bcd : out STD_LOGIC_VECTOR (7 downto 0));
19
end component;
20
signal hex : std_logic_vector (3 downto 0);
21
signal bcd : std_logic_vector (7 downto 0);
22
begin
23
24
Seg_Disp: process(clk)
25
variable count_disp : integer;
26
begin
27
28
    if (rising_edge(clk)) then
29
        count <= count + 1;
30
        if count = x"20000" then
31
            count <= x"00000";
32
                case count_disp is
33
                    when 0 => 
34
                        count_disp := count_disp + 1;
35
                        an_out <= "01111111";
36
                        hex <= disp_data (3 downto 0);
37
                        led_out(6 downto 0) <= bcd(6 downto 0);
38
                        led_out(7) <= not disp_data(39);
39
                    when 1 =>
40
                        count_disp := count_disp + 1;
41
                        an_out <= "11111110";
42
                        hex <= disp_data (7 downto 4);
43
                        led_out(6 downto 0) <= bcd(6 downto 0);
44
                        led_out(7) <= not disp_data(32);
45
                    when 2 =>
46
                        count_disp := count_disp + 1;
47
                        an_out <= "11111101";
48
                        hex <= disp_data (11 downto 8);
49
                        led_out(6 downto 0) <= bcd(6 downto 0);
50
                        led_out(7) <=  not disp_data(33);
51
                    when 3 =>
52
                        count_disp := count_disp + 1;
53
                        an_out <= "11111011";
54
                        hex <= disp_data (15 downto 12);
55
                        led_out(6 downto 0) <= bcd(6 downto 0);
56
                        led_out(7) <= not disp_data(34);
57
                    when 4 =>
58
                        count_disp := count_disp + 1;
59
                        an_out <= "11110111";
60
                        hex <= disp_data (19 downto 16);
61
                        led_out(6 downto 0) <= bcd(6 downto 0);
62
                        led_out(7) <= not disp_data(35);
63
                    when 5 =>
64
                        count_disp := count_disp + 1;
65
                        an_out <= "11101111";
66
                        hex <= disp_data (23 downto 20);
67
                        led_out(6 downto 0) <= bcd(6 downto 0);
68
                        led_out(7) <= not disp_data(36);
69
                    when 6 =>
70
                        count_disp := count_disp + 1;
71
                        an_out <= "11011111";
72
                        hex <= disp_data (27 downto 24);
73
                        led_out(6 downto 0) <= bcd(6 downto 0);
74
                        led_out(7) <= not disp_data(37);
75
                    when 7 =>
76
                        count_disp := count_disp + 1;
77
                        an_out <= "10111111";
78
                        hex <= disp_data (31 downto 28);
79
                        led_out(6 downto 0) <= bcd(6 downto 0);
80
                        led_out(7) <= not disp_data(38);
81
                        count_disp := 0;
82
                    when others => an_out <= "11111111";
83
                end case;
84
        end if;
85
    end if;
86
end process;
87
88
G1_Bcd_Dec: Bcd_Dec port map (hex,bcd);
89
                
90
end Behavioral;

Er benutzt diesen BCD-Decoder:
1
library IEEE;
2
use IEEE.STD_LOGIC_1164.ALL;
3
4
entity Bcd_Dec is
5
    Port ( hex : in STD_LOGIC_VECTOR (3 downto 0);
6
           bcd : out STD_LOGIC_VECTOR (7 downto 0));
7
end Bcd_Dec;
8
9
architecture Behavioral of Bcd_Dec is
10
begin
11
BCD_Proc: Process (hex)
12
begin
13
    case hex is
14
    when "0000" => bcd <= "01000000"; --0
15
        when "0001" => bcd <= "01111001"; --1
16
        when "0010" => bcd <= "00100100"; --2
17
        when "0011" => bcd <= "00110000"; --3
18
        when "0100" => bcd <= "00011001"; --4
19
        when "0101" => bcd <= "00010010"; --5
20
        when "0110" => bcd <= "00000011"; --6
21
        when "0111" => bcd <= "01111000"; --7
22
        when "1000" => bcd <= "00000000"; --8
23
        when "1001" => bcd <= "00011000"; --9
24
        when "1010" => bcd <= "00001000"; --A --> "01110111"
25
        when "1011" => bcd <= "00000011"; --B --> "01111100"
26
        when "1100" => bcd <= "01000110"; --C --> "00111001"
27
        when "1101" => bcd <= "00100001"; --D --> "01011110"
28
        when "1110" => bcd <= "00000110"; --E --> "01111001"
29
        when "1111" => bcd <= "00001110"; --F --> "01110001"
30
        when others => bcd <= "00000000";
31
    end case;
32
end process;
33
end Behavioral;

Achim S. schrieb:
> Also:
> wie sieht Seg_Disp intern aus? Bei den Warnings sind Bits 39..4 von
> disp_data immer auf 0, beim Beispiel mit dem Counter ist das nicht der
> Fall. Macht das den Unterschied für Seg_Disp?

Tatsächlich, mann müsste erwarten dass die Bits 4..39 immer auf 0 sind 
und deshalb unused und ab 8 auch undriven sind. Allerdings kommt die 
Meldung unused für die Bits 0..7, lediglich für die Bits 8..39 gibt es:
[Synth 8-3295] tying undriven pin Disp:disp_data[37] to constant 0

Wobei das undriven nachvollziebar ist, das unused von 0..3 finde ich 
nicht nachvollziehbar.

Achim S. schrieb:
> Nutze
> lieber die 100MHz-Clock um sauber mit getakteten FlipFlops zu arbeiten,
> und machen an SCLK eine Flankenerkennung, wann die Werte von Data
> übernommen werden sollen.

Wie meinst du dass?
Ich möchte nur Daten übernehmen, wenn die der CLK sich sinvoll ändert. 
Darüber geben die 100MHZ je keine Information. Auch wünsche ich mir 
keine "Überabtastung" mit hoher Frequenz und meist den selben Werten. 
Deshalb gibt es an SCLK, welches ein CLK-Eingang ist, eine 
Pflankenerkennung.

Mein langfristiges Ziel ist die aufgenommenen Daten in ein FIFO zu 
schreiben. So hätte ich alles vor dem FIFO mit SCLK eingetacktet und die 
daten mit 100MHZ herausgeholt.

Warnings gibt es deshalb keine.

Lothar M. schrieb:
> Man kann das mit dem lokalen Takt schon so machen. Allerdings sollte man
> sich dann ausführlich Gedanken zur Übergabe der Daten an die 100MHz
> Clock-Domäne machen.

Die Übergabe soll letztendlich über einen FIFO passieren.
So sollte es doch keine Probleme geben?

Achim S. schrieb:
> Ist in diesem Fall imho noch etwas problematischer, weil das
> "rising_edge(sclk)" innerhalb eines geschachtelten if-then-else steht
> (ein äußeres Konstrukt für den asynchronen Reset, aber drunter noch eine
> Abfrage für das CS und erst abhängig davon kommt das rising_edge). Ich
> bin mir nicht sicher, ob die geschachtelten if-then-else in die
> Generierung eines Reset-Signals zusammengefasst werden können (für
> wren_out ein Reset abhängig vom externen Signal Reset, für outreg ein
> Reset abhängig von den externen Signalen Reset und CS).
>
> Wenn das nicht passiert, macht er mit SCLK hier nicht nur eine zweite
> Taktdomäne auf, sondern es wird noch verwickelter.

Dass dachte ich auch schon.
Würde gerne weniger Abfragen von Signalen mit rising_edge's quasi 
&-Verknüpft haben wollen.

Aber wie wird so etwas 'vereinfacht'?

von Achim S. (Gast)


Angehängte Dateien:

Lesenswert?

Matze schrieb:
> Mein langfristiges Ziel ist die aufgenommenen Daten in ein FIFO zu
> schreiben. So hätte ich alles vor dem FIFO mit SCLK eingetacktet und die
> daten mit 100MHZ herausgeholt.

ok, kannst du machen (wenn SCLK auf einen CLK-Eingang geht und wenn du 
auf das Framing mit CS verzichten willst - denn du wirst ggf. nur 
SCLK-Flanken bekommen, während CS low ist, und den Anfang/das Ende eines 
Frames nicht erkennen können).

Ich hatte Bedenken, dass das geschaltete if-then-else um die rising_edge 
Abfrage nicht zu einem Reset aufgelöst wird. Aber die Bedenken haben 
sich zerstreut, als ich eben deinen SPI-Code in Vivado eingegeben und 
mir das Synthese-Ergebnis angeschaut habe (siehe Anhang). Die 
geschachtelte if-then-else wird tatsächlich in eine Kombinatorik zur 
Erzeugung eines Resets aufgelöst, du hast also eine "saubere" zweite 
Taktdomäne.

Matze schrieb:
> Dass dachte ich auch schon.
> Würde gerne weniger Abfragen von Signalen mit rising_edge's quasi
> &-Verknüpft haben wollen.
>
> Aber wie wird so etwas 'vereinfacht'?

indem du alles mit SYSCLK taktest und eine Flankenerkennung auf SCLK 
machst, die das Abspeichern der Eingänge steuert.
http://www.lothar-miller.de/s9y/categories/18-Flankenerkennung

Matze schrieb:
> Hier ist es, ein gewöhnlicher Multiplexer für 7Segment-Anzeigen:

Tja, dem sehe ich auf die Schnelle ehrlich gesagt auch nicht an, wieso 
LED_out dieser Komponente / C des topmoduls nicht mit echten Daten 
getrieben werden sollten. Vielleicht kannst du dich ja mal durch die 
Ergebnisse deiner Synthese durcharbeiten (z.B. per schematic view) um zu 
sehen, wer laut Syntheseergebnis C treibt.

von Achim S. (Gast)


Lesenswert?

ok, ich denke jetzt hab ich den Grund für die Warnung gefunden.

adisp_out(3..0) und led_out(3..0) sind genau die identischen Daten. Es 
gibt keinen Grund, zwei identische Kopien unter zwei verschiedenen Namen 
zu führen. Deswegen wird adisp_out(3..0) wegoptimiert.

adisp_out(39..4) ist konstant 0 und braucht deswegen auch keine eigenen 
Flipflops.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.