Single Input Array von Custom Module in Verilog
Frage
So habe ich eine Reihe von vier RAM-Module, die ich möchte in der Lage sein, basierend auf zwei verschiedenen Anwahlsignale zu lesen / schreiben. Im Moment bin ich Instanziieren des RAM mit Zwischensignal:
genvar i;
generate
for (i = 0; i < regnum; i=i+1) begin: regs
rfram_generic rf (clk,rst,ce_a_int[i],addr_a_int[i],do_a_int[i],
ce_b_int[i],addr_b_int[i],do_b_int[i],
ce_w_int[i],we_w_int[i],addr_w_int[i],
di_w_int[i]);
end
endgenerate
Und ich möchte den RAM wählen, um entweder head
oder tail
Signale (2-Bit-Vektoren) verwendet wird. Irgendwelche Ideen, wie dies zu tun?
Lösung
Ich bin neu hier und kommentieren kann noch nicht auf Fragen, aber in Reaktion auf Marty: Die meisten FPGA-Synthese-Tools werden mit Tri-State-Werten in MUX-ähnlichen Logik, wenn möglich, interne Signale mit mehreren Quellen übersetzen. Siehe zum Beispiel: eine Beschreibung der alten Tri-State-to-Logik Verhalten, das klingt genau mir .
Als Empfehlung an Adam, sind Sie wahrscheinlich besser dran, so dass diese in Ihrem Code explizit durch Ausführen den sie maskiert, anstatt mit dem tristates. Dies wird die Portabilität verbessern, geben Sie besser vorhersehbare Ergebnisse und dienen als Selbstdokumentation, wenn jemand jemals Code hat zu überdenken.
Doch einige Vermutungen auf Ihrer Lösung machen basieren, wäre es wahrscheinlich sinnvoll, die Taktfreigabe auf dem Schreib-Port und Mux die Ausgabe des Lese-Port einfach zu maskieren. Zum Beispiel:
reg [WIDTH-1:0] do_a,do_b;
always @(*) do_a = do_a_int[head];
always @(*) do_b = do_b_int[tail];
generate
genvar i;
for (i = 0; i < regnum; i=i+1) begin: regs
rfram_generic rf (clk,rst,
ce_a,addr_a,do_a_int[i],
ce_b,addr_b,do_b_int[i],
ce_w,head==i?we_w:1'b0,addr_w,di_w);
end
endgenerate
Dies wird wahrscheinlich in weniger komplexen Logik zur Folge hat ( d. , besser Fläche und Verzögerung) als Ihre Lösung.
Andere Tipps
Ich glaube, ich es herausgefunden, verwenden Sie Gotta eine generieren Anweisung:
genvar i;
generate
for (i = 0; i < regnum; i=i+1) begin: sigassign
//read from the checkpoint in progress
assign ce_a_int[i] = (head == i) ? ce_a : 'bz;
assign addr_a_int[i] = (head == i) ? addr_a : 'bz;
assign do_a = (head == i) ? do_a_int[i] : 'bz;
//write to the checkpoint in progress
assign ce_w_int[i] = (head == i) ? ce_w : 'bz;
assign we_w_int[i] = (head == i) ? we_w : 'bz;
assign addr_w_int[i] = (head == i) ? addr_w : 'bz;
assign di_w_int[i] = (head == i) ? di_w : 'bz;
//read from the last stable checkpoint
assign ce_b_int[i] = (tail == i) ? ce_b : 'bz;
assign addr_b_int[i] = (tail == i) ? addr_b : 'bz;
assign do_b = (tail == i) ? do_b_int[i] : 'bz;
end
endgenerate
froh zu hören, Sie eine Lösung für Ihr Problem gefunden. Ich muss zugeben, dass ich nicht ganz verstanden, was Sie vorhatten, aber ein Kommentar, können Sie auch if
innen verwenden Anweisungen generieren und damit unterschiedliche Module instanziiert oder unterschiedliche Signale auf dem genvar
abhängig verwenden, z.
generate
genvar i;
for (i = 0; i < regnum; i=i+1) begin: regs
if (i == head) begin
rfram_generic_a rf(...);
end else if (i == tail) begin
rfram_generic_b rf(...);
end else begin
rfram_generic_c rf(...);
end
end
endgenerate