我希望通过VGA在系统verilog中显示一个负斜率的线(正斜率线正确显示)

时间:2017-06-28 11:44:32

标签: verilog system-verilog vga

所以基本上我希望我的显示器显示负斜率线。我写的当前代码完全显示任何正斜率线,但如果我试图使其为负,它不会出现或变成点状。 我有一个模糊的想法,为什么它不起作用,但如果有人能指出我正确的方向,将非常感激。

(注意:我的VGA驱动程序和VGAWrapper一样正常工作)

这是代码:

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;

1 个答案:

答案 0 :(得分:0)

你快到了。问题是负斜率是,你现在正在处理签名数量,这在Verilog中可能相当棘手。

要记住的两个主要规则是:

  1. 请务必为符号位分配一个额外位。虽然你可以 在10b无符号中表示0..1023。那变成了-512..511 签名。
  2. 在verilog中,数学运算的结果是无符号的 除非两个操作数都已签名。这通常很深刻 这对新手来说是令人惊讶的行为,但这就是语言运作的方式。
  3. 因此,使用一些带符号的注释,修复常量的宽度,将输出减少到一位,并修复我认为什么是剪切和粘贴错误,我最终得到了这个:

    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
    

    有几点需要注意:

    1. localparams中的's'表示有符号常数
    2. $ signed系统任务,强制将值视为已签名。注意我是如何添加前导零的,所以如果设置输入信号的高位,我们不会无意中得到负数。