Forum: FPGA, VHDL & Co. Custom IP-Core hängt sich auf.


von Florian R. (flo0815)


Lesenswert?

Hallo VHDL-Gemeinde,

schon wieder habe ich - wer hätte das gedacht - ein Problem. Ein 
selbstgebastelter IP-Core, der in der Simulation einwandfrei 
funktioniert, scheint sich auf dem FPGA immer wieder aufzuhängen.

Zentraler Teil ist eine FSM. Die variable r wird durch Triggerimpulse 
gezählt und eine weitere Zählvariable gemäß einem Bitmuster mitgezählt. 
Nach einigen Triggerimpulsen bleibt alles stehen, hier mal der Code:
1
library IEEE;
2
use IEEE.STD_LOGIC_1164.ALL;
3
use IEEE.NUMERIC_STD.ALL;
4
5
--------------------------------------------------------------------
6
entity CALC is
7
--------------------------------------------------------------------
8
  Port ( ETrigger_C       : in  STD_LOGIC;
9
       SWDTTrigger_C      : in  STD_LOGIC;
10
       clk_C          : in  STD_LOGIC;
11
       Dir_C          : in  STD_LOGIC;
12
       Resetr_C        : in  STD_LOGIC;
13
       ResetN_C        : in  STD_LOGIC;
14
       ResetMOD_C        : in  STD_LOGIC;
15
       EnableMOD_C      : in  STD_LOGIC;
16
       EnableAdapt_C      : in  STD_LOGIC;
17
       AzimuthType_C      : in  STD_LOGIC;
18
       CounterValue_C    : in  STD_LOGIC_VECTOR (16 downto 0);
19
       rmax_C          : in  UNSIGNED(15 downto 0);
20
       MODref_C        : in  UNSIGNED(31 downto 0);
21
       NT_C            : in  SIGNED(19 downto 0);
22
       h_times_g_C      : in  UNSIGNED(19 downto 0);
23
       
24
       Reset_C          : out STD_LOGIC;
25
       Busy_C          : out STD_LOGIC;
26
       DirOut_C        : out STD_LOGIC;
27
       N_C            : out SIGNED(19 downto 0);
28
       dN_C            : out UNSIGNED(15 downto 0);
29
       ND_C            : out UNSIGNED(15 downto 0);
30
       r_C            : out UNSIGNED(15 downto 0);
31
       MOD_C          : out UNSIGNED(31 downto 0));
32
  end CALC;
33
--------------------------------------------------------------------
34
35
--------------------------------------------------------------------
36
architecture Behavioral of CALC is
37
--------------------------------------------------------------------
38
39
  constant PSTable : STD_LOGIC_VECTOR (1023 downto 0):="00100001000010000100000100001000010000100001000010000100001000001000010"
40
                                    & "00010000100001000010000100001000010000010000100001000010000100001000010"
41
                                    & "00010000010000100001000010000100001000010000100001000001000010000100001"
42
                                    & "00001000010000100001000001000010000100001000010000100001000010000010000"
43
                                    & "10000100001000010000100001000010000100000100001000010000100001000010000"
44
                                    & "10000100000100001000010000100001000010000100001000001000010000100001000"
45
                                    & "01000010000100001000001000010000100001000010000100001000010000100000100"
46
                                    & "00100001000010000100001000010000100000100001000010000100001000010000100"
47
                                    & "00100000100001000010000100001000010000100001000010000010000100001000010"
48
                                    & "00010000100001000010000010000100001000010000100001000010000100000100001"
49
                                    & "00001000010000100001000010000100001000001000010000100001000010000100001"
50
                                    & "00001000001000010000100001000010000100001000010000100000100001000010000"
51
                                    & "10000100001000010000100000100001000010000100001000010000100001000001000"
52
                                    & "01000010000100001000010000100001000001000010000100001000010000100001000"
53
                                    & "010000100000100001000010000100";
54
  
55
  --type MODTable is array (0 to 50) of INTEGER RANGE 0 TO 255 ;
56
  --constant MODFactorRed : MODTable:=(128,127,126,125,124,123,122,121,120,119,118,117,116,115,114,113,112,111,110,109,108,107,106,105,104,103,102,101,100,98,96,94,92,90,88,86,84,82,80,78,76,74,72,70,68,66,64,62,60,58,56);
57
  --constant MODFActorEnl : MODTable:=(128,129,130,131,132,133,134,135,136,137,138,139,140,142,144,146,148,150,152,154,156,158,160,164,168,172,176,180,184,188,192,196,200,204,208,212,216,220,224,228,232,236,240,244,248,252,255,255,255,255,255);
58
  
59
---------------------------------------------------------------------                                    
60
  component Divider is
61
    Generic ( b  : natural range 4 to 32 := 32 ); 
62
      Port ( start     : in   STD_LOGIC;
63
           divisor   : in   STD_LOGIC_VECTOR (b-1 downto 0);
64
           dividend  : in   STD_LOGIC_VECTOR (b-1 downto 0);
65
           quotient  : out  STD_LOGIC_VECTOR (b-1 downto 0);
66
           remainder : out  STD_LOGIC_VECTOR (b-1 downto 0);
67
           busy      : out  STD_LOGIC;
68
           clk       : in   STD_LOGIC);
69
  end component;
70
---------------------------------------------------------------------
71
  type state is (Init, Idle, Calc_N, Calc_dN, Calc_MOD, Calc_ND, WaitOneClk, Done);
72
  signal s         : state;
73
  signal countervalue   : STD_LOGIC_VECTOR(16 downto 0);
74
  signal startDIV      : STD_LOGIC:='0';
75
  signal divisorDIV    : STD_LOGIC_VECTOR (16 downto 0);
76
  signal quotientDIV   : STD_LOGIC_VECTOR (16 downto 0);
77
  signal busyDIV       : STD_LOGIC:='0';
78
  signal EFlag      : STD_LOGIC;
79
  signal EFlagReset    : STD_LOGIC;
80
  signal SWDTFlag    : STD_LOGIC;
81
  signal SWDTFlagReset : STD_LOGIC;
82
---------------------------------------------------------------------  
83
  begin
84
  
85
    instDivider : Divider
86
      Generic Map ( b => 17 )
87
      Port Map    ( start     => startDIV,
88
                divisor   => divisorDIV,
89
                dividend  => std_logic_vector(to_unsigned(97656,17)),
90
                quotient  => quotientDIV,
91
                remainder => open,
92
                busy      => busyDIV,
93
                clk       => clk_C);
94
95
---------------------------------------------------------------------  
96
    FSM : process 
97
---------------------------------------------------------------------
98
    type NTArray is array (3 downto 0) of SIGNED(19 downto 0);
99
    variable NT        : NTArray;
100
    variable dNsquare    : UNSIGNED(31 downto 0);
101
    variable ND64bitfp  : UNSIGNED(63 downto 0);
102
    variable r         : UNSIGNED(15 downto 0):=to_unsigned(1,16);
103
    variable N         : SIGNED(19 downto 0):=to_signed(0,20);
104
    variable dN        : UNSIGNED(15 downto 0):=to_unsigned(0,16);
