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

Subversion Repositories or1k

[/] [or1k/] [tags/] [nog_patch_34/] [or1ksim/] [cache/] [dcache_model.c] - Diff between revs 541 and 631

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

Rev 541 Rev 631
Line 35... Line 35...
#include "sprs.h"
#include "sprs.h"
#include "sim-config.h"
#include "sim-config.h"
 
 
/* Data cache */
/* Data cache */
 
 
 
extern struct dev_memarea *cur_area;
struct dc_set {
struct dc_set {
  struct {
  struct {
 
    unsigned long line[MAX_DC_BLOCK_SIZE];
    unsigned long tagaddr;  /* tag address */
    unsigned long tagaddr;  /* tag address */
    int lru;    /* least recently used */
    int lru;    /* least recently used */
  } way[MAX_DC_WAYS];
  } way[MAX_DC_WAYS];
} dc[MAX_DC_SETS];
} dc[MAX_DC_SETS];
 
 
Line 62... Line 64...
   and if not:
   and if not:
    - increment DC read miss stats
    - increment DC read miss stats
    - find lru way and entry and replace old tag with tag of the 'dataaddr'
    - find lru way and entry and replace old tag with tag of the 'dataaddr'
    - set 'lru' with config.dc.ustates - 1 and decrement 'lru' of other
    - set 'lru' with config.dc.ustates - 1 and decrement 'lru' of other
      ways unless they have reached 0
      ways unless they have reached 0
 
    - refill cache line
