有没有办法将寄存器从相同数字的正数切换到负数,而不会收到锁存器调整警告



我正在为一个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;
always@( 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
always@( * ) 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
我没有

完全通读您的代码,但是如果您是正确的,则此寄存器在10'b0000_0000_0110'b1111_1111_11之间切换,则LSB始终为1。无需使用触发器来存储该位,因此对其进行了优化。

Ben 下面的评论指出了如何处理这个问题。您可以显式进行此优化。像这样:

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;

最新更新