Verilog 得到 'x' 作为输出而不是 '0' 和 '1'
Verilog getting 'x' as an output instead of '0' and '1'
我正在尝试创建一个具有四位内存地址的四元素直接映射缓存。程序 运行 完全没问题,没有编译错误,但突然在输出中,我得到 'x' 只是第一条语句。在那之后,我在其他任何地方都看不到它。任何帮助,将不胜感激。这是代码
module cache_memory_direct_mapped(input clk,
input reset,
input [3:0]read_addr,
output reg hit,
output reg miss,
output reg [7:0]hit_count,
output reg [7:0]miss_count);
reg [1:0]c1[3:0];
initial
begin
hit_count =8'h00;
miss_count = 8'h00;
end
always @(posedge clk, posedge reset)
begin
if(reset)
begin
c1[0] <= 2'hx;
c1[1] <= 2'hx;
c1[2] <= 2'hx;
c1[3] <= 2'hx;
end
else
begin
if(read_addr[3:2] == c1[0] || read_addr[3:2] == c1[1] || read_addr[3:2] == c1[2] || read_addr[3:2] == c1[3])
begin
hit <= 1;
hit_count <= hit_count + 1;
miss <= 0;
end
else
begin
hit <= 0;
miss <= 1;
miss_count <= miss_count + 1;
if(read_addr[1:0] == 2'b0 )
c1[0] <= read_addr[3:2];
else if(read_addr[1:0] == 2'b1 )
c1[1] <= read_addr[3:2];
else if(read_addr[1:0] == 2'b10 )
c1[2] <= read_addr[3:2];
else if(read_addr[1:0] == 2'b11 )
c1[3] <= read_addr[3:2];
end
end
end
endmodule
module Tb_direct_mapped;
// Inputs
reg clk;
reg reset;
reg [3:0] read_addr;
// Outputs
wire hit;
wire miss;
wire [7:0]hit_count;
wire [7:0]miss_count;
integer data_file ; // file handler
integer scan_file ; // file handler
reg [4:0]captured_data;
// Instantiate the Unit Under Test (UUT)
cache_memory_direct_mapped uut (
.clk(clk),
.reset(reset),
.read_addr(read_addr),
.hit(hit),
.miss(miss),
.hit_count(hit_count),
.miss_count(miss_count)
);
initial begin
// Initialize Inputs
clk = 0;
reset = 0;
data_file = $fopen("data_file.txt", "r");
end
always
#10 clk= ~clk;
always @(posedge clk) begin
scan_file = $fscanf(data_file, "%h\n", captured_data);
if (!$feof(data_file)) begin
read_addr <= captured_data;
$display(hit);
//$display(hit_count);
end
else
$finish;
end
endmodule
这是输出的图片
我可以在“cache_memory_direct_mapped”中看到一个问题。
always里面的else下面(下面复制粘贴)
if(read_addr[1:0] == 2'b0 )
c1[0] <= read_addr[3:2];
else if(read_addr[1:0] == 2'b1 )
c1[1] <= read_addr[3:2];
else if(read_addr[1:0] == 2'b10 )
c1[2] <= read_addr[3:2];
else if(read_addr[1:0] == 2'b11 )
c1[3] <= read_addr[3:2];
- 在每个 if 语句下,您只为 C1 的一个部分赋值,其余部分将不会更新并带有它们的初始“X”值。在每个 is/else if?
中,您可以将 0 分配给其余部分吗?
- 如果不满足none个条件会怎样,最后可能还需要else语句。
变化:
$display(hit);
至:
$strobe(hit);
这输出:
0
0
1
1
0
1
来自 IEEE 标准 1800-2017,第 21.2.2 节频闪监控:
The system task $strobe provides the ability to display simulation
data at a selected time. That time is the end of the current
simulation time, when all the simulation events have occurred for that
simulation time, just before simulation time is advanced.
问题是当您在 posedge clk 调用 $display
时,您的信号值正在改变。
这里有一些额外的调试技巧:
- 使用波形调试器。
- 显示仿真时间和数值:
$strobe($time, " ", hit);
我正在尝试创建一个具有四位内存地址的四元素直接映射缓存。程序 运行 完全没问题,没有编译错误,但突然在输出中,我得到 'x' 只是第一条语句。在那之后,我在其他任何地方都看不到它。任何帮助,将不胜感激。这是代码
module cache_memory_direct_mapped(input clk,
input reset,
input [3:0]read_addr,
output reg hit,
output reg miss,
output reg [7:0]hit_count,
output reg [7:0]miss_count);
reg [1:0]c1[3:0];
initial
begin
hit_count =8'h00;
miss_count = 8'h00;
end
always @(posedge clk, posedge reset)
begin
if(reset)
begin
c1[0] <= 2'hx;
c1[1] <= 2'hx;
c1[2] <= 2'hx;
c1[3] <= 2'hx;
end
else
begin
if(read_addr[3:2] == c1[0] || read_addr[3:2] == c1[1] || read_addr[3:2] == c1[2] || read_addr[3:2] == c1[3])
begin
hit <= 1;
hit_count <= hit_count + 1;
miss <= 0;
end
else
begin
hit <= 0;
miss <= 1;
miss_count <= miss_count + 1;
if(read_addr[1:0] == 2'b0 )
c1[0] <= read_addr[3:2];
else if(read_addr[1:0] == 2'b1 )
c1[1] <= read_addr[3:2];
else if(read_addr[1:0] == 2'b10 )
c1[2] <= read_addr[3:2];
else if(read_addr[1:0] == 2'b11 )
c1[3] <= read_addr[3:2];
end
end
end
endmodule
module Tb_direct_mapped;
// Inputs
reg clk;
reg reset;
reg [3:0] read_addr;
// Outputs
wire hit;
wire miss;
wire [7:0]hit_count;
wire [7:0]miss_count;
integer data_file ; // file handler
integer scan_file ; // file handler
reg [4:0]captured_data;
// Instantiate the Unit Under Test (UUT)
cache_memory_direct_mapped uut (
.clk(clk),
.reset(reset),
.read_addr(read_addr),
.hit(hit),
.miss(miss),
.hit_count(hit_count),
.miss_count(miss_count)
);
initial begin
// Initialize Inputs
clk = 0;
reset = 0;
data_file = $fopen("data_file.txt", "r");
end
always
#10 clk= ~clk;
always @(posedge clk) begin
scan_file = $fscanf(data_file, "%h\n", captured_data);
if (!$feof(data_file)) begin
read_addr <= captured_data;
$display(hit);
//$display(hit_count);
end
else
$finish;
end
endmodule
这是输出的图片
我可以在“cache_memory_direct_mapped”中看到一个问题。 always里面的else下面(下面复制粘贴)
if(read_addr[1:0] == 2'b0 )
c1[0] <= read_addr[3:2];
else if(read_addr[1:0] == 2'b1 )
c1[1] <= read_addr[3:2];
else if(read_addr[1:0] == 2'b10 )
c1[2] <= read_addr[3:2];
else if(read_addr[1:0] == 2'b11 )
c1[3] <= read_addr[3:2];
- 在每个 if 语句下,您只为 C1 的一个部分赋值,其余部分将不会更新并带有它们的初始“X”值。在每个 is/else if? 中,您可以将 0 分配给其余部分吗?
- 如果不满足none个条件会怎样,最后可能还需要else语句。
变化:
$display(hit);
至:
$strobe(hit);
这输出:
0
0
1
1
0
1
来自 IEEE 标准 1800-2017,第 21.2.2 节频闪监控:
The system task $strobe provides the ability to display simulation data at a selected time. That time is the end of the current simulation time, when all the simulation events have occurred for that simulation time, just before simulation time is advanced.
问题是当您在 posedge clk 调用 $display
时,您的信号值正在改变。
这里有一些额外的调试技巧:
- 使用波形调试器。
- 显示仿真时间和数值:
$strobe($time, " ", hit);