Verilog — сложение с отрицательными числами

У меня проблема, когда кажется, что отрицательное число интерпретируется как положительное, и два значения добавляются, а не вычитаются. Вот мой код:

module color_controller(
input [10:0] hcount,
input [10:0] vcount,
 input CLK,
 input [1:0] mux,
 input blank,
 input [1:0] sw,
output reg [7:0] RGB,
 output reg [11:0] x
);

wire [2:0] a;


always @(posedge CLK)
    if(mux == 2'b10)
        x <= x + 1'b1;
    else if(mux == 2'b01)
        x <= x - 1'b1;
    else x <= x;

assign a = {blank, sw};
always @(a)
begin
    case(a)
        0 : RGB = 8'b00111000;
        1 : RGB = 8'b00111111;
        2 : if(hcount > (304 + x) && hcount < (336 + x) && vcount > 224 && vcount < 256)
                    RGB = 8'b11000000;
                else 
                    RGB = 8'b00000000;
        3 : if(vcount < 60)
                RGB = 8'b00000111;
            else if(vcount < 120)
                RGB = 8'b00111000;
            else if(vcount < 180)
                RGB = 8'b11000000;
            else if(vcount < 240)
                RGB = 8'b00111111;
            else if(vcount < 300)
                RGB = 8'b11000111;
            else if(vcount < 360)
                RGB = 8'b11111000;
            else if(vcount < 420)
                RGB = 8'b00000000;
            else 
                RGB = 8'b11111111;
        default : RGB = 8'b00000000;
    endcase
end

То, что я пытаюсь сделать, это прямо сейчас переместить прямоугольник по оси x на мониторе. Я могу заставить его нормально двигаться вдоль положительной (правой) оси и влево, вправо до тех пор, пока значение смещения x не станет отрицательным.

Я думаю, это происходит из-за того, что представление -1 в виде 2 равно FFF, но по какой-то причине, когда оно доходит до

if(hcount > (304 + x))

он забывает, что x является отрицательным, и я получаю очень большое значение, так что hcount никогда не достигнет его, и я не увижу ничего отображаемого.

Я попытался исправить это, изменив следующий код:

            2 : if(x[11] == 1'b0)
                if(hcount > (304 + x) && hcount < (336 + x) && vcount > 224 && vcount < 256)
                    RGB = 8'b11000000;
                else 
                    RGB = 8'b00000000;
            else 
                if(hcount > (304 - (~x+1)) && hcount < (336 - (~x+1)) && vcount > 224 && vcount < 256)
                    RGB = 8'b11000000;
                else 
                    RGB = 8'b00000000;

Я надеялся, что дополнительный код проверит, является ли x отрицательным, и переключит операцию на положительное число минус положительное число. Увы, это не сработало, и я просто не знаю, почему.

Помощь будет очень признательна, спасибо!


person user3474353    schedule 26.01.2015    source источник


Ответы (1)


В Verilog это арифметика со знаком или без знака, а не число. Число — это всего лишь набор битов, и его можно интерпретировать как угодно.

Verilog выполняет арифметику со знаком только в том случае, если все операнды подписаны. 304 - это беззнаковое десятичное число, заставляющее беззнаковую арифметику. Эти числа также должны иметь связанную с ними ширину для улучшения читаемости кода и соответствующих предупреждений, когда ширина недостаточно велика для представления значения.

пытаться:

if( hcount > (12'sd304 + x) )

or

if( hcount > ($signed(304) + x) )
person Morgan    schedule 26.01.2015