我正在为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
答案 0 :(得分:1)
我没有完全读完你的代码,但如果你说这个寄存器在10'b0000_0000_01
和10'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;