寄存器和整数比较不起作用
Register and integer comparison does not work
我在 SystemVerilog 中遇到了一个有趣的问题,即无法与寄存器进行比较。
module VGA_Colours
(
input wire clk, reset,
// input wire [3:0] swred, swgreen,
// input wire [1:0] swblue,
output wire hsync, vsync,
output wire [3:0] r, g, b
);
// constant declarations for VGA sync parameters
localparam H_DISPLAY = 640; // horizontal display area
localparam H_L_BORDER = 48; // horizontal left border
localparam H_R_BORDER = 16; // horizontal right border
localparam H_RETRACE = 96; // horizontal retrace
localparam H_MAX = H_DISPLAY + H_L_BORDER + H_R_BORDER + H_RETRACE - 1;
localparam START_H_RETRACE = H_DISPLAY + H_R_BORDER;
localparam END_H_RETRACE = H_DISPLAY + H_R_BORDER + H_RETRACE - 1;
localparam V_DISPLAY = 480; // vertical display area
localparam V_T_BORDER = 10; // vertical top border
localparam V_B_BORDER = 33; // vertical bottom border
localparam V_RETRACE = 2; // vertical retrace
localparam V_MAX = V_DISPLAY + V_T_BORDER + V_B_BORDER + V_RETRACE - 1;
localparam START_V_RETRACE = V_DISPLAY + V_B_BORDER;
localparam END_V_RETRACE = V_DISPLAY + V_B_BORDER + V_RETRACE - 1;
wire video_on, p_tick;
reg [9:0] ii;
reg j;
reg [3:0] red_reg, green_reg, blue_reg;
reg [11:0] rbg;
// mod-2 counter to generate 25 MHz pixel tick
reg pixel_reg = 0;
wire pixel_next;
wire pixel_tick;
always @(posedge clk)
pixel_reg <= pixel_next;
assign pixel_next = ~pixel_reg; // next state is complement of current
assign pixel_tick = (pixel_reg == 0); // assert tick half of the time
// registers to keep track of current pixel location
reg [9:0] h_count_reg, h_count_next, v_count_reg, v_count_next;
// register to keep track of vsync and hsync signal states
reg vsync_reg, hsync_reg;
wire vsync_next, hsync_next;
// infer registers
always @(posedge clk)
if(~reset)
begin
v_count_reg <= 0;
h_count_reg <= 0;
vsync_reg <= 0;
hsync_reg <= 0;
end
else
begin
v_count_reg <= v_count_next;
h_count_reg <= h_count_next;
vsync_reg <= vsync_next;
hsync_reg <= hsync_next;
end
// next-state logic of horizontal vertical sync counters
always @*
begin
h_count_next = pixel_tick ?
h_count_reg == H_MAX ? 0 : h_count_reg + 1
: h_count_reg;
v_count_next = pixel_tick && h_count_reg == H_MAX ?
(v_count_reg == V_MAX ? 0 : v_count_reg + 1)
: v_count_reg;
end
// hsync and vsync are active low signals
// hsync signal asserted during horizontal retrace
assign hsync_next = h_count_reg >= START_H_RETRACE
&& h_count_reg <= END_H_RETRACE;
// vsync signal asserted during vertical retrace
assign vsync_next = v_count_reg >= START_V_RETRACE
&& v_count_reg <= END_V_RETRACE;
// video only on when pixels are in both horizontal and vertical display region
assign video_on = (h_count_reg < H_DISPLAY)
&& (v_count_reg < V_DISPLAY);
// output signals
assign hsync = hsync_reg;
assign vsync = vsync_reg;
assign p_tick = pixel_tick;
always @(posedge p_tick) begin
if (~reset) begin
rbg <= 12'b000000000000;
ii <= 9'b0;
end else begin
if (h_count_reg == 0) begin
rbg <= 12'b000000000000;
ii <= 9'b0;
end else if (h_count_reg == ii) begin
ii <= ii + 9'b001010000;
rbg <= rbg + 12'b000010000000;
end
end
end
// output
assign r = (video_on) ? rbg[11:8] : 4'b0;
assign g = (video_on) ? rbg[7:4] : 4'b0;
assign b = (video_on) ? rbg[3:0] : 4'b0;
endmodule
在上面的代码中 h_count_reg
是 0 可以正常工作。如果我将 0 更改为任何不同的数字,它将按预期工作。但是,如果我用一个变量(即“ii”,在我的模块顶部声明为 reg[9:0] ii
)替换该数字,代码似乎会忽略它,这很奇怪。用任何数字替换 ii
变量都可以。为什么?
测试台文件:
module VGA_Colours_tb ();
logic clk;
reg reset;
wire hsync, vsync;
wire [3:0] r, g, b;
VGA_Colours scr0 (
.clk (clk),
.reset (reset),
.hsync (hsync),
.vsync (vsync),
.r (r),
.b (b),
.g (g)
);
initial begin
clk = 0;
forever #10 clk = ~clk;
end
always @(posedge clk) begin
#20
reset <= 1'b0;
#20
reset <= 1'b1;
#100000
$finish;
end
endmodule
模拟波:
从代码可以看出,当h_count_reg==到ii时,增加rbg和ii的值。然而,根据模拟波,它并没有这样做,就好像 h_count_reg 的值不等于 ii 而实际上是这样。
您在 VGA_Colours
模块中存在逻辑错误。
这是缩进更一致的代码:
always @(posedge p_tick) begin
if (~reset) begin
rbg <= 12'b000000000000;
ii <= 9'b0;
end else begin
if (h_count_reg == 0) begin
rbg <= 12'b000000000000;
ii <= 9'b0;
end else if (h_count_reg == ii) begin
rbg <= rbg + 12'b000010000000;
ii <= ii + 9'b001010000;
end
end
end
当我 运行 你的模拟时,我观察到 ii
在初始重置后始终为 0。
该代码有 3 个 if
语句。当 reset=0 时,第一个 if
语句在模拟开始时为真。这会将 ii
设置为 0。
重置后,我看到 h_count_reg=0 4 次。这意味着第 2 个 if
语句为真 4 次。这使 ii
= 0.
第三个if
语句仅在h_count_reg
不为0时才被评估。现在应该很清楚第三个if
语句永远不会为真。这意味着 ii
不会递增,它会保持为 0。例如,当 h_count_reg=1 时,则 (h_count_reg == ii)
为假,因为 ii
始终为 0.
我在 SystemVerilog 中遇到了一个有趣的问题,即无法与寄存器进行比较。
module VGA_Colours
(
input wire clk, reset,
// input wire [3:0] swred, swgreen,
// input wire [1:0] swblue,
output wire hsync, vsync,
output wire [3:0] r, g, b
);
// constant declarations for VGA sync parameters
localparam H_DISPLAY = 640; // horizontal display area
localparam H_L_BORDER = 48; // horizontal left border
localparam H_R_BORDER = 16; // horizontal right border
localparam H_RETRACE = 96; // horizontal retrace
localparam H_MAX = H_DISPLAY + H_L_BORDER + H_R_BORDER + H_RETRACE - 1;
localparam START_H_RETRACE = H_DISPLAY + H_R_BORDER;
localparam END_H_RETRACE = H_DISPLAY + H_R_BORDER + H_RETRACE - 1;
localparam V_DISPLAY = 480; // vertical display area
localparam V_T_BORDER = 10; // vertical top border
localparam V_B_BORDER = 33; // vertical bottom border
localparam V_RETRACE = 2; // vertical retrace
localparam V_MAX = V_DISPLAY + V_T_BORDER + V_B_BORDER + V_RETRACE - 1;
localparam START_V_RETRACE = V_DISPLAY + V_B_BORDER;
localparam END_V_RETRACE = V_DISPLAY + V_B_BORDER + V_RETRACE - 1;
wire video_on, p_tick;
reg [9:0] ii;
reg j;
reg [3:0] red_reg, green_reg, blue_reg;
reg [11:0] rbg;
// mod-2 counter to generate 25 MHz pixel tick
reg pixel_reg = 0;
wire pixel_next;
wire pixel_tick;
always @(posedge clk)
pixel_reg <= pixel_next;
assign pixel_next = ~pixel_reg; // next state is complement of current
assign pixel_tick = (pixel_reg == 0); // assert tick half of the time
// registers to keep track of current pixel location
reg [9:0] h_count_reg, h_count_next, v_count_reg, v_count_next;
// register to keep track of vsync and hsync signal states
reg vsync_reg, hsync_reg;
wire vsync_next, hsync_next;
// infer registers
always @(posedge clk)
if(~reset)
begin
v_count_reg <= 0;
h_count_reg <= 0;
vsync_reg <= 0;
hsync_reg <= 0;
end
else
begin
v_count_reg <= v_count_next;
h_count_reg <= h_count_next;
vsync_reg <= vsync_next;
hsync_reg <= hsync_next;
end
// next-state logic of horizontal vertical sync counters
always @*
begin
h_count_next = pixel_tick ?
h_count_reg == H_MAX ? 0 : h_count_reg + 1
: h_count_reg;
v_count_next = pixel_tick && h_count_reg == H_MAX ?
(v_count_reg == V_MAX ? 0 : v_count_reg + 1)
: v_count_reg;
end
// hsync and vsync are active low signals
// hsync signal asserted during horizontal retrace
assign hsync_next = h_count_reg >= START_H_RETRACE
&& h_count_reg <= END_H_RETRACE;
// vsync signal asserted during vertical retrace
assign vsync_next = v_count_reg >= START_V_RETRACE
&& v_count_reg <= END_V_RETRACE;
// video only on when pixels are in both horizontal and vertical display region
assign video_on = (h_count_reg < H_DISPLAY)
&& (v_count_reg < V_DISPLAY);
// output signals
assign hsync = hsync_reg;
assign vsync = vsync_reg;
assign p_tick = pixel_tick;
always @(posedge p_tick) begin
if (~reset) begin
rbg <= 12'b000000000000;
ii <= 9'b0;
end else begin
if (h_count_reg == 0) begin
rbg <= 12'b000000000000;
ii <= 9'b0;
end else if (h_count_reg == ii) begin
ii <= ii + 9'b001010000;
rbg <= rbg + 12'b000010000000;
end
end
end
// output
assign r = (video_on) ? rbg[11:8] : 4'b0;
assign g = (video_on) ? rbg[7:4] : 4'b0;
assign b = (video_on) ? rbg[3:0] : 4'b0;
endmodule
在上面的代码中 h_count_reg
是 0 可以正常工作。如果我将 0 更改为任何不同的数字,它将按预期工作。但是,如果我用一个变量(即“ii”,在我的模块顶部声明为 reg[9:0] ii
)替换该数字,代码似乎会忽略它,这很奇怪。用任何数字替换 ii
变量都可以。为什么?
测试台文件:
module VGA_Colours_tb ();
logic clk;
reg reset;
wire hsync, vsync;
wire [3:0] r, g, b;
VGA_Colours scr0 (
.clk (clk),
.reset (reset),
.hsync (hsync),
.vsync (vsync),
.r (r),
.b (b),
.g (g)
);
initial begin
clk = 0;
forever #10 clk = ~clk;
end
always @(posedge clk) begin
#20
reset <= 1'b0;
#20
reset <= 1'b1;
#100000
$finish;
end
endmodule
模拟波:
从代码可以看出,当h_count_reg==到ii时,增加rbg和ii的值。然而,根据模拟波,它并没有这样做,就好像 h_count_reg 的值不等于 ii 而实际上是这样。
您在 VGA_Colours
模块中存在逻辑错误。
这是缩进更一致的代码:
always @(posedge p_tick) begin
if (~reset) begin
rbg <= 12'b000000000000;
ii <= 9'b0;
end else begin
if (h_count_reg == 0) begin
rbg <= 12'b000000000000;
ii <= 9'b0;
end else if (h_count_reg == ii) begin
rbg <= rbg + 12'b000010000000;
ii <= ii + 9'b001010000;
end
end
end
当我 运行 你的模拟时,我观察到 ii
在初始重置后始终为 0。
该代码有 3 个 if
语句。当 reset=0 时,第一个 if
语句在模拟开始时为真。这会将 ii
设置为 0。
重置后,我看到 h_count_reg=0 4 次。这意味着第 2 个 if
语句为真 4 次。这使 ii
= 0.
第三个if
语句仅在h_count_reg
不为0时才被评估。现在应该很清楚第三个if
语句永远不会为真。这意味着 ii
不会递增,它会保持为 0。例如,当 h_count_reg=1 时,则 (h_count_reg == ii)
为假,因为 ii
始终为 0.