2017-11-16 9 views
0

Ich schreibe ein Modul für ein Spiel von Pong, das zwei Register namens change_x und change_y hat, die zwischen positiv und negativ wechseln (es sagt ZWEI im Code, aber ich änderte es beim Debuggen auf 1). Diese Register sind 10 Bits, so dass sie zwischen 10'b0000_0000_01 und 10'b1111_1111_11 wechseln. Als ich synthetisieren ich die Warnung erhalten:Gibt es eine Möglichkeit, ein Register von einem positiven auf ein negatives zu ändern, ohne dass die Warnung "Latch trimming" ausgegeben wird?

Xst:1710 - FF/Latch <change_x_0> (without init value) has a constant value of 1 in block <pixel_gen>. This FF/Latch will be trimmed during the optimization process. 
Xst:1710 - FF/Latch <change_y_0> (without init value) has a constant value of 1 in block <pixel_gen>. This FF/Latch will be trimmed during the optimization process. 
Xst:1710 - FF/Latch <change_x_0> (without init value) has a constant value of 1 in block <PIXEL_GEN>. This FF/Latch will be trimmed during the optimization process. 
Xst:1895 - Due to other FF/Latch trimming, FF/Latch <change_y_0> (without init value) has a constant value of 1 in block <PIXEL_GEN>. This FF/Latch will be trimmed during the optimization process. 

Zuerst möchte ich sicher, nur um sicherzustellen, dass ich die Warnungen richtig bin zu interpretieren, bin ich sie bekommen, weil die am wenigsten signifikanten Bits auf diese Register nie ändern? Zweitens, gibt es eine andere Möglichkeit, sie zuzuordnen, damit ich die Warnungen nicht bekomme? Ich setze einen Blockkommentar über den Teil, wo die Register geschaltet werden.

module PIXEL_GEN(
input clock, 
input reset, 
input [9:0] pixel_x, pixel_y, 
input video_on, 
input btn_up, 
input btn_dn, 
output reg [7:0] rgb 
); 

// ROM signals for round ball. 
wire [3:0] rom_col; 
wire [3:0] rom_addr; 
wire [7:0] ball_rgb, wall_rgb, paddle_rgb, background_rgb; 
wire  rom_bit, round_ball_on; 
reg [8:0] rom_data; 

// Ball moving parts. 
reg [9:0] ball_top; 
reg [9:0] ball_btm; 
reg [9:0] ball_lef; 
reg [9:0] ball_rit; 

// Ball change reg. 
reg [9:0] change_x; 
reg [9:0] change_y;  

// Paddle moving parts. 
reg [9:0] paddle_top; 
reg [9:0] paddle_btm; 

// Wall limits. 
localparam WALL_LEFT = 10'd32; 
localparam WALL_RIGHT = 10'd35; 

// Paddle side limits. 
localparam PADDLE_LEFT  = 10'd600; 
localparam PADDLE_RIGHT  = 10'd603; 
localparam PADDLE_BTM_RESET = 10'd276; 
localparam PADDLE_TOP_RESET = 10'd204; 

// Paddle length. 
localparam PADDLE_LENGTH = PADDLE_BTM_RESET - PADDLE_TOP_RESET; 

// Ball reset limits. 
localparam BALL_LEFT_RESET = 10'd580; 
localparam BALL_RIGHT_RESET = 10'd588; 
localparam BALL_TOP_RESET = 10'd238; 
localparam BALL_BTM_RESET = 10'd246; 

// Screen boundaries. 
localparam TOP = 10'd0; 
localparam BOTTOM = 10'd479; 
localparam LEFT = 10'd0; 
localparam RIGHT = 10'd639; 

// Two pixel shift each transition. 
localparam TWO = 10'd1; 
localparam ONE = 10'd1; 
localparam ZERO = 10'd0; 

// Assigns object colors. 
localparam BALL_RGB  = 8'b000_000_11; // Blue 
localparam WALL_RGB  = 8'b111_000_00; // Red 
localparam PADDLE_RGB  = 8'b000_111_00; // Green 
localparam BACKGROUND_RGB = 8'b111_111_11; // White 
localparam BLACK   = 8'b000_000_00; // Black 

// Refrence tick 60Hz. 
assign ref_tick = (pixel_y == 10'd481) & (pixel_x == 10'd0); 
// Define boundaries for square ball and asserts an "on" signal. 
assign square_ball_on = pixel_x >= ball_lef & pixel_x <= ball_rit & 
         pixel_y <= ball_btm & pixel_y >= ball_top; 
// Selects ROM row. 
assign rom_addr = pixel_y[3:0] - ball_top[3:0]; 
// Finds ROM column. 
assign rom_col = pixel_x[3:0] - ball_lef[3:0]; 
// Finds specific bit from ROM row and column. 
assign rom_bit = rom_data[ rom_col ]; 
// Asserts round_ball_on signal if in the correct 
// region and current bit is a one. 
assign round_ball_on = square_ball_on & rom_bit; 

[email protected](posedge clock, posedge reset) begin 

    // Restore paddle and ball to reset state. 
    if(reset) begin 

     // Reset paddle top/bottom limits. 
     paddle_top <= PADDLE_TOP_RESET; 
     paddle_btm <= PADDLE_BTM_RESET; 

     // Reset ball limits. 
     ball_top <= BALL_TOP_RESET; 
     ball_btm <= BALL_BTM_RESET; 
     ball_lef <= BALL_LEFT_RESET; 
     ball_rit <= BALL_RIGHT_RESET; 

     // Set change. 
     change_x <= -TWO; 
     change_y <= -TWO; 

    end 

    // Move paddle up or down if button is pushed. 
    else if(ref_tick) begin 

    // Update paddle top and bottom limits. 
    // BtnUp and not hitting top. 
    if  (btn_up & paddle_top >= TWO   ) begin 
     paddle_top <= paddle_top - TWO; 
     paddle_btm <= paddle_btm - TWO; 
    end 
    // BtnUp and hitting top. 
    else if(btn_up        ) begin 
     paddle_top <= TOP; 
     paddle_btm <= TOP + PADDLE_LENGTH; 
    end 
    // BtnDn and not hitting bottom. 
    else if(btn_dn & paddle_btm + TWO < BOTTOM) begin 
     paddle_top <= paddle_top + TWO; 
     paddle_btm <= paddle_btm + TWO; 
    end 
    // BtnDn and hitting bottom. 
    else if(btn_dn & paddle_btm + TWO >= BOTTOM) begin 
     paddle_top <= BOTTOM - PADDLE_LENGTH; 
     paddle_btm <= BOTTOM; 
    end 
    else begin 
     paddle_top <= paddle_top; 
     paddle_btm <= paddle_btm;   
    end 

    /************************************************************ 
    This is where the values switch between positve and negative. 
    ************************************************************/ 

    // Update change in velocity if top is hit. 
    if  (ball_top - TWO <= TOP  ) 
     change_y <= TWO; 
    // Update change in velocity if bottom is hit. 
    else if(ball_btm + TWO >= BOTTOM ) 
     change_y <= -TWO;  
    // Update change in velocity if wall is hit. 
    else if(ball_lef - TWO <= WALL_RIGHT) 
     change_x <= TWO; 
    // Update change in velocity if paddle is hit. 
    else if(ball_rit + TWO == PADDLE_LEFT & 
      ~((ball_top < paddle_top & ball_btm < paddle_top) | 
       (ball_top > paddle_btm & ball_btm > paddle_btm))     
      ) 
     change_x <= -TWO; 
    else begin 
     change_y <= change_y; 
     change_x <= change_x; 
    end    

    // Update ball limits. 
    ball_top <= ball_top + change_y; 
    ball_btm <= ball_btm + change_y; 
    ball_lef <= ball_lef + change_x; 
    ball_rit <= ball_rit + change_x; 

    end 

end 

[email protected](*) begin 

    // Wall 
    if(pixel_x >= WALL_LEFT & pixel_x <= WALL_RIGHT & 
     video_on) 
     rgb = WALL_RGB ; 
    // Paddle 
    else if(pixel_x >= PADDLE_LEFT & pixel_x <= PADDLE_RIGHT & 
      pixel_y >= paddle_top & pixel_y <= paddle_btm & 
      video_on) 
     rgb = PADDLE_RGB ; 
    // Ball 
    else if(round_ball_on & video_on) 
     rgb = BALL_RGB; 
    // Background 
    else if(video_on) 
     rgb = BACKGROUND_RGB ; 
    // Black if no video on signal. 
    else 
     rgb = BLACK;   

    // Round ball image ROM. 
    case(rom_addr) 
     4'h0 : rom_data = 9'b000111000; // *** 
     4'h1 : rom_data = 9'b011111110; // ******* 
     4'h2 : rom_data = 9'b011111110; // ******* 
     4'h3 : rom_data = 9'b111111111; // ********* 
     4'h4 : rom_data = 9'b111111111; // ********* 
     4'h5 : rom_data = 9'b111111111; // ********* 
     4'h6 : rom_data = 9'b011111110; // ******* 
     4'h7 : rom_data = 9'b011111110; // ******* 
     4'h8 : rom_data = 9'b000111000; // *** 
     default: rom_data = 9'b000000000; // Default 
    endcase 

end 

endmodule 

Antwort

1

Ich habe nicht vollständig durch den Code zu lesen, aber wenn Sie richtig sind, dass dieses Register schaltet zwischen 10'b0000_0000_01 und 10'b1111_1111_11 dann dem LSB immer 1. Keine Notwendigkeit, einen Flip-Flop zu haben, das Bit zu speichern, so es ist weg optimiert.

Bens Kommentar unten zeigt, wie man damit umgeht. Sie können diese Optimierung explizit vornehmen. Etwas wie:

logic change_polarity; 
... 
if(some_condition) 
    change_polarity <= 1'b1; 
else if(some_other_condition) 
    change_polarity <= 1'b0; 
... 
logic [9:0] change; 
assign change = change_polarity ? 10'h3FF : 1h'h001; 
+0

Ein besserer Optimierer würde das auf nur ein Register abschneiden, weil alle anderen Bits gleich sind. –

Verwandte Themen