Changeset 165 for trunk/modules/vci_cc_xcache_wrapper_v4/caba
- Timestamp:
- May 11, 2011, 1:36:38 PM (14 years ago)
- Location:
- trunk/modules/vci_cc_xcache_wrapper_v4/caba
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/modules/vci_cc_xcache_wrapper_v4/caba/metadata/vci_cc_xcache_wrapper_v4.sd
r134 r165 22 22 Uses('common:iss2'), 23 23 Uses('caba:multi_write_buffer'), 24 Uses('caba:generic_fifo'), 24 25 Uses('caba:generic_cache', addr_t = 'uint32_t'), 25 26 ], -
trunk/modules/vci_cc_xcache_wrapper_v4/caba/source/include/vci_cc_xcache_wrapper_v4.h
r147 r165 31 31 32 32 #include <inttypes.h> 33 #include <fstream> 33 34 #include <systemc> 34 35 #include <queue> … … 36 37 #include "multi_write_buffer.h" 37 38 #include "generic_cache.h" 39 #include "generic_fifo.h" 38 40 #include "vci_initiator.h" 39 41 #include "vci_target.h" … … 42 44 43 45 /* 44 * CC_XCACHE_WRAPPER_SELECT_VICTIM : 45 * The selection and the update of cache (after a read miss) 46 * are separated in two step 47 * Also, the cleanup can be send in parallel at the read miss. 48 * 49 * CC_XCACHE_WRAPPER_FIFO_RSP 50 * Two simple fifo (each 2x32 depth) receive the cache line from 51 * RAM. Instead of two buffers (m_icache_words and m_dcache_words) 52 * 53 * CC_XCACHE_WRAPPER_CC_UPDATE_MULTI_CYCLE 54 * Update cache in "2*cache_words" cycles (read+mask, write) 55 * 56 * CC_XCACHE_WRAPPER_CC_UPDATE_MULTI_CYCLE_OPT 57 * Update cache with only modified data (be != 0) 58 * 59 * CC_XCACHE_WRAPPER_WBUF_UPDATE_SCHEME 60 * Write buffer scheme for update step : 61 * 1 - multi_scan 62 * 2 - round_robin_scan 63 * 3 - one_scan 64 * else - default scheme 65 * 66 * CC_XCACHE_WRAPPER_VCI_CMD_PRIORITY 67 * Write buffer access is conditionnal with dcache_miss_req and icache_miss_req 68 * 1 - two access authorized 69 * 2 - one access with static priority (dcache prior) 70 * 3 - one access with static priority (icache prior) 71 * 4 - one access with round robin priority 72 * 73 * CC_XCACHE_WRAPPER_STOP_SIMULATION : 46 * ---------------------------------------------------------- 47 * Implementation 48 * ---------------------------------------------------------- 49 * 50 * CC_XCACHE_WRAPPER_MULTI_CACHE 51 * 1 - icache static partitionnement 52 * 2 - icache dedicated 53 * 54 * ---------------------------------------------------------- 55 * Debug 56 * ---------------------------------------------------------- 57 * 58 * CC_XCACHE_WRAPPER_STOP_SIMULATION 74 59 * stop simulation if processor is stall after a long time 75 60 * (configurable with "stop_simulation" function) 76 61 * 77 * CC_XCACHE_WRAPPER_DEBUG :62 * CC_XCACHE_WRAPPER_DEBUG 78 63 * Add log to help the debugging 79 64 * 80 * CC_XCACHE_WRAPPER_DEBUG_CYCLE_MIN :65 * CC_XCACHE_WRAPPER_DEBUG_CYCLE_MIN 81 66 * Number of cycle before to prinf debug message 82 67 * 83 * CC_XCACHE_WRAPPER_DEBUG_DCACHE_TRANSACTION 84 * Print transaction between the cpu and the cache 68 * CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION 69 * Print transaction between : 70 * - the cpu and the cache (icache and dcache) 71 * - vci 72 * - cleanup 73 * - coherency 74 * 75 * MWBUF_VHDL_TESTBENCH 76 * generate a vhdl testbench for multi write buffer 85 77 */ 86 78 87 79 // implementation 88 #ifndef CC_XCACHE_WRAPPER_SELECT_VICTIM 89 #define CC_XCACHE_WRAPPER_SELECT_VICTIM 0 90 #endif 91 #ifndef CC_XCACHE_WRAPPER_FIFO_RSP 92 #define CC_XCACHE_WRAPPER_FIFO_RSP 0 93 #endif 94 #ifndef CC_XCACHE_WRAPPER_CC_UPDATE_MULTI_CYCLE 95 #define CC_XCACHE_WRAPPER_CC_UPDATE_MULTI_CYCLE 1 96 #endif 97 #ifndef CC_XCACHE_WRAPPER_CC_UPDATE_MULTI_CYCLE_OPT 98 #define CC_XCACHE_WRAPPER_CC_UPDATE_MULTI_CYCLE_OPT 1 99 #endif 100 #ifndef CC_XCACHE_WRAPPER_WBUF_UPDATE_SCHEME 101 #define CC_XCACHE_WRAPPER_WBUF_UPDATE_SCHEME 0 102 #endif 103 #ifndef CC_XCACHE_WRAPPER_VCI_CMD_PRIORITY 104 #define CC_XCACHE_WRAPPER_VCI_CMD_PRIORITY 2 105 #endif 106 // debugging 80 #ifndef CC_XCACHE_WRAPPER_MULTI_CACHE 81 #define CC_XCACHE_WRAPPER_MULTI_CACHE 2 82 // if multi_cache : 83 // <tsar toplevel>/modules/vci_mem_cache_v4/caba/source/include/mem_cache_directory_v4.h : L1_MULTI_CACHE 1 84 #endif 85 86 // debug 107 87 #ifndef CC_XCACHE_WRAPPER_STOP_SIMULATION 108 #define CC_XCACHE_WRAPPER_STOP_SIMULATION 188 #define CC_XCACHE_WRAPPER_STOP_SIMULATION 1 109 89 #endif 110 90 #ifndef CC_XCACHE_WRAPPER_DEBUG 111 #define CC_XCACHE_WRAPPER_DEBUG 091 #define CC_XCACHE_WRAPPER_DEBUG 0 112 92 #endif 113 93 #ifndef CC_XCACHE_WRAPPER_DEBUG_CYCLE_MIN 114 #define CC_XCACHE_WRAPPER_DEBUG_CYCLE_MIN 200000 115 #endif 116 #ifndef CC_XCACHE_WRAPPER_DEBUG_DCACHE_TRANSACTION 117 #define CC_XCACHE_WRAPPER_DEBUG_DCACHE_TRANSACTION 0 94 #define CC_XCACHE_WRAPPER_DEBUG_CYCLE_MIN 4725000 95 #endif 96 #ifndef CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION 97 #define CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION 0 98 #define CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION_PATH "log" 99 #endif 100 #ifndef MWBUF_VHDL_TESTBENCH 101 #define MWBUF_VHDL_TESTBENCH 0 118 102 #endif 119 103 … … 129 113 : public soclib::caba::BaseModule 130 114 { 115 typedef uint64_t vhdl_tb_t; 131 116 typedef sc_dt::sc_uint<40> addr_40; 132 typedef sc_dt::sc_uint<64> data_64;133 117 typedef uint32_t data_t; 134 118 typedef uint32_t tag_t; 135 119 typedef uint32_t be_t; 136 120 typedef typename vci_param::fast_addr_t vci_addr_t; 137 121 typedef enum 122 { 123 WRITE_THROUGH, 124 RELEASE_WRITE_THROUGH 125 } write_policy_t; 126 138 127 enum dcache_fsm_state_e { 139 128 DCACHE_IDLE, 140 129 DCACHE_WRITE_UPDT, 141 #if CC_XCACHE_WRAPPER_SELECT_VICTIM142 130 DCACHE_MISS_VICTIM, 143 #endif144 131 DCACHE_MISS_WAIT, 145 132 DCACHE_MISS_UPDT, … … 157 144 enum icache_fsm_state_e { 158 145 ICACHE_IDLE, 159 #if CC_XCACHE_WRAPPER_SELECT_VICTIM160 146 ICACHE_MISS_VICTIM, 161 #endif162 147 ICACHE_MISS_WAIT, 163 148 ICACHE_MISS_UPDT, … … 204 189 enum cleanup_fsm_state_e { 205 190 CLEANUP_IDLE, 206 CLEANUP_DCACHE, 207 CLEANUP_ICACHE, 191 CLEANUP_REQ, 192 CLEANUP_RSP_DCACHE, 193 CLEANUP_RSP_ICACHE, 208 194 }; 209 195 … … 231 217 sc_in<bool> p_clk; 232 218 sc_in<bool> p_resetn; 233 sc_in<bool> p_irq[iss_t::n_irq];219 sc_in<bool> ** p_irq;//[m_nb_cpu][iss_t::n_irq]; 234 220 soclib::caba::VciInitiator<vci_param> p_vci_ini_rw; 235 221 soclib::caba::VciInitiator<vci_param> p_vci_ini_c; … … 241 227 const soclib::common::AddressDecodingTable<vci_addr_t, bool> m_cacheability_table; 242 228 const soclib::common::Segment m_segment; 243 iss_t m_iss;229 iss_t ** m_iss; //[m_nb_cpu] 244 230 const uint32_t m_srcid_rw; 245 231 const uint32_t m_srcid_c; 246 232 247 const size_t m_dcache_ways; 248 const size_t m_dcache_words; 249 const uint32_t m_dcache_words_shift; 250 const size_t m_dcache_yzmask; 251 const size_t m_icache_ways; 252 const size_t m_icache_words; 253 const uint32_t m_icache_words_shift; 254 const size_t m_icache_yzmask; 255 const size_t m_cache_words; // max between m_dcache_words and m_icache_words 233 const size_t m_nb_cpu; 234 const size_t m_nb_icache; 235 const size_t m_nb_dcache; 236 const size_t m_nb_cache; 237 const size_t m_dcache_ways; 238 const size_t m_dcache_words; 239 const uint32_t m_dcache_words_shift; 240 const size_t m_dcache_yzmask; 241 const size_t m_icache_ways; 242 const size_t m_icache_words; 243 const uint32_t m_icache_words_shift; 244 const size_t m_icache_yzmask; 245 const write_policy_t m_write_policy; 246 const size_t m_cache_words; // max between m_dcache_words and m_icache_words 256 247 257 248 #if CC_XCACHE_WRAPPER_STOP_SIMULATION 258 249 bool m_stop_simulation; 259 250 uint32_t m_stop_simulation_nb_frz_cycles_max; 260 uint32_t m_stop_simulation_nb_frz_cycles;251 uint32_t * m_stop_simulation_nb_frz_cycles; //[m_nb_cpu] 261 252 #endif // CC_XCACHE_WRAPPER_STOP_SIMULATION 262 253 263 254 // REGISTERS 264 sc_signal<int> r_dcache_fsm; 265 sc_signal<int> r_dcache_fsm_save; 266 sc_signal<addr_40> r_dcache_addr_save; 267 sc_signal<data_t> r_dcache_wdata_save; 268 sc_signal<data_t> r_dcache_rdata_save; 269 sc_signal<int> r_dcache_type_save; 270 sc_signal<be_t> r_dcache_be_save; 271 sc_signal<bool> r_dcache_cached_save; 272 sc_signal<bool> r_dcache_cleanup_req; 273 sc_signal<addr_40> r_dcache_cleanup_line; 274 sc_signal<bool> r_dcache_miss_req; 275 sc_signal<size_t> r_dcache_miss_way; 276 sc_signal<size_t> r_dcache_miss_set; 277 sc_signal<bool> r_dcache_unc_req; 278 sc_signal<bool> r_dcache_sc_req; 279 sc_signal<bool> r_dcache_inval_rsp; 280 sc_signal<size_t> r_dcache_update_addr; 281 sc_signal<data_64> r_dcache_ll_data; 282 sc_signal<addr_40> r_dcache_ll_addr; 283 sc_signal<bool> r_dcache_ll_valid; 284 sc_signal<bool> r_dcache_previous_unc; 285 286 sc_signal<int> r_icache_fsm; 287 sc_signal<int> r_icache_fsm_save; 288 sc_signal<addr_40> r_icache_addr_save; 289 sc_signal<bool> r_icache_miss_req; 290 sc_signal<size_t> r_icache_miss_way; 291 sc_signal<size_t> r_icache_miss_set; 292 sc_signal<bool> r_icache_unc_req; 293 sc_signal<bool> r_icache_cleanup_req; 294 sc_signal<addr_40> r_icache_cleanup_line; 295 sc_signal<bool> r_icache_inval_rsp; 296 sc_signal<size_t> r_icache_update_addr; 255 sc_signal<uint32_t> r_cpu_prior; 256 sc_signal<uint32_t> * r_icache_lock;//[m_nb_icache] 257 sc_signal<uint32_t> * r_dcache_lock;//[m_nb_dcache] 258 sc_signal<bool> * r_dcache_sync;//[m_nb_dcache] 259 260 sc_signal<int> * r_dcache_fsm; //[m_nb_dcache] 261 sc_signal<int> * r_dcache_fsm_save; //[m_nb_dcache] 262 sc_signal<addr_40> * r_dcache_addr_save; //[m_nb_dcache] 263 sc_signal<data_t> * r_dcache_wdata_save; //[m_nb_dcache] 264 sc_signal<data_t> * r_dcache_rdata_save; //[m_nb_dcache] 265 sc_signal<int> * r_dcache_type_save; //[m_nb_dcache] 266 sc_signal<be_t> * r_dcache_be_save; //[m_nb_dcache] 267 sc_signal<bool> * r_dcache_cached_save; //[m_nb_dcache] 268 sc_signal<uint32_t> * r_dcache_num_cpu_save; //[m_nb_dcache] 269 sc_signal<bool> * r_dcache_cleanup_req; //[m_nb_dcache] 270 sc_signal<addr_40> * r_dcache_cleanup_line; //[m_nb_dcache] 271 sc_signal<bool> * r_dcache_miss_req; //[m_nb_dcache] 272 sc_signal<size_t> * r_dcache_miss_way; //[m_nb_dcache] 273 sc_signal<size_t> * r_dcache_miss_set; //[m_nb_dcache] 274 sc_signal<bool> * r_dcache_unc_req; //[m_nb_dcache] 275 sc_signal<bool> * r_dcache_sc_req; //[m_nb_dcache] 276 sc_signal<bool> * r_dcache_inval_rsp; //[m_nb_dcache] 277 sc_signal<size_t> * r_dcache_update_addr; //[m_nb_dcache] 278 sc_signal<data_t> ** r_dcache_ll_data; //[m_nb_dcache][m_nb_cpu] 279 sc_signal<addr_40> ** r_dcache_ll_addr; //[m_nb_dcache][m_nb_cpu] 280 sc_signal<bool> ** r_dcache_ll_valid; //[m_nb_dcache][m_nb_cpu] 281 sc_signal<bool> * r_dcache_previous_unc; //[m_nb_dcache] 282 283 sc_signal<int> * r_icache_fsm; //[m_nb_icache] 284 sc_signal<int> * r_icache_fsm_save; //[m_nb_icache] 285 sc_signal<addr_40> * r_icache_addr_save; //[m_nb_icache] 286 sc_signal<bool> * r_icache_miss_req; //[m_nb_icache] 287 sc_signal<size_t> * r_icache_miss_way; //[m_nb_icache] 288 sc_signal<size_t> * r_icache_miss_set; //[m_nb_icache] 289 sc_signal<bool> * r_icache_unc_req; //[m_nb_icache] 290 sc_signal<bool> * r_icache_cleanup_req; //[m_nb_icache] 291 sc_signal<addr_40> * r_icache_cleanup_line; //[m_nb_icache] 292 sc_signal<bool> * r_icache_inval_rsp; //[m_nb_icache] 293 sc_signal<size_t> * r_icache_update_addr; //[m_nb_icache] 294 sc_signal<bool> * r_icache_buf_unc_valid;//[m_nb_icache] 297 295 298 296 sc_signal<int> r_vci_cmd_fsm; … … 301 299 sc_signal<size_t> r_vci_cmd_cpt; 302 300 sc_signal<bool> r_vci_cmd_dcache_prior; 303 301 sc_signal<uint32_t> r_vci_cmd_num_icache_prior; 302 sc_signal<uint32_t> r_vci_cmd_num_dcache_prior; 303 sc_signal<uint32_t> r_vci_cmd_num_cache; 304 304 305 sc_signal<int> r_vci_rsp_fsm; 305 sc_signal<bool> r_vci_rsp_ins_error;306 sc_signal<bool> r_vci_rsp_data_error;307 306 sc_signal<size_t> r_vci_rsp_cpt; 308 sc_signal<bool> r_vci_rsp_ack; 309 310 #if CC_XCACHE_WRAPPER_FIFO_RSP 311 std::queue<data_t> r_icache_miss_buf; 312 std::queue<data_t> r_dcache_miss_buf; 313 #else 314 bool *r_icache_miss_val; //[m_icache_words] 315 data_t *r_icache_miss_buf; //[m_icache_words] 316 bool *r_dcache_miss_val; //[m_dcache_words] 317 data_t *r_dcache_miss_buf; //[m_dcache_words] 318 #endif 319 sc_signal<bool> r_icache_buf_unc_valid; 320 321 data_t *r_tgt_buf; //[m_cache_words] 322 be_t *r_tgt_be; //[m_cache_words] 323 #if CC_XCACHE_WRAPPER_CC_UPDATE_MULTI_CYCLE 307 sc_signal<uint32_t> r_vci_rsp_num_cache; 308 sc_signal<bool> * r_vci_rsp_ins_error; //[m_nb_icache] 309 sc_signal<bool> * r_vci_rsp_data_error; //[m_nb_dcache] 310 311 GenericFifo<data_t> r_vci_rsp_fifo_icache_data; 312 GenericFifo<uint32_t> r_vci_rsp_fifo_icache_num_cache; 313 GenericFifo<data_t> r_vci_rsp_fifo_dcache_data; 314 GenericFifo<uint32_t> r_vci_rsp_fifo_dcache_num_cache; 315 316 data_t * r_tgt_buf; //[m_cache_words] 317 be_t * r_tgt_be; //[m_cache_words] 324 318 sc_signal<uint32_t> r_cache_word; 325 #endif326 319 327 320 sc_signal<int> r_vci_tgt_fsm; 328 sc_signal<addr_40> r_tgt_addr; 321 sc_signal<addr_40> r_tgt_iaddr; 322 sc_signal<addr_40> r_tgt_daddr; 329 323 sc_signal<size_t> r_tgt_word; 330 324 sc_signal<bool> r_tgt_update; … … 335 329 sc_signal<size_t> r_tgt_trdid; 336 330 //sc_signal<size_t> r_tgt_plen; 337 sc_signal<bool> r_tgt_icache_req; 338 sc_signal<bool> r_tgt_dcache_req; 339 sc_signal<bool> r_tgt_icache_rsp; 340 sc_signal<bool> r_tgt_dcache_rsp; 331 sc_signal<uint32_t> r_tgt_num_cache; 332 sc_signal<bool> * r_tgt_icache_req; //[m_nb_icache] 333 sc_signal<bool> * r_tgt_icache_rsp; //[m_nb_icache] 334 sc_signal<bool> * r_tgt_dcache_req; //[m_nb_dcache] 335 sc_signal<bool> * r_tgt_dcache_rsp; //[m_nb_dcache] 341 336 342 337 sc_signal<int> r_cleanup_fsm; // controls initiator port of the coherence network 343 344 MultiWriteBuffer<addr_40> r_wbuf; 345 GenericCache<vci_addr_t> r_icache; 346 GenericCache<vci_addr_t> r_dcache; 347 348 #if CC_XCACHE_WRAPPER_DEBUG_DCACHE_TRANSACTION 349 std::ofstream log_dcache_transaction_file; 338 sc_signal<uint32_t> r_cleanup_num_cache; 339 sc_signal<bool> r_cleanup_icache; 340 341 MultiWriteBuffer<addr_40>** r_wbuf; 342 GenericCache<vci_addr_t> ** r_icache; 343 GenericCache<vci_addr_t> ** r_dcache; 344 345 #if CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION 346 bool generate_log_transaction_file_icache; 347 bool generate_log_transaction_file_dcache; 348 bool generate_log_transaction_file_cmd; 349 bool generate_log_transaction_file_tgt; 350 bool generate_log_transaction_file_cleanup; 351 352 std::ofstream * log_transaction_file_icache; //[m_nb_cpu] 353 std::ofstream * log_transaction_file_dcache; //[m_nb_cpu] 354 std::ofstream log_transaction_file_cmd; 355 std::ofstream log_transaction_file_tgt; 356 std::ofstream log_transaction_file_cleanup; 357 #endif 358 359 #if MWBUF_VHDL_TESTBENCH 360 bool simulation_started; 361 bool generate_vhdl_testbench_mwbuf; 362 std::ofstream * vhdl_testbench_mwbuf; //[m_nb_dcache] 350 363 #endif 351 364 352 365 // Activity counters 353 uint32_t m_cpt_dcache_data_read; // * DCACHE DATA READ 354 uint32_t m_cpt_dcache_data_write; // * DCACHE DATA WRITE 355 uint32_t m_cpt_dcache_dir_read; // * DCACHE DIR READ 356 uint32_t m_cpt_dcache_dir_write; // * DCACHE DIR WRITE 357 358 uint32_t m_cpt_icache_data_read; // * ICACHE DATA READ 359 uint32_t m_cpt_icache_data_write; // * ICACHE DATA WRITE 360 uint32_t m_cpt_icache_dir_read; // * ICACHE DIR READ 361 uint32_t m_cpt_icache_dir_write; // * ICACHE DIR WRITE 362 363 uint32_t m_cpt_cc_update_icache; // number of coherence update packets (for icache) 364 uint32_t m_cpt_cc_update_dcache; // number of coherence update packets (for dcache) 365 uint32_t m_cpt_cc_inval_broadcast; // number of coherence inval packets 366 uint32_t m_cpt_cc_inval_icache; // number of coherence inval packets 367 uint32_t m_cpt_cc_inval_dcache; // number of coherence inval packets 368 uint32_t m_cpt_cc_update_icache_word_useful; // number of valid word in coherence update packets 369 uint32_t m_cpt_cc_update_dcache_word_useful; // number of valid word in coherence update packets 370 371 uint32_t m_cpt_frz_cycles; // * number of cycles where the cpu is frozen 372 uint32_t m_cpt_total_cycles; // total number of cycles 373 374 uint32_t m_cpt_data_read; // number of data read 375 uint32_t m_cpt_data_read_miss; // number of data read miss 376 uint32_t m_cpt_data_read_uncached; // number of data read uncached 377 uint32_t m_cpt_data_write; // number of data write 378 uint32_t m_cpt_data_write_miss; // number of data write miss 379 uint32_t m_cpt_data_write_uncached; // number of data write uncached 380 uint32_t m_cpt_ins_miss; // * number of instruction miss 381 382 uint32_t m_cost_write_frz; // * number of frozen cycles related to write buffer 383 uint32_t m_cost_data_miss_frz; // * number of frozen cycles related to data miss 384 uint32_t m_cost_unc_read_frz; // * number of frozen cycles related to uncached read 385 uint32_t m_cost_ins_miss_frz; // * number of frozen cycles related to ins miss 386 387 uint32_t m_cpt_imiss_transaction; // * number of VCI instruction miss transactions 388 uint32_t m_cpt_dmiss_transaction; // * number of VCI data miss transactions 389 uint32_t m_cpt_unc_transaction; // * number of VCI uncached read transactions 390 uint32_t m_cpt_data_write_transaction; // * number of VCI write transactions 391 392 uint32_t m_cost_imiss_transaction; // * cumulated duration for VCI IMISS transactions 393 uint32_t m_cost_dmiss_transaction; // * cumulated duration for VCI DMISS transactions 394 uint32_t m_cost_unc_transaction; // * cumulated duration for VCI UNC transactions 395 uint32_t m_cost_write_transaction; // * cumulated duration for VCI WRITE transactions 396 uint32_t m_length_write_transaction; // * cumulated length for VCI WRITE transactions 366 uint32_t m_cpt_dcache_data_read; // * DCACHE DATA READ 367 uint32_t m_cpt_dcache_data_write; // * DCACHE DATA WRITE 368 uint32_t m_cpt_dcache_dir_read; // * DCACHE DIR READ 369 uint32_t m_cpt_dcache_dir_write; // * DCACHE DIR WRITE 370 371 uint32_t m_cpt_icache_data_read; // * ICACHE DATA READ 372 uint32_t m_cpt_icache_data_write; // * ICACHE DATA WRITE 373 uint32_t m_cpt_icache_dir_read; // * ICACHE DIR READ 374 uint32_t m_cpt_icache_dir_write; // * ICACHE DIR WRITE 375 376 uint32_t m_cpt_cc_update_icache; // number of coherence update packets (for icache) 377 uint32_t m_cpt_cc_update_dcache; // number of coherence update packets (for dcache) 378 uint32_t m_cpt_cc_inval_broadcast; // number of coherence inval packets 379 uint32_t m_cpt_cc_inval_icache; // number of coherence inval packets 380 uint32_t m_cpt_cc_inval_dcache; // number of coherence inval packets 381 uint32_t m_cpt_cc_update_icache_word_useful; // number of valid word in coherence update packets 382 uint32_t m_cpt_cc_update_dcache_word_useful; // number of valid word in coherence update packets 383 384 uint32_t * m_cpt_frz_cycles; // * number of cycles where the cpu is frozen 385 uint32_t m_cpt_total_cycles; // total number of cycles 386 387 uint32_t m_cpt_data_read; // number of data read 388 uint32_t m_cpt_data_read_miss; // number of data read miss 389 uint32_t m_cpt_data_read_uncached; // number of data read uncached 390 uint32_t m_cpt_data_write; // number of data write 391 uint32_t m_cpt_data_write_miss; // number of data write miss 392 uint32_t m_cpt_data_write_uncached; // number of data write uncached 393 uint32_t m_cpt_ins_miss; // * number of instruction miss 394 395 uint32_t m_cost_write_frz; // * number of frozen cycles related to write buffer 396 uint32_t m_cost_data_miss_frz; // * number of frozen cycles related to data miss 397 uint32_t m_cost_unc_read_frz; // * number of frozen cycles related to uncached read 398 uint32_t m_cost_ins_miss_frz; // * number of frozen cycles related to ins miss 399 400 uint32_t m_cpt_imiss_transaction; // * number of VCI instruction miss transactions 401 uint32_t m_cpt_dmiss_transaction; // * number of VCI data miss transactions 402 uint32_t m_cpt_unc_transaction; // * number of VCI uncached read transactions 403 uint32_t m_cpt_data_write_transaction; // * number of VCI write transactions 404 405 uint32_t m_cost_imiss_transaction; // * cumulated duration for VCI IMISS transactions 406 uint32_t m_cost_dmiss_transaction; // * cumulated duration for VCI DMISS transactions 407 uint32_t m_cost_unc_transaction; // * cumulated duration for VCI UNC transactions 408 uint32_t m_cost_write_transaction; // * cumulated duration for VCI WRITE transactions 409 uint32_t m_length_write_transaction; // * cumulated length for VCI WRITE transactions 410 411 uint32_t * m_cpt_icache_access; //[m_nb_icache] 412 uint32_t * m_cpt_dcache_access; //[m_nb_dcache] 413 uint32_t * m_cpt_dcache_hit_after_miss_read; //[m_nb_dcache] 414 uint32_t * m_cpt_dcache_hit_after_miss_write; //[m_nb_dcache] 415 uint32_t * m_cpt_dcache_store_after_store; //[m_nb_dcache] 416 uint32_t * m_cpt_icache_miss_victim_wait; //[m_nb_icache] 417 uint32_t * m_cpt_dcache_miss_victim_wait; //[m_nb_dcache] 418 419 uint32_t ** m_cpt_fsm_dcache; //[m_nb_dcache] 420 uint32_t ** m_cpt_fsm_icache; //[m_nb_icache] 421 uint32_t * m_cpt_fsm_cmd; 422 uint32_t * m_cpt_fsm_rsp; 423 uint32_t * m_cpt_fsm_tgt; 424 uint32_t * m_cpt_fsm_cleanup; 425 426 // Non blocking multi-cache 427 typename iss_t::InstructionRequest * ireq ; //[m_nb_icache] 428 typename iss_t::InstructionResponse * irsp ; //[m_nb_icache] 429 bool * ireq_cached ; //[m_nb_icache] 430 uint32_t * ireq_num_cpu; //[m_nb_dcache] 431 typename iss_t::DataRequest * dreq ; //[m_nb_dcache] 432 typename iss_t::DataResponse * drsp ; //[m_nb_dcache] 433 bool * dreq_cached ; //[m_nb_dcache] 434 uint32_t * dreq_num_cpu; //[m_nb_dcache] 435 436 const uint32_t m_num_cache_LSB; 437 const uint32_t m_num_cache_MSB; 438 addr_40 m_num_cache_LSB_mask; 439 addr_40 m_num_cache_mask; 397 440 398 441 protected: … … 409 452 const soclib::common::IntTab &initiator_index_c, 410 453 const soclib::common::IntTab &target_index, 454 size_t nb_cpu, 455 size_t nb_dcache, 411 456 size_t icache_ways, 412 457 size_t icache_sets, … … 417 462 size_t wbuf_nwords, 418 463 size_t wbuf_nlines, 419 size_t wbuf_timeout 464 size_t wbuf_timeout, 465 write_policy_t write_policy=WRITE_THROUGH 420 466 ); 421 467 422 468 ~VciCcXCacheWrapperV4(); 423 469 424 void print_trace(size_t mode = 0); 425 void print_cpi(); 426 void print_stats(); 427 428 // #if CC_XCACHE_WRAPPER_STOP_SIMULATION 429 void stop_simulation (uint32_t); 430 // #endif // CC_XCACHE_WRAPPER_STOP_SIMULATION 470 void print_trace(size_t mode = 0); 471 void print_cpi(); 472 void print_stats(bool print_wbuf=true, bool print_fsm=true); 473 474 void stop_simulation (uint32_t); 475 void log_transaction ( bool generate_file_icache 476 ,bool generate_file_dcache 477 ,bool generate_file_cmd 478 ,bool generate_file_tgt 479 ,bool generate_file_cleanup); 480 481 void vhdl_testbench (bool generate_file_mwbuf); 431 482 432 483 private: … … 435 486 void genMoore(); 436 487 437 soclib_static_assert((int)iss_t::SC_ATOMIC == (int)vci_param::STORE_COND_ATOMIC); 488 uint32_t get_num_cache (addr_40 & addr); 489 uint32_t get_num_cache_only(addr_40 addr); 490 void set_num_cache (addr_40 & addr, uint32_t num_cache); 491 addr_40 set_num_cache_only(addr_40 addr, uint32_t num_cache); 492 493 soclib_static_assert((int)iss_t::SC_ATOMIC == (int)vci_param::STORE_COND_ATOMIC); 438 494 soclib_static_assert((int)iss_t::SC_NOT_ATOMIC == (int)vci_param::STORE_COND_NOT_ATOMIC); 439 495 }; -
trunk/modules/vci_cc_xcache_wrapper_v4/caba/source/src/vci_cc_xcache_wrapper_v4.cpp
r161 r165 55 55 /////////////////////////////////////////////////////////////////////////////// 56 56 57 #include <cassert>58 57 #include <iomanip> 59 58 #include "arithmetics.h" 59 #include "size.h" 60 60 #include "../include/vci_cc_xcache_wrapper_v4.h" 61 namespace soclib { 62 namespace caba { 63 namespace { 64 65 // =====[ DEBUG ]==================================== 66 67 #define ASSERT_VERBOSE 68 #define ASSERT_NCYCLES m_cpt_total_cycles 69 70 #include "debug.h" 61 71 62 72 #if CC_XCACHE_WRAPPER_DEBUG 63 # define PRINTF(msg...) do { if (m_cpt_total_cycles>=CC_XCACHE_WRAPPER_DEBUG_CYCLE_MIN) printf(msg); } while (0);73 # define PRINTF(msg...) PRINTF_COND(m_cpt_total_cycles>=CC_XCACHE_WRAPPER_DEBUG_CYCLE_MIN,msg) 64 74 #else 65 75 # define PRINTF(msg...) 66 76 #endif 67 77 68 # define ASSERT(cond,msg) assert ((cond) and msg); 69 70 #if CC_XCACHE_WRAPPER_FIFO_RSP 71 # define CACHE_MISS_BUF_ALLOC 72 # define CACHE_MISS_BUF_DEALLOC 73 # define CACHE_MISS_BUF_RESET(c) while (r_##c##cache_miss_buf.size()>0) {r_##c##cache_miss_buf.pop();} 74 # define CACHE_MISS_BUF_REQ_INIT(c) 75 # define CACHE_MISS_BUF_RSP_VAL(c,n) (r_##c##cache_miss_buf.size()>0) 76 # define CACHE_MISS_BUF_RSP_ACK(c) (r_##c##cache_miss_buf.size()<2) 77 # define CACHE_MISS_BUF_RSP_DATA(c,n) r_##c##cache_miss_buf.front() 78 # define CACHE_MISS_BUF_RSP_POP(c) do { r_##c##cache_miss_buf.pop();} while (0) 79 # define CACHE_MISS_BUF_RSP_PUSH(c,n,d) do { r_##c##cache_miss_buf.push(d);} while (0) 80 # define CACHE_MISS_BUF_RSP_PRINT(c) do { PRINTF(" * cache_miss_buf - size : %d\n",r_##c##cache_miss_buf.size());} while (0) 78 ///////////////////////////////////////////////////////////////////// 79 // Management of address stocked in icache/dcache/mwbuf in case 80 // of multiple bank implementation 81 ///////////////////////////////////////////////////////////////////// 82 83 // =====[ MULTI_CACHE ]============================== 84 85 #if (CC_XCACHE_WRAPPER_MULTI_CACHE==1) 86 # define get_num_icache( addr,num_cpu) get_num_cache (addr) 87 # define get_num_icache_only(addr,num_cpu) get_num_cache_only(addr) 88 # define set_num_icache( addr,num_cache) set_num_cache (addr,num_cache) 89 # define set_num_icache_only(addr,num_cache) set_num_cache_only(addr,num_cache) 90 # define get_num_dcache( addr) get_num_cache (addr) 91 # define get_num_dcache_only(addr) get_num_cache_only(addr) 92 # define set_num_dcache( addr,num_cache) set_num_cache (addr,num_cache) 93 # define set_num_dcache_only(addr,num_cache) set_num_cache_only(addr,num_cache) 94 #elif (CC_XCACHE_WRAPPER_MULTI_CACHE==2) 95 # define get_num_icache( addr,num_cpu) num_cpu 96 # define get_num_icache_only(addr,num_cpu) num_cpu 97 # define set_num_icache( addr,num_cache) do {} while (0) 98 # define set_num_icache_only(addr,num_cache) addr 99 # define get_num_dcache( addr) get_num_cache (addr) 100 # define get_num_dcache_only(addr) get_num_cache_only(addr) 101 # define set_num_dcache( addr,num_cache) set_num_cache (addr,num_cache) 102 # define set_num_dcache_only(addr,num_cache) set_num_cache_only(addr,num_cache) 81 103 #else 82 # define CACHE_MISS_BUF_ALLOC do { \ 83 r_icache_miss_val = new bool [m_icache_words]; \ 84 r_icache_miss_buf = new data_t[m_icache_words]; \ 85 r_dcache_miss_val = new bool [m_dcache_words]; \ 86 r_dcache_miss_buf = new data_t[m_dcache_words]; \ 87 } while (0) 88 # define CACHE_MISS_BUF_DEALLOC do { \ 89 delete [] r_icache_miss_val; \ 90 delete [] r_icache_miss_buf; \ 91 delete [] r_dcache_miss_val; \ 92 delete [] r_dcache_miss_buf; \ 93 } while (0) 94 # define CACHE_MISS_BUF_RESET(c) 95 # define CACHE_MISS_BUF_REQ_INIT(c) do {for (uint32_t i=0; i<m_##c##cache_words;++i) r_##c##cache_miss_val[i] = false;} while (0) 96 # define CACHE_MISS_BUF_RSP_VAL(c,n) r_##c##cache_miss_val[n] 97 # define CACHE_MISS_BUF_RSP_ACK(c) true 98 # define CACHE_MISS_BUF_RSP_DATA(c,n) r_##c##cache_miss_buf[n] 99 # define CACHE_MISS_BUF_RSP_POP(c) 100 # define CACHE_MISS_BUF_RSP_PUSH(c,n,d) do {r_##c##cache_miss_val[n] = true; r_##c##cache_miss_buf[n] = d;} while (0) 101 # define CACHE_MISS_BUF_RSP_PRINT(c) do {for (uint32_t i=0; i<m_##c##cache_words;++i) PRINTF("%d %x |",r_##c##cache_miss_val[i],r_##c##cache_miss_buf[i]); PRINTF("\n");} while (0) 104 #error "Invalid value to CC_XCACHE_WRAPPER_MULTI_CACHE" 102 105 #endif 103 106 104 namespace soclib { 105 namespace caba { 106 namespace { 107 108 const char *dcache_fsm_state_str[] = { 109 "DCACHE_IDLE", 110 "DCACHE_WRITE_UPDT", 111 #if CC_XCACHE_WRAPPER_SELECT_VICTIM 112 "DCACHE_MISS_VICTIM", 113 #endif 114 "DCACHE_MISS_WAIT", 115 "DCACHE_MISS_UPDT", 116 "DCACHE_UNC_WAIT", 117 "DCACHE_SC_WAIT", 118 "DCACHE_INVAL", 119 "DCACHE_SYNC", 120 "DCACHE_ERROR", 121 "DCACHE_CC_CHECK", 122 "DCACHE_CC_INVAL", 123 "DCACHE_CC_UPDT", 124 "DCACHE_CC_CLEANUP", 125 }; 126 const char *icache_fsm_state_str[] = { 127 "ICACHE_IDLE", 128 #if CC_XCACHE_WRAPPER_SELECT_VICTIM 129 "ICACHE_MISS_VICTIM", 130 #endif 131 "ICACHE_MISS_WAIT", 132 "ICACHE_MISS_UPDT", 133 "ICACHE_UNC_WAIT", 134 "ICACHE_ERROR", 135 "ICACHE_CC_CLEANUP", 136 "ICACHE_CC_CHECK", 137 "ICACHE_CC_INVAL", 138 "ICACHE_CC_UPDT", 139 }; 140 const char *cmd_fsm_state_str[] = { 141 "CMD_IDLE", 142 "CMD_INS_MISS", 143 "CMD_INS_UNC", 144 "CMD_DATA_MISS", 145 "CMD_DATA_UNC", 146 "CMD_DATA_WRITE", 147 "CMD_DATA_SC", 148 }; 149 const char *rsp_fsm_state_str[] = { 150 "RSP_IDLE", 151 "RSP_INS_MISS", 152 "RSP_INS_UNC", 153 "RSP_DATA_MISS", 154 "RSP_DATA_UNC", 155 "RSP_DATA_WRITE", 156 "RSP_DATA_SC", 157 }; 158 const char *tgt_fsm_state_str[] = { 159 "TGT_IDLE", 160 "TGT_UPDT_WORD", 161 "TGT_UPDT_DATA", 162 "TGT_REQ_BROADCAST", 163 "TGT_REQ_ICACHE", 164 "TGT_REQ_DCACHE", 165 "TGT_RSP_BROADCAST", 166 "TGT_RSP_ICACHE", 167 "TGT_RSP_DCACHE", 168 }; 169 170 const char *cleanup_fsm_state_str[] = { 171 "CLEANUP_IDLE", 172 "CLEANUP_DCACHE", 173 "CLEANUP_ICACHE", 174 }; 107 const char *dcache_fsm_state_str[] = { 108 "DCACHE_IDLE", 109 "DCACHE_WRITE_UPDT", 110 "DCACHE_MISS_VICTIM", 111 "DCACHE_MISS_WAIT", 112 "DCACHE_MISS_UPDT", 113 "DCACHE_UNC_WAIT", 114 "DCACHE_SC_WAIT", 115 "DCACHE_INVAL", 116 "DCACHE_SYNC", 117 "DCACHE_ERROR", 118 "DCACHE_CC_CHECK", 119 "DCACHE_CC_INVAL", 120 "DCACHE_CC_UPDT", 121 "DCACHE_CC_CLEANUP", 122 }; 123 const char *icache_fsm_state_str[] = { 124 "ICACHE_IDLE", 125 "ICACHE_MISS_VICTIM", 126 "ICACHE_MISS_WAIT", 127 "ICACHE_MISS_UPDT", 128 "ICACHE_UNC_WAIT", 129 "ICACHE_ERROR", 130 "ICACHE_CC_CLEANUP", 131 "ICACHE_CC_CHECK", 132 "ICACHE_CC_INVAL", 133 "ICACHE_CC_UPDT", 134 }; 135 const char *cmd_fsm_state_str[] = { 136 "CMD_IDLE", 137 "CMD_INS_MISS", 138 "CMD_INS_UNC", 139 "CMD_DATA_MISS", 140 "CMD_DATA_UNC", 141 "CMD_DATA_WRITE", 142 "CMD_DATA_SC", 143 }; 144 const char *rsp_fsm_state_str[] = { 145 "RSP_IDLE", 146 "RSP_INS_MISS", 147 "RSP_INS_UNC", 148 "RSP_DATA_MISS", 149 "RSP_DATA_UNC", 150 "RSP_DATA_WRITE", 151 "RSP_DATA_SC", 152 }; 153 const char *tgt_fsm_state_str[] = { 154 "TGT_IDLE", 155 "TGT_UPDT_WORD", 156 "TGT_UPDT_DATA", 157 "TGT_REQ_BROADCAST", 158 "TGT_REQ_ICACHE", 159 "TGT_REQ_DCACHE", 160 "TGT_RSP_BROADCAST", 161 "TGT_RSP_ICACHE", 162 "TGT_RSP_DCACHE", 163 }; 164 165 const char *cleanup_fsm_state_str[] = { 166 "CLEANUP_IDLE", 167 "CLEANUP_REQ", 168 "CLEANUP_RSP_DCACHE", 169 "CLEANUP_RSP_ICACHE", 170 }; 175 171 } 172 173 typedef long long unsigned int blob_t; 176 174 177 175 #define tmpl(...) template<typename vci_param, typename iss_t> __VA_ARGS__ VciCcXCacheWrapperV4<vci_param, iss_t> … … 181 179 ///////////////////////////////// 182 180 tmpl(/**/)::VciCcXCacheWrapperV4( 183 ///////////////////////////////// 184 sc_module_name name, 185 int proc_id, 186 const soclib::common::MappingTable &mtp, 187 const soclib::common::MappingTable &mtc, 188 const soclib::common::IntTab &initiator_index_rw, 189 const soclib::common::IntTab &initiator_index_c, 190 const soclib::common::IntTab &target_index, 191 size_t icache_ways, 192 size_t icache_sets, 193 size_t icache_words, 194 size_t dcache_ways, 195 size_t dcache_sets, 196 size_t dcache_words, 197 size_t wbuf_nwords, 198 size_t wbuf_nlines, 199 size_t wbuf_timeout 181 ///////////////////////////////// 182 sc_module_name name, 183 int proc_id, 184 const soclib::common::MappingTable &mtp, 185 const soclib::common::MappingTable &mtc, 186 const soclib::common::IntTab &initiator_index_rw, 187 const soclib::common::IntTab &initiator_index_c, 188 const soclib::common::IntTab &target_index, 189 size_t nb_cpu, 190 size_t nb_dcache, 191 size_t icache_ways, 192 size_t icache_sets, 193 size_t icache_words, 194 size_t dcache_ways, 195 size_t dcache_sets, 196 size_t dcache_words, 197 size_t wbuf_nwords, 198 size_t wbuf_nlines, 199 size_t wbuf_timeout, 200 write_policy_t write_policy 200 201 ) 201 : 202 soclib::caba::BaseModule(name), 203 204 p_clk ("clk"), 205 p_resetn ("resetn"), 206 p_vci_ini_rw("vci_ini_rw"), 207 p_vci_ini_c ("vci_ini_c"), 208 p_vci_tgt ("vci_tgt"), 209 210 m_cacheability_table(mtp.getCacheabilityTable<vci_addr_t>()), 211 m_segment(mtc.getSegment(target_index)), 212 m_iss(this->name(), proc_id), 213 m_srcid_rw(mtp.indexForId(initiator_index_rw)), 214 m_srcid_c(mtc.indexForId(initiator_index_c)), 215 216 m_dcache_ways(dcache_ways), 217 m_dcache_words(dcache_words), 218 m_dcache_words_shift(uint32_log2(dcache_words)+2), 219 m_dcache_yzmask((~0)<<m_dcache_words_shift), 220 m_icache_ways(icache_ways), 221 m_icache_words(icache_words), 222 m_icache_words_shift(uint32_log2(icache_words)+2), 223 m_icache_yzmask((~0)<<m_icache_words_shift), 224 m_cache_words((dcache_words)?dcache_words:icache_words), 225 226 r_dcache_fsm("r_dcache_fsm"), 227 r_dcache_fsm_save("r_dcache_fsm_save"), 228 r_dcache_addr_save("r_dcache_addr_save"), 229 r_dcache_wdata_save("r_dcache_wdata_save"), 230 r_dcache_rdata_save("r_dcache_rdata_save"), 231 r_dcache_type_save("r_dcache_type_save"), 232 r_dcache_be_save("r_dcache_be_save"), 233 r_dcache_cached_save("r_dcache_cached_save"), 234 r_dcache_cleanup_req("r_dcache_cleanup_req"), 235 r_dcache_cleanup_line("r_dcache_cleanup_line"), 236 r_dcache_miss_req("r_dcache_miss_req"), 237 r_dcache_miss_way("r_dcache_miss_way"), 238 r_dcache_miss_set("r_dcache_miss_set"), 239 r_dcache_unc_req("r_dcache_unc_req"), 240 r_dcache_sc_req("r_dcache_sc_req"), 241 r_dcache_inval_rsp("r_dcache_inval_rsp"), 242 r_dcache_update_addr("r_dcache_update_addr"), 243 r_dcache_ll_data("r_dcache_ll_data"), 244 r_dcache_ll_addr("r_dcache_ll_addr"), 245 r_dcache_ll_valid("r_dcache_ll_valid"), 246 r_dcache_previous_unc("r_dcache_previous_unc"), 247 248 r_icache_fsm("r_icache_fsm"), 249 r_icache_fsm_save("r_icache_fsm_save"), 250 r_icache_addr_save("r_icache_addr_save"), 251 r_icache_miss_req("r_icache_miss_req"), 252 r_icache_miss_way("r_icache_miss_way"), 253 r_icache_miss_set("r_icache_miss_set"), 254 r_icache_unc_req("r_icache_unc_req"), 255 r_icache_cleanup_req("r_icache_cleanup_req"), 256 r_icache_cleanup_line("r_icache_cleanup_line"), 257 r_icache_inval_rsp("r_icache_inval_rsp"), 258 r_icache_update_addr("r_icache_update_addr"), 259 260 r_vci_cmd_fsm("r_vci_cmd_fsm"), 261 r_vci_cmd_min("r_vci_cmd_min"), 262 r_vci_cmd_max("r_vci_cmd_max"), 263 r_vci_cmd_cpt("r_vci_cmd_cpt"), 264 r_vci_cmd_dcache_prior("r_vci_cmd_dcache_prior"), 265 266 r_vci_rsp_fsm("r_vci_rsp_fsm"), 267 r_vci_rsp_ins_error("r_vci_rsp_ins_error"), 268 r_vci_rsp_data_error("r_vci_rsp_data_error"), 269 r_vci_rsp_cpt("r_vci_rsp_cpt"), 270 r_vci_rsp_ack("r_vci_rsp_ack"), 271 272 r_icache_buf_unc_valid("r_icache_buf_unc_valid"), 273 274 #if CC_XCACHE_WRAPPER_CC_UPDATE_MULTI_CYCLE 275 r_cache_word("r_cache_word"), 202 : 203 soclib::caba::BaseModule(name), 204 205 p_clk ("clk"), 206 p_resetn ("resetn"), 207 p_vci_ini_rw("vci_ini_rw"), 208 p_vci_ini_c ("vci_ini_c"), 209 p_vci_tgt ("vci_tgt"), 210 211 m_cacheability_table(mtp.getCacheabilityTable<vci_addr_t>()), 212 m_segment(mtc.getSegment(target_index)), 213 m_srcid_rw(mtp.indexForId(initiator_index_rw)), 214 m_srcid_c(mtc.indexForId(initiator_index_c)), 215 216 m_nb_cpu(nb_cpu), 217 #if (CC_XCACHE_WRAPPER_MULTI_CACHE==1) 218 m_nb_icache(nb_dcache), 219 #elif (CC_XCACHE_WRAPPER_MULTI_CACHE==2) 220 m_nb_icache(m_nb_cpu), 276 221 #endif 277 278 r_vci_tgt_fsm("r_vci_tgt_fsm"), 279 r_tgt_addr("r_tgt_addr"), 280 r_tgt_word("r_tgt_word"), 281 r_tgt_update("r_tgt_update"), 282 r_tgt_update_data("r_tgt_update_data"), 283 // r_tgt_brdcast("r_tgt_brdcast"), 284 r_tgt_srcid("r_tgt_srcid"), 285 r_tgt_pktid("r_tgt_pktid"), 286 r_tgt_trdid("r_tgt_trdid"), 287 // r_tgt_plen("r_tgt_plen"), 288 r_tgt_icache_req("r_tgt_icache_req"), 289 r_tgt_dcache_req("r_tgt_dcache_req"), 290 r_tgt_icache_rsp("r_tgt_icache_rsp"), 291 r_tgt_dcache_rsp("r_tgt_dcache_rsp"), 292 293 r_cleanup_fsm("r_cleanup_fsm"), 294 295 r_wbuf("r_wbuf", wbuf_nwords, wbuf_nlines, wbuf_timeout, dcache_words), 296 r_icache("icache", icache_ways, icache_sets, icache_words), 297 r_dcache("dcache", dcache_ways, dcache_sets, dcache_words) 298 { 299 // Size of word is 32 bits 300 ASSERT( (icache_words*vci_param::B) < (1<<vci_param::K), 301 "I need more PLEN bits"); 302 303 ASSERT( (vci_param::T > 2) and ((1<<(vci_param::T-1)) >= wbuf_nlines), 304 "I need more TRDID bits"); 305 306 CACHE_MISS_BUF_ALLOC; 307 308 r_tgt_buf = new data_t[m_cache_words]; 309 r_tgt_be = new be_t [m_cache_words]; 310 311 SC_METHOD(transition); 312 dont_initialize(); 313 sensitive << p_clk.pos(); 314 315 SC_METHOD(genMoore); 316 dont_initialize(); 317 sensitive << p_clk.neg(); 318 319 320 typename iss_t::CacheInfo cache_info; 321 cache_info.has_mmu = false; 322 cache_info.icache_line_size = icache_words*sizeof(data_t); 323 cache_info.icache_assoc = icache_ways; 324 cache_info.icache_n_lines = icache_sets; 325 cache_info.dcache_line_size = dcache_words*sizeof(data_t); 326 cache_info.dcache_assoc = dcache_ways; 327 cache_info.dcache_n_lines = dcache_sets; 328 m_iss.setCacheInfo(cache_info); 329 222 m_nb_dcache(nb_dcache), 223 m_nb_cache((m_nb_dcache>m_nb_icache)?m_nb_dcache:m_nb_icache), 224 m_dcache_ways(dcache_ways), 225 m_dcache_words(dcache_words), 226 m_dcache_words_shift(uint32_log2(dcache_words)+uint32_log2(sizeof(data_t))), 227 m_dcache_yzmask((~0)<<m_dcache_words_shift), 228 m_icache_ways(icache_ways), 229 m_icache_words(icache_words), 230 m_icache_words_shift(uint32_log2(icache_words)+uint32_log2(sizeof(data_t))), 231 m_icache_yzmask((~0)<<m_icache_words_shift), 232 m_write_policy(write_policy), 233 m_cache_words((dcache_words)?dcache_words:icache_words), 234 235 r_cpu_prior("r_cpu_prior"), 236 237 r_vci_cmd_fsm("r_vci_cmd_fsm"), 238 r_vci_cmd_min("r_vci_cmd_min"), 239 r_vci_cmd_max("r_vci_cmd_max"), 240 r_vci_cmd_cpt("r_vci_cmd_cpt"), 241 r_vci_cmd_dcache_prior("r_vci_cmd_dcache_prior"), 242 r_vci_cmd_num_icache_prior("r_vci_cmd_num_icache_prior"), 243 r_vci_cmd_num_dcache_prior("r_vci_cmd_num_dcache_prior"), 244 r_vci_cmd_num_cache("r_vci_cmd_num_cache"), 245 246 r_vci_rsp_fsm("r_vci_rsp_fsm"), 247 r_vci_rsp_cpt("r_vci_rsp_cpt"), 248 r_vci_rsp_num_cache("r_vci_rsp_num_cache"), 249 250 r_vci_rsp_fifo_icache_data ("r_vci_rsp_fifo_icache_data" ,2), 251 r_vci_rsp_fifo_icache_num_cache ("r_vci_rsp_fifo_icache_num_cache",2), 252 r_vci_rsp_fifo_dcache_data ("r_vci_rsp_fifo_dcache_data" ,2), 253 r_vci_rsp_fifo_dcache_num_cache ("r_vci_rsp_fifo_dcache_num_cache",2), 254 255 r_cache_word("r_cache_word"), 256 257 r_vci_tgt_fsm("r_vci_tgt_fsm"), 258 r_tgt_iaddr("r_tgt_iaddr"), 259 r_tgt_daddr("r_tgt_daddr"), 260 r_tgt_word("r_tgt_word"), 261 r_tgt_update("r_tgt_update"), 262 r_tgt_update_data("r_tgt_update_data"), 263 // r_tgt_brdcast("r_tgt_brdcast"), 264 r_tgt_srcid("r_tgt_srcid"), 265 r_tgt_pktid("r_tgt_pktid"), 266 r_tgt_trdid("r_tgt_trdid"), 267 // r_tgt_plen("r_tgt_plen"), 268 r_tgt_num_cache("r_tgt_num_cache"), 269 270 r_cleanup_fsm("r_cleanup_fsm"), 271 r_cleanup_num_cache("r_cleanup_num_cache"), 272 r_cleanup_icache("r_cleanup_icache"), 273 274 m_num_cache_LSB(uint32_log2(icache_words) + uint32_log2(sizeof(data_t))), 275 m_num_cache_MSB(uint32_log2(nb_dcache) + m_num_cache_LSB) 276 { 277 // Size of word is 32 bits 278 ASSERT((icache_words*vci_param::B) < (1<<vci_param::K), 279 "Need more PLEN bits."); 280 281 ASSERT((vci_param::T > 2) and ((1<<(vci_param::T-1)) >= (wbuf_nlines/m_nb_dcache)), 282 "Need more TRDID bits."); 283 284 ASSERT(uint32_log2(nb_dcache) <= (1<<vci_param::P), 285 "Need more PKTID bits."); 286 287 ASSERT(IS_POW_OF_2(m_nb_dcache), 288 "nb_dcache must be a power of 2."); 289 290 ASSERT(IS_POW_OF_2(m_nb_cpu) and (m_nb_cpu <= m_nb_dcache) and (m_nb_cpu > 0), 291 "nb cpu must be a multiple of nb cache."); 292 293 ASSERT(IS_POW_OF_2(m_icache_ways) and (m_nb_icache <= m_icache_ways), 294 "nb icache ways must be a multiple of nb cache."); 295 296 ASSERT(IS_POW_OF_2(m_dcache_ways) and (m_nb_dcache <= m_dcache_ways), 297 "nb dcache ways must be a multiple of nb cache."); 298 299 ASSERT(icache_words == dcache_words, 300 "icache_words must be equal at dcache_words."); 301 302 ASSERT(IS_POW_OF_2(wbuf_nlines) and (m_nb_dcache <= wbuf_nlines), 303 "wbuf_nlines must be a multiple of nb cache."); 304 305 // FIXME : s'adapter à la taille des requêtes XTN_READ/XTN_WRITE 306 ASSERT((m_nb_dcache == 1) or (dcache_words >= 16), 307 "When multi cache is activated, need 4 bits (16 word) to the cache set ."); 308 309 if (m_nb_cpu > 1) 310 ASSERT(CC_XCACHE_MULTI_CPU!=0, 311 "Macro CC_XCACHE_MULTI_CPU in wbuf must be set at 1."); 312 313 p_irq = new sc_in<bool> * [m_nb_cpu]; 314 for (uint32_t num_cpu=0; num_cpu<m_nb_cpu; ++num_cpu) 315 p_irq [num_cpu] = new sc_in<bool> [iss_t::n_irq]; 316 317 m_iss = new iss_t * [m_nb_cpu]; 318 for (uint32_t num_cpu=0; num_cpu<m_nb_cpu; ++num_cpu) 319 { 320 std::ostringstream iss_name(""); 321 iss_name << this->name() << "_" << num_cpu; 322 323 m_iss[num_cpu] = new iss_t (iss_name.str().c_str(), proc_id+num_cpu); 324 } 325 326 r_icache_lock = new sc_signal<uint32_t>[m_nb_icache]; 327 r_dcache_lock = new sc_signal<uint32_t>[m_nb_dcache]; 328 r_dcache_sync = new sc_signal<bool> [m_nb_dcache]; 329 330 r_icache_fsm = new sc_signal<int> [m_nb_icache]; 331 r_icache_fsm_save = new sc_signal<int> [m_nb_icache]; 332 r_icache_addr_save = new sc_signal<addr_40> [m_nb_icache]; 333 r_icache_miss_req = new sc_signal<bool> [m_nb_icache]; 334 r_icache_miss_way = new sc_signal<size_t> [m_nb_icache]; 335 r_icache_miss_set = new sc_signal<size_t> [m_nb_icache]; 336 r_icache_unc_req = new sc_signal<bool> [m_nb_icache]; 337 r_icache_cleanup_req = new sc_signal<bool> [m_nb_icache]; 338 r_icache_cleanup_line = new sc_signal<addr_40> [m_nb_icache]; 339 r_icache_inval_rsp = new sc_signal<bool> [m_nb_icache]; 340 r_icache_update_addr = new sc_signal<size_t> [m_nb_icache]; 341 r_icache_buf_unc_valid = new sc_signal<bool> [m_nb_icache]; 342 343 r_dcache_fsm = new sc_signal<int> [m_nb_dcache]; 344 r_dcache_fsm_save = new sc_signal<int> [m_nb_dcache]; 345 r_dcache_addr_save = new sc_signal<addr_40> [m_nb_dcache]; 346 r_dcache_wdata_save = new sc_signal<data_t> [m_nb_dcache]; 347 r_dcache_rdata_save = new sc_signal<data_t> [m_nb_dcache]; 348 r_dcache_type_save = new sc_signal<int> [m_nb_dcache]; 349 r_dcache_be_save = new sc_signal<be_t> [m_nb_dcache]; 350 r_dcache_cached_save = new sc_signal<bool> [m_nb_dcache]; 351 r_dcache_num_cpu_save = new sc_signal<uint32_t>[m_nb_dcache]; 352 r_dcache_cleanup_req = new sc_signal<bool> [m_nb_dcache]; 353 r_dcache_cleanup_line = new sc_signal<addr_40> [m_nb_dcache]; 354 r_dcache_miss_req = new sc_signal<bool> [m_nb_dcache]; 355 r_dcache_miss_way = new sc_signal<size_t> [m_nb_dcache]; 356 r_dcache_miss_set = new sc_signal<size_t> [m_nb_dcache]; 357 r_dcache_unc_req = new sc_signal<bool> [m_nb_dcache]; 358 r_dcache_sc_req = new sc_signal<bool> [m_nb_dcache]; 359 r_dcache_inval_rsp = new sc_signal<bool> [m_nb_dcache]; 360 r_dcache_update_addr = new sc_signal<size_t> [m_nb_dcache]; 361 r_dcache_previous_unc = new sc_signal<bool> [m_nb_dcache]; 362 363 r_dcache_ll_data = new sc_signal<data_t> * [m_nb_dcache]; 364 r_dcache_ll_addr = new sc_signal<addr_40> * [m_nb_dcache]; 365 r_dcache_ll_valid = new sc_signal<bool> * [m_nb_dcache]; 366 for (uint32_t num_cache=0; num_cache<m_nb_dcache; ++num_cache) 367 { 368 r_dcache_ll_data [num_cache] = new sc_signal<data_t> [m_nb_cpu]; 369 r_dcache_ll_addr [num_cache] = new sc_signal<addr_40> [m_nb_cpu]; 370 r_dcache_ll_valid [num_cache] = new sc_signal<bool> [m_nb_cpu]; 371 } 372 373 r_tgt_icache_req = new sc_signal<bool> [m_nb_icache]; 374 r_tgt_icache_rsp = new sc_signal<bool> [m_nb_icache]; 375 r_tgt_dcache_req = new sc_signal<bool> [m_nb_dcache]; 376 r_tgt_dcache_rsp = new sc_signal<bool> [m_nb_dcache]; 377 378 r_tgt_buf = new data_t [m_cache_words]; 379 r_tgt_be = new be_t [m_cache_words]; 380 381 r_vci_rsp_ins_error = new sc_signal<bool> [m_nb_icache]; 382 r_vci_rsp_data_error = new sc_signal<bool> [m_nb_dcache]; 383 384 ireq = new typename iss_t::InstructionRequest [m_nb_icache]; 385 irsp = new typename iss_t::InstructionResponse [m_nb_icache]; 386 ireq_cached = new bool [m_nb_icache]; 387 ireq_num_cpu = new uint32_t [m_nb_dcache]; 388 389 dreq = new typename iss_t::DataRequest [m_nb_dcache]; 390 drsp = new typename iss_t::DataResponse [m_nb_dcache]; 391 dreq_cached = new bool [m_nb_dcache]; 392 dreq_num_cpu = new uint32_t [m_nb_dcache]; 393 394 m_cpt_icache_access = new uint32_t [m_nb_icache]; 395 m_cpt_dcache_access = new uint32_t [m_nb_dcache]; 396 m_cpt_icache_miss_victim_wait = new uint32_t [m_nb_icache]; 397 m_cpt_dcache_miss_victim_wait = new uint32_t [m_nb_dcache]; 398 399 m_cpt_dcache_store_after_store = new uint32_t [m_nb_dcache]; 400 m_cpt_dcache_hit_after_miss_read = new uint32_t [m_nb_dcache]; 401 m_cpt_dcache_hit_after_miss_write = new uint32_t [m_nb_dcache]; 402 403 m_cpt_fsm_dcache = new uint32_t * [m_nb_dcache]; 404 m_cpt_fsm_icache = new uint32_t * [m_nb_icache]; 405 for (uint32_t num_cache=0; num_cache<m_nb_dcache; ++num_cache) 406 m_cpt_fsm_dcache[num_cache] = new uint32_t [soclib::common::size(dcache_fsm_state_str )]; 407 for (uint32_t num_cache=0; num_cache<m_nb_icache; ++num_cache) 408 m_cpt_fsm_icache[num_cache] = new uint32_t [soclib::common::size(icache_fsm_state_str )]; 409 m_cpt_fsm_cmd = new uint32_t [soclib::common::size(cmd_fsm_state_str )]; 410 m_cpt_fsm_rsp = new uint32_t [soclib::common::size(rsp_fsm_state_str )]; 411 m_cpt_fsm_tgt = new uint32_t [soclib::common::size(tgt_fsm_state_str )]; 412 m_cpt_fsm_cleanup = new uint32_t [soclib::common::size(cleanup_fsm_state_str)]; 413 414 m_cpt_frz_cycles = new uint32_t [m_nb_cpu]; 415 // r_icache_fsm("r_icache_fsm"), 416 // r_icache_fsm_save("r_icache_fsm_save"), 417 // r_icache_addr_save("r_icache_addr_save"), 418 // r_icache_miss_req("r_icache_miss_req"), 419 // r_icache_miss_way("r_icache_miss_way"), 420 // r_icache_miss_set("r_icache_miss_set"), 421 // r_icache_unc_req("r_icache_unc_req"), 422 // r_icache_cleanup_req("r_icache_cleanup_req"), 423 // r_icache_cleanup_line("r_icache_cleanup_line"), 424 // r_icache_inval_rsp("r_icache_inval_rsp"), 425 // r_icache_update_addr("r_icache_update_addr"), 426 // r_icache_buf_unc_valid("r_icache_buf_unc_valid"), 427 428 // r_dcache_fsm("r_dcache_fsm"), 429 // r_dcache_fsm_save("r_dcache_fsm_save"), 430 // r_dcache_addr_save("r_dcache_addr_save"), 431 // r_dcache_wdata_save("r_dcache_wdata_save"), 432 // r_dcache_rdata_save("r_dcache_rdata_save"), 433 // r_dcache_type_save("r_dcache_type_save"), 434 // r_dcache_be_save("r_dcache_be_save"), 435 // r_dcache_cached_save("r_dcache_cached_save"), 436 // r_dcache_cleanup_req("r_dcache_cleanup_req"), 437 // r_dcache_cleanup_line("r_dcache_cleanup_line"), 438 // r_dcache_miss_req("r_dcache_miss_req"), 439 // r_dcache_miss_way("r_dcache_miss_way"), 440 // r_dcache_miss_set("r_dcache_miss_set"), 441 // r_dcache_unc_req("r_dcache_unc_req"), 442 // r_dcache_sc_req("r_dcache_sc_req"), 443 // r_dcache_inval_rsp("r_dcache_inval_rsp"), 444 // r_dcache_update_addr("r_dcache_update_addr"), 445 // r_dcache_ll_data("r_dcache_ll_data"), 446 // r_dcache_ll_addr("r_dcache_ll_addr"), 447 // r_dcache_ll_valid("r_dcache_ll_valid"), 448 // r_dcache_previous_unc("r_dcache_previous_unc"), 449 450 // r_tgt_icache_req("r_tgt_icache_req"), 451 // r_tgt_icache_rsp("r_tgt_icache_rsp"), 452 453 // r_tgt_dcache_req("r_tgt_dcache_req"), 454 // r_tgt_dcache_rsp("r_tgt_dcache_rsp"), 455 456 // r_vci_rsp_ins_error("r_vci_rsp_ins_error"), 457 // r_vci_rsp_data_error("r_vci_rsp_data_error"), 458 459 size_t _icache_ways = icache_ways /m_nb_icache; 460 size_t _icache_sets = icache_sets ; 461 size_t _dcache_ways = dcache_ways /m_nb_dcache; 462 size_t _dcache_sets = dcache_sets ; 463 size_t _icache_words = icache_words; 464 size_t _dcache_words = dcache_words; 465 466 size_t _wbuf_nwords = wbuf_nwords ; 467 size_t _wbuf_nlines = wbuf_nlines /m_nb_dcache; 468 size_t _wbuf_timeout = wbuf_timeout; 469 470 r_icache = new GenericCache<vci_addr_t> * [m_nb_icache]; 471 r_dcache = new GenericCache<vci_addr_t> * [m_nb_dcache]; 472 r_wbuf = new MultiWriteBuffer<addr_40> * [m_nb_dcache]; 473 474 for (uint32_t num_cache=0; num_cache<m_nb_icache; ++num_cache) 475 { 476 r_icache [num_cache] = new GenericCache<vci_addr_t> ("icache", _icache_ways, _icache_sets, _icache_words); 477 } 478 for (uint32_t num_cache=0; num_cache<m_nb_dcache; ++num_cache) 479 { 480 r_dcache [num_cache] = new GenericCache<vci_addr_t> ("dcache", _dcache_ways, _dcache_sets, _dcache_words); 481 r_wbuf [num_cache] = new MultiWriteBuffer<addr_40> ("r_wbuf", _wbuf_nwords, _wbuf_nlines, _wbuf_timeout, _dcache_words); 482 } 483 484 m_num_cache_LSB_mask = 0; 485 for (uint32_t i=0; i<m_num_cache_LSB; ++i) 486 { 487 m_num_cache_LSB_mask <<= 1; 488 m_num_cache_LSB_mask |= 1; 489 } 490 m_num_cache_mask = 0; 491 for (uint32_t i=0; i<(m_num_cache_MSB-m_num_cache_LSB); ++i) 492 { 493 m_num_cache_mask <<= 1; 494 m_num_cache_mask |= 1; 495 } 496 497 SC_METHOD(transition); 498 dont_initialize(); 499 sensitive << p_clk.pos(); 500 501 SC_METHOD(genMoore); 502 dont_initialize(); 503 sensitive << p_clk.neg(); 504 505 typename iss_t::CacheInfo cache_info; 506 cache_info.has_mmu = false; 507 cache_info.icache_line_size = icache_words*sizeof(data_t); 508 cache_info.icache_assoc = icache_ways; 509 cache_info.icache_n_lines = icache_sets; 510 cache_info.dcache_line_size = dcache_words*sizeof(data_t); 511 cache_info.dcache_assoc = dcache_ways; 512 cache_info.dcache_n_lines = dcache_sets; 513 514 for (uint32_t num_cpu=0; num_cpu<m_nb_cpu; ++num_cpu) 515 m_iss[num_cpu]->setCacheInfo(cache_info); 516 330 517 #if CC_XCACHE_WRAPPER_STOP_SIMULATION 331 m_stop_simulation = false; 332 m_stop_simulation_nb_frz_cycles = 0; 518 m_stop_simulation = false; 519 m_stop_simulation_nb_frz_cycles = new uint32_t [m_nb_cpu]; 520 for (uint32_t num_cpu=0; num_cpu<m_nb_cpu; ++num_cpu) 521 m_stop_simulation_nb_frz_cycles [num_cpu] = 0; 333 522 #endif // CC_XCACHE_WRAPPER_STOP_SIMULATION 334 523 335 #if CC_XCACHE_WRAPPER_DEBUG_DCACHE_TRANSACTION 336 std::ostringstream filename(""); 337 filename << "Instruction_flow_" << proc_id << ".log"; 338 339 log_dcache_transaction_file.open(filename.str().c_str() ,std::ios::out | std::ios::trunc); 524 #if CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION 525 generate_log_transaction_file_icache = true; 526 generate_log_transaction_file_dcache = true; 527 generate_log_transaction_file_cmd = true; 528 generate_log_transaction_file_tgt = true; 529 generate_log_transaction_file_cleanup = true; 530 531 log_transaction_file_icache = new std::ofstream [m_nb_cpu]; 532 log_transaction_file_dcache = new std::ofstream [m_nb_cpu]; 533 for (uint32_t num_cpu=0; num_cpu<m_nb_cpu; ++num_cpu) 534 { 535 { 536 std::ostringstream filename(""); 537 filename << CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION_PATH << "/Transaction_icache-" << proc_id << "_" << num_cpu << ".log"; 538 log_transaction_file_icache[num_cpu].open(filename.str().c_str() ,std::ios::out | std::ios::trunc); 539 } 540 { 541 std::ostringstream filename(""); 542 filename << CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION_PATH << "/Transaction_dcache-" << proc_id << "_" << num_cpu << ".log"; 543 log_transaction_file_dcache[num_cpu].open(filename.str().c_str() ,std::ios::out | std::ios::trunc); 544 } 545 } 546 547 { 548 std::ostringstream filename(""); 549 filename << CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION_PATH << "/Transaction_cmd-" << proc_id << ".log"; 550 log_transaction_file_cmd.open(filename.str().c_str() ,std::ios::out | std::ios::trunc); 551 } 552 { 553 std::ostringstream filename(""); 554 filename << CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION_PATH << "/Transaction_tgt-" << proc_id << ".log"; 555 log_transaction_file_tgt.open(filename.str().c_str() ,std::ios::out | std::ios::trunc); 556 } 557 { 558 std::ostringstream filename(""); 559 filename << CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION_PATH << "/Transaction_cleanup-" << proc_id << ".log"; 560 log_transaction_file_cleanup.open(filename.str().c_str() ,std::ios::out | std::ios::trunc); 561 } 340 562 #endif 341 } // end constructor 563 564 #if MWBUF_VHDL_TESTBENCH 565 simulation_started = false; 566 567 vhdl_testbench_mwbuf = new std::ofstream [m_nb_dcache]; 568 for (uint32_t num_dcache=0; num_dcache<m_nb_dcache; ++num_dcache) 569 { 570 std::ostringstream filename(""); 571 filename << "VHDL_testbench_mwbuf-" << proc_id << "_" << num_dcache << ".txt"; 572 vhdl_testbench_mwbuf[num_dcache].open(filename.str().c_str() ,std::ios::out | std::ios::trunc); 573 574 vhdl_testbench_mwbuf[num_dcache] 575 << _wbuf_nlines << " " // nb_lines 576 << _wbuf_nwords << " " // nb_words 577 << _wbuf_timeout << " " // timeout 578 << m_nb_cpu << " " // nb_cpu 579 << 32 << " " // size_data 580 << 40 << " " // size_addr 581 << _dcache_words << std::endl; // cache_nb_words 582 } 583 584 #endif 585 } // end constructor 342 586 343 587 /////////////////////////////////// 344 588 tmpl(/**/)::~VciCcXCacheWrapperV4() 345 ///////////////////////////////////589 /////////////////////////////////// 346 590 { 347 #if CC_XCACHE_WRAPPER_DEBUG_DCACHE_TRANSACTION 348 log_dcache_transaction_file.close(); 591 #if MWBUF_VHDL_TESTBENCH 592 for (uint32_t num_dcache=0; num_dcache<m_nb_dcache; ++num_dcache) 593 vhdl_testbench_mwbuf[num_dcache].close(); 594 delete [] vhdl_testbench_mwbuf; 349 595 #endif 350 596 351 delete [] r_tgt_buf; 352 delete [] r_tgt_be ; 353 354 CACHE_MISS_BUF_DEALLOC; 597 #if CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION 598 for (uint32_t num_cpu=0; num_cpu<m_nb_cpu; ++num_cpu) 599 { 600 log_transaction_file_dcache[num_cpu].close(); 601 log_transaction_file_icache[num_cpu].close(); 602 } 603 delete [] log_transaction_file_dcache; 604 delete [] log_transaction_file_icache; 605 606 log_transaction_file_cmd .close(); 607 log_transaction_file_tgt .close(); 608 log_transaction_file_cleanup.close(); 609 #endif 610 611 delete [] m_stop_simulation_nb_frz_cycles; 612 613 614 delete [] r_icache_lock ; 615 delete [] r_dcache_lock ; 616 delete [] r_dcache_sync ; 617 618 delete [] r_icache_fsm ; 619 delete [] r_icache_fsm_save ; 620 delete [] r_icache_addr_save ; 621 delete [] r_icache_miss_req ; 622 delete [] r_icache_miss_way ; 623 delete [] r_icache_miss_set ; 624 delete [] r_icache_unc_req ; 625 delete [] r_icache_cleanup_req ; 626 delete [] r_icache_cleanup_line ; 627 delete [] r_icache_inval_rsp ; 628 delete [] r_icache_update_addr ; 629 delete [] r_icache_buf_unc_valid; 630 631 delete [] r_dcache_fsm ; 632 delete [] r_dcache_fsm_save ; 633 delete [] r_dcache_addr_save ; 634 delete [] r_dcache_wdata_save ; 635 delete [] r_dcache_rdata_save ; 636 delete [] r_dcache_type_save ; 637 delete [] r_dcache_be_save ; 638 delete [] r_dcache_cached_save ; 639 delete [] r_dcache_cleanup_req ; 640 delete [] r_dcache_cleanup_line ; 641 delete [] r_dcache_miss_req ; 642 delete [] r_dcache_miss_way ; 643 delete [] r_dcache_miss_set ; 644 delete [] r_dcache_unc_req ; 645 delete [] r_dcache_sc_req ; 646 delete [] r_dcache_inval_rsp ; 647 delete [] r_dcache_update_addr ; 648 delete [] r_dcache_previous_unc ; 649 650 for (uint32_t num_cache=0; num_cache<m_nb_dcache; ++num_cache) 651 { 652 delete [] r_dcache_ll_data [num_cache]; 653 delete [] r_dcache_ll_addr [num_cache]; 654 delete [] r_dcache_ll_valid [num_cache]; 655 } 656 delete [] r_dcache_num_cpu_save ; 657 delete [] r_dcache_ll_data ; 658 delete [] r_dcache_ll_addr ; 659 delete [] r_dcache_ll_valid ; 660 661 delete [] r_tgt_icache_req ; 662 delete [] r_tgt_icache_rsp ; 663 delete [] r_tgt_dcache_req ; 664 delete [] r_tgt_dcache_rsp ; 665 666 delete [] r_tgt_be ; 667 delete [] r_tgt_buf; 668 669 delete [] r_vci_rsp_ins_error ; 670 delete [] r_vci_rsp_data_error ; 671 672 delete [] ireq ; 673 delete [] irsp ; 674 delete [] ireq_cached ; 675 delete [] ireq_num_cpu ; 676 delete [] dreq ; 677 delete [] drsp ; 678 delete [] dreq_cached ; 679 delete [] dreq_num_cpu ; 680 681 delete [] m_cpt_frz_cycles; 682 683 delete [] m_cpt_icache_access ; 684 delete [] m_cpt_dcache_access ; 685 delete [] m_cpt_icache_miss_victim_wait; 686 delete [] m_cpt_dcache_miss_victim_wait; 687 delete [] m_cpt_dcache_store_after_store; 688 delete [] m_cpt_dcache_hit_after_miss_read; 689 delete [] m_cpt_dcache_hit_after_miss_write; 690 for (uint32_t num_cache=0; num_cache<m_nb_dcache; ++num_cache) 691 delete [] m_cpt_fsm_dcache [num_cache]; 692 for (uint32_t num_cache=0; num_cache<m_nb_icache; ++num_cache) 693 delete [] m_cpt_fsm_icache [num_cache]; 694 695 delete [] m_cpt_fsm_dcache ; 696 delete [] m_cpt_fsm_icache ; 697 delete [] m_cpt_fsm_cmd ; 698 delete [] m_cpt_fsm_rsp ; 699 delete [] m_cpt_fsm_tgt ; 700 delete [] m_cpt_fsm_cleanup; 701 702 for (uint32_t num_cache=0; num_cache<m_nb_icache; ++num_cache) 703 { 704 delete r_icache [num_cache]; 705 } 706 for (uint32_t num_cache=0; num_cache<m_nb_dcache; ++num_cache) 707 { 708 delete r_wbuf [num_cache]; 709 delete r_dcache [num_cache]; 710 } 711 delete [] r_wbuf; 712 delete [] r_icache; 713 delete [] r_dcache; 714 715 for (uint32_t num_cpu=0; num_cpu<m_nb_cpu; ++num_cpu) 716 { 717 delete m_iss [num_cpu]; 718 delete [] p_irq [num_cpu]; 719 } 720 delete [] m_iss; 721 delete [] p_irq; 355 722 } 356 723 … … 359 726 //////////////////////// 360 727 { 728 for (uint32_t num_cpu=0; num_cpu<m_nb_cpu; ++num_cpu) 361 729 std::cout << "CPU " << m_srcid_rw << " : CPI = " 362 << (float)m_cpt_total_cycles/(m_cpt_total_cycles - m_cpt_frz_cycles) << std::endl ;730 << (float)m_cpt_total_cycles/(m_cpt_total_cycles - m_cpt_frz_cycles[num_cpu]) << std::endl ; 363 731 } 364 732 //////////////////////// 365 tmpl(void)::print_stats( )366 ////////////////////////733 tmpl(void)::print_stats(bool print_wbuf, bool print_fsm) 734 //////////////////////// 367 735 { 368 float run_cycles = (float)(m_cpt_total_cycles - m_cpt_frz_cycles); 369 370 uint32_t m_cpt_data_read_cached = m_cpt_data_read-m_cpt_data_read_uncached; 371 uint32_t m_cpt_data_write_cached = m_cpt_data_write-m_cpt_data_write_uncached; 372 std::cout << "------------------------------------" << std:: dec << std::endl; 373 std::cout << "CPU " << m_srcid_rw << " / Time = " << m_cpt_total_cycles << std::endl; 374 std::cout << "- CPI : " << (float)m_cpt_total_cycles/run_cycles << std::endl ; 375 std::cout << "- IPC : " << (float)run_cycles/m_cpt_total_cycles << std::endl ; 376 std::cout << "- DATA READ * : " << m_cpt_data_read << std::endl ; 377 std::cout << " + Uncached : " << m_cpt_data_read_uncached << " (" << (float)m_cpt_data_read_uncached*100.0/(float)m_cpt_data_read << "%)" << std::endl ; 378 std::cout << " + Cached and miss : " << m_cpt_data_read_miss << " (" << (float)m_cpt_data_read_miss*100.0/(float)m_cpt_data_read_cached << "%)" << std::endl; 379 std::cout << "- DATA WRITE * : " << m_cpt_data_write << std::endl ; 380 std::cout << " + Uncached : " << m_cpt_data_write_uncached << " (" << (float)m_cpt_data_write_uncached*100.0/(float)m_cpt_data_write << "%)" << std::endl ; 381 std::cout << " + Cached and miss : " << m_cpt_data_write_miss << " (" << (float)m_cpt_data_write_miss*100.0/(float)m_cpt_data_write_cached << "%)" << std::endl; 382 // std::cout << "- WRITE RATE : " << (float)m_cpt_data_write/run_cycles << std::endl; 383 // std::cout << "- UNCACHED READ RATE : " << (float)m_cpt_data_read_uncached/m_cpt_data_read << std::endl ; 384 // std::cout << "- CACHED WRITE RATE : " << (float)m_cpt_data_write_cached/m_cpt_data_write << std::endl ; 385 // std::cout << "- IMISS_RATE : " << (float)m_cpt_ins_miss/run_cycles << std::endl; 386 // std::cout << "- DMISS RATE : " << (float)m_cpt_data_miss/(m_cpt_data_read-m_cpt_data_read_uncached) << std::endl ; 387 // std::cout << "- INS MISS COST : " << (float)m_cost_ins_miss_frz/m_cpt_ins_miss << std::endl; 388 // std::cout << "- IMISS TRANSACTION : " << (float)m_cost_imiss_transaction/m_cpt_imiss_transaction << std::endl; 389 // std::cout << "- DMISS COST : " << (float)m_cost_data_miss_frz/m_cpt_data_miss << std::endl; 390 // std::cout << "- DMISS TRANSACTION : " << (float)m_cost_dmiss_transaction/m_cpt_dmiss_transaction << std::endl; 391 // std::cout << "- UNC COST : " << (float)m_cost_unc_read_frz/m_cpt_data_read_uncached << std::endl; 392 // std::cout << "- UNC TRANSACTION : " << (float)m_cost_unc_transaction/m_cpt_unc_transaction << std::endl; 393 // std::cout << "- WRITE COST : " << (float)m_cost_write_frz/m_cpt_data_write << std::endl; 394 // std::cout << "- WRITE TRANSACTION : " << (float)m_cost_write_transaction/m_cpt_data_write_transaction << std::endl; 395 // std::cout << "- WRITE LENGTH : " << (float)m_length_write_transaction/m_cpt_data_write_transaction << std::endl; 396 397 std::cout << "- CC_UPDATE_ICACHE : " << m_cpt_cc_update_icache << std::endl; 398 std::cout << " + AVERAGE WORD USEFUL : " << (float)m_cpt_cc_update_icache_word_useful/(float)m_cpt_cc_update_icache << " on " << m_icache_words << " words" << std::endl; 399 std::cout << "- CC_UPDATE_DCACHE : " << m_cpt_cc_update_dcache << std::endl; 400 std::cout << " + AVERAGE WORD USEFUL : " << (float)m_cpt_cc_update_dcache_word_useful/(float)m_cpt_cc_update_dcache << " on " << m_dcache_words << " words" << std::endl; 401 uint32_t m_cpt_cc_inval = m_cpt_cc_inval_broadcast+m_cpt_cc_inval_icache+m_cpt_cc_inval_dcache; 402 std::cout << "- CC_INVALID : " << m_cpt_cc_inval << std::endl; 403 std::cout << " + ICACHE Only : " << (float)m_cpt_cc_inval_icache *100.0/(float)m_cpt_cc_inval << "%" << std::endl; 404 std::cout << " + DCACHE Only : " << (float)m_cpt_cc_inval_dcache *100.0/(float)m_cpt_cc_inval << "%" << std::endl; 405 std::cout << " + BROADCAST : " << (float)m_cpt_cc_inval_broadcast*100.0/(float)m_cpt_cc_inval << "%" << std::endl; 406 std::cout << "* : accepted or not by the cache" << std::endl ; 407 408 r_wbuf.printStatistics(); 736 uint32_t m_cpt_data_read_cached = m_cpt_data_read-m_cpt_data_read_uncached; 737 uint32_t m_cpt_data_write_cached = m_cpt_data_write-m_cpt_data_write_uncached; 738 std::cout << "------------------------------------" << std:: dec << std::endl; 739 std::cout << "CPU " << m_srcid_rw << " / Time = " << m_cpt_total_cycles << std::endl; 740 for (uint32_t num_cpu=0; num_cpu<m_nb_cpu; ++num_cpu) 741 { 742 float run_cycles = (float)(m_cpt_total_cycles - m_cpt_frz_cycles[num_cpu]); 743 744 std::cout << "- CPI : [" << num_cpu << "] "<< (float)m_cpt_total_cycles/run_cycles << std::endl ; 745 std::cout << "- IPC : [" << num_cpu << "] "<< (float)run_cycles/m_cpt_total_cycles << std::endl ; 746 } 747 std::cout << "- DATA READ * : " << m_cpt_data_read << std::endl ; 748 std::cout << " + Uncached : " << m_cpt_data_read_uncached << " (" << (float)m_cpt_data_read_uncached*100.0/(float)m_cpt_data_read << "%)" << std::endl ; 749 std::cout << " + Cached and miss : " << m_cpt_data_read_miss << " (" << (float)m_cpt_data_read_miss*100.0/(float)m_cpt_data_read_cached << "%)" << std::endl; 750 std::cout << "- DATA WRITE * : " << m_cpt_data_write << std::endl ; 751 std::cout << " + Uncached : " << m_cpt_data_write_uncached << " (" << (float)m_cpt_data_write_uncached*100.0/(float)m_cpt_data_write << "%)" << std::endl ; 752 std::cout << " + Cached and miss : " << m_cpt_data_write_miss << " (" << (float)m_cpt_data_write_miss*100.0/(float)m_cpt_data_write_cached << "%)" << std::endl; 753 // std::cout << "- WRITE RATE : " << (float)m_cpt_data_write/run_cycles << std::endl; 754 // std::cout << "- UNCACHED READ RATE : " << (float)m_cpt_data_read_uncached/m_cpt_data_read << std::endl ; 755 // std::cout << "- CACHED WRITE RATE : " << (float)m_cpt_data_write_cached/m_cpt_data_write << std::endl ; 756 // std::cout << "- IMISS_RATE : " << (float)m_cpt_ins_miss/run_cycles << std::endl; 757 // std::cout << "- DMISS RATE : " << (float)m_cpt_data_miss/(m_cpt_data_read-m_cpt_data_read_uncached) << std::endl ; 758 // std::cout << "- INS MISS COST : " << (float)m_cost_ins_miss_frz/m_cpt_ins_miss << std::endl; 759 // std::cout << "- IMISS TRANSACTION : " << (float)m_cost_imiss_transaction/m_cpt_imiss_transaction << std::endl; 760 // std::cout << "- DMISS COST : " << (float)m_cost_data_miss_frz/m_cpt_data_miss << std::endl; 761 // std::cout << "- DMISS TRANSACTION : " << (float)m_cost_dmiss_transaction/m_cpt_dmiss_transaction << std::endl; 762 // std::cout << "- UNC COST : " << (float)m_cost_unc_read_frz/m_cpt_data_read_uncached << std::endl; 763 // std::cout << "- UNC TRANSACTION : " << (float)m_cost_unc_transaction/m_cpt_unc_transaction << std::endl; 764 // std::cout << "- WRITE COST : " << (float)m_cost_write_frz/m_cpt_data_write << std::endl; 765 // std::cout << "- WRITE TRANSACTION : " << (float)m_cost_write_transaction/m_cpt_data_write_transaction << std::endl; 766 // std::cout << "- WRITE LENGTH : " << (float)m_length_write_transaction/m_cpt_data_write_transaction << std::endl; 767 768 std::cout << "- CC_UPDATE_ICACHE : " << m_cpt_cc_update_icache << std::endl; 769 std::cout << " + AVERAGE WORD USEFUL : " << (float)m_cpt_cc_update_icache_word_useful/(float)m_cpt_cc_update_icache << " on " << m_icache_words << " words" << std::endl; 770 std::cout << "- CC_UPDATE_DCACHE : " << m_cpt_cc_update_dcache << std::endl; 771 std::cout << " + AVERAGE WORD USEFUL : " << (float)m_cpt_cc_update_dcache_word_useful/(float)m_cpt_cc_update_dcache << " on " << m_dcache_words << " words" << std::endl; 772 uint32_t m_cpt_cc_inval = m_cpt_cc_inval_broadcast+m_cpt_cc_inval_icache+m_cpt_cc_inval_dcache; 773 std::cout << "- CC_INVALID : " << m_cpt_cc_inval << std::endl; 774 std::cout << " + ICACHE Only : " << (float)m_cpt_cc_inval_icache *100.0/(float)m_cpt_cc_inval << "%" << std::endl; 775 std::cout << " + DCACHE Only : " << (float)m_cpt_cc_inval_dcache *100.0/(float)m_cpt_cc_inval << "%" << std::endl; 776 std::cout << " + BROADCAST : " << (float)m_cpt_cc_inval_broadcast*100.0/(float)m_cpt_cc_inval << "%" << std::endl; 777 778 uint32_t m_cpt_icache_access_all = 0; 779 for (uint32_t num_cache=0; num_cache<m_nb_icache; ++num_cache) 780 m_cpt_icache_access_all += m_cpt_icache_access [num_cache]; 781 782 std::cout << "- ICACHE ACCESS : " << m_cpt_icache_access_all << std::endl; 783 for (uint32_t num_cache=0; num_cache<m_nb_icache; ++num_cache) 784 std::cout << " + [" << num_cache << "] : " << m_cpt_icache_access [num_cache] << " (" << (float)m_cpt_icache_access [num_cache]*100.0/(float)m_cpt_icache_access_all << "%)" << std::endl; 785 786 uint32_t m_cpt_dcache_access_all = 0; 787 for (uint32_t num_cache=0; num_cache<m_nb_dcache; ++num_cache) 788 m_cpt_dcache_access_all += m_cpt_dcache_access [num_cache]; 789 790 std::cout << "- DCACHE ACCESS : " << m_cpt_dcache_access_all << std::endl; 791 for (uint32_t num_cache=0; num_cache<m_nb_dcache; ++num_cache) 792 { 793 std::cout << " + [" << num_cache << "] : " << m_cpt_dcache_access [num_cache] << " (" << (float)m_cpt_dcache_access [num_cache]*100.0/(float)m_cpt_dcache_access_all << "%)"; 794 795 std::cout << " - store after store : " << m_cpt_dcache_store_after_store [num_cache]; 796 std::cout << " - Hit after Miss : Read " << m_cpt_dcache_hit_after_miss_read [num_cache] << ", Write " << m_cpt_dcache_hit_after_miss_write [num_cache]; 797 std::cout << std::endl; 798 } 799 800 uint32_t m_cpt_icache_miss_victim_wait_all = 0; 801 for (uint32_t num_cache=0; num_cache<m_nb_icache; ++num_cache) 802 m_cpt_icache_miss_victim_wait_all += m_cpt_icache_miss_victim_wait [num_cache]; 803 std::cout << "- ICACHE MISS VICTIM WAIT : " << m_cpt_icache_miss_victim_wait_all << std::endl; 804 for (uint32_t num_cache=0; num_cache<m_nb_icache; ++num_cache) 805 std::cout << " + [" << num_cache << "] : " << m_cpt_icache_miss_victim_wait [num_cache] << std::endl; 806 807 uint32_t m_cpt_dcache_miss_victim_wait_all = 0; 808 for (uint32_t num_cache=0; num_cache<m_nb_dcache; ++num_cache) 809 m_cpt_dcache_miss_victim_wait_all += m_cpt_dcache_miss_victim_wait [num_cache]; 810 std::cout << "- DCACHE MISS VICTIM WAIT : " << m_cpt_dcache_miss_victim_wait_all << std::endl; 811 for (uint32_t num_cache=0; num_cache<m_nb_dcache; ++num_cache) 812 std::cout << " + [" << num_cache << "] : " << m_cpt_dcache_miss_victim_wait [num_cache] << std::endl; 813 814 if (print_fsm) 815 { 816 std::cout << "- DCACHE FSM" << std::endl; 817 for (uint32_t i=0; i<soclib::common::size(dcache_fsm_state_str ); ++i) 818 { 819 std::cout << " + " << dcache_fsm_state_str[i] << " :\t "; 820 for (uint32_t num_cache=0; num_cache<m_nb_dcache; ++num_cache) 821 std::cout << m_cpt_fsm_dcache [num_cache][i] << ", "; 822 std::cout << std::endl; 823 } 824 std::cout << "- ICACHE FSM" << std::endl; 825 for (uint32_t i=0; i<soclib::common::size(icache_fsm_state_str ); ++i) 826 { 827 std::cout << " + " << icache_fsm_state_str[i] << " :\t "; 828 for (uint32_t num_cache=0; num_cache<m_nb_icache; ++num_cache) 829 std::cout << m_cpt_fsm_icache [num_cache][i] << ", "; 830 std::cout << std::endl; 831 } 832 std::cout << "- CMD FSM" << std::endl; 833 for (uint32_t i=0; i<soclib::common::size(cmd_fsm_state_str ); ++i) 834 std::cout << " + " << cmd_fsm_state_str[i] << " :\t " << m_cpt_fsm_cmd [i] << std::endl; 835 std::cout << "- RSP FSM" << std::endl; 836 for (uint32_t i=0; i<soclib::common::size(rsp_fsm_state_str ); ++i) 837 std::cout << " + " << rsp_fsm_state_str[i] << " :\t " << m_cpt_fsm_rsp [i] << std::endl; 838 std::cout << "- TGT FSM" << std::endl; 839 for (uint32_t i=0; i<soclib::common::size(tgt_fsm_state_str ); ++i) 840 std::cout << " + " << tgt_fsm_state_str[i] << " :\t " << m_cpt_fsm_tgt [i] << std::endl; 841 std::cout << "- CLEANUP FSM" << std::endl; 842 for (uint32_t i=0; i<soclib::common::size(cleanup_fsm_state_str ); ++i) 843 std::cout << " + " << cleanup_fsm_state_str[i] << " :\t " << m_cpt_fsm_cleanup [i] << std::endl; 844 } 845 846 std::cout << "* : accepted or not by the cache" << std::endl ; 847 848 if (print_wbuf) 849 for (uint32_t num_cache=0; num_cache<m_nb_dcache; ++num_cache) 850 r_wbuf[num_cache]->printStatistics(); 409 851 } 410 852 411 853 //////////////////////////////////// 412 854 tmpl(void)::print_trace(size_t mode) 413 ////////////////////////////////////855 //////////////////////////////////// 414 856 { 415 // b0 : write buffer print trace 416 // b1 : write buffer verbose 417 // b2 : dcache print trace 418 // b3 : icache print trace 419 420 typename iss_t::InstructionRequest ireq; 421 typename iss_t::DataRequest dreq; 422 423 m_iss.getRequests( ireq, dreq ); 424 std::cout << std::dec << "Proc \"" << name() << "\"" << std::endl; 425 std::cout << ireq << std::endl; 426 std::cout << dreq << std::endl; 427 std::cout << " " << dcache_fsm_state_str[r_dcache_fsm] 428 << " " << icache_fsm_state_str[r_icache_fsm] 429 << " " << cmd_fsm_state_str[r_vci_cmd_fsm] 430 << " " << rsp_fsm_state_str[r_vci_rsp_fsm] 431 << " " << tgt_fsm_state_str[r_vci_tgt_fsm] 432 << " " << cleanup_fsm_state_str[r_cleanup_fsm] << std::endl; 433 434 if(mode & 0x1) 435 { 436 r_wbuf.printTrace((mode>>1)&1); 437 } 438 if(mode & 0x4) 439 { 440 std::cout << " Data cache" << std::endl; 441 r_dcache.printTrace(); 442 } 443 if(mode & 0x8) 444 { 445 std::cout << " Instruction cache" << std::endl; 446 r_icache.printTrace(); 447 } 448 449 // if(mode & 0x10) 450 // { 451 // std::cout << " Icache miss buffer : "; 452 // CACHE_MISS_BUF_RSP_PRINT(i); 453 // std::cout << std::endl; 454 455 // std::cout << " Dcache miss buffer : "; 456 // CACHE_MISS_BUF_RSP_PRINT(d); 457 // std::cout << std::endl; 458 // } 857 // b0 : write buffer print trace 858 // b1 : write buffer verbose 859 // b2 : dcache print trace 860 // b3 : icache print trace 861 862 typename iss_t::InstructionRequest ireq; 863 typename iss_t::DataRequest dreq; 864 865 std::cout << std::dec << "Proc \"" << name() << "\"" << std::endl; 866 867 for (uint32_t num_cpu=0; num_cpu<m_nb_cpu; ++num_cpu) 868 { 869 m_iss[num_cpu]->getRequests( ireq, dreq ); 870 std::cout << ireq << std::endl; 871 std::cout << dreq << std::endl; 872 } 873 for (uint32_t num_cache=0; num_cache<m_nb_icache; ++num_cache) 874 std::cout << " " << icache_fsm_state_str[r_icache_fsm[num_cache]] << std::endl; 875 for (uint32_t num_cache=0; num_cache<m_nb_dcache; ++num_cache) 876 std::cout << " " << dcache_fsm_state_str[r_dcache_fsm[num_cache]] << std::endl; 877 878 std::cout << " " << cmd_fsm_state_str[r_vci_cmd_fsm] 879 << " " << rsp_fsm_state_str[r_vci_rsp_fsm] 880 << " " << tgt_fsm_state_str[r_vci_tgt_fsm] 881 << " " << cleanup_fsm_state_str[r_cleanup_fsm] << std::endl; 882 883 if(mode & 0x1) 884 { 885 for (uint32_t num_cache=0; num_cache<m_nb_dcache; ++num_cache) 886 r_wbuf[num_cache]->printTrace((mode>>1)&1); 887 } 888 if(mode & 0x4) 889 { 890 std::cout << " Data cache" << std::endl; 891 for (uint32_t num_cache=0; num_cache<m_nb_dcache; ++num_cache) 892 r_dcache[num_cache]->printTrace(); 893 } 894 if(mode & 0x8) 895 { 896 std::cout << " Instruction cache" << std::endl; 897 for (uint32_t num_cache=0; num_cache<m_nb_icache; ++num_cache) 898 r_icache[num_cache]->printTrace(); 899 } 459 900 } 460 901 … … 463 904 ////////////////////////// 464 905 { 465 if ( not p_resetn.read() ) { 466 467 m_iss.reset(); 468 469 // FSM states 470 r_dcache_fsm = DCACHE_IDLE; 471 r_icache_fsm = ICACHE_IDLE; 472 r_vci_cmd_fsm = CMD_IDLE; 473 r_vci_rsp_fsm = RSP_IDLE; 474 r_vci_tgt_fsm = TGT_IDLE; 475 r_cleanup_fsm = CLEANUP_IDLE; 476 906 907 ///////////////////////////////////////////////////////////////////// 908 // Reset 909 ///////////////////////////////////////////////////////////////////// 910 911 if ( not p_resetn.read() ) { 912 913 r_cpu_prior = 0; 914 915 for (uint32_t num_cpu=0; num_cpu<m_nb_cpu; ++num_cpu) 916 m_iss[num_cpu]->reset(); 917 918 // FSM states 919 for (uint32_t num_cache=0; num_cache<m_nb_icache; ++num_cache) 920 { 921 r_icache_fsm [num_cache] = ICACHE_IDLE; 922 923 r_icache_lock[num_cache] = m_nb_cpu; 924 } 925 for (uint32_t num_cache=0; num_cache<m_nb_dcache; ++num_cache) 926 { 927 r_dcache_fsm [num_cache] = DCACHE_IDLE; 928 929 r_dcache_lock[num_cache] = m_nb_cpu; 930 r_dcache_sync[num_cache] = false; 931 } 932 933 r_vci_cmd_fsm = CMD_IDLE; 934 r_vci_rsp_fsm = RSP_IDLE; 935 r_vci_tgt_fsm = TGT_IDLE; 936 r_cleanup_fsm = CLEANUP_IDLE; 937 938 for (uint32_t num_cache=0; num_cache<m_nb_icache; ++num_cache) 939 { 477 940 // write buffer & caches 478 r_wbuf.reset(); 479 r_icache.reset(); 480 r_dcache.reset(); 941 r_icache[num_cache]->reset(); 481 942 482 943 // synchronisation flip-flops from ICACHE & DCACHE FSMs to VCI FSMs 483 r_icache_miss_req = false; 484 r_icache_unc_req = false; 485 r_icache_cleanup_req = false; 486 r_dcache_miss_req = false; 487 r_dcache_unc_req = false; 488 r_dcache_sc_req = false; 489 r_dcache_cleanup_req = false; 490 r_dcache_previous_unc= false; 944 r_icache_miss_req [num_cache] = false; 945 r_icache_unc_req [num_cache] = false; 946 r_icache_cleanup_req [num_cache] = false; 947 948 // internal messages in DCACHE et ICACHE FSMs 949 r_icache_inval_rsp [num_cache] = false; 950 951 // error signals from the VCI RSP FSM to the ICACHE or DCACHE FSMs 952 r_icache_buf_unc_valid [num_cache] = false; 491 953 492 954 // synchronisation flip-flops from TGT FSM to ICACHE & DCACHE FSMs 493 r_tgt_icache_req = false; 494 r_tgt_dcache_req = false; 495 r_tgt_icache_rsp = false; 496 r_tgt_dcache_rsp = false; 497 498 #if CC_XCACHE_WRAPPER_CC_UPDATE_MULTI_CYCLE 499 r_cache_word = 0; 955 r_tgt_icache_req [num_cache] = false; 956 r_tgt_icache_rsp [num_cache] = false; 957 958 r_vci_rsp_ins_error [num_cache] = false; 959 }// end for num_cache 960 961 for (uint32_t num_cache=0; num_cache<m_nb_dcache; ++num_cache) 962 { 963 // write buffer & caches 964 r_wbuf [num_cache]->reset(); 965 r_dcache[num_cache]->reset(); 966 967 // synchronisation flip-flops from ICACHE & DCACHE FSMs to VCI FSMs 968 r_dcache_miss_req [num_cache] = false; 969 r_dcache_unc_req [num_cache] = false; 970 r_dcache_sc_req [num_cache] = false; 971 r_dcache_cleanup_req [num_cache] = false; 972 r_dcache_previous_unc[num_cache] = false; 973 974 // internal messages in DCACHE et ICACHE FSMs 975 r_dcache_inval_rsp [num_cache] = false; 976 977 // error signals from the VCI RSP FSM to the ICACHE or DCACHE FSMs 978 for (uint32_t num_cpu=0; num_cpu<m_nb_cpu; ++num_cpu) 979 r_dcache_ll_valid [num_cache][num_cpu] = false; 980 981 // synchronisation flip-flops from TGT FSM to ICACHE & DCACHE FSMs 982 r_tgt_dcache_req [num_cache] = false; 983 r_tgt_dcache_rsp [num_cache] = false; 984 985 r_vci_rsp_data_error [num_cache] = false; 986 }// end for num_cache 987 988 r_cache_word = 0; 989 990 r_vci_cmd_dcache_prior = false; 991 r_vci_cmd_num_icache_prior = 0; 992 r_vci_cmd_num_dcache_prior = 0; 993 994 r_vci_rsp_fifo_icache_data .init(); 995 r_vci_rsp_fifo_icache_num_cache .init(); 996 r_vci_rsp_fifo_dcache_data .init(); 997 r_vci_rsp_fifo_dcache_num_cache .init(); 998 999 // activity counters 1000 m_cpt_dcache_data_read = 0; 1001 m_cpt_dcache_data_write = 0; 1002 m_cpt_dcache_dir_read = 0; 1003 m_cpt_dcache_dir_write = 0; 1004 m_cpt_icache_data_read = 0; 1005 m_cpt_icache_data_write = 0; 1006 m_cpt_icache_dir_read = 0; 1007 m_cpt_icache_dir_write = 0; 1008 1009 m_cpt_cc_update_icache = 0; 1010 m_cpt_cc_update_dcache = 0; 1011 m_cpt_cc_inval_broadcast = 0; 1012 m_cpt_cc_inval_icache = 0; 1013 m_cpt_cc_inval_dcache = 0; 1014 m_cpt_cc_update_icache_word_useful = 0; 1015 m_cpt_cc_update_dcache_word_useful = 0; 1016 1017 for (uint32_t num_cpu=0; num_cpu<m_nb_cpu; ++num_cpu) 1018 m_cpt_frz_cycles [num_cpu] = 0; 1019 m_cpt_total_cycles = 0; 1020 1021 m_cpt_data_read = 0; 1022 m_cpt_data_read_miss = 0; 1023 m_cpt_data_read_uncached = 0; 1024 m_cpt_data_write = 0; 1025 m_cpt_data_write_miss = 0; 1026 m_cpt_data_write_uncached = 0; 1027 1028 m_cpt_ins_miss = 0; 1029 1030 m_cost_write_frz = 0; 1031 m_cost_data_miss_frz = 0; 1032 m_cost_unc_read_frz = 0; 1033 m_cost_ins_miss_frz = 0; 1034 1035 m_cpt_imiss_transaction = 0; 1036 m_cpt_dmiss_transaction = 0; 1037 m_cpt_unc_transaction = 0; 1038 m_cpt_data_write_transaction = 0; 1039 1040 m_cost_imiss_transaction = 0; 1041 m_cost_dmiss_transaction = 0; 1042 m_cost_unc_transaction = 0; 1043 m_cost_write_transaction = 0; 1044 m_length_write_transaction = 0; 1045 1046 for (uint32_t num_cache=0; num_cache<m_nb_icache; ++num_cache) 1047 { 1048 m_cpt_icache_access [num_cache] = 0; 1049 m_cpt_icache_miss_victim_wait [num_cache] = 0; 1050 1051 for (uint32_t i=0; i<soclib::common::size(icache_fsm_state_str ); ++i) 1052 m_cpt_fsm_icache [num_cache][i] = 0; 1053 } 1054 for (uint32_t num_cache=0; num_cache<m_nb_dcache; ++num_cache) 1055 { 1056 m_cpt_dcache_access [num_cache] = 0; 1057 m_cpt_dcache_miss_victim_wait [num_cache] = 0; 1058 m_cpt_dcache_store_after_store [num_cache] = 0; 1059 m_cpt_dcache_hit_after_miss_read [num_cache] = 0; 1060 m_cpt_dcache_hit_after_miss_write [num_cache] = 0; 1061 for (uint32_t i=0; i<soclib::common::size(dcache_fsm_state_str ); ++i) 1062 m_cpt_fsm_dcache [num_cache][i] = 0; 1063 } 1064 1065 for (uint32_t i=0; i<soclib::common::size(cmd_fsm_state_str ); ++i) 1066 m_cpt_fsm_cmd [i] = 0; 1067 for (uint32_t i=0; i<soclib::common::size(rsp_fsm_state_str ); ++i) 1068 m_cpt_fsm_rsp [i] = 0; 1069 for (uint32_t i=0; i<soclib::common::size(tgt_fsm_state_str ); ++i) 1070 m_cpt_fsm_tgt [i] = 0; 1071 for (uint32_t i=0; i<soclib::common::size(cleanup_fsm_state_str); ++i) 1072 m_cpt_fsm_cleanup [i] = 0; 1073 1074 return; // reset is finish, quit the transition fonction 1075 } 1076 1077 bool vci_rsp_fifo_icache_get = false; 1078 bool vci_rsp_fifo_icache_put = false; 1079 data_t vci_rsp_fifo_icache_data = 0; 1080 uint32_t vci_rsp_fifo_icache_num_cache = 0; 1081 1082 bool vci_rsp_fifo_dcache_get = false; 1083 bool vci_rsp_fifo_dcache_put = false; 1084 data_t vci_rsp_fifo_dcache_data = 0; 1085 uint32_t vci_rsp_fifo_dcache_num_cache = 0; 1086 1087 ///////////////////////////////////////////////////////////////////// 1088 // VHDL TESTBENCH 1089 // Create and initialize variable 1090 ///////////////////////////////////////////////////////////////////// 1091 1092 #if MWBUF_VHDL_TESTBENCH 1093 simulation_started = true; 1094 1095 vhdl_tb_t vhdl_mwbuf_test_empty [m_nb_dcache]; 1096 vhdl_tb_t vhdl_mwbuf_port_empty [m_nb_dcache]; 1097 vhdl_tb_t vhdl_mwbuf_port_flush [m_nb_dcache]; 1098 vhdl_tb_t vhdl_mwbuf_port_write_val [m_nb_dcache]; 1099 vhdl_tb_t vhdl_mwbuf_test_write_ack [m_nb_dcache]; 1100 vhdl_tb_t vhdl_mwbuf_port_write_ack [m_nb_dcache]; 1101 vhdl_tb_t vhdl_mwbuf_port_write_addr [m_nb_dcache]; 1102 vhdl_tb_t vhdl_mwbuf_port_write_data [m_nb_dcache]; 1103 vhdl_tb_t vhdl_mwbuf_port_write_be [m_nb_dcache]; 1104 vhdl_tb_t vhdl_mwbuf_port_write_cached [m_nb_dcache]; 1105 vhdl_tb_t vhdl_mwbuf_port_write_cpu_id [m_nb_dcache]; 1106 vhdl_tb_t vhdl_mwbuf_test_sent_val [m_nb_dcache]; 1107 vhdl_tb_t vhdl_mwbuf_port_sent_val [m_nb_dcache]; 1108 vhdl_tb_t vhdl_mwbuf_port_sent_ack [m_nb_dcache]; 1109 vhdl_tb_t vhdl_mwbuf_test_sent_word_min [m_nb_dcache]; 1110 vhdl_tb_t vhdl_mwbuf_port_sent_word_min [m_nb_dcache]; 1111 vhdl_tb_t vhdl_mwbuf_test_sent_word_max [m_nb_dcache]; 1112 vhdl_tb_t vhdl_mwbuf_port_sent_word_max [m_nb_dcache]; 1113 vhdl_tb_t vhdl_mwbuf_port_sent_word [m_nb_dcache]; 1114 vhdl_tb_t vhdl_mwbuf_test_sent_addr [m_nb_dcache]; 1115 vhdl_tb_t vhdl_mwbuf_port_sent_addr [m_nb_dcache]; 1116 vhdl_tb_t vhdl_mwbuf_test_sent_data [m_nb_dcache]; 1117 vhdl_tb_t vhdl_mwbuf_port_sent_data [m_nb_dcache]; 1118 vhdl_tb_t vhdl_mwbuf_test_sent_be [m_nb_dcache]; 1119 vhdl_tb_t vhdl_mwbuf_port_sent_be [m_nb_dcache]; 1120 vhdl_tb_t vhdl_mwbuf_test_sent_index [m_nb_dcache]; 1121 vhdl_tb_t vhdl_mwbuf_port_sent_index [m_nb_dcache]; 1122 vhdl_tb_t vhdl_mwbuf_port_raw_test [m_nb_dcache]; 1123 vhdl_tb_t vhdl_mwbuf_port_raw_addr [m_nb_dcache]; 1124 vhdl_tb_t vhdl_mwbuf_test_raw_miss [m_nb_dcache]; 1125 vhdl_tb_t vhdl_mwbuf_port_raw_miss [m_nb_dcache]; 1126 vhdl_tb_t vhdl_mwbuf_port_completed_val [m_nb_dcache]; 1127 vhdl_tb_t vhdl_mwbuf_port_completed_index [m_nb_dcache]; 1128 vhdl_tb_t vhdl_mwbuf_test_completed_cached [m_nb_dcache]; 1129 vhdl_tb_t vhdl_mwbuf_port_completed_cached [m_nb_dcache]; 1130 vhdl_tb_t vhdl_mwbuf_test_completed_cpu_id [m_nb_dcache]; 1131 vhdl_tb_t vhdl_mwbuf_port_completed_cpu_id [m_nb_dcache]; 1132 1133 for (uint32_t num_dcache=0; num_dcache<m_nb_dcache; ++num_dcache) 1134 { 1135 vhdl_mwbuf_test_empty [num_dcache] = 0; 1136 vhdl_mwbuf_port_empty [num_dcache] = 0; 1137 vhdl_mwbuf_port_flush [num_dcache] = 0; 1138 vhdl_mwbuf_port_write_val [num_dcache] = 0; 1139 vhdl_mwbuf_test_write_ack [num_dcache] = 0; 1140 vhdl_mwbuf_port_write_ack [num_dcache] = 0; 1141 vhdl_mwbuf_port_write_addr [num_dcache] = 0; 1142 vhdl_mwbuf_port_write_data [num_dcache] = 0; 1143 vhdl_mwbuf_port_write_be [num_dcache] = 0; 1144 vhdl_mwbuf_port_write_cached [num_dcache] = 0; 1145 vhdl_mwbuf_port_write_cpu_id [num_dcache] = 0; 1146 vhdl_mwbuf_test_sent_val [num_dcache] = 0; 1147 vhdl_mwbuf_port_sent_val [num_dcache] = 0; 1148 vhdl_mwbuf_port_sent_ack [num_dcache] = 0; 1149 vhdl_mwbuf_test_sent_word_min [num_dcache] = 0; 1150 vhdl_mwbuf_port_sent_word_min [num_dcache] = 0; 1151 vhdl_mwbuf_test_sent_word_max [num_dcache] = 0; 1152 vhdl_mwbuf_port_sent_word_max [num_dcache] = 0; 1153 vhdl_mwbuf_port_sent_word [num_dcache] = 0; 1154 vhdl_mwbuf_test_sent_addr [num_dcache] = 0; 1155 vhdl_mwbuf_port_sent_addr [num_dcache] = 0; 1156 vhdl_mwbuf_test_sent_data [num_dcache] = 0; 1157 vhdl_mwbuf_port_sent_data [num_dcache] = 0; 1158 vhdl_mwbuf_test_sent_be [num_dcache] = 0; 1159 vhdl_mwbuf_port_sent_be [num_dcache] = 0; 1160 vhdl_mwbuf_test_sent_index [num_dcache] = 0; 1161 vhdl_mwbuf_port_sent_index [num_dcache] = 0; 1162 vhdl_mwbuf_port_raw_test [num_dcache] = 0; 1163 vhdl_mwbuf_port_raw_addr [num_dcache] = 0; 1164 vhdl_mwbuf_test_raw_miss [num_dcache] = 0; 1165 vhdl_mwbuf_port_raw_miss [num_dcache] = 0; 1166 vhdl_mwbuf_port_completed_val [num_dcache] = 0; 1167 vhdl_mwbuf_port_completed_index [num_dcache] = 0; 1168 vhdl_mwbuf_test_completed_cached [num_dcache] = 0; 1169 vhdl_mwbuf_port_completed_cached [num_dcache] = 0; 1170 vhdl_mwbuf_test_completed_cpu_id [num_dcache] = 0; 1171 vhdl_mwbuf_port_completed_cpu_id [num_dcache] = 0; 1172 } 500 1173 #endif 501 1174 502 503 // internal messages in DCACHE et ICACHE FSMs 504 r_icache_inval_rsp = false; 505 r_dcache_inval_rsp = false; 506 507 // error signals from the VCI RSP FSM to the ICACHE or DCACHE FSMs 508 r_dcache_ll_valid = false; 509 r_icache_buf_unc_valid = false; 510 511 r_vci_cmd_dcache_prior = false; 512 513 r_vci_rsp_data_error = false; 514 r_vci_rsp_ins_error = false; 515 516 CACHE_MISS_BUF_RESET(i); 517 CACHE_MISS_BUF_RESET(d); 518 519 // activity counters 520 m_cpt_dcache_data_read = 0; 521 m_cpt_dcache_data_write = 0; 522 m_cpt_dcache_dir_read = 0; 523 m_cpt_dcache_dir_write = 0; 524 m_cpt_icache_data_read = 0; 525 m_cpt_icache_data_write = 0; 526 m_cpt_icache_dir_read = 0; 527 m_cpt_icache_dir_write = 0; 528 529 m_cpt_cc_update_icache = 0; 530 m_cpt_cc_update_dcache = 0; 531 m_cpt_cc_inval_broadcast = 0; 532 m_cpt_cc_inval_icache = 0; 533 m_cpt_cc_inval_dcache = 0; 534 m_cpt_cc_update_icache_word_useful = 0; 535 m_cpt_cc_update_dcache_word_useful = 0; 536 537 m_cpt_frz_cycles = 0; 538 m_cpt_total_cycles = 0; 539 540 m_cpt_data_read = 0; 541 m_cpt_data_read_miss = 0; 542 m_cpt_data_read_uncached = 0; 543 m_cpt_data_write = 0; 544 m_cpt_data_write_miss = 0; 545 m_cpt_data_write_uncached = 0; 546 547 m_cpt_ins_miss = 0; 548 549 m_cost_write_frz = 0; 550 m_cost_data_miss_frz = 0; 551 m_cost_unc_read_frz = 0; 552 m_cost_ins_miss_frz = 0; 553 554 m_cpt_imiss_transaction = 0; 555 m_cpt_dmiss_transaction = 0; 556 m_cpt_unc_transaction = 0; 557 m_cpt_data_write_transaction = 0; 558 559 m_cost_imiss_transaction = 0; 560 m_cost_dmiss_transaction = 0; 561 m_cost_unc_transaction = 0; 562 m_cost_write_transaction = 0; 563 m_length_write_transaction = 0; 564 565 return; 566 } 567 568 // printf("%d\n",(uint32_t)m_cpt_total_cycles); 569 570 PRINTF("--------------------------------------------\n"); 571 PRINTF(" * CC_XCACHE_WRAPPER \"%s\" - Time = %d\n",name().c_str(),(uint32_t)m_cpt_total_cycles); 572 PRINTF(" * fsm dcache = %s\n",dcache_fsm_state_str[r_dcache_fsm]); 573 PRINTF(" * fsm icache = %s\n",icache_fsm_state_str[r_icache_fsm]); 574 PRINTF(" * fsm cmd = %s\n",cmd_fsm_state_str[r_vci_cmd_fsm]); 575 PRINTF(" * fsm rsp = %s\n",rsp_fsm_state_str[r_vci_rsp_fsm]); 576 PRINTF(" * fsm tgt = %s\n",tgt_fsm_state_str[r_vci_tgt_fsm]); 577 PRINTF(" * fsm cleanup = %s\n",cleanup_fsm_state_str[r_cleanup_fsm]); 578 PRINTF(" * ll info : %d %llx %llx\n",r_dcache_ll_valid.read(), (uint64_t)r_dcache_ll_addr.read(), (uint64_t)r_dcache_ll_data.read()); 579 PRINTF(" * dcache_previous_unc : %d\n",r_dcache_previous_unc.read()); 580 // CACHE_MISS_BUF_RSP_PRINT(i); 581 // CACHE_MISS_BUF_RSP_PRINT(d); 1175 ///////////////////////////////////////////////////////////////////// 1176 // DEBUG : 1177 // print state of all fsm and main register 1178 ///////////////////////////////////////////////////////////////////// 1179 1180 // printf("%d\n",(uint32_t)m_cpt_total_cycles); 1181 1182 PRINTF("--------------------------------------------\n"); 1183 PRINTF(" * CC_XCACHE_WRAPPER \"%s\" Transition - Time = %d\n",name().c_str(),(uint32_t)m_cpt_total_cycles); 1184 for (uint32_t num_cache=0; num_cache<m_nb_dcache; ++num_cache) 1185 PRINTF(" * fsm dcache = [%.2d] %s - (%.2d) %llx (%llx)\n",num_cache,dcache_fsm_state_str[r_dcache_fsm[num_cache]],r_dcache_lock[num_cache].read(),(blob_t)r_dcache_addr_save[num_cache].read(),(blob_t)set_num_dcache_only(r_dcache_addr_save[num_cache].read(),num_cache)); 1186 for (uint32_t num_cache=0; num_cache<m_nb_icache; ++num_cache) 1187 PRINTF(" * fsm icache = [%.2d] %s - (%.2d) %llx (%llx)\n",num_cache,icache_fsm_state_str[r_icache_fsm[num_cache]],r_icache_lock[num_cache].read(),(blob_t)r_icache_addr_save[num_cache].read(),(blob_t)set_num_icache_only(r_icache_addr_save[num_cache].read(),num_cache)); 1188 PRINTF(" * fsm cmd = (%.2d) %s\n",r_vci_cmd_num_cache.read(), cmd_fsm_state_str[r_vci_cmd_fsm]); 1189 PRINTF(" * fsm rsp = (%.2d) %s\n",r_vci_rsp_num_cache.read(), rsp_fsm_state_str[r_vci_rsp_fsm]); 1190 PRINTF(" * fsm tgt = (%.2d) %s - i %llx d %llx\n",r_tgt_num_cache.read(), tgt_fsm_state_str[r_vci_tgt_fsm],(blob_t)r_tgt_iaddr.read(),(blob_t)r_tgt_daddr.read()); 1191 //PRINTF(" * fsm tgt = %s - %llx\n",tgt_fsm_state_str[r_vci_tgt_fsm],(blob_t)r_tgt_addr.read()); 1192 PRINTF(" * fsm cleanup = (%.2d) %s\n",r_cleanup_num_cache.read(), cleanup_fsm_state_str[r_cleanup_fsm]); 1193 for (uint32_t num_cache=0; num_cache<m_nb_dcache; ++num_cache) 1194 { 1195 for (uint32_t num_cpu=0; num_cpu<m_nb_cpu; ++num_cpu) 1196 PRINTF(" * ll info : [%.2d][%.2d] %d %llx (%llx) %llx\n" 1197 ,num_cache 1198 ,num_cpu 1199 , r_dcache_ll_valid [num_cache][num_cpu].read() 1200 ,(blob_t)r_dcache_ll_addr [num_cache][num_cpu].read() 1201 ,(blob_t)set_num_dcache_only(r_dcache_ll_addr [num_cache][num_cpu].read(),num_cache) 1202 ,(blob_t)r_dcache_ll_data [num_cache][num_cpu].read()); 1203 1204 PRINTF(" * dcache_previous_unc : [%.2d] %d\n",num_cache,r_dcache_previous_unc[num_cache].read()); 582 1205 583 1206 #if CC_XCACHE_WRAPPER_DEBUG 584 if (m_cpt_total_cycles>=CC_XCACHE_WRAPPER_DEBUG_CYCLE_MIN) 585 { 586 r_wbuf.printTrace(1); 587 } 1207 if (m_cpt_total_cycles>=CC_XCACHE_WRAPPER_DEBUG_CYCLE_MIN) 1208 r_wbuf[num_cache]->printTrace(1); 588 1209 #endif 589 1210 590 m_cpt_total_cycles++; 591 592 ///////////////////////////////////////////////////////////////////// 593 // The TGT_FSM controls the following ressources: 594 // - r_vci_tgt_fsm 595 // - r_tgt_buf[nwords] 596 // - r_tgt_be[nwords] 597 // - r_tgt_update 598 // - r_tgt_word 599 // - r_tgt_addr 600 // - r_tgt_srcid 601 // - r_tgt_trdid 602 // - r_tgt_pktid 603 // All VCI commands must be CMD_WRITE. 604 // If the VCI address offset is null, the command is an invalidate 605 // request. It is an update request otherwise. 606 // The VCI_TGT FSM stores the external request arguments in the 607 // IDLE, UPDT_WORD & UPDT_DATA states. It sets the r_tgt_icache_req 608 // & r_tgt_dcache_req flip-flops to signal the external request to 609 // the ICACHE & DCACHE FSMs in the REQ state. It waits the completion 610 // of the update or invalidate request in the RSP state. 611 // - for an invalidate request the VCI packet length is 1 word. 612 // The WDATA field contains the line index (i.e. the Z & Y fields). 613 // - for an update request the VCI packet length is (n+2) words. 614 // The WDATA field of the first VCI word contains the line number. 615 // The WDATA field of the second VCI word contains the word index. 616 // The WDATA field of the n following words contains the values. 617 // - for both invalidate & update requests, the VCI response 618 // is one single word. 619 // In case of errors in the VCI command packet, the simulation 620 // is stopped with an error message. 621 ///////////////////////////////////////////////////////////////////// 622 623 switch(r_vci_tgt_fsm) { 624 625 case TGT_IDLE: 626 if ( p_vci_tgt.cmdval.read() ) 627 { 628 PRINTF(" * <TGT> request\n"); 629 630 addr_40 address = p_vci_tgt.address.read(); 631 632 if ( p_vci_tgt.cmd.read() != vci_param::CMD_WRITE) 633 { 1211 // VHDL debug 1212 // #if MWBUF_VHDL_TESTBENCH 1213 // printf("\nMWBUF[%d] - Time = %d\n\n",num_cache,(uint32_t)m_cpt_total_cycles); 1214 // r_wbuf[num_cache]->printTrace(1); 1215 // #endif 1216 1217 } 1218 1219 ///////////////////////////////////////////////////////////////////// 1220 // Statistics 1221 // Count state fsm activity 1222 ///////////////////////////////////////////////////////////////////// 1223 1224 1225 for (uint32_t num_cache=0; num_cache<m_nb_dcache; ++num_cache) 1226 m_cpt_fsm_dcache [num_cache][r_dcache_fsm[num_cache]] ++; 1227 for (uint32_t num_cache=0; num_cache<m_nb_icache; ++num_cache) 1228 m_cpt_fsm_icache [num_cache][r_icache_fsm[num_cache]] ++; 1229 m_cpt_fsm_cmd [r_vci_cmd_fsm] ++; 1230 m_cpt_fsm_rsp [r_vci_rsp_fsm] ++; 1231 m_cpt_fsm_tgt [r_vci_tgt_fsm] ++; 1232 m_cpt_fsm_cleanup [r_cleanup_fsm] ++; 1233 1234 m_cpt_total_cycles++; 1235 1236 ///////////////////////////////////////////////////////////////////// 1237 // The TGT_FSM controls the following ressources: 1238 // - r_vci_tgt_fsm 1239 // - r_tgt_buf[nwords] 1240 // - r_tgt_be[nwords] 1241 // - r_tgt_update 1242 // - r_tgt_word 1243 // - r_tgt_addr 1244 // - r_tgt_srcid 1245 // - r_tgt_trdid 1246 // - r_tgt_pktid 1247 // All VCI commands must be CMD_WRITE. 1248 // If the VCI address offset is null, the command is an invalidate 1249 // request. It is an update request otherwise. 1250 // The VCI_TGT FSM stores the external request arguments in the 1251 // IDLE, UPDT_WORD & UPDT_DATA states. It sets the r_tgt_icache_req 1252 // & r_tgt_dcache_req flip-flops to signal the external request to 1253 // the ICACHE & DCACHE FSMs in the REQ state. It waits the completion 1254 // of the update or invalidate request in the RSP state. 1255 // - for an invalidate request the VCI packet length is 1 word. 1256 // The WDATA field contains the line index (i.e. the Z & Y fields). 1257 // - for an update request the VCI packet length is (n+2) words. 1258 // The WDATA field of the first VCI word contains the line number. 1259 // The WDATA field of the second VCI word contains the word index. 1260 // The WDATA field of the n following words contains the values. 1261 // - for both invalidate & update requests, the VCI response 1262 // is one single word. 1263 // In case of errors in the VCI command packet, the simulation 1264 // is stopped with an error message. 1265 ///////////////////////////////////////////////////////////////////// 1266 1267 switch(r_vci_tgt_fsm) { 1268 1269 case TGT_IDLE: 1270 if ( p_vci_tgt.cmdval.read() ) 1271 { 1272 PRINTF(" * <TGT> Request\n"); 1273 1274 addr_40 address = p_vci_tgt.address.read(); 1275 1276 if ( p_vci_tgt.cmd.read() != vci_param::CMD_WRITE) 1277 { 1278 std::cout << "error in component VCI_CC_XCACHE_WRAPPER " << name() << std::endl; 1279 std::cout << "coherence request is not a write" << std::endl; 1280 std::cout << "address = " << std::hex << address << std::dec << std::endl; 1281 std::cout << "srcid = " << p_vci_tgt.srcid.read() << std::endl; 1282 exit(0); 1283 } 1284 1285 // multi-update or multi-invalidate for data type 1286 if ( ((address&0x3) != 0x3) and (not m_segment.contains(address)) ) 1287 { 1288 std::cout << "error in component VCI_CC_XCACHE_WRAPPER " << name() << std::endl; 1289 std::cout << "out of segment coherence request" << std::endl; 1290 std::cout << "address = " << std::hex << address << std::dec << std::endl; 1291 std::cout << "srcid = " << p_vci_tgt.srcid.read() << std::endl; 1292 exit(0); 1293 } 1294 1295 addr_40 tgt_addr = ((((addr_40)p_vci_tgt.be.read() & 0x3) << 32) | ((addr_40) p_vci_tgt.wdata.read())) << (addr_40)m_dcache_words_shift; 1296 // * m_dcache_words * 4; 1297 1298 addr_40 tgt_iaddr = tgt_addr; 1299 addr_40 tgt_daddr = tgt_addr; 1300 1301 PRINTF(" * <TGT> srcid : %d\n",(uint32_t)p_vci_tgt.srcid.read()); 1302 PRINTF(" * <TGT> trdid : %d\n",(uint32_t)p_vci_tgt.trdid.read()); 1303 PRINTF(" * <TGT> pktid : %d\n",(uint32_t)p_vci_tgt.pktid.read()); 1304 PRINTF(" * <TGT> address (before) : %llx\n",(blob_t)tgt_iaddr); 1305 1306 r_tgt_srcid = p_vci_tgt.srcid.read(); 1307 r_tgt_trdid = p_vci_tgt.trdid.read(); 1308 r_tgt_pktid = p_vci_tgt.pktid.read(); 1309 // r_tgt_plen = p_vci_tgt.plen.read(); 1310 1311 // BROADCAST 1312 if ( (address&0x3) == 0x3 ) // broadcast invalidate for data or instruction type 1313 { 1314 if ( not p_vci_tgt.eop.read() ) 1315 { 1316 std::cout << "error in component VCI_CC_XCACHE_WRAPPER " << name() << std::endl; 1317 std::cout << "the BROADCAST INVALIDATE command length must be one word" << std::endl; 1318 exit(0); 1319 } 1320 r_tgt_update = false; 1321 // r_tgt_brdcast= true; 1322 r_vci_tgt_fsm = TGT_REQ_BROADCAST; 1323 uint32_t tgt_num_cache; 1324 tgt_num_cache = get_num_icache(tgt_iaddr,0); // none effect (else CC_XCACHE_WRAPPER_MULTI_CACHE==1) 1325 tgt_num_cache = get_num_dcache(tgt_daddr); 1326 r_tgt_num_cache = tgt_num_cache; 1327 1328 PRINTF(" * <TGT> REQ_BROADCAST\n"); 1329 PRINTF(" * <TGT> num_cache (data) : %d\n",tgt_num_cache); 1330 1331 m_cpt_cc_inval_broadcast++ ; 1332 1333 #if CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION 1334 if (generate_log_transaction_file_tgt) 1335 { 1336 log_transaction_file_tgt 1337 << "[" << m_cpt_total_cycles << "] " 1338 << "BROADCAST " 1339 << std::hex 1340 << " L " << std::setw(10) << (blob_t)tgt_addr 1341 << std::dec 1342 << " - " << tgt_num_cache 1343 << std::endl; 1344 } 1345 #endif //CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION 1346 1347 } 1348 else // multi-update or multi-invalidate for data type 1349 { 1350 uint32_t cell = address - m_segment.baseAddress(); // addr_40 1351 // r_tgt_brdcast = false; 1352 1353 if (cell == 0) 1354 { // invalidate data 1355 if ( not p_vci_tgt.eop.read() ) 1356 { 634 1357 std::cout << "error in component VCI_CC_XCACHE_WRAPPER " << name() << std::endl; 635 std::cout << "coherence request is not a write" << std::endl; 636 std::cout << "oddress = " << std::hex << address << std::dec << std::endl; 637 std::cout << "srcid = " << p_vci_tgt.srcid.read() << std::endl; 1358 std::cout << "the MULTI-INVALIDATE command length must be one word" << std::endl; 638 1359 exit(0); 639 } 640 641 // multi-update or multi-invalidate for data type 642 if ( ((address&0x3) != 0x3) and (not m_segment.contains(address)) ) 643 { 644 std::cout << "error in component VCI_CC_XCACHE_WRAPPER " << name() << std::endl; 645 std::cout << "out of segment coherence request" << std::endl; 646 std::cout << "oddress = " << std::hex << address << std::dec << std::endl; 647 std::cout << "srcid = " << p_vci_tgt.srcid.read() << std::endl; 1360 } 1361 r_tgt_update = false; 1362 r_vci_tgt_fsm = TGT_REQ_DCACHE; 1363 uint32_t tgt_num_cache = get_num_dcache(tgt_daddr); // static partionnement 1364 r_tgt_num_cache = tgt_num_cache; 1365 1366 PRINTF(" * <TGT> REQ_DCACHE\n"); 1367 PRINTF(" * <TGT> num_cache : %d\n",tgt_num_cache); 1368 1369 m_cpt_cc_inval_dcache++ ; 1370 1371 #if CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION 1372 if (generate_log_transaction_file_tgt) 1373 { 1374 log_transaction_file_tgt 1375 << "[" << m_cpt_total_cycles << "] " 1376 << "INVAL DATA " 1377 << std::hex 1378 << " L " << std::setw(10) << (blob_t)tgt_addr 1379 << std::dec 1380 << " - " << tgt_num_cache 1381 << std::endl; 1382 } 1383 #endif //CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION 1384 1385 } 1386 else if (cell == 4) // invalidate instruction 1387 { 1388 if ( not p_vci_tgt.eop.read() ) 1389 { 1390 std::cout << "error in component VCI_CC_VCACHE_WRAPPER " << name() << std::endl; 1391 std::cout << "the MULTI-INVALIDATE command length must be one word" << std::endl; 648 1392 exit(0); 649 } 650 651 r_tgt_addr = (((addr_40) ((p_vci_tgt.be.read() & 0x3) << 32)) | 652 ((addr_40) (p_vci_tgt.wdata.read()))) * m_dcache_words * 4; 653 r_tgt_srcid = p_vci_tgt.srcid.read(); 654 r_tgt_trdid = p_vci_tgt.trdid.read(); 655 r_tgt_pktid = p_vci_tgt.pktid.read(); 656 // r_tgt_plen = p_vci_tgt.plen.read(); 657 658 PRINTF(" * <TGT> address : %llx\n",(uint64_t)address); 659 PRINTF(" * <TGT> address : %llx\n",(uint64_t)((((addr_40) ((p_vci_tgt.be.read() & 0x3) << 32)) | 660 ((addr_40) (p_vci_tgt.wdata.read()))) * m_dcache_words * 4)); 661 662 if ( (address&0x3) == 0x3 ) // broadcast invalidate for data or instruction type 663 { 664 if ( not p_vci_tgt.eop.read() ) 665 { 666 std::cout << "error in component VCI_CC_XCACHE_WRAPPER " << name() << std::endl; 667 std::cout << "the BROADCAST INVALIDATE command length must be one word" << std::endl; 668 exit(0); 669 } 670 r_tgt_update = false; 671 // r_tgt_brdcast= true; 672 r_vci_tgt_fsm = TGT_REQ_BROADCAST; 673 m_cpt_cc_inval_broadcast++ ; 674 } 675 else // multi-update or multi-invalidate for data type 676 { 677 uint32_t cell = address - m_segment.baseAddress(); // addr_40 678 // r_tgt_brdcast = false; 679 if (cell == 0) 680 { // invalidate data 681 if ( not p_vci_tgt.eop.read() ) 682 { 683 std::cout << "error in component VCI_CC_XCACHE_WRAPPER " << name() << std::endl; 684 std::cout << "the MULTI-INVALIDATE command length must be one word" << std::endl; 685 exit(0); 686 } 687 r_tgt_update = false; 688 r_vci_tgt_fsm = TGT_REQ_DCACHE; 689 m_cpt_cc_inval_dcache++ ; 690 } 691 else if (cell == 4) // invalidate instruction 692 { 693 if ( not p_vci_tgt.eop.read() ) 694 { 695 std::cout << "error in component VCI_CC_VCACHE_WRAPPER " << name() << std::endl; 696 std::cout << "the MULTI-INVALIDATE command length must be one word" << std::endl; 697 exit(0); 698 } 699 r_tgt_update = false; 700 r_vci_tgt_fsm = TGT_REQ_ICACHE; 701 m_cpt_cc_inval_icache++ ; 702 } 703 else if ( (cell == 8) or (cell==12) ) // update data or instruction 704 { 705 if ( p_vci_tgt.eop.read() ) 706 { 707 std::cout << "error in component VCI_CC_VCACHE_WRAPPER " << name() << std::endl; 708 std::cout << "the MULTI-UPDATE command length must be N+2 words" << std::endl; 709 exit(0); 710 } 711 if(cell == 8) 712 { 713 m_cpt_cc_update_dcache++; 714 r_tgt_update_data = true; 715 } 716 else 717 { 718 m_cpt_cc_update_icache++; 719 r_tgt_update_data = false; 720 } 721 r_tgt_update = true; 722 r_vci_tgt_fsm = TGT_UPDT_WORD; 723 } 724 725 } // end if address 726 } // end if cmdval 727 break; 728 729 case TGT_UPDT_WORD: 730 if (p_vci_tgt.cmdval.read()) 731 { 1393 } 1394 r_tgt_update = false; 1395 r_vci_tgt_fsm = TGT_REQ_ICACHE; 1396 uint32_t tgt_num_cpu = p_vci_tgt.pktid.read(); 1397 uint32_t tgt_num_cache = get_num_icache(tgt_iaddr,tgt_num_cpu); 1398 r_tgt_num_cache = tgt_num_cache; 1399 1400 PRINTF(" * <TGT> REQ_ICACHE\n"); 1401 PRINTF(" * <TGT> num_cache : %d\n",tgt_num_cache); 1402 1403 m_cpt_cc_inval_icache++ ; 1404 1405 #if CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION 1406 if (generate_log_transaction_file_tgt) 1407 { 1408 log_transaction_file_tgt 1409 << "[" << m_cpt_total_cycles << "] " 1410 << "INVAL INS " 1411 << std::hex 1412 << " L " << std::setw(10) << (blob_t)tgt_addr 1413 << std::dec 1414 << " - " << tgt_num_cache 1415 << std::endl; 1416 } 1417 #endif //CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION 1418 1419 } 1420 else if ( (cell == 8) or (cell==12) ) // update data or instruction 1421 { 732 1422 if ( p_vci_tgt.eop.read() ) 733 {734 std::cout << "error in component VCI_CC_ XCACHE_WRAPPER " << name() << std::endl;1423 { 1424 std::cout << "error in component VCI_CC_VCACHE_WRAPPER " << name() << std::endl; 735 1425 std::cout << "the MULTI-UPDATE command length must be N+2 words" << std::endl; 736 1426 exit(0); 737 } 738 for ( size_t i=0 ; i<m_dcache_words ; i++ ) r_tgt_be[i] = 0; 739 r_tgt_word = p_vci_tgt.wdata.read(); // the first modified word index 740 #ifdef COHERENCE_DEBUG 741 std::cout << "PROC " << m_srcid_rw << " update, line : " << std::hex << r_tgt_addr.read() << " word : " << p_vci_tgt.wdata.read() << std::dec << std::endl; 1427 } 1428 if(cell == 8) 1429 { 1430 m_cpt_cc_update_dcache++; 1431 r_tgt_update_data = true; 1432 1433 uint32_t tgt_num_cache = get_num_dcache(tgt_daddr); 1434 r_tgt_num_cache = tgt_num_cache; 1435 1436 PRINTF(" * <TGT> UPDT_WORD DATA\n"); 1437 PRINTF(" * <TGT> num_cache : %d\n",tgt_num_cache); 1438 1439 #if CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION 1440 if (generate_log_transaction_file_tgt) 1441 { 1442 log_transaction_file_tgt 1443 << "[" << m_cpt_total_cycles << "] " 1444 << "UPT DATA " 1445 << std::hex 1446 << " L " << std::setw(10) << (blob_t)tgt_addr 1447 << std::dec 1448 << " - " << tgt_num_cache 1449 << std::endl; 1450 } 1451 #endif //CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION 1452 } 1453 else 1454 { 1455 m_cpt_cc_update_icache++; 1456 r_tgt_update_data = false; 1457 1458 uint32_t tgt_num_cpu = p_vci_tgt.pktid.read(); 1459 uint32_t tgt_num_cache = get_num_icache(tgt_iaddr,tgt_num_cpu); 1460 r_tgt_num_cache = tgt_num_cache; 1461 1462 PRINTF(" * <TGT> UPDT_WORD INSTRUCTION\n"); 1463 PRINTF(" * <TGT> num_cache : %d\n",tgt_num_cache); 1464 1465 #if CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION 1466 if (generate_log_transaction_file_tgt) 1467 { 1468 log_transaction_file_tgt 1469 << "[" << m_cpt_total_cycles << "] " 1470 << "UPT INS " 1471 << std::hex 1472 << " L " << std::setw(10) << (blob_t)tgt_addr 1473 << std::dec 1474 << " - " << tgt_num_cache 1475 << std::endl; 1476 } 1477 #endif //CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION 1478 } 1479 r_tgt_update = true; 1480 r_vci_tgt_fsm = TGT_UPDT_WORD; 1481 } 1482 1483 } // end if address 1484 1485 r_tgt_iaddr = tgt_iaddr; 1486 r_tgt_daddr = tgt_daddr; 1487 PRINTF(" * <TGT> address (after) : i %llx, d %llx\n",(blob_t)tgt_iaddr,(blob_t)tgt_daddr); 1488 1489 } // end if cmdval 1490 break; 1491 1492 case TGT_UPDT_WORD: 1493 if (p_vci_tgt.cmdval.read()) 1494 { 1495 if ( p_vci_tgt.eop.read() ) 1496 { 1497 std::cout << "error in component VCI_CC_XCACHE_WRAPPER " << name() << std::endl; 1498 std::cout << "the MULTI-UPDATE command length must be N+2 words" << std::endl; 1499 exit(0); 1500 } 1501 for ( size_t i=0 ; i<m_dcache_words ; i++ ) r_tgt_be[i] = 0; 1502 r_tgt_word = p_vci_tgt.wdata.read(); // the first modified word index 1503 r_vci_tgt_fsm = TGT_UPDT_DATA; 1504 } 1505 break; 1506 1507 case TGT_UPDT_DATA: 1508 if (p_vci_tgt.cmdval.read()) 1509 { 1510 size_t word = r_tgt_word.read(); 1511 if ( word >= m_cache_words ) 1512 { 1513 std::cout << "error in component VCI_CC_XCACHE_WRAPPER " << name() << std::endl; 1514 std::cout << "the reveived MULTI-UPDATE command length is wrong" << std::endl; 1515 exit(0); 1516 } 1517 1518 r_tgt_buf[word] = p_vci_tgt.wdata.read(); 1519 r_tgt_be [word] = p_vci_tgt.be.read(); 1520 1521 if (p_vci_tgt.be.read()) 1522 { 1523 if(r_tgt_update_data.read()) 1524 m_cpt_cc_update_dcache_word_useful++ ; 1525 else 1526 m_cpt_cc_update_icache_word_useful++ ; 1527 } 1528 1529 r_tgt_word = word + 1; 1530 if (p_vci_tgt.eop.read()){ 1531 1532 uint32_t word=0; 1533 for (; word<m_cache_words; ++word) 1534 if (r_tgt_be[word] != 0) 1535 break; 1536 r_cache_word = word; 1537 1538 if(r_tgt_update_data.read()){ 1539 r_vci_tgt_fsm = TGT_REQ_DCACHE; 1540 } else { 1541 r_vci_tgt_fsm = TGT_REQ_ICACHE; 1542 } 1543 } 1544 } 1545 break; 1546 1547 case TGT_REQ_BROADCAST: 1548 { 1549 bool tgt_icache_req; 1550 1551 #if (CC_XCACHE_WRAPPER_MULTI_CACHE==1) 1552 tgt_icache_req = r_tgt_icache_req[r_tgt_num_cache].read(); 1553 #elif (CC_XCACHE_WRAPPER_MULTI_CACHE==2) 1554 tgt_icache_req = false; 1555 for (uint32_t num_cache=0; num_cache<m_nb_icache; ++num_cache) 1556 tgt_icache_req |= r_tgt_icache_req[num_cache].read(); 742 1557 #endif 743 r_vci_tgt_fsm = TGT_UPDT_DATA; 1558 if (not tgt_icache_req and not r_tgt_dcache_req[r_tgt_num_cache].read()) 1559 { 1560 r_vci_tgt_fsm = TGT_RSP_BROADCAST; 1561 1562 #if (CC_XCACHE_WRAPPER_MULTI_CACHE==1) 1563 r_tgt_icache_req[r_tgt_num_cache] = true; 1564 #elif (CC_XCACHE_WRAPPER_MULTI_CACHE==2) 1565 for (uint32_t num_cache=0; num_cache<m_nb_icache; ++num_cache) 1566 r_tgt_icache_req[ num_cache] = true; 1567 #endif 1568 1569 r_tgt_dcache_req[r_tgt_num_cache] = true; 1570 } 1571 } 1572 break; 1573 //////////////////// 1574 case TGT_REQ_ICACHE: 1575 { 1576 // Request treated by the icache 1577 if ( not r_tgt_icache_req[r_tgt_num_cache].read() ) 1578 { 1579 r_vci_tgt_fsm = TGT_RSP_ICACHE; 1580 r_tgt_icache_req[r_tgt_num_cache] = true; 1581 } 1582 break; 1583 } 1584 1585 case TGT_REQ_DCACHE: 1586 { 1587 // Request treated by the dcache 1588 1589 if ( not r_tgt_dcache_req[r_tgt_num_cache].read() ) 1590 { 1591 r_vci_tgt_fsm = TGT_RSP_DCACHE; 1592 r_tgt_dcache_req[r_tgt_num_cache] = true; 1593 } 1594 break; 1595 } 1596 case TGT_RSP_BROADCAST: 1597 { 1598 PRINTF(" * <TGT> dcache[%d] : %d - %d\n",(uint32_t)r_tgt_num_cache, (uint32_t)r_tgt_dcache_req[r_tgt_num_cache].read(),(uint32_t)r_tgt_dcache_rsp[r_tgt_num_cache].read()); 1599 for (uint32_t num_cache=0; num_cache<m_nb_icache; ++num_cache) 1600 PRINTF(" * <TGT> icache[%d] : %d - %d\n",(uint32_t)num_cache, (uint32_t)r_tgt_icache_req[num_cache].read(),(uint32_t)r_tgt_icache_rsp[num_cache].read()); 1601 1602 bool tgt_icache_req; 1603 1604 #if (CC_XCACHE_WRAPPER_MULTI_CACHE==1) 1605 tgt_icache_req = r_tgt_icache_req[r_tgt_num_cache].read(); 1606 #elif (CC_XCACHE_WRAPPER_MULTI_CACHE==2) 1607 tgt_icache_req = false; 1608 for (uint32_t num_cache=0; num_cache<m_nb_icache; ++num_cache) 1609 tgt_icache_req |= r_tgt_icache_req[num_cache].read(); 1610 #endif 1611 if (not tgt_icache_req and not r_tgt_dcache_req[r_tgt_num_cache].read()) 1612 { 1613 bool tgt_icache_rsp; 1614 uint32_t tgt_icache_rsp_num_cache; 1615 1616 #if (CC_XCACHE_WRAPPER_MULTI_CACHE==1) 1617 tgt_icache_rsp_num_cache = r_tgt_num_cache; 1618 tgt_icache_rsp = r_tgt_icache_rsp[r_tgt_num_cache].read(); 1619 #elif (CC_XCACHE_WRAPPER_MULTI_CACHE==2) 1620 tgt_icache_rsp_num_cache = 0; 1621 for (;tgt_icache_rsp_num_cache<m_nb_icache; ++tgt_icache_rsp_num_cache) 1622 { 1623 PRINTF(" * <TGT> icache[%d] : %d\n",(uint32_t)tgt_icache_rsp_num_cache, (uint32_t)r_tgt_icache_rsp[tgt_icache_rsp_num_cache].read()); 1624 1625 if (r_tgt_icache_rsp[tgt_icache_rsp_num_cache].read()) 1626 break; 744 1627 } 745 break; 746 747 case TGT_UPDT_DATA: 748 if (p_vci_tgt.cmdval.read()) 1628 1629 tgt_icache_rsp = (tgt_icache_rsp_num_cache<m_nb_icache); 1630 #endif 1631 1632 PRINTF(" * <TGT> icache_rsp [%d] : %d\n",tgt_icache_rsp_num_cache,(uint32_t) tgt_icache_rsp); 1633 PRINTF(" * <TGT> dcache_rsp [%d] : %d\n",(uint32_t)r_tgt_num_cache,(uint32_t) r_tgt_dcache_rsp[r_tgt_num_cache]); 1634 1635 if (tgt_icache_rsp or r_tgt_dcache_rsp[r_tgt_num_cache]) 749 1636 { 750 size_t word = r_tgt_word.read();751 if ( word >= m_cache_words )1637 // Have send one response 1638 if ( p_vci_tgt.rspack.read()) 752 1639 { 753 std::cout << "error in component VCI_CC_XCACHE_WRAPPER " << name() << std::endl; 754 std::cout << "the reveived MULTI-UPDATE command length is wrong" << std::endl; 755 exit(0); 756 } 757 #ifdef COHERENCE_DEBUG 758 std::cout << "PROC " << m_srcid_rw << " update, data : " << p_vci_tgt.wdata.read() << " be : " << std::hex << p_vci_tgt.be.read() << std::dec << std::endl; 759 #endif 760 761 r_tgt_buf[word] = p_vci_tgt.wdata.read(); 762 r_tgt_be [word] = p_vci_tgt.be.read(); 763 764 if (p_vci_tgt.be.read()) 765 { 766 if(r_tgt_update_data.read()) 767 m_cpt_cc_update_dcache_word_useful++ ; 768 else 769 m_cpt_cc_update_icache_word_useful++ ; 770 } 771 772 r_tgt_word = word + 1; 773 if (p_vci_tgt.eop.read()){ 774 #if CC_XCACHE_WRAPPER_CC_UPDATE_MULTI_CYCLE_OPT 775 uint32_t word=0; 776 for (; word<m_cache_words; ++word) 777 if (r_tgt_be[word] != 0) 778 break; 779 r_cache_word = word; 780 #endif 781 if(r_tgt_update_data.read()){ 782 r_vci_tgt_fsm = TGT_REQ_DCACHE; 783 } else { 784 r_vci_tgt_fsm = TGT_REQ_ICACHE; 785 } 1640 // reset dcache if activated 1641 if (r_tgt_dcache_rsp[r_tgt_num_cache]) 1642 r_tgt_dcache_rsp[r_tgt_num_cache] = false; 1643 else 1644 // reset one icache 1645 r_tgt_icache_rsp[tgt_icache_rsp_num_cache] = false; 786 1646 } 787 1647 } 1648 1649 // // one response 1650 // if ( not r_tgt_icache_rsp[r_tgt_num_cache] or not r_tgt_dcache_rsp[r_tgt_num_cache] ) 1651 // { 1652 // if ( p_vci_tgt.rspack.read() ) 1653 // { 1654 // r_vci_tgt_fsm = TGT_IDLE; 1655 // r_tgt_icache_rsp[r_tgt_num_cache] = false; 1656 // r_tgt_dcache_rsp[r_tgt_num_cache] = false; 1657 // } 1658 // } 1659 1660 // // if data and instruction have the inval line, need two responses 1661 // if ( r_tgt_icache_rsp[r_tgt_num_cache] and r_tgt_dcache_rsp[r_tgt_num_cache] ) 1662 // { 1663 // if ( p_vci_tgt.rspack.read() ) 1664 // { 1665 // r_tgt_icache_rsp[r_tgt_num_cache] = false; // only reset one for respond the second time 1666 // } 1667 // } 1668 1669 PRINTF(" * <TGT> icache_rsp : %d\n",(uint32_t) r_tgt_icache_rsp[r_tgt_num_cache]); 1670 PRINTF(" * <TGT> dcache_rsp[%d] : %d\n",(uint32_t)r_tgt_num_cache,(uint32_t)r_tgt_dcache_rsp[r_tgt_num_cache].read()); 1671 // if there is no need for a response 1672 if (not tgt_icache_rsp and not r_tgt_dcache_rsp[r_tgt_num_cache] ) 1673 { 1674 r_vci_tgt_fsm = TGT_IDLE; 1675 } 1676 1677 } 1678 break; 1679 } 1680 //////////////////// 1681 case TGT_RSP_ICACHE: 1682 { 1683 bool transaction_rsp = (p_vci_tgt.rspack.read() or not r_tgt_icache_rsp[r_tgt_num_cache].read()) and not r_tgt_icache_req[r_tgt_num_cache].read(); 1684 1685 PRINTF(" * <TGT> RSP_ICACHE : transaction : %d ((%d or not %d) and not %d)\n",transaction_rsp 1686 ,(int)p_vci_tgt.rspack.read() 1687 ,(int)r_tgt_icache_rsp[r_tgt_num_cache].read() 1688 ,(int)r_tgt_icache_req[r_tgt_num_cache].read() 1689 ); 1690 1691 if (transaction_rsp) 1692 { 1693 r_vci_tgt_fsm = TGT_IDLE; 1694 r_tgt_icache_rsp[r_tgt_num_cache] = false; 1695 } 1696 break; 1697 } 1698 1699 case TGT_RSP_DCACHE: 1700 { 1701 bool transaction_rsp = (p_vci_tgt.rspack.read() or not r_tgt_dcache_rsp[r_tgt_num_cache].read()) and not r_tgt_dcache_req[r_tgt_num_cache].read(); 1702 1703 PRINTF(" * <TGT> RSP_DCACHE : transaction : %d\n",transaction_rsp); 1704 1705 if (transaction_rsp) 1706 { 1707 r_vci_tgt_fsm = TGT_IDLE; 1708 r_tgt_dcache_rsp[r_tgt_num_cache] = false; 1709 } 1710 break; 1711 } 1712 } // end switch TGT_FSM 1713 1714 ///////////////////////////////////////////////////////////////////// 1715 // Interface between CPU and CACHE FSM 1716 /////////////////////////////////////////////////////////////////////// 1717 1718 uint32_t ireq_num_cache [m_nb_cpu]; 1719 uint32_t dreq_num_cache [m_nb_cpu]; 1720 bool have_sync = false; 1721 1722 { 1723 typename iss_t::InstructionRequest _ireq = ISS_IREQ_INITIALIZER; 1724 typename iss_t::DataRequest _dreq = ISS_DREQ_INITIALIZER; 1725 1726 for (uint32_t num_cache=0; num_cache<m_nb_icache; ++num_cache) 1727 { 1728 ireq [num_cache] = _ireq; 1729 //irsp [num_cache] = _irsp; 1730 } 1731 for (uint32_t num_cache=0; num_cache<m_nb_dcache; ++num_cache) 1732 { 1733 dreq [num_cache] = _dreq; 1734 //drsp [num_cache] = _drsp; 1735 1736 have_sync |= r_dcache_sync [num_cache]; 1737 } 1738 } 1739 1740 for (uint32_t _num_cpu=0; _num_cpu<m_nb_cpu; ++_num_cpu) 1741 { 1742 // round robin priority 1743 uint32_t num_cpu = (r_cpu_prior+_num_cpu)%m_nb_cpu; 1744 1745 typename iss_t::InstructionRequest _ireq = ISS_IREQ_INITIALIZER; 1746 typename iss_t::DataRequest _dreq = ISS_DREQ_INITIALIZER; 1747 1748 m_iss[num_cpu]->getRequests(_ireq, _dreq); 1749 1750 addr_40 addr; 1751 uint32_t num_cache; 1752 1753 addr = (addr_40)_ireq.addr; 1754 num_cache = get_num_icache(addr,num_cpu); 1755 1756 bool icache_req_valid = ((not ireq[num_cache].valid and // no previous request in this cycle 1757 (r_icache_lock [num_cache] == m_nb_cpu)) or // no previous request in previous cycle 1758 (r_icache_lock [num_cache] == num_cpu)); // previous request in previous cycle by this cpu 1759 1760 if (icache_req_valid) 1761 { 1762 bool valid = _ireq.valid; 1763 1764 if (valid) 1765 { 1766 PRINTF(" * <CPU2CACHE> ICACHE : Transaction between cpu %d and cache %d (lock)\n",num_cpu,num_cache); 1767 ireq_num_cache [num_cpu ] = num_cache; 1768 r_icache_lock [num_cache] = num_cpu; 1769 } 1770 else 1771 { 1772 PRINTF(" * <CPU2CACHE> ICACHE : No Transaction between cpu %d and cache %d : invalid\n",num_cpu,num_cache); 1773 ireq_num_cache [num_cpu] = m_nb_icache; 1774 } 1775 1776 ireq_cached [num_cache] = m_cacheability_table[(vci_addr_t)_ireq.addr]; 1777 ireq_num_cpu [num_cache] = num_cpu; 1778 ireq [num_cache] = _ireq; 1779 ireq [num_cache].addr = addr; 1780 } 1781 else 1782 { 1783 PRINTF(" * <CPU2CACHE> ICACHE : No transaction (cpu %d)\n",num_cpu); 1784 1785 ireq_num_cache [num_cpu] = m_nb_icache; 1786 } 1787 1788 addr = (addr_40)_dreq.addr; 1789 num_cache = get_num_dcache(addr); 1790 1791 1792 bool dcache_no_lock = (r_dcache_lock [num_cache] == m_nb_cpu); 1793 bool dcache_lock_owner = (r_dcache_lock [num_cache] == num_cpu); 1794 bool dcache_lock_no_owner= not dcache_no_lock and not dcache_lock_owner; 1795 bool dcache_req_valid; 1796 1797 // multi cache : hit after miss) 1798 if (m_nb_dcache > 0) 1799 { 1800 bool dcache_wait = ((r_dcache_fsm[num_cache] == DCACHE_MISS_WAIT)// or 1801 // (r_dcache_fsm[num_cache] == DCACHE_UNC_WAIT) or 1802 // (r_dcache_fsm[num_cache] == DCACHE_SC_WAIT) 1803 ); 1804 1805 dcache_req_valid = ((not dreq[num_cache].valid and // no previous request in this cycle 1806 not have_sync and // no sync instruction 1807 (dcache_no_lock or 1808 (dcache_lock_no_owner and dcache_wait))) or // no previous request in previous cycle 1809 (dcache_lock_owner and not dcache_wait)); // previous request in previous cycle by this cpu 1810 } 1811 else 1812 { 1813 dcache_req_valid = ((not dreq[num_cache].valid and // no previous request in this cycle 1814 not have_sync and // no sync instruction 1815 dcache_no_lock) or // no previous request in previous cycle 1816 dcache_lock_owner); // previous request in previous cycle by this cpu 1817 } 1818 1819 // test if already used 1820 if (dcache_req_valid) 1821 { 1822 bool valid = _dreq.valid; 1823 1824 if (valid) 1825 { 1826 PRINTF(" * <CPU2CACHE> DCACHE : Transaction between cpu %d and cache %d (lock)\n",num_cpu,num_cache); 1827 dreq_num_cache [num_cpu ] = num_cache; 1828 1829 // always lock if no multi cache 1830 if ((m_nb_dcache == 1) or (not dcache_lock_no_owner)) 1831 r_dcache_lock [num_cache] = num_cpu; 1832 } 1833 else 1834 { 1835 PRINTF(" * <CPU2CACHE> DCACHE : No Transaction between cpu %d and cache %d : invalid\n",num_cpu,num_cache); 1836 dreq_num_cache [num_cpu] = m_nb_dcache; 1837 } 1838 1839 dreq_cached [num_cache] = m_cacheability_table[(vci_addr_t)_dreq.addr]; 1840 dreq_num_cpu [num_cache] = num_cpu; 1841 dreq [num_cache] = _dreq; 1842 dreq [num_cache].addr = addr; 1843 } 1844 else 1845 { 1846 PRINTF(" * <CPU2CACHE> DCACHE : No transaction (cpu %d)\n",num_cpu); 1847 1848 dreq_num_cache [num_cpu] = m_nb_dcache; 1849 } 1850 1851 1852 #if CC_XCACHE_WRAPPER_DEBUG 1853 if (m_cpt_total_cycles>=CC_XCACHE_WRAPPER_DEBUG_CYCLE_MIN) 1854 { 1855 std::cout << " * <CPU2CACHE> Instruction Request : " << ireq_num_cache[num_cpu] << " - " << _ireq << std::endl 1856 << " * <CPU2CACHE> Data Request : " << dreq_num_cache[num_cpu] << " - " << _dreq << std::endl; 1857 } 1858 #endif 1859 } 1860 1861 // round robin priority 1862 r_cpu_prior = (r_cpu_prior+1)%m_nb_cpu; 1863 1864 ///////////////////////////////////////////////////////////////////// 1865 // The ICACHE FSM controls the following ressources: 1866 // - r_icache_fsm 1867 // - r_icache_fsm_save 1868 // - r_icache instruction cache access 1869 // - r_icache_addr_save 1870 // - r_icache_miss_req set 1871 // - r_icache_unc_req set 1872 // - r_icache_buf_unc_valid set 1873 // - r_vci_rsp_icache_miss_ok reset 1874 // - r_vci_rsp_ins_error reset 1875 // - r_tgt_icache_req reset 1876 // - ireq & irsp structures for communication with the processor 1877 // 1878 // 1/ External requests (update or invalidate) have highest priority. 1879 // They are taken into account in the IDLE and WAIT states. 1880 // As external hit should be extremly rare on the ICACHE, 1881 // all external requests are handled as invalidate... 1882 // In case of external request the ICACHE FSM goes to the CC_CHECK 1883 // state to test the external hit, and returns in the 1884 // pre-empted state after completion. 1885 // 2/ Processor requests are taken into account only in the IDLE state. 1886 // In case of MISS, or in case of uncached instruction, the FSM 1887 // writes the missing address line in the r_icache_addr_save register 1888 // and sets the r_icache_miss_req or the r_icache_unc_req flip-flops. 1889 // These request flip-flops are reset by the VCI_RSP FSM 1890 // when the VCI transaction is completed and the r_icache_buf_unc_valid 1891 // is set in case of uncached access. 1892 // In case of bus error, the VCI_RSP FSM sets the r_vci_rsp_ins_error 1893 // flip-flop. It is reset by the ICACHE FSM. 1894 /////////////////////////////////////////////////////////////////////// 1895 1896 for (uint32_t num_cache=0; num_cache<m_nb_icache; ++num_cache) 1897 { 1898 typename iss_t::InstructionRequest _ireq = ireq [num_cache]; 1899 typename iss_t::InstructionResponse _irsp = ISS_IRSP_INITIALIZER; 1900 1901 switch(r_icache_fsm[num_cache]) { 1902 ///////////////// 1903 case ICACHE_IDLE: 1904 { 1905 if ( r_tgt_icache_req[num_cache] ) { // external request 1906 // if ( _ireq.valid ) m_cost_ins_miss_frz++; 1907 r_icache_fsm [num_cache] = ICACHE_CC_CHECK; 1908 r_icache_fsm_save[num_cache] = r_icache_fsm[num_cache]; 788 1909 break; 789 790 case TGT_REQ_BROADCAST: 791 if ( not r_tgt_icache_req.read() and not r_tgt_dcache_req.read() ) 1910 } 1911 if ( _ireq.valid ) { 1912 data_t icache_ins = 0; 1913 bool icache_hit = false; 1914 bool icache_cached = ireq_cached [num_cache]; 1915 // uint32_t icache_num_cpu = ireq_num_cpu [num_cache]; 1916 bool icache_cleanup_hit = r_icache_cleanup_req[num_cache] and (((addr_40)_ireq.addr >> (addr_40)m_icache_words_shift) == r_icache_cleanup_line[num_cache].read()); 1917 1918 // icache_hit & icache_ins evaluation 1919 if ( icache_cached ) { 1920 icache_hit = r_icache[num_cache]->read((vci_addr_t) _ireq.addr, &icache_ins); 1921 } else { 1922 // if uncache, again in the vci_rsp_fifo_icache 1923 icache_hit = (r_icache_buf_unc_valid[num_cache] and 1924 ((addr_40) _ireq.addr == (addr_40)r_icache_addr_save[num_cache])); 1925 1926 // Test if top of fifo_rsp is for this cache is in ICACHE_UNC_WAIT 1927 icache_ins = r_vci_rsp_fifo_icache_data.read(); 1928 1929 if (icache_hit) 1930 vci_rsp_fifo_icache_get = true; 1931 } 1932 1933 PRINTF(" * <ICACHE [%d]> hit %d - cached %d - cleanup_hit %d\n",num_cache, icache_hit, icache_cached, icache_cleanup_hit); 1934 1935 if (icache_hit and icache_cleanup_hit) 1936 { 1937 PRINTF(" * <ICACHE [%d]> Warning : icache hit and icache_cleanup_hit\n",num_cache); 1938 icache_hit = false; 1939 } 1940 else 1941 { 1942 if ( not icache_hit and not icache_cleanup_hit) 1943 { 1944 1945 m_cpt_ins_miss++; 1946 m_cost_ins_miss_frz++; 1947 1948 r_icache_addr_save[num_cache] = (addr_40) _ireq.addr; 1949 1950 if ( icache_cached ) 1951 { 1952 // to prevent deadlock, miss victim don't be block 1953 if (not r_icache_cleanup_req[num_cache]) 1954 { 1955 r_icache_fsm [num_cache] = ICACHE_MISS_VICTIM; 1956 r_icache_miss_req[num_cache] = true; 1957 } 1958 else 1959 m_cpt_icache_miss_victim_wait [num_cache] ++; 1960 } 1961 else 1962 { 1963 r_icache_addr_save[num_cache] = (addr_40) _ireq.addr; 1964 1965 r_icache_fsm [num_cache] = ICACHE_UNC_WAIT; 1966 r_icache_unc_req[num_cache] = true; 1967 } 1968 } 1969 else 1970 { 1971 // icache_hit and not icache_cleanup_hit 1972 // not icache_hit and icache_cleanup_hit 1973 1974 // request accepted, inval the buf unc 1975 1976 r_icache_buf_unc_valid[num_cache] = false; 1977 } 1978 m_cpt_icache_dir_read += m_icache_ways; 1979 m_cpt_icache_data_read += m_icache_ways; 1980 } 1981 1982 _irsp.valid = icache_hit; 1983 _irsp.instruction = icache_ins; 1984 } 1985 break; 1986 } 1987 ////////////////////// 1988 case ICACHE_MISS_VICTIM: 1989 { 1990 // if (not r_icache_cleanup_req[num_cache]) 1991 { 1992 size_t way; 1993 size_t set; 1994 vci_addr_t addr = (vci_addr_t) r_icache_addr_save[num_cache].read(); 1995 vci_addr_t victim; 1996 1997 r_icache_cleanup_req [num_cache] = r_icache[num_cache]->victim_select(addr, &victim, &way, &set ); 1998 r_icache_cleanup_line[num_cache] = (addr_40) victim; 1999 r_icache_miss_way [num_cache] = way; 2000 r_icache_miss_set [num_cache] = set; 2001 2002 r_icache_fsm [num_cache] = ICACHE_MISS_WAIT; 2003 } 2004 break; 2005 } 2006 ////////////////////// 2007 case ICACHE_MISS_WAIT: 2008 { 2009 m_cost_ins_miss_frz++; 2010 if ( r_tgt_icache_req[num_cache] ) { // external request 2011 r_icache_fsm [num_cache] = ICACHE_CC_CHECK; 2012 r_icache_fsm_save [num_cache] = r_icache_fsm[num_cache].read(); 2013 break; 2014 } 2015 2016 bool val = (r_vci_rsp_fifo_icache_data.rok() and 2017 (r_vci_rsp_fifo_icache_num_cache.read() == num_cache)); 2018 2019 PRINTF(" * <ICACHE [%d]> val : %d\n",num_cache,val); 2020 2021 if (val) 792 2022 { 793 r_vci_tgt_fsm = TGT_RSP_BROADCAST; 794 r_tgt_icache_req = true; 795 r_tgt_dcache_req = true; 2023 PRINTF(" * <ICACHE [%d]> r_icache_inval_rsp : %d\n",num_cache,(int) r_icache_inval_rsp [num_cache]); 2024 PRINTF(" * <ICACHE [%d]> r_vci_rsp_ins_error : %d\n",num_cache,(int) r_vci_rsp_ins_error [num_cache]); 2025 PRINTF(" * <ICACHE [%d]> r_icache_cleanup_req : %d\n",num_cache,(int) r_icache_cleanup_req[num_cache]); 2026 2027 // Miss read response and no invalidation 2028 if ( r_vci_rsp_ins_error [num_cache]) { 2029 r_icache_fsm[num_cache] = ICACHE_ERROR; 2030 } else { 2031 r_icache_update_addr[num_cache] = 0; 2032 r_icache_fsm [num_cache] = ICACHE_MISS_UPDT; 2033 } 796 2034 } 2035 break; 2036 } 2037 ///////////////////// 2038 case ICACHE_UNC_WAIT: 2039 { 2040 m_cost_ins_miss_frz++; 2041 if ( r_tgt_icache_req[num_cache] ) { // external request 2042 r_icache_fsm [num_cache] = ICACHE_CC_CHECK; 2043 r_icache_fsm_save[num_cache] = r_icache_fsm[num_cache].read(); 797 2044 break; 798 //////////////////// 799 case TGT_REQ_ICACHE: 2045 } 2046 2047 bool ok = (r_vci_rsp_fifo_icache_data.rok() and 2048 (r_vci_rsp_fifo_icache_num_cache.read() == num_cache)); 2049 2050 PRINTF(" * <ICACHE [%d]> ok : %d\n",num_cache,ok); 2051 PRINTF(" * <ICACHE [%d]> error : %d\n",num_cache,(uint32_t)r_vci_rsp_ins_error [num_cache]); 2052 2053 if (ok) 800 2054 { 801 if ( not r_tgt_icache_req.read() ) 2055 if ( r_vci_rsp_ins_error [num_cache]) { 2056 r_icache_fsm[num_cache] = ICACHE_ERROR; 2057 } else { 2058 r_icache_fsm [num_cache] = ICACHE_IDLE; 2059 r_icache_buf_unc_valid[num_cache] = true; 2060 } 2061 } 2062 break; 2063 } 2064 ////////////////// 2065 case ICACHE_ERROR: 2066 { 2067 if ( (addr_40)_ireq.addr == (addr_40)r_icache_addr_save[num_cache] ) { 2068 _irsp.error = true; 2069 _irsp.valid = true; 2070 } 2071 r_icache_fsm [num_cache] = ICACHE_IDLE; 2072 r_vci_rsp_ins_error [num_cache] = false; 2073 break; 2074 } 2075 ////////////////////// 2076 case ICACHE_MISS_UPDT: 2077 { 2078 size_t word = r_icache_update_addr[num_cache].read(); 2079 vci_addr_t addr = (vci_addr_t) r_icache_addr_save [num_cache].read(); 2080 size_t way = r_icache_miss_way[num_cache].read(); 2081 size_t set = r_icache_miss_set[num_cache].read(); 2082 2083 bool val = (r_vci_rsp_fifo_icache_data.rok() and 2084 (r_vci_rsp_fifo_icache_num_cache.read() == num_cache)); 2085 2086 if (val) 2087 { 2088 PRINTF(" * <ICACHE [%d]> rsp_val : %d/%d\n",num_cache,(int)r_icache_update_addr[num_cache],(int)m_icache_words); 2089 PRINTF(" * <ICACHE [%d]> r_icache_inval_rsp : %d\n" ,num_cache,(int)r_icache_inval_rsp[num_cache]); 2090 PRINTF(" * <ICACHE [%d]> ins : %x\n" ,num_cache,(int)r_vci_rsp_fifo_icache_data.read()); 2091 // m_cpt_icache_dir_write++; 2092 // m_cpt_icache_data_write++; 2093 // if ( _ireq.valid ) m_cost_ins_miss_frz++; 2094 2095 // if need invalid rsp, don't modify the cache, but pop the buf_rsp 2096 if (not r_icache_inval_rsp[num_cache]) 2097 r_icache[num_cache]->write(way, set, word, r_vci_rsp_fifo_icache_data.read()); 2098 2099 vci_rsp_fifo_icache_get = true; 2100 2101 r_icache_update_addr[num_cache] = ++word; 2102 2103 // if last word, finish the update 2104 if (word >= m_icache_words) 802 2105 { 803 r_vci_tgt_fsm = TGT_RSP_ICACHE; 804 r_tgt_icache_req = true; 805 } 806 break; 807 } 808 809 case TGT_REQ_DCACHE: 810 if ( not r_tgt_dcache_req.read() ) 811 { 812 r_vci_tgt_fsm = TGT_RSP_DCACHE; 813 r_tgt_dcache_req = true; 814 } 815 break; 816 817 case TGT_RSP_BROADCAST: 818 if ( not r_tgt_icache_req.read() and not r_tgt_dcache_req.read() ) 819 { 820 // one response 821 if ( not r_tgt_icache_rsp or not r_tgt_dcache_rsp ) 822 { 823 if ( p_vci_tgt.rspack.read() ) 2106 // in all case (inval_rsp or not), update the victim tag 2107 r_icache[num_cache]->victim_update_tag(addr, way, set); 2108 2109 // Last word : if previous invalid_rsp, can cleanup, else update the TAG 2110 if (r_icache_inval_rsp[num_cache]) 824 2111 { 825 r_vci_tgt_fsm = TGT_IDLE; 826 r_tgt_icache_rsp = false; 827 r_tgt_dcache_rsp = false; 2112 r_icache_inval_rsp[num_cache] = false; 2113 r_icache_fsm [num_cache] = ICACHE_CC_CLEANUP; 2114 } 2115 else 2116 { 2117 r_icache_fsm [num_cache] = ICACHE_IDLE; 828 2118 } 829 2119 } 830 831 // if data and instruction have the inval line, need two responses 832 if ( r_tgt_icache_rsp and r_tgt_dcache_rsp ) 2120 } 2121 2122 break; 2123 } 2124 //////////////////// 2125 case ICACHE_CC_CLEANUP: 2126 { 2127 // cleanup 2128 if(not r_icache_cleanup_req[num_cache]){ 2129 r_icache_cleanup_req [num_cache] = true; 2130 r_icache_cleanup_line[num_cache] = r_icache_addr_save[num_cache].read() >> m_icache_words_shift; 2131 r_icache_fsm [num_cache] = ICACHE_IDLE; 2132 2133 m_cpt_icache_dir_read += m_icache_ways; 2134 r_icache[num_cache]->inval((addr_40)r_icache_addr_save[num_cache]); 2135 } 2136 break; 2137 } 2138 ///////////////////// 2139 case ICACHE_CC_CHECK: // read directory in case of invalidate or update request 2140 { 2141 2142 m_cpt_icache_dir_read += m_icache_ways; 2143 m_cpt_icache_data_read += m_icache_ways; 2144 addr_40 ad = r_tgt_iaddr; 2145 data_t icache_rdata = 0; 2146 2147 PRINTF(" * <ICACHE [%d]> CC_CHECK\n",num_cache); 2148 2149 if((r_icache_fsm_save[num_cache] == ICACHE_MISS_WAIT) and 2150 ((r_icache_addr_save[num_cache].read() & ~((m_icache_words<<2)-1)) == (ad & ~((m_icache_words<<2)-1)))) { 2151 PRINTF(" * <ICACHE [%d]> have request, need inval rsp\n",num_cache); 2152 2153 r_icache_inval_rsp[num_cache] = true; 2154 r_tgt_icache_req [num_cache] = false; 2155 if(r_tgt_update){ // Also send a cleanup and answer 2156 PRINTF(" * <ICACHE [%d]> send a cleanup and answer\n",num_cache); 2157 r_tgt_icache_rsp[num_cache] = true; 2158 } else { // Also send a cleanup but don't answer 2159 PRINTF(" * <ICACHE [%d]> send a cleanup and but don't answer\n",num_cache); 2160 r_tgt_icache_rsp[num_cache] = false; 2161 } 2162 r_icache_fsm[num_cache] = r_icache_fsm_save[num_cache]; 2163 } else { 2164 bool icache_hit = r_icache[num_cache]->read(ad, &icache_rdata); 2165 2166 PRINTF(" * <ICACHE [%d]> have no request, hit cache : %d\n",num_cache,icache_hit); 2167 2168 if ( icache_hit and r_tgt_update) 2169 { 2170 uint32_t word = r_cache_word; 2171 data_t mask = vci_param::be2mask(r_tgt_be[word]); 2172 data_t rdata = 0; 2173 2174 r_icache[num_cache]->read(ad+word*4,&rdata); 2175 r_tgt_buf[word] = (mask & r_tgt_buf[word]) | (~mask & rdata); 2176 2177 word ++; 2178 2179 // Find next valid word 2180 for (; word<m_icache_words; ++word) 2181 if (r_tgt_be[word] != 0) 2182 break; 2183 2184 if (word==m_icache_words) 2185 { 2186 r_icache_fsm[num_cache] = ICACHE_CC_UPDT; 2187 2188 // find next valid word 2189 for (word=0; word<m_icache_words; ++word) 2190 if (r_tgt_be[word] != 0) 2191 break; 2192 } 2193 r_cache_word = word; 2194 2195 } else if ( icache_hit and not r_tgt_update) { 2196 r_icache_fsm[num_cache] = ICACHE_CC_INVAL; 2197 } else { // instruction not found (can happen) 2198 r_tgt_icache_req[num_cache] = false; 2199 if(r_tgt_update){ 2200 r_tgt_icache_rsp[num_cache] = true; 2201 } else { 2202 r_tgt_icache_rsp[num_cache] = false; 2203 } 2204 r_icache_fsm[num_cache] = r_icache_fsm_save[num_cache]; 2205 } 2206 } 2207 break; 2208 } 2209 ///////////////////// 2210 case ICACHE_CC_INVAL: 2211 { 2212 addr_40 ad = r_tgt_iaddr; 2213 // if ( _ireq.valid ) m_cost_ins_miss_frz++; 2214 m_cpt_icache_dir_read += m_icache_ways; 2215 r_tgt_icache_rsp[num_cache] = true; 2216 r_icache[num_cache]->inval(ad); 2217 r_tgt_icache_req[num_cache] = false; 2218 r_icache_fsm [num_cache] = r_icache_fsm_save[num_cache]; 2219 break; 2220 } 2221 ///////////////////// 2222 case ICACHE_CC_UPDT: 2223 { 2224 addr_40 ad = r_tgt_iaddr.read(); 2225 m_cpt_icache_dir_write++; 2226 m_cpt_icache_data_write++; 2227 2228 uint32_t word = r_cache_word; 2229 2230 if(r_tgt_be[word]) 2231 r_icache[num_cache]->write(ad+word*4, r_tgt_buf[word]); 2232 2233 word ++; 2234 2235 // find next valid word 2236 for (; word<m_icache_words; ++word) 2237 if (r_tgt_be[word] != 0) 2238 break; 2239 2240 if (word==m_icache_words) 2241 { 2242 r_tgt_icache_req[num_cache] = false; 2243 r_tgt_icache_rsp[num_cache] = true; 2244 r_icache_fsm [num_cache] = r_icache_fsm_save[num_cache].read(); 2245 word = 0; 2246 } 2247 r_cache_word = word; 2248 2249 break; 2250 } 2251 2252 }// end switch r_icache_fsm 2253 2254 irsp [num_cache] = _irsp; 2255 if (_ireq.valid and _irsp.valid) 2256 { 2257 PRINTF(" * <CPU2CACHE> Transaction between cpu %d and Icache %d (unlock)\n",r_icache_lock [num_cache].read(),num_cache); 2258 2259 r_icache_lock [num_cache] = m_nb_cpu; 2260 m_cpt_icache_access [num_cache] ++; 2261 } 2262 2263 }// end for num_cache 2264 2265 //////////////////////////////////////////////////////////////////////:///////////// 2266 // The DCACHE FSM controls the following ressources: 2267 // - r_dcache_fsm 2268 // - r_dcache_fsm_save 2269 // - r_dcache (data cache access) 2270 // - r_dcache_addr_save 2271 // - r_dcache_wdata_save 2272 // - r_dcache_rdata_save 2273 // - r_dcache_type_save 2274 // - r_dcache_be_save 2275 // - r_dcache_cached_save 2276 // - r_dcache_miss_req set 2277 // - r_dcache_unc_req set 2278 // - r_dcache_cleanup_req set 2279 // - r_vci_rsp_data_error reset 2280 // - r_tgt_dcache_req reset 2281 // - r_wbuf write 2282 // - dreq & drsp structures for communication with the processor 2283 // 2284 // 1/ EXTERNAL REQUEST : 2285 // There is an external request when the tgt_dcache req flip-flop is set, 2286 // requesting a line invalidation or a line update. 2287 // External requests are taken into account in the states IDLE, WRITE_REQ, 2288 // UNC_WAIT, MISS_WAIT, and have the highest priority : 2289 // The actions associated to the pre-empted state are not executed, the DCACHE FSM 2290 // goes to the CC_CHECK state to execute the requested action, and returns to the 2291 // pre-empted state. 2292 // 2/ PROCESSOR REQUEST : 2293 // In order to support VCI write burst, the processor requests are taken into account 2294 // in the WRITE_REQ state as well as in the IDLE state. 2295 // - In the IDLE state, the processor request cannot be satisfied if 2296 // there is a cached read miss, or an uncached read. 2297 // - In the WRITE_REQ state, the request cannot be satisfied if 2298 // there is a cached read miss, or an uncached read, 2299 // or when the write buffer is full. 2300 // - In all other states, the processor request is not satisfied. 2301 // 2302 // The cache access takes into account the cacheability_table. 2303 // In case of processor request, there is five conditions to exit the IDLE state: 2304 // - CACHED READ MISS => to the MISS_WAIT state (waiting the r_miss_ok signal), 2305 // then to the MISS_UPDT state, and finally to the IDLE state. 2306 // - UNCACHED READ => to the UNC_WAIT state (waiting the r_miss_ok signal), 2307 // and to the IDLE state. 2308 // - CACHE INVALIDATE HIT => to the INVAL state for one cycle, then to IDLE state. 2309 // - WRITE MISS => directly to the WRITE_REQ state to access the write buffer. 2310 // - WRITE HIT => to the WRITE_UPDT state, then to the WRITE_REQ state. 2311 // 2312 // Error handling : Read Bus Errors are synchronous events, but 2313 // Write Bus Errors are asynchronous events (processor is not frozen). 2314 // - If a Read Bus Error is detected, the VCI_RSP FSM sets the 2315 // r_vci_rsp_data_error flip-flop, and the synchronous error is signaled 2316 // by the DCACHE FSM. 2317 // - If a Write Bus Error is detected, the VCI_RSP FSM signals 2318 // the asynchronous error using the setWriteBerr() method. 2319 /////////////////////////////////////////////////////////////////////////////////// 2320 2321 for (uint32_t num_cache=0; num_cache<m_nb_dcache; ++num_cache) 2322 { 2323 typename iss_t::DataRequest _dreq = dreq [num_cache]; 2324 typename iss_t::DataResponse _drsp = ISS_DRSP_INITIALIZER; 2325 2326 switch ( r_dcache_fsm[num_cache]) { 2327 2328 ///////////////// 2329 case DCACHE_IDLE: 2330 { 2331 if ( r_tgt_dcache_req[num_cache]) { // external request 2332 r_dcache_fsm [num_cache] = DCACHE_CC_CHECK; 2333 r_dcache_fsm_save[num_cache] = r_dcache_fsm[num_cache]; 2334 break; 2335 } 2336 2337 if ( _dreq.valid ) { 2338 PRINTF(" * <DCACHE [%d]> Have dreq\n",num_cache); 2339 2340 data_t dcache_rdata = 0; 2341 // dcache_cached and dcache_hit don't used with _dreq.type == {DATA_SC, XTN_READ, XTN_WRITE} 2342 bool dcache_cached = dreq_cached [num_cache]; 2343 uint32_t dcache_num_cpu = dreq_num_cpu [num_cache]; 2344 bool dcache_hit = r_dcache[num_cache]->read((vci_addr_t) _dreq.addr, &dcache_rdata); 2345 bool dcache_cleanup_hit = r_dcache_cleanup_req[num_cache] and (((addr_40)_dreq.addr >> (addr_40)m_dcache_words_shift) == r_dcache_cleanup_line[num_cache].read()); 2346 2347 PRINTF(" * <DCACHE [%d]> hit %d - cached %d - cleanup_hit %d\n",num_cache,dcache_hit, dcache_cached, dcache_cleanup_hit); 2348 2349 m_cpt_dcache_data_read += m_dcache_ways; 2350 m_cpt_dcache_dir_read += m_dcache_ways; 2351 2352 switch( _dreq.type ) { 2353 case iss_t::DATA_READ: 2354 case iss_t::DATA_LL: 2355 { 2356 m_cpt_data_read++; // new dcache read 2357 2358 if (dcache_hit) // no special test for uncached read, because it's always miss 2359 { 2360 // address is in the cache : return the word 2361 r_dcache_fsm [num_cache] = DCACHE_IDLE; 2362 2363 _drsp.valid = true; 2364 _drsp.rdata = dcache_rdata; // return read data (cf dcache_hit) 2365 2366 // if the request is a Load Linked instruction, save request information 2367 if(_dreq.type == iss_t::DATA_LL) 2368 { 2369 PRINTF(" * <DCACHE [%d]> ll_valid = true\n",num_cache); 2370 2371 r_dcache_ll_valid [num_cache][dcache_num_cpu] = true; 2372 r_dcache_ll_data [num_cache][dcache_num_cpu] = dcache_rdata; 2373 r_dcache_ll_addr [num_cache][dcache_num_cpu] = (vci_addr_t) _dreq.addr; 2374 } 2375 } 2376 else 2377 { 2378 if (not dcache_cleanup_hit) 2379 { 2380 2381 // Miss : send signal at the CMD_FSM (via r_dcache_miss_req or r_dcache_unc_req) 2382 if ( dcache_cached ) { 2383 // to prevent deadlock, miss victim don't be block 2384 if (not r_dcache_cleanup_req[num_cache].read()) 2385 { 2386 m_cpt_data_read_miss++; 2387 m_cost_data_miss_frz++; 2388 r_dcache_miss_req [num_cache] = true; 2389 r_dcache_fsm [num_cache] = DCACHE_MISS_VICTIM; 2390 } 2391 else 2392 m_cpt_icache_miss_victim_wait [num_cache] ++; 2393 } else { 2394 if (not r_dcache_previous_unc[num_cache].read()) // strongly order to the uncached access 2395 { 2396 r_dcache_previous_unc[num_cache] = true; 2397 2398 m_cpt_data_read_uncached++; 2399 m_cost_unc_read_frz++; 2400 r_dcache_unc_req[num_cache] = true; 2401 r_dcache_fsm [num_cache] = DCACHE_UNC_WAIT; 2402 } 2403 } 2404 } 2405 } 2406 } 2407 break; 2408 case iss_t::DATA_SC: 2409 { 2410 PRINTF(" * <DCACHE [%d]> DATA_SC - ll_valid = %d, num_cpu = %d\n",num_cache,r_dcache_ll_valid[num_cache][dcache_num_cpu].read(),dcache_num_cpu); 2411 2412 if (not r_dcache_previous_unc[num_cache].read() and not dcache_cleanup_hit) // strongly order to the uncached access 2413 { 2414 //m_cpt_data_read_unc++; // instruction must read the memory in uncached mode 2415 m_cost_unc_read_frz++; 2416 2417 // if previous load linked (with the same address), make a transaction 2418 // else, keep in IDLE state and return 1 (no OK) 2419 if( r_dcache_ll_valid[num_cache][dcache_num_cpu].read() and 2420 (r_dcache_ll_addr [num_cache][dcache_num_cpu].read() == (vci_addr_t)_dreq.addr)){ 2421 PRINTF(" * <DCACHE [%d]> have previous load linked\n",num_cache); 2422 2423 r_dcache_previous_unc[num_cache] = true; 2424 r_dcache_sc_req [num_cache] = true; 2425 2426 r_dcache_fsm [num_cache] = DCACHE_SC_WAIT; 2427 } else { 2428 PRINTF(" * <DCACHE [%d]> don't have previous load linked\n",num_cache); 2429 2430 _drsp.valid = true; 2431 _drsp.rdata = 1; // SC rsp NOK 2432 r_dcache_ll_valid[num_cache][dcache_num_cpu] = false; 2433 } 2434 } 2435 2436 break; 2437 } 2438 case iss_t::XTN_READ: 2439 case iss_t::XTN_WRITE: 2440 { 2441 bool valid = false; 2442 // only DCACHE INVALIDATE and SYNC request are supported 2443 switch (_dreq.addr>>2) 2444 { 2445 case iss_t::XTN_DCACHE_INVAL : 2446 { 2447 valid = true; 2448 r_dcache_fsm[num_cache] = DCACHE_INVAL; 2449 break; 2450 } 2451 case iss_t::XTN_SYNC : 2452 { 2453 // Test if write buffer is already empty 2454 // * gain : 1 cycle 2455 // * cost : can be on the critical path 2456 2457 bool empty=true; 2458 for (uint32_t i=0; i<m_nb_dcache; ++i) 2459 empty &= r_wbuf[i]->empty(); 2460 2461 if (empty) 2462 { 2463 valid = true; 2464 r_dcache_fsm [num_cache] = DCACHE_IDLE; 2465 } 2466 else 2467 { 2468 valid = false; 2469 r_dcache_fsm [num_cache] = DCACHE_SYNC; 2470 r_dcache_sync[num_cache] = true; 2471 } 2472 break; 2473 } 2474 default : 2475 { 2476 // std::cout << "Warning in VCI_CC_XCACHE_WRAPPER " << name() << std::endl; 2477 // std::cout << "Unsupported external access : " << (_dreq.addr>>2) << std::endl; 2478 2479 r_dcache_fsm [num_cache] = DCACHE_IDLE; 2480 } 2481 }//end switch (_dreq.addr>>2) 2482 2483 _drsp.valid = valid; 2484 _drsp.rdata = 0; 2485 break; 2486 } 2487 case iss_t::DATA_WRITE: 2488 2489 PRINTF(" * <DCACHE [%d]> r_dcache_previous_unc : %d\n",num_cache,r_dcache_previous_unc[num_cache].read()); 2490 2491 if (dcache_cached or not r_dcache_previous_unc[num_cache].read()) // strongly order to the uncached access 833 2492 { 834 if ( p_vci_tgt.rspack.read() ) 2493 bool valid; 2494 addr_40 addr = _dreq.addr; 2495 set_num_dcache(addr,num_cache); 2496 2497 // FIXME : 2498 // * dans le wbuf, ne pas mettre l'adresse au complet (economie de surface) 2499 // * pour cela, virer le set_num_dcache ! 2500 valid = r_wbuf[num_cache]->write(addr, _dreq.be, _dreq.wdata, dcache_cached, dcache_num_cpu); 2501 2502 #if MWBUF_VHDL_TESTBENCH 2503 vhdl_mwbuf_port_write_val [num_cache] = (vhdl_tb_t)1; 2504 vhdl_mwbuf_test_write_ack [num_cache] = (vhdl_tb_t)1; 2505 vhdl_mwbuf_port_write_ack [num_cache] = (vhdl_tb_t)valid; 2506 vhdl_mwbuf_port_write_addr [num_cache] = (vhdl_tb_t)addr; 2507 vhdl_mwbuf_port_write_data [num_cache] = (vhdl_tb_t)_dreq.wdata; 2508 vhdl_mwbuf_port_write_be [num_cache] = (vhdl_tb_t)_dreq.be; 2509 vhdl_mwbuf_port_write_cached [num_cache] = (vhdl_tb_t)dcache_cached; 2510 vhdl_mwbuf_port_write_cpu_id [num_cache] = (vhdl_tb_t)dcache_num_cpu; 2511 #endif 2512 2513 2514 PRINTF(" * <DCACHE [%d]> r_wbuf valid : %d\n",num_cache,valid); 2515 2516 if (valid) 835 2517 { 836 r_tgt_icache_rsp = false; // only reset one for respond the second time 2518 m_cpt_data_write++; 2519 2520 if (not dcache_cached) 2521 { 2522 r_dcache_previous_unc[num_cache] = true; 2523 m_cpt_data_write_uncached++; 2524 } 2525 else if (not dcache_hit) 2526 m_cpt_data_write_miss++; 2527 2528 if (dcache_hit) { 2529 // update data cache 2530 r_dcache_fsm[num_cache] = DCACHE_WRITE_UPDT; 2531 } else { 2532 // write accepted 2533 r_dcache_fsm [num_cache] = DCACHE_IDLE; 2534 } 2535 } 2536 2537 _drsp.valid = valid; 2538 _drsp.rdata = 0; 2539 } 2540 break; 2541 } // end switch _dreq.type 2542 2543 r_dcache_addr_save [num_cache] = (addr_40) _dreq.addr; 2544 r_dcache_type_save [num_cache] = _dreq.type; 2545 r_dcache_wdata_save [num_cache] = _dreq.wdata; 2546 r_dcache_be_save [num_cache] = _dreq.be; 2547 r_dcache_rdata_save [num_cache] = dcache_rdata; 2548 r_dcache_cached_save [num_cache] = dcache_cached; 2549 r_dcache_num_cpu_save[num_cache] = dcache_num_cpu; 2550 2551 } else { // end if _dreq.valid 2552 r_dcache_fsm [num_cache] = DCACHE_IDLE; 2553 } 2554 2555 break; 2556 } 2557 /////////////////////// 2558 case DCACHE_WRITE_UPDT: 2559 { 2560 m_cpt_dcache_data_write++; 2561 data_t mask = vci_param::be2mask(r_dcache_be_save[num_cache]); 2562 data_t wdata = (mask & r_dcache_wdata_save[num_cache]) | (~mask & r_dcache_rdata_save[num_cache]); 2563 vci_addr_t ad = r_dcache_addr_save[num_cache].read(); 2564 r_dcache[num_cache]->write(ad, wdata); 2565 2566 int dcache_fsm_next = DCACHE_IDLE; // default 2567 2568 // Test if write after write 2569 2570 if (_dreq.valid and (_dreq.type == iss_t::DATA_WRITE)) 2571 { 2572 PRINTF(" * <DCACHE [%d]> Have dreq (Write after Write)\n",num_cache); 2573 2574 data_t dcache_rdata = 0; 2575 // dcache_cached and dcache_hit don't used with _dreq.type == {DATA_SC, XTN_READ, XTN_WRITE} 2576 bool dcache_cached = dreq_cached [num_cache]; 2577 uint32_t dcache_num_cpu = dreq_num_cpu [num_cache]; 2578 bool dcache_hit = r_dcache[num_cache]->read((vci_addr_t) _dreq.addr, &dcache_rdata); 2579 2580 m_cpt_dcache_data_read += m_dcache_ways; 2581 m_cpt_dcache_dir_read += m_dcache_ways; 2582 2583 PRINTF(" * <DCACHE [%d]> r_dcache_previous_unc : %d\n",num_cache,r_dcache_previous_unc[num_cache].read()); 2584 2585 if (dcache_cached or not r_dcache_previous_unc[num_cache].read()) // strongly order to the uncached access 2586 { 2587 bool valid; 2588 addr_40 addr = _dreq.addr; 2589 set_num_dcache(addr,num_cache); 2590 2591 // FIXME : 2592 // * dans le wbuf, ne pas mettre l'adresse au complet (economie de surface) 2593 // * pour cela, virer le set_num_dcache ! 2594 valid = r_wbuf[num_cache]->write(addr, _dreq.be, _dreq.wdata, dcache_cached, dcache_num_cpu); 2595 2596 #if MWBUF_VHDL_TESTBENCH 2597 vhdl_mwbuf_port_write_val [num_cache] = (vhdl_tb_t)1; 2598 vhdl_mwbuf_test_write_ack [num_cache] = (vhdl_tb_t)1; 2599 vhdl_mwbuf_port_write_ack [num_cache] = (vhdl_tb_t)valid; 2600 vhdl_mwbuf_port_write_addr [num_cache] = (vhdl_tb_t)addr; 2601 vhdl_mwbuf_port_write_data [num_cache] = (vhdl_tb_t)_dreq.wdata; 2602 vhdl_mwbuf_port_write_be [num_cache] = (vhdl_tb_t)_dreq.be; 2603 vhdl_mwbuf_port_write_cached [num_cache] = (vhdl_tb_t)dcache_cached; 2604 vhdl_mwbuf_port_write_cpu_id [num_cache] = (vhdl_tb_t)dcache_num_cpu; 2605 #endif 2606 2607 PRINTF(" * <DCACHE [%d]> r_wbuf valid : %d\n",num_cache,valid); 2608 2609 if (valid) 2610 { 2611 m_cpt_dcache_store_after_store [num_cache] ++; 2612 2613 m_cpt_data_write++; 2614 2615 if (not dcache_cached) 2616 { 2617 r_dcache_previous_unc[num_cache] = true; 2618 m_cpt_data_write_uncached++; 2619 } 2620 else if (not dcache_hit) 2621 m_cpt_data_write_miss++; 2622 2623 if (dcache_hit) { 2624 // update data cache 2625 dcache_fsm_next = DCACHE_WRITE_UPDT; 2626 } else { 2627 // write accepted 2628 dcache_fsm_next = DCACHE_IDLE; 2629 } 2630 } 2631 2632 _drsp.valid = valid; 2633 _drsp.rdata = 0; 2634 } 2635 2636 r_dcache_addr_save [num_cache] = (addr_40) _dreq.addr; 2637 // r_dcache_type_save [num_cache] = _dreq.type; 2638 r_dcache_wdata_save [num_cache] = _dreq.wdata; 2639 r_dcache_be_save [num_cache] = _dreq.be; 2640 r_dcache_rdata_save [num_cache] = dcache_rdata; 2641 // r_dcache_cached_save [num_cache] = dcache_cached; 2642 // r_dcache_num_cpu_save[num_cache] = dcache_num_cpu; 2643 } 2644 2645 r_dcache_fsm [num_cache] = dcache_fsm_next; // default 2646 2647 break; 2648 } 2649 ////////////////////// 2650 case DCACHE_MISS_VICTIM: 2651 { 2652 // if (not r_dcache_cleanup_req[num_cache].read()) 2653 { 2654 size_t way; 2655 size_t set; 2656 vci_addr_t addr = (vci_addr_t) r_dcache_addr_save[num_cache].read(); 2657 vci_addr_t victim; 2658 bool victim_val = r_dcache[num_cache]->victim_select(addr, &victim, &way, &set ); 2659 2660 r_dcache_cleanup_req [num_cache] = victim_val; 2661 r_dcache_cleanup_line [num_cache] = (addr_40) victim; 2662 r_dcache_miss_way [num_cache] = way; 2663 r_dcache_miss_set [num_cache] = set; 2664 2665 PRINTF(" * <DCACHE [%d]> MISS_VICTIM : Victim %d - %llx (way %d, set %d)\n",num_cache,victim_val, (blob_t)victim, (int)way, (int)set); 2666 2667 r_dcache_fsm [num_cache] = DCACHE_MISS_WAIT; 2668 } 2669 2670 break; 2671 } 2672 ////////////////////// 2673 case DCACHE_MISS_WAIT: 2674 { 2675 // Multi_cache ; Hit after Miss 2676 if (m_nb_dcache>0) 2677 { 2678 data_t dcache_rdata = 0; 2679 bool dcache_hit = r_dcache[num_cache]->read((vci_addr_t) _dreq.addr, &dcache_rdata); 2680 // bool dcache_cached = dreq_cached [num_cache]; 2681 // uint32_t dcache_num_cpu = dreq_num_cpu [num_cache]; 2682 2683 m_cpt_dcache_data_read += m_dcache_ways; 2684 m_cpt_dcache_dir_read += m_dcache_ways; 2685 2686 if (_dreq.valid) 2687 switch (_dreq.type) 2688 { 2689 case iss_t::DATA_READ : // accept only hit dcache load 2690 { 2691 m_cpt_data_read++; // new dcache read 2692 2693 if (dcache_hit) // no special test for uncached read, because it's always miss 2694 { 2695 m_cpt_dcache_hit_after_miss_read [num_cache] ++; 2696 2697 // address is in the cache : return the word 2698 _drsp.valid = true; 2699 _drsp.rdata = dcache_rdata; // return read data (cf dcache_hit) 2700 } 2701 break; 2702 } 2703 // case iss_t::DATA_WRITE : // accept only cached write and miss in dcache (else need update dcache) 2704 // { 2705 // if (dcache_cached and not dcache_hit) 2706 // { 2707 // bool valid; 2708 // addr_40 addr = _dreq.addr; 2709 // set_num_dcache(addr,num_cache); 2710 2711 // // FIXME : 2712 // // * dans le wbuf, ne pas mettre l'adresse au complet (economie de surface) 2713 // // * pour cela, virer le set_num_dcache ! 2714 // valid = r_wbuf[num_cache]->write(addr, _dreq.be, _dreq.wdata, dcache_cached, dcache_num_cpu); 2715 // PRINTF(" * <DCACHE [%d]> r_wbuf valid : %d\n",num_cache,valid); 2716 2717 // if (valid) 2718 // { 2719 // m_cpt_dcache_hit_after_miss_write [num_cache] ++; 2720 2721 // m_cpt_data_write++; 2722 // m_cpt_data_write_miss++; 2723 // } 2724 2725 // _drsp.valid = valid; 2726 // _drsp.rdata = 0; 2727 // } 2728 // break; 2729 // } 2730 default : 2731 { 2732 break; 2733 } 2734 } 2735 } // end multi cache hit after miss 2736 2737 // if ( _dreq.valid ) m_cost_data_miss_frz++; 2738 if ( r_tgt_dcache_req[num_cache].read() ) { // external request 2739 r_dcache_fsm [num_cache] = DCACHE_CC_CHECK; 2740 r_dcache_fsm_save [num_cache] = r_dcache_fsm[num_cache]; 2741 break; 2742 } 2743 2744 bool val = (r_vci_rsp_fifo_dcache_data.rok() and 2745 (r_vci_rsp_fifo_dcache_num_cache.read() == num_cache)); 2746 2747 if (val) 2748 { 2749 // Miss read response and no invalidation 2750 if (r_vci_rsp_data_error[num_cache]) 2751 { 2752 r_dcache_fsm [num_cache] = DCACHE_ERROR; 2753 } 2754 else 2755 { 2756 r_dcache_update_addr[num_cache] = 0; 2757 r_dcache_fsm [num_cache] = DCACHE_MISS_UPDT; 2758 } 2759 } 2760 break; 2761 } 2762 ////////////////////// 2763 case DCACHE_MISS_UPDT: 2764 { 2765 size_t word = r_dcache_update_addr[num_cache].read(); 2766 vci_addr_t addr = (vci_addr_t) r_dcache_addr_save[num_cache].read(); 2767 size_t way = r_dcache_miss_way[num_cache].read(); 2768 size_t set = r_dcache_miss_set[num_cache].read(); 2769 2770 PRINTF(" * <DCACHE [%d]> MISS_UPDT : Victim way %d, set %d\n",num_cache, (int)way, (int)set); 2771 2772 bool val = (r_vci_rsp_fifo_dcache_data.rok() and 2773 (r_vci_rsp_fifo_dcache_num_cache.read() == num_cache)); 2774 2775 if (val) 2776 { 2777 // m_cpt_dcache_dir_write++; 2778 // if ( _dreq.valid ) m_cost_data_miss_frz++; 2779 2780 // if need invalid rsp, don't modify the cache, but pop the buf_rsp 2781 // (power save) 2782 if (not r_dcache_inval_rsp[num_cache]) 2783 { 2784 r_dcache[num_cache]->write(way, set, word, r_vci_rsp_fifo_dcache_data.read()); 2785 m_cpt_dcache_data_write++; 2786 } 2787 2788 vci_rsp_fifo_dcache_get = true; 2789 2790 r_dcache_update_addr[num_cache] = ++word; 2791 2792 // if last word, finish the update 2793 if (word >= m_dcache_words) 2794 { 2795 // in all case (inval_rsp or not), update the victim tag 2796 // because victim is already cleanup 2797 r_dcache[num_cache]->victim_update_tag(addr, way, set); 2798 2799 // Last word : if previous invalid_rsp, can cleanup, else update the TAG 2800 if (r_dcache_inval_rsp[num_cache]) 2801 { 2802 r_dcache_inval_rsp[num_cache] = false; 2803 r_dcache_fsm [num_cache] = DCACHE_CC_CLEANUP; 2804 } 2805 else 2806 { 2807 r_dcache_fsm [num_cache] = DCACHE_IDLE; 837 2808 } 838 2809 } 839 840 // if there is no need for a response841 if ( not r_tgt_icache_rsp and not r_tgt_dcache_rsp )842 {843 r_vci_tgt_fsm = TGT_IDLE;844 }845 846 2810 } 2811 2812 break; 2813 } 2814 //////////////////// 2815 case DCACHE_UNC_WAIT: 2816 { 2817 // if ( _dreq.valid ) m_cost_unc_read_frz++; 2818 if ( r_tgt_dcache_req[num_cache] ) { // external request 2819 r_dcache_fsm [num_cache] = DCACHE_CC_CHECK; 2820 r_dcache_fsm_save[num_cache] = r_dcache_fsm[num_cache]; 847 2821 break; 848 //////////////////// 849 case TGT_RSP_ICACHE: 2822 } 2823 2824 bool ok = (r_vci_rsp_fifo_dcache_data.rok() and 2825 (r_vci_rsp_fifo_dcache_num_cache.read() == num_cache)); 2826 2827 if (ok) { 2828 if (r_vci_rsp_data_error[num_cache]) { 2829 r_dcache_fsm[num_cache] = DCACHE_ERROR; 2830 } else { 2831 data_t rdata = r_vci_rsp_fifo_dcache_data.read(); 2832 vci_rsp_fifo_dcache_get = true; 2833 2834 if(_dreq.type == iss_t::DATA_LL){ 2835 PRINTF(" * <DCACHE [%d]> ll_valid = true\n",num_cache); 2836 2837 r_dcache_ll_valid [num_cache][r_dcache_num_cpu_save[num_cache]] = true; 2838 r_dcache_ll_data [num_cache][r_dcache_num_cpu_save[num_cache]] = rdata; 2839 r_dcache_ll_addr [num_cache][r_dcache_num_cpu_save[num_cache]] = (vci_addr_t) _dreq.addr; 2840 } 2841 r_dcache_fsm [num_cache] = DCACHE_IDLE; 2842 2843 _drsp.valid = true; 2844 _drsp.rdata = rdata; 2845 } 2846 } 2847 break; 2848 } 2849 //////////////////// 2850 case DCACHE_SC_WAIT: 2851 { 2852 // if ( _dreq.valid ) m_cost_unc_read_frz++; 2853 if ( r_tgt_dcache_req[num_cache] ) { // external request 2854 r_dcache_fsm [num_cache] = DCACHE_CC_CHECK; 2855 r_dcache_fsm_save [num_cache] = r_dcache_fsm [num_cache]; 2856 break; 2857 } 2858 2859 bool ok = (r_vci_rsp_fifo_dcache_data.rok() and 2860 (r_vci_rsp_fifo_dcache_num_cache.read() == num_cache)); 2861 2862 if (ok) { 2863 if (r_vci_rsp_data_error[num_cache]) { 2864 r_dcache_fsm [num_cache] = DCACHE_ERROR; 2865 } else { 2866 r_dcache_fsm [num_cache] = DCACHE_IDLE; 2867 2868 _drsp.valid = true; 2869 _drsp.rdata = r_vci_rsp_fifo_dcache_data.read(); 2870 vci_rsp_fifo_dcache_get = true; 2871 r_dcache_ll_valid [num_cache][r_dcache_num_cpu_save[num_cache]] = false; 2872 } 2873 } 2874 break; 2875 } 2876 2877 ////////////////// 2878 case DCACHE_ERROR: 2879 { 2880 r_dcache_fsm [num_cache] = DCACHE_IDLE; 2881 2882 r_vci_rsp_data_error[num_cache] = false; 2883 _drsp.error = true; 2884 _drsp.valid = true; 2885 break; 2886 } 2887 ///////////////// 2888 case DCACHE_INVAL: 2889 { 2890 if ( r_tgt_dcache_req[num_cache].read() ) { // external request 2891 r_dcache_fsm [num_cache] = DCACHE_CC_CHECK; 2892 r_dcache_fsm_save [num_cache] = r_dcache_fsm [num_cache]; 2893 break; 2894 } 2895 if( not r_dcache_cleanup_req [num_cache].read() ){ 2896 m_cpt_dcache_dir_read += m_dcache_ways; 2897 vci_addr_t ad = r_dcache_addr_save [num_cache].read(); 2898 r_dcache_cleanup_req [num_cache] = r_dcache[num_cache]->inval(ad); 2899 r_dcache_cleanup_line [num_cache] = r_dcache_addr_save [num_cache].read() >> m_dcache_words_shift; 2900 2901 r_dcache_fsm [num_cache] = DCACHE_IDLE; 2902 } 2903 break; 2904 } 2905 case DCACHE_SYNC : 2906 { 2907 if ( r_tgt_dcache_req[num_cache] ) { // external request 2908 r_dcache_fsm [num_cache] = DCACHE_CC_CHECK; 2909 r_dcache_fsm_save[num_cache] = r_dcache_fsm[num_cache]; 2910 break; 2911 } 2912 2913 bool empty=true; 2914 for (uint32_t i=0; i<m_nb_dcache; ++i) 2915 empty &= r_wbuf[i]->empty(); 2916 2917 if (empty) 850 2918 { 851 if ( (p_vci_tgt.rspack.read() or not r_tgt_icache_rsp.read()) and not r_tgt_icache_req.read() ) 852 { 853 r_vci_tgt_fsm = TGT_IDLE; 854 r_tgt_icache_rsp = false; 855 } 856 break; 2919 _drsp.valid = true; // end, can accept the sync request 2920 r_dcache_fsm [num_cache] = DCACHE_IDLE; 2921 r_dcache_sync[num_cache] = false; 857 2922 } 858 859 case TGT_RSP_DCACHE: 2923 break; 2924 } 2925 ///////////////////// 2926 case DCACHE_CC_CHECK: // read directory in case of invalidate or update request 2927 { 2928 addr_40 ad = r_tgt_daddr; 2929 data_t dcache_rdata = 0; 2930 2931 PRINTF(" * <DCACHE [%d]> CC_CHECK\n",num_cache); 2932 2933 // 2934 if((r_dcache_fsm_save[num_cache] == DCACHE_MISS_WAIT) and 2935 ((r_dcache_addr_save[num_cache].read() & ~((m_dcache_words<<2)-1)) == (ad & ~((m_dcache_words<<2)-1)))) { 2936 PRINTF(" * <DCACHE [%d]> have request, need inval rsp\n",num_cache); 2937 2938 r_dcache_inval_rsp[num_cache] = true; 2939 r_tgt_dcache_req [num_cache] = false; 2940 if(r_tgt_update){ // Also send a cleanup and answer 2941 PRINTF(" * <DCACHE [%d]> send a cleanup and answer\n",num_cache); 2942 r_tgt_dcache_rsp[num_cache] = true; 2943 } else { // Also send a cleanup but don't answer 2944 PRINTF(" * <DCACHE [%d]> send a cleanup and but don't answer\n",num_cache); 2945 r_tgt_dcache_rsp[num_cache] = false; 2946 } 2947 r_dcache_fsm[num_cache] = r_dcache_fsm_save[num_cache]; 2948 } else { 2949 bool dcache_hit = r_dcache[num_cache]->read(ad, &dcache_rdata); 2950 2951 PRINTF(" * <DCACHE [%d]> have no request, hit cache : %d, update : %d\n",num_cache,dcache_hit,(uint32_t)r_tgt_update); 2952 2953 m_cpt_dcache_data_read += m_dcache_ways; 2954 m_cpt_dcache_dir_read += m_dcache_ways; 2955 2956 if ( dcache_hit and r_tgt_update ) 2957 { 2958 uint32_t word = r_cache_word; 2959 data_t mask = vci_param::be2mask(r_tgt_be[word]); 2960 data_t rdata = 0; 2961 2962 r_dcache[num_cache]->read(ad+word*4,&rdata); 2963 2964 r_tgt_buf[word] = (mask & r_tgt_buf[word]) | (~mask & rdata); 2965 2966 word ++; 2967 2968 // find next valid word 2969 for (; word<m_dcache_words; ++word) 2970 if (r_tgt_be[word] != 0) 2971 break; 2972 2973 if (word==m_dcache_words) 2974 { 2975 r_dcache_fsm[num_cache] = DCACHE_CC_UPDT; 2976 2977 for (word=0; word<m_dcache_words; ++word) 2978 if (r_tgt_be[word] != 0) 2979 break; 2980 } 2981 r_cache_word = word; 2982 2983 } else if ( dcache_hit and not r_tgt_update ) { 2984 r_dcache_fsm[num_cache] = DCACHE_CC_INVAL; 2985 } else { 2986 if(r_tgt_update){ 2987 r_tgt_dcache_rsp[num_cache] = true; 2988 } else { 2989 r_tgt_dcache_rsp[num_cache] = false; 2990 } 2991 r_tgt_dcache_req[num_cache] = false; 2992 r_dcache_fsm [num_cache] = r_dcache_fsm_save[num_cache]; 2993 } 2994 } 2995 break; 2996 } 2997 /////////////////// 2998 case DCACHE_CC_UPDT: // update directory and data cache 2999 { 3000 addr_40 ad = r_tgt_daddr; 3001 3002 m_cpt_dcache_dir_write++; 3003 m_cpt_dcache_data_write++; 3004 3005 uint32_t word = r_cache_word; 3006 3007 if(r_tgt_be[word]) 3008 r_dcache[num_cache]->write(ad+word*4, r_tgt_buf[word]); 3009 3010 word ++; 3011 3012 for (; word<m_dcache_words; ++word) 3013 if (r_tgt_be[word] != 0) 3014 break; 3015 3016 if (word==m_dcache_words) 860 3017 { 861 if ( (p_vci_tgt.rspack.read() or not r_tgt_dcache_rsp.read()) and not r_tgt_dcache_req.read() ) 862 { 863 r_vci_tgt_fsm = TGT_IDLE; 864 r_tgt_dcache_rsp = false; 865 } 866 break; 3018 r_tgt_dcache_req[num_cache] = false; 3019 r_tgt_dcache_rsp[num_cache] = true; 3020 r_dcache_fsm [num_cache] = r_dcache_fsm_save[num_cache]; 3021 word = 0; 867 3022 } 868 } // end switch TGT_FSM 869 870 ///////////////////////////////////////////////////////////////////// 871 // The ICACHE FSM controls the following ressources: 872 // - r_icache_fsm 873 // - r_icache_fsm_save 874 // - r_icache instruction cache access 875 // - r_icache_addr_save 876 // - r_icache_miss_req set 877 // - r_icache_unc_req set 878 // - r_icache_buf_unc_valid set 879 // - r_vci_rsp_icache_miss_ok reset 880 // - r_vci_rsp_ins_error reset 881 // - r_tgt_icache_req reset 882 // - ireq & irsp structures for communication with the processor 883 // 884 // 1/ External requests (update or invalidate) have highest priority. 885 // They are taken into account in the IDLE and WAIT states. 886 // As external hit should be extremly rare on the ICACHE, 887 // all external requests are handled as invalidate... 888 // In case of external request the ICACHE FSM goes to the CC_CHECK 889 // state to test the external hit, and returns in the 890 // pre-empted state after completion. 891 // 2/ Processor requests are taken into account only in the IDLE state. 892 // In case of MISS, or in case of uncached instruction, the FSM 893 // writes the missing address line in the r_icache_addr_save register 894 // and sets the r_icache_miss_req or the r_icache_unc_req flip-flops. 895 // These request flip-flops are reset by the VCI_RSP FSM 896 // when the VCI transaction is completed and the r_icache_buf_unc_valid 897 // is set in case of uncached access. 898 // In case of bus error, the VCI_RSP FSM sets the r_vci_rsp_ins_error 899 // flip-flop. It is reset by the ICACHE FSM. 900 /////////////////////////////////////////////////////////////////////// 901 902 typename iss_t::InstructionRequest ireq = ISS_IREQ_INITIALIZER; 903 typename iss_t::InstructionResponse irsp = ISS_IRSP_INITIALIZER; 904 905 typename iss_t::DataRequest dreq = ISS_DREQ_INITIALIZER; 906 typename iss_t::DataResponse drsp = ISS_DRSP_INITIALIZER; 907 908 m_iss.getRequests( ireq, dreq ); 3023 r_cache_word = word; 3024 3025 break; 3026 } 3027 ///////////////////// 3028 case DCACHE_CC_INVAL: // invalidate a cache line 3029 { 3030 addr_40 ad = r_tgt_daddr; 3031 r_tgt_dcache_rsp[num_cache] = true; 3032 r_dcache [num_cache]->inval(ad); 3033 r_tgt_dcache_req[num_cache] = false; 3034 r_dcache_fsm [num_cache] = r_dcache_fsm_save[num_cache]; 3035 break; 3036 } 3037 /////////////////// 3038 case DCACHE_CC_CLEANUP: 3039 { 3040 // cleanup 3041 if(not r_dcache_cleanup_req[num_cache]){ 3042 r_dcache_cleanup_req [num_cache] = true; 3043 r_dcache_cleanup_line [num_cache] = r_dcache_addr_save[num_cache].read() >> m_dcache_words_shift; 3044 r_dcache_fsm [num_cache] = DCACHE_IDLE; 3045 3046 m_cpt_dcache_dir_read += m_dcache_ways; 3047 r_dcache[num_cache]->inval((addr_40)r_dcache_addr_save[num_cache]); 3048 } 3049 break; 3050 } 3051 3052 } // end switch r_dcache_fsm 3053 3054 ////////// write buffer state update ///////////// 3055 // The update() method must be called at each cycle to update the internal state. 3056 // All pending write requests must be locked in case of SYNC 3057 3058 r_wbuf[num_cache]->update (have_sync); 3059 3060 #if MWBUF_VHDL_TESTBENCH 3061 vhdl_mwbuf_port_flush [num_cache] = (vhdl_tb_t)have_sync; 3062 #endif 3063 3064 drsp [num_cache] = _drsp; 3065 if (_dreq.valid and _drsp.valid) 3066 { 3067 PRINTF(" * <CPU2CACHE> Transaction between cpu %d and Dcache %d (unlock)\n",r_dcache_lock [num_cache].read(),num_cache); 3068 3069 r_dcache_lock [num_cache] = m_nb_cpu; 3070 m_cpt_dcache_access [num_cache] ++; 3071 } 3072 3073 }// end for num_cache 3074 3075 /////////// execute one iss cycle ///////////////////////////////////////////// 3076 3077 for (uint32_t num_cpu=0; num_cpu<m_nb_cpu; ++num_cpu) 3078 { 3079 // Test if the resquest is accepted 3080 typename iss_t::InstructionResponse _irsp = ISS_IRSP_INITIALIZER; 3081 typename iss_t::DataResponse _drsp = ISS_DRSP_INITIALIZER; 3082 3083 if (ireq_num_cache[num_cpu]<m_nb_icache) 3084 _irsp = irsp[ireq_num_cache[num_cpu]]; 3085 if (dreq_num_cache[num_cpu]<m_nb_dcache) 3086 _drsp = drsp[dreq_num_cache[num_cpu]]; 3087 3088 #if CC_XCACHE_WRAPPER_STOP_SIMULATION or CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION 3089 typename iss_t::InstructionRequest _ireq = ISS_IREQ_INITIALIZER; 3090 typename iss_t::DataRequest _dreq = ISS_DREQ_INITIALIZER; 3091 3092 if (ireq_num_cache[num_cpu]<m_nb_icache) 3093 _ireq = ireq[ireq_num_cache[num_cpu]]; 3094 if (dreq_num_cache[num_cpu]<m_nb_dcache) 3095 _dreq = dreq[dreq_num_cache[num_cpu]]; 3096 #endif 909 3097 910 3098 #if CC_XCACHE_WRAPPER_DEBUG 911 if (m_cpt_total_cycles>=CC_XCACHE_WRAPPER_DEBUG_CYCLE_MIN) 912 std::cout << " * Instruction Request : " << ireq << std::endl; 3099 if (m_cpt_total_cycles>=CC_XCACHE_WRAPPER_DEBUG_CYCLE_MIN) 3100 { 3101 3102 std::cout << " * CPU : " << num_cpu << std::endl 3103 << " * Instruction Cache : " << ireq_num_cache[num_cpu] << ", valid : " << (ireq_num_cache[num_cpu]<m_nb_icache) << std::endl 3104 << " * Instruction Request : " << _ireq << std::endl 3105 << " * Instruction Response : " << _irsp << std::endl 3106 << " * Data Cache : " << dreq_num_cache[num_cpu] << ", valid : " << (dreq_num_cache[num_cpu]<m_nb_dcache) << std::endl 3107 << " * Data Request : " << _dreq << std::endl 3108 << " * Data Response : " << _drsp << std::endl; 3109 } 913 3110 #endif 914 3111 915 switch(r_icache_fsm) { 916 ///////////////// 917 case ICACHE_IDLE: 3112 if ((_ireq.valid and not _irsp.valid) or 3113 (_dreq.valid and not _drsp.valid)) 3114 { 3115 m_cpt_frz_cycles [num_cpu]++; 3116 #if CC_XCACHE_WRAPPER_STOP_SIMULATION 3117 m_stop_simulation_nb_frz_cycles [num_cpu]++; 3118 3119 if (m_stop_simulation and (m_stop_simulation_nb_frz_cycles [num_cpu]>= m_stop_simulation_nb_frz_cycles_max)) 918 3120 { 919 if ( r_tgt_icache_req ) { // external request 920 if ( ireq.valid ) m_cost_ins_miss_frz++; 921 r_icache_fsm = ICACHE_CC_CHECK; 922 r_icache_fsm_save = r_icache_fsm.read(); 923 break; 924 } 925 if ( ireq.valid ) { 926 data_t icache_ins = 0; 927 bool icache_hit = false; 928 bool icache_cached = m_cacheability_table[(vci_addr_t)ireq.addr]; 929 bool icache_cleanup_hit = r_icache_cleanup_req and (((addr_40)ireq.addr >> (addr_40)m_icache_words_shift) == r_icache_cleanup_line.read()); 930 931 // icache_hit & icache_ins evaluation 932 if ( icache_cached ) { 933 icache_hit = r_icache.read((vci_addr_t) ireq.addr, &icache_ins); 934 } else { 935 // if uncache, again in the icache_miss_buf 936 icache_hit = ( r_icache_buf_unc_valid and ((addr_40) ireq.addr == (addr_40)r_icache_addr_save)); 937 icache_ins = CACHE_MISS_BUF_RSP_DATA(i,0); 938 CACHE_MISS_BUF_RSP_POP(i); 939 } 940 941 PRINTF(" * <ICACHE> hit %d - cached %d - cleanup_hit %d\n",icache_hit, icache_cached, icache_cleanup_hit); 942 943 ASSERT( not (icache_hit and icache_cleanup_hit), 944 "Icache hit and icache_cleanup_hit"); 945 946 if ( not icache_hit and not icache_cleanup_hit) { 947 m_cpt_ins_miss++; 948 m_cost_ins_miss_frz++; 949 r_icache_addr_save = (addr_40) ireq.addr; 950 951 CACHE_MISS_BUF_REQ_INIT(i); 952 953 if ( icache_cached ) { 954 #if CC_XCACHE_WRAPPER_SELECT_VICTIM 955 r_icache_fsm = ICACHE_MISS_VICTIM; 956 #else 957 r_icache_fsm = ICACHE_MISS_WAIT; 958 #endif 959 r_icache_miss_req = true; 960 961 } else { 962 r_icache_fsm = ICACHE_UNC_WAIT; 963 r_icache_unc_req = true; 964 } 965 } else { 966 r_icache_buf_unc_valid = false; 967 } 968 m_cpt_icache_dir_read += m_icache_ways; 969 m_cpt_icache_data_read += m_icache_ways; 970 irsp.valid = icache_hit; 971 irsp.instruction = icache_ins; 972 } 973 break; 3121 std::cout << std::dec << "CC_XCACHE_WRAPPER \"" << name() << "\" (" << num_cpu << ") : cycle " << m_cpt_total_cycles << ", the cpu is frozen since " << m_stop_simulation_nb_frz_cycles [num_cpu]<< " cycles." << std::endl; 3122 ASSERT(false,"CPU : anormal activity"); // exit 974 3123 } 975 ////////////////////// 976 #if CC_XCACHE_WRAPPER_SELECT_VICTIM 977 case ICACHE_MISS_VICTIM: 978 { 979 if (not r_icache_cleanup_req) 980 { 981 size_t way; 982 size_t set; 983 vci_addr_t addr = (vci_addr_t) r_icache_addr_save.read(); 984 vci_addr_t victim; 985 986 r_icache_cleanup_req = r_icache.victim_select(addr, &victim, &way, &set ); 987 r_icache_cleanup_line = (addr_40) victim; 988 r_icache_miss_way = way; 989 r_icache_miss_set = set; 990 991 r_icache_fsm = ICACHE_MISS_WAIT; 992 } 993 break; 994 } 995 #endif 996 ////////////////////// 997 case ICACHE_MISS_WAIT: 998 { 999 m_cost_ins_miss_frz++; 1000 if ( r_tgt_icache_req ) { // external request 1001 r_icache_fsm = ICACHE_CC_CHECK; 1002 r_icache_fsm_save = r_icache_fsm.read(); 1003 break; 1004 } 1005 1006 bool val = CACHE_MISS_BUF_RSP_VAL(i,0); 1007 1008 PRINTF(" * <ICACHE> val : %d\n",val); 1009 1010 if (val) 1011 { 1012 PRINTF(" * <ICACHE> r_icache_inval_rsp : %d\n",(int) r_icache_inval_rsp ); 1013 PRINTF(" * <ICACHE> r_vci_rsp_ins_error : %d\n",(int) r_vci_rsp_ins_error ); 1014 PRINTF(" * <ICACHE> r_icache_cleanup_req : %d\n",(int) r_icache_cleanup_req); 1015 1016 // if (not r_icache_inval_rsp ) 1017 // { 1018 // Miss read response and no invalidation 1019 if ( r_vci_rsp_ins_error ) { 1020 r_icache_fsm = ICACHE_ERROR; 1021 } else { 1022 #if not CC_XCACHE_WRAPPER_SELECT_VICTIM 1023 if (not r_icache_cleanup_req.read()) 1024 #endif 1025 { 1026 r_icache_update_addr = 0; 1027 r_icache_fsm = ICACHE_MISS_UPDT; 1028 } 1029 } 1030 // } 1031 // else 1032 // { 1033 // r_icache_inval_rsp = false; 1034 1035 // // Miss read response and invalidation 1036 // if ( r_vci_rsp_ins_error ) 1037 // r_icache_fsm = ICACHE_ERROR; 1038 // else 1039 // r_icache_fsm = ICACHE_CC_CLEANUP; 1040 // } 1041 } 1042 break; 1043 } 1044 ///////////////////// 1045 case ICACHE_UNC_WAIT: 1046 { 1047 m_cost_ins_miss_frz++; 1048 if ( r_tgt_icache_req ) { // external request 1049 r_icache_fsm = ICACHE_CC_CHECK; 1050 r_icache_fsm_save = r_icache_fsm.read(); 1051 break; 1052 } 1053 1054 bool ok = CACHE_MISS_BUF_RSP_VAL(i,0); 1055 1056 if (ok) 1057 { 1058 if ( r_vci_rsp_ins_error ) { 1059 r_icache_fsm = ICACHE_ERROR; 1060 } else { 1061 r_icache_fsm = ICACHE_IDLE; 1062 r_icache_buf_unc_valid = true; 1063 } 1064 } 1065 break; 1066 } 1067 ////////////////// 1068 case ICACHE_ERROR: 1069 { 1070 if ( (addr_40)ireq.addr == (addr_40)r_icache_addr_save ) { 1071 irsp.error = true; 1072 irsp.valid = true; 1073 } 1074 r_icache_fsm = ICACHE_IDLE; 1075 r_vci_rsp_ins_error = false; 1076 break; 1077 } 1078 ////////////////////// 1079 case ICACHE_MISS_UPDT: 1080 { 1081 size_t word = r_icache_update_addr.read(); 1082 vci_addr_t addr = (vci_addr_t) r_icache_addr_save.read(); 1083 size_t way = 0; 1084 size_t set = 0; 1085 1086 // need invalid rsp, don't select a victim 1087 if (not r_icache_inval_rsp ) 1088 { 1089 #if CC_XCACHE_WRAPPER_SELECT_VICTIM 1090 way = r_icache_miss_way.read(); 1091 set = r_icache_miss_set.read(); 1092 #else 1093 1094 // First word : select an victim ! 1095 if (word == 0) 1096 { 1097 vci_addr_t victim; 1098 1099 // r_icache_cleanup_req is false because is the transition condition to go in ICACHE_MISS_UPDT state 1100 r_icache_cleanup_req = r_icache.victim_select(addr, &victim, &way, &set ); 1101 r_icache.victim_update_tag(addr, way, set); 1102 1103 r_icache_cleanup_line = (addr_40) victim; 1104 r_icache_miss_way = way; 1105 r_icache_miss_set = set; 1106 } 1107 else 1108 { 1109 way = r_icache_miss_way.read(); 1110 set = r_icache_miss_set.read(); 1111 } 1112 #endif 1113 } 1114 bool val = CACHE_MISS_BUF_RSP_VAL(i,word); 1115 1116 if (val) 1117 { 1118 PRINTF(" * <ICACHE> rsp_val : %d/%d\n",(int)r_icache_update_addr,m_icache_words); 1119 PRINTF(" * <ICACHE> r_icache_inval_rsp : %d\n",(int)r_icache_inval_rsp); 1120 PRINTF(" * <ICACHE> ins : %x\n",(int)CACHE_MISS_BUF_RSP_DATA(i,word)); 1121 1122 // m_cpt_icache_dir_write++; 1123 // m_cpt_icache_data_write++; 1124 // if ( ireq.valid ) m_cost_ins_miss_frz++; 1125 1126 // if need invalid rsp, don't modify the cache, but pop the buf_rsp 1127 if (not r_icache_inval_rsp ) 1128 r_icache.write(way, set, word, CACHE_MISS_BUF_RSP_DATA(i,word)); 1129 CACHE_MISS_BUF_RSP_POP(i); 1130 1131 r_icache_update_addr = ++word; 1132 1133 // if last word, finish the update 1134 if (word >= m_icache_words) 1135 { 1136 // Last word : if previous invalid_rsp, can cleanup, else update the TAG 1137 if (r_icache_inval_rsp) 1138 { 1139 r_icache_inval_rsp = false; 1140 r_icache_fsm = ICACHE_CC_CLEANUP; 1141 } 1142 else 1143 { 1144 #if CC_XCACHE_WRAPPER_SELECT_VICTIM 1145 r_icache.victim_update_tag(addr, way, set); 1146 #endif 1147 r_icache_fsm = ICACHE_IDLE; 1148 } 1149 } 1150 } 1151 1152 break; 1153 } 1154 //////////////////// 1155 case ICACHE_CC_CLEANUP: 1156 { 1157 // external cache invalidate request 1158 if ( r_tgt_icache_req ) 1159 { 1160 r_icache_fsm = ICACHE_CC_CHECK; 1161 r_icache_fsm_save = r_icache_fsm.read(); 1162 break; 1163 } 1164 // cleanup 1165 if(not r_icache_cleanup_req){ 1166 r_icache_cleanup_req = true; 1167 r_icache_cleanup_line = r_icache_addr_save.read() >> m_icache_words_shift; 1168 r_icache_fsm = ICACHE_IDLE; 1169 } 1170 break; 1171 } 1172 ///////////////////// 1173 case ICACHE_CC_CHECK: // read directory in case of invalidate or update request 1174 { 1175 1176 m_cpt_icache_dir_read += m_icache_ways; 1177 m_cpt_icache_data_read += m_icache_ways; 1178 addr_40 ad = r_tgt_addr; 1179 data_t icache_rdata = 0; 1180 1181 if((r_icache_fsm_save == ICACHE_MISS_WAIT) and 1182 ( (r_icache_addr_save.read() & ~((m_icache_words<<2)-1)) == (ad & ~((m_icache_words<<2)-1)))) { 1183 r_icache_inval_rsp = true; 1184 r_tgt_icache_req = false; 1185 if(r_tgt_update){ // Also send a cleanup and answer 1186 r_tgt_icache_rsp = true; 1187 } else { // Also send a cleanup but don't answer 1188 r_tgt_icache_rsp = false; 1189 } 1190 r_icache_fsm = r_icache_fsm_save; 1191 } else { 1192 bool icache_hit = r_icache.read(ad, &icache_rdata); 1193 if ( icache_hit and r_tgt_update ) 1194 { 1195 #if CC_XCACHE_WRAPPER_CC_UPDATE_MULTI_CYCLE 1196 uint32_t word = r_cache_word; 1197 data_t mask = vci_param::be2mask(r_tgt_be[word]); 1198 data_t rdata = 0; 1199 1200 r_icache.read(ad+word*4,&rdata); 1201 r_tgt_buf[word] = (mask & r_tgt_buf[word]) | (~mask & rdata); 1202 1203 word ++; 1204 #if CC_XCACHE_WRAPPER_CC_UPDATE_MULTI_CYCLE_OPT 1205 for (; word<m_icache_words; ++word) 1206 if (r_tgt_be[word] != 0) 1207 break; 1208 #endif 1209 1210 if (word==m_icache_words) 1211 { 1212 r_icache_fsm = ICACHE_CC_UPDT; 1213 1214 #if CC_XCACHE_WRAPPER_CC_UPDATE_MULTI_CYCLE_OPT 1215 for (word=0; word<m_icache_words; ++word) 1216 if (r_tgt_be[word] != 0) 1217 break; 1218 #else 1219 word = 0; 1220 #endif 1221 } 1222 r_cache_word = word; 1223 #else //CC_XCACHE_WRAPPER_CC_UPDATE_MULTI_CYCLE 1224 r_icache_fsm = ICACHE_CC_UPDT; 1225 // complete the line buffer in case of update 1226 for(size_t i=0; i<m_icache_words; i++){ 1227 data_t rdata = 0; 1228 r_icache.read(ad + i*4,&rdata); 1229 data_t mask = vci_param::be2mask(r_tgt_be[i]); 1230 r_tgt_buf[i] = (mask & r_tgt_buf[i]) | (~mask & rdata); 1231 } 1232 #endif //CC_XCACHE_WRAPPER_CC_UPDATE_MULTI_CYCLE 1233 } else if ( icache_hit and not r_tgt_update ) { 1234 r_icache_fsm = ICACHE_CC_INVAL; 1235 } else { // instruction not found (can happen) 1236 r_tgt_icache_req = false; 1237 if(r_tgt_update){ 1238 r_tgt_icache_rsp = true; 1239 } else { 1240 r_tgt_icache_rsp = false; 1241 } 1242 r_icache_fsm = r_icache_fsm_save; 1243 } 1244 } 1245 break; 1246 } 1247 ///////////////////// 1248 case ICACHE_CC_INVAL: 1249 { 1250 addr_40 ad = r_tgt_addr; 1251 if ( ireq.valid ) m_cost_ins_miss_frz++; 1252 m_cpt_icache_dir_read += m_icache_ways; 1253 r_tgt_icache_rsp = true; 1254 r_icache.inval(ad); 1255 r_tgt_icache_req = false; 1256 r_icache_fsm = r_icache_fsm_save; 1257 break; 1258 } 1259 ///////////////////// 1260 case ICACHE_CC_UPDT: 1261 { 1262 addr_40 ad = r_tgt_addr.read(); 1263 m_cpt_icache_dir_write++; 1264 m_cpt_icache_data_write++; 1265 1266 #if CC_XCACHE_WRAPPER_CC_UPDATE_MULTI_CYCLE 1267 uint32_t word = r_cache_word; 1268 1269 if(r_tgt_be[word]) 1270 r_icache.write(ad+word*4, r_tgt_buf[word]); 1271 1272 word ++; 1273 #if CC_XCACHE_WRAPPER_CC_UPDATE_MULTI_CYCLE_OPT 1274 for (; word<m_icache_words; ++word) 1275 if (r_tgt_be[word] != 0) 1276 break; 1277 #endif 1278 1279 if (word==m_icache_words) 1280 { 1281 r_tgt_icache_req = false; 1282 r_tgt_icache_rsp = true; 1283 r_icache_fsm = r_icache_fsm_save.read(); 1284 word = 0; 1285 } 1286 r_cache_word = word; 1287 #else //CC_XCACHE_WRAPPER_CC_UPDATE_MULTI_CYCLE 1288 data_t* buf = r_tgt_buf; 1289 for(size_t i=0; i<m_icache_words;i++){ 1290 if(r_tgt_be[i]) r_icache.write( ad + i*4, buf[i]); 1291 } 1292 r_tgt_icache_req = false; 1293 r_tgt_icache_rsp = true; 1294 r_icache_fsm = r_icache_fsm_save.read(); 1295 #endif //CC_XCACHE_WRAPPER_CC_UPDATE_MULTI_CYCLE 1296 1297 break; 1298 } 1299 1300 } // end switch r_icache_fsm 1301 1302 #if CC_XCACHE_WRAPPER_DEBUG 1303 if (m_cpt_total_cycles>=CC_XCACHE_WRAPPER_DEBUG_CYCLE_MIN) 1304 std::cout << " * Instruction Response : " << irsp << std::endl; 1305 #endif 1306 1307 //////////////////////////////////////////////////////////////////////:///////////// 1308 // The DCACHE FSM controls the following ressources: 1309 // - r_dcache_fsm 1310 // - r_dcache_fsm_save 1311 // - r_dcache (data cache access) 1312 // - r_dcache_addr_save 1313 // - r_dcache_wdata_save 1314 // - r_dcache_rdata_save 1315 // - r_dcache_type_save 1316 // - r_dcache_be_save 1317 // - r_dcache_cached_save 1318 // - r_dcache_miss_req set 1319 // - r_dcache_unc_req set 1320 // - r_dcache_cleanup_req set 1321 // - r_vci_rsp_data_error reset 1322 // - r_tgt_dcache_req reset 1323 // - r_wbuf write 1324 // - dreq & drsp structures for communication with the processor 1325 // 1326 // 1/ EXTERNAL REQUEST : 1327 // There is an external request when the tgt_dcache req flip-flop is set, 1328 // requesting a line invalidation or a line update. 1329 // External requests are taken into account in the states IDLE, WRITE_REQ, 1330 // UNC_WAIT, MISS_WAIT, and have the highest priority : 1331 // The actions associated to the pre-empted state are not executed, the DCACHE FSM 1332 // goes to the CC_CHECK state to execute the requested action, and returns to the 1333 // pre-empted state. 1334 // 2/ PROCESSOR REQUEST : 1335 // In order to support VCI write burst, the processor requests are taken into account 1336 // in the WRITE_REQ state as well as in the IDLE state. 1337 // - In the IDLE state, the processor request cannot be satisfied if 1338 // there is a cached read miss, or an uncached read. 1339 // - In the WRITE_REQ state, the request cannot be satisfied if 1340 // there is a cached read miss, or an uncached read, 1341 // or when the write buffer is full. 1342 // - In all other states, the processor request is not satisfied. 1343 // 1344 // The cache access takes into account the cacheability_table. 1345 // In case of processor request, there is five conditions to exit the IDLE state: 1346 // - CACHED READ MISS => to the MISS_WAIT state (waiting the r_miss_ok signal), 1347 // then to the MISS_UPDT state, and finally to the IDLE state. 1348 // - UNCACHED READ => to the UNC_WAIT state (waiting the r_miss_ok signal), 1349 // and to the IDLE state. 1350 // - CACHE INVALIDATE HIT => to the INVAL state for one cycle, then to IDLE state. 1351 // - WRITE MISS => directly to the WRITE_REQ state to access the write buffer. 1352 // - WRITE HIT => to the WRITE_UPDT state, then to the WRITE_REQ state. 1353 // 1354 // Error handling : Read Bus Errors are synchronous events, but 1355 // Write Bus Errors are asynchronous events (processor is not frozen). 1356 // - If a Read Bus Error is detected, the VCI_RSP FSM sets the 1357 // r_vci_rsp_data_error flip-flop, and the synchronous error is signaled 1358 // by the DCACHE FSM. 1359 // - If a Write Bus Error is detected, the VCI_RSP FSM signals 1360 // the asynchronous error using the setWriteBerr() method. 1361 /////////////////////////////////////////////////////////////////////////////////// 1362 1363 #if CC_XCACHE_WRAPPER_DEBUG 1364 if (m_cpt_total_cycles>=CC_XCACHE_WRAPPER_DEBUG_CYCLE_MIN) 1365 std::cout << " * Data Request : " << dreq << std::endl; 1366 #endif 1367 1368 switch ( r_dcache_fsm ) { 1369 1370 ///////////////// 1371 case DCACHE_IDLE: 1372 { 1373 if ( r_tgt_dcache_req ) { // external request 1374 r_dcache_fsm = DCACHE_CC_CHECK; 1375 r_dcache_fsm_save = r_dcache_fsm; 1376 break; 1377 } 1378 1379 if ( dreq.valid ) { 1380 PRINTF(" * <DCACHE> Have dreq\n"); 1381 1382 data_t dcache_rdata = 0; 1383 // dcache_cached and dcache_hit don't used with dreq.type == {DATA_SC, XTN_READ, XTN_WRITE} 1384 bool dcache_cached = m_cacheability_table[(vci_addr_t)dreq.addr]; 1385 bool dcache_hit = r_dcache.read((vci_addr_t) dreq.addr, &dcache_rdata); 1386 bool dcache_cleanup_hit = r_dcache_cleanup_req and (((addr_40)dreq.addr >> (addr_40)m_dcache_words_shift) == r_dcache_cleanup_line.read()); 1387 1388 PRINTF(" * <DCACHE> hit %d - cached %d - cleanup_hit %d\n",dcache_hit, dcache_cached, dcache_cleanup_hit); 1389 1390 m_cpt_dcache_data_read += m_dcache_ways; 1391 m_cpt_dcache_dir_read += m_dcache_ways; 1392 1393 switch( dreq.type ) { 1394 case iss_t::DATA_READ: 1395 case iss_t::DATA_LL: 1396 { 1397 m_cpt_data_read++; // new dcache read 1398 1399 if (dcache_hit) // no special test for uncached read, because it's always miss 1400 { 1401 // address is in the cache : return the word 1402 r_dcache_fsm = DCACHE_IDLE; 1403 drsp.valid = true; 1404 drsp.rdata = dcache_rdata; // return read data (cf dcache_hit) 1405 1406 // if the request is a Load Linked instruction, save request information 1407 if(dreq.type == iss_t::DATA_LL) 1408 { 1409 PRINTF(" * <DCACHE> ll_valid = true\n"); 1410 1411 r_dcache_ll_valid = true; 1412 r_dcache_ll_data = dcache_rdata; 1413 r_dcache_ll_addr = (vci_addr_t) dreq.addr; 1414 #ifdef COHERENCE_DEBUG 1415 std::cout << "Value returned for LL at address : " << std::hex << dreq.addr << " data : " << std::dec << dcache_rdata<< std::endl; 1416 r_dcache.read((vci_addr_t) dreq.addr, &dcache_rdata); 1417 std::cout << "Value stored at this address : " << std::hex << dreq.addr << " data : " << std::dec << dcache_rdata<< std::endl; 1418 #endif 1419 } 1420 } 1421 else 1422 { 1423 if (not dcache_cleanup_hit) 1424 { 1425 CACHE_MISS_BUF_REQ_INIT(d); 1426 1427 // Miss : send signal at the CMD_FSM (via r_dcache_miss_req or r_dcache_unc_req) 1428 if ( dcache_cached ) { 1429 m_cpt_data_read_miss++; 1430 m_cost_data_miss_frz++; 1431 r_dcache_miss_req = true; 1432 #if CC_XCACHE_WRAPPER_SELECT_VICTIM 1433 r_dcache_fsm = DCACHE_MISS_VICTIM; 1434 #else 1435 r_dcache_fsm = DCACHE_MISS_WAIT; 1436 #endif 1437 1438 } else { 1439 if (not r_dcache_previous_unc.read()) // strongly order to the uncached access 1440 { 1441 r_dcache_previous_unc = true; 1442 1443 m_cpt_data_read_uncached++; 1444 m_cost_unc_read_frz++; 1445 r_dcache_unc_req = true; 1446 r_dcache_fsm = DCACHE_UNC_WAIT; 1447 } 1448 } 1449 } 1450 } 1451 } 1452 break; 1453 case iss_t::DATA_SC: 1454 { 1455 PRINTF(" * <DCACHE> DATA_SC - ll_valid = %d\n",r_dcache_ll_valid.read()); 1456 1457 if (not r_dcache_previous_unc.read() and not dcache_cleanup_hit) // strongly order to the uncached access 1458 { 1459 //m_cpt_data_read_unc++; // instruction must read the memory in uncached mode 1460 m_cost_unc_read_frz++; 1461 1462 // if previous load linked (with the same address), make a transaction 1463 // else, keep in IDLE state and return 1 (no OK) 1464 if(r_dcache_ll_valid.read() and (r_dcache_ll_addr.read() == (vci_addr_t)dreq.addr)){ 1465 PRINTF(" * <DCACHE> have previous load linked\n"); 1466 1467 r_dcache_previous_unc = true; 1468 1469 r_dcache_sc_req = true; 1470 1471 CACHE_MISS_BUF_REQ_INIT(d); 1472 1473 r_dcache_fsm = DCACHE_SC_WAIT; 1474 } else { 1475 PRINTF(" * <DCACHE> don't have previous load linked\n"); 1476 1477 drsp.valid = true; 1478 drsp.rdata = 1; // SC rsp NOK 1479 r_dcache_ll_valid = false; 1480 } 1481 } 1482 1483 break; 1484 } 1485 case iss_t::XTN_READ: 1486 case iss_t::XTN_WRITE: 1487 { 1488 bool drsp_valid = false; 1489 // only DCACHE INVALIDATE and SYNC request are supported 1490 switch (dreq.addr>>2) 1491 { 1492 case iss_t::XTN_DCACHE_INVAL : 1493 { 1494 drsp_valid = true; 1495 r_dcache_fsm = DCACHE_INVAL; 1496 break; 1497 } 1498 case iss_t::XTN_SYNC : 1499 { 1500 // Test if write buffer is already empty 1501 // * gain : 1 cycle 1502 // * cost : can be on the critical path 1503 if (r_wbuf.empty()) 1504 { 1505 drsp_valid = true; 1506 r_dcache_fsm = DCACHE_IDLE; 1507 } 1508 else 1509 { 1510 drsp_valid = false; 1511 r_dcache_fsm = DCACHE_SYNC; 1512 } 1513 break; 1514 } 1515 default : 1516 { 1517 // std::cout << "Warning in VCI_CC_XCACHE_WRAPPER " << name() << std::endl; 1518 // std::cout << "Unsupported external access : " << (dreq.addr>>2) << std::endl; 1519 1520 r_dcache_fsm = DCACHE_IDLE; 1521 } 1522 }//end switch (dreq.addr>>2) 1523 1524 drsp.valid = drsp_valid; 1525 drsp.rdata = 0; 1526 break; 1527 } 1528 case iss_t::DATA_WRITE: 1529 1530 if (dcache_cached or not r_dcache_previous_unc.read()) // strongly order to the uncached access 1531 { 1532 bool drsp_valid; 1533 1534 drsp_valid = r_wbuf.write((addr_40) dreq.addr, dreq.be, dreq.wdata, dcache_cached); 1535 1536 if (drsp_valid) 1537 { 1538 m_cpt_data_write++; 1539 1540 if (not dcache_cached) 1541 { 1542 r_dcache_previous_unc = true; 1543 m_cpt_data_write_uncached++; 1544 } 1545 else if (not dcache_hit) 1546 m_cpt_data_write_miss++; 1547 1548 if ( dcache_hit) { 1549 r_dcache_fsm = DCACHE_WRITE_UPDT; 1550 } else { 1551 r_dcache_fsm = DCACHE_IDLE; 1552 } 1553 } 1554 1555 drsp.valid = drsp_valid; 1556 drsp.rdata = 0; 1557 } 1558 break; 1559 } // end switch dreq.type 1560 1561 r_dcache_addr_save = (addr_40) dreq.addr; 1562 r_dcache_type_save = dreq.type; 1563 r_dcache_wdata_save = dreq.wdata; 1564 r_dcache_be_save = dreq.be; 1565 r_dcache_rdata_save = dcache_rdata; 1566 r_dcache_cached_save = dcache_cached; 1567 1568 } else { // end if dreq.valid 1569 r_dcache_fsm = DCACHE_IDLE; 1570 } 1571 1572 break; 1573 } 1574 /////////////////////// 1575 case DCACHE_WRITE_UPDT: 1576 { 1577 m_cpt_dcache_data_write++; 1578 data_t mask = vci_param::be2mask(r_dcache_be_save); 1579 data_t wdata = (mask & r_dcache_wdata_save) | (~mask & r_dcache_rdata_save); 1580 vci_addr_t ad = r_dcache_addr_save.read(); 1581 r_dcache.write(ad, wdata); 1582 1583 r_dcache_fsm = DCACHE_IDLE; 1584 1585 break; 1586 } 1587 ////////////////////// 1588 #if CC_XCACHE_WRAPPER_SELECT_VICTIM 1589 case DCACHE_MISS_VICTIM: 1590 { 1591 if (not r_dcache_cleanup_req.read()) 1592 { 1593 size_t way; 1594 size_t set; 1595 vci_addr_t addr = (vci_addr_t) r_dcache_addr_save.read(); 1596 vci_addr_t victim; 1597 1598 r_dcache_cleanup_req = r_dcache.victim_select(addr, &victim, &way, &set ); 1599 r_dcache_cleanup_line = (addr_40) victim; 1600 r_dcache_miss_way = way; 1601 r_dcache_miss_set = set; 1602 1603 r_dcache_fsm = DCACHE_MISS_WAIT; 1604 } 1605 1606 break; 1607 } 1608 #endif 1609 ////////////////////// 1610 case DCACHE_MISS_WAIT: 1611 { 1612 1613 if ( dreq.valid ) m_cost_data_miss_frz++; 1614 if ( r_tgt_dcache_req.read() ) { // external request 1615 r_dcache_fsm = DCACHE_CC_CHECK; 1616 r_dcache_fsm_save = r_dcache_fsm; 1617 break; 1618 } 1619 1620 bool val = CACHE_MISS_BUF_RSP_VAL(d,0); 1621 if (val) 1622 { 1623 // if (not r_dcache_inval_rsp ) 1624 // { 1625 1626 // Miss read response and no invalidation 1627 if ( r_vci_rsp_data_error ) 1628 { 1629 r_dcache_fsm = DCACHE_ERROR; 1630 } 1631 else 1632 { 1633 #if not CC_XCACHE_WRAPPER_SELECT_VICTIM 1634 if (not r_dcache_cleanup_req.read()) 1635 #endif 1636 { 1637 r_dcache_update_addr = 0; 1638 r_dcache_fsm = DCACHE_MISS_UPDT; 1639 } 1640 } 1641 // } 1642 // else 1643 // { 1644 // r_dcache_inval_rsp = false; 1645 1646 // // Miss read response and invalidation 1647 // if ( r_vci_rsp_data_error ) { 1648 // r_dcache_fsm = DCACHE_ERROR; 1649 // } else { 1650 // r_dcache_fsm = DCACHE_CC_CLEANUP; 1651 // } 1652 // } 1653 } 1654 break; 1655 } 1656 ////////////////////// 1657 case DCACHE_MISS_UPDT: 1658 { 1659 size_t word = r_dcache_update_addr.read(); 1660 vci_addr_t addr = (vci_addr_t) r_dcache_addr_save.read(); 1661 size_t way = 0; 1662 size_t set = 0; 1663 1664 // need invalid rsp, don't select a victim 1665 if (not r_dcache_inval_rsp ) 1666 { 1667 #if CC_XCACHE_WRAPPER_SELECT_VICTIM 1668 way = r_dcache_miss_way.read(); 1669 set = r_dcache_miss_set.read(); 1670 #else 1671 // First word : select an victim ! 1672 if (word == 0) 1673 { 1674 vci_addr_t victim; 1675 1676 // r_dcache_cleanup_req is false (condition to enter in DCACHE_MISS_UPDT 1677 r_dcache_cleanup_req = r_dcache.victim_select(addr, &victim, &way, &set ); 1678 r_dcache.victim_update_tag(addr, way, set); 1679 r_dcache_cleanup_line = (addr_40) victim; 1680 1681 r_dcache_miss_way = way; 1682 r_dcache_miss_set = set; 1683 } 1684 else 1685 { 1686 way = r_dcache_miss_way.read(); 1687 set = r_dcache_miss_set.read(); 1688 } 1689 #endif 1690 } 1691 1692 bool val = CACHE_MISS_BUF_RSP_VAL(d,word); 1693 if (val) 1694 { 1695 // m_cpt_dcache_dir_write++; 1696 // if ( ireq.valid ) m_cost_data_miss_frz++; 1697 1698 // if need invalid rsp, don't modify the cache, but pop the buf_rsp 1699 if (not r_dcache_inval_rsp ) 1700 { 1701 r_dcache.write(way, set, word, CACHE_MISS_BUF_RSP_DATA(d,word)); 1702 m_cpt_dcache_data_write++; 1703 } 1704 1705 CACHE_MISS_BUF_RSP_POP(d); 1706 r_dcache_update_addr = ++word; 1707 1708 // if last word, finish the update 1709 if (word >= m_dcache_words) 1710 { 1711 // Last word : if previous invalid_rsp, can cleanup, else update the TAG 1712 if (r_dcache_inval_rsp) 1713 { 1714 r_dcache_inval_rsp = false; 1715 r_dcache_fsm = DCACHE_CC_CLEANUP; 1716 } 1717 else 1718 { 1719 #if CC_XCACHE_WRAPPER_SELECT_VICTIM 1720 r_dcache.victim_update_tag(addr, way, set); 1721 #endif 1722 r_dcache_fsm = DCACHE_IDLE; 1723 } 1724 } 1725 } 3124 } 3125 else 3126 { 3127 m_stop_simulation_nb_frz_cycles [num_cpu] = 0; // reinit counter 3128 #endif //CC_XCACHE_WRAPPER_STOP_SIMULATION 3129 } 3130 3131 #if CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION 3132 if (generate_log_transaction_file_icache and _ireq.valid and _irsp.valid) 3133 { 3134 log_transaction_file_icache [num_cpu] 3135 << "[" << m_cpt_total_cycles << "]" 3136 << std::hex 3137 << " @ " << std::setw(8) << (uint32_t)_ireq.addr 3138 << " (" << std::setw(8) << (uint32_t)set_num_icache_only(_ireq.addr,ireq_num_cache[num_cpu]) 3139 << " - L " << std::setw(8) <<((uint32_t)set_num_icache_only(_ireq.addr,ireq_num_cache[num_cpu])&m_icache_yzmask) << ")" 3140 << " I " << std::setw(8) << (uint32_t)_irsp.instruction 3141 << " error " << (uint32_t)_irsp.error 3142 << std::dec 3143 << std::endl; 3144 } 3145 3146 if (generate_log_transaction_file_dcache and _dreq.valid and _drsp.valid) 3147 { 3148 log_transaction_file_dcache [num_cpu] 3149 << "[" << m_cpt_total_cycles << "]" 3150 << std::hex 3151 << " @ " << std::setw(8) << (uint32_t)_dreq.addr 3152 << " (" << std::setw(8) << (uint32_t)set_num_dcache_only(_dreq.addr,dreq_num_cache[num_cpu]) 3153 << " - L " << std::setw(8) <<((uint32_t)set_num_dcache_only(_dreq.addr,dreq_num_cache[num_cpu])&m_dcache_yzmask) << ")" 3154 << " be " << std::setw(1) << (uint32_t)_dreq.be 3155 << " W " << std::setw(8) << (uint32_t)_dreq.wdata 3156 << " R " << std::setw(8) << (uint32_t)_drsp.rdata 3157 << " error " << (uint32_t)_drsp.error 3158 << std::dec 3159 << " " << type_str(_dreq.type); 1726 3160 1727 break; 1728 } 1729 //////////////////// 1730 case DCACHE_UNC_WAIT: 1731 { 1732 if ( dreq.valid ) m_cost_unc_read_frz++; 1733 if ( r_tgt_dcache_req ) { // external request 1734 r_dcache_fsm = DCACHE_CC_CHECK; 1735 r_dcache_fsm_save = r_dcache_fsm; 1736 break; 1737 } 1738 1739 bool ok = CACHE_MISS_BUF_RSP_VAL(d,0); 1740 1741 if (ok) { 1742 if ( r_vci_rsp_data_error ) { 1743 r_dcache_fsm = DCACHE_ERROR; 1744 } else { 1745 data_t rdata = CACHE_MISS_BUF_RSP_DATA(d,0); 1746 CACHE_MISS_BUF_RSP_POP(d); 1747 1748 if(dreq.type == iss_t::DATA_LL){ 1749 PRINTF(" * <DCACHE> ll_valid = true\n"); 1750 1751 r_dcache_ll_valid = true; 1752 r_dcache_ll_data = rdata; 1753 r_dcache_ll_addr = (vci_addr_t) dreq.addr; 1754 } 1755 r_dcache_fsm = DCACHE_IDLE; 1756 drsp.valid = true; 1757 drsp.rdata = rdata; 1758 } 1759 } 1760 break; 1761 } 1762 //////////////////// 1763 case DCACHE_SC_WAIT: 1764 { 1765 if ( dreq.valid ) m_cost_unc_read_frz++; 1766 if ( r_tgt_dcache_req ) { // external request 1767 r_dcache_fsm = DCACHE_CC_CHECK; 1768 r_dcache_fsm_save = r_dcache_fsm; 1769 break; 1770 } 1771 1772 bool ok = CACHE_MISS_BUF_RSP_VAL(d,0); 1773 1774 if (ok) { 1775 if ( r_vci_rsp_data_error ) { 1776 r_dcache_fsm = DCACHE_ERROR; 1777 } else { 1778 r_dcache_fsm = DCACHE_IDLE; 1779 drsp.valid = true; 1780 drsp.rdata = CACHE_MISS_BUF_RSP_DATA(d,0); 1781 CACHE_MISS_BUF_RSP_POP(d); 1782 r_dcache_ll_valid = false; 1783 } 1784 } 1785 break; 1786 } 1787 1788 ////////////////// 1789 case DCACHE_ERROR: 1790 { 1791 r_dcache_fsm = DCACHE_IDLE; 1792 r_vci_rsp_data_error = false; 1793 drsp.error = true; 1794 drsp.valid = true; 1795 break; 1796 } 1797 ///////////////// 1798 case DCACHE_INVAL: 1799 { 1800 if ( r_tgt_dcache_req.read() ) { // external request 1801 r_dcache_fsm = DCACHE_CC_CHECK; 1802 r_dcache_fsm_save = r_dcache_fsm; 1803 break; 1804 } 1805 if( not r_dcache_cleanup_req.read() ){ 1806 m_cpt_dcache_dir_read += m_dcache_ways; 1807 vci_addr_t ad = r_dcache_addr_save.read(); 1808 r_dcache_cleanup_req = r_dcache.inval(ad); 1809 r_dcache_cleanup_line = r_dcache_addr_save.read() >> m_dcache_words_shift; 1810 1811 r_dcache_fsm = DCACHE_IDLE; 1812 } 1813 break; 1814 } 1815 case DCACHE_SYNC : 1816 { 1817 if ( r_tgt_dcache_req ) { // external request 1818 r_dcache_fsm = DCACHE_CC_CHECK; 1819 r_dcache_fsm_save = r_dcache_fsm; 1820 break; 1821 } 1822 1823 if (r_wbuf.empty()) 1824 { 1825 drsp.valid = true; // end, can accept the sync request 1826 r_dcache_fsm = DCACHE_IDLE; 1827 } 1828 break; 1829 } 1830 ///////////////////// 1831 case DCACHE_CC_CHECK: // read directory in case of invalidate or update request 1832 { 1833 addr_40 ad = r_tgt_addr; 1834 data_t dcache_rdata = 0; 1835 1836 if((r_dcache_fsm_save == DCACHE_MISS_WAIT) and 1837 ( (r_dcache_addr_save.read() & ~((m_dcache_words<<2)-1)) == (ad & ~((m_dcache_words<<2)-1)))) { 1838 r_dcache_inval_rsp = true; 1839 r_tgt_dcache_req = false; 1840 if(r_tgt_update){ // Also send a cleanup and answer 1841 r_tgt_dcache_rsp = true; 1842 } else { // Also send a cleanup but don't answer 1843 r_tgt_dcache_rsp = false; 1844 } 1845 r_dcache_fsm = r_dcache_fsm_save; 1846 } else { 1847 bool dcache_hit = r_dcache.read(ad, &dcache_rdata); 1848 1849 m_cpt_dcache_data_read += m_dcache_ways; 1850 m_cpt_dcache_dir_read += m_dcache_ways; 1851 1852 #ifdef COHERENCE_DEBUG 1853 std::cout << "PROC " << m_srcid_rw << " DCACHE_CC_CHECK, hit ? : " << dcache_hit << std::endl; 1854 #endif 1855 if ( dcache_hit and r_tgt_update ) 1856 { 1857 #if CC_XCACHE_WRAPPER_CC_UPDATE_MULTI_CYCLE 1858 uint32_t word = r_cache_word; 1859 data_t mask = vci_param::be2mask(r_tgt_be[word]); 1860 data_t rdata = 0; 1861 1862 r_dcache.read(ad+word*4,&rdata); 1863 1864 r_tgt_buf[word] = (mask & r_tgt_buf[word]) | (~mask & rdata); 1865 1866 word ++; 1867 #if CC_XCACHE_WRAPPER_CC_UPDATE_MULTI_CYCLE_OPT 1868 for (; word<m_dcache_words; ++word) 1869 if (r_tgt_be[word] != 0) 1870 break; 1871 #endif 1872 1873 if (word==m_dcache_words) 1874 { 1875 r_dcache_fsm = DCACHE_CC_UPDT; 1876 #if CC_XCACHE_WRAPPER_CC_UPDATE_MULTI_CYCLE_OPT 1877 for (word=0; word<m_dcache_words; ++word) 1878 if (r_tgt_be[word] != 0) 1879 break; 1880 #else 1881 word = 0; 1882 #endif 1883 } 1884 r_cache_word = word; 1885 #else //CC_XCACHE_WRAPPER_CC_UPDATE_MULTI_CYCLE 1886 // complete the line buffer in case of update 1887 for(size_t i=0; i<m_dcache_words; i++){ 1888 data_t rdata = 0; 1889 r_dcache.read(ad + i*4,&rdata); 1890 data_t mask = vci_param::be2mask(r_tgt_be[i]); 1891 r_tgt_buf[i] = (mask & r_tgt_buf[i]) | (~mask & rdata); 1892 } 1893 r_dcache_fsm = DCACHE_CC_UPDT; 1894 #endif //CC_XCACHE_WRAPPER_CC_UPDATE_MULTI_CYCLE 1895 } else if ( dcache_hit and not r_tgt_update ) { 1896 r_dcache_fsm = DCACHE_CC_INVAL; 1897 } else { 1898 if(r_tgt_update){ 1899 r_tgt_dcache_rsp = true; 1900 } else { 1901 r_tgt_dcache_rsp = false; 1902 } 1903 r_tgt_dcache_req = false; 1904 r_dcache_fsm = r_dcache_fsm_save; 1905 } 1906 } 1907 break; 1908 } 1909 /////////////////// 1910 case DCACHE_CC_UPDT: // update directory and data cache 1911 { 1912 addr_40 ad = r_tgt_addr; 1913 1914 m_cpt_dcache_dir_write++; 1915 m_cpt_dcache_data_write++; 1916 1917 # ifdef COHERENCE_DEBUG 1918 std::cout << "PROC " << m_srcid_rw << " DCACHE_CC_UPDT, update : " << std::endl; 1919 # endif 1920 1921 #if CC_XCACHE_WRAPPER_CC_UPDATE_MULTI_CYCLE 1922 uint32_t word = r_cache_word; 1923 1924 if(r_tgt_be[word]) 1925 r_dcache.write(ad+word*4, r_tgt_buf[word]); 1926 # ifdef COHERENCE_DEBUG 1927 std::cout << " address " << std::hex << ad+word*4 << " data " << std::dec << r_tgt_buf[word] << std::endl; 1928 data_t rdata = 0xAAAAAAAA; 1929 r_dcache.read(ad+word*4,&rdata); 1930 std::cout << "data written " << rdata << std::endl; 1931 # endif 1932 1933 word ++; 1934 #if CC_XCACHE_WRAPPER_CC_UPDATE_MULTI_CYCLE_OPT 1935 for (; word<m_dcache_words; ++word) 1936 if (r_tgt_be[word] != 0) 1937 break; 1938 #endif 1939 1940 if (word==m_dcache_words) 1941 { 1942 r_tgt_dcache_req = false; 1943 r_tgt_dcache_rsp = true; 1944 r_dcache_fsm = r_dcache_fsm_save; 1945 word = 0; 1946 } 1947 r_cache_word = word; 1948 #else //CC_XCACHE_WRAPPER_CC_UPDATE_MULTI_CYCLE 1949 data_t* buf = r_tgt_buf; 1950 for(size_t i=0; i<m_dcache_words; i++){ 1951 if(r_tgt_be[i]) { 1952 r_dcache.write( ad + i*4, buf[i]); 1953 # ifdef COHERENCE_DEBUG 1954 std::cout << " address " << std::hex << ad+i*4 << " data " << std::dec << buf[i] << std::endl; 1955 data_t rdata = 0xAAAAAAAA; 1956 r_dcache.read(ad + i*4,&rdata); 1957 std::cout << "data written " << rdata << std::endl; 1958 # endif //CC_XCACHE_WRAPPER_CC_UPDATE_MULTI_CYCLE 1959 } 1960 } 1961 r_tgt_dcache_req = false; 1962 r_tgt_dcache_rsp = true; 1963 r_dcache_fsm = r_dcache_fsm_save; 1964 #endif 1965 break; 1966 } 1967 ///////////////////// 1968 case DCACHE_CC_INVAL: // invalidate a cache line 1969 { 1970 addr_40 ad = r_tgt_addr; 1971 r_tgt_dcache_rsp = true; 1972 r_dcache.inval(ad); 1973 r_tgt_dcache_req = false; 1974 r_dcache_fsm = r_dcache_fsm_save; 1975 break; 1976 } 1977 /////////////////// 1978 case DCACHE_CC_CLEANUP: 1979 { 1980 // external cache invalidate request 1981 if ( r_tgt_dcache_req ) 1982 { 1983 r_dcache_fsm = DCACHE_CC_CHECK; 1984 r_dcache_fsm_save = r_dcache_fsm; 1985 break; 1986 } 1987 // cleanup 1988 if(not r_dcache_cleanup_req){ 1989 r_dcache_cleanup_req = true; 1990 r_dcache_cleanup_line = r_dcache_addr_save.read() >> m_dcache_words_shift; 1991 r_dcache_fsm = DCACHE_IDLE; 1992 } 1993 break; 1994 } 1995 1996 } // end switch r_dcache_fsm 1997 1998 ////////// write buffer state update ///////////// 1999 // The update() method must be called at each cycle to update the internal state. 2000 // All pending write requests must be locked in case of SYNC 2001 bool wbuf_flush=(r_dcache_fsm == DCACHE_SYNC); 2002 #if (CC_XCACHE_WRAPPER_WBUF_UPDATE_SCHEME==1) 2003 r_wbuf.update_multi_scan (wbuf_flush); 2004 #elif (CC_XCACHE_WRAPPER_WBUF_UPDATE_SCHEME==2) 2005 r_wbuf.update_round_robin_scan(wbuf_flush); 2006 #elif (CC_XCACHE_WRAPPER_WBUF_UPDATE_SCHEME==3) 2007 r_wbuf.update_one_scan (wbuf_flush); 2008 #else 2009 r_wbuf.update (wbuf_flush); 2010 #endif 2011 2012 #if CC_XCACHE_WRAPPER_DEBUG 2013 if (m_cpt_total_cycles>=CC_XCACHE_WRAPPER_DEBUG_CYCLE_MIN) 2014 std::cout << " * Data Response : " << drsp << std::endl; 2015 #endif 2016 2017 /////////// execute one iss cycle ///////////////////////////////////////////// 2018 { 3161 if ((_dreq.type == iss_t::XTN_READ) or 3162 (_dreq.type == iss_t::XTN_WRITE)) 3163 //log_transaction_file_dcache [num_cpu] << xtn_str(_dreq.addr>>2); 3164 switch (_dreq.addr>>2) 3165 { 3166 case iss_t::XTN_DCACHE_INVAL : log_transaction_file_dcache [num_cpu]<< " INVAL"; break; 3167 case iss_t::XTN_SYNC : log_transaction_file_dcache [num_cpu]<< " SYNC"; break; 3168 default : log_transaction_file_dcache [num_cpu]<< " invalid"; break; 3169 } 3170 3171 log_transaction_file_dcache [num_cpu]<< std::endl; 3172 } 3173 #endif //CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION 3174 3175 { 2019 3176 uint32_t it = 0; 2020 3177 for (size_t i=0; i<(size_t)iss_t::n_irq; i++) 2021 if(p_irq[i].read()) it |= (1<<i); 2022 m_iss.executeNCycles(1, irsp, drsp, it); 2023 } 2024 2025 if ( (ireq.valid and not irsp.valid) or 2026 (dreq.valid and not drsp.valid)) 2027 { 2028 m_cpt_frz_cycles++; 2029 #if CC_XCACHE_WRAPPER_STOP_SIMULATION 2030 m_stop_simulation_nb_frz_cycles ++; 2031 2032 if (m_stop_simulation and (m_stop_simulation_nb_frz_cycles >= m_stop_simulation_nb_frz_cycles_max)) 2033 { 2034 std::cout << std::dec << "CC_XCACHE_WRAPPER \"" << name() << "\" : cycle " << m_cpt_total_cycles << ", the cpu is frozen since " << m_stop_simulation_nb_frz_cycles << " cycles." << std::endl; 2035 ASSERT(false,"CPU : anormal activity"); // exit 2036 } 2037 } 2038 else 2039 { 2040 m_stop_simulation_nb_frz_cycles = 0; // reinit counter 2041 #endif //CC_XCACHE_WRAPPER_STOP_SIMULATION 2042 } 2043 2044 2045 #if CC_XCACHE_WRAPPER_DEBUG_DCACHE_TRANSACTION 2046 if (dreq.valid and drsp.valid) 2047 { 2048 log_dcache_transaction_file 2049 << "[" << m_cpt_total_cycles << "]" 2050 << std::hex 2051 << " @ " << std::setw(8) << (uint32_t)dreq.addr 2052 << " be " << std::setw(1) << (uint32_t)dreq.be 2053 << " W " << std::setw(8) << (uint32_t)dreq.wdata 2054 << " R " << std::setw(8) << (uint32_t)drsp.rdata 2055 << " error " << (uint32_t)drsp.error 2056 << std::dec 2057 << " " << type_str(dreq.type); 2058 2059 if ((dreq.type == iss_t::XTN_READ) or 2060 (dreq.type == iss_t::XTN_WRITE)) 2061 //log_dcache_transaction_file << xtn_str(dreq.addr>>2); 2062 switch (dreq.addr>>2) 3178 if(p_irq[num_cpu][i].read()) it |= (1<<i); 3179 3180 m_iss[num_cpu]->executeNCycles(1, _irsp, _drsp, it); 3181 } 3182 }//end num_cpu 3183 3184 //////////////////////////////////////////////////////////////////////////// 3185 // This CLEANUP FSM controls the transmission of the cleanup transactions 3186 // on the coherence network. It controls the following ressources: 3187 // - r_cleanup_fsm 3188 // - r_dcache_cleanup_req (reset) 3189 // - r_icache_cleanup_req (reset) 3190 // 3191 // This FSM handles cleanup requests from both the DCACHE FSM & ICACHE FSM 3192 // - Instruction Cleanup : r_icache_cleanup_req 3193 // - Data Cleanup : r_dcache_cleanup_req 3194 // In case of simultaneous requests, the data request have highest priority. 3195 // There is only one cleanup transaction at a given time (sequencial behavior) 3196 // because the same FSM controls both command & response. 3197 // The the r_icache_cleanup_req & r_dcache_cleanup_req are reset only 3198 // when the response packet is received. 3199 // Error handling : 3200 // As the coherence trafic is controled by hardware, errors are not reported 3201 // to software : In case of errors, the simulation stops. 3202 //////////////////////////////////////////////////////////////////////////// 3203 3204 switch (r_cleanup_fsm) { 3205 3206 case CLEANUP_IDLE: 3207 { 3208 uint32_t num_cache = 0; 3209 bool cleanup_dcache_req = false; 3210 bool cleanup_icache_req = false; 3211 3212 // dcache is prior 3213 for (uint32_t i=0; i<m_nb_dcache; ++i) 3214 { 3215 PRINTF(" * <CLEANUP> dcache_cleanup_req : [%d] %d\n",i,(int)r_dcache_cleanup_req[i]); 3216 cleanup_dcache_req |= r_dcache_cleanup_req[i]; 3217 if (cleanup_dcache_req) 2063 3218 { 2064 case iss_t::XTN_DCACHE_INVAL : log_dcache_transaction_file << " INVAL"; break; 2065 case iss_t::XTN_SYNC : log_dcache_transaction_file << " SYNC"; break; 2066 default : log_dcache_transaction_file << " invalid"; break; 2067 } 2068 2069 log_dcache_transaction_file << std::endl; 2070 2071 // printf("[%d] @ %.8x be %.1x W %.8x R %.8x error %d - %s" 2072 // ,(uint32_t)m_cpt_total_cycles 2073 // ,(uint32_t)dreq.addr 2074 // ,(uint32_t)dreq.be 2075 // ,(uint32_t)dreq.wdata 2076 // ,(uint32_t)drsp.rdata 2077 // ,(uint32_t)drsp.error 2078 // ,type_str(dreq.type)); 2079 // if ((dreq.type == iss_t::XTN_READ) or 2080 // (dreq.type == iss_t::XTN_WRITE)) 2081 // // printf(" %s",xtn_str(dreq.addr>>2)); 2082 // switch (dreq.addr>>2) 2083 // { 2084 // case iss_t::XTN_DCACHE_INVAL : printf(" INVAL"); break; 2085 // case iss_t::XTN_SYNC : printf(" SYNC"); break; 2086 // default : printf(" invalid"); break; 2087 // } 2088 // printf("\n"); 2089 } 2090 #endif //CC_XCACHE_WRAPPER_DEBUG_DCACHE_TRANSACTION 2091 2092 //////////////////////////////////////////////////////////////////////////// 2093 // This CLEANUP FSM controls the transmission of the cleanup transactions 2094 // on the coherence network. It controls the following ressources: 2095 // - r_cleanup_fsm 2096 // - r_dcache_cleanup_req (reset) 2097 // - r_icache_cleanup_req (reset) 2098 // 2099 // This FSM handles cleanup requests from both the DCACHE FSM & ICACHE FSM 2100 // - Instruction Cleanup : r_icache_cleanup_req 2101 // - Data Cleanup : r_dcache_cleanup_req 2102 // In case of simultaneous requests, the data request have highest priority. 2103 // There is only one cleanup transaction at a given time (sequencial behavior) 2104 // because the same FSM controls both command & response. 2105 // The the r_icache_cleanup_req & r_dcache_cleanup_req are reset only 2106 // when the response packet is received. 2107 // Error handling : 2108 // As the coherence trafic is controled by hardware, errors are not reported 2109 // to software : In case of errors, the simulation stops. 2110 //////////////////////////////////////////////////////////////////////////// 2111 2112 switch (r_cleanup_fsm) { 2113 2114 case CLEANUP_IDLE: 2115 { 2116 if ( p_vci_ini_c.cmdack ) 3219 PRINTF(" * <CLEANUP> ... find\n"); 3220 num_cache=i; 3221 break; 3222 } 3223 } 3224 3225 if (not cleanup_dcache_req) 3226 for (uint32_t i=0; i<m_nb_icache; ++i) 3227 { 3228 PRINTF(" * <CLEANUP> icache_cleanup_req : [%d] %d\n",i,(int)r_icache_cleanup_req[i]); 3229 3230 cleanup_icache_req |= r_icache_cleanup_req[i]; 3231 if (cleanup_icache_req) 3232 { 3233 PRINTF(" * <CLEANUP> ... find\n"); 3234 num_cache=i; 3235 break; 3236 } 3237 } 3238 3239 PRINTF(" * <CLEANUP> cleanup_icache_req : %d\n",cleanup_icache_req); 3240 PRINTF(" * <CLEANUP> cleanup_dcache_req : %d\n",cleanup_dcache_req); 3241 PRINTF(" * <CLEANUP> num_cache : %d\n",num_cache); 3242 3243 if (cleanup_icache_req or cleanup_dcache_req) 3244 { 3245 r_cleanup_fsm = CLEANUP_REQ; 3246 r_cleanup_icache = cleanup_icache_req; 3247 r_cleanup_num_cache = num_cache; 3248 3249 PRINTF(" * <CLEANUP> address : %llx\n",((cleanup_icache_req)?((blob_t)set_num_icache_only(r_icache_cleanup_line[num_cache].read()<<m_icache_words_shift,num_cache)):((blob_t)set_num_dcache_only(r_dcache_cleanup_line[num_cache].read()<<m_dcache_words_shift,num_cache)))); 3250 3251 #if CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION 3252 if (generate_log_transaction_file_cleanup) 2117 3253 { 2118 if (r_dcache_cleanup_req) r_cleanup_fsm = CLEANUP_DCACHE; 2119 else if (r_icache_cleanup_req) r_cleanup_fsm = CLEANUP_ICACHE; 3254 log_transaction_file_cleanup 3255 << "[" << m_cpt_total_cycles << "] " 3256 << ((cleanup_icache_req)?("icache "):("dcache ")) 3257 << num_cache << " : " 3258 << std::hex 3259 << " L " << std::setw(10) << ((cleanup_icache_req)?((blob_t)set_num_icache_only(r_icache_cleanup_line[num_cache].read()<<m_icache_words_shift,num_cache)):((blob_t)set_num_dcache_only(r_dcache_cleanup_line[num_cache].read()<<m_dcache_words_shift,num_cache))) 3260 // << " (" << std::setw(10) << addr << ")" 3261 << std::dec 3262 << std::endl; 2120 3263 } 2121 break; 2122 } 2123 case CLEANUP_DCACHE: 2124 { 2125 if ( p_vci_ini_c.rspval ) 2126 { 2127 PRINTF(" * <CLEANUP> rerror : %d (%d)\n",(uint32_t)p_vci_ini_c.rerror.read(),0x2 & ( (1 << vci_param::E) - 1)); 2128 2129 ASSERT(p_vci_ini_c.reop and (p_vci_ini_c.rtrdid.read() == TYPE_DATA_CLEANUP), 2130 "illegal response packet received for a cleanup transaction"); 2131 ASSERT( (p_vci_ini_c.rerror.read()&0x1) == vci_param::ERR_NORMAL, 2132 "error signaled in a cleanup response" ); 3264 #endif //CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION 3265 3266 } 3267 break; 3268 } 3269 case CLEANUP_REQ: 3270 { 3271 if ( p_vci_ini_c.cmdack ) 3272 { 3273 if (r_cleanup_icache) 3274 r_cleanup_fsm = CLEANUP_RSP_ICACHE; 3275 else 3276 r_cleanup_fsm = CLEANUP_RSP_DCACHE; 3277 } 3278 break; 3279 } 3280 case CLEANUP_RSP_DCACHE: 3281 { 3282 if ( p_vci_ini_c.rspval ) 3283 { 3284 PRINTF(" * <CLEANUP> rerror : %d (%d)\n",(uint32_t)p_vci_ini_c.rerror.read(),0x2 & ( (1 << vci_param::E) - 1)); 3285 PRINTF(" * <CLEANUP> rpktid : %d, r_cleanup_num_cache : %d\n",(uint32_t)p_vci_ini_c.rpktid.read(), (uint32_t)r_cleanup_num_cache); 3286 3287 ASSERT(p_vci_ini_c.reop and (p_vci_ini_c.rtrdid.read() == TYPE_DATA_CLEANUP), 3288 "illegal response packet received for a cleanup transaction"); 3289 ASSERT(p_vci_ini_c.rerror.read() == vci_param::ERR_NORMAL, 3290 "error signaled in a cleanup response" ); 3291 ASSERT(p_vci_ini_c.rpktid.read() == (sc_dt::sc_uint<vci_param::P>)r_cleanup_num_cache, 3292 "invalid pktid in a cleanup response"); 3293 3294 r_cleanup_fsm = CLEANUP_IDLE; 3295 r_dcache_cleanup_req[r_cleanup_num_cache] = false; 3296 // m_cpt_cc_cleanup_data++; 3297 } 3298 break; 3299 } 3300 case CLEANUP_RSP_ICACHE: 3301 { 3302 if ( p_vci_ini_c.rspval ) 3303 { 3304 PRINTF(" * <CLEANUP> rerror : %d (%d)\n",(uint32_t)p_vci_ini_c.rerror.read(),0x2 & ( (1 << vci_param::E) - 1)); 3305 3306 ASSERT(p_vci_ini_c.reop and (p_vci_ini_c.rtrdid.read() == TYPE_INS_CLEANUP), 3307 "illegal response packet received for a cleanup transaction"); 3308 ASSERT(p_vci_ini_c.rerror.read() == vci_param::ERR_NORMAL, 3309 "error signaled in a cleanup response" ); 2133 3310 2134 r_cleanup_fsm = CLEANUP_IDLE; 2135 r_dcache_cleanup_req = false; 2136 // m_cpt_cc_cleanup_data++; TODO 2137 } 2138 break; 2139 } 2140 case CLEANUP_ICACHE: 2141 { 2142 if ( p_vci_ini_c.rspval ) 2143 { 2144 PRINTF(" * <CLEANUP> rerror : %d (%d)\n",(uint32_t)p_vci_ini_c.rerror.read(),0x2 & ( (1 << vci_param::E) - 1)); 2145 2146 ASSERT(p_vci_ini_c.reop and (p_vci_ini_c.rtrdid.read() == TYPE_INS_CLEANUP), 2147 "illegal response packet received for a cleanup transaction"); 2148 ASSERT( (p_vci_ini_c.rerror.read()&0x1) == vci_param::ERR_NORMAL, 2149 "error signaled in a cleanup response" ); 2150 2151 r_cleanup_fsm = CLEANUP_IDLE; 2152 r_icache_cleanup_req = false; 2153 // m_cpt_cc_cleanup_ins++; TODO 2154 } 2155 break; 2156 } 2157 } // end switch r_cleanup_fsm 3311 r_cleanup_fsm = CLEANUP_IDLE; 3312 r_icache_cleanup_req[r_cleanup_num_cache] = false; 3313 // m_cpt_cc_cleanup_ins++; 3314 } 3315 break; 3316 } 3317 } // end switch r_cleanup_fsm 2158 3318 2159 3319 //////////////////////////////////////////////////////////////////////////// … … 2187 3347 ////////////////////////////////////////////////////////////////////////////// 2188 3348 2189 r_vci_cmd_dcache_prior = not r_vci_cmd_dcache_prior; 2190 2191 switch (r_vci_cmd_fsm) { 2192 2193 case CMD_IDLE: 3349 // reverse priority 3350 r_vci_cmd_dcache_prior = not r_vci_cmd_dcache_prior; 3351 r_vci_cmd_num_icache_prior = (r_vci_cmd_num_icache_prior+1)%m_nb_icache; 3352 r_vci_cmd_num_dcache_prior = (r_vci_cmd_num_dcache_prior+1)%m_nb_dcache; 3353 3354 size_t wbuf_min = 0; 3355 size_t wbuf_max = 0; 3356 #if CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION 3357 addr_40 wbuf_addr = 0; 3358 size_t wbuf_index = 0; 3359 #endif 3360 3361 uint32_t dcache_write_num_cache = m_nb_dcache; 3362 3363 for (uint32_t i=0; i<m_nb_dcache; ++i) 3364 { 3365 bool find = false; 3366 3367 size_t _wbuf_min = 0; 3368 size_t _wbuf_max = 0; 3369 #if CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION 3370 addr_40 _wbuf_addr = 0; 3371 size_t _wbuf_index = 0; 3372 #endif 3373 3374 if ( 3375 #if CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION 3376 (r_wbuf[i]->rok_info(&_wbuf_min, &_wbuf_max, &_wbuf_addr, &_wbuf_index)) and 3377 #else 3378 (r_wbuf[i]->rok (&_wbuf_min, &_wbuf_max)) and 3379 #endif 3380 (dcache_write_num_cache == m_nb_dcache)) 3381 { 3382 find = true; 3383 dcache_write_num_cache = i; 3384 3385 PRINTF(" * <CMD> wbuf min, max : %d, %d\n",(int)_wbuf_min,(int)_wbuf_max); 3386 3387 wbuf_min = _wbuf_min ; 3388 wbuf_max = _wbuf_max ; 3389 #if CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION 3390 wbuf_addr = _wbuf_addr ; 3391 wbuf_index = _wbuf_index; 3392 3393 PRINTF(" * <CMD> wbuf index : %d\n",(int)_wbuf_index); 3394 PRINTF(" * <CMD> wbuf address : %llx\n",(blob_t)_wbuf_addr); 3395 #endif 3396 } 3397 3398 PRINTF(" * <CMD> Test read after miss : cache : %d, find : %d\n",dcache_write_num_cache, find); 3399 3400 #if MWBUF_VHDL_TESTBENCH 3401 vhdl_mwbuf_test_sent_val [dcache_write_num_cache] = (vhdl_tb_t)1; 3402 vhdl_mwbuf_port_sent_val [dcache_write_num_cache] = (vhdl_tb_t)find; 3403 vhdl_mwbuf_test_sent_word_min [dcache_write_num_cache] = (vhdl_tb_t)find; 3404 vhdl_mwbuf_port_sent_word_min [dcache_write_num_cache] = (vhdl_tb_t)wbuf_min; 3405 vhdl_mwbuf_test_sent_word_max [dcache_write_num_cache] = (vhdl_tb_t)find; 3406 vhdl_mwbuf_port_sent_word_max [dcache_write_num_cache] = (vhdl_tb_t)wbuf_max; 3407 #endif 3408 } 3409 3410 switch (r_vci_cmd_fsm) { 3411 3412 case CMD_IDLE: 3413 { 3414 // if (r_vci_rsp_fsm != RSP_IDLE) break; 3415 3416 3417 // Requests : 3418 3419 // multi_write_buffer access is conditionnal with dcache_miss_req and icache_miss_req 3420 3421 bool dcache_miss_req = false; 3422 bool icache_miss_req = false; 3423 uint32_t dcache_miss_num_cache = 0; 3424 uint32_t icache_miss_num_cache = 0; 3425 addr_40 addr = 0; 3426 3427 bool wbuf_imiss = false; 3428 bool wbuf_dmiss = false; 3429 3430 { 3431 for (; dcache_miss_num_cache<m_nb_dcache; ++dcache_miss_num_cache) 3432 { 3433 dcache_miss_req = r_dcache_miss_req[dcache_miss_num_cache]; 3434 if (dcache_miss_req) 3435 break; 3436 } 3437 for (; icache_miss_num_cache<m_nb_icache; ++icache_miss_num_cache) 3438 { 3439 icache_miss_req = r_icache_miss_req[icache_miss_num_cache]; 3440 if (icache_miss_req) 3441 break; 3442 } 3443 3444 PRINTF(" * <CMD> icache_miss_req (before) : %d\n",icache_miss_req); 3445 PRINTF(" * <CMD> dcache_miss_req (before) : %d\n",dcache_miss_req); 3446 3447 // one access with round robin priority 3448 dcache_miss_req = ((dcache_miss_req and not icache_miss_req) or // only dcache 3449 (dcache_miss_req and r_vci_cmd_dcache_prior)); // dcache prior 3450 icache_miss_req &= not dcache_miss_req; 3451 3452 PRINTF(" * <CMD> icache_miss_req (after ) : %d\n",icache_miss_req); 3453 PRINTF(" * <CMD> dcache_miss_req (after ) : %d\n",dcache_miss_req); 3454 3455 PRINTF(" * <CMD> icache_miss_num_cache : %d\n",icache_miss_num_cache); 3456 PRINTF(" * <CMD> dcache_miss_num_cache : %d\n",dcache_miss_num_cache); 3457 3458 if (icache_miss_req or dcache_miss_req) 3459 { 3460 addr = (icache_miss_req)?r_icache_addr_save[icache_miss_num_cache].read():r_dcache_addr_save[dcache_miss_num_cache].read(); 3461 3462 PRINTF(" * <CMD> addr : %llx\n",(blob_t)addr); 3463 3464 if (icache_miss_req) 3465 { 3466 // FIXME : 3467 // si wbuf contient des addresses partionné, set_num_icache puis get_num_dcache 3468 // dcache_miss_num_cache = icache_miss_num_cache; 3469 set_num_icache(addr,icache_miss_num_cache); 3470 // get_num_dcache(addr,dcache_miss_num_cache); 3471 } 3472 else 3473 set_num_dcache(addr,dcache_miss_num_cache); 3474 3475 PRINTF(" * <CMD> addr : %llx\n",(blob_t)addr); 3476 3477 uint32_t num_cache = get_num_dcache_only(addr); 3478 3479 wbuf_imiss = (icache_miss_req)?r_wbuf[num_cache]->miss(addr):false; 3480 wbuf_dmiss = (dcache_miss_req)?r_wbuf[num_cache]->miss(addr):false; 3481 3482 #if MWBUF_VHDL_TESTBENCH 3483 vhdl_mwbuf_port_raw_test [num_cache] = (vhdl_tb_t)1; 3484 vhdl_mwbuf_port_raw_addr [num_cache] = (vhdl_tb_t)addr; 3485 vhdl_mwbuf_test_raw_miss [num_cache] = (vhdl_tb_t)1; 3486 vhdl_mwbuf_port_raw_miss [num_cache] = (dcache_miss_req)?(vhdl_tb_t)wbuf_dmiss:(vhdl_tb_t)wbuf_imiss; 3487 #endif 3488 } 3489 } 3490 3491 uint32_t dcache_unc_num_cache = 0; 3492 for (; dcache_unc_num_cache<m_nb_dcache; ++dcache_unc_num_cache) 3493 if (r_dcache_unc_req[dcache_unc_num_cache]) 3494 break; 3495 uint32_t icache_unc_num_cache = 0; 3496 for (; icache_unc_num_cache<m_nb_icache; ++icache_unc_num_cache) 3497 if (r_icache_unc_req[icache_unc_num_cache]) 3498 break; 3499 uint32_t dcache_sc_num_cache = 0; 3500 for (; dcache_sc_num_cache<m_nb_dcache; ++dcache_sc_num_cache) 3501 if (r_dcache_sc_req[dcache_sc_num_cache]) 3502 break; 3503 3504 // 1 - Data Read 3505 if (wbuf_dmiss) 3506 // (dcache_miss_req and r_wbuf[dcache_miss_num_cache]->miss(addr)) 3507 { 3508 r_vci_cmd_fsm = CMD_DATA_MISS; 3509 r_vci_cmd_num_cache = dcache_miss_num_cache; 3510 r_dcache_miss_req[dcache_miss_num_cache] = false; 3511 m_cpt_dmiss_transaction++; 3512 3513 3514 #if CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION 3515 if (generate_log_transaction_file_cmd) 2194 3516 { 2195 // if (r_vci_rsp_fsm != RSP_IDLE) break; 2196 2197 size_t min; 2198 size_t max; 2199 2200 r_vci_cmd_cpt = 0; 2201 2202 // Requests : 2203 2204 // multi_write_buffer access is conditionnal with dcache_miss_req and icache_miss_req 2205 2206 #if (CC_XCACHE_WRAPPER_VCI_CMD_PRIORITY==1) 2207 // 1) two access authorized 2208 bool dcache_miss_req = r_dcache_miss_req; 2209 bool icache_miss_req = r_icache_miss_req; 2210 #elif (CC_XCACHE_WRAPPER_VCI_CMD_PRIORITY==2) 2211 // 2) one access with static priority (dcache prior) 2212 bool dcache_miss_req = r_dcache_miss_req; // dcache prior 2213 bool icache_miss_req = not dcache_miss_req and r_icache_miss_req; 2214 #elif (CC_XCACHE_WRAPPER_VCI_CMD_PRIORITY==3) 2215 // 3) one access with static priority (icache prior) 2216 bool icache_miss_req = r_icache_miss_req; 2217 bool dcache_miss_req = not icache_miss_req and r_dcache_miss_req; // dcache prior 2218 #elif (CC_XCACHE_WRAPPER_VCI_CMD_PRIORITY==4) 2219 // 4) one access with round robin priority 2220 bool dcache_miss_req = ((r_dcache_miss_req and not r_icache_miss_req) or // only dcache 2221 (r_dcache_miss_req and r_vci_cmd_dcache_prior)); // dcache prior 2222 bool icache_miss_req = not dcache_miss_req and r_icache_miss_req; 2223 #else 2224 #error "Invalid value to CC_XCACHE_WRAPPER_VCI_CMD_PRIORITY" 3517 log_transaction_file_cmd 3518 << "[" << m_cpt_total_cycles << "] " 3519 << "CMD DATA MISS " 3520 << "(" << dcache_miss_num_cache << ") " 3521 << std::hex 3522 << " @ " << std::setw(10) << (blob_t)addr 3523 << " (L " << std::setw(10) << ((blob_t)addr&(blob_t)m_dcache_yzmask) << ")" 3524 << std::dec 3525 << std::endl; 3526 } 3527 #endif //CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION 3528 3529 } 3530 3531 // 2 - Data Read Uncachable 3532 else if (dcache_unc_num_cache < m_nb_dcache) // have r_dcache_unc_req 3533 { 3534 r_vci_cmd_fsm = CMD_DATA_UNC; 3535 r_vci_cmd_num_cache = dcache_unc_num_cache; 3536 r_dcache_unc_req[dcache_unc_num_cache] = false; 3537 // m_cpt_data_unc_transaction++; 3538 3539 #if CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION 3540 if (generate_log_transaction_file_cmd) 3541 { 3542 addr_40 addr = (addr_40) r_dcache_addr_save[dcache_unc_num_cache].read() & ~0x3; 3543 set_num_dcache(addr,dcache_unc_num_cache); 3544 3545 log_transaction_file_cmd 3546 << "[" << m_cpt_total_cycles << "] " 3547 << "CMD DATA UNC " 3548 << "(" << dcache_unc_num_cache << ") " 3549 << std::hex 3550 << " @ " << std::setw(10) << (blob_t)addr 3551 << " (L " << std::setw(10) << ((blob_t)addr&(blob_t)m_dcache_yzmask) << ")" 3552 << std::dec 3553 << std::endl; 3554 } 3555 #endif //CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION 3556 } 3557 3558 // 3 - Instruction Miss 3559 else if (wbuf_imiss) 3560 //else if (icache_miss_req and r_wbuf[icache_miss_num_cache]->miss(addr)) 3561 { 3562 r_vci_cmd_fsm = CMD_INS_MISS; 3563 r_vci_cmd_num_cache = icache_miss_num_cache; 3564 r_icache_miss_req[icache_miss_num_cache] = false; 3565 m_cpt_imiss_transaction++; 3566 3567 #if CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION 3568 if (generate_log_transaction_file_cmd) 3569 { 3570 log_transaction_file_cmd 3571 << "[" << m_cpt_total_cycles << "] " 3572 << "CMD INS MISS " 3573 << "(" << icache_miss_num_cache << ") " 3574 << std::hex 3575 << " @ " << std::setw(10) << (blob_t)addr 3576 << " (L " << std::setw(10) << ((blob_t)addr&(blob_t)m_icache_yzmask) << ")" 3577 << std::dec 3578 << std::endl; 3579 } 3580 #endif //CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION 3581 } 3582 3583 // 4 - Instruction Uncachable 3584 else if (icache_unc_num_cache < m_nb_icache) // have r_icache_unc_req 3585 { 3586 r_vci_cmd_fsm = CMD_INS_UNC; 3587 r_vci_cmd_num_cache = icache_unc_num_cache; 3588 r_icache_unc_req[icache_unc_num_cache] = false; 3589 // m_cpt_ins_unc_transaction++; 3590 3591 #if CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION 3592 if (generate_log_transaction_file_cmd) 3593 { 3594 addr_40 addr = (addr_40) r_icache_addr_save[icache_unc_num_cache].read() & ~0x3; 3595 set_num_dcache(addr,icache_unc_num_cache); 3596 3597 log_transaction_file_cmd 3598 << "[" << m_cpt_total_cycles << "] " 3599 << "CMD INS UNC " 3600 << "(" << icache_unc_num_cache << ") " 3601 << std::hex 3602 << " @ " << std::setw(10) << (blob_t)addr 3603 << " (L " << std::setw(10) << ((blob_t)addr&(blob_t)m_icache_yzmask) << ")" 3604 << std::dec 3605 << std::endl; 3606 } 3607 #endif //CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION 3608 } 3609 3610 // 5 - Data Write 3611 else if (dcache_write_num_cache < m_nb_dcache) // have r_wbuf.rok(&wbuf_min, &wbuf_max) 3612 { 3613 r_vci_cmd_num_cache = dcache_write_num_cache; 3614 r_vci_cmd_fsm = CMD_DATA_WRITE; 3615 r_vci_cmd_cpt = wbuf_min; 3616 r_vci_cmd_min = wbuf_min; 3617 r_vci_cmd_max = wbuf_max; 3618 m_cpt_data_write_transaction++; 3619 m_length_write_transaction += (wbuf_max-wbuf_min+1); 3620 3621 #if CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION 3622 if (generate_log_transaction_file_cmd) 3623 { 3624 addr_40 addr = (addr_40) wbuf_addr&~0x3; 3625 3626 log_transaction_file_cmd 3627 << "[" << m_cpt_total_cycles << "] " 3628 << "CMD DATA WRITE " 3629 << "(" << dcache_write_num_cache << ") " 3630 << std::hex 3631 << " @ " << std::setw(10) << (blob_t)addr 3632 << " (L " << std::setw(10) << ((blob_t)addr&(blob_t)m_dcache_yzmask) << ")" 3633 << " [" << wbuf_min << ":" << wbuf_max << "]" 3634 << " {" << wbuf_index << "}" 3635 << std::dec 3636 << std::endl; 3637 } 3638 #endif //CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION 3639 } 3640 3641 // 6 - Data Store Conditionnal 3642 else if (dcache_sc_num_cache < m_nb_dcache) // have r_dcache_sc_req 3643 { 3644 r_vci_cmd_fsm = CMD_DATA_SC; 3645 r_vci_cmd_num_cache = dcache_sc_num_cache; 3646 r_vci_cmd_cpt = 0; 3647 r_vci_cmd_min = 0; 3648 r_vci_cmd_max = 1; 3649 m_cpt_unc_transaction++; 3650 r_dcache_sc_req[dcache_sc_num_cache] = false; 3651 3652 #if CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION 3653 if (generate_log_transaction_file_cmd) 3654 { 3655 addr_40 addr = (addr_40) r_dcache_addr_save[dcache_sc_num_cache].read() & ~0x3; 3656 set_num_dcache(addr,dcache_sc_num_cache); 3657 3658 log_transaction_file_cmd 3659 << "[" << m_cpt_total_cycles << "] " 3660 << "CMD DATA SC " 3661 << "(" << dcache_sc_num_cache << ") " 3662 << std::hex 3663 << " @ " << std::setw(10) << (blob_t)addr 3664 << " (L " << std::setw(10) << ((blob_t)addr&(blob_t)m_dcache_yzmask) << ")" 3665 << std::dec 3666 << std::endl; 3667 } 3668 #endif //CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION 3669 } 3670 3671 break; 3672 } 3673 case CMD_DATA_WRITE: 3674 if ( p_vci_ini_rw.cmdack.read() ) { 3675 3676 #if MWBUF_VHDL_TESTBENCH 3677 vhdl_mwbuf_port_sent_word [r_vci_cmd_num_cache] = (vhdl_tb_t)r_vci_cmd_cpt; 3678 vhdl_mwbuf_test_sent_addr [r_vci_cmd_num_cache] = (vhdl_tb_t)1; 3679 vhdl_mwbuf_port_sent_addr [r_vci_cmd_num_cache] = (vhdl_tb_t)r_wbuf[r_vci_cmd_num_cache]->getAddress(r_vci_cmd_cpt); 3680 vhdl_mwbuf_test_sent_data [r_vci_cmd_num_cache] = (vhdl_tb_t)1; 3681 vhdl_mwbuf_port_sent_data [r_vci_cmd_num_cache] = (vhdl_tb_t)r_wbuf[r_vci_cmd_num_cache]->getData(r_vci_cmd_cpt); 3682 vhdl_mwbuf_test_sent_be [r_vci_cmd_num_cache] = (vhdl_tb_t)1; 3683 vhdl_mwbuf_port_sent_be [r_vci_cmd_num_cache] = (vhdl_tb_t)r_wbuf[r_vci_cmd_num_cache]->getBe(r_vci_cmd_cpt); 3684 vhdl_mwbuf_test_sent_index [r_vci_cmd_num_cache] = (vhdl_tb_t)1; 3685 vhdl_mwbuf_port_sent_index [r_vci_cmd_num_cache] = (vhdl_tb_t)r_wbuf[r_vci_cmd_num_cache]->getIndex(); 2225 3686 #endif 2226 // 1 - Data Read 2227 if (dcache_miss_req and r_wbuf.miss(r_dcache_addr_save)) 2228 { 2229 r_vci_cmd_fsm = CMD_DATA_MISS; 2230 r_dcache_miss_req = false; 2231 m_cpt_dmiss_transaction++; 2232 } 2233 2234 // 2 - Data Read Uncachable 2235 else if ( r_dcache_unc_req ) 2236 { 2237 r_vci_cmd_fsm = CMD_DATA_UNC; 2238 r_dcache_unc_req = false; 2239 // m_cpt_data_unc_transaction++; 2240 } 2241 2242 // 3 - Instruction Miss 2243 else if (icache_miss_req and r_wbuf.miss(r_icache_addr_save)) 2244 { 2245 r_vci_cmd_fsm = CMD_INS_MISS; 2246 r_icache_miss_req = false; 2247 m_cpt_imiss_transaction++; 2248 } 2249 2250 // 4 - Instruction Uncachable 2251 else if ( r_icache_unc_req ) 2252 { 2253 r_vci_cmd_fsm = CMD_INS_UNC; 2254 r_icache_unc_req = false; 2255 // m_cpt_ins_unc_transaction++; 2256 } 2257 2258 // 5 - Data Write 2259 else if ( r_wbuf.rok(&min, &max) ) 2260 { 2261 r_vci_cmd_fsm = CMD_DATA_WRITE; 2262 r_vci_cmd_cpt = min; 2263 r_vci_cmd_min = min; 2264 r_vci_cmd_max = max; 2265 m_cpt_data_write_transaction++; 2266 m_length_write_transaction += (max-min+1); 2267 } 2268 2269 // 6 - Data Store Conditionnal 2270 else if ( r_dcache_sc_req ) 2271 { 2272 r_vci_cmd_fsm = CMD_DATA_SC; 2273 r_vci_cmd_max = 1; 2274 m_cpt_unc_transaction++; 2275 r_dcache_sc_req = false; 2276 } 2277 2278 break; 2279 } 2280 case CMD_DATA_WRITE: 2281 if ( p_vci_ini_rw.cmdack.read() ) { 2282 r_vci_cmd_cpt = r_vci_cmd_cpt + 1; 2283 if (r_vci_cmd_cpt == r_vci_cmd_max) { 2284 r_vci_cmd_fsm = CMD_IDLE ; 2285 r_wbuf.sent() ; 2286 } 2287 } 2288 break; 2289 2290 case CMD_DATA_SC: 2291 if ( p_vci_ini_rw.cmdack.read() ) { 2292 r_vci_cmd_cpt = r_vci_cmd_cpt + 1; 2293 if (r_vci_cmd_cpt == r_vci_cmd_max) { 2294 r_vci_cmd_fsm = CMD_IDLE ; 2295 } 2296 } 2297 break; 2298 case CMD_INS_MISS: 2299 case CMD_INS_UNC: 2300 case CMD_DATA_MISS: 2301 case CMD_DATA_UNC: 2302 if ( p_vci_ini_rw.cmdack.read() ) { 2303 r_vci_cmd_fsm = CMD_IDLE; 2304 } 2305 break; 2306 2307 } // end switch r_vci_cmd_fsm 3687 3688 r_vci_cmd_cpt = r_vci_cmd_cpt + 1; 3689 if (r_vci_cmd_cpt == r_vci_cmd_max) { 3690 r_vci_cmd_fsm = CMD_IDLE ; 3691 r_wbuf[r_vci_cmd_num_cache]->sent() ; 3692 #if MWBUF_VHDL_TESTBENCH 3693 vhdl_mwbuf_port_sent_ack [r_vci_cmd_num_cache] = (vhdl_tb_t)1; 3694 #endif 3695 } 3696 } 3697 break; 3698 3699 case CMD_DATA_SC: 3700 if ( p_vci_ini_rw.cmdack.read() ) { 3701 r_vci_cmd_cpt = r_vci_cmd_cpt + 1; 3702 if (r_vci_cmd_cpt == r_vci_cmd_max) { 3703 r_vci_cmd_fsm = CMD_IDLE ; 3704 } 3705 } 3706 break; 3707 case CMD_INS_MISS: 3708 case CMD_INS_UNC: 3709 case CMD_DATA_MISS: 3710 case CMD_DATA_UNC: 3711 if ( p_vci_ini_rw.cmdack.read() ) { 3712 r_vci_cmd_fsm = CMD_IDLE; 3713 } 3714 break; 3715 3716 } // end switch r_vci_cmd_fsm 2308 3717 2309 3718 ////////////////////////////////////////////////////////////////////////// 2310 3719 // The VCI_RSP FSM controls the following ressources: 2311 3720 // - r_vci_rsp_fsm: 2312 // - r_ icache_miss_buf[m_icache_words]2313 // - r_ dcache_miss_buf[m_dcache_words]3721 // - r_vci_rsp_fifo_icache[m_icache_words] 3722 // - r_vci_rsp_fifo_dcache[m_dcache_words] 2314 3723 // - r_vci_rsp_data_error set 2315 3724 // - r_vci_rsp_ins_error set … … 2333 3742 ////////////////////////////////////////////////////////////////////////// 2334 3743 2335 switch (r_vci_rsp_fsm) { 2336 2337 case RSP_IDLE: 2338 2339 if( p_vci_ini_rw.rspval.read() ) 2340 { 2341 PRINTF(" * <RSP> have rsp - trdid : %x\n",(uint32_t)p_vci_ini_rw.rtrdid.read()); 2342 2343 r_vci_rsp_cpt = 0; 2344 2345 if ((p_vci_ini_rw.rtrdid.read()>>(vci_param::T-1)) != 0 ) 2346 r_vci_rsp_fsm = RSP_DATA_WRITE; 2347 else 3744 switch (r_vci_rsp_fsm) { 3745 3746 case RSP_IDLE: 3747 3748 if( p_vci_ini_rw.rspval.read() ) 3749 { 3750 PRINTF(" * <RSP> have rsp - trdid : %x - num_cache : %d\n",(uint32_t)p_vci_ini_rw.rtrdid.read(),(uint32_t)p_vci_ini_rw.rpktid.read()); 3751 3752 ASSERT(p_vci_ini_rw.rpktid.read() <= (1<<vci_param::P), 3753 "invalid pktid in a cleanup response"); 3754 3755 r_vci_rsp_cpt = 0; 3756 3757 if ((p_vci_ini_rw.rtrdid.read()>>(vci_param::T-1)) != 0 ) 3758 { 3759 r_vci_rsp_fsm = RSP_DATA_WRITE; 3760 3761 #if CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION 3762 if (generate_log_transaction_file_cmd) 3763 { 3764 log_transaction_file_cmd 3765 << "[" << m_cpt_total_cycles << "] " 3766 << "RSP DATA WRITE " 3767 << "(" << p_vci_ini_rw.rpktid.read() << ") " 3768 << "{" << (p_vci_ini_rw.rtrdid.read() - (1<<(vci_param::T-1))) << "}" 3769 << std::endl; 3770 } 3771 #endif //CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION 3772 } 3773 else 3774 { 3775 switch (p_vci_ini_rw.rtrdid.read()) 3776 { 3777 case TYPE_INS_MISS : 2348 3778 { 2349 switch (p_vci_ini_rw.rtrdid.read()) 3779 r_vci_rsp_fsm = RSP_INS_MISS; 3780 3781 #if CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION 3782 if (generate_log_transaction_file_cmd) 2350 3783 { 2351 case TYPE_INS_MISS : r_vci_rsp_fsm = RSP_INS_MISS; break; 2352 case TYPE_INS_UNC : r_vci_rsp_fsm = RSP_INS_UNC; break; 2353 case TYPE_DATA_MISS : r_vci_rsp_fsm = RSP_DATA_MISS; break; 2354 case TYPE_DATA_UNC : r_vci_rsp_fsm = RSP_DATA_UNC; break; 2355 case TYPE_DATA_SC : r_vci_rsp_fsm = RSP_DATA_SC; break; 2356 default : 2357 { 2358 ASSERT(false, "Unexpected response"); 2359 } 3784 log_transaction_file_cmd 3785 << "[" << m_cpt_total_cycles << "] " 3786 << "RSP INS MISS " 3787 << "(" << p_vci_ini_rw.rpktid.read() << ") " 3788 << std::endl; 2360 3789 } 3790 #endif //CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION 3791 3792 break; 2361 3793 } 2362 } 2363 break; 2364 2365 case RSP_INS_MISS: 2366 2367 m_cost_imiss_transaction++; 2368 PRINTF(" * <RSP> rspval/ack : %d - %d\n",(uint32_t)p_vci_ini_rw.rspval.read(), (uint32_t)r_vci_rsp_ack); 2369 2370 if (p_vci_ini_rw.rspval.read() and r_vci_rsp_ack) 2371 { 2372 PRINTF(" * <RSP> have rsp - r_vci_rsp_cpt : %d/%d\n",(uint32_t)r_vci_rsp_cpt.read(),(uint32_t)m_icache_words); 2373 PRINTF(" * <RSP> ins : %x\n",(int)p_vci_ini_rw.rdata.read()); 2374 2375 ASSERT( (r_vci_rsp_cpt < m_icache_words), 2376 "The VCI response packet for instruction miss is too long" ); 2377 r_vci_rsp_cpt = r_vci_rsp_cpt + 1; 2378 CACHE_MISS_BUF_RSP_PUSH(i,r_vci_rsp_cpt,(data_t)p_vci_ini_rw.rdata.read()); 2379 if ( p_vci_ini_rw.reop.read() ) 3794 case TYPE_INS_UNC : 2380 3795 { 2381 PRINTF(" * <RSP> have reop\n"); 2382 ASSERT( ((r_vci_rsp_cpt.read() == m_icache_words - 1) or 2383 p_vci_ini_rw.rerror.read() or 2384 (r_vci_rsp_ins_error.read()&0x1)), 2385 "The VCI response packet for instruction miss is too short"); 2386 r_vci_rsp_cpt = 0; 2387 r_vci_rsp_fsm = RSP_IDLE; 2388 3796 r_vci_rsp_fsm = RSP_INS_UNC; 3797 3798 #if CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION 3799 if (generate_log_transaction_file_cmd) 3800 { 3801 log_transaction_file_cmd 3802 << "[" << m_cpt_total_cycles << "] " 3803 << "RSP INS UNC " 3804 << "(" << p_vci_ini_rw.rpktid.read() << ") " 3805 << std::endl; 3806 } 3807 #endif //CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION 3808 3809 break; 2389 3810 } 2390 if ( (p_vci_ini_rw.rerror.read()&0x1) != vci_param::ERR_NORMAL ) r_vci_rsp_ins_error = true; 2391 } 2392 break; 2393 2394 case RSP_INS_UNC: 2395 2396 m_cost_imiss_transaction++; 2397 if (p_vci_ini_rw.rspval.read() and r_vci_rsp_ack) 2398 { 2399 ASSERT(p_vci_ini_rw.reop.read(), 2400 "illegal VCI response packet for uncached instruction"); 2401 2402 CACHE_MISS_BUF_RSP_PUSH(i,0,(data_t)p_vci_ini_rw.rdata.read()); 2403 2404 r_vci_rsp_fsm = RSP_IDLE; 2405 2406 if ( (p_vci_ini_rw.rerror.read()&0x1) != vci_param::ERR_NORMAL ) r_vci_rsp_ins_error = true; 2407 } 2408 break; 2409 2410 case RSP_DATA_MISS: 2411 2412 m_cost_dmiss_transaction++; 2413 if (p_vci_ini_rw.rspval.read() and r_vci_rsp_ack) 2414 { 2415 PRINTF(" * <RSP> have rspval - error : %d\n",(int)p_vci_ini_rw.rerror.read()); 2416 2417 ASSERT(r_vci_rsp_cpt < m_dcache_words, 2418 "illegal VCI response packet for data read miss"); 2419 r_vci_rsp_cpt = r_vci_rsp_cpt + 1; 2420 2421 CACHE_MISS_BUF_RSP_PUSH(d,r_vci_rsp_cpt,(data_t)p_vci_ini_rw.rdata.read()); 2422 2423 if ( p_vci_ini_rw.reop.read() ) { 2424 ASSERT( ((r_vci_rsp_cpt == m_dcache_words - 1) 2425 or (p_vci_ini_rw.rerror.read()&0x1) 2426 or r_vci_rsp_data_error.read()), 2427 "illegal VCI response packet for data read miss"); 2428 r_vci_rsp_cpt = 0; 2429 r_vci_rsp_fsm = RSP_IDLE; 3811 case TYPE_DATA_MISS : 3812 { 3813 r_vci_rsp_fsm = RSP_DATA_MISS; 3814 3815 #if CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION 3816 if (generate_log_transaction_file_cmd) 3817 { 3818 log_transaction_file_cmd 3819 << "[" << m_cpt_total_cycles << "] " 3820 << "RSP DATA MISS " 3821 << "(" << p_vci_ini_rw.rpktid.read() << ") " 3822 << std::endl; 3823 } 3824 #endif //CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION 3825 3826 break; 2430 3827 } 2431 if ( (p_vci_ini_rw.rerror.read()&0x1) != vci_param::ERR_NORMAL ) r_vci_rsp_data_error = true; 2432 } 2433 break; 2434 2435 case RSP_DATA_WRITE: 2436 2437 m_cost_write_transaction++; 2438 if (p_vci_ini_rw.rspval.read()) 2439 { 2440 PRINTF(" * <RSP> have rspval - error : %d\n",(int)p_vci_ini_rw.rerror.read()); 2441 2442 ASSERT(p_vci_ini_rw.reop.read(), 2443 "A VCI response packet must contain one flit for a write transaction"); 2444 r_vci_rsp_fsm = RSP_IDLE; 2445 bool cached = r_wbuf.completed(p_vci_ini_rw.rtrdid.read() - (1<<(vci_param::T-1)) ); 2446 2447 PRINTF(" * <RSP> cached : %d\n",cached); 2448 2449 if (not cached) 2450 r_dcache_previous_unc = false; 2451 2452 if ((p_vci_ini_rw.rerror.read()&0x1) != vci_param::ERR_NORMAL) m_iss.setWriteBerr(); 2453 } 2454 break; 2455 2456 case RSP_DATA_UNC: 2457 m_cost_unc_transaction++; 2458 if (p_vci_ini_rw.rspval.read() and r_vci_rsp_ack) 2459 { 2460 ASSERT(p_vci_ini_rw.reop.read(), 2461 "illegal VCI response packet for data read uncached"); 2462 2463 CACHE_MISS_BUF_RSP_PUSH(d,0,(data_t)p_vci_ini_rw.rdata.read()); 2464 2465 r_vci_rsp_fsm = RSP_IDLE; 2466 r_dcache_previous_unc = false; 2467 2468 if ( (p_vci_ini_rw.rerror.read()&0x1) != vci_param::ERR_NORMAL ) r_vci_rsp_data_error = true; 2469 } 2470 break; 2471 2472 case RSP_DATA_SC: 2473 m_cost_unc_transaction++; 2474 if (p_vci_ini_rw.rspval.read() and r_vci_rsp_ack) 2475 { 2476 ASSERT(p_vci_ini_rw.reop.read(), 2477 "illegal VCI response packet for data SC"); 2478 2479 CACHE_MISS_BUF_RSP_PUSH(d,0,(data_t)p_vci_ini_rw.rdata.read()); 2480 2481 r_vci_rsp_fsm = RSP_IDLE; 2482 r_dcache_previous_unc = false; 2483 2484 if ( (p_vci_ini_rw.rerror.read()&0x1) != vci_param::ERR_NORMAL ) r_vci_rsp_data_error = true; 2485 } 2486 break; 2487 2488 } // end switch r_vci_rsp_fsm 2489 3828 case TYPE_DATA_UNC : 3829 { 3830 r_vci_rsp_fsm = RSP_DATA_UNC; 3831 3832 #if CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION 3833 if (generate_log_transaction_file_cmd) 3834 { 3835 log_transaction_file_cmd 3836 << "[" << m_cpt_total_cycles << "] " 3837 << "RSP DATA UNC " 3838 << "(" << p_vci_ini_rw.rpktid.read() << ") " 3839 << std::endl; 3840 } 3841 #endif //CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION 3842 3843 break; 3844 } 3845 case TYPE_DATA_SC : 3846 { 3847 r_vci_rsp_fsm = RSP_DATA_SC; 3848 3849 #if CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION 3850 if (generate_log_transaction_file_cmd) 3851 { 3852 log_transaction_file_cmd 3853 << "[" << m_cpt_total_cycles << "] " 3854 << "RSP DATA SC " 3855 << "(" << p_vci_ini_rw.rpktid.read() << ") " 3856 << std::endl; 3857 } 3858 #endif //CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION 3859 3860 break; 3861 } 3862 default : 3863 { 3864 ASSERT(false, "Unexpected response"); 3865 } 3866 } 3867 } 3868 3869 r_vci_rsp_num_cache = p_vci_ini_rw.rpktid.read(); 3870 } 3871 break; 3872 3873 case RSP_INS_MISS: 3874 3875 m_cost_imiss_transaction++; 3876 PRINTF(" * <RSP> rspval : %d\n",(uint32_t)p_vci_ini_rw.rspval.read()); 3877 3878 if (p_vci_ini_rw.rspval.read() and r_vci_rsp_fifo_icache_data.wok()) 3879 { 3880 PRINTF(" * <RSP> have rsp - r_vci_rsp_cpt : %d/%d\n",(uint32_t)r_vci_rsp_cpt.read(),(uint32_t)m_icache_words); 3881 PRINTF(" * <RSP> ins : %x\n",(int)p_vci_ini_rw.rdata.read()); 3882 3883 ASSERT( (r_vci_rsp_cpt < m_icache_words), 3884 "The VCI response packet for instruction miss is too long" ); 3885 r_vci_rsp_cpt = r_vci_rsp_cpt + 1; 3886 vci_rsp_fifo_icache_put = true, 3887 vci_rsp_fifo_icache_num_cache = r_vci_rsp_num_cache; 3888 vci_rsp_fifo_icache_data = p_vci_ini_rw.rdata.read(); 3889 3890 if ( p_vci_ini_rw.reop.read() ) 3891 { 3892 PRINTF(" * <RSP> have reop\n"); 3893 3894 ASSERT( ((r_vci_rsp_cpt == m_icache_words - 1) or 3895 p_vci_ini_rw.rerror.read() or 3896 (r_vci_rsp_ins_error[r_vci_rsp_num_cache].read()&0x1)), 3897 "The VCI response packet for instruction miss is too short"); 3898 r_vci_rsp_cpt = 0; 3899 r_vci_rsp_fsm = RSP_IDLE; 3900 3901 } 3902 if ( (p_vci_ini_rw.rerror.read()&0x1) != vci_param::ERR_NORMAL ) r_vci_rsp_ins_error[r_vci_rsp_num_cache] = true; 3903 } 3904 break; 3905 3906 case RSP_INS_UNC: 3907 3908 m_cost_imiss_transaction++; 3909 if (p_vci_ini_rw.rspval.read() and r_vci_rsp_fifo_icache_data.wok()) 3910 { 3911 ASSERT(p_vci_ini_rw.reop.read(), 3912 "illegal VCI response packet for uncached instruction"); 3913 3914 vci_rsp_fifo_icache_put = true, 3915 vci_rsp_fifo_icache_num_cache = r_vci_rsp_num_cache; 3916 vci_rsp_fifo_icache_data = p_vci_ini_rw.rdata.read(); 3917 3918 r_vci_rsp_fsm = RSP_IDLE; 3919 3920 if ( (p_vci_ini_rw.rerror.read()&0x1) != vci_param::ERR_NORMAL ) r_vci_rsp_ins_error[r_vci_rsp_num_cache] = true; 3921 } 3922 break; 3923 3924 case RSP_DATA_MISS: 3925 3926 m_cost_dmiss_transaction++; 3927 if (p_vci_ini_rw.rspval.read() and r_vci_rsp_fifo_dcache_data.wok()) 3928 { 3929 PRINTF(" * <RSP> have rspval - error : %d\n",(int)p_vci_ini_rw.rerror.read()); 3930 3931 ASSERT(r_vci_rsp_cpt < m_dcache_words, 3932 "illegal VCI response packet for data read miss"); 3933 r_vci_rsp_cpt = r_vci_rsp_cpt + 1; 3934 3935 vci_rsp_fifo_dcache_put = true, 3936 vci_rsp_fifo_dcache_num_cache = r_vci_rsp_num_cache; 3937 vci_rsp_fifo_dcache_data = p_vci_ini_rw.rdata.read(); 3938 3939 if ( p_vci_ini_rw.reop.read() ) { 3940 ASSERT( ((r_vci_rsp_cpt == m_dcache_words - 1) 3941 or (p_vci_ini_rw.rerror.read()&0x1) 3942 or r_vci_rsp_data_error[r_vci_rsp_num_cache].read()), 3943 "illegal VCI response packet for data read miss"); 3944 r_vci_rsp_cpt = 0; 3945 r_vci_rsp_fsm = RSP_IDLE; 3946 } 3947 if ( (p_vci_ini_rw.rerror.read()&0x1) != vci_param::ERR_NORMAL ) r_vci_rsp_data_error[r_vci_rsp_num_cache] = true; 3948 } 3949 break; 3950 3951 case RSP_DATA_WRITE: 3952 m_cost_write_transaction++; 3953 if (p_vci_ini_rw.rspval.read()) 3954 { 3955 PRINTF(" * <RSP> have rspval - error : %d\n",(int)p_vci_ini_rw.rerror.read()); 3956 3957 ASSERT(p_vci_ini_rw.reop.read(), 3958 "A VCI response packet must contain one flit for a write transaction"); 3959 r_vci_rsp_fsm = RSP_IDLE; 3960 uint32_t wbuf_index = p_vci_ini_rw.rtrdid.read() - (1<<(vci_param::T-1)); 3961 size_t cpu_id = r_wbuf[r_vci_rsp_num_cache]->getCpuId (wbuf_index); 3962 bool cached = r_wbuf[r_vci_rsp_num_cache]->completed(wbuf_index); 3963 PRINTF(" * <RSP> cached : %d\n",cached); 3964 3965 if (not cached) 3966 r_dcache_previous_unc[r_vci_rsp_num_cache] = false; 3967 3968 if ((p_vci_ini_rw.rerror.read()&0x1) != vci_param::ERR_NORMAL) 3969 m_iss[cpu_id]->setWriteBerr(); 3970 3971 #if MWBUF_VHDL_TESTBENCH 3972 vhdl_mwbuf_port_completed_val [r_vci_rsp_num_cache] = (vhdl_tb_t)1; 3973 vhdl_mwbuf_port_completed_index [r_vci_rsp_num_cache] = (vhdl_tb_t)wbuf_index; 3974 vhdl_mwbuf_test_completed_cached [r_vci_rsp_num_cache] = (vhdl_tb_t)1; 3975 vhdl_mwbuf_port_completed_cached [r_vci_rsp_num_cache] = (vhdl_tb_t)cached; 3976 vhdl_mwbuf_test_completed_cpu_id [r_vci_rsp_num_cache] = (vhdl_tb_t)1; 3977 vhdl_mwbuf_port_completed_cpu_id [r_vci_rsp_num_cache] = (vhdl_tb_t)cpu_id; 3978 #endif 3979 } 3980 break; 3981 3982 case RSP_DATA_UNC: 3983 m_cost_unc_transaction++; 3984 if (p_vci_ini_rw.rspval.read() and r_vci_rsp_fifo_dcache_data.wok()) 3985 { 3986 ASSERT(p_vci_ini_rw.reop.read(), 3987 "illegal VCI response packet for data read uncached"); 3988 3989 vci_rsp_fifo_dcache_put = true, 3990 vci_rsp_fifo_dcache_num_cache = r_vci_rsp_num_cache; 3991 vci_rsp_fifo_dcache_data = p_vci_ini_rw.rdata.read(); 3992 3993 r_vci_rsp_fsm = RSP_IDLE; 3994 r_dcache_previous_unc[r_vci_rsp_num_cache] = false; 3995 3996 if ( (p_vci_ini_rw.rerror.read()&0x1) != vci_param::ERR_NORMAL ) r_vci_rsp_data_error[r_vci_rsp_num_cache] = true; 3997 } 3998 break; 3999 4000 case RSP_DATA_SC: 4001 m_cost_unc_transaction++; 4002 if (p_vci_ini_rw.rspval.read() and r_vci_rsp_fifo_dcache_data.wok()) 4003 { 4004 ASSERT(p_vci_ini_rw.reop.read(), 4005 "illegal VCI response packet for data SC"); 4006 4007 vci_rsp_fifo_dcache_put = true, 4008 vci_rsp_fifo_dcache_num_cache = r_vci_rsp_num_cache; 4009 vci_rsp_fifo_dcache_data = p_vci_ini_rw.rdata.read(); 4010 4011 r_vci_rsp_fsm = RSP_IDLE; 4012 r_dcache_previous_unc[r_vci_rsp_num_cache] = false; 4013 4014 if ( (p_vci_ini_rw.rerror.read()&0x1) != vci_param::ERR_NORMAL ) r_vci_rsp_data_error[r_vci_rsp_num_cache] = true; 4015 } 4016 break; 4017 4018 } // end switch r_vci_rsp_fsm 4019 4020 ////////////////////////////////////////////////////////////////////////// 4021 // FIFO_RSP 4022 ////////////////////////////////////////////////////////////////////////// 4023 4024 r_vci_rsp_fifo_icache_data .update(vci_rsp_fifo_icache_get, 4025 vci_rsp_fifo_icache_put, 4026 vci_rsp_fifo_icache_data); 4027 r_vci_rsp_fifo_icache_num_cache.update(vci_rsp_fifo_icache_get, 4028 vci_rsp_fifo_icache_put, 4029 vci_rsp_fifo_icache_num_cache); 4030 4031 r_vci_rsp_fifo_dcache_data .update(vci_rsp_fifo_dcache_get, 4032 vci_rsp_fifo_dcache_put, 4033 vci_rsp_fifo_dcache_data); 4034 r_vci_rsp_fifo_dcache_num_cache.update(vci_rsp_fifo_dcache_get, 4035 vci_rsp_fifo_dcache_put, 4036 vci_rsp_fifo_dcache_num_cache); 4037 4038 #if MWBUF_VHDL_TESTBENCH 4039 for (uint32_t num_dcache=0; num_dcache<m_nb_dcache; ++num_dcache) 4040 { 4041 vhdl_mwbuf_test_empty [num_dcache] = (vhdl_tb_t)1; 4042 vhdl_mwbuf_port_empty [num_dcache] = (vhdl_tb_t)r_wbuf[num_dcache]->empty(); 4043 4044 vhdl_testbench_mwbuf [num_dcache] 4045 << std::hex 4046 << vhdl_mwbuf_test_empty [num_dcache] << " " 4047 << vhdl_mwbuf_port_empty [num_dcache] << " " 4048 << vhdl_mwbuf_port_flush [num_dcache] << " " 4049 << vhdl_mwbuf_port_write_val [num_dcache] << " " 4050 << vhdl_mwbuf_test_write_ack [num_dcache] << " " 4051 << vhdl_mwbuf_port_write_ack [num_dcache] << " " 4052 << vhdl_mwbuf_port_write_addr [num_dcache] << " " 4053 << vhdl_mwbuf_port_write_data [num_dcache] << " " 4054 << vhdl_mwbuf_port_write_be [num_dcache] << " " 4055 << vhdl_mwbuf_port_write_cached [num_dcache] << " " 4056 << vhdl_mwbuf_port_write_cpu_id [num_dcache] << " " 4057 << vhdl_mwbuf_test_sent_val [num_dcache] << " " 4058 << vhdl_mwbuf_port_sent_val [num_dcache] << " " 4059 << vhdl_mwbuf_port_sent_ack [num_dcache] << " " 4060 << vhdl_mwbuf_test_sent_word_min [num_dcache] << " " 4061 << vhdl_mwbuf_port_sent_word_min [num_dcache] << " " 4062 << vhdl_mwbuf_test_sent_word_max [num_dcache] << " " 4063 << vhdl_mwbuf_port_sent_word_max [num_dcache] << " " 4064 << vhdl_mwbuf_port_sent_word [num_dcache] << " " 4065 << vhdl_mwbuf_test_sent_addr [num_dcache] << " " 4066 << vhdl_mwbuf_port_sent_addr [num_dcache] << " " 4067 << vhdl_mwbuf_test_sent_data [num_dcache] << " " 4068 << vhdl_mwbuf_port_sent_data [num_dcache] << " " 4069 << vhdl_mwbuf_test_sent_be [num_dcache] << " " 4070 << vhdl_mwbuf_port_sent_be [num_dcache] << " " 4071 << vhdl_mwbuf_test_sent_index [num_dcache] << " " 4072 << vhdl_mwbuf_port_sent_index [num_dcache] << " " 4073 << vhdl_mwbuf_port_raw_test [num_dcache] << " " 4074 << vhdl_mwbuf_port_raw_addr [num_dcache] << " " 4075 << vhdl_mwbuf_test_raw_miss [num_dcache] << " " 4076 << vhdl_mwbuf_port_raw_miss [num_dcache] << " " 4077 << vhdl_mwbuf_port_completed_val [num_dcache] << " " 4078 << vhdl_mwbuf_port_completed_index [num_dcache] << " " 4079 << vhdl_mwbuf_test_completed_cached [num_dcache] << " " 4080 << vhdl_mwbuf_port_completed_cached [num_dcache] << " " 4081 << vhdl_mwbuf_test_completed_cpu_id [num_dcache] << " " 4082 << vhdl_mwbuf_port_completed_cpu_id [num_dcache] 4083 << std::dec 4084 << std::endl; 4085 } 4086 #endif 2490 4087 } // end transition() 2491 4088 … … 2494 4091 ////////////////////////////////////////////////////////////////////////////////// 2495 4092 { 2496 2497 // VCI initiator response 2498 switch ( r_cleanup_fsm.read() ) { 2499 2500 case CLEANUP_IDLE: 2501 p_vci_ini_c.rspack = false; 2502 p_vci_ini_c.cmdval = r_icache_cleanup_req || r_dcache_cleanup_req; 2503 if ( r_dcache_cleanup_req ) 2504 { 2505 p_vci_ini_c.address = r_dcache_cleanup_line.read() * (m_dcache_words << 2); 2506 p_vci_ini_c.trdid = TYPE_DATA_CLEANUP; 2507 } 2508 else 2509 { 2510 p_vci_ini_c.address = r_icache_cleanup_line.read() * (m_icache_words << 2); 2511 p_vci_ini_c.trdid = TYPE_INS_CLEANUP; 2512 } 2513 p_vci_ini_c.wdata = 0; 2514 p_vci_ini_c.be = 0xF; 2515 p_vci_ini_c.plen = 4; 2516 p_vci_ini_c.cmd = vci_param::CMD_WRITE; 2517 p_vci_ini_c.pktid = 0; 2518 p_vci_ini_c.srcid = m_srcid_c; 2519 p_vci_ini_c.cons = false; 2520 p_vci_ini_c.wrap = false; 2521 p_vci_ini_c.contig = false; 2522 p_vci_ini_c.clen = 0; 2523 p_vci_ini_c.cfixed = false; 2524 p_vci_ini_c.eop = true; 2525 break; 2526 2527 case CLEANUP_DCACHE: 2528 p_vci_ini_c.rspack = true; 2529 p_vci_ini_c.cmdval = false; 2530 p_vci_ini_c.address = 0; 2531 p_vci_ini_c.wdata = 0; 2532 p_vci_ini_c.be = 0; 2533 p_vci_ini_c.plen = 0; 2534 p_vci_ini_c.cmd = vci_param::CMD_WRITE; 2535 p_vci_ini_c.trdid = 0; 2536 p_vci_ini_c.pktid = 0; 2537 p_vci_ini_c.srcid = 0; 2538 p_vci_ini_c.cons = false; 2539 p_vci_ini_c.wrap = false; 2540 p_vci_ini_c.contig = false; 2541 p_vci_ini_c.clen = 0; 2542 p_vci_ini_c.cfixed = false; 2543 p_vci_ini_c.eop = false; 2544 break; 2545 2546 case CLEANUP_ICACHE: 2547 p_vci_ini_c.rspack = true; 2548 p_vci_ini_c.cmdval = false; 2549 p_vci_ini_c.address = 0; 2550 p_vci_ini_c.wdata = 0; 2551 p_vci_ini_c.be = 0; 2552 p_vci_ini_c.plen = 0; 2553 p_vci_ini_c.cmd = vci_param::CMD_WRITE; 2554 p_vci_ini_c.trdid = 0; 2555 p_vci_ini_c.pktid = 0; 2556 p_vci_ini_c.srcid = 0; 2557 p_vci_ini_c.cons = false; 2558 p_vci_ini_c.wrap = false; 2559 p_vci_ini_c.contig = false; 2560 p_vci_ini_c.clen = 0; 2561 p_vci_ini_c.cfixed = false; 2562 p_vci_ini_c.eop = false; 2563 break; 2564 } // end switch r_cleanup_fsm 4093 PRINTF("--------------------------------------------\n"); 4094 PRINTF(" * CC_XCACHE_WRAPPER \"%s\" genMoore - Time = %d\n",name().c_str(),(uint32_t)m_cpt_total_cycles); 4095 4096 // VCI initiator response 4097 switch ( r_cleanup_fsm.read() ) { 4098 case CLEANUP_IDLE: 4099 p_vci_ini_c.rspack = false; 4100 p_vci_ini_c.cmdval = false; 4101 p_vci_ini_c.address = 0; 4102 p_vci_ini_c.wdata = 0; 4103 p_vci_ini_c.be = 0; 4104 p_vci_ini_c.plen = 0; 4105 p_vci_ini_c.cmd = vci_param::CMD_WRITE; 4106 p_vci_ini_c.trdid = 0; 4107 p_vci_ini_c.pktid = 0; 4108 p_vci_ini_c.srcid = 0; 4109 p_vci_ini_c.cons = false; 4110 p_vci_ini_c.wrap = false; 4111 p_vci_ini_c.contig = false; 4112 p_vci_ini_c.clen = 0; 4113 p_vci_ini_c.cfixed = false; 4114 p_vci_ini_c.eop = false; 4115 break; 4116 4117 case CLEANUP_REQ: 4118 { 4119 addr_40 addr; 4120 if (r_cleanup_icache) 4121 { 4122 addr = r_icache_cleanup_line[r_cleanup_num_cache].read()<<m_icache_words_shift; 4123 set_num_icache(addr,r_cleanup_num_cache); 4124 4125 PRINTF(" * <CLEANUP> icache : %llx\n",(blob_t)addr); 4126 } 4127 else 4128 { 4129 addr = r_dcache_cleanup_line[r_cleanup_num_cache].read()<<m_dcache_words_shift; 4130 set_num_dcache(addr,r_cleanup_num_cache); 4131 4132 PRINTF(" * <CLEANUP> dcache : %llx\n",(blob_t)addr); 4133 } 4134 4135 p_vci_ini_c.rspack = false; 4136 p_vci_ini_c.cmdval = true; 4137 p_vci_ini_c.address = addr; 4138 p_vci_ini_c.wdata = 0; 4139 p_vci_ini_c.be = 0xF; 4140 p_vci_ini_c.plen = 4; 4141 p_vci_ini_c.cmd = vci_param::CMD_WRITE; 4142 p_vci_ini_c.trdid = (r_cleanup_icache)?TYPE_INS_CLEANUP:TYPE_DATA_CLEANUP; 4143 p_vci_ini_c.pktid = (sc_dt::sc_uint<vci_param::P>)r_cleanup_num_cache; 4144 p_vci_ini_c.srcid = m_srcid_c; 4145 p_vci_ini_c.cons = false; 4146 p_vci_ini_c.wrap = false; 4147 p_vci_ini_c.contig = false; 4148 p_vci_ini_c.clen = 0; 4149 p_vci_ini_c.cfixed = false; 4150 p_vci_ini_c.eop = true; 4151 4152 break; 4153 } 4154 4155 case CLEANUP_RSP_DCACHE: 4156 p_vci_ini_c.rspack = true; 4157 p_vci_ini_c.cmdval = false; 4158 p_vci_ini_c.address = 0; 4159 p_vci_ini_c.wdata = 0; 4160 p_vci_ini_c.be = 0; 4161 p_vci_ini_c.plen = 0; 4162 p_vci_ini_c.cmd = vci_param::CMD_WRITE; 4163 p_vci_ini_c.trdid = 0; 4164 p_vci_ini_c.pktid = 0; 4165 p_vci_ini_c.srcid = 0; 4166 p_vci_ini_c.cons = false; 4167 p_vci_ini_c.wrap = false; 4168 p_vci_ini_c.contig = false; 4169 p_vci_ini_c.clen = 0; 4170 p_vci_ini_c.cfixed = false; 4171 p_vci_ini_c.eop = false; 4172 break; 4173 4174 case CLEANUP_RSP_ICACHE: 4175 p_vci_ini_c.rspack = true; 4176 p_vci_ini_c.cmdval = false; 4177 p_vci_ini_c.address = 0; 4178 p_vci_ini_c.wdata = 0; 4179 p_vci_ini_c.be = 0; 4180 p_vci_ini_c.plen = 0; 4181 p_vci_ini_c.cmd = vci_param::CMD_WRITE; 4182 p_vci_ini_c.trdid = 0; 4183 p_vci_ini_c.pktid = 0; 4184 p_vci_ini_c.srcid = 0; 4185 p_vci_ini_c.cons = false; 4186 p_vci_ini_c.wrap = false; 4187 p_vci_ini_c.contig = false; 4188 p_vci_ini_c.clen = 0; 4189 p_vci_ini_c.cfixed = false; 4190 p_vci_ini_c.eop = false; 4191 break; 4192 } // end switch r_cleanup_fsm 2565 4193 2566 4194 // VCI initiator command 2567 4195 2568 switch (r_vci_cmd_fsm.read() ) { 2569 2570 case CMD_IDLE: 2571 p_vci_ini_rw.cmdval = false; 2572 p_vci_ini_rw.address = 0; 2573 p_vci_ini_rw.wdata = 0; 2574 p_vci_ini_rw.be = 0; 2575 p_vci_ini_rw.plen = 0; 2576 p_vci_ini_rw.cmd = vci_param::CMD_NOP; 2577 p_vci_ini_rw.trdid = 0; 2578 p_vci_ini_rw.pktid = 0; 2579 p_vci_ini_rw.srcid = 0; 2580 p_vci_ini_rw.cons = false; 2581 p_vci_ini_rw.wrap = false; 2582 p_vci_ini_rw.contig = false; 2583 p_vci_ini_rw.clen = 0; 2584 p_vci_ini_rw.cfixed = false; 2585 p_vci_ini_rw.eop = false; 2586 2587 break; 2588 2589 case CMD_DATA_UNC: 2590 p_vci_ini_rw.cmdval = true; 2591 p_vci_ini_rw.address = (addr_40) r_dcache_addr_save.read() & ~0x3; 2592 switch( r_dcache_type_save ) { 2593 case iss_t::DATA_READ: 2594 p_vci_ini_rw.wdata = 0; 2595 p_vci_ini_rw.be = r_dcache_be_save.read(); 2596 p_vci_ini_rw.cmd = vci_param::CMD_READ; 2597 break; 2598 case iss_t::DATA_LL: 2599 p_vci_ini_rw.wdata = 0; 2600 p_vci_ini_rw.be = 0xF; 2601 p_vci_ini_rw.cmd = vci_param::CMD_LOCKED_READ; 2602 break; 2603 default: 2604 ASSERT(false,"this should not happen"); 2605 } 2606 p_vci_ini_rw.plen = 4; 2607 p_vci_ini_rw.trdid = TYPE_DATA_UNC; // data cache uncached read 2608 p_vci_ini_rw.pktid = 0; 2609 p_vci_ini_rw.srcid = m_srcid_rw; 2610 p_vci_ini_rw.cons = false; 2611 p_vci_ini_rw.wrap = false; 2612 p_vci_ini_rw.contig = true; 2613 p_vci_ini_rw.clen = 0; 2614 p_vci_ini_rw.cfixed = false; 2615 p_vci_ini_rw.eop = true; 2616 2617 break; 2618 2619 case CMD_DATA_SC: 2620 p_vci_ini_rw.cmdval = true; 2621 p_vci_ini_rw.address = (addr_40) r_dcache_addr_save.read() & ~0x3; 2622 if(r_vci_cmd_max.read() == 3){ 2623 ASSERT(false, "Not handled yet"); 2624 } else { // r_vci_cmd_cpt == 1 2625 switch(r_vci_cmd_cpt.read()){ 2626 case 0: 2627 p_vci_ini_rw.wdata = (uint32_t)(r_dcache_ll_data.read() & 0xFFFFFFFF); 2628 break; 2629 case 1: 2630 p_vci_ini_rw.wdata = r_dcache_wdata_save.read(); 2631 break; 2632 } 2633 } 2634 p_vci_ini_rw.be = 0xF; 2635 p_vci_ini_rw.cmd = vci_param::CMD_STORE_COND; 2636 p_vci_ini_rw.plen = 4*(r_vci_cmd_max.read()+1); 2637 p_vci_ini_rw.trdid = TYPE_DATA_SC; // data cache uncached read 2638 p_vci_ini_rw.pktid = 0; 2639 p_vci_ini_rw.srcid = m_srcid_rw; 2640 p_vci_ini_rw.cons = true; 2641 p_vci_ini_rw.wrap = false; 2642 p_vci_ini_rw.contig = false; 2643 p_vci_ini_rw.clen = 0; 2644 p_vci_ini_rw.cfixed = false; 2645 p_vci_ini_rw.eop = (r_vci_cmd_cpt.read() == r_vci_cmd_max.read()); 2646 2647 break; 2648 2649 case CMD_DATA_WRITE: 2650 p_vci_ini_rw.cmdval = true; 2651 p_vci_ini_rw.address = r_wbuf.getAddress(r_vci_cmd_cpt)&~0x3; 2652 p_vci_ini_rw.wdata = r_wbuf.getData(r_vci_cmd_cpt); 2653 p_vci_ini_rw.be = r_wbuf.getBe(r_vci_cmd_cpt); 2654 p_vci_ini_rw.plen = (r_vci_cmd_max - r_vci_cmd_min + 1)<<2; 2655 p_vci_ini_rw.cmd = vci_param::CMD_WRITE; 2656 p_vci_ini_rw.trdid = r_wbuf.getIndex() + (1<<(vci_param::T-1)); 2657 p_vci_ini_rw.pktid = 0; 2658 p_vci_ini_rw.srcid = m_srcid_rw; 2659 p_vci_ini_rw.cons = false; 2660 p_vci_ini_rw.wrap = false; 2661 p_vci_ini_rw.contig = true; 2662 p_vci_ini_rw.clen = 0; 2663 p_vci_ini_rw.cfixed = false; 2664 p_vci_ini_rw.eop = (r_vci_cmd_cpt == r_vci_cmd_max); 2665 2666 break; 2667 2668 case CMD_DATA_MISS: 2669 p_vci_ini_rw.cmdval = true; 2670 p_vci_ini_rw.address = r_dcache_addr_save.read() & (addr_40) m_dcache_yzmask; 2671 p_vci_ini_rw.be = 0xF; 2672 p_vci_ini_rw.plen = m_dcache_words << 2; 2673 p_vci_ini_rw.cmd = vci_param::CMD_READ; 2674 p_vci_ini_rw.trdid = TYPE_DATA_MISS; // data cache cached read 2675 p_vci_ini_rw.pktid = 0; 2676 p_vci_ini_rw.srcid = m_srcid_rw; 2677 p_vci_ini_rw.cons = false; 2678 p_vci_ini_rw.wrap = false; 2679 p_vci_ini_rw.contig = true; 2680 p_vci_ini_rw.clen = 0; 2681 p_vci_ini_rw.cfixed = false; 2682 p_vci_ini_rw.eop = true; 2683 2684 break; 2685 2686 case CMD_INS_MISS: 2687 p_vci_ini_rw.cmdval = true; 2688 p_vci_ini_rw.address = r_icache_addr_save.read() & (addr_40) m_icache_yzmask; 2689 p_vci_ini_rw.be = 0xF; 2690 p_vci_ini_rw.plen = m_icache_words << 2; 2691 p_vci_ini_rw.cmd = vci_param::CMD_READ; 2692 p_vci_ini_rw.trdid = TYPE_INS_MISS; // ins cache cached read 2693 p_vci_ini_rw.pktid = 0; 2694 p_vci_ini_rw.srcid = m_srcid_rw; 2695 p_vci_ini_rw.cons = false; 2696 p_vci_ini_rw.wrap = false; 2697 p_vci_ini_rw.contig = true; 2698 p_vci_ini_rw.clen = 0; 2699 p_vci_ini_rw.cfixed = false; 2700 p_vci_ini_rw.eop = true; 2701 2702 break; 2703 2704 case CMD_INS_UNC: 2705 p_vci_ini_rw.cmdval = true; 2706 p_vci_ini_rw.address = r_icache_addr_save.read() & ~0x3; 2707 p_vci_ini_rw.be = 0xF; 2708 p_vci_ini_rw.plen = 4; 2709 p_vci_ini_rw.cmd = vci_param::CMD_READ; 2710 p_vci_ini_rw.trdid = TYPE_INS_UNC; // ins cache uncached read 2711 p_vci_ini_rw.pktid = 0; 2712 p_vci_ini_rw.srcid = m_srcid_rw; 2713 p_vci_ini_rw.cons = false; 2714 p_vci_ini_rw.wrap = false; 2715 p_vci_ini_rw.contig = true; 2716 p_vci_ini_rw.clen = 0; 2717 p_vci_ini_rw.cfixed = false; 2718 p_vci_ini_rw.eop = true; 2719 2720 break; 2721 2722 } // end switch r_vci_cmd_fsm 2723 2724 bool ack; 2725 2726 switch (r_vci_rsp_fsm.read() ) { 2727 case RSP_IDLE : ack = false; break; 2728 case RSP_DATA_WRITE : ack = true; break; 2729 case RSP_INS_MISS : 2730 case RSP_INS_UNC : ack = CACHE_MISS_BUF_RSP_ACK(i); break; 2731 case RSP_DATA_MISS : 2732 case RSP_DATA_UNC : 2733 case RSP_DATA_SC : ack = CACHE_MISS_BUF_RSP_ACK(d); break; 2734 } // end switch r_vci_cmd_fsm 2735 2736 r_vci_rsp_ack = ack; 2737 p_vci_ini_rw.rspack = ack; 2738 2739 // VCI_TGT 2740 2741 switch ( r_vci_tgt_fsm.read() ) { 2742 2743 case TGT_IDLE: 2744 case TGT_UPDT_WORD: 2745 case TGT_UPDT_DATA: 2746 p_vci_tgt.cmdack = true; 2747 p_vci_tgt.rspval = false; 2748 break; 2749 2750 case TGT_RSP_BROADCAST: 2751 p_vci_tgt.cmdack = false; 2752 p_vci_tgt.rspval = not r_tgt_icache_req.read() and not r_tgt_dcache_req.read() and ( r_tgt_icache_rsp | r_tgt_dcache_rsp ); 2753 p_vci_tgt.rsrcid = r_tgt_srcid.read(); 2754 p_vci_tgt.rpktid = r_tgt_pktid.read(); 2755 p_vci_tgt.rtrdid = r_tgt_trdid.read(); 2756 p_vci_tgt.rdata = 0; 2757 p_vci_tgt.rerror = 0x2 & ( (1 << vci_param::E) - 1); // Write OK 2758 p_vci_tgt.reop = true; 2759 break; 2760 2761 case TGT_RSP_ICACHE: 2762 p_vci_tgt.cmdack = false; 2763 p_vci_tgt.rspval = not r_tgt_icache_req.read() and r_tgt_icache_rsp.read(); 2764 p_vci_tgt.rsrcid = r_tgt_srcid.read(); 2765 p_vci_tgt.rpktid = r_tgt_pktid.read(); 2766 p_vci_tgt.rtrdid = r_tgt_trdid.read(); 2767 p_vci_tgt.rdata = 0; 2768 p_vci_tgt.rerror = 0x2 & ( (1 << vci_param::E) - 1); // Write OK 2769 p_vci_tgt.reop = true; 2770 break; 2771 2772 case TGT_RSP_DCACHE: 2773 p_vci_tgt.cmdack = false; 2774 p_vci_tgt.rspval = not r_tgt_dcache_req.read() and r_tgt_dcache_rsp.read(); 2775 p_vci_tgt.rsrcid = r_tgt_srcid.read(); 2776 p_vci_tgt.rpktid = r_tgt_pktid.read(); 2777 p_vci_tgt.rtrdid = r_tgt_trdid.read(); 2778 p_vci_tgt.rdata = 0; 2779 p_vci_tgt.rerror = 0x2 & ( (1 << vci_param::E) - 1); // Write OK 2780 p_vci_tgt.reop = true; 2781 break; 2782 2783 case TGT_REQ_BROADCAST: 2784 case TGT_REQ_ICACHE: 2785 case TGT_REQ_DCACHE: 2786 p_vci_tgt.cmdack = false; 2787 p_vci_tgt.rspval = false; 2788 break; 2789 2790 } // end switch TGT_FSM 4196 switch (r_vci_cmd_fsm.read() ) { 4197 case CMD_IDLE: 4198 { 4199 p_vci_ini_rw.cmdval = false; 4200 p_vci_ini_rw.address = 0; 4201 p_vci_ini_rw.wdata = 0; 4202 p_vci_ini_rw.be = 0; 4203 p_vci_ini_rw.plen = 0; 4204 p_vci_ini_rw.cmd = vci_param::CMD_NOP; 4205 p_vci_ini_rw.trdid = 0; 4206 p_vci_ini_rw.pktid = 0; 4207 p_vci_ini_rw.srcid = 0; 4208 p_vci_ini_rw.cons = false; 4209 p_vci_ini_rw.wrap = false; 4210 p_vci_ini_rw.contig = false; 4211 p_vci_ini_rw.clen = 0; 4212 p_vci_ini_rw.cfixed = false; 4213 p_vci_ini_rw.eop = false; 4214 4215 break; 4216 } 4217 case CMD_DATA_UNC: 4218 { 4219 p_vci_ini_rw.cmdval = true; 4220 4221 addr_40 addr = (addr_40) r_dcache_addr_save[r_vci_cmd_num_cache].read() & ~0x3; 4222 set_num_dcache(addr,r_vci_cmd_num_cache); 4223 4224 PRINTF(" * <CMD> DATA_UNC : %d - %llx\n",(uint32_t)r_vci_cmd_num_cache,(blob_t)(addr)); 4225 4226 p_vci_ini_rw.address = addr; 4227 switch( r_dcache_type_save[r_vci_cmd_num_cache] ) { 4228 case iss_t::DATA_READ: 4229 p_vci_ini_rw.wdata = 0; 4230 p_vci_ini_rw.be = r_dcache_be_save[r_vci_cmd_num_cache].read(); 4231 p_vci_ini_rw.cmd = vci_param::CMD_READ; 4232 break; 4233 case iss_t::DATA_LL: 4234 p_vci_ini_rw.wdata = 0; 4235 p_vci_ini_rw.be = 0xF; 4236 p_vci_ini_rw.cmd = vci_param::CMD_LOCKED_READ; 4237 break; 4238 default: 4239 ASSERT(false,"this should not happen"); 4240 } 4241 p_vci_ini_rw.plen = 4; 4242 p_vci_ini_rw.trdid = TYPE_DATA_UNC; // data cache uncached read 4243 p_vci_ini_rw.pktid = (sc_dt::sc_uint<vci_param::P>)r_vci_cmd_num_cache; 4244 p_vci_ini_rw.srcid = m_srcid_rw; 4245 p_vci_ini_rw.cons = false; 4246 p_vci_ini_rw.wrap = false; 4247 p_vci_ini_rw.contig = true; 4248 p_vci_ini_rw.clen = 0; 4249 p_vci_ini_rw.cfixed = false; 4250 p_vci_ini_rw.eop = true; 4251 4252 break; 4253 } 4254 case CMD_DATA_SC: 4255 { 4256 p_vci_ini_rw.cmdval = true; 4257 4258 addr_40 addr = (addr_40) r_dcache_addr_save[r_vci_cmd_num_cache].read() & ~0x3; 4259 set_num_dcache(addr,r_vci_cmd_num_cache); 4260 4261 PRINTF(" * <CMD> DATA_SC : %d - %llx\n",(uint32_t)r_vci_cmd_num_cache,(blob_t)(addr)); 4262 4263 p_vci_ini_rw.address = addr; 4264 if(r_vci_cmd_max.read() == 3){ 4265 ASSERT(false, "Not handled yet"); 4266 } else { // r_vci_cmd_cpt == 1 4267 switch(r_vci_cmd_cpt.read()){ 4268 case 0: 4269 p_vci_ini_rw.wdata = (uint32_t)(r_dcache_ll_data[r_vci_cmd_num_cache][r_dcache_num_cpu_save[r_vci_cmd_num_cache]].read() & 0xFFFFFFFF); 4270 break; 4271 case 1: 4272 p_vci_ini_rw.wdata = r_dcache_wdata_save[r_vci_cmd_num_cache].read(); 4273 break; 4274 } 4275 } 4276 p_vci_ini_rw.be = 0xF; 4277 p_vci_ini_rw.cmd = vci_param::CMD_STORE_COND; 4278 p_vci_ini_rw.plen = 4*(r_vci_cmd_max.read()+1); 4279 p_vci_ini_rw.trdid = TYPE_DATA_SC; // data cache uncached read 4280 p_vci_ini_rw.pktid = (sc_dt::sc_uint<vci_param::P>)r_vci_cmd_num_cache; 4281 p_vci_ini_rw.srcid = m_srcid_rw; 4282 p_vci_ini_rw.cons = true; 4283 p_vci_ini_rw.wrap = false; 4284 p_vci_ini_rw.contig = false; 4285 p_vci_ini_rw.clen = 0; 4286 p_vci_ini_rw.cfixed = false; 4287 p_vci_ini_rw.eop = (r_vci_cmd_cpt.read() == r_vci_cmd_max.read()); 4288 4289 break; 4290 } 4291 case CMD_DATA_WRITE: 4292 { 4293 p_vci_ini_rw.cmdval = true; 4294 4295 addr_40 addr = (addr_40) r_wbuf[r_vci_cmd_num_cache]->getAddress(r_vci_cmd_cpt)&~0x3; 4296 4297 PRINTF(" * <CMD> DATA_WRITE : %d - %llx\n",(uint32_t)r_vci_cmd_num_cache,(blob_t)(addr)); 4298 4299 p_vci_ini_rw.address = addr; 4300 p_vci_ini_rw.wdata = r_wbuf[r_vci_cmd_num_cache]->getData(r_vci_cmd_cpt); 4301 p_vci_ini_rw.be = r_wbuf[r_vci_cmd_num_cache]->getBe(r_vci_cmd_cpt); 4302 p_vci_ini_rw.plen = (r_vci_cmd_max - r_vci_cmd_min + 1)<<2; 4303 p_vci_ini_rw.cmd = vci_param::CMD_WRITE; 4304 p_vci_ini_rw.trdid = r_wbuf[r_vci_cmd_num_cache]->getIndex() + (1<<(vci_param::T-1)); 4305 p_vci_ini_rw.pktid = (sc_dt::sc_uint<vci_param::P>)r_vci_cmd_num_cache; 4306 p_vci_ini_rw.srcid = m_srcid_rw; 4307 p_vci_ini_rw.cons = false; 4308 p_vci_ini_rw.wrap = false; 4309 p_vci_ini_rw.contig = true; 4310 p_vci_ini_rw.clen = 0; 4311 p_vci_ini_rw.cfixed = false; 4312 p_vci_ini_rw.eop = (r_vci_cmd_cpt == r_vci_cmd_max); 4313 4314 break; 4315 } 4316 case CMD_DATA_MISS: 4317 { 4318 p_vci_ini_rw.cmdval = true; 4319 4320 addr_40 addr = r_dcache_addr_save[r_vci_cmd_num_cache].read() & (addr_40) m_dcache_yzmask; 4321 set_num_dcache(addr,r_vci_cmd_num_cache); 4322 4323 PRINTF(" * <CMD> DATA_MISS : %d - %llx\n",(uint32_t)r_vci_cmd_num_cache,(blob_t)(addr)); 4324 4325 p_vci_ini_rw.address = addr; 4326 p_vci_ini_rw.be = 0xF; 4327 p_vci_ini_rw.plen = m_dcache_words << 2; 4328 p_vci_ini_rw.cmd = vci_param::CMD_READ; 4329 p_vci_ini_rw.trdid = TYPE_DATA_MISS; // data cache cached read 4330 p_vci_ini_rw.pktid = (sc_dt::sc_uint<vci_param::P>)r_vci_cmd_num_cache; 4331 p_vci_ini_rw.srcid = m_srcid_rw; 4332 p_vci_ini_rw.cons = false; 4333 p_vci_ini_rw.wrap = false; 4334 p_vci_ini_rw.contig = true; 4335 p_vci_ini_rw.clen = 0; 4336 p_vci_ini_rw.cfixed = false; 4337 p_vci_ini_rw.eop = true; 4338 4339 break; 4340 } 4341 case CMD_INS_MISS: 4342 { 4343 p_vci_ini_rw.cmdval = true; 4344 4345 addr_40 addr = r_icache_addr_save[r_vci_cmd_num_cache].read() & (addr_40) m_icache_yzmask; 4346 set_num_icache(addr,r_vci_cmd_num_cache); 4347 4348 PRINTF(" * <CMD> INS_MISS : %d - %llx\n",(uint32_t)r_vci_cmd_num_cache,(blob_t)(addr)); 4349 4350 p_vci_ini_rw.address = addr; 4351 p_vci_ini_rw.be = 0xF; 4352 p_vci_ini_rw.plen = m_icache_words << 2; 4353 p_vci_ini_rw.cmd = vci_param::CMD_READ; 4354 p_vci_ini_rw.trdid = TYPE_INS_MISS; // ins cache cached read 4355 p_vci_ini_rw.pktid = (sc_dt::sc_uint<vci_param::P>)r_vci_cmd_num_cache; 4356 p_vci_ini_rw.srcid = m_srcid_rw; 4357 p_vci_ini_rw.cons = false; 4358 p_vci_ini_rw.wrap = false; 4359 p_vci_ini_rw.contig = true; 4360 p_vci_ini_rw.clen = 0; 4361 p_vci_ini_rw.cfixed = false; 4362 p_vci_ini_rw.eop = true; 4363 4364 break; 4365 } 4366 case CMD_INS_UNC: 4367 { 4368 p_vci_ini_rw.cmdval = true; 4369 4370 addr_40 addr = r_icache_addr_save[r_vci_cmd_num_cache].read() & ~0x3; 4371 set_num_icache(addr,r_vci_cmd_num_cache); 4372 4373 PRINTF(" * <CMD> INS_UNC : %d - %llx\n",(uint32_t)r_vci_cmd_num_cache,(blob_t)(addr)); 4374 4375 p_vci_ini_rw.address = addr; 4376 p_vci_ini_rw.be = 0xF; 4377 p_vci_ini_rw.plen = 4; 4378 p_vci_ini_rw.cmd = vci_param::CMD_READ; 4379 p_vci_ini_rw.trdid = TYPE_INS_UNC; // ins cache uncached read 4380 p_vci_ini_rw.pktid = (sc_dt::sc_uint<vci_param::P>)r_vci_cmd_num_cache; 4381 p_vci_ini_rw.srcid = m_srcid_rw; 4382 p_vci_ini_rw.cons = false; 4383 p_vci_ini_rw.wrap = false; 4384 p_vci_ini_rw.contig = true; 4385 p_vci_ini_rw.clen = 0; 4386 p_vci_ini_rw.cfixed = false; 4387 p_vci_ini_rw.eop = true; 4388 4389 break; 4390 } 4391 } // end switch r_vci_cmd_fsm 4392 4393 switch (r_vci_rsp_fsm.read() ) { 4394 case RSP_DATA_WRITE : p_vci_ini_rw.rspack = true; break; 4395 case RSP_INS_MISS : 4396 case RSP_INS_UNC : p_vci_ini_rw.rspack = r_vci_rsp_fifo_icache_data.wok(); break; 4397 case RSP_DATA_MISS : 4398 case RSP_DATA_UNC : 4399 case RSP_DATA_SC : p_vci_ini_rw.rspack = r_vci_rsp_fifo_dcache_data.wok(); break; 4400 case RSP_IDLE : 4401 default : p_vci_ini_rw.rspack = false; break; 4402 } // end switch r_vci_rsp_fsm 4403 4404 // VCI_TGT 4405 4406 // PRINTF(" * <TGT> srcid : %d\n", r_tgt_srcid.read()); 4407 4408 switch ( r_vci_tgt_fsm.read() ) { 4409 4410 case TGT_IDLE: 4411 case TGT_UPDT_WORD: 4412 case TGT_UPDT_DATA: 4413 p_vci_tgt.cmdack = true; 4414 p_vci_tgt.rspval = false; 4415 break; 4416 4417 case TGT_RSP_BROADCAST: 4418 { 4419 bool tgt_icache_req; 4420 bool tgt_icache_rsp; 4421 4422 #if (CC_XCACHE_WRAPPER_MULTI_CACHE==1) 4423 tgt_icache_req = r_tgt_icache_req[r_tgt_num_cache].read(); 4424 tgt_icache_rsp = r_tgt_icache_rsp[r_tgt_num_cache].read(); 4425 #elif (CC_XCACHE_WRAPPER_MULTI_CACHE==2) 4426 tgt_icache_req = false; 4427 tgt_icache_rsp = false; 4428 for (uint32_t num_cache=0; num_cache<m_nb_icache; ++num_cache) 4429 { 4430 tgt_icache_req |= r_tgt_icache_req[num_cache].read(); 4431 tgt_icache_rsp |= r_tgt_icache_rsp[num_cache].read(); 4432 } 4433 #endif 4434 4435 bool rspval = ((not tgt_icache_req and not r_tgt_dcache_req[r_tgt_num_cache].read()) 4436 and (tgt_icache_rsp | r_tgt_dcache_rsp[r_tgt_num_cache])); 4437 4438 PRINTF(" * <TGT> RSP_BROADCAST : rspval : %d (i %d %d, d %d %d)\n",rspval,tgt_icache_req,tgt_icache_rsp, r_tgt_dcache_req[r_tgt_num_cache].read(), r_tgt_dcache_rsp[r_tgt_num_cache].read()); 4439 4440 p_vci_tgt.cmdack = false; 4441 p_vci_tgt.rspval = rspval; 4442 p_vci_tgt.rsrcid = r_tgt_srcid.read(); 4443 p_vci_tgt.rpktid = r_tgt_pktid.read(); 4444 p_vci_tgt.rtrdid = r_tgt_trdid.read(); 4445 p_vci_tgt.rdata = 0; 4446 p_vci_tgt.rerror = 0x2 & ( (1 << vci_param::E) - 1); // Write OK 4447 p_vci_tgt.reop = true; 4448 break; 4449 } 4450 case TGT_RSP_ICACHE: 4451 { 4452 bool rspval = not r_tgt_icache_req[r_tgt_num_cache].read() and r_tgt_icache_rsp[r_tgt_num_cache].read(); 4453 4454 PRINTF(" * <TGT> RSP_ICACHE : rspval : %d\n",rspval); 4455 4456 p_vci_tgt.cmdack = false; 4457 p_vci_tgt.rspval = rspval; 4458 p_vci_tgt.rsrcid = r_tgt_srcid.read(); 4459 p_vci_tgt.rpktid = r_tgt_pktid.read(); 4460 p_vci_tgt.rtrdid = r_tgt_trdid.read(); 4461 p_vci_tgt.rdata = 0; 4462 p_vci_tgt.rerror = 0x2 & ( (1 << vci_param::E) - 1); // Write OK 4463 p_vci_tgt.reop = true; 4464 break; 4465 } 4466 case TGT_RSP_DCACHE: 4467 { 4468 bool rspval = not r_tgt_dcache_req[r_tgt_num_cache].read() and r_tgt_dcache_rsp[r_tgt_num_cache].read(); 4469 4470 PRINTF(" * <TGT> RSP_DCACHE : rspval : %d\n",rspval); 4471 4472 p_vci_tgt.cmdack = false; 4473 p_vci_tgt.rspval = rspval; 4474 p_vci_tgt.rsrcid = r_tgt_srcid.read(); 4475 p_vci_tgt.rpktid = r_tgt_pktid.read(); 4476 p_vci_tgt.rtrdid = r_tgt_trdid.read(); 4477 p_vci_tgt.rdata = 0; 4478 p_vci_tgt.rerror = 0x2 & ( (1 << vci_param::E) - 1); // Write OK 4479 p_vci_tgt.reop = true; 4480 break; 4481 } 4482 case TGT_REQ_BROADCAST: 4483 case TGT_REQ_ICACHE: 4484 case TGT_REQ_DCACHE: 4485 p_vci_tgt.cmdack = false; 4486 p_vci_tgt.rspval = false; 4487 break; 4488 4489 } // end switch TGT_FSM 2791 4490 } // end genMoore() 2792 4491 2793 4492 ////////////////////////////////////////////////////////////////////////////////// 2794 4493 tmpl(void)::stop_simulation (uint32_t nb_frz_cycles) … … 2796 4495 { 2797 4496 #if CC_XCACHE_WRAPPER_STOP_SIMULATION 2798 2799 2800 2801 2802 2803 2804 2805 2806 2807 2808 4497 if (nb_frz_cycles == 0) 4498 { 4499 PRINTF("CC_XCACHE_WRAPPER \"%s\" : don't stop the simulation.\n",name().c_str()); 4500 m_stop_simulation = false; 4501 } 4502 else 4503 { 4504 PRINTF("CC_XCACHE_WRAPPER \"%s\" : stop the simulation after %d cycles.\n",name().c_str(),nb_frz_cycles); 4505 m_stop_simulation = true; 4506 m_stop_simulation_nb_frz_cycles_max = nb_frz_cycles; 4507 } 2809 4508 #else 2810 4509 std::cout << "CC_XCACHE_WRAPPER \"" << name() << "\" : flag CC_XCACHE_WRAPPER_STOP_SIMULATION is unset, you can't use stop_simulation." << std::endl; 2811 4510 #endif // CC_XCACHE_WRAPPER_STOP_SIMULATION 2812 4511 2813 4512 } 2814 4513 2815 }} // end namespace 4514 ////////////////////////////////////////////////////////////////////////////////// 4515 tmpl(void)::log_transaction ( bool generate_file_icache 4516 ,bool generate_file_dcache 4517 ,bool generate_file_cmd 4518 ,bool generate_file_tgt 4519 ,bool generate_file_cleanup) 4520 ////////////////////////////////////////////////////////////////////////////////// 4521 { 4522 #if CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION 4523 generate_log_transaction_file_icache = generate_file_icache ; 4524 generate_log_transaction_file_dcache = generate_file_dcache ; 4525 generate_log_transaction_file_cmd = generate_file_cmd ; 4526 generate_log_transaction_file_tgt = generate_file_tgt ; 4527 generate_log_transaction_file_cleanup = generate_file_cleanup; 4528 #else 4529 std::cout << "CC_XCACHE_WRAPPER \"" << name() << "\" : flag CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION is unset, you can't use log_transaction." << std::endl; 4530 #endif // CC_XCACHE_WRAPPER_STOP_SIMULATION 4531 4532 } 4533 4534 ////////////////////////////////////////////////////////////////////////////////// 4535 tmpl(void)::vhdl_testbench (bool generate_file_mwbuf) 4536 ////////////////////////////////////////////////////////////////////////////////// 4537 { 4538 #if MWBUF_VHDL_TESTBENCH 4539 if (simulation_started) 4540 std::cout << "CC_XCACHE_WRAPPER \"" << name() << "\" : Simulation is starting, you can't use vhdl_testbench." << std::endl; 4541 else 4542 generate_vhdl_testbench_mwbuf = generate_file_mwbuf; 4543 #else 4544 std::cout << "CC_XCACHE_WRAPPER \"" << name() << "\" : flag MWBUF_VHDL_TESTBENCH is unset, you can't use vhdl_testbench." << std::endl; 4545 #endif // CC_XCACHE_WRAPPER_STOP_SIMULATION 4546 } 4547 4548 ////////////////////////////////////////////////////////////////////////////////// 4549 tmpl(uint32_t)::get_num_cache(addr_40 & addr) 4550 ////////////////////////////////////////////////////////////////////////////////// 4551 { 4552 uint32_t num_cache = get_num_cache_only(addr); 4553 4554 addr = ((addr&m_num_cache_LSB_mask) | // keep LSB 4555 ((addr>>m_num_cache_MSB)<<m_num_cache_LSB)); // set MSB 4556 4557 return num_cache; 4558 } 4559 4560 ////////////////////////////////////////////////////////////////////////////////// 4561 tmpl(uint32_t)::get_num_cache_only(addr_40 addr) 4562 ////////////////////////////////////////////////////////////////////////////////// 4563 { 4564 return (addr>>m_num_cache_LSB)&m_num_cache_mask; 4565 } 4566 4567 ////////////////////////////////////////////////////////////////////////////////// 4568 tmpl(void)::set_num_cache(addr_40 & addr, uint32_t num_cache) 4569 ////////////////////////////////////////////////////////////////////////////////// 4570 { 4571 addr = ((addr&m_num_cache_LSB_mask) | // keep LSB 4572 ((addr_40)num_cache << m_num_cache_LSB) | 4573 ((addr>>m_num_cache_LSB)<<m_num_cache_MSB)); // set MSB 4574 } 4575 4576 ////////////////////////////////////////////////////////////////////////////////// 4577 // FIXME : mettre le type addr_40 4578 tmpl(sc_dt::sc_uint<40>)::set_num_cache_only(addr_40 addr, uint32_t num_cache) 4579 ////////////////////////////////////////////////////////////////////////////////// 4580 { 4581 return ((addr&m_num_cache_LSB_mask) | // keep LSB 4582 ((addr_40)num_cache << m_num_cache_LSB) | 4583 ((addr>>m_num_cache_LSB)<<m_num_cache_MSB)); // set MSB 4584 } 4585 4586 4587 }} // end namespace 2816 4588 2817 4589 // Local Variables:
Note: See TracChangeset
for help on using the changeset viewer.