105
    variable ND        : UNSIGNED(15 downto 0):=to_unsigned(0,16);
106
    variable dir      : STD_LOGIC_VECTOR(3 downto 0):="0000";
107
    variable Modifier    : UNSIGNED(31 downto 0);
108
    variable Modifier40b  : UNSIGNED(39 downto 0); 
109
    variable absDeltaN  : UNSIGNED(19 downto 0);
110
    variable factor    : UNSIGNED(7 downto 0);
111
    
112
    begin
113
    
114
      wait until rising_edge(clk_c);
115
      
116
      If Resetr_C = '1'   then r := to_unsigned(1,16); else r := r;            end if;
117
      If ResetN_C = '1'   then N := to_signed(0,20);   else N := N;             end if;
118
      If ResetMOD_C = '1' then Modifier := MODref_C;   else Modifier := Modifier; end if;
119
      
120
      -------------------------------------------------------
121
      case s is 
122
      -------------------------------------------------------
123
        ----------------------------------------------------
124
        when Init    =>
125
        ----------------------------------------------------
126
          Modifier := MODref_C;
127
          s <= Idle;
128
        
129
         ----------------------------------------------------
130
        when Idle    =>
131
         ----------------------------------------------------  
132
          Reset_C <= '0';
133
          if EFlag='1' then
134
            Busy_C <= '1';
135
            EFlagReset <= '1';
136
            If Dir_C='1' then r := r + 1; else r := r - 1; end if;
137
            If r = 0 then r := rmax_C; elsif r > rmax_C then r := r - rmax_C; end if;
138
            If PSTable(to_integer(r)-1)='1' then
139
              countervalue <= CounterValue_C;
140
              Reset_C <= '1';
141
              dir := to_stdlogicvector(to_bitvector(dir) sll 1);
142
              dir(0) := Dir_C;
143
              NT(3 downto 1):=NT(2 downto 0);
144
              NT(0) := NT_C;
145
              s <= Calc_N; 
146
            else 
147
              s <= Done; 
148
            end if;
149
          elsif SWDTFlag='1' then
150
            Busy_C <= '1';
151
            SWDTFlagReset <='1';
152
            dN := to_unsigned(0,16);
153
            ND := to_unsigned(0,16);
154
            s  <= Done;
155
          else
156
            EFlagReset <= '0';
157
            SWDTFlagReset <= '0';
158
            Busy_C <= '0';
159
            s <= Idle;
160
          end if;
161
          
162
         ------------------------------------------------------  
163
        when Calc_N    =>
164
         ------------------------------------------------------
165
          If dir(0)='1' then N := N + 1; else N := N - 1; end if;
166
          If AzimuthType_C = '1' then
167
            If   N < 0                then N := N + signed(h_times_g_C); 
168
            elsif N > signed(h_times_g_C-1) then N := N - signed(h_times_g_C);
169
            else                               N := N;                 
170
            end if;
171
          else
172
            N := N;
173
          end if;
174
          s <= Calc_dN;
175
  
176
         ------------------------------------------------------  
177
        when Calc_dN  =>
178
        ------------------------------------------------------
179
          if dir(0)=dir(1) then
180
            If busyDIV='0' and startDIV='0' then
181
              divisorDIV  <= countervalue;
182
              startDIV <= '1';
183
              s <= WaitOneClk;
184
            elsif busyDIV='0' and startDIV='1' then
185
              dN := unsigned(quotientDIV(15 downto 0));
186
              startDIV <= '0';
187
              If EnableAdapt_C = '1' and NT(3)=NT(2) and NT(2)=NT(1) and NT(1)=NT(0) then
188
                s <= Calc_MOD;
189
              else
190
                s <= Calc_ND;
191
              end if;
192
            else
193
              s <= Calc_dN;
194
            end if;
195
          else
196
            dN := to_unsigned(0,16);
197
            ND := to_unsigned(0,16);
198
            s  <= Done;
199
          end if;
200
          
201
        -------------------------------------------------------
202
        when Calc_MOD =>
203
        -------------------------------------------------------
204
          absDeltaN := unsigned(abs(NT_C - N));
205
            If    (dir(3)=dir(2) and dir(2)/=dir(1) and dir(1)/=dir(0)) then  -- reduce  Modifier
206
              If absDeltaN > to_unsigned(64,20) then 
207
                factor := to_unsigned(64,8);
208
              else
209
                factor := 128 - absDeltaN(7 downto 0);--to_unsigned(MODFactorRed(to_integer(absDeltaN)),8);
210
              end if;  
211
            elsif (dir(3)=dir(2) and dir(2)/=dir(1) and dir(1) =dir(0)) then  -- enlarge Modifier
212
              If absDeltaN > to_unsigned(64,20) then
213
                factor := to_unsigned(255,8);
214
              else
215
                factor := 128 + absDeltaN(7 downto 0);--to_unsigned(MODFactorEnl(to_integer(absDeltaN)),8);
216
              end if;
217
            else
218
              factor := to_unsigned(128,8);
219
            end if;
220
          Modifier40b := Modifier * "000000000000000000000000"&factor / 128;
221
          Modifier := Modifier40b(31 downto 0);
222
          s <= Calc_ND;
223
              
224
        -------------------------------------------------------
225
        when Calc_ND  =>
226
        -------------------------------------------------------
227
          dNsquare := dN * dN;
228
          If EnableMOD_C = '0' then
229
            ND64bitfp := MODref_C * dNsquare;
230
          else
231
            ND64bitfp := Modifier * dNsquare;
232
          end if;
233
          ND := ND64bitfp(47 downto 32);
234
          s <= Done;
235
          
236
        -------------------------------------------------------
237
        when WaitOneClk  =>
238
        -------------------------------------------------------
239
          s <= Calc_dN;
240
          
241
        -------------------------------------------------------
242
        when Done    =>
243
        -------------------------------------------------------
244
          Busy_C <= '0';
245
          s <= Idle;
246
      
247
      ----------------------------------------------------------
248
      end case;
249
      ----------------------------------------------------------
250
    
251
      r_C <= r;
252
      N_C <= N;
253
      dN_C <= dN;
254
      ND_C <= ND;
255
      DirOut_C <= dir(0);
256
      MOD_C  <= Modifier;
257
    
258
    end process;
259
    
260
-------------------------------------------------------------------        
261
    EFlipFlop : process(ETrigger_C, EFlagReset)
262
-------------------------------------------------------------------
263
    begin
264
      If EFlagReset='1' then
265
        EFlag <='0';
266
      elsif rising_edge(ETrigger_C) then
267
        EFlag <='1';
268
      end if;
269
    end process;
270
    
271
-------------------------------------------------------------------        
272
    SWDTFlipFlop : process(SWDTTrigger_C, SWDTFlagReset)
273
-------------------------------------------------------------------
274
    begin
275
      If SWDTFlagReset='1' then
276
        SWDTFlag <='0';
277
      elsif rising_edge(SWDTTrigger_C) then
278
        SWDTFlag <='1';
279
      end if;
280
    end process;
