I design a instruction cache, my problem is that when I change the sram index at posedge clk it returns the value of the previous index. When I test sram module it behaves normally, but I instantiate it in data_array and tag_array module it does not work properly and keep previous index data its output. I can't figure out why it behaves like this.
Here is some partion of my testbench :
module top_tb;
// Parameters
// Ports
logic clk = 0;
logic rst = 0;
logic flush = 0;
logic write_en = 0;
logic [3:0] i_data;
logic [9:0] pc;
logic [3:0] o_data;
top
top_dut (
.clk (clk ),
.rst (rst ),
.flush (flush ),
.write_en (write_en ),
.i_data (i_data ),
.pc (pc ),
.o_data (o_data)
);
initial begin
begin
rst = 1;
flush = 0;
write_en = 0;
i_data = 0;
pc = 0;
#10;
// Flush cycle keep 16 cycle
rst = 0;
flush = 0; // no change
write_en = 0;
i_data = 0;
pc = 0;
#45;
// end of flush
write_en = 1;
i_data = 1;
pc = 1;
#10;
write_en = 1;
i_data = 2;
pc = 2;
#10;
write_en = 0;
end
end
always
#5 clk = ! clk ;
endmodule
Additionally, SRAM module is instantiated in data array module and data array module is instantiated in icache_top module. Top module get Program Counter as an input and inside the module, index information is extracted and assigned a wire which is named index. If I assign this signal to data array index port this problem happens, but when I directly drive the program counter index part to data array module this problem does not happen I want to learn why this stiuation happens in systemverilog (vivado)?
The code have wrong wave form:
`timescale 1ns / 1ps
module top(
input logic clk,
input logic rst,
input logic flush,
input logic write_en,
input logic [3:0] i_data,
input logic [9:0] pc,
output logic [3:0] o_data
);
// Ports
logic [1:0] index;
assign index = pc[1:0];
test test_ex (
.clk (clk),
.rst (rst),
.i_flush (flush),
.i_wr_en (write_en),
.i_data (i_data),
.i_index (index),
.o_data (o_data)
);
endmodule
The code have correct wave form:
`timescale 1ns / 1ps
module top(
input logic clk,
input logic rst,
input logic flush,
input logic write_en,
input logic [3:0] i_data,
input logic [9:0] pc,
output logic [3:0] o_data
);
// Ports
logic [1:0] index;
assign index = pc[1:0];
test test_ex (
.clk (clk),
.rst (rst),
.i_flush (flush),
.i_wr_en (write_en),
.i_data (i_data),
.i_index (pc[1:0]),
.o_data (o_data)
);
endmodule
The test module as following;
module test(
input logic clk,
input logic rst,
input logic i_flush,
input logic i_wr_en,
input logic [3:0] i_data,
input logic [1:0] i_index,
output logic [3:0] o_data
);
logic flush_q;
logic [15:0] memory [3:0];
logic [1:0] flush_index;
logic [1:0] wr_index;
logic [15:0] wr_data;
assign wr_data = flush_q ? '0 : i_data;
assign wr_index = flush_q ? flush_index : i_index;
always_ff@(posedge clk)begin
if(i_wr_en | flush_q)begin
memory[wr_index] <= wr_data;
end else begin
o_data <= memory[wr_index];
end
end
always_ff @(posedge clk) begin
if(rst) begin
flush_q <= 1'b1;
flush_index <= '0;
end
else begin
if(flush_q) begin
if(flush_index == 3) begin
flush_index <= '0;
flush_q <= 1'b0;
end else begin
flush_index <= flush_index + 1'b1;
end
end else begin
flush_q <= i_flush;
end
end
end
endmodule
Note: Post is updated for basic example for this situation. If you compare two top module in first one I extract index form pc to index wire and then drive the test module and this module apply the write operation previous index. But in second top module if I drive pc[1:0] (index part) directly to test module data is written to the present index. Which behaviour correct? Is this a race condition?