@@ -341,7 +341,7 @@ class xrt_sim::Impl {
341341 for (int b = 0 ; b < PLATFORM_MEMORY_BANKS ; ++b) {
342342 *m_axi_mem_[b].arready = 1 ;
343343 *m_axi_mem_[b].awready = 1 ;
344- *m_axi_mem_[b].wready = 0 ;
344+ *m_axi_mem_[b].wready = 1 ;
345345 }
346346 }
347347
@@ -426,6 +426,10 @@ class xrt_sim::Impl {
426426
427427 // write response
428428 *m_axi_mem_[b].bvalid = 0 ;
429+
430+ // states
431+ m_axi_states_[b].write_req_addr_ack = false ;
432+ m_axi_states_[b].write_req_data_ack = false ;
429433 }
430434 }
431435
@@ -479,7 +483,6 @@ class xrt_sim::Impl {
479483
480484 // handle read requests
481485 if (*m_axi_mem_[b].arvalid && *m_axi_mem_[b].arready ) {
482- // create read request
483486 auto mem_req = new mem_req_t ();
484487 mem_req->tag = *m_axi_mem_[b].arid ;
485488 mem_req->addr = uint64_t (*m_axi_mem_[b].araddr );
@@ -498,21 +501,32 @@ class xrt_sim::Impl {
498501 dram_queues_[b].push (mem_req);
499502 }
500503
504+ // handle write address requests
505+ if (*m_axi_mem_[b].awvalid && *m_axi_mem_[b].awready && !m_axi_states_[b].write_req_addr_ack ) {
506+ m_axi_states_[b].write_req_addr = *m_axi_mem_[b].awaddr ;
507+ m_axi_states_[b].write_req_tag = *m_axi_mem_[b].awid ;
508+ m_axi_states_[b].write_req_addr_ack = true ;
509+ }
510+
501511 // handle write data requests
502- if (*m_axi_mem_[b].wvalid && *m_axi_mem_[b].wready ) {
503- // ensure write address channel is not active
504- assert (!*m_axi_mem_[b].awvalid );
512+ if (*m_axi_mem_[b].wvalid && *m_axi_mem_[b].wready && !m_axi_states_[b].write_req_data_ack ) {
513+ m_axi_states_[b].write_req_byteen = *m_axi_mem_[b].wstrb ;
514+ auto data = (const uint8_t *)m_axi_mem_[b].wdata ->data ();
515+ for (int i = 0 ; i < PLATFORM_MEMORY_DATA_SIZE ; ++i) {
516+ m_axi_states_[b].write_req_data [i] = data[i];
517+ }
518+ m_axi_states_[b].write_req_data_ack = true ;
519+ }
505520
506- // capture write data
521+ // handle write requests
522+ if (m_axi_states_[b].write_req_addr_ack && m_axi_states_[b].write_req_data_ack ) {
523+ auto byteen = m_axi_states_[b].write_req_byteen ;
507524 auto byte_addr = m_axi_states_[b].write_req_addr ;
508- auto data = (const uint8_t *)m_axi_mem_[b].wdata ->data ();
509- auto byteen = *m_axi_mem_[b].wstrb ;
510525 for (int i = 0 ; i < PLATFORM_MEMORY_DATA_SIZE ; ++i) {
511526 if ((byteen >> i) & 0x1 ) {
512- (*ram_)[byte_addr + i] = data [i];
527+ (*ram_)[byte_addr + i] = m_axi_states_[b]. write_req_data [i];
513528 }
514529 }
515- // create write request
516530 auto mem_req = new mem_req_t ();
517531 mem_req->tag = m_axi_states_[b].write_req_tag ;
518532 mem_req->addr = byte_addr;
@@ -522,35 +536,29 @@ class xrt_sim::Impl {
522536
523537 /* printf("%0ld: [sim] axi-mem-write[%d]: addr=0x%lx, byteen=0x%lx, tag=0x%x, data=0x", timestamp, b, mem_req->addr, byteen, mem_req->tag);
524538 for (int i = PLATFORM_MEMORY_DATA_SIZE-1; i >= 0; --i) {
525- printf("%02x", data [i]]);
539+ printf("%02x", m_axi_states_[b].write_req_data [i]]);
526540 }
527541 printf("\n");*/
528542
529543 // send dram request
530544 dram_queues_[b].push (mem_req);
531545
532- // reset write request handshake
533- *m_axi_mem_[b].wready = 0 ;
534- *m_axi_mem_[b].awready = 1 ;
535- }
536-
537- // handle write address requests
538- if (*m_axi_mem_[b].awvalid && *m_axi_mem_[b].awready ) {
539- // capture write request address
540- m_axi_states_[b].write_req_addr = *m_axi_mem_[b].awaddr ;
541- m_axi_states_[b].write_req_tag = *m_axi_mem_[b].awid ;
542- // enable write data handshake
543- *m_axi_mem_[b].awready = 0 ;
544- *m_axi_mem_[b].wready = 1 ;
546+ // clear acks
547+ m_axi_states_[b].write_req_addr_ack = false ;
548+ m_axi_states_[b].write_req_data_ack = false ;
545549 }
546550 }
547551 }
548552
549553 typedef struct {
554+ std::array<uint8_t , PLATFORM_MEMORY_DATA_SIZE > write_req_data;
555+ uint64_t write_req_byteen;
550556 uint64_t write_req_addr;
551557 uint32_t write_req_tag;
552558 bool read_rsp_ready;
553559 bool write_rsp_ready;
560+ bool write_req_addr_ack;
561+ bool write_req_data_ack;
554562 } m_axi_state_t ;
555563
556564 typedef struct {
0 commit comments