cache maping using Verilog
Direct mapped cache using Verilog
`timescale 1ns / 1psmodule direct_mapped_cache #(
parameter DATA_WIDTH = 32, // Data width (32-bit)
parameter ADDR_WIDTH = 8, // Address width (8-bit)
parameter CACHE_SIZE = 16 // Cache size in terms of number of blocks (16 blocks)
)(
input clk, // Clock signal
input rst, // Reset signal
input [ADDR_WIDTH-1:0] address, // Address from CPU
input [DATA_WIDTH-1:0] write_data, // Data to be written
input mem_write, // Memory write signal
input mem_read, // Memory read signal
output reg [DATA_WIDTH-1:0] read_data, // Data to CPU
output reg hit // Cache hit signal
);
// Cache line structure
reg [DATA_WIDTH-1:0] cache_data [CACHE_SIZE-1:0]; // Cache memory for storing data
reg [ADDR_WIDTH-ADDR_WIDTH/2-1:0] tag_array [CACHE_SIZE-1:0]; // Tag array
reg valid_array [CACHE_SIZE-1:0]; // Valid bits
wire [ADDR_WIDTH/2-1:0] index; // Cache index
wire [ADDR_WIDTH-ADDR_WIDTH/2-1:0] tag; // Tag for comparison
// Split address into index and tag
assign index = address[ADDR_WIDTH/2-1:0];
assign tag = address[ADDR_WIDTH-1:ADDR_WIDTH/2];
// Reset logic
integer i;
always @(posedge rst) begin
if (rst) begin
for (i = 0; i < CACHE_SIZE; i = i + 1) begin
valid_array[i] <= 0;
end
end
end
// Cache read/write logic
always @(posedge clk) begin
if (mem_read) begin
// Check if the tag matches and the block is valid
if (valid_array[index] && (tag_array[index] == tag)) begin
read_data <= cache_data[index]; // Cache hit
hit <= 1;
end else begin
read_data <= 0; // Cache miss
hit <= 0;
end
end
if (mem_write) begin
// Write data into cache, update tag and valid bit
cache_data[index] <= write_data;
tag_array[index] <= tag;
valid_array[index] <= 1;
end
end
endmodule
Test bench
`timescale 1ns / 1ps
module tb_direct_mapped_cache();
// Parameters
parameter DATA_WIDTH = 32;
parameter ADDR_WIDTH = 8;
parameter CACHE_SIZE = 16;
// Inputs and Outputs for the cache
reg clk, rst;
reg [ADDR_WIDTH-1:0] address;
reg [DATA_WIDTH-1:0] write_data;
reg mem_write, mem_read;
wire [DATA_WIDTH-1:0] read_data;
wire hit;
direct_mapped_cache #(
.DATA_WIDTH(DATA_WIDTH),
.ADDR_WIDTH(ADDR_WIDTH),
.CACHE_SIZE(CACHE_SIZE)
) DUT (
.clk(clk),
.rst(rst),
.address(address),
.write_data(write_data),
.mem_write(mem_write),
.mem_read(mem_read),
.read_data(read_data),
.hit(hit)
);
// Clock generation
initial begin
clk = 0;
forever #5 clk = ~clk; // Clock period is 10 units
end
// Test procedure
initial begin
// Initialize Inputs
rst = 1;
address = 0;
write_data = 0;
mem_write = 0;
mem_read = 0;
// Reset the system
#10;
rst = 0;
// Test Case 1: Write to cache and then read from it
// Write data 0x12345678 at address 8
address = 8;
write_data = 32'h12345678;
mem_write = 1;
#10;
mem_write = 0;
// Read from address 8 and expect a cache hit
mem_read = 1;
address = 8;
#10;
if (read_data == 32'h12345678 && hit)
$display("Test Case 1 Passed: Cache Hit and Correct Data");
else
$display("Test Case 1 Failed: Cache Miss or Incorrect Data");
mem_read = 0;
// Test Case 2: Read from address 4 (should be a miss)
address = 4;
mem_read = 1;
#10;
if (!hit)
$display("Test Case 2 Passed: Cache Miss");
else
$display("Test Case 2 Failed: Cache Hit Unexpected");
mem_read = 0;
// Test Case 3: Write new data and verify cache update
address = 8;
write_data = 32'hDEADBEEF;
mem_write = 1;
#10;
mem_write = 0;
// Read back the updated data from address 8
mem_read = 1;
#10;
if (read_data == 32'hDEADBEEF && hit)
$display("Test Case 3 Passed: Cache Updated and Hit");
else
$display("Test Case 3 Failed: Cache Not Updated Correctly");
mem_read = 0;
// End simulation
$stop;
end
endmodule
Direct mapping cache using Verilog
Cache maping
Comments
Post a Comment