cache maping using Verilog

Direct mapped cache using Verilog 
`timescale 1ns / 1ps
module 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

Popular posts from this blog

Number system

Realme 13+ specifications

Vivo Y300 Pro key specifications