281
  end Behavioral;

Ich hab ich anderen Beiträgen was über "Eintakten" gelesen. Kann hier 
der Fehler liegen?
Der daranhängende MicroBlaze bleibt nicht hängen, nur der IPCore.
Wie gesagt, stelle ich das Szenario im Simulator nach, dann funktioniert 
alles. Allerdings ist das natürlich das VHDL Modell ohne 
Schnittstellenanbindung, aber daran kanns ja eigentlich nicht liegen.

Wäre für jeden Tipp sehr dankbar. Vielleicht hat schon mal jemand 
ähnliche Erfahrungen gemacht.

Vielen Dank.

Gruß
Flo

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


Lesenswert?

Du hast 3 Taktdomänen:
> rising_edge(clk_c)
> rising_edge(ETrigger_C)
> rising_edge(SWDTTrigger_C)
Und du fragst in der ersten Domäne (clk_c) Signale ab, die von den 
beiden anderen asynchron gesetzt werden (EFlag und SWDTFlag). Das wird 
garantiert Probleme geben (Hintergrund: Laufzeiten im FPGA, siehe 
http://www.lothar-miller.de/s9y/categories/35-Einsynchronisieren)


> EFlag
> SWDTFlag
Sieh dir mal an, wie man einen Spike in einen synchronen Puls umwandelt: 
http://www.lothar-miller.de/s9y/categories/19-SpikePuls


> Wie gesagt, stelle ich das Szenario im Simulator nach,
> dann funktioniert alles.
Solche Fehler findest du in der Verhaltenssimulation niemals, in einer 
Post-Route-Simulation evtl. zufällig. Du mußt diese Fehler per Design 
ausschliessen (= Lernen, Üben, Wissen)...  :-o

von Florian R. (flo0815)


Lesenswert?

Danke für die Tipps.
Nach genauerer Überlegung können gar keine Spikes auftreten. Habe das 
Ganze also so abgewandelt:
1
library IEEE;
2
use IEEE.STD_LOGIC_1164.ALL;
3
use IEEE.NUMERIC_STD.ALL;
4
5
--------------------------------------------------------------------
6
entity CALC is
7
--------------------------------------------------------------------
8
  Port ( ETrigger_C       : in  STD_LOGIC;
9
       SWDTTrigger_C      : in  STD_LOGIC;
10
       clk_C          : in  STD_LOGIC;
11
       Dir_C          : in  STD_LOGIC;
12
       Resetr_C        : in  STD_LOGIC;
13
       ResetN_C        : in  STD_LOGIC;
14
       ResetMOD_C        : in  STD_LOGIC;
15
       EnableMOD_C      : in  STD_LOGIC;
16
       EnableAdapt_C      : in  STD_LOGIC;
17
       AzimuthType_C      : in  STD_LOGIC;
18
       CounterValue_C    : in  STD_LOGIC_VECTOR (16 downto 0);
19
       rmax_C          : in  UNSIGNED(15 downto 0);
20
       MODref_C        : in  UNSIGNED(31 downto 0);
21
       NT_C            : in  SIGNED(19 downto 0);
22
       h_times_g_C      : in  UNSIGNED(19 downto 0);
23
       
24
       Reset_C          : out STD_LOGIC;
25
       Busy_C          : out STD_LOGIC;
26
       DirOut_C        : out STD_LOGIC;
27
       N_C            : out SIGNED(19 downto 0);
28
       dN_C            : out UNSIGNED(15 downto 0);
29
       ND_C            : out UNSIGNED(15 downto 0);
30
       r_C            : out UNSIGNED(15 downto 0);
31
       MOD_C          : out UNSIGNED(31 downto 0));
32
  end CALC;
33
--------------------------------------------------------------------
34
35
--------------------------------------------------------------------
36
architecture Behavioral of CALC is
37
--------------------------------------------------------------------
38
39
  constant PSTable : STD_LOGIC_VECTOR (1023 downto 0):="00100001000010000100000100001000010000100001000010000100001000001000010"
40
                                    & "00010000100001000010000100001000010000010000100001000010000100001000010"
41
                                    & "00010000010000100001000010000100001000010000100001000001000010000100001"
42
                                    & "00001000010000100001000001000010000100001000010000100001000010000010000"
43
                                    & "10000100001000010000100001000010000100000100001000010000100001000010000"
44
                                    & "10000100000100001000010000100001000010000100001000001000010000100001000"
45
                                    & "01000010000100001000001000010000100001000010000100001000010000100000100"
46
                                    & "00100001000010000100001000010000100000100001000010000100001000010000100"
47
                                    & "00100000100001000010000100001000010000100001000010000010000100001000010"
48
                                    & "00010000100001000010000010000100001000010000100001000010000100000100001"
49
                                    & "00001000010000100001000010000100001000001000010000100001000010000100001"
50
                                    & "00001000001000010000100001000010000100001000010000100000100001000010000"
51
                                    & "10000100001000010000100000100001000010000100001000010000100001000001000"
52
                                    & "01000010000100001000010000100001000001000010000100001000010000100001000"
53
                                    & "010000100000100001000010000100";
54
  
55
---------------------------------------------------------------------                                    
56
  component Divider is
57
    Generic ( b  : natural range 4 to 32 := 32 ); 
58
      Port ( start     : in   STD_LOGIC;
59
           divisor   : in   STD_LOGIC_VECTOR (b-1 downto 0);
60
           dividend  : in   STD_LOGIC_VECTOR (b-1 downto 0);
61
           quotient  : out  STD_LOGIC_VECTOR (b-1 downto 0);
62
           remainder : out  STD_LOGIC_VECTOR (b-1 downto 0);
63
           busy      : out  STD_LOGIC;
64
           clk       : in   STD_LOGIC);
65
  end component;
66
---------------------------------------------------------------------
67
  type state is (Init, Idle, Calc_N, Calc_dN, Calc_MOD, Calc_ND, WaitOneClk, Done);
68
  signal s         : state;
69
  signal countervalue   : STD_LOGIC_VECTOR(16 downto 0);
70
  signal startDIV      : STD_LOGIC:='0';
71
  signal divisorDIV    : STD_LOGIC_VECTOR (16 downto 0);
72
  signal quotientDIV   : STD_LOGIC_VECTOR (16 downto 0);
73
  signal busyDIV       : STD_LOGIC:='0';
74
  signal Esr        : STD_LOGIC_VECTOR(2 downto 0);
75
  signal SWDTsr      : STD_LOGIC_VECTOR(2 downto 0);
76
---------------------------------------------------------------------  
77
  begin
78
  
79
    instDivider : Divider
80
      Generic Map ( b => 17 )
81
      Port Map    ( start     => startDIV,
82
                divisor   => divisorDIV,
83
                dividend  => std_logic_vector(to_unsigned(97656,17)),
84
                quotient  => quotientDIV,
85
                remainder => open,
86
                busy      => busyDIV,
87
                clk       => clk_C);
88
89
---------------------------------------------------------------------  
90
    FSM : process 
91
---------------------------------------------------------------------
92
    type NTArray is array (3 downto 0) of SIGNED(19 downto 0);
93
    variable NT        : NTArray;
94
    variable dNsquare    : UNSIGNED(31 downto 0);
95
    variable ND64bitfp  : UNSIGNED(63 downto 0);
96
    variable r         : UNSIGNED(15 downto 0):=to_unsigned(1,16);
97
    variable N         : SIGNED(19 downto 0):=to_signed(0,20);
98
    variable dN        : UNSIGNED(15 downto 0):=to_unsigned(0,16);
99
    variable ND        : UNSIGNED(15 downto 0):=to_unsigned(0,16);
100
    variable dir      : STD_LOGIC_VECTOR(3 downto 0):="0000";
101
    variable Modifier    : UNSIGNED(31 downto 0);
102
    variable Modifier40b  : UNSIGNED(39 downto 0); 
103
    variable absDeltaN  : UNSIGNED(19 downto 0);
104
    variable factor    : UNSIGNED(7 downto 0);
105
    
106
    begin
107
    
108
      wait until rising_edge(clk_c);
109
      
110
      If Resetr_C = '1'   then r := to_unsigned(1,16); else r := r;            end if;
111
      If ResetN_C = '1'   then N := to_signed(0,20);   else N := N;             end if;
112
      If ResetMOD_C = '1' then Modifier := MODref_C;   else Modifier := Modifier; end if;
113
      
114
      -------------------------------------------------------
115
      case s is 
116
      -------------------------------------------------------
117
        ----------------------------------------------------
118
        when Init    =>
119
        ----------------------------------------------------
120
          Modifier := MODref_C;
121
          s <= Idle;
122
        
123
         ----------------------------------------------------
124
        when Idle    =>
125
         ----------------------------------------------------  
126
          Reset_C <= '0';
127
          if Esr(2 downto 1)="01" then
128
            Busy_C <= '1';
129
            If Dir_C='1' then r := r + 1; else r := r - 1; end if;
130
            If r = 0 then r := rmax_C; elsif r > rmax_C then r := r - rmax_C; end if;
131
            If PSTable(to_integer(r)-1)='1' then
132
              countervalue <= CounterValue_C;
133
              Reset_C <= '1';
134
              dir := to_stdlogicvector(to_bitvector(dir) sll 1);
135
              dir(0) := Dir_C;
136
              NT(3 downto 1):=NT(2 downto 0);
137
              NT(0) := NT_C;
138
              s <= Calc_N; 
139
            else 
140
              s <= Done; 
141
            end if;
142
          elsif SWDTsr(2 downto 1)="01" then
143
            Busy_C <= '1';
144
            dN := to_unsigned(0,16);
145
            ND := to_unsigned(0,16);
146
            s  <= Done;
147
          else
148
            Busy_C <= '0';
149
            s <= Idle;
150
          end if;
151
          
152
         ------------------------------------------------------  
153
        when Calc_N    =>
154
         ------------------------------------------------------
155
          If dir(0)='1' then N := N + 1; else N := N - 1; end if;
156
          If AzimuthType_C = '1' then
157
            If   N < 0                then N := N + signed(h_times_g_C); 
158
            elsif N > signed(h_times_g_C-1) then N := N - signed(h_times_g_C);
159
            else                               N := N;                 
160
            end if;
161
          else
162
            N := N;
163
          end if;
164
          s <= Calc_dN;
165
  
166
         ------------------------------------------------------  
167
        when Calc_dN  =>
168
        ------------------------------------------------------
169
          if dir(0)=dir(1) then
170
            If busyDIV='0' and startDIV='0' then
171
              divisorDIV  <= countervalue;
172
              startDIV <= '1';
173
              s <= WaitOneClk;
174
            elsif busyDIV='0' and startDIV='1' then
175
              dN := unsigned(quotientDIV(15 downto 0));
176
              startDIV <= '0';
177
              If EnableAdapt_C = '1' and NT(3)=NT(2) and NT(2)=NT(1) and NT(1)=NT(0) then
178
                s <= Calc_MOD;
179
              else
180
                s <= Calc_ND;
181
              end if;
182
            else
183
              s <= Calc_dN;
184
            end if;
185
          else
186
            dN := to_unsigned(0,16);
187
            ND := to_unsigned(0,16);
188
            s  <= Done;
189
          end if;
190
          
191
        -------------------------------------------------------
192
        when Calc_MOD =>
193
        -------------------------------------------------------
194
          absDeltaN := unsigned(abs(NT_C - N));
195
            If    (dir(3)=dir(2) and dir(2)/=dir(1) and dir(1)/=dir(0)) then  -- reduce  Modifier
196
              If absDeltaN > to_unsigned(64,20) then 
197
                factor := to_unsigned(64,8);
198
              else
199
                factor := 128 - absDeltaN(7 downto 0);
200
              end if;  
201
            elsif (dir(3)=dir(2) and dir(2)/=dir(1) and dir(1) =dir(0)) then  -- enlarge Modifier
202
              If absDeltaN > to_unsigned(64,20) then
203
                factor := to_unsigned(255,8);
204
              else
205
                factor := 128 + absDeltaN(7 downto 0);
206
              end if;
207
            else
208
              factor := to_unsigned(128,8);
209
            end if;
210
          Modifier40b := Modifier * "000000000000000000000000"&factor / 128;
211
          Modifier := Modifier40b(31 downto 0);
212
          s <= Calc_ND;
213
              
214
        -------------------------------------------------------
215
        when Calc_ND  =>
216
        -------------------------------------------------------
217
          dNsquare := dN * dN;
218
          If EnableMOD_C = '0' then
219
            ND64bitfp := MODref_C * dNsquare;
220
          else
221
            ND64bitfp := Modifier * dNsquare;
222
          end if;
223
          ND := ND64bitfp(47 downto 32);
224
          s <= Done;
225
          
226
        -------------------------------------------------------
227
        when WaitOneClk  =>
228
        -------------------------------------------------------
229
          s <= Calc_dN;
230
          
231
        -------------------------------------------------------
232
        when Done    =>
233
        -------------------------------------------------------
234
          Busy_C <= '0';
235
          s <= Idle;
236
      
237
      ----------------------------------------------------------
238
      end case;
239
      ----------------------------------------------------------
240
    
241
      r_C <= r;
242
      N_C <= N;
243
      dN_C <= dN;
244
      ND_C <= ND;
245
      DirOut_C <= dir(0);
246
      MOD_C  <= Modifier;
247
    
248
    end process;
249
    
250
-------------------------------------------------------------------        
251
    SyncETrigger : process
252
-------------------------------------------------------------------
253
    begin
254
      wait until rising_edge(clk_C);
255
      Esr <= Esr(1 downto 0) & ETrigger_C;
256
    end process;
257
    
258
-------------------------------------------------------------------        
259
    SyncSWDTTrigger : process
260
-------------------------------------------------------------------
261
    begin
262
      wait until rising_edge(clk_C);
263
      SWDTsr <= SWDTsr(1 downto 0) & SWDTTrigger_C;
264
    end process;
265
    
266
  end Behavioral;

Das hat das Problem aber leider nicht gelöst. Wäre für jeden weiteren 
Einfall dankbar.

Gruß
Flo

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


Lesenswert?

> Nach einigen Triggerimpulsen bleibt alles stehen...
In welchem Zustand?

von Florian R. (flo0815)


Lesenswert?

In welchem Zustand, habe ich noch nicht rausgefunden. Dazu muss ich erst 
wohl das Zustandssignal nach außen führen ?!

Allerdings konnte ich feststellen, dass sich das VHDL Modul im 
stand-alone Betrieb, also nicht als IP-Core + Microblaze, nicht 
aufhängt.

Bin ein wenig ratlos.

Schönen Pfingstmontag an alle Leser.

Gruß
Flo

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


Lesenswert?

> Dazu muss ich erst wohl das Zustandssignal nach außen führen ?!
Ja, z.B. auf LEDs auf diese Art:
http://www.lothar-miller.de/s9y/archives/49-FSM-debuggen.html

von Florian R. (flo0815)


Lesenswert?

Bevor ich das probier, noch eine Frage: Mal angenommen, die FSM bleibt 
im Zustand Calc_dN hängen bzw. wackelt zwischen Cald_dN und WaitOneClk. 
Könnte da irgendwas mit dem Handshake mit der Divisions-Komponente nicht 
stimmen? Weise ich da vielleicht Signale falsch zu, sodass Synthese und 
Simulation sich unterscheiden?
Hat z.B. eine Bedingung wie
1
If busyDIV='0' and startDIV='0' then
2
  divisorDIV  <= countervalue;
3
  startDIV <= '1';
4
  s <= WaitOneClk;
5
elsif busyDIV='0' and startDIV='1' then
6
  dN := unsigned(quotientDIV(15 downto 0));
7
  startDIV <= '0';
8
  If EnableAdapt_C = '1' and NT(3)=NT(2) and NT(2)=NT(1) and NT(1)=NT(0) then
9
    s <= Calc_MOD;
10
  else
11
    s <= Calc_ND;
12
  end if;
13
else
14
  s <= Calc_dN;
15
end if;

in der ein Signal abgefragt und dann davon abhängig gesetzt wird 
irgendwelche für den Anfänger unvorhergesehene Folgen? Wird z.B. 
startDIV gleichzeitig gesetzt und abgefragt und führt daher zu irgendwas 
"Verrücktem"?

Vielen Dank für die Hilfe.

Gruß
Flo

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


Lesenswert?

> Wird z.B. startDIV gleichzeitig gesetzt und abgefragt ...
... ist das eine ganz übliche Vorgehensweise. Absolut jede State-Machine 
arbeitet so.
1
If busyDIV='0' and startDIV='0' then
2
  startDIV <= '1';
3
elsif busyDIV='0' and startDIV='1' then
4
  startDIV <= '0';
Das startDIV ist in der brutalen Realität ein Flipflop, das am Eingang 
eine Kombinatorik hat, mit der der Zustand berechnet wird, der mit dem 
nächsten Takt übernommen wird. Und danach ist dieses startDIV mindestens 
einen Takt lang stabil.

Dein Problem liegt irgendwo anders...

von Florian R. (flo0815)


Lesenswert?

Also, zunächst habe ich noch ein paar kleine Änderungen vorgenommen, die 
mit dem Problem nichts zu tun haben. Der Vollständigkeit halber hier der 
Code:
1
library IEEE;
2
use IEEE.STD_LOGIC_1164.ALL;
3
use IEEE.NUMERIC_STD.ALL;
4
5
--------------------------------------------------------------------
6
entity CALC is
7
--------------------------------------------------------------------
8
  Port ( ETrigger_C       : in  STD_LOGIC;
9
       SWDTTrigger_C      : in  STD_LOGIC;
10
       clk_C          : in  STD_LOGIC;
11
       Dir_C          : in  STD_LOGIC;
12
       Resetr_C        : in  STD_LOGIC;
13
       ResetN_C        : in  STD_LOGIC;
14
       ResetMOD_C        : in  STD_LOGIC;
15
       EnableMOD_C      : in  STD_LOGIC;
16
       EnableAdapt_C      : in  STD_LOGIC;
17
       AzimuthType_C      : in  STD_LOGIC;
18
       CounterValue_C    : in  STD_LOGIC_VECTOR (16 downto 0);
19
       rmax_C          : in  UNSIGNED(15 downto 0);
20
       MODref_C        : in  UNSIGNED(31 downto 0);
21
       NT_C            : in  SIGNED(19 downto 0);
22
       h_times_g_C      : in  UNSIGNED(19 downto 0);
23
       
24
       Reset_C          : out STD_LOGIC;
25
       Busy_C          : out STD_LOGIC;
26
       DirOut_C        : out STD_LOGIC;
27
       N_C            : out SIGNED(19 downto 0);
28
       dN_C            : out UNSIGNED(15 downto 0);
29
       ND_C            : out UNSIGNED(15 downto 0);
30
       r_C            : out UNSIGNED(15 downto 0);
31
       MOD_C          : out UNSIGNED(31 downto 0);
32
       state_as_vector    : out STD_LOGIC_VECTOR(3 downto 0));
33
  end CALC;
34
--------------------------------------------------------------------
35
36
--------------------------------------------------------------------
37
architecture Behavioral of CALC is
38
--------------------------------------------------------------------
39
40
  constant PSTable : STD_LOGIC_VECTOR (1023 downto 0):="00100001000010000100000100001000010000100001000010000100001000001000010"
41
                                    & "00010000100001000010000100001000010000010000100001000010000100001000010"
42
                                    & "00010000010000100001000010000100001000010000100001000001000010000100001"
43
                                    & "00001000010000100001000001000010000100001000010000100001000010000010000"
44
                                    & "10000100001000010000100001000010000100000100001000010000100001000010000"
45
                                    & "10000100000100001000010000100001000010000100001000001000010000100001000"
46
                                    & "01000010000100001000001000010000100001000010000100001000010000100000100"
47
                                    & "00100001000010000100001000010000100000100001000010000100001000010000100"
48
                                    & "00100000100001000010000100001000010000100001000010000010000100001000010"
49
                                    & "00010000100001000010000010000100001000010000100001000010000100000100001"
50
                                    & "00001000010000100001000010000100001000001000010000100001000010000100001"
51
                                    & "00001000001000010000100001000010000100001000010000100000100001000010000"
52
                                    & "10000100001000010000100000100001000010000100001000010000100001000001000"
53
                                    & "01000010000100001000010000100001000001000010000100001000010000100001000"
54
                                    & "010000100000100001000010000100";
55
  
56
---------------------------------------------------------------------                                    
57
  component Divider is
58
    Generic ( b  : natural range 4 to 32 := 32 ); 
59
      Port ( start     : in   STD_LOGIC;
60
           divisor   : in   STD_LOGIC_VECTOR (b-1 downto 0);
61
           dividend  : in   STD_LOGIC_VECTOR (b-1 downto 0);
62
           quotient  : out  STD_LOGIC_VECTOR (b-1 downto 0);
63
           remainder : out  STD_LOGIC_VECTOR (b-1 downto 0);
64
           busy      : out  STD_LOGIC;
65
           clk       : in   STD_LOGIC);
66
  end component;
67
---------------------------------------------------------------------
68
  type state is (Init, Idle, Calc_N, Calc_dN, Calc_MOD, Calc_ND, WaitOneClk);--, Done);
