2016-07-04 10 views
0

Ich bin neu in Verilog und ich würde es wirklich zu schätzen, wenn jemand mir mit diesem Fehler helfen könnte:Verilog-Fehler: Ein Verweis auf einen Draht oder reg nicht in einem konstanten Ausdruck erlaubt

output reg [0:image_width][image_height:0] result 
.... 
integer i, j, imageX, imageY, x, y, kernelX, kernelY; 
.... 

@(negedge ACLK) 
for(x = 0; x < image_width; x++) begin 
    for(y = 0; y < image_height; y++) 
    begin 
    //multiply every value of the filter with corresponding image pixel 
     for(kernelX = 0; kernelX < kernel_width; kernelX++) begin    
      for(kernelY = 0; kernelY < kernel_height; kernelY++) 
       begin   
        imageX = (x - kernel_width/2 + kernelX + image_width) % image_width; 
        imageY = (y - kernel_height/2 + kernelY + image_height) % image_height; 

        // ignore input samples which are out of bound 
        if(imageY >= 0 && imageY < image_height && imageX >= 0 && imageX < image_width) 
         //ERROR HERE!!! 
         result[x][y] += image[imageX][imageY] * kernel[kernelX][kernelY]; 
        end 
       end 
     end 
    end 
end 

Die Fehler, den ich bekomme ist:

error: A reference to a wire or reg ('x') is not allowed in a constant expression.
error: Array index expressions must be constant here.
error: A reference to a wire or reg ('imageX') is not allowed in a constant expression.
error: Array index expressions must be constant here.
error: A reference to a wire or reg ('kernelX') is not allowed in a constant expression.
error: Array index expressions must be constant here.

Könnte mir jemand sagen, was ich falsch mache? Vielen Dank!

+0

Sind Sie sicher, 'image_width' und' image_height' sind Parameter? – sharvil111

+0

Ja, das sind sie. '' Modul PU_conv '# (// Parameters' ' Parameter image_width integer = 10, '' Parameter integer image_height = 4, '' Parameter integer kernel_width = 2, '' Parameter integer kernel_height = 2' ')' – AnnaR

Antwort

0

Diese Linie ist das Problem:

result[x][y] += image[imageX][imageY] * kernel[kernelX][kernelY]; 

Indizierung in Arrays nur für konstanten Ausdrücke erlaubt. Sie dürfen keine Variablen in Vektorindizes verwenden. Denken Sie daran, dass Sie mit einem HDL arbeiten: Sie diktieren physikalische Verbindungen in Hardware. Wenn Sie eine Variable im Index haben, können Sie die Schaltung dynamisch neu verkabeln. This SO question hat einige grobe Problemumgehungen, die für Sie arbeiten können. Sie sollten jedoch wirklich versuchen, Ihren Algorithmus umzuformulieren, um zu vermeiden, dass Sie die Variablenindexierung zuerst verwenden müssen.

Übrigens sollten Sie non-blocking assignments anstatt der blockierenden Zuordnungen verwenden, die Sie zurzeit haben. Ihr Code ist in einem getakteten Block, so dass blockierende kombinatorische Logik sollte vermieden werden:

imageX <= (x - kernel_width/2 + kernelX + image_width) % image_width; 
imageY <= (y - kernel_height/2 + kernelY + image_height) % image_height; 

// ignore input samples which are out of bound 
if(imageY >= 0 && imageY < image_height && imageX >= 0 && imageX < image_width) 
    result[x][y] <= result[x][y] + image[imageX][imageY] * kernel[kernelX][kernelY]; 
+0

Vielen Dank! Würde es Ihnen etwas ausmachen, mir zu sagen, wie ich das beheben kann? Ich habe es nicht herausgefunden. – AnnaR

+0

@AnnaR Ich schlage vor, dass Sie jemanden besuchen, der Verilog persönlich kennt, um Hilfe zu bekommen. Dein TA oder Professor sollte helfen können. Sie müssen Ihren gesamten Algorithmus überdenken, um die Notwendigkeit zu vermeiden, Variablen zu verwenden, um in Ihre Vektoren zu indizieren. Wenn Sie zulassen können, dass es sich um Konstanten handelt, können Sie eine Genvar verwenden, um Ihre Funktionsaufrufe statisch zu verbinden. Ich schlage das auch vor, weil Ihr Code umfangreiche Verbesserungen benötigt - sie können Ihnen dabei helfen, blockierende und nicht blockierende Zuweisungen zu verstehen, und vier verschachtelte Schleifen deuten darauf hin, dass es einen besseren Weg dafür gibt. – skrrgwasme

0
@(negedge ACLK); 
      ^

Ich bin mir ziemlich sicher, dass Semikolon nicht dorthin gehört. Wie geschrieben, sind die for-Schleifen alle außerhalb des Blocks.

Zusätzlich verfügt Ihr Array image derzeit nur über ein Bit pro Pixel. Ist das beabsichtigt? Ob es ist oder nicht, ich würde empfehlen, dass Sie diese Architektur überdenken; Das Filtern eines Bildes mit irgendeiner signifikanten Größe in einem einzigen Taktzyklus wird nicht sehr gut synthetisieren.

+0

Es tut mir leid, das war ein Tippfehler. Ich habe es behoben. Ich bekomme immer noch den gleichen Fehler. Alle for-Schleifen befinden sich in der Task. Außerdem, nein, ich brauche mehr als 1 Bit pro Pixel, stimmt etwas nicht damit, wie ich das Array deklariert habe? – AnnaR

+0

Sie deklarieren das Array als 'image_width' x' image_height' Array von 'reg's. Ein Register ist ein Bit. – duskwuff