@@ -1222,12 +1222,13 @@ void flush_all_caches();
12221222
12231223uint64_t calculate_tag (uint64_t * cache , uint64_t * paddr );
12241224uint64_t * calculate_set (uint64_t * cache , uint64_t vaddr );
1225- uint64_t * retrieve_cache_block (uint64_t * cache , uint64_t * paddr , uint64_t vaddr , uint64_t is_access );
12261225uint64_t get_new_timestamp (uint64_t * cache );
1227- uint64_t * cache_lookup (uint64_t * cache , uint64_t vaddr , uint64_t tag , uint64_t is_access );
1228- uint64_t * handle_cache_miss (uint64_t * cache , uint64_t * cache_block , uint64_t tag , uint64_t is_access );
1226+ uint64_t * cache_lookup (uint64_t * cache , uint64_t * paddr , uint64_t vaddr , uint64_t is_access );
1227+ void fill_cache_block (uint64_t * cache_block , uint64_t cache_block_size , uint64_t * start_paddr );
1228+ uint64_t * handle_cache_miss (uint64_t * cache , uint64_t * cache_block , uint64_t * paddr , uint64_t is_access );
1229+ uint64_t * retrieve_cache_block (uint64_t * cache , uint64_t * paddr , uint64_t vaddr , uint64_t is_access );
12291230
1230- void fill_cache_block (uint64_t * cache_block , uint64_t cache_block_size , uint64_t * start_paddr );
1231+ uint64_t calculate_word_offset (uint64_t cache_block_size , uint64_t vaddr );
12311232void flush_cache_block (uint64_t * cache_block , uint64_t cache_block_size , uint64_t * start_paddr );
12321233void store_in_cache (uint64_t * cache , uint64_t * paddr , uint64_t vaddr , uint64_t data );
12331234uint64_t load_from_cache (uint64_t * cache , uint64_t * paddr , uint64_t vaddr );
@@ -7493,14 +7494,17 @@ uint64_t get_new_timestamp(uint64_t* cache) {
74937494 return timestamp ;
74947495}
74957496
7496- uint64_t * cache_lookup (uint64_t * cache , uint64_t vaddr , uint64_t tag , uint64_t is_access ) {
7497+ uint64_t * cache_lookup (uint64_t * cache , uint64_t * paddr , uint64_t vaddr , uint64_t is_access ) {
74977498 uint64_t * set ;
7499+ uint64_t tag ;
74987500 uint64_t i ;
74997501 uint64_t * cache_block ;
75007502 uint64_t * lru_block ; // least-recently used block for replacement strategy
75017503
75027504 set = calculate_set (cache , vaddr );
75037505
7506+ tag = calculate_tag (cache , paddr );
7507+
75047508 i = 0 ;
75057509
75067510 lru_block = (uint64_t * ) * set ;
@@ -7534,21 +7538,47 @@ uint64_t* cache_lookup(uint64_t* cache, uint64_t vaddr, uint64_t tag, uint64_t i
75347538 return lru_block ;
75357539}
75367540
7537- uint64_t * handle_cache_miss (uint64_t * cache , uint64_t * cache_block , uint64_t tag , uint64_t is_access ) {
7541+ void fill_cache_block (uint64_t * cache_block , uint64_t cache_block_size , uint64_t * start_paddr ) {
7542+ uint64_t words ;
7543+ uint64_t * data ;
7544+ uint64_t i ;
7545+
7546+ words = cache_block_size / WORDSIZE ;
7547+
7548+ data = get_data (cache_block );
7549+
7550+ i = 0 ;
7551+
7552+ while (i < words ) {
7553+ * (data + i ) = load_physical_memory (start_paddr + i );
7554+
7555+ i = i + 1 ;
7556+ }
7557+ }
7558+
7559+ uint64_t * handle_cache_miss (uint64_t * cache , uint64_t * cache_block , uint64_t * paddr , uint64_t is_access ) {
7560+ uint64_t cache_block_size ;
7561+
75387562 if (is_access ) {
75397563 set_cache_misses (cache , get_cache_misses (cache ) + 1 );
75407564
7541- set_tag (cache_block , tag );
7565+ cache_block_size = get_cache_block_size (cache );
7566+
7567+ // make sure the entire cache block contains valid data
7568+ fill_cache_block (cache_block , cache_block_size , (uint64_t * ) (((uint64_t ) paddr / cache_block_size ) * cache_block_size ));
7569+
7570+ set_tag (cache_block , calculate_tag (cache , paddr ));
75427571
75437572 set_timestamp (cache_block , get_new_timestamp (cache ));
75447573
7574+ set_valid_flag (cache_block , 1 );
7575+
75457576 return cache_block ;
75467577 } else
75477578 return (uint64_t * ) 0 ;
75487579}
75497580
75507581uint64_t * retrieve_cache_block (uint64_t * cache , uint64_t * paddr , uint64_t vaddr , uint64_t is_access ) {
7551- uint64_t tag ;
75527582 uint64_t * cache_block ;
75537583
75547584 // vaddr
@@ -7566,18 +7596,16 @@ uint64_t* retrieve_cache_block(uint64_t* cache, uint64_t* paddr, uint64_t vaddr,
75667596 // | tag | |
75677597 // +-----+---------------------+
75687598
7569- tag = calculate_tag (cache , paddr );
7570-
7571- cache_block = cache_lookup (cache , vaddr , tag , is_access );
7599+ cache_block = cache_lookup (cache , paddr , vaddr , is_access );
75727600
75737601 if (get_valid_flag (cache_block ))
75747602 // cache hit
75757603 return cache_block ;
75767604 else
7577- return handle_cache_miss (cache , cache_block , tag , is_access );
7605+ return handle_cache_miss (cache , cache_block , paddr , is_access );
75787606}
75797607
7580- void fill_cache_block (uint64_t * cache_block , uint64_t cache_block_size , uint64_t * start_paddr ) {
7608+ void flush_cache_block (uint64_t * cache_block , uint64_t cache_block_size , uint64_t * start_paddr ) {
75817609 uint64_t words ;
75827610 uint64_t * data ;
75837611 uint64_t i ;
@@ -7589,86 +7617,45 @@ void fill_cache_block(uint64_t* cache_block, uint64_t cache_block_size, uint64_t
75897617 i = 0 ;
75907618
75917619 while (i < words ) {
7592- * ( data + i ) = load_physical_memory ( start_paddr + i );
7620+ store_physical_memory ( start_paddr + i , * ( data + i ) );
75937621
75947622 i = i + 1 ;
75957623 }
75967624}
75977625
7598- void flush_cache_block (uint64_t * cache_block , uint64_t cache_block_size , uint64_t * start_paddr ) {
7599- uint64_t words ;
7600- uint64_t * data ;
7601- uint64_t i ;
7602-
7603- words = cache_block_size / WORDSIZE ;
7604-
7605- data = get_data (cache_block );
7606-
7607- i = 0 ;
7626+ uint64_t calculate_word_offset (uint64_t cache_block_size , uint64_t vaddr ) {
7627+ uint64_t byte_offset ;
76087628
7609- while (i < words ) {
7610- store_physical_memory (start_paddr + i , * (data + i ));
7629+ byte_offset = vaddr - ((vaddr / cache_block_size ) * cache_block_size );
76117630
7612- i = i + 1 ;
7613- }
7631+ return byte_offset / WORDSIZE ;
76147632}
76157633
76167634void store_in_cache (uint64_t * cache , uint64_t * paddr , uint64_t vaddr , uint64_t data ) {
76177635 uint64_t * cache_block ;
76187636 uint64_t * cache_block_data ;
76197637 uint64_t cache_block_size ;
7620- uint64_t byte_offset ;
7621- uint64_t word_offset ;
7622-
7623- cache_block_size = get_cache_block_size (cache );
76247638
76257639 cache_block = retrieve_cache_block (cache , paddr , vaddr , 1 );
76267640
76277641 cache_block_data = get_data (cache_block );
76287642
7629- if (get_valid_flag (cache_block ) == 0 ) {
7630- // make sure that the entire block contains valid data since we will only write one word
7631- fill_cache_block (cache_block , cache_block_size , (uint64_t * ) (((uint64_t ) paddr / cache_block_size ) * cache_block_size ));
7632-
7633- set_valid_flag (cache_block , 1 );
7634- }
7635-
7636- byte_offset = vaddr - ((vaddr / cache_block_size ) * cache_block_size );
7637-
7638- // calculate word offset due to pointer arithmetic
7639- word_offset = byte_offset / WORDSIZE ;
7643+ cache_block_size = get_cache_block_size (cache );
76407644
7641- * (cache_block_data + word_offset ) = data ;
7645+ * (cache_block_data + calculate_word_offset ( cache_block_size , vaddr ) ) = data ;
76427646
76437647 flush_cache_block (cache_block , cache_block_size , (uint64_t * ) (((uint64_t ) paddr / cache_block_size ) * cache_block_size ));
76447648}
76457649
76467650uint64_t load_from_cache (uint64_t * cache , uint64_t * paddr , uint64_t vaddr ) {
76477651 uint64_t * cache_block ;
76487652 uint64_t * data ;
7649- uint64_t cache_block_size ;
7650- uint64_t byte_offset ;
7651- uint64_t word_offset ;
7652-
7653- cache_block_size = get_cache_block_size (cache );
76547653
76557654 cache_block = retrieve_cache_block (cache , paddr , vaddr , 1 );
76567655
7657- // if we missed the cache, we receive a block whose data has been invalidated
7658- if (get_valid_flag (cache_block ) == 0 ) {
7659- fill_cache_block (cache_block , cache_block_size , (uint64_t * ) (((uint64_t ) paddr / cache_block_size ) * cache_block_size ));
7660-
7661- set_valid_flag (cache_block , 1 );
7662- }
7663-
76647656 data = get_data (cache_block );
76657657
7666- byte_offset = vaddr - ((vaddr / cache_block_size ) * cache_block_size );
7667-
7668- // calculate word offset due to pointer arithmetic
7669- word_offset = byte_offset / WORDSIZE ;
7670-
7671- return * (data + word_offset );
7658+ return * (data + calculate_word_offset (get_cache_block_size (cache ), vaddr ));
76727659}
76737660
76747661uint64_t load_instruction_from_cache (uint64_t * paddr , uint64_t vaddr ) {
0 commit comments