69
  signal s         : state;
70
  signal countervalue   : STD_LOGIC_VECTOR(16 downto 0);
71
  signal startDIV      : STD_LOGIC:='0';
72
  signal divisorDIV    : STD_LOGIC_VECTOR (16 downto 0);
73
  signal quotientDIV   : STD_LOGIC_VECTOR (16 downto 0);
74
  signal busyDIV       : STD_LOGIC:='0';
75
  signal Esr        : STD_LOGIC_VECTOR(2 downto 0);
76
  signal SWDTsr      : STD_LOGIC_VECTOR(2 downto 0);
77
---------------------------------------------------------------------  
78
  begin
79
  
80
    instDivider : Divider
81
      Generic Map ( b => 17 )
82
      Port Map    ( start     => startDIV,
83
                divisor   => divisorDIV,
84
                dividend  => std_logic_vector(to_unsigned(97656,17)),
85
                quotient  => quotientDIV,
86
                remainder => open,
87
                busy      => busyDIV,
88
                clk       => clk_C);
89
90
---------------------------------------------------------------------  
91
    FSM : process 
92
---------------------------------------------------------------------
93
    type NTArray is array (3 downto 0) of SIGNED(19 downto 0);
94
    variable NT        : NTArray;
95
    variable dNsquare    : UNSIGNED(31 downto 0);
