3

Ich versuche, Constraint mit einem 2d-Array mit 1 und 0 gefüllt. Ich möchte, dass jede Zeile eine Gesamtsumme von entweder 0,1,2,4 hat und jede Spalte zu 1 addiert. Außerdem möchte ich, dass die gesamte Summe der Matrix gleich 8 ist (was mit der Summenfunktion funktionierte). Ich versuchte mit der Funktion .sum() zu Constraint jeder Zeile und Spalte auf den Wert, den ich forderte, aber ich bekomme immer Syntaxfehler. Was mache ich falsch?Summe 2D-Array in Einschränkungen in System Verilog

rand bit MAT[8][8]; 
constraint range { 
MAT.sum() with (32' (item)) == 8; 
    foreach (MAT[j]){ 
     foreach(MAT[j][i]){ 
    MAT[j][].sum() with (32' (item)) == 1; 
    MAT[][i].sum() with (32' (item)) inside {0,1,2,4}; 
    } 
} 

Antwort

1

Abschnitt 7.12.3 Array Reduktionsmethoden der IEEE 1800-2012 Standard besagt, dass

[Array] Reduktionsverfahren kann auf jeden entpackten Array von Integralwerten angewendet werden, um das Array zu verringern, zu einem Einzelwert.

Während MAT[0].sum() oder MAT[1].sum() erlaubt ist (gilt Summe auf der Leitung 0 bzw. 1 von MAT), MAT.sum() nicht. Eine Zeile in MAT ist ein Array von bit und bit ist ein integraler Typ, aber MAT ist ein Array von entpackten Array von bit, die kein integraler Typ ist.

Es ist auch nicht möglich, eine einzelne Spalte aus einem Array auszuwählen. Sie können nur in Reihen schneiden. Dies ist ein wenig komplizierter zu implementieren, aber machbar.

Schauen wir uns jede Einschränkung an. Zuerst beschränke die Summe jeder Zeile leicht mit der sum() Funktion erfolgt:

constraint sum_on_row { 
    foreach (MAT[i]) 
     MAT[i].sum() with (32'(item)) inside { 0, 1, 2, 4 }; 
    } 

Um die Summe auf einer Spaltenintegritäts müssen Sie das Array transponieren (Zeilen zu Spalten, Spalten Zeilen werden) und schränke das ein. Lassen Sie uns zunächst die Transponierung von MAT definieren:

rand bit MAT_transp[8][8]; 

    constraint construct_MAT_transp { 
    foreach (MAT[i,j]) 
     MAT_transp[j][i] == MAT[i][j]; 
    } 

wir einen anderen Array zuweisen und halten seinen Inhalt synchron mit denen der MAT. Alle Einschränkungen für MAT_transp wirken sich indirekt auf MAT aus. Nach wie vor können wir die Reihen von MAT_transp, beschränken die effektiv die Spalten von MAT einschränken wird:

constraint sum_on_col { 
    foreach (MAT_transp[i]) 
     MAT_transp[i].sum() with (32'(item)) == 1; 
    } 

Und schließlich wollen Sie die Summe aller Elemente im Array 8. Dies ist der schwierigste zu sein, zu tun . Während wir die Array-Summe nicht direkt beschränken können, können wir das Problem in zwei Teile aufteilen. Erstens können wir die Summe für jede Zeile in MAT berechnen und speichern sie alle in einem Array:

rand int unsigned row_sums[8]; 

    constraint compute_row_sums { 
    foreach (row_sums[i]) 
     row_sums[i] == MAT[i].sum() with (32'(item)); 
    } 

Nun, da wir die Summe in jeder Zeile haben, ist es leicht, die Summe der gesamten Anordnung zu beschränken, indem den Zwang Summe aller Zeilensummen:

constraint sum_of_matrix { 
    row_sums.sum() == 8; 
    } 

Die kühle Sache ist, dass mit diesem ein Problem, das wir eine Menge von den üblichen „Tricks“ abgedeckt haben, können wir anwenden, wenn Arrays einzuschränken. Sie können weitere Array-Constraint-Idiome in einer old post I wrote finden.