Verilog Task

Gast #2766399
Lesenswert?
• ▲
▼
Hallo,

ich habe ein Problem und ich finde einfach keine Lösung.

1
always @(posedge clkin_150) begin
2

3
case(state_square)
4
 
5
 IDLE: begin
6
          if(control_go_square_psd==1'b1)begin
7
               control_done_square_psd_reg<=0;
8
             state_square <= COPY;
9
             
10
            end
11
          else begin state_square <= IDLE; end
12
      end
13
 COPY: begin  
14
            for(int j=0;j<process_steps;j=j+1) begin      --// copy new psd values to task
15
              new_psd_reg_task[j]<=psd[steps_offset_square+j];
16
              new_psd_reg_task_temp[j]<=psd[steps_offset_square+j];
17
          end
18
          
19
          state_square <= COPY_END;
20
      end
21
COPY_END: begin
22
             state_square <= SQUARE;
23
      end
24
     
25
 SQUARE: begin
26
               
27
           square(psd,new_psd_reg_task,new_psd_reg_task_temp,tolerance_delta,maxima); // calling task
28
  
29
          state_square <= DELAY;
30
       end   
31
    
32
 DELAY: begin
33

34
          
35
              state_square <= SQUARE_END;
36
      end
37
 SQUARE_END: begin
38
              
39
          for(int i=0;i<process_steps;i=i+1)begin  --// save values
40
          new_psd_reg[steps_offset_square+i]<=new_psd_reg_task[i];
41
          end
42
          if(steps_offset_square==steps-process_steps) begin -- // last interval was processed
43
             state_square <= DONE;
44
            steps_offset_square<=0;
45
          end
46
          else begin
47
            steps_offset_square<=steps_offset_square+process_steps; --// increase offset 
48
            state_square<=COPY;
49
          end
50

51
          
52
       end
53
 DONE: begin
54
              control_done_square_psd_reg<=1;
55
            if(control_go_square_psd==0) begin
56
              state_square<=IDLE;
57
            end
58
          else begin
59
          state_square <=DONE;  
60
            end
61
     end
62

63

64

65

66
endcase
67
end

Ich habe eine Zustandsmaschine die abhängig von der Anzahl der 
Werte(steps_offset) den Task square aufrufen soll. Nun passiert es aber 
das nachdem ausführen auf dem FPGA nur der letzte Aufruf des Tasks das 
richtige Ergebnis bringt. Die anderen Aufrufe werden nicht bearbeitet.

Nun frage ich mich warum immer nur der letzte Aufruf bearbeitet wird in 
der Simulation funktioniert alles einwandfrei.

Ich habe auch schon versucht den task auf automatic zu setzen was aber 
keine Besserung gebracht hat.

Liegt es vielleicht an den Zuweisungen in den for - Schleifen und das 
mir Quartus die vorherigen Aufrufe wegsynthetisiert?
Gast #2767156
Lesenswert?
• ▲
▼
1
task square;
2
   input signed [7:0]psd[0:steps-1];
3
   inout signed [7:0]new_psd_reg_task[0:process_steps-1];
4
  input signed [7:0]new_psd_reg_task_temp[0:process_steps-1];
5
  input [7:0]tolerance_delta;
6
  input signed [7:0] maxima [0:max_channels-1];
7

8
  
9
  for(int j=0;j<process_steps;j=j+1) begin
10
   
11
      for(int i=0;i<max_channels;i=i+1)begin // for every maxima value +/- tolerance delta, psd is compared and adapt to maxima value if in this interval
12
                           
13
            if (new_psd_reg_task_temp[j]<=maxima[i]+tolerance_delta && new_psd_reg_task_temp[j]>=maxima[i]-tolerance_delta) begin
14
            
15
              new_psd_reg_task[j]=maxima[i];
16
              
17
              
18
             end // end if
19
             
20
             
21
          end  // end i
22
    end // end j
23
  
24
endtask
Gast #2767196
Lesenswert?
• ▲
▼
na new_psd_reg_task brauch ich doch um im Zustand Square_END die Werte 
zu übertragen. Mein gedanke dahinter ist Ressourcen zu sparen indem ich 
imemr wieder den selben Task verwende und die berechneten Werte danach 
übertrage.
Gast #2767407
Lesenswert?
• ▲
▼
Aber du überschreibst doch alle Werte von 'new_psd_reg_task' in dem 
Task, ohne sie dort vorher zur Berechnung zu verwenden. Da brauchst du 
doch kein inout. Ein output hätte doch gereicht.

Und wieso sollen Tasks beim Resourcen sparen helfen? Es kommt doch das 
gleiche bei raus, wenn du den Code aus dem Task direkt in deine State 
Machine kopierst. Was anderes macht das Synthesetool später dann ja auch 
nicht.
Tasks dienen dazu, häufig verwendete Codeteile nur an einer Stelle zu 
beschreiben.

Außerdem wird dein Input 'psd' im Task garnicht verwendet. Der kann also 
auch weg.
Gast #2767566
Lesenswert?
• ▲
▼
mit psd hast du recht aber new_psd_reg_task überschreib ich nicht alle 
Werte sondern nur die welche die if Bedingugn erfüllen deswegen das 
inout.


Ich habe ein problem mit dem Konstruct
1
for(int i=0;i<process_steps;i=i+1)begin  --// save values
2
          new_psd_reg[steps_offset_square+i]<=new_psd_reg_task[i];
3
          end

Nehmen wir an ich bekomme vom Task immer 10 Werte und möchte diese in 
das große Feld new_psd_reg abspeichern was z.B. 600 Werte hat. MEine 
Lösung verschlingt im RTL Viewer viel Platz fällt jemanden eine bessere 
Lösung ein?
Gast #2767612
Lesenswert?
• ▲
▼
Schreib einen Task oder eine Funktion, die nur 10 Werte als Eingang 
annimmt und auch 10 wieder rausgibt und sortiere sie dann entsprechend 
in das Array mit 600 Einträgen ein (aber nicht mit einer for-Schleife).
Gast #2767716
Lesenswert?
• ▲
▼
Nimm einen Zähler, der in 10er Schritten Zählt. Mit dem selektierst du 
die Eingangswerte für den/die Task/Function und auch die Position im 
Ergebnis-Array. Bei jedem Aufruf von square() wird der Zähler 
hochgezählt (aber bitte nicht in dem Task, sondern dort wo der Task 
aufgerufen wird!!!)
Gast #2767752
Lesenswert?
• ▲
▼
auch Hans schrieb:
> Nimm einen Zähler, der in 10er Schritten Zählt. Mit dem selektierst du
> die Eingangswerte für den/die Task/Function und auch die Position im
> Ergebnis-Array. Bei jedem Aufruf von square() wird der Zähler
> hochgezählt (aber bitte nicht in dem Task, sondern dort wo der Task
> aufgerufen wird!!!)

Das tu ich ja im Prinzip mit steps_offset_square das zähl ich immer 10 
hoch und wähle so die stelle im Ergebnisarray aus aber wie soll ich die 
for Schleife umgehen

new_psd_reg[steps_offset_square:steps_offset_square+10]<=new_psd_reg_tas 
k;


sowas erzeugt bei mir einen Fehler bei der Codegenerierung
Gast #2767790
Lesenswert?
• ▲
▼
Bei dem Fehler schlägt jedes handelsübliche Verilogbuch sowas vor:
1
new_psd_reg[steps_offset_square+:10]<=new_psd_reg_task;

Ansonsten schmeiß das bekloppte inout aus dem Task raus. Was soll das 
da? Schreib das mal um.

Also new_psd_reg_task_temp und new_psd_reg_task sind ja beim Aufruf des 
Tasks identisch, oder? Dann kannst du den ..._temp weglassen und 
fütterst den Task mit new_psd_reg_task. Im Task legst du einen output 
an, z.B. new_psd_reg_task_out. In der for-Schleife weist du jedem 
Arrayelemt des Outputs entweder den Wert des Inputs new_psd_reg_task 
oder den entsprechenden maxima-Wert zu.
Das was du da treibst sieht wie Software in-place Denkweise aus und ist 
hier völlig falsch. Hab dir ja in ein paar anderen Threads schon geraten 
mal etwas Geld in ein Buch zum digitalen Hardwaredesign zu investieren.
Gast #2768456
Lesenswert?
• ▲
▼
new_psd_reg[steps_offset_square+:10]<=new_psd_reg_task;

zu solchen kontrukten kommt bei mir immer der Fehler steps_offset_square 
is not a constant deswegen habe ich aj den Weg über die forschleifen 
gewählt
Gast #2768864
Lesenswert?
• ▲
▼
Dann wäre es wohl günstiger dein Array in ein RAM aufzuteilen. Die 
Datenbreite des RAMs wählt du so, daß z.B. 10 Elemente gleichzeitig 
gelesen/geschrieben werden können. Also in diesem Fall 80 Bit. Dann 
würdest du in der State Machine einen Satz auslesen, ihn modifizieren 
und dann wieder ins RAM schreiben. Allerdings könntest du dann niemals 
auf alle Array-Elemente gleichzeitig zugreifen.
Du könntest auch dein Array dreidimensional gestalten. Also 8 Bit * 10 
Elemente * 60. Dann würdest du ein zweidimensionales Array daraus 
selektieren und könntest mit dem Arbeiten. Ob die Synthese das frisst 
weiß ich aber gerade nicht.
Gast #2769077
Lesenswert?
• ▲
▼
ich ahbe es jetzt mit so einem Konstrukt versucht
1
reg signed [7:0]new_psd_reg[process_steps-1:0][0:steps/process_steps-1];
2

3

4
new_psd_reg[process_steps-1:0][0]<=new_psd_reg_output; -- zuweisung

allerdings erhalte ich folgenden Fehler


range must be the final index in the indexed name


Was mach ich falsch.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren