2017-11-16 4 views
0

나는 Pong 게임을 위해 change_x와 change_y라는 두 개의 레지스터를 가지고 있는데, 양수와 음수 사이를 전환합니다. (코드에서 TWO라고 쓰지만 디버깅 중에는 1로 변경했습니다). 이 레지스터는 10 비트이므로 10'b0000_0000_01과 10'b1111_1111_11 사이를 전환합니다. 내가 경고 얻을 합성 할 때 :래치 트림 경고를받지 않고 같은 번호의 레지스터를 양수에서 음수로 전환 할 수 있습니까?

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. 

이 먼저 난 그냥 경고를 잘 해석하고있어이 있는지 확인하려면 이러한 레지스터의 최하위 비트는 변경하지 않기 때문에, 나는 그들에게 무엇입니까? 둘째, 경고를받지 않도록 지정하는 또 다른 방법이 있습니까? 레지스터가 전환되는 부분 위에 블록 주석을 달았습니다.

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 

답변

1

나는 완전히 당신의 코드를 읽어 보지 않았,하지만 당신이 올바른지 다음 10'b0000_0000_0110'b1111_1111_11 사이의 레지스터 스위치는 LSB 1. 그 비트를 저장하는 플립 플롭을 할 필요가 항상입니다 그래서 그것은 최적화되어 있습니다.

아래의 벤의 의견은 어떻게 처리해야하는지 지적합니다. 명시 적으로 최적화를 수행 할 수 있습니다. 다음과 같음 :

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

더 나은 옵티마이 저는 다른 모든 비트가 서로 같기 때문에 하나의 레지스터만으로 트리밍 할 수 있습니다. –

관련 문제