2017-06-28 3 views
0

Donc, fondamentalement, je veux que mon moniteur affiche une ligne négativement inclinée. Le code courant que j'ai écrit affiche parfaitement toute ligne positivement inclinée mais si je tente de la rendre négative, elle n'apparaît pas ou devient pointillée. J'ai une vague idée de pourquoi cela ne fonctionne pas, mais si quelqu'un pouvait me diriger dans la bonne direction, il serait très apprécié.Je souhaite afficher une ligne avec une pente négative dans le système verilog à travers VGA (les lignes à pente positive sont affichées correctement)

(Note: Mon pilote VGA fonctionne très bien, ainsi que le VGAWrapper)

Voici le code:

module vga_rgb(
    input logic [8:0] row_o, 
    input logic [9:0] column_o, 
    input logic clk_i,reset_i, 
    output logic [15:0]rgb_i 
    ); 

    localparam X1 = 10'd200; 
    localparam Y1 = 9'd100; 

    localparam X2 = 10'd400; 
    localparam Y2 = 9'd300; 

    wire [15:0] slope = ((Y2-Y1)/(X2-X1)); 

    [email protected](posedge clk_i, posedge reset_i) 
    if (reset_i) 
     rgb_i <= 16'b0; 
    else 
     if (((row_o-Y1) == (slope * (column_o-X1))) && ((row_o < 300) && (row_o > 100/))) 
     rgb_i <= 16'b0; 
     else   
     rgb_i <= 16'b11111_111111_11111; 
+0

Je devrais mentionner, le moniteur est un 640by480 – DIB98

+0

Je soupçonne une sorte d'erreur de débordement d'entier. – mkrieger1

Répondre

0

Vous y êtes presque. Le problème avec une pente négative, c'est que vous avez affaire à des quantités signées maintenant, ce qui peut être assez compliqué dans Verilog.

Les deux principales règles à garder à l'esprit sont:

  1. Assurez-vous d'allouer un peu plus pour le bit de signe. Alors que vous pouvez représentent 0..1023 en 10b non signé. Cela devient -512..511 lorsque est signé.
  2. En verilog le résultat d'une opration mathématique est non signé sauf si les deux opérandes sont signés. C'est généralement un comportement surprenant pour les nouveaux arrivants, mais c'est ainsi que le langage fonctionne.

Donc, avec quelques annotations signées, fixer la largeur de vos constantes, ce qui réduit la sortie à un bit, et réparer ce que je suppose que ce qui était une erreur de couper et coller je finis avec ceci:

module vga_rgb(
    input wire [8:0] row_o, 
    input wire [9:0] column_o, 
    input logic clk_i,reset_i, 
    output logic rgb_i 
    ); 

    localparam X1 = 11'sd200; 
    localparam Y1 = 10'sd100; 

    localparam X2 = 11'sd400; 
    localparam Y2 = 10'sd300; 

    wire signed [15:0] slope = ((Y2-Y1)/(X2-X1)); 

    [email protected](posedge clk_i, posedge reset_i) 
    if (reset_i) 
     rgb_i <= 16'b0; 
    else 
     if ((($signed({1'b0, row_o})-Y1) == (slope * ($signed({1'b0, column_o})-X1))) && ((row_o < Y2) && (row_o > Y1))) 
     rgb_i <= 1'b1; 
     else 
     rgb_i <= 1'b0; 

endmodule 

quelques choses à noter:

  1. Le « s » dans les localparams désignent une constante signé
  2. La tâche du système signé $ qui force une valeur à traiter comme signé. Notez comment j'ai ajouté un zéro initial, donc si le bit haut du signal entrant est défini, nous n'obtenons pas par inadvertance un nombre négatif.
+0

Ahhh, merci beaucoup pour vos commentaires! Cela a vraiment éclairci les choses pour moi, je l'apprécie :) – DIB98

+0

Glad it was helpful. N'hésitez pas à accepter la réponse si vous pensez que mon explication était suffisante. –