Forum: FPGA, VHDL & Co. Aufgezeichneter Signalablauf in VHDL nicht nachvollziehbar?


von Matze (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,

Ich möchte in Vivado die ansteuerung eines Speichers Programmieren.
Verstehe jedoch die Logik nicht.

Im angehängten Bild, wird das Signal R_w auf 1 gesetzt, ohnen dass ein 
Setzen von R_w_en erfolgt.

Konkret sehe ich dass Problem darin, dass eine veränderung von R_w_en 
und R_w im beigefügten VHDL-Code niemals unabhängig voneinander erfolgt.

Das problem scheint im folgenden Code-Abschnitt

Hier wird zunächst in den deb_state = 4 gesprungen.
Da UART_SEND_rdy scheinbar = 1 ist, wird auf DDR_DDR2_rdy gewartet.
Nach erkennung des Rdy-signals wird DDR_R_w = 1 gesetzt.
DDR_R_w_en wird jedoch nicht auf 1 gesetzt.

Wie kann dass möglich sein?
1
               elsif state = read_data then --Daten geschrieben
2
                    deb_state <="100";
3
                    if UART_SEND_ready = '1' then           -- Wenn FIFO bereit Daten zu senden
4
                        if DDR_DDR2_rdy = '1' then          -- Daten Lesen     
5
                            DDR_Address <= ADDR_rd;
6
                            if ADDR_wr >= ADDR_rd and ueberlauf = '0' then
7
                                DDR_R_w <= '1';
8
                                DDR_R_w_en <= '1';
9
                                ADDR_rd <= ADDR_rd + 1;
10
                                state <= read_data_wait;
11
                                DDR_empty <= '0';                            
12
                            elsif ADDR_wr < ADDR_rd and ueberlauf = '1' then
13
                                DDR_R_w <= '1';
14
                                DDR_R_w_en <= '1';
15
                                state <= read_data_wait;
16
                                if ADDR_rd < x"ffffff" then
17
                                    ADDR_rd <= ADDR_rd + 1;
18
                                else
19
                                    ueberlauf <= '0';
20
                                    ADDR_rd <= x"000000";                                    
21
                                end if;
22
                                DDR_empty <= '0';
23
                            else
24
                                DDR_R_w <= '0';
25
                                DDR_R_w_en <= '0';
26
                                DDR_empty <= '1';
27
                                state <= idle;
28
                            end if;
29
                        end if;
30
                    else
31
                        DDR_R_w <= '0';
32
                        DDR_R_w_en <= '0';
33
                        state <= idle;
34
                    end if;
35
                elsif state = read_data_wait then
36
                    deb_state <="101";
37
                    DDR_R_w_en <= '0';
38
                    DDR_R_w <= '0';
39
                    state <= transmit_data;

Hier nochmals der Komplette VHLD-Code:
1
entity Main is
2
    Port ( 
3
            SYS_clk              : in STD_LOGIC;
4
            Reset               : in STD_LOGIC;
5
            -- UART_Control
6
            UART_SEND_data            : out STD_LOGIC_VECTOR (63 downto 0);    -- zu sendende Daten
7
            UART_SEND_data_en         : out STD_LOGIC;                         -- 1 -> Send_Data sollen gesendet werden
8
            UART_SEND_ready           : in std_logic;                        -- 1 -> bereit zum senden
9
            -- QSPI-BUFF
10
            BUFF_RD_sampled_data      : out STD_LOGIC;
11
            BUFF_SAMPLED_data_out     : in STD_LOGIC_VECTOR(63 downto 0);
12
            BUFF_FIFO_empty           : in STD_LOGIC;
13
            -- DDR_2_RAM
14
            DDR_R_w                 : out STD_LOGIC;
15
            DDR_R_w_en              : out STD_LOGIC;
16
            DDR_Address             : out STD_LOGIC_VECTOR(23 downto 0);
17
            DDR_DDR2_rdy            : in STD_LOGIC;
18
            DDR_DATA_out            : in STD_LOGIC_VECTOR(63 downto 0);
19
            DDR_DATA_in             : out STD_LOGIC_VECTOR(63 downto 0); 
20
            DDR_empty           : out STD_LOGIC;
21
            
22
            deb_ADDR_rd  : out STD_LOGIC_VECTOR(23 downto 0);
23
            deb_ADDR_wr  : out STD_LOGIC_VECTOR(23 downto 0);
24
            deb_ueberlauf: out STD_LOGIC;
25
            deb_WR_err   : out STD_LOGIC;
26
            deb_RD_err   : out STD_LOGIC;
27
            deb_state    : out STD_LOGIC_VECTOR(2 downto 0)
28
            );
29
end Main;
30
31
architecture Behavioral of Main is          
32
33
signal ADDR_rd  : STD_LOGIC_VECTOR(23 downto 0);
34
signal ADDR_wr  : STD_LOGIC_VECTOR(23 downto 0);
35
signal ueberlauf: STD_LOGIC;
36
signal WR_err   : STD_LOGIC;
37
signal RD_err   : STD_LOGIC;
38
type statetype is (get_data, write_data_ddr, write_data_ddr_wait, read_data, read_data_wait, transmit_data, idle);
39
signal state : statetype;
40
41
begin
42
    P1: Process(SYS_clk)
43
    begin
44
45
    
46
        if rising_edge(SYS_clk) then
47
48
            deb_ADDR_rd   <= ADDR_rd;   --: STD_LOGIC_VECTOR(23 downto 0);
49
            deb_ADDR_wr   <= ADDR_wr;   --: STD_LOGIC_VECTOR(23 downto 0);
50
            deb_ueberlauf <= ueberlauf; --: STD_LOGIC;
51
            deb_WR_err    <= WR_err;    --: STD_LOGIC;
52
            deb_RD_err    <= RD_err;    --: STD_LOGIC;
53
        
54
            if Reset = '1' then         -- Reset Aktiv
55
                UART_SEND_data_en <= '0';
56
                BUFF_RD_sampled_data <= '0';
57
                DDR_R_w <= '0';
58
                DDR_R_w_en <= '0';
59
                WR_err <= '0';
60
                RD_err <= '0';
61
                DDR_Address <= x"000000";
62
                DDR_DATA_in <= x"0000000000000000";
63
                UART_SEND_data <= x"0000000000000000";
64
                ADDR_rd <= x"000000";
65
                ADDR_wr <= x"000001";
66
                ueberlauf <= '0';
67
                DDR_empty <= '1';
68
                state <= idle;
69
            else -- Reset inaktiv
70
                if state = idle then            -- Wenn IDLE
71
                    deb_state <="000";
72
                    UART_SEND_data_en <= '0';
73
                    if BUFF_FIFO_empty = '0' then    -- Wenn fifo != empty --> Lesen
74
                        BUFF_RD_sampled_data <= '1';
75
                        state <= get_data;
76
                    end if;
77
                elsif state = get_data then     -- Wenn daten von FIFO gelesen
78
                    deb_state <="001";
79
                    BUFF_RD_sampled_data <= '0';
80
                    DDR_DATA_in <= BUFF_SAMPLED_data_out;-- Daten puffern
81
                    state <= write_data_ddr;
82
                elsif state = write_data_ddr then   -- Daten in DDR schreiben
83
                    deb_state <="010";
84
                    if DDR_DDR2_rdy = '1' then          -- Wenn DDR bereit --> Schreiben
85
                        DDR_Address <= ADDR_wr;
86
                        if ADDR_wr > ADDR_rd and ueberlauf = '0' then
87
                            DDR_R_w <= '0';
88
                            DDR_R_w_en <= '1';
89
                            if ADDR_wr < x"ffffff" then 
90
                            --Wenn Maximal Addresse erreicht --> an addresse 0 beginnen, falls bereits ausgelesen
91
                                ADDR_wr <= ADDR_wr + 1;
92
                                state <= write_data_ddr_wait;
93
                            else
94
                                state <= write_data_ddr_wait;
95
                                ADDR_wr <= x"000000";
96
                                ueberlauf <= '1';       -- Setzen überlauf hat stattgefunden
97
                            end if;                        
98
                        elsif ADDR_wr < ADDR_rd and ueberlauf = '1' then
99
                            DDR_R_w <= '0';
100
                            DDR_R_w_en <= '1';
101
                            state <= write_data_ddr_wait;
102
                            ADDR_wr <= ADDR_wr + 1;
103
                        else
104
                            DDR_R_w <= '0';
105
                            DDR_R_w_en <= '0';
106
                            WR_err <= '1';                     
107
                        end if; 
108
                    end if;
109
                elsif state = write_data_ddr_wait then    
110
                    deb_state <="011";
111
                    DDR_R_w_en <= '0';
112
                    state <= read_data;
113
                elsif state = read_data then --Daten geschrieben
114
                    deb_state <="100";
115
                    if UART_SEND_ready = '1' then           -- Wenn FIFO bereit Daten zu senden
116
                        if DDR_DDR2_rdy = '1' then          -- Daten Lesen     
117
                            DDR_Address <= ADDR_rd;
118
                            if ADDR_wr >= ADDR_rd and ueberlauf = '0' then
119
                                DDR_R_w <= '1';
120
                                DDR_R_w_en <= '1';
121
                                ADDR_rd <= ADDR_rd + 1;
122
                                state <= read_data_wait;
123
                                DDR_empty <= '0';                            
124
                            elsif ADDR_wr < ADDR_rd and ueberlauf = '1' then
125
                                DDR_R_w <= '1';
126
                                DDR_R_w_en <= '1';
127
                                state <= read_data_wait;
128
                                if ADDR_rd < x"ffffff" then
129
                                    ADDR_rd <= ADDR_rd + 1;
130
                                else
131
                                    ueberlauf <= '0';
132
                                    ADDR_rd <= x"000000";                                    
133
                                end if;
134
                                DDR_empty <= '0';
135
                            else
136
                                DDR_R_w <= '0';
137
                                DDR_R_w_en <= '0';
138
                                DDR_empty <= '1';
139
                                state <= idle;
140
                            end if;
141
                        end if;
142
                    else
143
                        DDR_R_w <= '0';
144
                        DDR_R_w_en <= '0';
145
                        state <= idle;
146
                    end if;
147
                elsif state = read_data_wait then
148
                    deb_state <="101";
149
                    DDR_R_w_en <= '0';
150
                    DDR_R_w <= '0';
151
                    state <= transmit_data;
152
                elsif state = transmit_data then
153
                    deb_state <="110";
154
                    DDR_R_w <= '0';
155
                    DDR_R_w_en <= '0';
156
                    if DDR_DDR2_rdy = '1' then
157
                        UART_SEND_data <= DDR_DATA_out;
158
                        UART_SEND_data_en <= '1';
159
                        state <= idle;
160
                    end if;
161
                end if;
162
            end if;
163
        end if;
164
    end Process;
165
end Behavioral;

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


Lesenswert?

Matze schrieb:
> Konkret sehe ich dass Problem darin, dass eine veränderung von R_w_en
> und R_w im beigefügten VHDL-Code niemals unabhängig voneinander erfolgt.
Doch, dort:
1
       ...
2
                            DDR_R_w <= '0';
3
                            DDR_R_w_en <= '1';
4
        ...
Und deshalb wird für diese beiden Signale eine unterschiedliche Logik 
erzeugt. Wenn du nun einen schnellen Takt und die Constraints nicht oder 
falsch angegeben hast, dann kann es schon sein, dass sich die beiden 
Signale unterschiedlich verhalten...

Also stellen sich diese Fragen:
Welche Frequenz hat SYS_clk?
Weiß das die Toolchain?

von Matze (Gast)


Lesenswert?

Lothar M. schrieb:
> Doch, dort:       ...
>                             DDR_R_w <= '0';
>                             DDR_R_w_en <= '1';
>         ...
> Und deshalb wird für diese beiden Signale eine unterschiedliche Logik
> erzeugt. Wenn du nun einen schnellen Takt und die Constraints nicht oder
> falsch angegeben hast, dann kann es schon sein, dass sich die beiden
> Signale unterschiedlich verhalten...

Nein, hier wird R_w_en auf 1 gesetzt, während R_w auf 0 bleibt.

Dies steht für schreibe aufs RAM uns sollte auch so sein.
Im Bild wird R_w auf 1 gesetzt, R_w_en bleibt auf 0.
Dies kommt nie vor.

Lothar M. schrieb:
> Wenn du nun einen schnellen Takt und die Constraints nicht oder
> falsch angegeben hast, dann kann es schon sein, dass sich die beiden
> Signale unterschiedlich verhalten...

Ich habe einen 100MHz Takt, was auch in den Constraints steht.

Die Toolchain ist Vovado 2015.4.

von Markus F. (Gast)


Lesenswert?

Ich sehe, dass in den states nicht alles Signale überall belegt sind. 
Damit kommt der Ablauf ins Spiel. Soll das so sein? Ich überschaue das 
nämlich schon nicht mehr.

von bko (Gast)


Lesenswert?

In der Waveform sehe ich Main_0 und Main_1, da ist doch mehr Code oder?

von Matze (Gast)


Lesenswert?

Markus F. schrieb:
> Ich sehe, dass in den states nicht alles Signale überall belegt sind.
> Damit kommt der Ablauf ins Spiel. Soll das so sein? Ich überschaue das
> nämlich schon nicht mehr.

Wäre es übersichtlicher wenn in alles States alle Signale zugewiesen 
würden?

bko schrieb:
> In der Waveform sehe ich Main_0 und Main_1, da ist doch mehr Code oder?

Leider kann ich nun selbst auf die schnelle nicht mehr nachvollziehen, 
warum dass so ist.
Mehr Code ist da jedenfalls nicht.

von bko (Gast)


Lesenswert?

Ah ok die Waveform ist vom Logikanalyzer und nicht Simuliert?
Da ist auch kein Signal Vertauscht?

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.