So basically I want my monitor to display a negatively sloped line. The current code which I wrote displays any positively sloped line perfectly however if I attempt to make it negative, it doesn't appear or becomes dotted. I have a vague idea of why it doesn't work however if anyone could point me in the right direction it would be much appreciated.
(Note: My VGA driver works fine as well as the VGAWrapper)
This is the 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));
always@(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;
You're almost there. The problem is with a negative slope is, well, that you're dealing with signed quantities now which can be pretty tricky in Verilog.
The two main rules to keep in mind are:
So with a few signed annotations, fixing the width of your constants, reducing the output to one bit, and repairing what I presume what was a cut and paste error I end up with this:
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));
always@(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
A few things to note: