'Verilog getting 'x' as an output instead of '0' and '1'

I am trying to create a four element direct mapped cache with four bit memory address. Program is running completely fine no compilation error but suddenly in output, I am getting 'x' just for the first statement. After that I don't see it anywhere else. Any help would be appreciated. Here is the code

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

And here is the picture of the output enter image description here



Solution 1:[1]

I can see an issue inside the "cache_memory_direct_mapped". Under the else inside always (copied and pasted below)

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]; 
  1. under each if statement you only assign a value to one section of C1, the rest will not be updated and carries their initial 'X'values. Can you assign 0 to the rest in each is/else if?
  2. What happens if none of the conditions are not satisfied, you may need to have else statement at the end as well.

Solution 2:[2]

I 'm going to explain with this list (because you will get IndexError with current list):

L = [1, 2, 3, 4, 5]
print(L[L[2]])

First, Python sees the print() function, in order to call this function, Python has to know it's arguments. So it goes further to evaluate the argument L[L[2]].

L is a list, we can pass an index to the bracket to get the item at that index. So we need to know the index. We go further and calculate the expression inside the first []. It's L[2].

Now we can easily evaluate the expression L[2]. The result is 3.

Take that result and put it instead of L[2]. our full expression is print(L[3]) at the moment.

I think you get the idea now...

From inside to the outside:

step1 -- >  print(L[L[2]])
step2 -- >  print(L[3])
step3 -- >  print(4)

Solution 3:[3]

Here what you are doing is, you are getting the value at 2 which should be 3, because python starts from 0 and goes up. So after that the interior braces should be done, and then you find the index at 3 which is too big. Because the indexes only go up to 2, and if I say I had three numbers, and you ask me what the fourth number is, that wouldn't make sense right? So that is the same thing. This would result in an error.

Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IndexError: list index out of range

This means that you are trying to get a value that does not exist. I hope this makes it clear.

Solution 4:[4]

L[L[2]] becomes L[3], since L[2] is equal to 3. Then, since there are three elements in L, and indexing starts at 0 in Python, this would result in an IndexError.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Ashkanxy
Solution 2 S.B
Solution 3 ThatOneAmazingPanda
Solution 4 BrokenBenchmark