2017-10-03 10 views
0

Parfois, une situation apparaît dans un code paramétré où je veux vérifier une tranche de tableau si la largeur de cette tranche est non nulle. Je pourrais écrire quelque chose comme ceci:Les plages de tranches null/invalides de Verilog dans les évaluations inaccessibles

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 

C'est ainsi que j'ai géré ces situations lors de l'écriture VHDL; en se basant sur un court-circuit dans les évaluations constantes pour éviter que la plage de matrice invalide ne soit jamais évaluée. Dans le système verilog tel qu'il est écrit, cela génère des erreurs "plage de sélection de pièce est inversée" et des erreurs "plage de largeur ne peut être nulle" dans QuestaSim.

Existe-t-il un moyen de traiter correctement les plages nulles que la plupart des outils acceptent sans dupliquer le contenu de //do something dans plusieurs constructions if-generate?

Répondre

0

Ce que vous pouvez faire est de créer un paramètre de masquage

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 

outils de synthèse optimiseront logique loin quand MASQUE est 0.

n'a pas testé cela, alors vous pourriez avoir à jouer avec mon équation .

+0

J'ai été capable d'utiliser une variation de masquage pour cette instance, bien qu'il soit dommage qu'il n'y ait pas de cas général plus propre. Je suppose que je pourrais utiliser une génération pour condenser de façon combinée la condition dans un réseau intermédiaire sans cloner beaucoup de lignes de logique séquentielle. – QuantumRipple

0

La manière habituelle de le gérer dans verilog est de 'générer' des blocs.

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 

Avec SV vous n'avez pas besoin d'utiliser les mots-clés generate/endgenerate.

+0

Le PO a spécifiquement demandé une solution qui n'impliquait pas la réplication des blocs de code * do something *. –

+0

Cette solution est la seule solution propre et éprouvée pour résoudre ces problèmes dans Verilog. Le reste ne sont que des hacks et astuces qui pourraient fonctionner dans certains cas spécifiques. – Serge