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

Subversion Repositories or1k

[/] [or1k/] [tags/] [nog_patch_52/] [or1ksim/] [cache/] [dcache_model.c] - Diff between revs 54 and 102

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

Rev 54 Rev 102
Line 29... Line 29...
#include <stdarg.h>
#include <stdarg.h>
 
 
#include "dcache_model.h"
#include "dcache_model.h"
#include "abstract.h"
#include "abstract.h"
#include "stats.h"
#include "stats.h"
 
#include "spr_defs.h"
 
#include "sprs.h"
 
 
/* Data cache */
/* Data cache */
 
 
/* Number of DC sets (power of 2) */
/* Number of DC sets (power of 2) */
#define DC_SETS 512
#define DC_SETS 512
Line 53... Line 55...
        } way[DC_WAYS];
        } way[DC_WAYS];
} dc[DC_SETS];
} dc[DC_SETS];
 
 
void dc_info()
void dc_info()
{
{
 
        if (!getsprbits(SPR_UPR, SPR_UPR_DCP)) {
 
                printf("DCache not implemented. Set UPR[DCP].\n");
 
                return;
 
        }
 
 
        printf("Data cache %dKB: ", DC_SETS * DC_BLOCK_SIZE * DC_WAYS / 1024);
        printf("Data cache %dKB: ", DC_SETS * DC_BLOCK_SIZE * DC_WAYS / 1024);
        printf("%d ways, %d sets, block size %d bytes\n", DC_WAYS, DC_SETS, DC_BLOCK_SIZE);
        printf("%d ways, %d sets, block size %d bytes\n", DC_WAYS, DC_SETS, DC_BLOCK_SIZE);
}
}
 
 
/* First check if data is already in the cache and if it is:
/* First check if data 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;
 
 
 
        if ((!getsprbits(SPR_UPR, SPR_UPR_DCP)) || (!getsprbits(SPR_SR, SPR_SR_DCE)))
 
                return;
 
 
        /* Which set to check out? */
        /* Which set to check out? */
        set = (dataaddr / DC_BLOCK_SIZE) % DC_SETS;
        set = (dataaddr / DC_BLOCK_SIZE) % DC_SETS;
        tagaddr = (dataaddr / DC_BLOCK_SIZE) / DC_SETS;
        tagaddr = (dataaddr / DC_BLOCK_SIZE) / DC_SETS;
 
 
        /* Scan all ways and try to find a matching way. */
        /* Scan all ways and try to find a matching way. */
Line 99... Line 109...
                int minway = 0;
                int minway = 0;
 
 
                dc_stats.readmiss++;
                dc_stats.readmiss++;
 
 
                for (i = 0; i < DC_WAYS; i++)
                for (i = 0; i < DC_WAYS; i++)
                        if (dc[set].way[i].lru < minlru)
                        if ((dc[set].way[i].lru < minlru) &&
 
                            (getsprbits(SPR_DCCR, SPR_DCCR_EW) & (1 << i)))
                                minway = i;
                                minway = i;
 
 
                dc[set].way[minway].tagaddr = tagaddr;
                dc[set].way[minway].tagaddr = tagaddr;
                for (i = 0; i < DC_WAYS; i++)
                for (i = 0; i < DC_WAYS; i++)
                        if (dc[set].way[i].lru)
                        if (dc[set].way[i].lru)
Line 127... Line 138...
{
{
        int set, way = -1;
        int set, way = -1;
        int i;
        int i;
        unsigned long tagaddr;
        unsigned long tagaddr;
 
 
 
        if ((!getsprbits(SPR_UPR, SPR_UPR_DCP)) || (!getsprbits(SPR_SR, SPR_SR_DCE)))
 
                return;
 
 
        /* Which set to check out? */
        /* Which set to check out? */
        set = (dataaddr / DC_BLOCK_SIZE) % DC_SETS;
        set = (dataaddr / DC_BLOCK_SIZE) % DC_SETS;
        tagaddr = (dataaddr / DC_BLOCK_SIZE) / DC_SETS;
        tagaddr = (dataaddr / DC_BLOCK_SIZE) / DC_SETS;
 
 
        /* Scan all ways and try to find a matching way. */
        /* Scan all ways and try to find a matching way. */
Line 152... Line 166...
                int minway = 0;
                int minway = 0;
 
 
                dc_stats.writemiss++;
                dc_stats.writemiss++;
 
 
                for (i = 0; i < DC_WAYS; i++)
                for (i = 0; i < DC_WAYS; i++)
                        if (dc[set].way[i].lru < minlru)
                        if ((dc[set].way[i].lru < minlru) &&
 
                            (getsprbits(SPR_DCCR, SPR_DCCR_EW) & (1 << i)))
                                minway = i;
                                minway = i;
 
 
                dc[set].way[minway].tagaddr = tagaddr;
                dc[set].way[minway].tagaddr = tagaddr;
                for (i = 0; i < DC_WAYS; i++)
                for (i = 0; i < DC_WAYS; i++)
                        if (dc[set].way[i].lru)
                        if (dc[set].way[i].lru)
                                dc[set].way[i].lru--;
                                dc[set].way[i].lru--;
                dc[set].way[minway].lru = DC_USTATES - 1;
                dc[set].way[minway].lru = DC_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 dc_inv(unsigned long dataaddr)
 
{
 
        int set, way = -1;
 
        int i;
 
        unsigned long tagaddr;
 
 
 
        if (!getsprbits(SPR_UPR, SPR_UPR_DCP))
 
                return;
 
 
 
        /* Which set to check out? */
 
        set = (dataaddr / DC_BLOCK_SIZE) % DC_SETS;
 
        tagaddr = (dataaddr / DC_BLOCK_SIZE) / DC_SETS;
 
 
 
        /* Scan all ways and try to find a matching way. */
 
        for (i = 0; i < DC_WAYS; i++)
 
                if (dc[set].way[i].tagaddr == tagaddr)
 
                        way = i;
 
 
 
        /* Did we find our cached data? */
 
        if ((way >= 0) && (getsprbits(SPR_DCCR, SPR_DCCR_EW) & (1 << way))) { /* Yes, we did. */
 
                dc[set].way[way].tagaddr = -1;
 
        }
 
}
 
 
 
void dc_clock()
 
{
 
        unsigned long addr;
 
 
 
        if (addr = mfspr(SPR_DCBPR)) {
 
                dc_simulate_read(addr);
 
                mtspr(SPR_DCBPR, 0);
 
        }
 
        if (addr = mfspr(SPR_DCBFR)) {
 
                dc_inv(addr);
 
                mtspr(SPR_DCBFR, 0);
 
        }
 
        if (addr = mfspr(SPR_DCBIR)) {
 
                dc_inv(addr);
 
                mtspr(SPR_DCBIR, 0);
 
        }
 
        if (addr = mfspr(SPR_DCBWR)) {
 
                mtspr(SPR_DCBWR, 0);
 
        }
 
        if (addr = mfspr(SPR_DCBLR)) {
 
                mtspr(SPR_DCBLR, 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.