📄 cache_ctrl.cpp
字号:
/* * TU Eindhoven * Eindhoven, The Netherlands * * Name : cache_ctrl.cpp * * Author : A.S.Slusarczyk@tue.nl * * Date : * * Function : Cache control logic * * */#include "cache_ctrl.h"void CACHE_ADDR_SPLIT::split(){ sc_bv<32> a, ar; sc_bv<TAG_BITS> t, tr; sc_bv<INDEX_BITS> i, ir; sc_bv<OFFSET_BITS> o, ofr; sc_uint<2> b, br; a = addr.read(); ar = addr_reg.read(); b = sc_bv<2>(a.range(1,0)); br = sc_bv<2>(ar.range(1,0)); o = a.range(OFFSET_BITS+1, 2); ofr = ar.range(OFFSET_BITS+1, 2); if( fetch_word_rdy.read() ) o = fetch_word.read(); i = a.range(OFFSET_BITS+INDEX_BITS+1, OFFSET_BITS+2); ir = ar.range(OFFSET_BITS+INDEX_BITS+1, OFFSET_BITS+2); t = a.range(TAG_BITS+OFFSET_BITS+INDEX_BITS+1, INDEX_BITS+OFFSET_BITS+2); if( rewrite.read() ) t = tag_rewrite.read(); tr = ar.range(TAG_BITS+OFFSET_BITS+INDEX_BITS+1, INDEX_BITS+OFFSET_BITS+2); tag.write(t); tag_reg.write(tr); index.write(i); index_reg.write(ir); offset.write(o); offset_reg.write(ofr); byte.write(b); byte_reg.write(br);}void CACHE_BYTE_SELECT::select(){ // the requested byte replaces the most significant byte of the word sc_bv<32> data = din.read(); sc_bv<24> lsbs = data.range(23,0); sc_bv<8> msb; sc_uint<2> r_v = r.read(); if( r_v == 2 ){ switch( byte.read() ){ case 1 : msb = data.range(23,16); break; case 2 : msb = data.range(15,8); break; case 3 : msb = data.range(7,0); break; default: msb = data.range(31,24); break; } } else msb = data.range(31,24); dout.write( (msb, lsbs) );}void CACHE_MISS_CTRL::change_state(){ current_state = next_state; operation = n_operation; waiting = miss_wait.read();}void CACHE_MISS_CTRL::fetch_word_reg(){ // synchronous clear and increment if( word_clr.read() ) { fetch_word = next_fetch_word.read(); next_fetch_word = 0; } else if( word_inc.read() ) { fetch_word = next_fetch_word.read(); next_fetch_word = next_fetch_word.read()+1; }}void CACHE_MISS_CTRL::write_progress(){ //cout << "write_progress sw=" << start_write.read() << " mr=" << mem_rdy.read() << " " << sc_time_stamp() << endl; if( start_write.read() ) { //cout << "set\n"; write_in_progress.write(true); } else if( mem_rdy.read() ){ //cout << "reset\n"; write_in_progress.write(false); } }void CACHE_MISS_CTRL::miss_detect(){ miss.write( !cache_valid.read() || (cache_tag.read() != addr_tag.read()) );}void CACHE_MISS_CTRL::logic(){ sc_uint<2> w_v, r_v; sc_bv<32> addr_v; sc_bv<2> zero(0), wrd; bool en_v = (en.read()[0]==true); miss_wait.write(false); cache_we.write(false); cache_en.write(false); rewrite.write(false); byte_rpl.write(false); current_reg.write(false); mem_r.write(false); mem_ww.write(false); mem_wb.write(false); mem_din.write( din.read() ); wrd = next_fetch_word.read(); addr_v = (addr.read().range(31,4), wrd, zero); mem_addr.write( addr.read() ); fetch_word_rdy.write(false); word_inc = false; word_clr = false; start_write = false; n_operation = operation.read(); next_state = current_state.read(); switch( current_state.read() ) { case MEMORY : if( operation.read() != NONE && miss.read() && operation.read() != WB && !waiting.read() ){ if( operation.read() == R ){ // missed on read, need to download the memory block if( write_in_progress.read() && !mem_rdy.read() ) next_state = WAIT_FETCH; else { next_state = FETCH; word_inc.write(true); mem_r.write(true); mem_addr.write( addr_v ); } current_reg.write(true); miss_wait.write(true); } else { // miss on word write - rewrite the previous value of the memory miss_wait.write(true); rewrite.write(true); cache_we.write(true); cache_en.write(true); next_state = MEMORY; n_operation = NONE; current_reg.write(true); } } else if( operation.read() == WB && !miss.read() && !waiting.read() ){ // byte write // We've read the word, replace the byte and write it back // If we missed, we can just proceed, since write-through has been initiated // and cache wasn't modified miss_wait.write(true); byte_rpl.write(true); rewrite.write(true); cache_we.write(true); cache_en.write(true); current_reg.write(true); next_state = MEMORY; n_operation = NONE; } else if( en_v ) { // ready! initiate next operation r_v = r.read(); w_v = w.read(); cache_we.write( w_v==1 ); cache_en.write( (r_v!=0) || (w_v!=0) ); if( w_v != 0 ){ next_state = MEMORY; if( w_v == 2 ){ // writing byte in two cycles: 1. read the word, initiate write-through // 2. replace the byte, write back the word cache_en.write(true); mem_wb.write(true); start_write = true; n_operation = WB; } else { // writing word - just write it to the memory, check the result // later; at the same time, order FETCH_CTRL to write the word to memory cache_we.write(true); cache_en.write(true); start_write.write(true); mem_ww.write(true); n_operation = WW; } if( write_in_progress.read() && !mem_rdy.read() ){ // oops! memory is busy - // we'll need write-through and the previous write did not finish // we'll have to wait start_write = false; miss_wait.write(true); cache_we.write(false); cache_en.write(false); mem_wb.write(false); mem_ww.write(false); next_state = WAIT_WRITE; } } else if( r_v != 0 ){ // reading data n_operation = R; next_state = MEMORY; } else { // nothing to do n_operation = NONE; next_state = MEMORY; } } else { // disable next_state = MEMORY; n_operation = operation.read(); current_reg.write(true); } break; case FETCH : miss_wait.write(true); current_reg.write(true); mem_addr.write( addr_v ); if( mem_rdy.read() ){ fetch_word_rdy.write(true); cache_we.write(true); cache_en.write(true); if( next_fetch_word.read()==0 ){ next_state = REREAD_WORD; } else{ word_inc.write(true); mem_r.write(true); next_state = FETCH; } } else { next_state = FETCH; } break; case REREAD_WORD : miss_wait.write(true); current_reg.write(true); cache_en.write(true); n_operation = NONE; next_state = MEMORY; break; case WAIT_FETCH : miss_wait.write(true); if( write_in_progress.read() ) next_state = WAIT_FETCH; else{ next_state = FETCH; current_reg.write(true); word_inc.write(true); mem_r.write(true); mem_addr.write( addr_v ); } break; case WAIT_WRITE : miss_wait.write(true); if( !mem_rdy.read() ) next_state = WAIT_WRITE; else{ next_state = MEMORY; start_write = true; miss_wait.write(false); cache_en.write(true); if( operation == WB ) mem_wb.write(true); else { mem_ww.write(true); cache_we.write(true); } } break; }}void CACHE_DIN_SELECT::select(){ sc_bv<32> d; bool v = false; if( rewrite.read() ){ d = din_out.read(); if( byte_rpl.read() ) { switch(byte.read()){ case 0 : d.range(31,24) = din_data_reg.read().range(7,0); break; case 1 : d.range(23,16) = din_data_reg.read().range(7,0); break; case 2 : d.range(15,8) = din_data_reg.read().range(7,0); break; default : d.range(7,0) = din_data_reg.read().range(7,0); break; } } v = rewrite_valid.read(); } else if( fetch_word_rdy.read() ){ d = din_fetch.read(); v = true; } else { d = din_data.read(); v = true; } data.write( d ); valid.write( v );}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -