diff --git a/test/model/simulator/cclo_sim.cpp b/test/model/simulator/cclo_sim.cpp index e78dd735..887494f5 100644 --- a/test/model/simulator/cclo_sim.cpp +++ b/test/model/simulator/cclo_sim.cpp @@ -94,24 +94,55 @@ void control_read_fsm(XSI_DUT *dut, Stream &addr, Stream > &addr, Stream > &ret){ +void data_read_fsm(XSI_DUT *dut, Stream > &addr, Stream > &len, Stream > &ret){ static axi_fsm_state state = VALID_ADDR; + static ap_uint<64> curr_addr = 0; + static unsigned int curr_nbytes = 0; + static ap_uint<8> nbeats = 0; + unsigned int nbytes_to_4k_boundary, nbytes_this_transfer; switch(state){ case VALID_ADDR: - //set up bus to transfer one 64-byte word at a time - dut->write(datamem.arsize(), 6);//64B - dut->write(datamem.arlen(), 0);//one word - dut->write(datamem.arburst(), 1);//INCR if(!addr.IsEmpty()){ - dut->write<64>(datamem.araddr(), addr.Pop()); + curr_addr = addr.Pop(); + curr_nbytes = len.Pop(); + nbytes_to_4k_boundary = (curr_addr/4096+1)*4096 - curr_addr; + nbytes_this_transfer = std::min(nbytes_to_4k_boundary, curr_nbytes); + nbeats = (nbytes_this_transfer+63)/64;//number of 64B beats in transfer + logger << log_level::debug << "Read start addr=" << curr_addr << " len=" << nbytes_this_transfer << " (" << nbeats << ")" << endl; + //set up bus to transfer one 64-byte word at a time + dut->write(datamem.arsize(), 6);//64B + dut->write(datamem.arlen(), nbeats-1); + dut->write(datamem.arburst(), 1);//INCR + dut->write<64>(datamem.araddr(), curr_addr); dut->set(datamem.arvalid()); if(dut->test(datamem.arready())){ state = CLEAR_ADDR; } else { state = READY_ADDR; } + curr_addr += nbytes_this_transfer; + curr_nbytes -= nbytes_this_transfer; } return; + case CONTINUE_ADDR: + nbytes_to_4k_boundary = (curr_addr/4096+1)*4096 - curr_addr; + nbytes_this_transfer = std::min(nbytes_to_4k_boundary, curr_nbytes); + nbeats = (nbytes_this_transfer+63)/64;//number of 64B beats in transfer + logger << log_level::debug << "Read continue addr=" << curr_addr << " len=" << nbytes_this_transfer << " (" << nbeats << ")" << endl; + //set up bus to transfer one 64-byte word at a time + dut->write(datamem.arsize(), 6);//64B + dut->write(datamem.arlen(), nbeats-1); + dut->write(datamem.arburst(), 1);//INCR + dut->write<64>(datamem.araddr(), curr_addr); + dut->set(datamem.arvalid()); + if(dut->test(datamem.arready())){ + state = CLEAR_ADDR; + } else { + state = READY_ADDR; + } + curr_addr += nbytes_this_transfer; + curr_nbytes -= nbytes_this_transfer; + return; case READY_ADDR: if(dut->test(datamem.arready())){ state = CLEAR_ADDR; @@ -124,13 +155,20 @@ void data_read_fsm(XSI_DUT *dut, Stream > &addr, Stream return; case READY_DATA: if(dut->test(datamem.rvalid())){ + nbeats--; ret.Push(dut->read<512>(datamem.rdata())); - state = CLEAR_DATA; + if(nbeats == 0){ + state = CLEAR_DATA; + } } return; case CLEAR_DATA: dut->clear(datamem.rready()); - state = VALID_ADDR; + if(curr_nbytes == 0){ + state = VALID_ADDR; + } else { + state = CONTINUE_ADDR; + } return; } } @@ -201,17 +239,26 @@ void control_write_fsm(XSI_DUT *dut, Stream &addr, Stream > &addr, Stream > &val, Stream > &strb){ +void data_write_fsm(XSI_DUT *dut, Stream > &addr, Stream > &len, Stream > &val, Stream > &strb){ static axi_fsm_state state = VALID_ADDR; + static ap_uint<64> curr_addr = 0; + static unsigned int curr_nbytes = 0; + static ap_uint<8> nbeats = 0; + unsigned int nbytes_to_4k_boundary, nbytes_this_transfer; switch(state){ case VALID_ADDR: - dut->write(datamem.awsize(), 6);//64B width - dut->write(datamem.awlen(), 0);//one word - dut->write(datamem.awburst(), 1);//INCR - dut->write(datamem.wlast(), 1);//always last transfer //set awaddr = addr if(!addr.IsEmpty()){ - dut->write<64>(datamem.awaddr(), addr.Pop()); + curr_addr = addr.Pop(); + curr_nbytes = len.Pop(); + nbytes_to_4k_boundary = (curr_addr/4096+1)*4096 - curr_addr; + nbytes_this_transfer = std::min(nbytes_to_4k_boundary, curr_nbytes); + nbeats = (nbytes_this_transfer+63)/64;//number of 64B beats in transfer + logger << log_level::debug << "Write start addr=" << curr_addr << " len=" << nbytes_this_transfer << " (" << nbeats << ")" << endl; + dut->write(datamem.awsize(), 6);//64B width + dut->write(datamem.awlen(), nbeats-1); + dut->write(datamem.awburst(), 1);//INCR + dut->write<64>(datamem.awaddr(), curr_addr); //set awvalid = 1 dut->set(datamem.awvalid()); if(dut->test(datamem.awready())){ @@ -219,7 +266,28 @@ void data_write_fsm(XSI_DUT *dut, Stream > &addr, Streamwrite(datamem.awsize(), 6);//64B width + dut->write(datamem.awlen(), nbeats-1); + dut->write(datamem.awburst(), 1);//INCR + dut->write<64>(datamem.awaddr(), curr_addr); + //set awvalid = 1 + dut->set(datamem.awvalid()); + if(dut->test(datamem.awready())){ + state = CLEAR_ADDR; + } else{ + state = READY_ADDR; } + curr_addr += nbytes_this_transfer; + curr_nbytes -= nbytes_this_transfer; return; case READY_ADDR: if(dut->test(datamem.awready())){ @@ -234,10 +302,16 @@ void data_write_fsm(XSI_DUT *dut, Stream > &addr, Streamwrite<512>(datamem.wdata(), val.Pop()); dut->write<64>(datamem.wstrb(), strb.Pop()); + dut->write(datamem.wlast(), nbeats==1); //set wvalid = 1 dut->set(datamem.wvalid()); if(dut->test(datamem.wready())){ - state = CLEAR_DATA; + nbeats--; + if(nbeats != 0){ + state = UPDATE_DATA; + } else { + state = CLEAR_DATA; + } } else{ state = READY_DATA; } @@ -245,7 +319,29 @@ void data_write_fsm(XSI_DUT *dut, Stream > &addr, Streamtest(datamem.wready())){ - state = CLEAR_DATA; + nbeats--; + if(nbeats != 0){ + state = UPDATE_DATA; + } else { + state = CLEAR_DATA; + } + } + return; + case UPDATE_DATA: + if(!val.IsEmpty() && !strb.IsEmpty()){ + dut->write<512>(datamem.wdata(), val.Pop()); + dut->write<64>(datamem.wstrb(), strb.Pop()); + dut->write(datamem.wlast(), nbeats==1); + if(dut->test(datamem.wready())){ + nbeats--; + if(nbeats != 0){ + state = UPDATE_DATA; + } else { + state = CLEAR_DATA; + } + } else{ + state = READY_DATA; + } } return; case CLEAR_DATA: @@ -267,7 +363,11 @@ void data_write_fsm(XSI_DUT *dut, Stream > &addr, Streamclear(datamem.bready()); - state = VALID_ADDR; + if(curr_nbytes == 0){ + state = VALID_ADDR; + } else { + state = CONTINUE_ADDR; + } return; } } @@ -420,8 +520,8 @@ void krnl_egress_fsm(XSI_DUT *dut, Stream &val){ void interface_handler(XSI_DUT *dut, Stream &axilite_rd_addr, Stream &axilite_rd_data, Stream &axilite_wr_addr, Stream &axilite_wr_data, - Stream > &aximm_rd_addr, Stream > &aximm_rd_data, - Stream > &aximm_wr_addr, Stream > &aximm_wr_data, Stream > &aximm_wr_strb, + Stream > &aximm_rd_addr, Stream > &aximm_rd_len, Stream > &aximm_rd_data, + Stream > &aximm_wr_addr, Stream > &aximm_wr_len, Stream > &aximm_wr_data, Stream > &aximm_wr_strb, Stream &callreq, Stream &callack, Stream ð_tx_data, Stream ð_rx_data, Stream &cclo_to_krnl_data, Stream &krnl_to_cclo_data){ @@ -430,8 +530,8 @@ void interface_handler(XSI_DUT *dut, Stream &axilite_rd_addr, Stre dut->run_ncycles(1); control_read_fsm(dut, axilite_rd_addr, axilite_rd_data); control_write_fsm(dut, axilite_wr_addr, axilite_wr_data); - data_read_fsm(dut, aximm_rd_addr, aximm_rd_data); - data_write_fsm(dut, aximm_wr_addr, aximm_wr_data, aximm_wr_strb); + data_read_fsm(dut, aximm_rd_addr, aximm_rd_len, aximm_rd_data); + data_write_fsm(dut, aximm_wr_addr, aximm_wr_len, aximm_wr_data, aximm_wr_strb); call_req_fsm(dut, callreq); call_ack_fsm(dut, callack); eth_ingress_fsm(dut, eth_rx_data); @@ -522,8 +622,10 @@ int main(int argc, char **argv) Stream axilite_wr_addr; Stream axilite_wr_data; Stream > aximm_rd_addr; + Stream > aximm_rd_len; Stream > aximm_rd_data; Stream > aximm_wr_addr; + Stream > aximm_wr_len; Stream > aximm_wr_data; Stream > aximm_wr_strb; Stream callreq; //need some capacity for all args @@ -552,16 +654,16 @@ int main(int argc, char **argv) HLSLIB_DATAFLOW_FUNCTION(interface_handler, &dut, axilite_rd_addr, axilite_rd_data, axilite_wr_addr, axilite_wr_data, - aximm_rd_addr, aximm_rd_data, - aximm_wr_addr, aximm_wr_data, aximm_wr_strb, + aximm_rd_addr, aximm_rd_len, aximm_rd_data, + aximm_wr_addr, aximm_wr_len, aximm_wr_data, aximm_wr_strb, callreq, callack, eth_tx_data, eth_rx_data, cclo_to_krnl_data, krnl_to_cclo_data); HLSLIB_DATAFLOW_FUNCTION(zmq_cmd_server, &ctx, axilite_rd_addr, axilite_rd_data, axilite_wr_addr, axilite_wr_data, - aximm_rd_addr, aximm_rd_data, - aximm_wr_addr, aximm_wr_data, aximm_wr_strb, + aximm_rd_addr, aximm_rd_len, aximm_rd_data, + aximm_wr_addr, aximm_wr_len, aximm_wr_data, aximm_wr_strb, callreq, callack); //ZMQ to other nodes process(es) HLSLIB_DATAFLOW_FUNCTION(zmq_eth_egress_server, &ctx, eth_tx_data, local_rank); diff --git a/test/model/simulator/cclo_sim.h b/test/model/simulator/cclo_sim.h index 2c95076f..b0c1909a 100644 --- a/test/model/simulator/cclo_sim.h +++ b/test/model/simulator/cclo_sim.h @@ -15,7 +15,7 @@ # # *******************************************************************************/ -enum axi_fsm_state {VALID_ADDR, READY_ADDR, CLEAR_ADDR, VALID_DATA, READY_DATA, CLEAR_DATA, VALID_ACK, READY_ACK, CLEAR_ACK}; +enum axi_fsm_state {VALID_ADDR, CONTINUE_ADDR, READY_ADDR, CLEAR_ADDR, VALID_DATA, READY_DATA, UPDATE_DATA, CLEAR_DATA, VALID_ACK, READY_ACK, CLEAR_ACK}; struct axilite{ std::string basename = ""; diff --git a/test/model/zmq/zmq_server.cpp b/test/model/zmq/zmq_server.cpp index ee67668d..35677b60 100644 --- a/test/model/zmq/zmq_server.cpp +++ b/test/model/zmq/zmq_server.cpp @@ -414,8 +414,8 @@ void serve_zmq(zmq_intf_context *ctx, uint32_t *cfgmem, vector &devicemem, void serve_zmq(zmq_intf_context *ctx, Stream &axilite_rd_addr, Stream &axilite_rd_data, Stream &axilite_wr_addr, Stream &axilite_wr_data, - Stream > &aximm_rd_addr, Stream > &aximm_rd_data, - Stream > &aximm_wr_addr, Stream > &aximm_wr_data, Stream > &aximm_wr_strb, + Stream > &aximm_rd_addr, Stream > &aximm_rd_len, Stream > &aximm_rd_data, + Stream > &aximm_wr_addr, Stream > &aximm_wr_len, Stream > &aximm_wr_data, Stream > &aximm_wr_strb, Stream &callreq, Stream &callack){ Json::Reader reader; @@ -498,19 +498,17 @@ void serve_zmq(zmq_intf_context *ctx, response["rdata"][0] = 0; *logger << log_level::error << "Mem read outside available range ("<< ACCL_SIM_MEM_SIZE_KB << "KB) at addr: " << adr << " len: " << len << endl; } else { - for(int i=0; istop){ - if(!aximm_rd_data.IsEmpty()){ - mem_data = aximm_rd_data.Pop(); - break; - } else{ - this_thread::sleep_for(chrono::milliseconds(1)); + aximm_rd_addr.Push(adr); + aximm_rd_len.Push(len); + unsigned int idx = 0; + while(!ctx->stop && len>idx){ + if(!aximm_rd_data.IsEmpty()){ + mem_data = aximm_rd_data.Pop(); + for(int j=0; j<64 && len>idx; j++, idx++){ + response["rdata"][idx] = (unsigned int)mem_data(8*(j+1)-1, 8*j); } - } - for(int j=0; j<64 && (i+j)stop){ - if(!aximm_wr_addr.IsFull() && !aximm_wr_data.IsFull() && !aximm_wr_strb.IsFull()){ - aximm_wr_addr.Push(mem_addr); + if(!aximm_wr_data.IsFull() && !aximm_wr_strb.IsFull()){ aximm_wr_data.Push(mem_data); aximm_wr_strb.Push(mem_strb); break; @@ -681,16 +679,16 @@ void serve_zmq(zmq_intf_context *ctx, void zmq_cmd_server(zmq_intf_context *ctx, Stream &axilite_rd_addr, Stream &axilite_rd_data, Stream &axilite_wr_addr, Stream &axilite_wr_data, - Stream > &aximm_rd_addr, Stream > &aximm_rd_data, - Stream > &aximm_wr_addr, Stream > &aximm_wr_data, Stream > &aximm_wr_strb, + Stream > &aximm_rd_addr, Stream > &aximm_rd_len, Stream > &aximm_rd_data, + Stream > &aximm_wr_addr, Stream > &aximm_wr_len, Stream > &aximm_wr_data, Stream > &aximm_wr_strb, Stream &callreq, Stream &callack){ (*logger)("Starting ZMQ server\n", log_level::verbose); while(!ctx->stop){ serve_zmq(ctx, axilite_rd_addr, axilite_rd_data, axilite_wr_addr, axilite_wr_data, - aximm_rd_addr, aximm_rd_data, - aximm_wr_addr, aximm_wr_data, aximm_wr_strb, + aximm_rd_addr, aximm_rd_len, aximm_rd_data, + aximm_wr_addr, aximm_wr_len, aximm_wr_data, aximm_wr_strb, callreq, callack ); this_thread::sleep_for(chrono::milliseconds(10)); diff --git a/test/model/zmq/zmq_server.h b/test/model/zmq/zmq_server.h index b8106887..0cb02940 100644 --- a/test/model/zmq/zmq_server.h +++ b/test/model/zmq/zmq_server.h @@ -104,9 +104,11 @@ void krnl_endpoint_egress_port(zmq_intf_context *ctx, hlslib::Stream &axilite_rd_addr, hlslib::Stream &axilite_rd_data, hlslib::Stream &axilite_wr_addr, hlslib::Stream &axilite_wr_data, - hlslib::Stream > &aximm_rd_addr, hlslib::Stream > &aximm_rd_data, - hlslib::Stream > &aximm_wr_addr, hlslib::Stream > &aximm_wr_data, hlslib::Stream > &aximm_wr_strb, + hlslib::Stream > &aximm_rd_addr, hlslib::Stream > &aximm_rd_len, hlslib::Stream > &aximm_rd_data, + hlslib::Stream > &aximm_wr_addr, hlslib::Stream > &aximm_wr_len, hlslib::Stream > &aximm_wr_data, hlslib::Stream > &aximm_wr_strb, hlslib::Stream &callreq, hlslib::Stream &callack); /**