OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [tags/] [nog_patch_59/] [or1ksim/] [cache/] [icache_model.c] - Diff between revs 76 and 102

Go to most recent revision | Show entire file | Details | Blame | View Log

Rev 76 Rev 102
Line 29... Line 29...
#include <stdarg.h>
#include <stdarg.h>
 
 
#include "icache_model.h"
#include "icache_model.h"
#include "abstract.h"
#include "abstract.h"
#include "stats.h"
#include "stats.h"
 
#include "sim-config.h"
 
#include "spr_defs.h"
 
 
/* Instruction cache */
/* Instruction cache */
 
 
/* Number of IC sets (power of 2) */
/* Number of IC sets (power of 2) */
#define IC_SETS 512
#define IC_SETS 512
Line 53... Line 55...
        } way[IC_WAYS];
        } way[IC_WAYS];
} ic[IC_SETS];
} ic[IC_SETS];
 
 
void ic_info()
void ic_info()
{
{
 
        if (!getsprbits(SPR_UPR, SPR_UPR_ICP)) {
 
                        printf("ICache not implemented. Set UPR[ICP].\n");
 
                        return;
 
        }
 
 
        printf("Instruction cache %dKB: ", IC_SETS * IC_BLOCK_SIZE * IC_WAYS / 1024);
        printf("Instruction cache %dKB: ", IC_SETS * IC_BLOCK_SIZE * IC_WAYS / 1024);
        printf("%d ways, %d sets, block size %d bytes\n", IC_WAYS, IC_SETS, IC_BLOCK_SIZE);
        printf("%d ways, %d sets, block size %d bytes\n", IC_WAYS, IC_SETS, IC_BLOCK_SIZE);
}
}
 
 
/* First check if instruction is already in the cache and if it is:
/* First check if instruction is already in the cache and if it is:
Line 74... Line 81...
{
{
        int set, way = -1;
        int set, way = -1;
        int i;
        int i;
        unsigned long tagaddr;
        unsigned long tagaddr;
 
 
 
        /* ICache simulation enabled/disabled. */
 
        if ((!getsprbits(SPR_UPR, SPR_UPR_ICP)) || (!getsprbits(SPR_SR, SPR_SR_ICE)))
 
                return;
 
 
        /* Which set to check out? */
        /* Which set to check out? */
        set = (fetchaddr / IC_BLOCK_SIZE) % IC_SETS;
        set = (fetchaddr / IC_BLOCK_SIZE) % IC_SETS;
        tagaddr = (fetchaddr / IC_BLOCK_SIZE) / IC_SETS;
        tagaddr = (fetchaddr / IC_BLOCK_SIZE) / IC_SETS;
 
 
        /* Scan all ways and try to find a matching way. */
        /* Scan all ways and try to find a matching way. */
Line 104... Line 115...
                        if (ic[set].way[i].lru < minlru)
                        if (ic[set].way[i].lru < minlru)
                                minway = i;
                                minway = i;
 
 
                ic[set].way[minway].tagaddr = tagaddr;
                ic[set].way[minway].tagaddr = tagaddr;
                for (i = 0; i < IC_WAYS; i++)
                for (i = 0; i < IC_WAYS; i++)
                        if (ic[set].way[i].lru)
                        if ((ic[set].way[i].lru) &&
 
                            (getsprbits(SPR_ICCR, SPR_ICCR_EW) & (1 << i)))
                                ic[set].way[i].lru--;
                                ic[set].way[i].lru--;
                ic[set].way[minway].lru = IC_USTATES - 1;
                ic[set].way[minway].lru = IC_USTATES - 1;
        }
        }
}
}
 
 
 No newline at end of file
 No newline at end of file
 
/* First check if data is already in the cache and if it is:
 
    - invalidate block if way isn't locked
 
   otherwise don't do anything.
 
*/
 
 
 
void ic_inv(unsigned long dataaddr)
 
{
 
        int set, way = -1;
 
        int i;
 
        unsigned long tagaddr;
 
 
 
        if (!getsprbits(SPR_UPR, SPR_UPR_ICP))
 
                return;
 
 
 
        /* Which set to check out? */
 
        set = (dataaddr / IC_BLOCK_SIZE) % IC_SETS;
 
        tagaddr = (dataaddr / IC_BLOCK_SIZE) / IC_SETS;
 
 
 
        /* Scan all ways and try to find a matching way. */
 
        for (i = 0; i < IC_WAYS; i++)
 
                if (ic[set].way[i].tagaddr == tagaddr)
 
                        way = i;
 
 
 
        /* Did we find our cached data? */
 
        if ((way >= 0) && (getsprbits(SPR_ICCR, SPR_ICCR_EW) & (1 << way))) { /* Yes, we did. */
 
                ic[set].way[way].tagaddr = -1;
 
        }
 
}
 
 
 
void ic_clock()
 
{
 
        unsigned long addr;
 
 
 
        if (addr = mfspr(SPR_ICBPR)) {
 
                ic_simulate_read(addr);
 
                mtspr(SPR_ICBPR, 0);
 
        }
 
        if (addr = mfspr(SPR_ICBIR)) {
 
                ic_inv(addr);
 
                mtspr(SPR_ICBIR, 0);
 
        }
 
        if (addr = mfspr(SPR_ICBLR)) {
 
                mtspr(SPR_ICBLR, 0);
 
        }
 
}
 
 
 No newline at end of file
 No newline at end of file

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.