diff --git a/Bender.local b/Bender.local index dc33deb..015e66b 100644 --- a/Bender.local +++ b/Bender.local @@ -5,7 +5,7 @@ overrides: axi : { git: "https://github.com/pulp-platform/axi.git" , version: 0.39.5 } obi : { git: "https://github.com/pulp-platform/obi.git" , rev: 528dc65303d5ffb02fbc254324c6b53eac0dd6e5 } register_interface : { git: "https://github.com/pulp-platform/register_interface.git", rev: e25b36670ff7aab3402f40efcc2b11ee0f31cf19 } - idma : { git: "https://github.com/pulp-platform/iDMA.git" , rev: c12caf59bb482fe44b27361f6924ad346b2d22fe } + idma : { git: "https://github.com/pulp-platform/iDMA.git" , version: 0.6.5 } tech_cells_generic : { git: "https://github.com/pulp-platform/tech_cells_generic.git", version: 0.2.13 } cluster_icache : { git: "https://github.com/pulp-platform/cluster_icache.git" , rev: f88227d287251812b54c77fbfa608aa6dcd92b31 } axi_riscv_atomics : { git: "https://github.com/pulp-platform/axi_riscv_atomics.git" , version: 0.8.2 } \ No newline at end of file diff --git a/Bender.yml b/Bender.yml index d0196ab..2563093 100644 --- a/Bender.yml +++ b/Bender.yml @@ -28,7 +28,7 @@ dependencies: cv32e40x : { git: "https://github.com/pulp-platform/cv32e40x.git" , rev: a90101211048ba1a16cedbe4db963ab6e12569d7 } # branch: vi/redmule_scaleup cv32e40p : { git: "https://github.com/pulp-platform/cv32e40p.git" , rev: f5241403d5d65dbe1fffacd7035dd7ae1359c8ef } # branch: lb/magia_core spatz : { git: "https://github.com/pulp-platform/spatz.git" , rev: 9380883fd36a4794d7f31e2c22e3fed3202aeb81 } # branch: lb/magia-spatz_cc - idma : { git: "https://github.com/pulp-platform/iDMA.git" , rev: a6b190c7991331432afa9a2899d032bc1b176830 } # branch: vi/redmule_scaleup + idma : { git: "https://github.com/pulp-platform/iDMA.git" , version: 0.6.5 } hwpe-stream : { git: "https://github.com/pulp-platform/hwpe-stream.git" , version: 1.6 } hwpe-ctrl : { git: "https://github.com/pulp-platform/hwpe-ctrl.git" , version: 3.0.0 } hci : { git: "https://github.com/pulp-platform/hci.git" , version: 2.3.0 } diff --git a/hw/tile/idma_ctrl_mm.sv b/hw/tile/idma_ctrl_mm.sv index a1a8293..507c169 100644 --- a/hw/tile/idma_ctrl_mm.sv +++ b/hw/tile/idma_ctrl_mm.sv @@ -122,6 +122,9 @@ module idma_ctrl_mm .transfer_error_o ( a2o_transfer_error ) ); + idma_obi_req_t obi_read_req_converter; + idma_obi_rsp_t obi_read_rsp_converter; + // OBI2AXI Transfer Channel (L1 to L2) idma_axi_obi_transfer_ch #( .CHANNEL_T ( magia_tile_pkg::OBI2AXI ), @@ -141,14 +144,40 @@ module idma_ctrl_mm .cfg_rsp_o ( idma_fe_reg_obi2axi_rsp ), .axi_req_o ( axi_write_req_o ), .axi_rsp_i ( axi_write_rsp_i ), - .obi_req_o ( obi_read_req_o ), - .obi_rsp_i ( obi_read_rsp_i ), + .obi_req_o ( obi_read_req_converter ), + .obi_rsp_i ( obi_read_rsp_converter ), .transfer_busy_o ( o2a_transfer_busy ), .transfer_start_o ( o2a_transfer_start ), .transfer_done_o ( o2a_transfer_done ), .transfer_error_o ( o2a_transfer_error ) ); + + obi_rready_converter #( + .obi_a_chan_t(idma_obi_a_chan_t), + .obi_r_chan_t(idma_obi_r_chan_t), + .Depth(1) + ) obi_rready_converter_read_i ( + .clk_i ( clk_i ), + .rst_ni ( rst_ni ), + .test_mode_i ( test_en_i ), + .sbr_a_chan_i ( obi_read_req_converter.a ), + .req_i ( obi_read_req_converter.req ), + .gnt_o ( obi_read_rsp_converter.gnt ), + .rready_i ( obi_read_req_converter.rready ), + .sbr_r_chan_o ( obi_read_rsp_converter.r ), + .rvalid_o ( obi_read_rsp_converter.rvalid ), + .mgr_a_chan_o ( obi_read_req_o.a ), + .req_o ( obi_read_req_o.req ), + .mgr_r_chan_i ( obi_read_rsp_i.r ), + .gnt_i ( obi_read_rsp_i.gnt ), + .rvalid_i ( obi_read_rsp_i.rvalid ) + ); + // We are always ready for responses, because we don't + // send more requests than we can absorb in the fifo + assign obi_read_req_o.rready = 1'b1; + + /*******************************************************/ /** Memory-Mapped Bridge with IRQ Serialization **/ /*******************************************************/ diff --git a/sw/tests/eu_tests/idma_test_event_unit.c b/sw/tests/eu_tests/idma_test_event_unit.c index e53768b..7b9112f 100644 --- a/sw/tests/eu_tests/idma_test_event_unit.c +++ b/sw/tests/eu_tests/idma_test_event_unit.c @@ -95,12 +95,13 @@ int main(void) { printf("reps_3: 0x%8x\n", reps_3); #endif - uint32_t transfer_id_1 = idma_L2ToL1(src_addr, dst_addr, len); - printf("iDMA moving data from L2 to L1...\n"); - // Clear Event Unit and ensure A2O mask is enabled eu_clear_events(0xFFFFFFFF); eu_enable_events(EU_IDMA_A2O_DONE_MASK); + + printf("iDMA moving data from L2 to L1...\n"); + uint32_t transfer_id_1 = idma_L2ToL1(src_addr, dst_addr, len); + if (USE_WFE) { eu_idma_wait_a2o_completion(EU_WAIT_MODE_WFE); @@ -135,15 +136,15 @@ int main(void) { printf("src_std_3: 0x%8x\n", src_std_3); printf("reps_3: 0x%8x\n", reps_3); #endif - - uint32_t transfer_id_2 = idma_L1ToL2(src_addr, dst_addr, len); - - printf("iDMA moving data from L1 to L2...\n"); - + // Clear Event Unit and ensure O2A mask is enabled eu_clear_events(0xFFFFFFFF); eu_enable_events(EU_IDMA_O2A_DONE_MASK); + printf("iDMA moving data from L1 to L2...\n"); + uint32_t transfer_id_2 = idma_L1ToL2(src_addr, dst_addr, len); + + if (USE_WFE) { eu_idma_wait_o2a_completion(EU_WAIT_MODE_WFE); printf("Detected WFE...\n"); diff --git a/sw/tests/eu_tests/mesh_test_event_unit.c b/sw/tests/eu_tests/mesh_test_event_unit.c index 2bb26e6..514e0e9 100644 --- a/sw/tests/eu_tests/mesh_test_event_unit.c +++ b/sw/tests/eu_tests/mesh_test_event_unit.c @@ -81,12 +81,12 @@ void idma_mv_in_pure_eu(unsigned int x_dim, unsigned int y_dim, uint16_t src_dat printf("len: %0d\n", len); #endif - idma_L2ToL1(src_addr, dst_addr, len); - // Clear Event Unit and ensure A2O mask is enabled eu_clear_events(0xFFFFFFFF); eu_enable_events(EU_IDMA_A2O_DONE_MASK); + idma_L2ToL1(src_addr, dst_addr, len); + // Use PURE Event Unit eu_wait_mode_t wait_mode = USE_WFE ? EU_WAIT_MODE_WFE : EU_WAIT_MODE_POLLING; @@ -126,12 +126,12 @@ void idma_mv_out_pure_eu(unsigned int x_dim, unsigned int y_dim, uint32_t src_ad printf("len: %0d\n", len); #endif - idma_L1ToL2(src_addr, dst_addr, len); - // Clear Event Unit and ensure O2A mask is enabled eu_clear_events(0xFFFFFFFF); eu_enable_events(EU_IDMA_O2A_DONE_MASK); + idma_L1ToL2(src_addr, dst_addr, len); + // Use PURE Event Unit eu_wait_mode_t wait_mode = USE_WFE ? EU_WAIT_MODE_WFE : EU_WAIT_MODE_POLLING; diff --git a/sw/utils/idma_mm_utils.h b/sw/utils/idma_mm_utils.h index 558a024..31b6aa2 100644 --- a/sw/utils/idma_mm_utils.h +++ b/sw/utils/idma_mm_utils.h @@ -75,6 +75,8 @@ #define IDMA_CONF_DST_MAX_LLEN_SHIFT (7) #define IDMA_CONF_ENABLE_ND_MASK (0xC00) // bits 11:10 #define IDMA_CONF_ENABLE_ND_SHIFT (10) +#define IDMA_CONF_SRC_PROTOCOL (12) +#define IDMA_CONF_DST_PROTOCOL (15) // Status Register Bit Fields #define IDMA_STATUS_BUSY_MASK (0x3FF) // bits 9:0 @@ -121,7 +123,13 @@ static inline void idma_mm_conf_dir(uint32_t is_l1_to_l2, uint32_t decouple_aw, conf_val |= ((src_max_llen & 0x7) << IDMA_CONF_SRC_MAX_LLEN_SHIFT); conf_val |= ((dst_max_llen & 0x7) << IDMA_CONF_DST_MAX_LLEN_SHIFT); conf_val |= ((enable_nd & 0x3) << IDMA_CONF_ENABLE_ND_SHIFT); - + conf_val |= ((enable_nd & 0x3) << IDMA_CONF_ENABLE_ND_SHIFT); + + if (is_l1_to_l2) + conf_val |= (1 << IDMA_CONF_SRC_PROTOCOL); + else + conf_val |= (1 << IDMA_CONF_DST_PROTOCOL); + mmio32(IDMA_CONF_ADDR(is_l1_to_l2)) = conf_val; }