2017-10-03 4 views
0

Manchmal kommt eine Situation in parametrisierten Code, wo ich gegen eine Array-Slice überprüfen möchte, wenn die Breite dieser Slice nicht Null ist. Ich könnte so etwas schreiben:Verilog Null/ungültige Slice-Bereiche in nicht erreichbaren Auswertungen

parameter SLICE_WIDTH; 
parameter SLICE_BASE; 
logic [my_array_size : 0] my_array; 
//... 
always_ff @ (posedge clk) begin 
    if (SLICE_WIDTH==0 || my_array[SLICE_BASE+:SLICE_WIDTH]==0) begin 
    //alternately "if (SLICE_WIDTH==0 || my_array[SLICE_WIDTH+SLICE_BASE-1:SLICE_BASE]==0) begin" 
     //do something 
    end 
    else begin 
     //do something else 
    end 
end 

Das war die Art, wie ich diese Situationen behandelt, wenn VHDL zu schreiben; Verlass auf Kurzschluss in den konstanten Auswertungen, um zu verhindern, dass der ungültige Array-Bereich jemals bewertet wird. In System Verilog, wie geschrieben, wirft dies in QuestaSim "Bereich der Teileauswahl ist umgekehrt" Fehler und "Bereich Breite kann nicht Null sein" Fehler.

Gibt es eine Möglichkeit, sauber mit Nullbereichen umzugehen, die die meisten Tools akzeptieren, ohne den Inhalt von //do something in mehrere if-generate-Konstrukte zu duplizieren?

Antwort

0

Was können Sie tun, ist

wird
parameter SLICE_WIDTH; 
parameter SLICE_BASE; 
localparam logic [my_array_size : 0] MASK) = 2**SLICE_WIDTH - 1 << SLICE_BASE; 
logic [my_array_size : 0] my_array; 
//... 
always_ff @ (posedge clk) 
    if (my_array&MASK) begin 
     //do something 
    end 
    else begin 
     //do something else 
    end 

Synthese-Tools zu optimieren, um eine Maskierungsparameter erstellen Logik weg, wenn MASK ist 0.

dies nicht testen Haben, so dass Sie mit meiner Gleichung könnte spielen .

+0

Ich konnte eine Variante der Maskierung für diese Instanz verwenden, obwohl es schade ist, dass es keinen saubereren allgemeinen Fall gibt. Ich nehme an, ich könnte ein Generat verwenden, um die Bedingung in ein intermediäres Netz zu kombinieren, ohne viele Zeilen sequentieller Logik zu klonen. – QuantumRipple

0

Der übliche Weg, um es in Verilog zu behandeln, ist das Generieren von Blöcken.

parameter SLICE_WIDTH; 
parameter SLICE_BASE; 

logic [my_array_size : 0] my_array; 
//... 

// generate 
if (SLICE_WIDTH==0) begin 
    // do something here 
end 
else begin 
    always_ff @ (posedge clk) begin 
     if (my_array[SLICE_BASE+:SLICE_WIDTH]==0) begin 
     //do something 
     end 
     else begin 
     //do something else 
     end 
    end 
end // endgenerate 

Mit SV müssen Sie die Schlüsselwörter generate/endgenerate nicht verwenden.

+0

Das OP hat ausdrücklich nach einer Lösung gefragt, bei der die Code-Blöcke * nicht umgesetzt wurden. –

+0

Diese Lösung ist der einzige saubere und bewährte Weg, um solche Probleme in Verilog zu lösen. Der Rest sind nur Hacks und Tricks, die in bestimmten Fällen funktionieren könnten. – Serge

Verwandte Themen