diff --git a/rtl/tb/include/hpdcache_test_mem_resp_model.h b/rtl/tb/include/hpdcache_test_mem_resp_model.h index 96dfbc0c..ac0dc4d6 100644 --- a/rtl/tb/include/hpdcache_test_mem_resp_model.h +++ b/rtl/tb/include/hpdcache_test_mem_resp_model.h @@ -30,6 +30,8 @@ #include "hpdcache_test_mem_resp_model_base.h" #include "logger.h" #include "mem_model.h" +#include "tlm.h" +#include "tlm_utils/peq_with_get.h" #include #include #include @@ -122,7 +124,8 @@ class hpdcache_test_mem_resp_model void readOperation() { hpdcache_test_transaction_mem_read_req req; - hpdcache_test_transaction_mem_read_resp resp; + hpdcache_test_transaction_mem_read_resp* resp = + new hpdcache_test_transaction_mem_read_resp(); // consume the request from the request ports req.addr = mem_req_read_addr_i.read().to_uint(); @@ -145,13 +148,14 @@ class hpdcache_test_mem_resp_model // response with the error flag asserted uint64_t addr = req.addr; uint64_t end_addr = addr + (1ULL << req.size); + sc_core::sc_time time = sc_core::sc_time(rd_valid_delay->read(), SC_NS); + rd_valid_delay->next(); if (within_error_region(addr, end_addr)) { - for (int i = 0; i < (req.len + 1); i++) { - resp.error = 1; - resp.id = req.id; - resp.last = (i == req.len); - while (!read_resp_fifo.nb_write(resp)) wait(); - } + resp->error = 1; + resp->id = req.id; + resp->last = true; + resp->len_data = req.len; + read_resp_peq.notify(*resp, time); return; } @@ -167,11 +171,12 @@ class hpdcache_test_mem_resp_model } for (int i = 0; i < (req.len + 1); i++) { + sc_bv tmp_data; for (int w = 0; w < words; w++) { uint64_t word_addr = (addr >> 3) + w; uint64_t ld_data = memory_m->readMemory(word_addr); uint64_t r = word_addr % MEM_NOC_DATA_WORDS; - resp.data.range((r + 1) * 64 - 1, r * 64) = ld_data; + tmp_data.range((r + 1) * 64 - 1, r * 64) = ld_data; #if DEBUG_HPDCACHE_TEST_MEM_RESP_MODEL if (check_verbosity(sc_core::SC_DEBUG)) { @@ -185,18 +190,22 @@ class hpdcache_test_mem_resp_model } // send response - resp.error = 0; - resp.id = req.id; - resp.last = (i == req.len); - while (!read_resp_fifo.nb_write(resp)) wait(); addr = ((addr >> 3) + words) << 3; + resp->my_data.push_back(tmp_data); } + resp->len_data = req.len; + resp->error = 0; + resp->id = req.id; + resp->last = true; + read_resp_peq.notify(*resp, time); } void writeOperation(hpdcache_test_transaction_mem_write_req req) { hpdcache_test_transaction_mem_write_resp resp; + sc_core::sc_time time = sc_core::sc_time(wb_valid_delay->read(), SC_NS); + wb_valid_delay->next(); unsigned int command = req.command; unsigned bytes = (1ULL << req.size); @@ -213,18 +222,25 @@ class hpdcache_test_mem_resp_model // response with the error flag asserted if (within_error_region(addr, end_addr)) { if (is_amo) { - hpdcache_test_transaction_mem_read_resp read_resp; - read_resp.data = 0; - read_resp.error = 0; - read_resp.id = req.id; - read_resp.last = true; - while (!read_resp_fifo.nb_write(read_resp)) wait(); + sc_core::sc_time time2 = sc_core::sc_time(rd_valid_delay->read(), SC_NS); + rd_valid_delay->next(); + hpdcache_test_transaction_mem_read_resp* read_resp = + new hpdcache_test_transaction_mem_read_resp(); + read_resp->data = 0; + read_resp->error = 0; + read_resp->id = req.id; + read_resp->last = true; + read_resp->len_data = 0; + read_resp_peq.notify(*read_resp, time2); } + hpdcache_test_transaction_mem_write_resp* resp_ptr = + new hpdcache_test_transaction_mem_write_resp(); resp.is_atomic = 0; resp.error = 1; resp.id = req.id; - while (!write_resp_fifo.nb_write(resp)) wait(); + *resp_ptr = resp; + write_resp_peq.notify(*resp_ptr, time); return; } @@ -302,13 +318,19 @@ class hpdcache_test_mem_resp_model // send the old data for AMO on the read response channel if (is_amo) { - hpdcache_test_transaction_mem_read_resp read_resp; - read_resp.data = 0; - read_resp.data.range((word + 1) * 64 - 1, word * 64) = ld_data; - read_resp.error = 0; - read_resp.id = req.id; - read_resp.last = true; - while (!read_resp_fifo.nb_write(read_resp)) wait(); + sc_core::sc_time time2 = sc_core::sc_time(rd_valid_delay->read(), SC_NS); + rd_valid_delay->next(); + hpdcache_test_transaction_mem_read_resp* read_resp = + new hpdcache_test_transaction_mem_read_resp(); + read_resp->data = 0; + sc_bv new_data; + new_data.range((word + 1) * 64 - 1, word * 64) = ld_data; + read_resp->my_data.push_back(new_data); + read_resp->error = 0; + read_resp->id = req.id; + read_resp->last = true; + read_resp->len_data = 0; + read_resp_peq.notify(*read_resp, time2); } } @@ -316,39 +338,59 @@ class hpdcache_test_mem_resp_model resp.is_atomic = req.is_stex() && excl_ok; resp.error = 0; resp.id = req.id; - while (!write_resp_fifo.nb_write(resp)) wait(); + hpdcache_test_transaction_mem_write_resp* resp_ptr = + new hpdcache_test_transaction_mem_write_resp(); + *resp_ptr = resp; + write_resp_peq.notify(*resp_ptr, time); } void read_response_process() { + mem_resp_read_valid_o.write(false); hpdcache_test_transaction_mem_read_resp read_resp; + hpdcache_test_transaction_mem_read_resp* tmp; - mem_resp_read_valid_o.write(false); for (;;) { - while (!read_resp_fifo.nb_read(read_resp)) wait(); - rd_valid_delay->next(); - for (int i = 0; i < rd_valid_delay->read(); i++) wait(); - sb_mem_read_resp_o.write(read_resp); // send response to scoreboard - mem_resp_read_valid_o.write(true); - mem_resp_read_error_o.write(read_resp.error); - mem_resp_read_id_o.write(read_resp.id); - mem_resp_read_data_o.write(read_resp.data); - mem_resp_read_last_o.write(read_resp.last); - do wait(); - while (!mem_resp_read_ready_i.read()); - mem_resp_read_valid_o.write(false); + while ((tmp = read_resp_peq.get_next_transaction()) == NULL) wait(); + read_resp = *tmp; + for (int i = 0; i < (read_resp.len_data + 1); i++) { + hpdcache_test_transaction_mem_read_resp read_resp_tmp; + read_resp_tmp.error = read_resp.error; + read_resp_tmp.data = 0; + read_resp_tmp.id = read_resp.id; + read_resp_tmp.last = (i == read_resp.len_data); + if (read_resp.my_data.size() > i) { + read_resp_tmp.data = read_resp.my_data.at(i); + } + sb_mem_read_resp_o.write(read_resp_tmp); // send response to scoreboard + mem_resp_read_valid_o.write(true); + mem_resp_read_error_o.write(read_resp_tmp.error); + mem_resp_read_id_o.write(read_resp_tmp.id); + mem_resp_read_data_o.write(read_resp_tmp.data); + mem_resp_read_last_o.write(read_resp_tmp.last); + do wait(); + while (!mem_resp_read_ready_i.read()); + mem_resp_read_valid_o.write(false); + between_valid_delay->next(); + if (i < read_resp.len_data) { + for (int j = 0; j < between_valid_delay->read(); j++) wait(); + between_valid_delay->next(); + } + } + delete tmp; } } void write_response_process() { - hpdcache_test_transaction_mem_write_resp resp; - mem_resp_write_valid_o.write(false); + hpdcache_test_transaction_mem_write_resp resp; + hpdcache_test_transaction_mem_write_resp* tmp; for (;;) { - while (!write_resp_fifo.nb_read(resp)) wait(); + while ((tmp = write_resp_peq.get_next_transaction()) == NULL) wait(); wb_valid_delay->next(); for (int i = 0; i < wb_valid_delay->read(); i++) wait(); + resp = *tmp; sb_mem_write_resp_o.write(resp); // send response to scoreboard mem_resp_write_valid_o.write(true); mem_resp_write_is_atomic_o.write(resp.is_atomic); @@ -357,6 +399,7 @@ class hpdcache_test_mem_resp_model do wait(); while (!mem_resp_write_ready_i.read()); mem_resp_write_valid_o.write(false); + delete tmp; } } diff --git a/rtl/tb/include/hpdcache_test_mem_resp_model_base.h b/rtl/tb/include/hpdcache_test_mem_resp_model_base.h index 5970db89..d8183248 100644 --- a/rtl/tb/include/hpdcache_test_mem_resp_model_base.h +++ b/rtl/tb/include/hpdcache_test_mem_resp_model_base.h @@ -29,6 +29,8 @@ #include "hpdcache_test_defs.h" #include "logger.h" #include "mem_model.h" +#include "tlm.h" +#include "tlm_utils/peq_with_get.h" #include #include #include @@ -112,16 +114,17 @@ class hpdcache_test_mem_resp_model_base } }; - sc_fifo read_resp_fifo; sc_fifo write_req_fifo; sc_fifo write_req_data_fifo; - sc_fifo write_resp_fifo; + tlm_utils::peq_with_get read_resp_peq; + tlm_utils::peq_with_get write_resp_peq; std::vector errorsegs; mem_model* memory_m; excl_reservation_buf_t excl_buf_m[1 << HPDCACHE_MEM_ID_WIDTH]; scv_smart_ptr ra_ready_delay; + scv_smart_ptr between_valid_delay; scv_smart_ptr rd_valid_delay; scv_smart_ptr wa_ready_delay; scv_smart_ptr wd_ready_delay; @@ -136,8 +139,8 @@ class hpdcache_test_mem_resp_model_base public: hpdcache_test_mem_resp_model_base(const std::string& nm) - : read_resp_fifo(2) - , write_resp_fifo(2) + : read_resp_peq("read") + , write_resp_peq("write") { std::string mem_model_name; mem_model_name = mem_model_name + "_" + nm; @@ -173,6 +176,10 @@ class hpdcache_test_mem_resp_model_base wb_delay_distribution.push(pair(3, 8), 90); wb_delay_distribution.push(pair(9, 64), 2); wb_valid_delay->set_mode(wb_delay_distribution); + + scv_bag> between_delay_distribution; + between_delay_distribution.push(pair(1, 10), 100); + between_valid_delay->set_mode(between_delay_distribution); } ~hpdcache_test_mem_resp_model_base() { delete memory_m; } @@ -212,6 +219,13 @@ class hpdcache_test_mem_resp_model_base wb_valid_delay->set_mode(dist); } + scv_smart_ptr get_between_valid_delay_distribution() { return between_valid_delay; } + + void set_between_valid_delay_distribution(scv_bag>& dist) + { + between_valid_delay->set_mode(dist); + } + scv_smart_ptr get_wb_valid_delay_distribution() { return wb_valid_delay; } bool within_region(uint64_t base0, uint64_t end0, uint64_t base1, uint64_t end1) diff --git a/rtl/tb/include/hpdcache_test_transaction.h b/rtl/tb/include/hpdcache_test_transaction.h index 65066f4b..01a917a4 100644 --- a/rtl/tb/include/hpdcache_test_transaction.h +++ b/rtl/tb/include/hpdcache_test_transaction.h @@ -518,6 +518,8 @@ class hpdcache_test_transaction_mem_read_resp uint32_t error; uint32_t id; sc_bv data; + std::vector> my_data; + uint32_t len_data; bool last; hpdcache_test_transaction_mem_read_resp() @@ -525,6 +527,8 @@ class hpdcache_test_transaction_mem_read_resp , id(0) , data(0) , last(false) + , len_data(0) + , my_data() { }