*/
*/
 
 
void dc_simulate_read(unsigned long dataaddr)
unsigned long dc_simulate_read(unsigned long dataaddr, int width)
{
{
  int set, way = -1;
  int set, way = -1;
  int i;
  int i;
  unsigned long tagaddr;
  unsigned long tagaddr;
  extern int mem_cycles;
  extern int mem_cycles;
 
  unsigned long tmp;
 
 
  if ((!testsprbits(SPR_UPR, SPR_UPR_DCP)) || (!testsprbits(SPR_SR, SPR_SR_DCE)))
  if ((!testsprbits(SPR_UPR, SPR_UPR_DCP)) || (!testsprbits(SPR_SR, SPR_SR_DCE))) {
    return;
    if (width == 4)
 
      return evalsim_mem32(dataaddr);
 
    else if (width == 2)
 
      return (unsigned long)evalsim_mem16(dataaddr);
 
    else if (width == 1)
 
      return (unsigned long)evalsim_mem8(dataaddr);
 
  }
 
 
  /* Which set to check out? */
  /* Which set to check out? */
  set = (dataaddr / config.dc.blocksize) % config.dc.nsets;
  set = (dataaddr / config.dc.blocksize) % config.dc.nsets;
  tagaddr = (dataaddr / config.dc.blocksize) / config.dc.nsets;
  tagaddr = (dataaddr / config.dc.blocksize) / config.dc.nsets;
 
 
Line 88... Line 98...
  /* Did we find our cached data? */
  /* Did we find our cached data? */
  if (way >= 0) { /* Yes, we did. */
  if (way >= 0) { /* Yes, we did. */
    dc_stats.readhit++;
    dc_stats.readhit++;
 
 
    for (i = 0; i < config.dc.nways; i++)
    for (i = 0; i < config.dc.nways; i++)
      if (dc[set].way[i].lru)
      if (dc[set].way[i].lru > dc[set].way[way].lru)
        dc[set].way[i].lru--;
        dc[set].way[i].lru--;
    dc[set].way[way].lru = config.dc.ustates - 1;
    dc[set].way[way].lru = config.dc.ustates - 1;
    mem_cycles += config.dc.load_hitdelay;
    mem_cycles += config.dc.load_hitdelay;
 
 
 
    tmp = dc[set].way[way].line[(dataaddr & (config.dc.blocksize - 1)) >> 2];
 
    if (width == 4)
 
      return tmp;
 
    else if (width == 2) {
 
      tmp = (unsigned long)((tmp >> ((dataaddr & 2) ? 0 : 16)) & 0xffff);
 
      return tmp;
 
    }
 
    else if (width == 1) {
 
      tmp = (unsigned long)((tmp  >> (8 * (3 - (dataaddr & 3)))) & 0xff);
 
      return tmp;
 
    }
  } else {  /* No, we didn't. */
  } else {  /* No, we didn't. */
    int minlru = config.dc.ustates - 1;
    int minlru = config.dc.ustates - 1;
    int minway = 0;
    int minway = 0;
 
 
                dc_stats.readmiss++;
                dc_stats.readmiss++;
 
 
    for (i = 0; i < config.dc.nways; i++)
    for (i = 0; i < config.dc.nways; 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;
 
 
 
    for (i = 0; i < (config.dc.blocksize); i += 4) {
 
      dc[set].way[minway].line[((dataaddr + i) & (config.dc.blocksize - 1)) >> 2] =
 
        evalsim_mem32((dataaddr & ~(config.dc.blocksize - 1)) + (((dataaddr & ~3ul)+ i) & (config.dc.blocksize - 1)));
 
      if(!cur_area)
 
        return 0;
 
    }
 
 
    dc[set].way[minway].tagaddr = tagaddr;
    dc[set].way[minway].tagaddr = tagaddr;
    for (i = 0; i < config.dc.nways; i++)
    for (i = 0; i < config.dc.nways; 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 = config.dc.ustates - 1;
    dc[set].way[minway].lru = config.dc.ustates - 1;
    mem_cycles += config.dc.load_missdelay;
    mem_cycles += config.dc.load_missdelay;
 
 
 
    tmp = dc[set].way[minway].line[(dataaddr & (config.dc.blocksize - 1)) >> 2];
 
    if (width == 4)
 
      return tmp;
 
    else if (width == 2) {
 
      tmp = (unsigned long)((tmp >> ((dataaddr & 2) ? 0 : 16)) & 0xffff);
 
      return tmp;
 
    }
 
    else if (width == 1) {
 
      tmp = (unsigned long)((tmp  >> (8 * (3 - (dataaddr & 3)))) & 0xff);
 
      return tmp;
 
    }
  }
  }
}
}
 
 
/* 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:
    - increment DC write hit stats,
    - increment DC write hit stats,
Line 123... Line 163...
    - find lru way and entry and replace old tag with tag of the 'dataaddr'
    - find lru way and entry and replace old tag with tag of the 'dataaddr'
    - set 'lru' with config.dc.ustates - 1 and decrement 'lru' of other
    - set 'lru' with config.dc.ustates - 1 and decrement 'lru' of other
      ways unless they have reached 0
      ways unless they have reached 0
*/
*/
 
 
void dc_simulate_write(unsigned long dataaddr)
void dc_simulate_write(unsigned long dataaddr, unsigned long data, int width)
{
{
  int set, way = -1;
  int set, way = -1;
  int i;
  int i;
  unsigned long tagaddr;
  unsigned long tagaddr;
  extern int mem_cycles;
  extern int mem_cycles;
 
  unsigned long tmp;
 
 
 
  if (width == 4)
 
    setsim_mem32(dataaddr, data);
 
  else if (width == 2)
 
    setsim_mem16(dataaddr, (unsigned short)data);
 
  else if (width == 1)
 
    setsim_mem8(dataaddr, (unsigned char)data);
 
 
 
  if (!cur_area)
 
    return;
 
 
  if ((!testsprbits(SPR_UPR, SPR_UPR_DCP)) || (!testsprbits(SPR_SR, SPR_SR_DCE)))
  if ((!testsprbits(SPR_UPR, SPR_UPR_DCP)) || (!testsprbits(SPR_SR, SPR_SR_DCE)))
    return;
    return;
 
 
  /* Which set to check out? */
  /* Which set to check out? */
Line 147... Line 198...
  /* Did we find our cached data? */
  /* Did we find our cached data? */
  if (way >= 0) { /* Yes, we did. */
  if (way >= 0) { /* Yes, we did. */
    dc_stats.writehit++;
    dc_stats.writehit++;
 
 
    for (i = 0; i < config.dc.nways; i++)
    for (i = 0; i < config.dc.nways; i++)
      if (dc[set].way[i].lru)
      if (dc[set].way[i].lru > dc[set].way[way].lru)
        dc[set].way[i].lru--;
        dc[set].way[i].lru--;
    dc[set].way[way].lru = config.dc.ustates - 1;
    dc[set].way[way].lru = config.dc.ustates - 1;
    mem_cycles += config.dc.store_hitdelay;
    mem_cycles += config.dc.store_hitdelay;
 
 
 
    tmp = dc[set].way[way].line[(dataaddr & (config.dc.blocksize - 1)) >> 2];
 
    if (width == 4)
 
      tmp = data;
 
    else if (width == 2) {
 
      tmp &= 0xffff << ((dataaddr & 2) ? 16 : 0);
 
      tmp |= (unsigned long)(data & 0xffff) << ((dataaddr & 2) ? 0 : 16);
 
    }
 
    else if (width == 1) {
 
      tmp &= ~(0xff << (8 * (3 - (dataaddr & 3))));
 
      tmp |= (unsigned long)(data & 0xff) << (8 * (3 - (dataaddr & 3)));
 
    }
 
    dc[set].way[way].line[(dataaddr & (config.dc.blocksize - 1)) >> 2] = tmp;
  }
  }
  else {  /* No, we didn't. */
  else {  /* No, we didn't. */
    int minlru = config.dc.ustates - 1;
    int minlru = config.dc.ustates - 1;
    int minway = 0;
    int minway = 0;
 
 
                dc_stats.writemiss++;
                dc_stats.writemiss++;
 
 
    for (i = 0; i < config.dc.nways; i++)
    for (i = 0; i < config.dc.nways; 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;
 
 
 
    for (i = 0; i < (config.dc.blocksize); i += 4) {
 
      dc[set].way[minway].line[((dataaddr + i) & (config.dc.blocksize - 1)) >> 2] =
 
        evalsim_mem32((dataaddr & ~(config.dc.blocksize - 1)) + (((dataaddr & ~3ul)+ i) & (config.dc.blocksize - 1)));
 
      if(!cur_area)
 
        return;
 
    }
 
 
    dc[set].way[minway].tagaddr = tagaddr;
    dc[set].way[minway].tagaddr = tagaddr;
    for (i = 0; i < config.dc.nways; i++)
    for (i = 0; i < config.dc.nways; 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 = config.dc.ustates - 1;
    dc[set].way[minway].lru = config.dc.ustates - 1;
Line 190... Line 260...
 
 
  /* Which set to check out? */
  /* Which set to check out? */
  set = (dataaddr / config.dc.blocksize) % config.dc.nsets;
  set = (dataaddr / config.dc.blocksize) % config.dc.nsets;
  tagaddr = (dataaddr / config.dc.blocksize) / config.dc.nsets;
  tagaddr = (dataaddr / config.dc.blocksize) / config.dc.nsets;
 
 
 
  if (!testsprbits(SPR_SR, SPR_SR_DCE)) {
 
    for (i = 0; i < config.dc.nways; i++) {
 
      dc[set].way[i].tagaddr = -1;
 
      dc[set].way[i].lru = 0;
 
    }
 
    return;
 
  }
  /* Scan all ways and try to find a matching way. */
  /* Scan all ways and try to find a matching way. */
  for (i = 0; i < config.dc.nways; i++)
  for (i = 0; i < config.dc.nways; i++)
    if (dc[set].way[i].tagaddr == tagaddr)
    if (dc[set].way[i].tagaddr == tagaddr)
      way = i;
      way = i;
 
 
  /* Did we find our cached data? */
  /* Did we find our cached data? */
  if ((way >= 0) && (getsprbits(SPR_DCCR, SPR_DCCR_EW) & (1 << way))) { /* Yes, we did. */
  if (way >= 0) { /* Yes, we did. */
    dc[set].way[way].tagaddr = -1;
    dc[set].way[way].tagaddr = -1;
 
    dc[set].way[way].lru = 0;
  }
  }
}
}
 
 
inline void dc_clock()
inline void dc_clock()
{
{
  unsigned long addr;
  unsigned long addr;
 
 
  if (addr = mfspr(SPR_DCBPR)) {
  if (addr = mfspr(SPR_DCBPR)) {
    dc_simulate_read(addr);
    dc_simulate_read(addr, 4);
    mtspr(SPR_DCBPR, 0);
    mtspr(SPR_DCBPR, 0);
  }
  }
  if (addr = mfspr(SPR_DCBFR)) {
  if ((addr = mfspr(SPR_DCBFR)) != -1) {
    dc_inv(addr);
    dc_inv(addr);
    mtspr(SPR_DCBFR, 0);
    mtspr(SPR_DCBFR, -1);
  }
  }
  if (addr = mfspr(SPR_DCBIR)) {
  if (addr = mfspr(SPR_DCBIR)) {
    dc_inv(addr);
    dc_inv(addr);
    mtspr(SPR_DCBIR, 0);
    mtspr(SPR_DCBIR, 0);
  }
  }

powered by: WebSVN 2.1.0

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