Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ifu cache update #769

Open
wants to merge 40 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 26 commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
28f3f69
adding test file
muhammad3mar Nov 2, 2024
88ba556
initializing files
abdkeb Dec 9, 2024
17994bf
Merge branch 'ifu_cache' of https://github.com/amichai-bd/fpga_mafia …
muhammad3mar Dec 9, 2024
e4dc181
Merge branch 'ifu_cache' of https://github.com/amichai-bd/fpga_mafia …
muhammad3mar Dec 9, 2024
8212f20
initail cach design
Abdullahkeblawi Dec 9, 2024
4e8aca5
Merge branch 'ifu_cache' of https://github.com/amichai-bd/fpga_mafia …
muhammad3mar Dec 11, 2024
a832289
test
muhammad3mar Dec 11, 2024
569bdac
test
muhammad3mar Dec 11, 2024
f9c1583
cache update
abdkeb Dec 11, 2024
48c8557
ifu_cache_tb1
muhammad3mar Dec 11, 2024
dc2464a
comiling module and test bench
abdkeb Dec 11, 2024
85a9ce5
updating file lists
abdkeb Dec 14, 2024
df6f352
remove uneccessary unnecessary dir's and syntax errors
roman012285 Dec 14, 2024
ff8641a
ifu_cache compilation success
abdkeb Dec 14, 2024
2a6c332
Merge branch 'ifu_cache' of https://github.com/amichai-bd/fpga_mafia …
abdkeb Dec 14, 2024
a54ec6c
simulation mini success
Abdullahkeblawi Dec 15, 2024
a596d79
adding the PLRU algorithim to the cache
muhammad3mar Dec 16, 2024
6889e37
fixing LRU cmpilation
Abdullahkeblawi Dec 20, 2024
bbe5ddb
converting cache to always_comb + new tb
abdkeb Dec 21, 2024
f426719
inserting the new cache with with always_comb
abdkeb Dec 21, 2024
f090227
fixing some width issues
abdkeb Dec 21, 2024
7081f51
changing the implementation of the getPLRUIndex
muhammad3mar Dec 24, 2024
4335684
this is the updated files, it was a mistake in the
muhammad3mar Dec 24, 2024
1325bc8
compiation, FFed arrays
abdkeb Dec 24, 2024
c8dfa10
update ifu arrays
abdkeb Dec 26, 2024
cf674b9
running plru tb
muhammad3mar Dec 26, 2024
9fbbb75
submodule problem
muhammad3mar Dec 26, 2024
5624ae6
submodules problem fixed
muhammad3mar Dec 26, 2024
50bfc64
adding debug signals and updating the testbench
muhammad3mar Dec 27, 2024
028dd91
PLRU simple test 1-3 working, 4 not working
abdkeb Dec 27, 2024
39e0560
merge the two submodules into the big module
muhammad3mar Dec 30, 2024
cd54d7a
Initialization the IFU unit interface.
muhammad3mar Jan 2, 2025
630df38
plru testing for cache
Abdullahkeblawi Jan 4, 2025
feea367
plru testing for cache
Abdullahkeblawi Jan 4, 2025
d679136
added Prefetcher and IFU top basic logic, changed interface, changed …
Abdullahkeblawi Jan 13, 2025
5658c23
adding state machine to prefetcher + test bench + adjusting interface…
Abdullahkeblawi Jan 25, 2025
6ef3c25
implementation of IDU and testbench
muhammad3mar Jan 29, 2025
26814d9
fixing ompilation IDu
Abdullahkeblawi Feb 1, 2025
deda30b
updating the IDU testbench to cover more cases
muhammad3mar Feb 1, 2025
d596a2f
initializing mini_core_di
Abdullahkeblawi Feb 18, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Empty file added source/ifu/ifu.sv
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks good the best way to evaluate it is to see it will work or not and how. good job

Empty file.
206 changes: 206 additions & 0 deletions source/ifu/ifu_cache.sv
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see what you have been talking about. It's better to separate and put each module into different files.

Original file line number Diff line number Diff line change
@@ -0,0 +1,206 @@

`include "macros.vh"

module ifu_cache
import ifu_pkg::*;
(
// Chip Signals
input logic Clock,
input logic Rst,

// CPU Interface
input logic [ADDR_WIDTH-1:0] cpu_reqAddrIn, // requested addr by cpu
output logic [ADDR_WIDTH-1:0] cpu_rspAddrOut, // address of the line in the response to cpu
output logic [LINE_WIDTH-1:0] cpu_rspInsLineOut, // the line in the response to cpu
output logic cpu_rspInsLineValidOut, // valid, meaning the cpu can read the line

// Memory Interface
input logic [TAG_WIDTH-1:0] mem_rspTagIn, // tag of the line provide by response of the memory
input logic [LINE_WIDTH-1:0] mem_rspInsLineIn, // the line provided in the response of the memory
input logic mem_rspInsLineValidIn, // the line is ready in the response and can be read by the cache
output logic [TAG_WIDTH-1:0] mem_reqTagOut, // tag requested by the cache from the memory
output logic mem_reqTagValidOut, // there is a request for the tag to be brought from the memory

// Prefetcher Interface
// to be added
//
// debug
output logic dataInsertion,
output logic hitStatusOut,
output logic [NUM_LINES - 2 :0] plruTreeOut

);


///////////////////
// Logic Defines //
///////////////////
// tag array
tag_arr_t tagArray [NUM_TAGS];
logic [ADDR_WIDTH - 1 : OFFSET_WIDTH-1 ] cpu_reqTagIn;

// data array
data_arr_t dataArray [NUM_LINES];
// logic dataInsertion;

// hit status
logic [P_BITS - 1:0] hitPosition; // synthesizable calculated in compilation time
logic [NUM_TAGS-1:0] hitArray;
logic hitStatus;

// plru
logic [P_BITS - 1 : 0] lineForPLRU;
logic [P_BITS - 1 : 0] freeLine;
logic freeLineValid;
logic [NUM_LINES - 2 : 0 ] plruTree;
logic [NUM_LINES - 2 : 0] updatedTree; // Holds the updated PLRU tree
logic [P_BITS - 1 : 0] plruIndex; // Holds the LRU index
logic updateTreeValid;

/////////////
// Assigns //
/////////////
assign cpu_reqTagIn = cpu_reqAddrIn[ADDR_WIDTH-1:OFFSET_WIDTH-1];
assign hitStatus = |hitArray;
assign mem_reqTagValidOut = !hitStatus;
assign dataInsertion = (mem_reqTagValidOut == VALID) && (mem_rspInsLineValidIn == VALID) && (mem_reqTagOut == mem_rspTagIn);
assign plruTreeOut = plruTree;
assign hitStatusOut = hitStatus;


///////////////////////////
// Always Comb Statement //
///////////////////////////

always_comb begin
////////////////
// Hit Status //
////////////////
for (int i = 0 ; i < NUM_TAGS; i++) begin
if (cpu_reqTagIn == tagArray[i].tag && tagArray[i].valid == VALID) begin
hitArray[i] = 1;
hitPosition = i;
cpu_rspAddrOut = cpu_reqAddrIn;
end else begin
hitArray[i] = 0;
end
end

//////////////////
// Cache Action //
//////////////////
if(hitStatus == HIT) begin // hit handling
cpu_rspInsLineOut = dataArray[hitPosition];
cpu_rspInsLineValidOut = VALID; // we have the line in cache
lineForPLRU = hitPosition;
end else begin // miss handling
cpu_rspInsLineValidOut = !VALID; // we do not have the line in cache
mem_reqTagOut = cpu_reqTagIn;
lineForPLRU = freeLine;
end

////////////////////
// Line Insertion //
////////////////////
if (dataInsertion) begin
freeLineValid = 0;
freeLine = 0;
//checks if there any empty cache lines before using the PLRU
for (int i = 0 ; i < NUM_TAGS ; i++)begin
if (!tagArray[i].valid)begin
freeLine = i;
freeLineValid = 1;
break;
end
end
//in case all the lines in the cache are full
if (freeLineValid == 0)begin
freeLine = plruIndex;
end
end
end // always_comb end


///////////////////////////
// Always ff Statement //
///////////////////////////
always_ff @(posedge Clock or posedge Rst) begin

/////////////////
// Cache Reset //
/////////////////
if (Rst) begin
for (int i = 0 ; i < NUM_TAGS ; i++) begin
tagArray[i] <= 0;
dataArray[i] <= 0;
end
plruTree <= 0; // Reset PLRU tree
end

if (hitStatus == HIT) begin
plruTree <= updatedTree; //updates the plru tree when there is a hit
end

if(dataInsertion) begin
dataArray[freeLine] <= mem_rspInsLineIn;
tagArray[freeLine].valid <= VALID;
tagArray[freeLine].tag <= mem_rspTagIn;
plruTree <= updatedTree;
end
end


///////////////
// Utilities //
///////////////
//Updates the PLRU tree after a hit or replacement.
module updatePLruTree (
input logic [NUM_LINES - 2 : 0] currentTree,
input logic [P_BITS - 1 : 0] line,
output logic [NUM_LINES - 2 : 0] updatedTree
);

logic [P_BITS - 1 : 0] index;

always_comb begin
//index = 0;
updatedTree = currentTree;
for (int level = P_BITS - 1 ; level >= 0; level--) begin
updatedTree[index] = (line >> level) & 1;
index = (index << 1) | ((line >> level) & 1);
end
end
endmodule

//Computes the least recently used (LRU) index.
module getPLRUIndex (
input logic [NUM_LINES - 2 : 0] tree,
output logic [P_BITS - 1 : 0] index
);

always_comb begin
//index = 0;
while(index < NUM_LINES - 1) begin
// Updates the index to search in the next layer in the tree, tree[index] chooses the left or right node
index = (index << 1 ) | tree[index];
index = index % 15 ; // mod 15 to insure the index is always smaller than 16
end
//index = index & ((1 << P_BITS) - 1);
end

endmodule


// Module Instantiations
getPLRUIndex plru_index_inst (
.tree(plruTree),
.index(plruIndex)
);

updatePLruTree update_plru_inst (
.currentTree(plruTree),
.line(lineForPLRU),
.updatedTree(updatedTree)
);

endmodule
34 changes: 34 additions & 0 deletions source/ifu/ifu_pkg.sv
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

its not necessary to declare parameter al logic. when you declare something as logic, it can be 0,1,x, Z. Its not wrong but for consistent coding style its better not to use logic

Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@


package ifu_pkg;



///////////////////////
// Parameter Defines //
///////////////////////
parameter logic HIT = 1'b1; // Indicates a hit
parameter logic MISS = 1'b0; // Indicates a miss
parameter logic VALID = 1'b1; // Indicates validity
parameter NUM_TAGS = 16; // Number of tags
parameter NUM_LINES = 16; // Number of lines: should be equal to number of tags
parameter OFFSET_WIDTH = 5; // Width of each offset
parameter ADDR_WIDTH = 32; // Width of address
parameter TAG_WIDTH = 27; // Width of each Tag
parameter LINE_WIDTH = 128; // Width of each cache line
parameter P_BITS = $clog2(NUM_TAGS); // Bits needed for position of line

/////////////////////
// Package Defines //
/////////////////////

typedef struct packed {
bit valid; // Valid bit
logic [TAG_WIDTH-1:0] tag; // Tag value
} tag_arr_t;

typedef struct packed {
logic [LINE_WIDTH-1:0] line; // Tag value
} data_arr_t;

endpackage
Empty file added source/ifu/ifu_prefetcher.sv
Empty file.
12 changes: 12 additions & 0 deletions source/ifu/ifu_rtl_list.f
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@

+incdir+../../../source/common/

// param packages
../../../source/ifu/ifu_pkg.sv


//RTL FIles
../../../source/ifu/ifu.sv
../../../source/ifu/ifu_cache.sv
../../../source/ifu/ifu_prefetcher.sv

1 change: 1 addition & 0 deletions test1.c
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
// test file for branch
3 changes: 3 additions & 0 deletions verif/ifu/file_list/ifu_list.f
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
+define+SIM_ONLY
-f ../../../source/ifu/ifu_rtl_list.f
-f ../../../verif/ifu/file_list/ifu_verif_list.f
4 changes: 4 additions & 0 deletions verif/ifu/file_list/ifu_verif_list.f
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
+incdir+../../../source/common/
+incdir+../../../verif/ifu/tb/
../../../verif/ifu/tb/ifu_cache_tb.sv
../../../verif/ifu/tb/PLRU_tb.sv
126 changes: 126 additions & 0 deletions verif/ifu/tb/PLRU_tb.sv
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

out simulator does not support assertion. you don't have to use assertion. If you want we have a special macro inside macros.vh that imitates that but its not necessary to use it

Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
`timescale 1ns/1ps

