0
votes

I'm having a problem where it seems that a negative number is interpreted as positive, and two values are added rather than subtracted. Here's my code:

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

What I'm trying to do is right now move a box along the x-axis on a monitor. I can get it to move just fine along the positive(right) axis, and to the left, right up until the displacement value x becomes negative.

I think this happens because the 2's comp representation of -1 is FFF, but for whatever reason when it gets to

if(hcount > (304 + x))

it forgets that x is negative and I get a very large value, such that hcount will never reach it and I will see nothing being displayed.

I tried to fix this by modifying the following code:

            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;

I hoped that the additional code would check if x was negative, and switch the operation to be a positive number minus a positive number. Alas, it did not work, and I just don't know why.

Help would be very appreciated, thanks!

1

1 Answers

0
votes

In verilog it is the arithmetic which is signed or unsigned rather than the number. The number is just a pattern of bits and can be interpreted however you want.

Verilog only performs signed arithmetic if all operands are signed. 304 is an unsigned decimal forcing unsigned arithmetic. These numbers should also have a width associated with them for improved code readability and relevant warnings when the width is not large enough to represent the value.

try:

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

or

if( hcount > ($signed(304) + x) )