eliesmith
eliesmith

Reputation: 59

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

Upvotes: 1

Views: 1313

Answers (2)

toolic
toolic

Reputation: 62037

Change:

    $display(hit);

to:

    $strobe(hit);

This outputs:

0
0
1
1
0
1

From the IEEE Std 1800-2017, section 21.2.2 Strobed monitoring:

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.

The problem is that your signal values are changing at the time you call $display at posedge clk.


Here are some additional debugging tips:

  1. Use a waveform debugger.
  2. Display the simulation time as well as values: $strobe($time, " ", hit);

Upvotes: 1

Ashkanxy
Ashkanxy

Reputation: 3941

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.

Upvotes: 0

Related Questions