96
    variable ND64bitfp  : UNSIGNED(63 downto 0);
97
    variable r         : UNSIGNED(15 downto 0):=to_unsigned(1,16);
98
    variable N         : SIGNED(19 downto 0):=to_signed(0,20);
99
    variable dN        : UNSIGNED(15 downto 0):=to_unsigned(0,16);
100
    variable ND        : UNSIGNED(15 downto 0):=to_unsigned(0,16);
101
    variable dir      : STD_LOGIC_VECTOR(3 downto 0):="0000";
102
    variable Modifier    : UNSIGNED(31 downto 0);
103
    variable Modifier40b  : UNSIGNED(39 downto 0); 
104
    variable absDeltaN  : UNSIGNED(19 downto 0);
105
    variable factor    : UNSIGNED(7 downto 0);
106
    
107
    begin
108
    
109
      wait until rising_edge(clk_c);
110
      
111
      If Resetr_C = '1'   then r := to_unsigned(1,16); else r := r;            end if;
112
      If ResetN_C = '1'   then N := to_signed(0,20);   else N := N;             end if;
113
      If ResetMOD_C = '1' then Modifier := MODref_C;   else Modifier := Modifier; end if;
114
      
115
      -------------------------------------------------------
116
      case s is 
117
      -------------------------------------------------------
