计算机系统原理 实验四 设计MIPS五级流水线模拟器中的Cache

这部分感觉写着很有意思,写之前一脸懵逼,写完后对cache方面的知识确实有了飞一般地认知,希望后面的学弟学妹们不要照抄,关键部分注释我都写得比较明白,还是要理解为主,希望大家都能自己写写,这个挺好玩的

那么话不多说,代码放这里了

 cache.h

#ifndef CACHE
#define CACHE

#include "mips.h"
#include <stdio.h>
#include <stdbool.h>
#include <stdint.h>

typedef struct {
    bool valid;
    uint32_t lru;//2 bytes
    uint32_t tag;//21 bytes
    uint32_t mem[32];
}cache_line;

typedef struct {
    cache_line line[4];
}cache_set;

typedef struct {
    cache_set set[64];
}Cache;

extern Cache cache;

void init();
void cache_write(uint32_t address);
uint32_t cache_read(uint32_t address);

extern int delay;

#endif

cache.c


#include "cache.h"
#include "pipe.h"
#include "shell.h"
#include "mips.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>

Cache cache;
int delay = 0;

void init(){
    int i =0, j = 0;
    for(i=0;i<64;i++){
        for(j=0;j<4;j++){
            cache.set[i].line[j].valid = 0;
            cache.set[i].line[j].lru = 0;
        }
    }
}

uint32_t cache_read(uint32_t address){
	uint32_t set = (address >>5) &(0x3F);//6 bytes of block
	uint32_t inoffset = address & (0x1f);//loc of line ,5 bytes
	uint32_t tag = address >> 11 ;//tag 21 bytes
	uint32_t word=0;
	int flag_lru=0;	
	int write_line=0;
    for(int i=0;i<4;i++){
        if(cache.set[set].line[i].valid==1){//judge is valid
            if(cache.set[set].line[i].tag == tag){//judge is tag right
                flag_lru=cache.set[set].line[i].lru;        
                write_line=i;    
                uint32_t j=inoffset;
                 word=  (cache.set[set].line[i].mem[j]<<0)    |
                        (cache.set[set].line[i].mem[j+1]<<8)  |
                        (cache.set[set].line[i].mem[j+2]<<16) |
                        (cache.set[set].line[i].mem[j+3]<<24);  
                break;
            }
        }
    }
    //cache hit
    if(write_line!=-1){
   	 	for(int i=0;i<4;i++){
    		if(i!=write_line){
    			if(cache.set[set].line[i].lru<flag_lru){
    				cache.set[set].line[i].lru++;
    			}
    		}
    	}
    	return word;
    }
    //cache miss
    delay = 49;
    cache_write(address);
    return 0;
}


void cache_write(uint32_t address){
    uint32_t inoffset= address & 0x1F;//loc of line ,5 bytes
    uint32_t set= (address >>5) &(0x3F);//6 bytes of block   
    uint32_t tag=address >>11;//tag 21 bytes
    uint32_t start_line= (address >> 5)<<5;//the loc of write line
    int write_line= -1;
    int flag_lru=0;
    for(int i=0;i<4;i++){
        if(cache.set[set].line[i].valid==0){//find the line in the set which isn't been written,initialize the line
        	flag_lru=cache.set[set].line[i].lru;
            cache.set[set].line[i].tag = tag;//new line ,the lru is zero        
            cache.set[set].line[i].valid = 1;//the line is changed
            cache.set[set].line[i].lru = 0;//update the lru
            write_line = i;            
            break;
        }
    }
    //cache hit,every lru++,expect write line
    if(write_line!=-1){
    	for(int i=0;i<4;i++){
       	  if(write_line!=i){
       	  	if(flag_lru>cache.set[set].line[i].lru)
       	     	cache.set[set].line[i].lru++;
       	  }
   		}
   	}
	else if(write_line==-1){//cache miss,the cache is full now,it should be replaced with one line
        uint8_t max_lru = 0;
        for(int i=0;i<4;i++){
            cache.set[set].line[i].lru++;//every lru ++,because cache miss
            if(max_lru<=cache.set[set].line[i].lru){//find the max_lru and write_line index in the lines of sets 
               max_lru = cache.set[set].line[i].lru;
               write_line = i;
            }
        }
        //init the replaced line again
        cache.set[set].line[write_line].tag = tag;//replace the origional tag with new tag
        cache.set[set].line[write_line].valid = 1;//the line is changed
        cache.set[set].line[write_line].lru = 0; //new line ,the lru is zero       
    }
    //read from memory and write on the write_line
    for(int i = 0;i<8;i++){
        uint32_t word = mem_read_32(start_line);//the mem block size is 32 bytes
        cache.set[set].line[write_line].mem[i*4]   = (uint8_t)(word>>0) &0xFF;//load low 8 bytes total 32 bytes each times from memory to write_lines
        cache.set[set].line[write_line].mem[i*4+1] = (uint8_t)(word>>8) &0xFF;
        cache.set[set].line[write_line].mem[i*4+2] = (uint8_t)(word>>16)&0xFF;
        cache.set[set].line[write_line].mem[i*4+3] = (uint8_t)(word>>24)&0xFF;
        start_line+=4;
    }
    
}

cache_data.h

#ifndef CACHEDATA
#define CACHEDATA

#include "stdio.h"
#include "mips.h"
#include "stdbool.h"
#include "stdint.h"

typedef struct {
    bool valid;
    bool dirty;
    uint32_t lru;
    uint32_t tag;
    uint32_t mem[32];
}cache_data_line;

typedef struct {
    cache_data_line data_line[8];
}cache_data_set;

typedef struct {
    cache_data_set data_set[256];
}Cache_data;

extern Cache_data cache_data;
extern int cache_data_delay;

void data_init();
void cache_data_write(uint32_t address,uint32_t write);
void cache_data_GetFromMem(uint32_t address);
uint32_t cache_data_read(uint32_t address);

#endif

cache_data.c


#include "cache_data.h"
#include "pipe.h"
#include "shell.h"
#include "mips.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>

Cache_data cache_data;
int cache_data_delay = 0;
void data_init(){
    int i =0, j = 0;
    for(i=0;i<256;i++)
    {
        for(j=0;j<8;j++)
        {
            cache_data.data_set[i].data_line[j].valid = 0;
            cache_data.data_set[i].data_line[j].lru = 0;
            cache_data.data_set[i].data_line[j].dirty = 0;
        }
    }
}
uint32_t cache_data_read(uint32_t address){
    uint32_t inoffset = address & (0x1F);//get the low 5 bytes
    uint32_t set = (address >>5) &(0xFF);//get 5-12 bytes
    uint32_t tag = address >> 13 ;//get tag bytes
    for(int i=0;i<8;i++){
        if(cache_data.data_set[set].data_line[i].valid==1){
            if(cache_data.data_set[set].data_line[i].tag == tag){
                uint32_t word = (cache_data.data_set[set].data_line[i].mem[inoffset]<<0)    |
                                (cache_data.data_set[set].data_line[i].mem[inoffset+1]<<8)  |
                                (cache_data.data_set[set].data_line[i].mem[inoffset+2]<<16) |
                                (cache_data.data_set[set].data_line[i].mem[inoffset+3]<<24);  
                return word;               
            }
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值