From 527438a2ed9a5bd84d4dfb10d9081a547df81040 Mon Sep 17 00:00:00 2001 From: TommiTerza Date: Mon, 9 Sep 2024 16:41:18 +0200 Subject: [PATCH] v1 modifications to im2col --- hw/core-v-mini-mcu/core_v_mini_mcu.sv | 60 ++ .../im2col_spc/data/im2col_spc.hjson | 17 +- hw/ip_examples/im2col_spc/rtl/im2col_spc.sv | 145 +-- .../im2col_spc/rtl/im2col_spc_reg_pkg.sv | 286 +++--- .../im2col_spc/rtl/im2col_spc_reg_top.sv | 968 +++++++++--------- sw/applications/example_im2col/im2col_lib.h | 2 +- sw/device/lib/drivers/im2col_spc/im2col.c | 27 +- sw/device/lib/drivers/im2col_spc/im2col.h | 48 +- .../lib/drivers/im2col_spc/im2col_spc_regs.h | 5 +- 9 files changed, 834 insertions(+), 724 deletions(-) diff --git a/hw/core-v-mini-mcu/core_v_mini_mcu.sv b/hw/core-v-mini-mcu/core_v_mini_mcu.sv index bd5914725..973124c08 100644 --- a/hw/core-v-mini-mcu/core_v_mini_mcu.sv +++ b/hw/core-v-mini-mcu/core_v_mini_mcu.sv @@ -459,6 +459,66 @@ module core_v_mini_mcu assign memory_subsystem_banks_powergate_iso_n[1] = memory_subsystem_pwr_ctrl_out[1].isogate_en_n; assign memory_subsystem_banks_set_retentive_n[1] = memory_subsystem_pwr_ctrl_out[1].retentive_en_n; assign memory_subsystem_clkgate_en_n[1] = memory_subsystem_pwr_ctrl_out[1].clkgate_en_n; + assign memory_subsystem_banks_powergate_switch_n[2] = memory_subsystem_pwr_ctrl_out[2].pwrgate_en_n; + assign memory_subsystem_pwr_ctrl_in[2].pwrgate_ack_n = memory_subsystem_banks_powergate_switch_ack_n[2]; + //isogate exposed outside for UPF sim flow and switch cells + assign memory_subsystem_banks_powergate_iso_n[2] = memory_subsystem_pwr_ctrl_out[2].isogate_en_n; + assign memory_subsystem_banks_set_retentive_n[2] = memory_subsystem_pwr_ctrl_out[2].retentive_en_n; + assign memory_subsystem_clkgate_en_n[2] = memory_subsystem_pwr_ctrl_out[2].clkgate_en_n; + assign memory_subsystem_banks_powergate_switch_n[3] = memory_subsystem_pwr_ctrl_out[3].pwrgate_en_n; + assign memory_subsystem_pwr_ctrl_in[3].pwrgate_ack_n = memory_subsystem_banks_powergate_switch_ack_n[3]; + //isogate exposed outside for UPF sim flow and switch cells + assign memory_subsystem_banks_powergate_iso_n[3] = memory_subsystem_pwr_ctrl_out[3].isogate_en_n; + assign memory_subsystem_banks_set_retentive_n[3] = memory_subsystem_pwr_ctrl_out[3].retentive_en_n; + assign memory_subsystem_clkgate_en_n[3] = memory_subsystem_pwr_ctrl_out[3].clkgate_en_n; + assign memory_subsystem_banks_powergate_switch_n[4] = memory_subsystem_pwr_ctrl_out[4].pwrgate_en_n; + assign memory_subsystem_pwr_ctrl_in[4].pwrgate_ack_n = memory_subsystem_banks_powergate_switch_ack_n[4]; + //isogate exposed outside for UPF sim flow and switch cells + assign memory_subsystem_banks_powergate_iso_n[4] = memory_subsystem_pwr_ctrl_out[4].isogate_en_n; + assign memory_subsystem_banks_set_retentive_n[4] = memory_subsystem_pwr_ctrl_out[4].retentive_en_n; + assign memory_subsystem_clkgate_en_n[4] = memory_subsystem_pwr_ctrl_out[4].clkgate_en_n; + assign memory_subsystem_banks_powergate_switch_n[5] = memory_subsystem_pwr_ctrl_out[5].pwrgate_en_n; + assign memory_subsystem_pwr_ctrl_in[5].pwrgate_ack_n = memory_subsystem_banks_powergate_switch_ack_n[5]; + //isogate exposed outside for UPF sim flow and switch cells + assign memory_subsystem_banks_powergate_iso_n[5] = memory_subsystem_pwr_ctrl_out[5].isogate_en_n; + assign memory_subsystem_banks_set_retentive_n[5] = memory_subsystem_pwr_ctrl_out[5].retentive_en_n; + assign memory_subsystem_clkgate_en_n[5] = memory_subsystem_pwr_ctrl_out[5].clkgate_en_n; + assign memory_subsystem_banks_powergate_switch_n[6] = memory_subsystem_pwr_ctrl_out[6].pwrgate_en_n; + assign memory_subsystem_pwr_ctrl_in[6].pwrgate_ack_n = memory_subsystem_banks_powergate_switch_ack_n[6]; + //isogate exposed outside for UPF sim flow and switch cells + assign memory_subsystem_banks_powergate_iso_n[6] = memory_subsystem_pwr_ctrl_out[6].isogate_en_n; + assign memory_subsystem_banks_set_retentive_n[6] = memory_subsystem_pwr_ctrl_out[6].retentive_en_n; + assign memory_subsystem_clkgate_en_n[6] = memory_subsystem_pwr_ctrl_out[6].clkgate_en_n; + assign memory_subsystem_banks_powergate_switch_n[7] = memory_subsystem_pwr_ctrl_out[7].pwrgate_en_n; + assign memory_subsystem_pwr_ctrl_in[7].pwrgate_ack_n = memory_subsystem_banks_powergate_switch_ack_n[7]; + //isogate exposed outside for UPF sim flow and switch cells + assign memory_subsystem_banks_powergate_iso_n[7] = memory_subsystem_pwr_ctrl_out[7].isogate_en_n; + assign memory_subsystem_banks_set_retentive_n[7] = memory_subsystem_pwr_ctrl_out[7].retentive_en_n; + assign memory_subsystem_clkgate_en_n[7] = memory_subsystem_pwr_ctrl_out[7].clkgate_en_n; + assign memory_subsystem_banks_powergate_switch_n[8] = memory_subsystem_pwr_ctrl_out[8].pwrgate_en_n; + assign memory_subsystem_pwr_ctrl_in[8].pwrgate_ack_n = memory_subsystem_banks_powergate_switch_ack_n[8]; + //isogate exposed outside for UPF sim flow and switch cells + assign memory_subsystem_banks_powergate_iso_n[8] = memory_subsystem_pwr_ctrl_out[8].isogate_en_n; + assign memory_subsystem_banks_set_retentive_n[8] = memory_subsystem_pwr_ctrl_out[8].retentive_en_n; + assign memory_subsystem_clkgate_en_n[8] = memory_subsystem_pwr_ctrl_out[8].clkgate_en_n; + assign memory_subsystem_banks_powergate_switch_n[9] = memory_subsystem_pwr_ctrl_out[9].pwrgate_en_n; + assign memory_subsystem_pwr_ctrl_in[9].pwrgate_ack_n = memory_subsystem_banks_powergate_switch_ack_n[9]; + //isogate exposed outside for UPF sim flow and switch cells + assign memory_subsystem_banks_powergate_iso_n[9] = memory_subsystem_pwr_ctrl_out[9].isogate_en_n; + assign memory_subsystem_banks_set_retentive_n[9] = memory_subsystem_pwr_ctrl_out[9].retentive_en_n; + assign memory_subsystem_clkgate_en_n[9] = memory_subsystem_pwr_ctrl_out[9].clkgate_en_n; + assign memory_subsystem_banks_powergate_switch_n[10] = memory_subsystem_pwr_ctrl_out[10].pwrgate_en_n; + assign memory_subsystem_pwr_ctrl_in[10].pwrgate_ack_n = memory_subsystem_banks_powergate_switch_ack_n[10]; + //isogate exposed outside for UPF sim flow and switch cells + assign memory_subsystem_banks_powergate_iso_n[10] = memory_subsystem_pwr_ctrl_out[10].isogate_en_n; + assign memory_subsystem_banks_set_retentive_n[10] = memory_subsystem_pwr_ctrl_out[10].retentive_en_n; + assign memory_subsystem_clkgate_en_n[10] = memory_subsystem_pwr_ctrl_out[10].clkgate_en_n; + assign memory_subsystem_banks_powergate_switch_n[11] = memory_subsystem_pwr_ctrl_out[11].pwrgate_en_n; + assign memory_subsystem_pwr_ctrl_in[11].pwrgate_ack_n = memory_subsystem_banks_powergate_switch_ack_n[11]; + //isogate exposed outside for UPF sim flow and switch cells + assign memory_subsystem_banks_powergate_iso_n[11] = memory_subsystem_pwr_ctrl_out[11].isogate_en_n; + assign memory_subsystem_banks_set_retentive_n[11] = memory_subsystem_pwr_ctrl_out[11].retentive_en_n; + assign memory_subsystem_clkgate_en_n[11] = memory_subsystem_pwr_ctrl_out[11].clkgate_en_n; for (genvar i = 0; i < EXT_DOMAINS_RND; i = i + 1) begin assign external_subsystem_powergate_switch_no[i] = external_subsystem_pwr_ctrl_out[i].pwrgate_en_n; diff --git a/hw/ip_examples/im2col_spc/data/im2col_spc.hjson b/hw/ip_examples/im2col_spc/data/im2col_spc.hjson index 9a28bbd1a..95bbd0d05 100644 --- a/hw/ip_examples/im2col_spc/data/im2col_spc.hjson +++ b/hw/ip_examples/im2col_spc/data/im2col_spc.hjson @@ -87,7 +87,7 @@ swaccess: "rw", hwaccess: "hro", fields: [ - { bits: "7:0", name: "NUM", desc: "Number of patches" } + { bits: "15:0", name: "NUM", desc: "Number of patches" } ] }, { name: "N_PATCHES_H", @@ -95,7 +95,7 @@ swaccess: "rw", hwaccess: "hro", fields: [ - { bits: "7:0", name: "NUM", desc: "Number of patches" } + { bits: "15:0", name: "NUM", desc: "Number of patches" } ] }, { name: "ADPT_PAD_RIGHT", @@ -234,12 +234,21 @@ ] }, { name: "SPC_CH_MASK", - desc: '''Mask that defines which DMA channels the SPC can access''', + desc: '''Mask that defines which DMA channel the SPC can access''', swaccess: "rw", hwaccess: "hro", resval: 1, fields: [ - { bits: "31:0", name: "NUM", desc: "Number of DMA channels" } + { bits: "31:0", name: "MASK", desc: "Mask of DMA channel" } + ] + }, + { name: "SPC_CH_OFFSET", + desc: '''Offset of the DMA channel the SPC can access''', + swaccess: "rw", + hwaccess: "hro", + resval: 1, + fields: [ + { bits: "31:0", name: "OFF", desc: "Offset of DMA channels" } ] } ] diff --git a/hw/ip_examples/im2col_spc/rtl/im2col_spc.sv b/hw/ip_examples/im2col_spc/rtl/im2col_spc.sv index adb936e3f..25f491d49 100644 --- a/hw/ip_examples/im2col_spc/rtl/im2col_spc.sv +++ b/hw/ip_examples/im2col_spc/rtl/im2col_spc.sv @@ -72,15 +72,13 @@ module im2col_spc /* DMA interface unit signals */ logic im2col_param_done; - logic [DMA_CH_NUM-1:0] dma_if_channels; - logic [DMA_CH_NUM-1:0] dma_ch_first_write; - logic [(DMA_CH_NUM == 1) ? 0 : ($clog2(DMA_CH_NUM) - 1):0] dma_free_channel; - logic [(DMA_CH_NUM == 1) ? 0 : ($clog2(DMA_CH_NUM) - 1):0] dma_trans_free_channel; + logic dma_ch_free; + logic dma_ch_first_write; logic [31:0] dma_ch_en_mask; - logic dma_if_loaded; - logic dma_channels_full; + logic [31:0] dma_ch_offset; logic [31:0] dma_addr; logic [31:0] dma_wdata; + logic dma_if_loaded; logic dma_regintfc_start; logic dma_regintfc_done; @@ -205,7 +203,7 @@ module im2col_spc unique case (dma_if_cu_d) IDLE_IF_CU: begin - if (fifo_empty == 1'b0 && im2col_fsms_done == 1'b0 && dma_channels_full == 1'b0) begin + if (fifo_empty == 1'b0 && im2col_fsms_done == 1'b0 && dma_ch_free == 1'b1) begin dma_if_cu_q = GET_TRANSACTION; end else begin dma_if_cu_q = IDLE_IF_CU; @@ -213,7 +211,7 @@ module im2col_spc end GET_TRANSACTION: begin - if (fifo_empty == 1'b0 && dma_channels_full == 1'b0) begin + if (fifo_empty == 1'b0 && dma_ch_free == 1'b1) begin dma_if_cu_q = LOAD_TRANSACTION; end else begin dma_if_cu_q = IDLE_IF_CU; @@ -222,7 +220,7 @@ module im2col_spc LOAD_TRANSACTION: begin if (dma_if_loaded == 1'b1) begin - if (im2col_fsms_done == 1'b0 && dma_channels_full == 1'b0) begin + if (im2col_fsms_done == 1'b0 && dma_ch_free == 1'b1) begin dma_if_cu_q = GET_TRANSACTION; end else begin dma_if_cu_q = IDLE_IF_CU; @@ -251,8 +249,8 @@ module im2col_spc always_comb begin : proc_comb_dma_if_trans_load_fsm unique case (dma_if_cu_load_d) IDLE_IF_LOAD: begin - if (dma_if_cu_d == GET_TRANSACTION && im2col_fsms_done == 1'b0 && dma_channels_full == 1'b0) begin - if (dma_ch_first_write[dma_trans_free_channel] == 1'b0) begin + if (dma_if_cu_d == GET_TRANSACTION && im2col_fsms_done == 1'b0 && dma_ch_free == 1'b1) begin + if (dma_ch_first_write == 1'b0) begin dma_if_cu_load_q = WRITE_DIMENSIONALITY; end else begin dma_if_cu_load_q = WRITE_TOP_PAD; @@ -416,129 +414,97 @@ module im2col_spc WRITE_DIMENSIONALITY: begin dma_wdata = 32'h1; - dma_addr = core_v_mini_mcu_pkg::DMA_START_ADDRESS + - dma_trans_free_channel * core_v_mini_mcu_pkg::DMA_CH_SIZE + - {25'h0, dma_reg_pkg::DMA_DIM_CONFIG_OFFSET}; + dma_addr = dma_ch_offset + {25'h0, dma_reg_pkg::DMA_DIM_CONFIG_OFFSET}; dma_regintfc_start = 1'b1; end WRITE_SLOTS: begin dma_wdata = {reg2hw.slot.tx_trigger_slot.q, reg2hw.slot.rx_trigger_slot.q}; - dma_addr = core_v_mini_mcu_pkg::DMA_START_ADDRESS + - dma_trans_free_channel * core_v_mini_mcu_pkg::DMA_CH_SIZE + - {25'h0, dma_reg_pkg::DMA_SLOT_OFFSET}; + dma_addr = dma_ch_offset + {25'h0, dma_reg_pkg::DMA_SLOT_OFFSET}; dma_regintfc_start = 1'b1; end WRITE_SRC_DATATYPE: begin dma_wdata = {30'h0, reg2hw.data_type.q} & 32'h3; - dma_addr = core_v_mini_mcu_pkg::DMA_START_ADDRESS + - dma_trans_free_channel * core_v_mini_mcu_pkg::DMA_CH_SIZE + - {25'h0, dma_reg_pkg::DMA_SRC_DATA_TYPE_OFFSET}; + dma_addr = dma_ch_offset + {25'h0, dma_reg_pkg::DMA_SRC_DATA_TYPE_OFFSET}; dma_regintfc_start = 1'b1; end WRITE_DST_DATATYPE: begin dma_wdata = {30'h0, reg2hw.data_type.q} & 32'h3; - dma_addr = core_v_mini_mcu_pkg::DMA_START_ADDRESS + - dma_trans_free_channel * core_v_mini_mcu_pkg::DMA_CH_SIZE + - {25'h0, dma_reg_pkg::DMA_DST_DATA_TYPE_OFFSET}; + dma_addr = dma_ch_offset + {25'h0, dma_reg_pkg::DMA_DST_DATA_TYPE_OFFSET}; dma_regintfc_start = 1'b1; end WRITE_TOP_PAD: begin dma_wdata = {24'h0, fifo_output.n_zeros_top}; - dma_addr = core_v_mini_mcu_pkg::DMA_START_ADDRESS + - dma_trans_free_channel * core_v_mini_mcu_pkg::DMA_CH_SIZE + - {25'h0, dma_reg_pkg::DMA_PAD_TOP_OFFSET}; + dma_addr = dma_ch_offset + {25'h0, dma_reg_pkg::DMA_PAD_TOP_OFFSET}; dma_regintfc_start = 1'b1; end WRITE_BOTTOM_PAD: begin dma_wdata = {24'h0, fifo_output.n_zeros_bottom}; - dma_addr = core_v_mini_mcu_pkg::DMA_START_ADDRESS + - dma_trans_free_channel * core_v_mini_mcu_pkg::DMA_CH_SIZE + - {25'h0, dma_reg_pkg::DMA_PAD_BOTTOM_OFFSET}; + dma_addr = dma_ch_offset + {25'h0, dma_reg_pkg::DMA_PAD_BOTTOM_OFFSET}; dma_regintfc_start = 1'b1; end WRITE_LEFT_PAD: begin dma_wdata = {24'h0, fifo_output.n_zeros_left}; - dma_addr = core_v_mini_mcu_pkg::DMA_START_ADDRESS + - dma_trans_free_channel * core_v_mini_mcu_pkg::DMA_CH_SIZE + - {25'h0, dma_reg_pkg::DMA_PAD_LEFT_OFFSET}; + dma_addr = dma_ch_offset + {25'h0, dma_reg_pkg::DMA_PAD_LEFT_OFFSET}; dma_regintfc_start = 1'b1; end WRITE_RIGHT_PAD: begin dma_wdata = {24'h0, fifo_output.n_zeros_right}; - dma_addr = core_v_mini_mcu_pkg::DMA_START_ADDRESS + - dma_trans_free_channel * core_v_mini_mcu_pkg::DMA_CH_SIZE + - {25'h0, dma_reg_pkg::DMA_PAD_RIGHT_OFFSET}; + dma_addr = dma_ch_offset + {25'h0, dma_reg_pkg::DMA_PAD_RIGHT_OFFSET}; dma_regintfc_start = 1'b1; end WRITE_INPUT_PTR: begin dma_wdata = fifo_output.input_ptr; - dma_addr = core_v_mini_mcu_pkg::DMA_START_ADDRESS + - dma_trans_free_channel * core_v_mini_mcu_pkg::DMA_CH_SIZE + - {25'h0, dma_reg_pkg::DMA_SRC_PTR_OFFSET}; + dma_addr = dma_ch_offset + {25'h0, dma_reg_pkg::DMA_SRC_PTR_OFFSET}; dma_regintfc_start = 1'b1; end WRITE_OUTPUT_PTR: begin dma_wdata = fifo_output.output_ptr; - dma_addr = core_v_mini_mcu_pkg::DMA_START_ADDRESS + - dma_trans_free_channel * core_v_mini_mcu_pkg::DMA_CH_SIZE + - {25'h0, dma_reg_pkg::DMA_DST_PTR_OFFSET}; + dma_addr = dma_ch_offset + {25'h0, dma_reg_pkg::DMA_DST_PTR_OFFSET}; dma_regintfc_start = 1'b1; end WRITE_INC_SRC_D1: begin dma_wdata = (1 << {28'h0, reg2hw.log_strides_d1.q}) << (2 - reg2hw.data_type.q) & 32'h3f; - dma_addr = core_v_mini_mcu_pkg::DMA_START_ADDRESS + - dma_trans_free_channel * core_v_mini_mcu_pkg::DMA_CH_SIZE + - {25'h0, dma_reg_pkg::DMA_SRC_PTR_INC_D1_OFFSET}; + dma_addr = dma_ch_offset + {25'h0, dma_reg_pkg::DMA_SRC_PTR_INC_D1_OFFSET}; dma_regintfc_start = 1'b1; end WRITE_INC_SRC_D2: begin dma_wdata = {9'h0, fifo_output.in_inc_d2} << (2 - reg2hw.data_type.q) & 32'h7fffff; - dma_addr = core_v_mini_mcu_pkg::DMA_START_ADDRESS + - dma_trans_free_channel * core_v_mini_mcu_pkg::DMA_CH_SIZE + - {25'h0, dma_reg_pkg::DMA_SRC_PTR_INC_D2_OFFSET}; + dma_addr = dma_ch_offset + {25'h0, dma_reg_pkg::DMA_SRC_PTR_INC_D2_OFFSET}; dma_regintfc_start = 1'b1; end WRITE_INC_DST_D1: begin dma_wdata = (4 >> reg2hw.data_type.q) & 32'h3f; - dma_addr = core_v_mini_mcu_pkg::DMA_START_ADDRESS + - dma_trans_free_channel * core_v_mini_mcu_pkg::DMA_CH_SIZE + - {25'h0, dma_reg_pkg::DMA_DST_PTR_INC_D1_OFFSET}; + dma_addr = dma_ch_offset + {25'h0, dma_reg_pkg::DMA_DST_PTR_INC_D1_OFFSET}; dma_regintfc_start = 1'b1; end WRITE_INC_DST_D2: begin dma_wdata = (4 >> reg2hw.data_type.q) & 32'h7fffff; - dma_addr = core_v_mini_mcu_pkg::DMA_START_ADDRESS + - dma_trans_free_channel * core_v_mini_mcu_pkg::DMA_CH_SIZE + - {25'h0, dma_reg_pkg::DMA_DST_PTR_INC_D2_OFFSET}; + dma_addr = dma_ch_offset + {25'h0, dma_reg_pkg::DMA_DST_PTR_INC_D2_OFFSET}; dma_regintfc_start = 1'b1; end WRITE_SIZE_D2: begin dma_wdata = {16'h0, fifo_output.size_du_d2}; - dma_addr = core_v_mini_mcu_pkg::DMA_START_ADDRESS + - dma_trans_free_channel * core_v_mini_mcu_pkg::DMA_CH_SIZE + - {25'h0, dma_reg_pkg::DMA_SIZE_D2_OFFSET}; + dma_addr = dma_ch_offset + {25'h0, dma_reg_pkg::DMA_SIZE_D2_OFFSET}; dma_regintfc_start = 1'b1; end WRITE_SIZE_D1: begin dma_wdata = {16'h0, fifo_output.size_du_d1}; - dma_addr = core_v_mini_mcu_pkg::DMA_START_ADDRESS + - dma_trans_free_channel * core_v_mini_mcu_pkg::DMA_CH_SIZE + - {25'h0, dma_reg_pkg::DMA_SIZE_D1_OFFSET}; + dma_addr = dma_ch_offset + {25'h0, dma_reg_pkg::DMA_SIZE_D1_OFFSET}; dma_regintfc_start = 1'b1; end @@ -558,51 +524,20 @@ module im2col_spc end end - /* Free channel finder */ - always_comb begin : proc_comb_free_channel - dma_free_channel = 0; - for (int i = 0; i < DMA_CH_NUM; i = i + 1) begin - if (dma_if_channels[i] == 1'b0 && dma_ch_en_mask[i] == 1'b1) begin - dma_free_channel = i[(DMA_CH_NUM==1)?0 : ($clog2(DMA_CH_NUM)-1):0]; - break; - end - end - end - /* Channel tracker */ always_ff @(posedge clk_i, negedge rst_ni) begin : proc_ff_control_unit if (!rst_ni) begin - dma_trans_free_channel <= 0; - for (int i = 0; i < DMA_CH_NUM; i = i + 1) begin - dma_if_channels[i] <= 1'b0; - dma_ch_first_write[i] <= 1'b0; - end + dma_ch_free <= 1'b1; end else begin - /* Reset everything with im2col start */ - if (im2col_start == 1'b1) begin - dma_trans_free_channel <= 0; - for (int i = 0; i < DMA_CH_NUM; i = i + 1) begin - dma_if_channels[i] <= 1'b0; - dma_ch_first_write[i] <= 1'b0; - end - end - - /* If an occupied channel asserts a done signal, free it up */ - for (int i = 0; i < DMA_CH_NUM; i = i + 1) begin - if (dma_if_channels[i] == 1'b1 && dma_done_i[i] == 1'b1) begin - dma_if_channels[i] <= 1'b0; - end + /* Set the dma_ch_free when im2col starts or when a transaction is finished */ + if ((im2col_start == 1'b1) | (|(dma_ch_en_mask[core_v_mini_mcu_pkg::DMA_CH_NUM-1:0] & dma_done_i)) == 1'b1) begin + dma_ch_free <= 1'b1; end - /* If a transaction has to take place, occupy the free channel */ - if (dma_if_cu_q == GET_TRANSACTION) begin - dma_trans_free_channel <= dma_free_channel; - end - - /* Allocate a channel only if the next state won't be the IDLE state */ + /* Clear the ch free flag only if the next state won't be the IDLE state */ if (dma_if_cu_d == GET_TRANSACTION && dma_if_cu_q != IDLE_IF_CU) begin - dma_if_channels[dma_trans_free_channel] <= 1'b1; - dma_ch_first_write[dma_trans_free_channel] <= 1'b1; + dma_ch_first_write <= 1'b1; + dma_ch_free <= 1'b0; end end end @@ -616,17 +551,6 @@ module im2col_spc end end - /* Channels full flag logic */ - always_comb begin : proc_comb_channels_full - dma_channels_full = 1'b1; - for (int i = 0; i < DMA_CH_NUM; i = i + 1) begin - if (dma_if_channels[i] == 1'b0 && dma_ch_en_mask[i] == 1'b1) begin - dma_channels_full = 1'b0; - break; - end - end - end - /* Transaction IFR update */ always_ff @(posedge clk_i, negedge rst_ni) begin : proc_ff_spc_ifr if (~rst_ni) begin @@ -660,7 +584,7 @@ module im2col_spc if (!rst_ni) begin im2col_done <= 1'b0; end else begin - if (im2col_fsms_done == 1'b1 && |dma_if_channels == 1'b0) begin + if (im2col_fsms_done == 1'b1 && dma_ch_free == 1'b1) begin im2col_done <= 1'b1; end else begin im2col_done <= 1'b0; @@ -685,4 +609,7 @@ module im2col_spc /* DMA channels mask register */ assign dma_ch_en_mask = reg2hw.spc_ch_mask.q; + /* DMA channel offset */ + assign dma_ch_offset = reg2hw.spc_ch_offset.q; + endmodule diff --git a/hw/ip_examples/im2col_spc/rtl/im2col_spc_reg_pkg.sv b/hw/ip_examples/im2col_spc/rtl/im2col_spc_reg_pkg.sv index a477e413b..ad6862425 100644 --- a/hw/ip_examples/im2col_spc/rtl/im2col_spc_reg_pkg.sv +++ b/hw/ip_examples/im2col_spc/rtl/im2col_spc_reg_pkg.sv @@ -13,151 +13,199 @@ package im2col_spc_reg_pkg; // Typedefs for registers // //////////////////////////// - typedef struct packed {logic [31:0] q;} im2col_spc_reg2hw_src_ptr_reg_t; + typedef struct packed { + logic [31:0] q; + } im2col_spc_reg2hw_src_ptr_reg_t; - typedef struct packed {logic [31:0] q;} im2col_spc_reg2hw_dst_ptr_reg_t; + typedef struct packed { + logic [31:0] q; + } im2col_spc_reg2hw_dst_ptr_reg_t; - typedef struct packed {logic [31:0] q;} im2col_spc_reg2hw_iw_reg_t; + typedef struct packed { + logic [31:0] q; + } im2col_spc_reg2hw_iw_reg_t; - typedef struct packed {logic [31:0] q;} im2col_spc_reg2hw_ih_reg_t; + typedef struct packed { + logic [31:0] q; + } im2col_spc_reg2hw_ih_reg_t; - typedef struct packed {logic [7:0] q;} im2col_spc_reg2hw_fw_reg_t; + typedef struct packed { + logic [7:0] q; + } im2col_spc_reg2hw_fw_reg_t; - typedef struct packed {logic [7:0] q;} im2col_spc_reg2hw_fh_reg_t; + typedef struct packed { + logic [7:0] q; + } im2col_spc_reg2hw_fh_reg_t; - typedef struct packed {logic [7:0] q;} im2col_spc_reg2hw_batch_reg_t; + typedef struct packed { + logic [7:0] q; + } im2col_spc_reg2hw_batch_reg_t; typedef struct packed { - logic [7:0] q; - logic qe; + logic [7:0] q; + logic qe; } im2col_spc_reg2hw_num_ch_reg_t; - typedef struct packed {logic [15:0] q;} im2col_spc_reg2hw_ch_col_reg_t; + typedef struct packed { + logic [15:0] q; + } im2col_spc_reg2hw_ch_col_reg_t; - typedef struct packed {logic [15:0] q;} im2col_spc_reg2hw_n_patches_w_reg_t; + typedef struct packed { + logic [15:0] q; + } im2col_spc_reg2hw_n_patches_w_reg_t; - typedef struct packed {logic [15:0] q;} im2col_spc_reg2hw_n_patches_h_reg_t; + typedef struct packed { + logic [15:0] q; + } im2col_spc_reg2hw_n_patches_h_reg_t; - typedef struct packed {logic [7:0] q;} im2col_spc_reg2hw_adpt_pad_right_reg_t; + typedef struct packed { + logic [7:0] q; + } im2col_spc_reg2hw_adpt_pad_right_reg_t; - typedef struct packed {logic [7:0] q;} im2col_spc_reg2hw_adpt_pad_bottom_reg_t; + typedef struct packed { + logic [7:0] q; + } im2col_spc_reg2hw_adpt_pad_bottom_reg_t; - typedef struct packed {logic [3:0] q;} im2col_spc_reg2hw_log_strides_d1_reg_t; + typedef struct packed { + logic [3:0] q; + } im2col_spc_reg2hw_log_strides_d1_reg_t; - typedef struct packed {logic [3:0] q;} im2col_spc_reg2hw_log_strides_d2_reg_t; + typedef struct packed { + logic [3:0] q; + } im2col_spc_reg2hw_log_strides_d2_reg_t; typedef struct packed { - logic q; - logic re; + logic q; + logic re; } im2col_spc_reg2hw_status_reg_t; typedef struct packed { - struct packed {logic [15:0] q;} rx_trigger_slot; - struct packed {logic [15:0] q;} tx_trigger_slot; + struct packed { + logic [15:0] q; + } rx_trigger_slot; + struct packed { + logic [15:0] q; + } tx_trigger_slot; } im2col_spc_reg2hw_slot_reg_t; - typedef struct packed {logic [1:0] q;} im2col_spc_reg2hw_data_type_reg_t; + typedef struct packed { + logic [1:0] q; + } im2col_spc_reg2hw_data_type_reg_t; typedef struct packed { - logic [5:0] q; - logic qe; + logic [5:0] q; + logic qe; } im2col_spc_reg2hw_pad_top_reg_t; typedef struct packed { - logic [5:0] q; - logic qe; + logic [5:0] q; + logic qe; } im2col_spc_reg2hw_pad_bottom_reg_t; typedef struct packed { - logic [5:0] q; - logic qe; + logic [5:0] q; + logic qe; } im2col_spc_reg2hw_pad_right_reg_t; typedef struct packed { - logic [5:0] q; - logic qe; + logic [5:0] q; + logic qe; } im2col_spc_reg2hw_pad_left_reg_t; - typedef struct packed {logic q;} im2col_spc_reg2hw_interrupt_en_reg_t; + typedef struct packed { + logic q; + } im2col_spc_reg2hw_interrupt_en_reg_t; typedef struct packed { - logic q; - logic re; + logic q; + logic re; } im2col_spc_reg2hw_spc_ifr_reg_t; - typedef struct packed {logic [31:0] q;} im2col_spc_reg2hw_spc_ch_mask_reg_t; + typedef struct packed { + logic [31:0] q; + } im2col_spc_reg2hw_spc_ch_mask_reg_t; - typedef struct packed {logic d;} im2col_spc_hw2reg_status_reg_t; + typedef struct packed { + logic [31:0] q; + } im2col_spc_reg2hw_spc_ch_offset_reg_t; - typedef struct packed {logic d;} im2col_spc_hw2reg_spc_ifr_reg_t; + typedef struct packed { + logic d; + } im2col_spc_hw2reg_status_reg_t; + + typedef struct packed { + logic d; + } im2col_spc_hw2reg_spc_ifr_reg_t; // Register -> HW type typedef struct packed { - im2col_spc_reg2hw_src_ptr_reg_t src_ptr; // [331:300] - im2col_spc_reg2hw_dst_ptr_reg_t dst_ptr; // [299:268] - im2col_spc_reg2hw_iw_reg_t iw; // [267:236] - im2col_spc_reg2hw_ih_reg_t ih; // [235:204] - im2col_spc_reg2hw_fw_reg_t fw; // [203:196] - im2col_spc_reg2hw_fh_reg_t fh; // [195:188] - im2col_spc_reg2hw_batch_reg_t batch; // [187:180] - im2col_spc_reg2hw_num_ch_reg_t num_ch; // [179:171] - im2col_spc_reg2hw_ch_col_reg_t ch_col; // [170:155] - im2col_spc_reg2hw_n_patches_w_reg_t n_patches_w; // [154:139] - im2col_spc_reg2hw_n_patches_h_reg_t n_patches_h; // [138:123] - im2col_spc_reg2hw_adpt_pad_right_reg_t adpt_pad_right; // [122:115] - im2col_spc_reg2hw_adpt_pad_bottom_reg_t adpt_pad_bottom; // [114:107] - im2col_spc_reg2hw_log_strides_d1_reg_t log_strides_d1; // [106:103] - im2col_spc_reg2hw_log_strides_d2_reg_t log_strides_d2; // [102:99] - im2col_spc_reg2hw_status_reg_t status; // [98:97] - im2col_spc_reg2hw_slot_reg_t slot; // [96:65] - im2col_spc_reg2hw_data_type_reg_t data_type; // [64:63] - im2col_spc_reg2hw_pad_top_reg_t pad_top; // [62:56] - im2col_spc_reg2hw_pad_bottom_reg_t pad_bottom; // [55:49] - im2col_spc_reg2hw_pad_right_reg_t pad_right; // [48:42] - im2col_spc_reg2hw_pad_left_reg_t pad_left; // [41:35] - im2col_spc_reg2hw_interrupt_en_reg_t interrupt_en; // [34:34] - im2col_spc_reg2hw_spc_ifr_reg_t spc_ifr; // [33:32] - im2col_spc_reg2hw_spc_ch_mask_reg_t spc_ch_mask; // [31:0] + im2col_spc_reg2hw_src_ptr_reg_t src_ptr; // [363:332] + im2col_spc_reg2hw_dst_ptr_reg_t dst_ptr; // [331:300] + im2col_spc_reg2hw_iw_reg_t iw; // [299:268] + im2col_spc_reg2hw_ih_reg_t ih; // [267:236] + im2col_spc_reg2hw_fw_reg_t fw; // [235:228] + im2col_spc_reg2hw_fh_reg_t fh; // [227:220] + im2col_spc_reg2hw_batch_reg_t batch; // [219:212] + im2col_spc_reg2hw_num_ch_reg_t num_ch; // [211:203] + im2col_spc_reg2hw_ch_col_reg_t ch_col; // [202:187] + im2col_spc_reg2hw_n_patches_w_reg_t n_patches_w; // [186:171] + im2col_spc_reg2hw_n_patches_h_reg_t n_patches_h; // [170:155] + im2col_spc_reg2hw_adpt_pad_right_reg_t adpt_pad_right; // [154:147] + im2col_spc_reg2hw_adpt_pad_bottom_reg_t adpt_pad_bottom; // [146:139] + im2col_spc_reg2hw_log_strides_d1_reg_t log_strides_d1; // [138:135] + im2col_spc_reg2hw_log_strides_d2_reg_t log_strides_d2; // [134:131] + im2col_spc_reg2hw_status_reg_t status; // [130:129] + im2col_spc_reg2hw_slot_reg_t slot; // [128:97] + im2col_spc_reg2hw_data_type_reg_t data_type; // [96:95] + im2col_spc_reg2hw_pad_top_reg_t pad_top; // [94:88] + im2col_spc_reg2hw_pad_bottom_reg_t pad_bottom; // [87:81] + im2col_spc_reg2hw_pad_right_reg_t pad_right; // [80:74] + im2col_spc_reg2hw_pad_left_reg_t pad_left; // [73:67] + im2col_spc_reg2hw_interrupt_en_reg_t interrupt_en; // [66:66] + im2col_spc_reg2hw_spc_ifr_reg_t spc_ifr; // [65:64] + im2col_spc_reg2hw_spc_ch_mask_reg_t spc_ch_mask; // [63:32] + im2col_spc_reg2hw_spc_ch_offset_reg_t spc_ch_offset; // [31:0] } im2col_spc_reg2hw_t; // HW -> register type typedef struct packed { - im2col_spc_hw2reg_status_reg_t status; // [1:1] - im2col_spc_hw2reg_spc_ifr_reg_t spc_ifr; // [0:0] + im2col_spc_hw2reg_status_reg_t status; // [1:1] + im2col_spc_hw2reg_spc_ifr_reg_t spc_ifr; // [0:0] } im2col_spc_hw2reg_t; // Register offsets - parameter logic [BlockAw-1:0] IM2COL_SPC_SRC_PTR_OFFSET = 7'h0; - parameter logic [BlockAw-1:0] IM2COL_SPC_DST_PTR_OFFSET = 7'h4; - parameter logic [BlockAw-1:0] IM2COL_SPC_IW_OFFSET = 7'h8; - parameter logic [BlockAw-1:0] IM2COL_SPC_IH_OFFSET = 7'hc; - parameter logic [BlockAw-1:0] IM2COL_SPC_FW_OFFSET = 7'h10; - parameter logic [BlockAw-1:0] IM2COL_SPC_FH_OFFSET = 7'h14; - parameter logic [BlockAw-1:0] IM2COL_SPC_BATCH_OFFSET = 7'h18; - parameter logic [BlockAw-1:0] IM2COL_SPC_NUM_CH_OFFSET = 7'h1c; - parameter logic [BlockAw-1:0] IM2COL_SPC_CH_COL_OFFSET = 7'h20; - parameter logic [BlockAw-1:0] IM2COL_SPC_N_PATCHES_W_OFFSET = 7'h24; - parameter logic [BlockAw-1:0] IM2COL_SPC_N_PATCHES_H_OFFSET = 7'h28; - parameter logic [BlockAw-1:0] IM2COL_SPC_ADPT_PAD_RIGHT_OFFSET = 7'h2c; - parameter logic [BlockAw-1:0] IM2COL_SPC_ADPT_PAD_BOTTOM_OFFSET = 7'h30; - parameter logic [BlockAw-1:0] IM2COL_SPC_LOG_STRIDES_D1_OFFSET = 7'h34; - parameter logic [BlockAw-1:0] IM2COL_SPC_LOG_STRIDES_D2_OFFSET = 7'h38; - parameter logic [BlockAw-1:0] IM2COL_SPC_STATUS_OFFSET = 7'h3c; - parameter logic [BlockAw-1:0] IM2COL_SPC_SLOT_OFFSET = 7'h40; - parameter logic [BlockAw-1:0] IM2COL_SPC_DATA_TYPE_OFFSET = 7'h44; - parameter logic [BlockAw-1:0] IM2COL_SPC_PAD_TOP_OFFSET = 7'h48; - parameter logic [BlockAw-1:0] IM2COL_SPC_PAD_BOTTOM_OFFSET = 7'h4c; - parameter logic [BlockAw-1:0] IM2COL_SPC_PAD_RIGHT_OFFSET = 7'h50; - parameter logic [BlockAw-1:0] IM2COL_SPC_PAD_LEFT_OFFSET = 7'h54; - parameter logic [BlockAw-1:0] IM2COL_SPC_INTERRUPT_EN_OFFSET = 7'h58; - parameter logic [BlockAw-1:0] IM2COL_SPC_SPC_IFR_OFFSET = 7'h5c; - parameter logic [BlockAw-1:0] IM2COL_SPC_SPC_CH_MASK_OFFSET = 7'h60; + parameter logic [BlockAw-1:0] IM2COL_SPC_SRC_PTR_OFFSET = 7'h 0; + parameter logic [BlockAw-1:0] IM2COL_SPC_DST_PTR_OFFSET = 7'h 4; + parameter logic [BlockAw-1:0] IM2COL_SPC_IW_OFFSET = 7'h 8; + parameter logic [BlockAw-1:0] IM2COL_SPC_IH_OFFSET = 7'h c; + parameter logic [BlockAw-1:0] IM2COL_SPC_FW_OFFSET = 7'h 10; + parameter logic [BlockAw-1:0] IM2COL_SPC_FH_OFFSET = 7'h 14; + parameter logic [BlockAw-1:0] IM2COL_SPC_BATCH_OFFSET = 7'h 18; + parameter logic [BlockAw-1:0] IM2COL_SPC_NUM_CH_OFFSET = 7'h 1c; + parameter logic [BlockAw-1:0] IM2COL_SPC_CH_COL_OFFSET = 7'h 20; + parameter logic [BlockAw-1:0] IM2COL_SPC_N_PATCHES_W_OFFSET = 7'h 24; + parameter logic [BlockAw-1:0] IM2COL_SPC_N_PATCHES_H_OFFSET = 7'h 28; + parameter logic [BlockAw-1:0] IM2COL_SPC_ADPT_PAD_RIGHT_OFFSET = 7'h 2c; + parameter logic [BlockAw-1:0] IM2COL_SPC_ADPT_PAD_BOTTOM_OFFSET = 7'h 30; + parameter logic [BlockAw-1:0] IM2COL_SPC_LOG_STRIDES_D1_OFFSET = 7'h 34; + parameter logic [BlockAw-1:0] IM2COL_SPC_LOG_STRIDES_D2_OFFSET = 7'h 38; + parameter logic [BlockAw-1:0] IM2COL_SPC_STATUS_OFFSET = 7'h 3c; + parameter logic [BlockAw-1:0] IM2COL_SPC_SLOT_OFFSET = 7'h 40; + parameter logic [BlockAw-1:0] IM2COL_SPC_DATA_TYPE_OFFSET = 7'h 44; + parameter logic [BlockAw-1:0] IM2COL_SPC_PAD_TOP_OFFSET = 7'h 48; + parameter logic [BlockAw-1:0] IM2COL_SPC_PAD_BOTTOM_OFFSET = 7'h 4c; + parameter logic [BlockAw-1:0] IM2COL_SPC_PAD_RIGHT_OFFSET = 7'h 50; + parameter logic [BlockAw-1:0] IM2COL_SPC_PAD_LEFT_OFFSET = 7'h 54; + parameter logic [BlockAw-1:0] IM2COL_SPC_INTERRUPT_EN_OFFSET = 7'h 58; + parameter logic [BlockAw-1:0] IM2COL_SPC_SPC_IFR_OFFSET = 7'h 5c; + parameter logic [BlockAw-1:0] IM2COL_SPC_SPC_CH_MASK_OFFSET = 7'h 60; + parameter logic [BlockAw-1:0] IM2COL_SPC_SPC_CH_OFFSET_OFFSET = 7'h 64; // Reset values for hwext registers and their fields - parameter logic [0:0] IM2COL_SPC_STATUS_RESVAL = 1'h1; - parameter logic [0:0] IM2COL_SPC_STATUS_READY_RESVAL = 1'h1; - parameter logic [0:0] IM2COL_SPC_SPC_IFR_RESVAL = 1'h0; - parameter logic [0:0] IM2COL_SPC_SPC_IFR_FLAG_RESVAL = 1'h0; + parameter logic [0:0] IM2COL_SPC_STATUS_RESVAL = 1'h 1; + parameter logic [0:0] IM2COL_SPC_STATUS_READY_RESVAL = 1'h 1; + parameter logic [0:0] IM2COL_SPC_SPC_IFR_RESVAL = 1'h 0; + parameter logic [0:0] IM2COL_SPC_SPC_IFR_FLAG_RESVAL = 1'h 0; // Register index typedef enum int { @@ -185,36 +233,38 @@ package im2col_spc_reg_pkg; IM2COL_SPC_PAD_LEFT, IM2COL_SPC_INTERRUPT_EN, IM2COL_SPC_SPC_IFR, - IM2COL_SPC_SPC_CH_MASK + IM2COL_SPC_SPC_CH_MASK, + IM2COL_SPC_SPC_CH_OFFSET } im2col_spc_id_e; // Register width information to check illegal writes - parameter logic [3:0] IM2COL_SPC_PERMIT[25] = '{ - 4'b1111, // index[ 0] IM2COL_SPC_SRC_PTR - 4'b1111, // index[ 1] IM2COL_SPC_DST_PTR - 4'b1111, // index[ 2] IM2COL_SPC_IW - 4'b1111, // index[ 3] IM2COL_SPC_IH - 4'b0001, // index[ 4] IM2COL_SPC_FW - 4'b0001, // index[ 5] IM2COL_SPC_FH - 4'b0001, // index[ 6] IM2COL_SPC_BATCH - 4'b0001, // index[ 7] IM2COL_SPC_NUM_CH - 4'b0011, // index[ 8] IM2COL_SPC_CH_COL - 4'b0011, // index[ 9] IM2COL_SPC_N_PATCHES_W - 4'b0011, // index[10] IM2COL_SPC_N_PATCHES_H - 4'b0001, // index[11] IM2COL_SPC_ADPT_PAD_RIGHT - 4'b0001, // index[12] IM2COL_SPC_ADPT_PAD_BOTTOM - 4'b0001, // index[13] IM2COL_SPC_LOG_STRIDES_D1 - 4'b0001, // index[14] IM2COL_SPC_LOG_STRIDES_D2 - 4'b0001, // index[15] IM2COL_SPC_STATUS - 4'b1111, // index[16] IM2COL_SPC_SLOT - 4'b0001, // index[17] IM2COL_SPC_DATA_TYPE - 4'b0001, // index[18] IM2COL_SPC_PAD_TOP - 4'b0001, // index[19] IM2COL_SPC_PAD_BOTTOM - 4'b0001, // index[20] IM2COL_SPC_PAD_RIGHT - 4'b0001, // index[21] IM2COL_SPC_PAD_LEFT - 4'b0001, // index[22] IM2COL_SPC_INTERRUPT_EN - 4'b0001, // index[23] IM2COL_SPC_SPC_IFR - 4'b1111 // index[24] IM2COL_SPC_SPC_CH_MASK + parameter logic [3:0] IM2COL_SPC_PERMIT [26] = '{ + 4'b 1111, // index[ 0] IM2COL_SPC_SRC_PTR + 4'b 1111, // index[ 1] IM2COL_SPC_DST_PTR + 4'b 1111, // index[ 2] IM2COL_SPC_IW + 4'b 1111, // index[ 3] IM2COL_SPC_IH + 4'b 0001, // index[ 4] IM2COL_SPC_FW + 4'b 0001, // index[ 5] IM2COL_SPC_FH + 4'b 0001, // index[ 6] IM2COL_SPC_BATCH + 4'b 0001, // index[ 7] IM2COL_SPC_NUM_CH + 4'b 0011, // index[ 8] IM2COL_SPC_CH_COL + 4'b 0011, // index[ 9] IM2COL_SPC_N_PATCHES_W + 4'b 0011, // index[10] IM2COL_SPC_N_PATCHES_H + 4'b 0001, // index[11] IM2COL_SPC_ADPT_PAD_RIGHT + 4'b 0001, // index[12] IM2COL_SPC_ADPT_PAD_BOTTOM + 4'b 0001, // index[13] IM2COL_SPC_LOG_STRIDES_D1 + 4'b 0001, // index[14] IM2COL_SPC_LOG_STRIDES_D2 + 4'b 0001, // index[15] IM2COL_SPC_STATUS + 4'b 1111, // index[16] IM2COL_SPC_SLOT + 4'b 0001, // index[17] IM2COL_SPC_DATA_TYPE + 4'b 0001, // index[18] IM2COL_SPC_PAD_TOP + 4'b 0001, // index[19] IM2COL_SPC_PAD_BOTTOM + 4'b 0001, // index[20] IM2COL_SPC_PAD_RIGHT + 4'b 0001, // index[21] IM2COL_SPC_PAD_LEFT + 4'b 0001, // index[22] IM2COL_SPC_INTERRUPT_EN + 4'b 0001, // index[23] IM2COL_SPC_SPC_IFR + 4'b 1111, // index[24] IM2COL_SPC_SPC_CH_MASK + 4'b 1111 // index[25] IM2COL_SPC_SPC_CH_OFFSET }; endpackage diff --git a/hw/ip_examples/im2col_spc/rtl/im2col_spc_reg_top.sv b/hw/ip_examples/im2col_spc/rtl/im2col_spc_reg_top.sv index 16341372e..a782b9000 100644 --- a/hw/ip_examples/im2col_spc/rtl/im2col_spc_reg_top.sv +++ b/hw/ip_examples/im2col_spc/rtl/im2col_spc_reg_top.sv @@ -8,44 +8,44 @@ `include "common_cells/assertions.svh" module im2col_spc_reg_top #( - parameter type reg_req_t = logic, - parameter type reg_rsp_t = logic, - parameter int AW = 7 + parameter type reg_req_t = logic, + parameter type reg_rsp_t = logic, + parameter int AW = 7 ) ( - input logic clk_i, - input logic rst_ni, - input reg_req_t reg_req_i, - output reg_rsp_t reg_rsp_o, - // To HW - output im2col_spc_reg_pkg::im2col_spc_reg2hw_t reg2hw, // Write - input im2col_spc_reg_pkg::im2col_spc_hw2reg_t hw2reg, // Read + input logic clk_i, + input logic rst_ni, + input reg_req_t reg_req_i, + output reg_rsp_t reg_rsp_o, + // To HW + output im2col_spc_reg_pkg::im2col_spc_reg2hw_t reg2hw, // Write + input im2col_spc_reg_pkg::im2col_spc_hw2reg_t hw2reg, // Read - // Config - input devmode_i // If 1, explicit error return for unmapped register access + // Config + input devmode_i // If 1, explicit error return for unmapped register access ); - import im2col_spc_reg_pkg::*; + import im2col_spc_reg_pkg::* ; localparam int DW = 32; - localparam int DBW = DW / 8; // Byte Width + localparam int DBW = DW/8; // Byte Width // register signals logic reg_we; logic reg_re; - logic [ AW-1:0] reg_addr; - logic [ DW-1:0] reg_wdata; + logic [AW-1:0] reg_addr; + logic [DW-1:0] reg_wdata; logic [DBW-1:0] reg_be; - logic [ DW-1:0] reg_rdata; + logic [DW-1:0] reg_rdata; logic reg_error; - logic addrmiss, wr_err; + logic addrmiss, wr_err; logic [DW-1:0] reg_rdata_next; // Below register interface can be changed - reg_req_t reg_intf_req; - reg_rsp_t reg_intf_rsp; + reg_req_t reg_intf_req; + reg_rsp_t reg_intf_rsp; assign reg_intf_req = reg_req_i; @@ -61,7 +61,7 @@ module im2col_spc_reg_top #( assign reg_intf_rsp.error = reg_error; assign reg_intf_rsp.ready = 1'b1; - assign reg_rdata = reg_rdata_next; + assign reg_rdata = reg_rdata_next ; assign reg_error = (devmode_i & addrmiss) | wr_err; @@ -144,426 +144,429 @@ module im2col_spc_reg_top #( logic [31:0] spc_ch_mask_qs; logic [31:0] spc_ch_mask_wd; logic spc_ch_mask_we; + logic [31:0] spc_ch_offset_qs; + logic [31:0] spc_ch_offset_wd; + logic spc_ch_offset_we; // Register instances // R[src_ptr]: V(False) prim_subreg #( - .DW (32), - .SWACCESS("RW"), - .RESVAL (32'h0) + .DW (32), + .SWACCESS("RW"), + .RESVAL (32'h0) ) u_src_ptr ( - .clk_i (clk_i), - .rst_ni(rst_ni), + .clk_i (clk_i ), + .rst_ni (rst_ni ), - // from register interface - .we(src_ptr_we), - .wd(src_ptr_wd), + // from register interface + .we (src_ptr_we), + .wd (src_ptr_wd), - // from internal hardware - .de(1'b0), - .d ('0), + // from internal hardware + .de (1'b0), + .d ('0 ), - // to internal hardware - .qe(), - .q (reg2hw.src_ptr.q), + // to internal hardware + .qe (), + .q (reg2hw.src_ptr.q ), - // to register interface (read) - .qs(src_ptr_qs) + // to register interface (read) + .qs (src_ptr_qs) ); // R[dst_ptr]: V(False) prim_subreg #( - .DW (32), - .SWACCESS("RW"), - .RESVAL (32'h0) + .DW (32), + .SWACCESS("RW"), + .RESVAL (32'h0) ) u_dst_ptr ( - .clk_i (clk_i), - .rst_ni(rst_ni), + .clk_i (clk_i ), + .rst_ni (rst_ni ), - // from register interface - .we(dst_ptr_we), - .wd(dst_ptr_wd), + // from register interface + .we (dst_ptr_we), + .wd (dst_ptr_wd), - // from internal hardware - .de(1'b0), - .d ('0), + // from internal hardware + .de (1'b0), + .d ('0 ), - // to internal hardware - .qe(), - .q (reg2hw.dst_ptr.q), + // to internal hardware + .qe (), + .q (reg2hw.dst_ptr.q ), - // to register interface (read) - .qs(dst_ptr_qs) + // to register interface (read) + .qs (dst_ptr_qs) ); // R[iw]: V(False) prim_subreg #( - .DW (32), - .SWACCESS("RW"), - .RESVAL (32'h0) + .DW (32), + .SWACCESS("RW"), + .RESVAL (32'h0) ) u_iw ( - .clk_i (clk_i), - .rst_ni(rst_ni), + .clk_i (clk_i ), + .rst_ni (rst_ni ), - // from register interface - .we(iw_we), - .wd(iw_wd), + // from register interface + .we (iw_we), + .wd (iw_wd), - // from internal hardware - .de(1'b0), - .d ('0), + // from internal hardware + .de (1'b0), + .d ('0 ), - // to internal hardware - .qe(), - .q (reg2hw.iw.q), + // to internal hardware + .qe (), + .q (reg2hw.iw.q ), - // to register interface (read) - .qs(iw_qs) + // to register interface (read) + .qs (iw_qs) ); // R[ih]: V(False) prim_subreg #( - .DW (32), - .SWACCESS("RW"), - .RESVAL (32'h0) + .DW (32), + .SWACCESS("RW"), + .RESVAL (32'h0) ) u_ih ( - .clk_i (clk_i), - .rst_ni(rst_ni), + .clk_i (clk_i ), + .rst_ni (rst_ni ), - // from register interface - .we(ih_we), - .wd(ih_wd), + // from register interface + .we (ih_we), + .wd (ih_wd), - // from internal hardware - .de(1'b0), - .d ('0), + // from internal hardware + .de (1'b0), + .d ('0 ), - // to internal hardware - .qe(), - .q (reg2hw.ih.q), + // to internal hardware + .qe (), + .q (reg2hw.ih.q ), - // to register interface (read) - .qs(ih_qs) + // to register interface (read) + .qs (ih_qs) ); // R[fw]: V(False) prim_subreg #( - .DW (8), - .SWACCESS("RW"), - .RESVAL (8'h0) + .DW (8), + .SWACCESS("RW"), + .RESVAL (8'h0) ) u_fw ( - .clk_i (clk_i), - .rst_ni(rst_ni), + .clk_i (clk_i ), + .rst_ni (rst_ni ), - // from register interface - .we(fw_we), - .wd(fw_wd), + // from register interface + .we (fw_we), + .wd (fw_wd), - // from internal hardware - .de(1'b0), - .d ('0), + // from internal hardware + .de (1'b0), + .d ('0 ), - // to internal hardware - .qe(), - .q (reg2hw.fw.q), + // to internal hardware + .qe (), + .q (reg2hw.fw.q ), - // to register interface (read) - .qs(fw_qs) + // to register interface (read) + .qs (fw_qs) ); // R[fh]: V(False) prim_subreg #( - .DW (8), - .SWACCESS("RW"), - .RESVAL (8'h0) + .DW (8), + .SWACCESS("RW"), + .RESVAL (8'h0) ) u_fh ( - .clk_i (clk_i), - .rst_ni(rst_ni), + .clk_i (clk_i ), + .rst_ni (rst_ni ), - // from register interface - .we(fh_we), - .wd(fh_wd), + // from register interface + .we (fh_we), + .wd (fh_wd), - // from internal hardware - .de(1'b0), - .d ('0), + // from internal hardware + .de (1'b0), + .d ('0 ), - // to internal hardware - .qe(), - .q (reg2hw.fh.q), + // to internal hardware + .qe (), + .q (reg2hw.fh.q ), - // to register interface (read) - .qs(fh_qs) + // to register interface (read) + .qs (fh_qs) ); // R[batch]: V(False) prim_subreg #( - .DW (8), - .SWACCESS("RW"), - .RESVAL (8'h0) + .DW (8), + .SWACCESS("RW"), + .RESVAL (8'h0) ) u_batch ( - .clk_i (clk_i), - .rst_ni(rst_ni), + .clk_i (clk_i ), + .rst_ni (rst_ni ), - // from register interface - .we(batch_we), - .wd(batch_wd), + // from register interface + .we (batch_we), + .wd (batch_wd), - // from internal hardware - .de(1'b0), - .d ('0), + // from internal hardware + .de (1'b0), + .d ('0 ), - // to internal hardware - .qe(), - .q (reg2hw.batch.q), + // to internal hardware + .qe (), + .q (reg2hw.batch.q ), - // to register interface (read) - .qs(batch_qs) + // to register interface (read) + .qs (batch_qs) ); // R[num_ch]: V(False) prim_subreg #( - .DW (8), - .SWACCESS("RW"), - .RESVAL (8'h0) + .DW (8), + .SWACCESS("RW"), + .RESVAL (8'h0) ) u_num_ch ( - .clk_i (clk_i), - .rst_ni(rst_ni), + .clk_i (clk_i ), + .rst_ni (rst_ni ), - // from register interface - .we(num_ch_we), - .wd(num_ch_wd), + // from register interface + .we (num_ch_we), + .wd (num_ch_wd), - // from internal hardware - .de(1'b0), - .d ('0), + // from internal hardware + .de (1'b0), + .d ('0 ), - // to internal hardware - .qe(reg2hw.num_ch.qe), - .q (reg2hw.num_ch.q), + // to internal hardware + .qe (reg2hw.num_ch.qe), + .q (reg2hw.num_ch.q ), - // to register interface (read) - .qs(num_ch_qs) + // to register interface (read) + .qs (num_ch_qs) ); // R[ch_col]: V(False) prim_subreg #( - .DW (16), - .SWACCESS("RW"), - .RESVAL (16'h0) + .DW (16), + .SWACCESS("RW"), + .RESVAL (16'h0) ) u_ch_col ( - .clk_i (clk_i), - .rst_ni(rst_ni), + .clk_i (clk_i ), + .rst_ni (rst_ni ), - // from register interface - .we(ch_col_we), - .wd(ch_col_wd), + // from register interface + .we (ch_col_we), + .wd (ch_col_wd), - // from internal hardware - .de(1'b0), - .d ('0), + // from internal hardware + .de (1'b0), + .d ('0 ), - // to internal hardware - .qe(), - .q (reg2hw.ch_col.q), + // to internal hardware + .qe (), + .q (reg2hw.ch_col.q ), - // to register interface (read) - .qs(ch_col_qs) + // to register interface (read) + .qs (ch_col_qs) ); // R[n_patches_w]: V(False) prim_subreg #( - .DW (16), - .SWACCESS("RW"), - .RESVAL (16'h0) + .DW (16), + .SWACCESS("RW"), + .RESVAL (16'h0) ) u_n_patches_w ( - .clk_i (clk_i), - .rst_ni(rst_ni), + .clk_i (clk_i ), + .rst_ni (rst_ni ), - // from register interface - .we(n_patches_w_we), - .wd(n_patches_w_wd), + // from register interface + .we (n_patches_w_we), + .wd (n_patches_w_wd), - // from internal hardware - .de(1'b0), - .d ('0), + // from internal hardware + .de (1'b0), + .d ('0 ), - // to internal hardware - .qe(), - .q (reg2hw.n_patches_w.q), + // to internal hardware + .qe (), + .q (reg2hw.n_patches_w.q ), - // to register interface (read) - .qs(n_patches_w_qs) + // to register interface (read) + .qs (n_patches_w_qs) ); // R[n_patches_h]: V(False) prim_subreg #( - .DW (16), - .SWACCESS("RW"), - .RESVAL (16'h0) + .DW (16), + .SWACCESS("RW"), + .RESVAL (16'h0) ) u_n_patches_h ( - .clk_i (clk_i), - .rst_ni(rst_ni), + .clk_i (clk_i ), + .rst_ni (rst_ni ), - // from register interface - .we(n_patches_h_we), - .wd(n_patches_h_wd), + // from register interface + .we (n_patches_h_we), + .wd (n_patches_h_wd), - // from internal hardware - .de(1'b0), - .d ('0), + // from internal hardware + .de (1'b0), + .d ('0 ), - // to internal hardware - .qe(), - .q (reg2hw.n_patches_h.q), + // to internal hardware + .qe (), + .q (reg2hw.n_patches_h.q ), - // to register interface (read) - .qs(n_patches_h_qs) + // to register interface (read) + .qs (n_patches_h_qs) ); // R[adpt_pad_right]: V(False) prim_subreg #( - .DW (8), - .SWACCESS("RW"), - .RESVAL (8'h0) + .DW (8), + .SWACCESS("RW"), + .RESVAL (8'h0) ) u_adpt_pad_right ( - .clk_i (clk_i), - .rst_ni(rst_ni), + .clk_i (clk_i ), + .rst_ni (rst_ni ), - // from register interface - .we(adpt_pad_right_we), - .wd(adpt_pad_right_wd), + // from register interface + .we (adpt_pad_right_we), + .wd (adpt_pad_right_wd), - // from internal hardware - .de(1'b0), - .d ('0), + // from internal hardware + .de (1'b0), + .d ('0 ), - // to internal hardware - .qe(), - .q (reg2hw.adpt_pad_right.q), + // to internal hardware + .qe (), + .q (reg2hw.adpt_pad_right.q ), - // to register interface (read) - .qs(adpt_pad_right_qs) + // to register interface (read) + .qs (adpt_pad_right_qs) ); // R[adpt_pad_bottom]: V(False) prim_subreg #( - .DW (8), - .SWACCESS("RW"), - .RESVAL (8'h0) + .DW (8), + .SWACCESS("RW"), + .RESVAL (8'h0) ) u_adpt_pad_bottom ( - .clk_i (clk_i), - .rst_ni(rst_ni), + .clk_i (clk_i ), + .rst_ni (rst_ni ), - // from register interface - .we(adpt_pad_bottom_we), - .wd(adpt_pad_bottom_wd), + // from register interface + .we (adpt_pad_bottom_we), + .wd (adpt_pad_bottom_wd), - // from internal hardware - .de(1'b0), - .d ('0), + // from internal hardware + .de (1'b0), + .d ('0 ), - // to internal hardware - .qe(), - .q (reg2hw.adpt_pad_bottom.q), + // to internal hardware + .qe (), + .q (reg2hw.adpt_pad_bottom.q ), - // to register interface (read) - .qs(adpt_pad_bottom_qs) + // to register interface (read) + .qs (adpt_pad_bottom_qs) ); // R[log_strides_d1]: V(False) prim_subreg #( - .DW (4), - .SWACCESS("RW"), - .RESVAL (4'h0) + .DW (4), + .SWACCESS("RW"), + .RESVAL (4'h0) ) u_log_strides_d1 ( - .clk_i (clk_i), - .rst_ni(rst_ni), + .clk_i (clk_i ), + .rst_ni (rst_ni ), - // from register interface - .we(log_strides_d1_we), - .wd(log_strides_d1_wd), + // from register interface + .we (log_strides_d1_we), + .wd (log_strides_d1_wd), - // from internal hardware - .de(1'b0), - .d ('0), + // from internal hardware + .de (1'b0), + .d ('0 ), - // to internal hardware - .qe(), - .q (reg2hw.log_strides_d1.q), + // to internal hardware + .qe (), + .q (reg2hw.log_strides_d1.q ), - // to register interface (read) - .qs(log_strides_d1_qs) + // to register interface (read) + .qs (log_strides_d1_qs) ); // R[log_strides_d2]: V(False) prim_subreg #( - .DW (4), - .SWACCESS("RW"), - .RESVAL (4'h0) + .DW (4), + .SWACCESS("RW"), + .RESVAL (4'h0) ) u_log_strides_d2 ( - .clk_i (clk_i), - .rst_ni(rst_ni), + .clk_i (clk_i ), + .rst_ni (rst_ni ), - // from register interface - .we(log_strides_d2_we), - .wd(log_strides_d2_wd), + // from register interface + .we (log_strides_d2_we), + .wd (log_strides_d2_wd), - // from internal hardware - .de(1'b0), - .d ('0), + // from internal hardware + .de (1'b0), + .d ('0 ), - // to internal hardware - .qe(), - .q (reg2hw.log_strides_d2.q), + // to internal hardware + .qe (), + .q (reg2hw.log_strides_d2.q ), - // to register interface (read) - .qs(log_strides_d2_qs) + // to register interface (read) + .qs (log_strides_d2_qs) ); // R[status]: V(True) prim_subreg_ext #( - .DW(1) + .DW (1) ) u_status ( - .re (status_re), - .we (1'b0), - .wd ('0), - .d (hw2reg.status.d), - .qre(reg2hw.status.re), - .qe (), - .q (reg2hw.status.q), - .qs (status_qs) + .re (status_re), + .we (1'b0), + .wd ('0), + .d (hw2reg.status.d), + .qre (reg2hw.status.re), + .qe (), + .q (reg2hw.status.q ), + .qs (status_qs) ); @@ -571,276 +574,303 @@ module im2col_spc_reg_top #( // F[rx_trigger_slot]: 15:0 prim_subreg #( - .DW (16), - .SWACCESS("RW"), - .RESVAL (16'h0) + .DW (16), + .SWACCESS("RW"), + .RESVAL (16'h0) ) u_slot_rx_trigger_slot ( - .clk_i (clk_i), - .rst_ni(rst_ni), + .clk_i (clk_i ), + .rst_ni (rst_ni ), - // from register interface - .we(slot_rx_trigger_slot_we), - .wd(slot_rx_trigger_slot_wd), + // from register interface + .we (slot_rx_trigger_slot_we), + .wd (slot_rx_trigger_slot_wd), - // from internal hardware - .de(1'b0), - .d ('0), + // from internal hardware + .de (1'b0), + .d ('0 ), - // to internal hardware - .qe(), - .q (reg2hw.slot.rx_trigger_slot.q), + // to internal hardware + .qe (), + .q (reg2hw.slot.rx_trigger_slot.q ), - // to register interface (read) - .qs(slot_rx_trigger_slot_qs) + // to register interface (read) + .qs (slot_rx_trigger_slot_qs) ); // F[tx_trigger_slot]: 31:16 prim_subreg #( - .DW (16), - .SWACCESS("RW"), - .RESVAL (16'h0) + .DW (16), + .SWACCESS("RW"), + .RESVAL (16'h0) ) u_slot_tx_trigger_slot ( - .clk_i (clk_i), - .rst_ni(rst_ni), + .clk_i (clk_i ), + .rst_ni (rst_ni ), - // from register interface - .we(slot_tx_trigger_slot_we), - .wd(slot_tx_trigger_slot_wd), + // from register interface + .we (slot_tx_trigger_slot_we), + .wd (slot_tx_trigger_slot_wd), - // from internal hardware - .de(1'b0), - .d ('0), + // from internal hardware + .de (1'b0), + .d ('0 ), - // to internal hardware - .qe(), - .q (reg2hw.slot.tx_trigger_slot.q), + // to internal hardware + .qe (), + .q (reg2hw.slot.tx_trigger_slot.q ), - // to register interface (read) - .qs(slot_tx_trigger_slot_qs) + // to register interface (read) + .qs (slot_tx_trigger_slot_qs) ); // R[data_type]: V(False) prim_subreg #( - .DW (2), - .SWACCESS("RW"), - .RESVAL (2'h0) + .DW (2), + .SWACCESS("RW"), + .RESVAL (2'h0) ) u_data_type ( - .clk_i (clk_i), - .rst_ni(rst_ni), + .clk_i (clk_i ), + .rst_ni (rst_ni ), - // from register interface - .we(data_type_we), - .wd(data_type_wd), + // from register interface + .we (data_type_we), + .wd (data_type_wd), - // from internal hardware - .de(1'b0), - .d ('0), + // from internal hardware + .de (1'b0), + .d ('0 ), - // to internal hardware - .qe(), - .q (reg2hw.data_type.q), + // to internal hardware + .qe (), + .q (reg2hw.data_type.q ), - // to register interface (read) - .qs(data_type_qs) + // to register interface (read) + .qs (data_type_qs) ); // R[pad_top]: V(False) prim_subreg #( - .DW (6), - .SWACCESS("RW"), - .RESVAL (6'h0) + .DW (6), + .SWACCESS("RW"), + .RESVAL (6'h0) ) u_pad_top ( - .clk_i (clk_i), - .rst_ni(rst_ni), + .clk_i (clk_i ), + .rst_ni (rst_ni ), - // from register interface - .we(pad_top_we), - .wd(pad_top_wd), + // from register interface + .we (pad_top_we), + .wd (pad_top_wd), - // from internal hardware - .de(1'b0), - .d ('0), + // from internal hardware + .de (1'b0), + .d ('0 ), - // to internal hardware - .qe(reg2hw.pad_top.qe), - .q (reg2hw.pad_top.q), + // to internal hardware + .qe (reg2hw.pad_top.qe), + .q (reg2hw.pad_top.q ), - // to register interface (read) - .qs(pad_top_qs) + // to register interface (read) + .qs (pad_top_qs) ); // R[pad_bottom]: V(False) prim_subreg #( - .DW (6), - .SWACCESS("RW"), - .RESVAL (6'h0) + .DW (6), + .SWACCESS("RW"), + .RESVAL (6'h0) ) u_pad_bottom ( - .clk_i (clk_i), - .rst_ni(rst_ni), + .clk_i (clk_i ), + .rst_ni (rst_ni ), - // from register interface - .we(pad_bottom_we), - .wd(pad_bottom_wd), + // from register interface + .we (pad_bottom_we), + .wd (pad_bottom_wd), - // from internal hardware - .de(1'b0), - .d ('0), + // from internal hardware + .de (1'b0), + .d ('0 ), - // to internal hardware - .qe(reg2hw.pad_bottom.qe), - .q (reg2hw.pad_bottom.q), + // to internal hardware + .qe (reg2hw.pad_bottom.qe), + .q (reg2hw.pad_bottom.q ), - // to register interface (read) - .qs(pad_bottom_qs) + // to register interface (read) + .qs (pad_bottom_qs) ); // R[pad_right]: V(False) prim_subreg #( - .DW (6), - .SWACCESS("RW"), - .RESVAL (6'h0) + .DW (6), + .SWACCESS("RW"), + .RESVAL (6'h0) ) u_pad_right ( - .clk_i (clk_i), - .rst_ni(rst_ni), + .clk_i (clk_i ), + .rst_ni (rst_ni ), - // from register interface - .we(pad_right_we), - .wd(pad_right_wd), + // from register interface + .we (pad_right_we), + .wd (pad_right_wd), - // from internal hardware - .de(1'b0), - .d ('0), + // from internal hardware + .de (1'b0), + .d ('0 ), - // to internal hardware - .qe(reg2hw.pad_right.qe), - .q (reg2hw.pad_right.q), + // to internal hardware + .qe (reg2hw.pad_right.qe), + .q (reg2hw.pad_right.q ), - // to register interface (read) - .qs(pad_right_qs) + // to register interface (read) + .qs (pad_right_qs) ); // R[pad_left]: V(False) prim_subreg #( - .DW (6), - .SWACCESS("RW"), - .RESVAL (6'h0) + .DW (6), + .SWACCESS("RW"), + .RESVAL (6'h0) ) u_pad_left ( - .clk_i (clk_i), - .rst_ni(rst_ni), + .clk_i (clk_i ), + .rst_ni (rst_ni ), - // from register interface - .we(pad_left_we), - .wd(pad_left_wd), + // from register interface + .we (pad_left_we), + .wd (pad_left_wd), - // from internal hardware - .de(1'b0), - .d ('0), + // from internal hardware + .de (1'b0), + .d ('0 ), - // to internal hardware - .qe(reg2hw.pad_left.qe), - .q (reg2hw.pad_left.q), + // to internal hardware + .qe (reg2hw.pad_left.qe), + .q (reg2hw.pad_left.q ), - // to register interface (read) - .qs(pad_left_qs) + // to register interface (read) + .qs (pad_left_qs) ); // R[interrupt_en]: V(False) prim_subreg #( - .DW (1), - .SWACCESS("RW"), - .RESVAL (1'h0) + .DW (1), + .SWACCESS("RW"), + .RESVAL (1'h0) ) u_interrupt_en ( - .clk_i (clk_i), - .rst_ni(rst_ni), + .clk_i (clk_i ), + .rst_ni (rst_ni ), - // from register interface - .we(interrupt_en_we), - .wd(interrupt_en_wd), + // from register interface + .we (interrupt_en_we), + .wd (interrupt_en_wd), - // from internal hardware - .de(1'b0), - .d ('0), + // from internal hardware + .de (1'b0), + .d ('0 ), - // to internal hardware - .qe(), - .q (reg2hw.interrupt_en.q), + // to internal hardware + .qe (), + .q (reg2hw.interrupt_en.q ), - // to register interface (read) - .qs(interrupt_en_qs) + // to register interface (read) + .qs (interrupt_en_qs) ); // R[spc_ifr]: V(True) prim_subreg_ext #( - .DW(1) + .DW (1) ) u_spc_ifr ( - .re (spc_ifr_re), - .we (1'b0), - .wd ('0), - .d (hw2reg.spc_ifr.d), - .qre(reg2hw.spc_ifr.re), - .qe (), - .q (reg2hw.spc_ifr.q), - .qs (spc_ifr_qs) + .re (spc_ifr_re), + .we (1'b0), + .wd ('0), + .d (hw2reg.spc_ifr.d), + .qre (reg2hw.spc_ifr.re), + .qe (), + .q (reg2hw.spc_ifr.q ), + .qs (spc_ifr_qs) ); // R[spc_ch_mask]: V(False) prim_subreg #( - .DW (32), - .SWACCESS("RW"), - .RESVAL (32'h1) + .DW (32), + .SWACCESS("RW"), + .RESVAL (32'h1) ) u_spc_ch_mask ( - .clk_i (clk_i), - .rst_ni(rst_ni), + .clk_i (clk_i ), + .rst_ni (rst_ni ), - // from register interface - .we(spc_ch_mask_we), - .wd(spc_ch_mask_wd), + // from register interface + .we (spc_ch_mask_we), + .wd (spc_ch_mask_wd), - // from internal hardware - .de(1'b0), - .d ('0), + // from internal hardware + .de (1'b0), + .d ('0 ), - // to internal hardware - .qe(), - .q (reg2hw.spc_ch_mask.q), + // to internal hardware + .qe (), + .q (reg2hw.spc_ch_mask.q ), - // to register interface (read) - .qs(spc_ch_mask_qs) + // to register interface (read) + .qs (spc_ch_mask_qs) ); + // R[spc_ch_offset]: V(False) + + prim_subreg #( + .DW (32), + .SWACCESS("RW"), + .RESVAL (32'h1) + ) u_spc_ch_offset ( + .clk_i (clk_i ), + .rst_ni (rst_ni ), + + // from register interface + .we (spc_ch_offset_we), + .wd (spc_ch_offset_wd), + + // from internal hardware + .de (1'b0), + .d ('0 ), + + // to internal hardware + .qe (), + .q (reg2hw.spc_ch_offset.q ), + + // to register interface (read) + .qs (spc_ch_offset_qs) + ); - logic [24:0] addr_hit; + + + logic [25:0] addr_hit; always_comb begin addr_hit = '0; - addr_hit[0] = (reg_addr == IM2COL_SPC_SRC_PTR_OFFSET); - addr_hit[1] = (reg_addr == IM2COL_SPC_DST_PTR_OFFSET); - addr_hit[2] = (reg_addr == IM2COL_SPC_IW_OFFSET); - addr_hit[3] = (reg_addr == IM2COL_SPC_IH_OFFSET); - addr_hit[4] = (reg_addr == IM2COL_SPC_FW_OFFSET); - addr_hit[5] = (reg_addr == IM2COL_SPC_FH_OFFSET); - addr_hit[6] = (reg_addr == IM2COL_SPC_BATCH_OFFSET); - addr_hit[7] = (reg_addr == IM2COL_SPC_NUM_CH_OFFSET); - addr_hit[8] = (reg_addr == IM2COL_SPC_CH_COL_OFFSET); - addr_hit[9] = (reg_addr == IM2COL_SPC_N_PATCHES_W_OFFSET); + addr_hit[ 0] = (reg_addr == IM2COL_SPC_SRC_PTR_OFFSET); + addr_hit[ 1] = (reg_addr == IM2COL_SPC_DST_PTR_OFFSET); + addr_hit[ 2] = (reg_addr == IM2COL_SPC_IW_OFFSET); + addr_hit[ 3] = (reg_addr == IM2COL_SPC_IH_OFFSET); + addr_hit[ 4] = (reg_addr == IM2COL_SPC_FW_OFFSET); + addr_hit[ 5] = (reg_addr == IM2COL_SPC_FH_OFFSET); + addr_hit[ 6] = (reg_addr == IM2COL_SPC_BATCH_OFFSET); + addr_hit[ 7] = (reg_addr == IM2COL_SPC_NUM_CH_OFFSET); + addr_hit[ 8] = (reg_addr == IM2COL_SPC_CH_COL_OFFSET); + addr_hit[ 9] = (reg_addr == IM2COL_SPC_N_PATCHES_W_OFFSET); addr_hit[10] = (reg_addr == IM2COL_SPC_N_PATCHES_H_OFFSET); addr_hit[11] = (reg_addr == IM2COL_SPC_ADPT_PAD_RIGHT_OFFSET); addr_hit[12] = (reg_addr == IM2COL_SPC_ADPT_PAD_BOTTOM_OFFSET); @@ -856,9 +886,10 @@ module im2col_spc_reg_top #( addr_hit[22] = (reg_addr == IM2COL_SPC_INTERRUPT_EN_OFFSET); addr_hit[23] = (reg_addr == IM2COL_SPC_SPC_IFR_OFFSET); addr_hit[24] = (reg_addr == IM2COL_SPC_SPC_CH_MASK_OFFSET); + addr_hit[25] = (reg_addr == IM2COL_SPC_SPC_CH_OFFSET_OFFSET); end - assign addrmiss = (reg_re || reg_we) ? ~|addr_hit : 1'b0; + assign addrmiss = (reg_re || reg_we) ? ~|addr_hit : 1'b0 ; // Check sub-word write is permitted always_comb begin @@ -887,7 +918,8 @@ module im2col_spc_reg_top #( (addr_hit[21] & (|(IM2COL_SPC_PERMIT[21] & ~reg_be))) | (addr_hit[22] & (|(IM2COL_SPC_PERMIT[22] & ~reg_be))) | (addr_hit[23] & (|(IM2COL_SPC_PERMIT[23] & ~reg_be))) | - (addr_hit[24] & (|(IM2COL_SPC_PERMIT[24] & ~reg_be))))); + (addr_hit[24] & (|(IM2COL_SPC_PERMIT[24] & ~reg_be))) | + (addr_hit[25] & (|(IM2COL_SPC_PERMIT[25] & ~reg_be))))); end assign src_ptr_we = addr_hit[0] & reg_we & !reg_error; @@ -966,6 +998,9 @@ module im2col_spc_reg_top #( assign spc_ch_mask_we = addr_hit[24] & reg_we & !reg_error; assign spc_ch_mask_wd = reg_wdata[31:0]; + assign spc_ch_offset_we = addr_hit[25] & reg_we & !reg_error; + assign spc_ch_offset_wd = reg_wdata[31:0]; + // Read data return always_comb begin reg_rdata_next = '0; @@ -1035,7 +1070,7 @@ module im2col_spc_reg_top #( end addr_hit[16]: begin - reg_rdata_next[15:0] = slot_rx_trigger_slot_qs; + reg_rdata_next[15:0] = slot_rx_trigger_slot_qs; reg_rdata_next[31:16] = slot_tx_trigger_slot_qs; end @@ -1071,6 +1106,10 @@ module im2col_spc_reg_top #( reg_rdata_next[31:0] = spc_ch_mask_qs; end + addr_hit[25]: begin + reg_rdata_next[31:0] = spc_ch_offset_qs; + end + default: begin reg_rdata_next = '1; end @@ -1091,23 +1130,24 @@ module im2col_spc_reg_top #( endmodule -module im2col_spc_reg_top_intf #( - parameter int AW = 7, - localparam int DW = 32 +module im2col_spc_reg_top_intf +#( + parameter int AW = 7, + localparam int DW = 32 ) ( - input logic clk_i, - input logic rst_ni, - REG_BUS.in regbus_slave, - // To HW - output im2col_spc_reg_pkg::im2col_spc_reg2hw_t reg2hw, // Write - input im2col_spc_reg_pkg::im2col_spc_hw2reg_t hw2reg, // Read - // Config - input devmode_i // If 1, explicit error return for unmapped register access + input logic clk_i, + input logic rst_ni, + REG_BUS.in regbus_slave, + // To HW + output im2col_spc_reg_pkg::im2col_spc_reg2hw_t reg2hw, // Write + input im2col_spc_reg_pkg::im2col_spc_hw2reg_t hw2reg, // Read + // Config + input devmode_i // If 1, explicit error return for unmapped register access ); - localparam int unsigned STRB_WIDTH = DW / 8; + localparam int unsigned STRB_WIDTH = DW/8; - `include "register_interface/typedef.svh" - `include "register_interface/assign.svh" +`include "register_interface/typedef.svh" +`include "register_interface/assign.svh" // Define structs for reg_bus typedef logic [AW-1:0] addr_t; @@ -1117,27 +1157,27 @@ module im2col_spc_reg_top_intf #( reg_bus_req_t s_reg_req; reg_bus_rsp_t s_reg_rsp; - + // Assign SV interface to structs `REG_BUS_ASSIGN_TO_REQ(s_reg_req, regbus_slave) `REG_BUS_ASSIGN_FROM_RSP(regbus_slave, s_reg_rsp) - + im2col_spc_reg_top #( - .reg_req_t(reg_bus_req_t), - .reg_rsp_t(reg_bus_rsp_t), - .AW(AW) + .reg_req_t(reg_bus_req_t), + .reg_rsp_t(reg_bus_rsp_t), + .AW(AW) ) i_regs ( - .clk_i, - .rst_ni, - .reg_req_i(s_reg_req), - .reg_rsp_o(s_reg_rsp), - .reg2hw, // Write - .hw2reg, // Read - .devmode_i + .clk_i, + .rst_ni, + .reg_req_i(s_reg_req), + .reg_rsp_o(s_reg_rsp), + .reg2hw, // Write + .hw2reg, // Read + .devmode_i ); - + endmodule diff --git a/sw/applications/example_im2col/im2col_lib.h b/sw/applications/example_im2col/im2col_lib.h index a05904ee6..8dea47414 100644 --- a/sw/applications/example_im2col/im2col_lib.h +++ b/sw/applications/example_im2col/im2col_lib.h @@ -105,7 +105,7 @@ #define OW_NHWC (FW * FH * CH * BATCH) #define OH_NHWC (N_PATCHES_W) * (N_PATCHES_H) -#define START_ID 0 +#define START_ID 2 #define TEST_EN 1 diff --git a/sw/device/lib/drivers/im2col_spc/im2col.c b/sw/device/lib/drivers/im2col_spc/im2col.c index 3b98983ab..2d02e728d 100644 --- a/sw/device/lib/drivers/im2col_spc/im2col.c +++ b/sw/device/lib/drivers/im2col_spc/im2col.c @@ -18,6 +18,24 @@ void handler_irq_im2col_spc( void ) return; } +/* Simple function to extract the channel from the channel mask */ +int get_channel_number(uint32_t mask) { + int channel = 0; + + // Check the position of the first set bit + while (mask > 0) { + channel++; + if (mask & 1) { // If the least significant bit is set + printf("%d\n", channel); + return channel; + } + mask >>= 1; // Right shift the mask to check the next bit + } + + // If no bit is set, return 0 indicating no valid channel + return 0; +} + int run_im2col(im2col_trans_t trans){ /* Initializing PLIC */ @@ -47,13 +65,20 @@ int run_im2col(im2col_trans_t trans){ dma_init(NULL); - /* Write the number of DMA channels the SPC has access to */ + /* Write the DMA channel mask that the SPC has access to */ write_register( trans.ch_mask, IM2COL_SPC_SPC_CH_MASK_REG_OFFSET, 0xffffffff, 0, IM2COL_SPC_BASE_ADDR ); + /* Write the offset of the DMA channel the SPC has access to */ + write_register( get_channel_number(trans.ch_mask) * DMA_CH_SIZE + DMA_START_ADDRESS, + IM2COL_SPC_SPC_CH_OFFSET_REG_OFFSET, + 0xffffffff, + 0, + IM2COL_SPC_BASE_ADDR ); + /* Write the source */ write_register( trans.src, IM2COL_SPC_SRC_PTR_REG_OFFSET, diff --git a/sw/device/lib/drivers/im2col_spc/im2col.h b/sw/device/lib/drivers/im2col_spc/im2col.h index 0bcd055e7..e8fb92078 100644 --- a/sw/device/lib/drivers/im2col_spc/im2col.h +++ b/sw/device/lib/drivers/im2col_spc/im2col.h @@ -6,7 +6,8 @@ Author: Tommaso Terzano - Info: This simple HAL is used to load the im2col SPC and to run it. + Info: This simple HAL is used to load the im2col SPC and to run it. Remember, only one DMA channel + at a time can be used! */ #ifndef _IM2COL_SPC_ @@ -22,39 +23,34 @@ #include "rv_plic.h" #include "csr.h" #include - #include "mmio.h" #include "handler.h" #include "hart.h" #include "fast_intr_ctrl.h" -// uint32_t IW, uint32_t IH, uint32_t FW, uint32_t FH, uint32_t CH, uint32_t CH_COL, -// uint32_t STRIDE_D1, uint32_t STRIDE_D2, uint32_t BATCH, uint32_t N_PATCHES_W, -// uint32_t N_PATCHES_H, uint32_t LEFT_PAD, uint32_t RIGHT_PAD, uint32_t TOP_PAD, -// uint32_t BOTTOM_PAD, uint32_t ADPT_PAD_RIGHT, uint32_t ADPT_PAD_BOTTOM, - +/* Transaction structure */ typedef struct { - uint32_t* src; /*!< Target from where the data will be copied. */ - uint32_t* dst; /*!< Target to where the data will be copied. */ - uint32_t ch_mask; /*!< Mask of the channels to be used. */ - uint32_t im_width; /*!< Width of the input image. */ - uint32_t im_height; /*!< Height of the input image. */ - uint32_t filter_width; /*!< Width of the filter. */ - uint32_t filter_height; /*!< Height of the filter. */ - uint32_t num_channels; /*!< Number of channels. */ + uint32_t* src; /*!< Target from where the data will be copied. */ + uint32_t* dst; /*!< Target to where the data will be copied. */ + uint32_t ch_mask; /*!< Mask of the channels to be used. */ + uint32_t im_width; /*!< Width of the input image. */ + uint32_t im_height; /*!< Height of the input image. */ + uint32_t filter_width; /*!< Width of the filter. */ + uint32_t filter_height; /*!< Height of the filter. */ + uint32_t num_channels; /*!< Number of channels. */ uint32_t num_channels_col; /*!< Number of channels to be processed. */ - uint32_t stride_d1; /*!< Stride in the first dimension. */ - uint32_t stride_d2; /*!< Stride in the second dimension. */ - uint32_t batch; /*!< Number of batches. */ - uint32_t n_patches_w; /*!< Number of patches in the width. */ - uint32_t n_patches_h; /*!< Number of patches in the height. */ - uint32_t left_pad; /*!< Padding on the left. */ - uint32_t right_pad; /*!< Padding on the right. */ - uint32_t top_pad; /*!< Padding on the top. */ - uint32_t bottom_pad; /*!< Padding on the bottom. */ - uint32_t adpt_pad_right; /*!< Adaptive padding on the right. */ - uint32_t adpt_pad_bottom; /*!< Adaptive padding on the bottom. */ + uint32_t stride_d1; /*!< Stride in the first dimension. */ + uint32_t stride_d2; /*!< Stride in the second dimension. */ + uint32_t batch; /*!< Number of batches. */ + uint32_t n_patches_w; /*!< Number of patches in the width. */ + uint32_t n_patches_h; /*!< Number of patches in the height. */ + uint32_t left_pad; /*!< Padding on the left. */ + uint32_t right_pad; /*!< Padding on the right. */ + uint32_t top_pad; /*!< Padding on the top. */ + uint32_t bottom_pad; /*!< Padding on the bottom. */ + uint32_t adpt_pad_right; /*!< Adaptive padding on the right. */ + uint32_t adpt_pad_bottom; /*!< Adaptive padding on the bottom. */ } im2col_trans_t; /* Base address of the im2col SPC */ diff --git a/sw/device/lib/drivers/im2col_spc/im2col_spc_regs.h b/sw/device/lib/drivers/im2col_spc/im2col_spc_regs.h index a0b798471..4a8e2f67e 100644 --- a/sw/device/lib/drivers/im2col_spc/im2col_spc_regs.h +++ b/sw/device/lib/drivers/im2col_spc/im2col_spc_regs.h @@ -167,9 +167,12 @@ extern "C" { #define IM2COL_SPC_SPC_IFR_REG_OFFSET 0x5c #define IM2COL_SPC_SPC_IFR_FLAG_BIT 0 -// Mask that defines which DMA channels the SPC can access +// Mask that defines which DMA channel the SPC can access #define IM2COL_SPC_SPC_CH_MASK_REG_OFFSET 0x60 +// Offset of the DMA channel the SPC can access +#define IM2COL_SPC_SPC_CH_OFFSET_REG_OFFSET 0x64 + #ifdef __cplusplus } // extern "C" #endif