118
        ----------------------------------------------------
119
        when Init    =>
120
        ----------------------------------------------------
121
          Modifier := MODref_C;
122
          s <= Idle;
123
        
124
         ----------------------------------------------------
125
        when Idle    =>
126
         ----------------------------------------------------  
127
          if Esr(2 downto 1)="01" then
128
            Busy_C  <= '1';
129
            Reset_C <= '0';
130
            If Dir_C='1' then r := r + 1; else r := r - 1; end if;
131
            If r = 0 then r := rmax_C; elsif r > rmax_C then r := r - rmax_C; end if;
132
            If PSTable(to_integer(r)-1)='1' then
133
              countervalue <= CounterValue_C;
134
              dir := to_stdlogicvector(to_bitvector(dir) sll 1);
135
              dir(0) := Dir_C;
136
              NT(3 downto 1):=NT(2 downto 0);
137
              NT(0) := NT_C;
138
              s <= Calc_N; 
139
            else 
140
              s <= Idle; 
141
            end if;
142
          elsif SWDTsr(2 downto 1)="01" then
143
            Busy_C <= '1';
144
            Reset_C <= '1';
145
            dN := to_unsigned(0,16);
146
            ND := to_unsigned(0,16);
147
            s  <= Idle;
148
          else
149
            Busy_C <= '0';
150
            Reset_C <= '0';
151
            s <= Idle;
152
          end if;
153
          
154
         ------------------------------------------------------  
155
        when Calc_N    =>
156
         ------------------------------------------------------
157
          If dir(0)='1' then N := N + 1; else N := N - 1; end if;
158
          If AzimuthType_C = '1' then
159
            If   N < 0                then N := N + signed(h_times_g_C); 
160
            elsif N > signed(h_times_g_C-1) then N := N - signed(h_times_g_C);
161
            else                               N := N;                 
162
            end if;
163
          else
164
            N := N;
165
          end if;
166
          Busy_C  <= '1';
167
          Reset_C <= '1';
168
          s <= Calc_dN;
169
  
170
         ------------------------------------------------------  
171
        when Calc_dN  =>
172
        ------------------------------------------------------
173
          if dir(0)=dir(1) then
174
            If busyDIV='0' and startDIV='0' then
175
              divisorDIV  <= countervalue;
176
              startDIV <= '1';
177
              s <= WaitOneClk;
178
            elsif busyDIV='0' and startDIV='1' then
179
              dN := unsigned(quotientDIV(15 downto 0));
180
              startDIV <= '0';
181
              If EnableAdapt_C = '1' and NT(3)=NT(2) and NT(2)=NT(1) and NT(1)=NT(0) then
182
                s <= Calc_MOD;
183
              else
184
                s <= Calc_ND;
185
              end if;
186
            else
187
              s <= Calc_dN;
188
            end if;
189
          else
190
            dN := to_unsigned(0,16);
191
            ND := to_unsigned(0,16);
192
            s  <= Idle;
193
          end if;
194
          Busy_C  <= '1';
195
          Reset_C <= '1';
196
          
197
        -------------------------------------------------------
198
        when Calc_MOD =>
199
        -------------------------------------------------------
200
          absDeltaN := unsigned(abs(NT_C - N));
201
            If    (dir(3)=dir(2) and dir(2)/=dir(1) and dir(1)/=dir(0)) then  -- reduce  Modifier
202
              If absDeltaN > to_unsigned(64,20) then 
203
                factor := to_unsigned(64,8);
204
              else
205
                factor := 128 - absDeltaN(7 downto 0);
206
              end if;  
207
            elsif (dir(3)=dir(2) and dir(2)/=dir(1) and dir(1) =dir(0)) then  -- enlarge Modifier
208
              If absDeltaN > to_unsigned(64,20) then
209
                factor := to_unsigned(255,8);
210
              else
211
                factor := 128 + absDeltaN(7 downto 0);
212
              end if;
213
            else
214
              factor := to_unsigned(128,8);
215
            end if;
216
          Modifier40b := Modifier * "000000000000000000000000"&factor / 128;
217
          Modifier := Modifier40b(31 downto 0);
218
          Busy_C  <= '1';
