Forum: FPGA, VHDL & Co. Verilog: Mehrere Module aus generate-Block synchronisieren?


von Thomas S. (th0ms0n)


Lesenswert?

Hallo,

vielleicht ist die Antwort ja ganz simpel, aber ich habe in der Suche 
nichts gefunden, bzw. weiß evtl. nicht genau, wonach ich suchen muss.
Es geht um folgendes Szenario:

- Ich habe per generate-for-loop mehrere Module instanziiert, die zu 
unterschiedlichen Zeitpunkten Ergebnisse zurückliefern, manchmal auch im 
gleichen Clock
- Mein uart-Puffer-Modul kann pro Takt allerdings nur einen Wert 
übernehmen
- Da allerdings selten Ergebnisse gleichzeitig eintreffen ist das i.O. 
und ich kann z.b. alle außer einem verwerfen

Das Grundprinzip sieht so aus:
1
genvar i;
2
generate
3
    for (i = 0; i < `NUM; i = i + 1)
4
    begin
5
        // hier das Modul, Ergebnis landet in result[32*i+:32]
6
        // und gotnew[i] ist high, wenn was reinkam
7
    end
8
endgenerate
9
10
// dieses reg geht zum uart Puffer
11
reg [31:0] buf;

Wie schaffe ich es nun, ein frisch eingetroffenes Ergebnis aus result 
nach buf zu schieben?
Ich habe schon an einen Tristate Bus gedacht, allerdings möchte ich gern 
darauf verzichten, da u.a. auch gleichzeitig Ergebnisse reinkommen 
können und ich dann mehrere Driver habe.

Wie kann ich das anstellen?
Beste Grüße,
Thomas

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


Lesenswert?

Thomas S. schrieb:
> Wie schaffe ich es nun, ein frisch eingetroffenes Ergebnis aus result
> nach buf zu schieben?
Wie würde denn so ein Baustein, der das könnte in Hardware aussehen? Was 
könnte das sein? Ja klar: ein Multiplexer kann mehrere Eingänge auf 
einen ausgang reduzieren.
Und jetzt kommt die Gretchenfrage: wie beschreibt man einen Multiplexer 
in Verilog?

> - Da allerdings selten Ergebnisse gleichzeitig eintreffen
Da Wort "selten" gibt es nicht. Es muss "immer" funktionieren. Du 
brauchst einen Mechanismus, der "immer" nur einen der Werte auswählt. 
Dann funktioniert auch der Sonderfall, dass evtl. nur ein einzelner 
Wert ankommt. Ich würde hier auf so etwas wie einen Prioritätsencoder 
setzen.

> ist das i.O. und ich kann z.b. alle außer einem verwerfen
Das musst aber du machen, das macht die Hardware nicht "automatisch".

von Thomas S. (th0ms0n)


Lesenswert?

Ok, ich brauche also einen MUX.
Jetzt stellt sich mir die Frage, wie ich per generate o.ä. einen 
Priority-Encoder baue, denn die Anzahl der Module ist ein Parameter. 
Ansonsten würde ich wohl sowas machen:
1
always@(*)
2
begin
3
   if (gotnew[0]) buf = result[0+:32];
4
   else if (gotnew[1]) buf = result[32+:32];
5
   // und so weiter
6
end

Das würde mein Problem wohl lösen, oder?
Nur wie formuliere ich das in Abhängigkeit von `NUM (der Anzahl der 
Module, die Ergebnisse berechnen?

von Thomas S. (th0ms0n)


Lesenswert?

Lösung gefunden:
1
always@(*)
2
begin
3
    sendrun  = 1'b0;
4
    chunk    = 32'hFFFFFFFF;   
5
    
6
    for (k = 0; k < `CNT; k = k + 1)
7
    begin
8
        if (isprime[2*k+:2] == SOLVER[0].pr.FOUND)
9
        begin
10
            sendrun  = 1'b1;
11
            chunk    = counter[32*k+:32];     
12
        end
13
    end
14
end

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.