module PLRU_tb;

import ifu_pkg::*;

// Inputs
logic Clock;
logic Rst;
logic [ADDR_WIDTH-1:0] cpu_reqAddrIn;
logic [LINE_WIDTH-1:0] mem_rspInsLineIn;
logic mem_rspInsLineValidIn;
logic [TAG_WIDTH-1:0] mem_rspTagIn;

// Outputs
logic [ADDR_WIDTH-1:0] cpu_rspAddrOut;
logic [LINE_WIDTH-1:0] cpu_rspInsLineOut;
logic cpu_rspInsLineValidOut;
logic [TAG_WIDTH-1:0] mem_reqTagOut;
logic mem_reqTagValidOut;

// Debug Outputs
logic [LINE_WIDTH-1:0] debug_dataArray [NUM_LINES];
logic [TAG_WIDTH-1:0] debug_tagArray [NUM_TAGS];
logic [NUM_TAGS-1:0] debug_validArray;
logic [NUM_LINES-2:0] debug_plruTree;
logic hitStatusOut;
logic dataInsertion;
logic [NUM_LINES - 2 :0] plruTreeOut;

// Instantiate the DUT (Device Under Test)
ifu_cache
dut (
.Clock(Clock),
.Rst(Rst),
.cpu_reqAddrIn(cpu_reqAddrIn),
.cpu_rspAddrOut(cpu_rspAddrOut),
.cpu_rspInsLineOut(cpu_rspInsLineOut),
.cpu_rspInsLineValidOut(cpu_rspInsLineValidOut),
.mem_rspTagIn(mem_rspTagIn),
.mem_rspInsLineIn(mem_rspInsLineIn),
.mem_rspInsLineValidIn(mem_rspInsLineValidIn),
.mem_reqTagOut(mem_reqTagOut),
.mem_reqTagValidOut(mem_reqTagValidOut),
.dataInsertion(dataInsertion),
.hitStatusOut(hitStatusOut),
.plruTreeOut(plruTreeOut)
//.debug_plruTree(debug_plruTree)
);

// Clock generation
always #5 Clock = ~Clock; // 10 ns clock period

// Testbench Variables
int test_counter = 0;

// Test Procedure
initial begin
// Initialize signals
Clock = 0;
Rst = 0;
cpu_reqAddrIn = 0;
mem_rspInsLineIn = 0;
mem_rspInsLineValidIn = 0;
mem_rspTagIn = 0;

// 1. Reset Behavior
$display("Test %0d: Reset Behavior", ++test_counter);
Rst = 1;
#20; // Hold reset for 20 ns
Rst = 0;
#10;
// Verify all entries are invalid and PLRU tree is reset
/*for (int i = 0; i < NUM_TAGS; i++) begin
assert(dut.debug_validArray[i] == 0) else $fatal("Reset failed for validArray[%0d].", i);
end*/
// assert(dut.debug_plruTree == 0) else $fatal("PLRU tree reset failed.");

// 2. Basic Cache Miss
$display("Test %0d: Basic Cache Miss", ++test_counter);
cpu_reqAddrIn = 32'h1000; // Set request address
mem_rspInsLineIn = 128'hDEADBEEFDEADBEEFDEADBEEFDEADBEEF; // Line data
mem_rspTagIn = cpu_reqAddrIn[ADDR_WIDTH-1:OFFSET_WIDTH];
mem_rspInsLineValidIn = 1;
#10; // Wait for one clock cycle
mem_rspInsLineValidIn = 0;
assert(dut.cpu_rspInsLineValidOut == 0) else $fatal("Cache miss handling failed.");

// Simulate response from memory
mem_rspInsLineValidIn = 1;
#10;
mem_rspInsLineValidIn = 0;
assert(dut.cpu_rspInsLineOut == 128'hDEADBEEFDEADBEEFDEADBEEFDEADBEEF) else $fatal("Incorrect data inserted in cache.");

// 3. Basic Cache Hit
$display("Test %0d: Basic Cache Hit", ++test_counter);
cpu_reqAddrIn = 32'h1000; // Access the same address
#10;
assert(dut.cpu_rspInsLineValidOut == 1) else $fatal("Cache hit failed.");
assert(dut.cpu_rspInsLineOut == 128'hDEADBEEFDEADBEEFDEADBEEFDEADBEEF) else $fatal("Incorrect data retrieved on cache hit.");

// 4. PLRU Replacement
$display("Test %0d: PLRU Replacement", ++test_counter);
for (int i = 0; i < NUM_LINES; i++) begin
cpu_reqAddrIn = i * 4; // Unique addresses
mem_rspInsLineIn = 128'hA5A5A5A5 + i; // Unique data
mem_rspInsLineValidIn = 1;
mem_rspTagIn = cpu_reqAddrIn[ADDR_WIDTH-1:OFFSET_WIDTH];
#10;
mem_rspInsLineValidIn = 0;
end
// Insert one more line to trigger replacement
cpu_reqAddrIn = 32'hFFFF;
mem_rspInsLineIn = 128'h123456789ABCDEF;
mem_rspInsLineValidIn = 1;
mem_rspTagIn = cpu_reqAddrIn[ADDR_WIDTH-1:OFFSET_WIDTH];
#10;
mem_rspInsLineValidIn = 0;
// Check replacement
assert(dut.cpu_rspInsLineValidOut == 0) else $fatal("PLRU replacement failed.");

$display("All tests passed!");
$stop;
end

endmodule
Loading
Loading