219
          Reset_C <= '1';
220
          s <= Calc_ND;
221
              
222
        -------------------------------------------------------
223
        when Calc_ND  =>
224
        -------------------------------------------------------
225
          dNsquare := dN * dN;
226
          If EnableMOD_C = '0' then
227
            ND64bitfp := MODref_C * dNsquare;
228
          else
229
            ND64bitfp := Modifier * dNsquare;
230
          end if;
231
          ND := ND64bitfp(47 downto 32);
232
          Busy_C  <= '1';
233
          Reset_C <= '1';
234
          s <= Idle;
235
          
236
        -------------------------------------------------------
237
        when WaitOneClk  =>
238
        -------------------------------------------------------
239
          Busy_C  <= '1';
240
          Reset_C <= '1';
241
          s <= Calc_dN;
242
          
243
        -------------------------------------------------------
244
--        when Done    =>
245
        -------------------------------------------------------
246
--          Busy_C  <= '0';
247
--          Reset_C <= '0';
248
--          s <= Idle;
249
      
250
      ----------------------------------------------------------
251
      end case;
252
      ----------------------------------------------------------
253
    
254
      r_C <= r;
255
      N_C <= N;
256
      dN_C <= dN;
257
      ND_C <= ND;
258
      DirOut_C <= dir(0);
259
      MOD_C  <= Modifier;
260
    
261
    end process;
262
    
263
    state_as_vector <= std_logic_vector(to_unsigned(state'pos(s),4));
264
    
265
-------------------------------------------------------------------        
266
    SyncETrigger : process
267
-------------------------------------------------------------------
268
    begin
269
      wait until rising_edge(clk_C);
270
      Esr <= Esr(1 downto 0) & ETrigger_C;
271
    end process;
272
    
273
-------------------------------------------------------------------        
274
    SyncSWDTTrigger : process
275
-------------------------------------------------------------------
276
    begin
277
      wait until rising_edge(clk_C);
278
      SWDTsr <= SWDTsr(1 downto 0) & SWDTTrigger_C;
279
    end process;
280
    
281
  end Behavioral;

Die FSM bleibt bei einem state_as_vector = "0011" hängen. Ich nehme an, 
das ist der Zustand Calc_dN (wie vermutet).

Gruß
Flo

von Rick Dangerus (Gast)


Lesenswert?

Florian Rems schrieb:
> when Calc_dN  =>
>         ------------------------------------------------------
>           if dir(0)=dir(1) then
>             If    busyDIV='0' and startDIV='0' then
...
>             elsif busyDIV='0' and startDIV='1' then
...
>             else
>               s <= Calc_dN;
>             end if;
>           else
...
>           end if;

Damit s = calc_dN bleibt, müssen folgende Bedingungen erfüllt sein: 
dir(0)=dir(1) und busyDIV=1. Und genau das ist offenbar der Fall...
Kannst Du Dir dir(0), dir(1), busyDIV und startDIV auch noch mit 
ausgeben lassen?

Rick
1
busyDIV startDIV gehe in else-Zweig
2
0       0        false
3
0       1        false
4
1       0        true 
5
1       1        true

von Florian R. (flo0815)


Lesenswert?

Danke für den Hinweis. Seh ich auch so. Der "Divider" ist auch eine FSM, 
mal sehen, ob die vielleicht auch hängen bleibt, eben mit busyDIV='1'.

Was mich allerdings irritiert ist, dass mein Konstrukt stand-alone auf 
dem FPGA NICHT hängen bleibt. In Verbindung mit dem MicroBlaze, wenn der 
FPGA also nahezu voll ist, tritt dieses Problem auf. Dann kann es 
eigentlich kein systematischer Fehler im Code sein?!

Gruß
Flo

von Rick Dangerus (Gast)


Lesenswert?

Florian Rems schrieb:
> systematischer Fehler

Hmm. Jetzt wo Du es sagst: Wieviele Clocks verwendest Du? Ist da 
eventuell ein unsauberes Clock-Domain-Crossing verbaut?

Rick

von Florian R. (flo0815)


Lesenswert?

Also der IP-Core arbeitet mit einem Takt, den hole ich mir direkt vom 
Takt des PLB-Buses vom Microblaze. Könnte da vielleicht ein Problem 
bestehen?

>Wieviele Clocks verwendest du?
Ich denke, nur eine. Aber woran erkenne ich das?

Was versteht man unter einem Clock-Domain-Crossing?

Danke für die Hilfe.

Gruß
Flo

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


Lesenswert?

> Ich denke, nur eine. Aber woran erkenne ich das?
Am 'event oder rising_edge() bzw. falling_edge().
Aber das hatten wir schon im 
Beitrag "Re: Custom IP-Core hängt sich auf."

> Was versteht man unter einem Clock-Domain-Crossing?
Den Übergang von Signalen von einer Taktdomäne in die andere...
Sitchworte: Eintakten, Synchronisieren, Fifo

von Florian R. (flo0815)


Lesenswert?

Bzgl. Eintakten etc. dürften ja wohl alle "Missetaten" beseitigt sein.
Selbst wenn ich jetzt weiß, dass BusyDIV='1' bleibt, vielleicht weil die 
Divisions-FSM hängen bleibt, nutzt mir das auch nix, weil es ja im 
stand-alone Betrieb funktioniert. Kann es denn an der Anbindung als 
IP-Core liegen? Da werden eigentlich nur den Signalen Register 
zugewiesen und umgekehrt.
Frustrierend ...

Gruß
Flo

von Florian R. (flo0815)


Lesenswert?

Noch eine Idee: Sind denn Timing-Probleme denkbar. Der Report im Xilinx 
EDK für den IP-Core schreibt:

Clock Information:
------------------
-----------------------------------------------+------------------------ 
---------------------------------------------------------------+-------+
Clock Signal                                   | Clock buffer(FF name) 
| Load  |
-----------------------------------------------+------------------------ 
---------------------------------------------------------------+-------+
SPLB_Clk                                       | 
NONE(motor_controller_ip_0/PLBV46_SLAVE_SINGLE_I/I_SLAVE_ATTACHMENT/I_DE 
CODER/rnw_s_h)|  886   |
motor_controller_ip_0/USER_LOGIC_I/CON/C/Busy_C| 
NONE(motor_controller_ip_0/USER_LOGIC_I/CON/LOG/Mode_LOG_0) 
| 3     |
-----------------------------------------------+------------------------ 
---------------------------------------------------------------+-------+
INFO:Xst:2169 - HDL ADVISOR - Some clock signals were not automatically 
buffered by XST with BUFG/BUFR resources. Please use the buffer_type 
constraint in order to insert these buffers to the clock signals to help 
prevent skew problems.

Asynchronous Control Signals Information:
----------------------------------------
------------------------------------------------------------------------ 
----------------------------+------------------------------------------- 
--------------------+-------+
Control Signal 
| Buffer(FF name)                                               | Load 
|
------------------------------------------------------------------------ 
----------------------------+------------------------------------------- 
--------------------+-------+
motor_controller_ip_0/USER_LOGIC_I/CON/C/Reset_C(motor_controller_ip_0/U 
SER_LOGIC_I/CON/C/Reset_C:Q)| 
NONE(motor_controller_ip_0/USER_LOGIC_I/CON/instSWDT/count_21)| 24    |
------------------------------------------------------------------------ 
----------------------------+------------------------------------------- 
--------------------+-------+

Timing Summary:
---------------
Speed Grade: -4

   Minimum period: 18.272ns (Maximum Frequency: 54.729MHz)
   Minimum input arrival time before clock: 15.577ns
   Maximum output required time after clock: 5.833ns
   Maximum combinational path delay: No path found

Clock ist 50 MHz. Ist das vielleicht zu knapp? Weiß jemand, wie man 
probeweise den Takt verringert?

Vielen Dank für jeglichen Tipp.

Gruß
Flo

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


Lesenswert?

> Clock ist 50 MHz. Ist das vielleicht zu knapp?
Nein, das würde reichen.

Aber du hast offenbar doch noch ein paar weitere Takte in deinem Design, 
erkennbar (wie gesagt) an 'event oder rising_edge() bzw. falling_edge().
Sieh dir die mal genauer an.

von Rick Dangerus (Gast)


Lesenswert?

Das sieht komisch aus: motor_controller_ip_0/USER_LOGIC_I/CON/C/Busy_C
Sind da doch ausversehen mehrere Clockdomains drin?!

Mit der Taktfrequenz das passt schon, solange Du keine Timing-Errors 
(Timingscore > 0) hast.

Rick

von Florian R. (flo0815)


Lesenswert?

Jetzt sieht das Ganze so aus.

======================================================================== 
=
TIMING REPORT

NOTE: THESE TIMING NUMBERS ARE ONLY A SYNTHESIS ESTIMATE.
      FOR ACCURATE TIMING INFORMATION PLEASE REFER TO THE TRACE REPORT
      GENERATED AFTER PLACE-and-ROUTE.

Clock Information:
------------------
-----------------------------------+------------------------------------ 
---------------------------------------------------+-------+
Clock Signal                       | Clock buffer(FF name) 
| Load  |
-----------------------------------+------------------------------------ 
---------------------------------------------------+-------+
SPLB_Clk                           | 
NONE(motor_controller_ip_0/PLBV46_SLAVE_SINGLE_I/I_SLAVE_ATTACHMENT/I_DE 
CODER/rnw_s_h)|  887   |
-----------------------------------+------------------------------------ 
---------------------------------------------------+-------+
INFO:Xst:2169 - HDL ADVISOR - Some clock signals were not automatically 
buffered by XST with BUFG/BUFR resources. Please use the buffer_type 
constraint in order to insert these buffers to the clock signals to help 
prevent skew problems.

Asynchronous Control Signals Information:
----------------------------------------
------------------------------------------------------------------------ 
----------------------------+------------------------------------------- 
--------------------+-------+
Control Signal 
| Buffer(FF name)                                               | Load 
|
------------------------------------------------------------------------ 
----------------------------+------------------------------------------- 
--------------------+-------+
motor_controller_ip_0/USER_LOGIC_I/CON/C/Reset_C(motor_controller_ip_0/U 
SER_LOGIC_I/CON/C/Reset_C:Q)| 
NONE(motor_controller_ip_0/USER_LOGIC_I/CON/instSWDT/count_14)| 24    |
------------------------------------------------------------------------ 
----------------------------+------------------------------------------- 
--------------------+-------+

Timing Summary:
---------------
Speed Grade: -4

   Minimum period: 21.721ns (Maximum Frequency: 46.038MHz)
   Minimum input arrival time before clock: 16.085ns
   Maximum output required time after clock: 4.772ns
   Maximum combinational path delay: No path found

Dazu muss ich sagen, dass jetzt zwei der IP-Cores dabei sind, so wie es 
am Schluss auch funktionieren soll.
Ist das mit dem Timing immer noch in Ordnung? jetzt hätten wir ja 
weniger als 50 Mhz.
Es bleibt leider immer noch hängen, genau wie oben.

Gruß
Flo

von Florian R. (flo0815)


Lesenswert?

Device utilization summary:
---------------------------

Selected Device : 3s500efg320-4

 Number of Slices:                     5142  out of   4656   110% (*)
 Number of Slice Flip Flops:           5037  out of   9312    54%
 Number of 4 input LUTs:               7757  out of   9312    83%
    Number used as logic:              7206
    Number used as Shift registers:     295
    Number used as RAMs:                256
 Number of IOs:                          54
 Number of bonded IOBs:                  54  out of    232    23%
    IOB Flip Flops:                      16
 Number of BRAMs:                        16  out of     20    80%
 Number of MULT18X18SIOs:                17  out of     20    85%
 Number of GCLKs:                         4  out of     24    16%
 Number of DCMs:                          1  out of      4    25%

WARNING:Xst:1336 -  (*) More than 100% of Device resources are used

Wie kann es sein, dass ich den Bitstream trotz (*) auf den FPGA laden 
kann?

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


Lesenswert?

> Device utilization summary: 110%
Sagt wer?
Die Synthese?
Oder P&R?

> Wie kann es sein, dass ich den Bitstream trotz (*) auf den FPGA laden
> kann?
Jetzt muß P&R endlich mal was tun und etwas optimieren...

>    Minimum period: 21.721ns (Maximum Frequency: 46.038MHz)
Das ist nach der Synthese...
> Ist das mit dem Timing immer noch in Ordnung?
... da kann bei richtigen constaints schon noch was verbessert werden.
> jetzt hätten wir ja weniger als 50 Mhz.
Also die Frage: du hast den Takt korrekt constrained?

von Florian R. (flo0815)


Lesenswert?

110% sagt der Synthese-Report in Xilinx EDK.

Ich habe gar nichts constrained :-).

Gruß
Flo

von Florian R. (flo0815)


Lesenswert?

Habe gerade versucht, die Divisionskomponente quasi auszuschalten und 
einen festen Wert für dN vorgegeben. Damit tritt das Aufhängen nicht 
mehr auf. Es muss also was mit der Divisions-FSM zu tun haben. Das ist 
allerdings keine Lösung, denn irgendwie muss ich diese Division 
durchführen.

Gruß
Flo

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


Lesenswert?

> Es muss also was mit der Divisions-FSM zu tun haben.
Woher hast du die?

von Florian R. (flo0815)


Lesenswert?

Von Dir: Beitrag FPGA/VHDL Timing

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


Lesenswert?

Ich habs geahnt...  :-o
Der läuft eigentlich recht gut.
Du solltest dir die Geschichte mit dem Takt nochmal anschauen.

> Ich habe gar nichts constrained :-)
Gib doch mal einen constraint auf den Takt vor.

von Florian R. (flo0815)


Lesenswert?

Folgendes stand tatsächlich im UCF File:

TIMESPEC TS_sys_clk_pin = PERIOD sys_clk_pin 20000 ps;

Das hat das EDK reingeschrieben. Was wäre denn eine sinnvolle Änderung?

Gruß
Flo

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.