diff --git a/src/cndm/rtl/cndm_micro_cpl_wr.sv b/src/cndm/rtl/cndm_micro_cpl_wr.sv index 7572a45..3c1bf04 100644 --- a/src/cndm/rtl/cndm_micro_cpl_wr.sv +++ b/src/cndm/rtl/cndm_micro_cpl_wr.sv @@ -59,6 +59,7 @@ cndm_micro_queue_state #( .QN_W(CQN_W), .DQN_W(CQN_W), // TODO .IS_CQ(1), + .QTYPE_EN(0), .QE_SIZE(16), .DMA_ADDR_W(DMA_ADDR_W) ) @@ -81,6 +82,7 @@ cq_mgr_inst ( * Queue management interface */ .req_qn(cq_req_cqn_reg), + .req_qtype('0), .req_valid(cq_req_valid_reg), .req_ready(cq_req_ready), .rsp_qn(), diff --git a/src/cndm/rtl/cndm_micro_desc_rd.sv b/src/cndm/rtl/cndm_micro_desc_rd.sv index f56da0a..ea77771 100644 --- a/src/cndm/rtl/cndm_micro_desc_rd.sv +++ b/src/cndm/rtl/cndm_micro_desc_rd.sv @@ -49,7 +49,15 @@ localparam DMA_ADDR_W = dma_rd_desc_req.SRC_ADDR_W; localparam RAM_ADDR_W = 16; +typedef enum logic [2:0] { + QTYPE_EQ, + QTYPE_CQ, + QTYPE_SQ, + QTYPE_RQ +} qtype_t; + logic [WQN_W-1:0] wq_req_wqn_reg = '0; +logic [2:0] wq_req_qtype_reg = '0; logic wq_req_valid_reg = 1'b0; logic wq_req_ready; logic [CQN_W-1:0] wq_rsp_cqn; @@ -62,6 +70,7 @@ cndm_micro_queue_state #( .QN_W(WQN_W), .DQN_W(CQN_W), .IS_CQ(0), + .QTYPE_EN(1), .QE_SIZE(16), .DMA_ADDR_W(DMA_ADDR_W) ) @@ -84,6 +93,7 @@ wq_mgr_inst ( * Queue management interface */ .req_qn(wq_req_wqn_reg), + .req_qtype(wq_req_qtype_reg), .req_valid(wq_req_valid_reg), .req_ready(wq_req_ready), .rsp_qn(), @@ -162,12 +172,14 @@ always_ff @(posedge clk) begin if (desc_req_reg[1]) begin desc_req_reg[1] <= 1'b0; wq_req_wqn_reg <= 1; + wq_req_qtype_reg <= QTYPE_RQ; wq_req_valid_reg <= 1'b1; dma_desc.req_id <= 1'b1; state_reg <= STATE_QUERY_WQ; end else if (desc_req_reg[0]) begin desc_req_reg[0] <= 1'b0; wq_req_wqn_reg <= 0; + wq_req_qtype_reg <= QTYPE_SQ; wq_req_valid_reg <= 1'b1; dma_desc.req_id <= 1'b0; state_reg <= STATE_QUERY_WQ; diff --git a/src/cndm/rtl/cndm_micro_dp_mgr.sv b/src/cndm/rtl/cndm_micro_dp_mgr.sv index cba8b66..4ee8d70 100644 --- a/src/cndm/rtl/cndm_micro_dp_mgr.sv +++ b/src/cndm/rtl/cndm_micro_dp_mgr.sv @@ -81,6 +81,13 @@ typedef enum logic [15:0] { CMD_OP_DESTROY_QP = 16'h0243 } cmd_opcode_t; +typedef enum logic [2:0] { + QTYPE_EQ, + QTYPE_CQ, + QTYPE_SQ, + QTYPE_RQ +} qtype_t; + typedef enum logic [4:0] { STATE_IDLE, STATE_START, @@ -162,6 +169,7 @@ logic [31:0] flags_reg = '0, flags_next; logic [15:0] port_reg = '0, port_next; logic [23:0] qn_reg = '0, qn_next; logic [23:0] qn2_reg = '0, qn2_next; +logic [2:0] qtype_reg = '0, qtype_next; logic [3:0] cmd_ptr_reg = '0, cmd_ptr_next; logic [DP_APB_ADDR_W-1:0] dp_ptr_reg = '0, dp_ptr_next; @@ -201,6 +209,7 @@ always_comb begin port_next = port_reg; qn_next = qn_reg; qn2_next = qn2_reg; + qtype_next = qtype_reg; cmd_ptr_next = cmd_ptr_reg; dp_ptr_next = dp_ptr_reg; @@ -272,6 +281,7 @@ always_comb begin CMD_OP_CREATE_CQ: begin cnt_next = 2**CQN_W-1; + qtype_next = QTYPE_CQ; dp_ptr_next = DP_APB_ADDR_W'({port_reg, 16'd0} | 'h8000) + DP_APB_ADDR_W'(PORT_BASE_ADDR_DP); host_ptr_next = 32'({port_reg, 16'd0} | 'h8000) + PORT_BASE_ADDR_HOST; end @@ -279,6 +289,7 @@ always_comb begin CMD_OP_QUERY_CQ, CMD_OP_DESTROY_CQ: begin + qtype_next = QTYPE_CQ; dp_ptr_next = DP_APB_ADDR_W'({port_reg, 16'd0} | 'h8000 | {qn_reg, 5'd00}) + DP_APB_ADDR_W'(PORT_BASE_ADDR_DP); host_ptr_next = 32'({port_reg, 16'd0} | 'h8000 | {qn_reg, 5'd00}) + PORT_BASE_ADDR_HOST; end @@ -286,6 +297,7 @@ always_comb begin CMD_OP_CREATE_SQ: begin cnt_next = 0; + qtype_next = QTYPE_SQ; dp_ptr_next = DP_APB_ADDR_W'({port_reg, 16'd0} | 'h0000) + DP_APB_ADDR_W'(PORT_BASE_ADDR_DP); host_ptr_next = 32'({port_reg, 16'd0} | 'h0000) + PORT_BASE_ADDR_HOST; end @@ -293,6 +305,7 @@ always_comb begin CMD_OP_QUERY_SQ, CMD_OP_DESTROY_SQ: begin + qtype_next = QTYPE_SQ; dp_ptr_next = DP_APB_ADDR_W'({port_reg, 16'd0} | 'h0000) + DP_APB_ADDR_W'(PORT_BASE_ADDR_DP); host_ptr_next = 32'({port_reg, 16'd0} | 'h0000) + PORT_BASE_ADDR_HOST; end @@ -300,6 +313,7 @@ always_comb begin CMD_OP_CREATE_RQ: begin cnt_next = 0; + qtype_next = QTYPE_RQ; dp_ptr_next = DP_APB_ADDR_W'({port_reg, 16'd0} | 'h0020) + DP_APB_ADDR_W'(PORT_BASE_ADDR_DP); host_ptr_next = 32'({port_reg, 16'd0} | 'h0020) + PORT_BASE_ADDR_HOST; end @@ -307,6 +321,7 @@ always_comb begin CMD_OP_QUERY_RQ, CMD_OP_DESTROY_RQ: begin + qtype_next = QTYPE_RQ; dp_ptr_next = DP_APB_ADDR_W'({port_reg, 16'd0} | 'h0020) + DP_APB_ADDR_W'(PORT_BASE_ADDR_DP); host_ptr_next = 32'({port_reg, 16'd0} | 'h0020) + PORT_BASE_ADDR_HOST; end @@ -600,6 +615,7 @@ always_comb begin m_apb_dp_ctrl_pwrite_next = 1'b1; m_apb_dp_ctrl_pwdata_next = '0; m_apb_dp_ctrl_pwdata_next[19:16] = cmd_ram_rd_data[3:0]; + m_apb_dp_ctrl_pwdata_next[23:20] = 4'(qtype_reg); m_apb_dp_ctrl_pwdata_next[0] = 1'b1; m_apb_dp_ctrl_pstrb_next = '1; @@ -855,6 +871,7 @@ always_ff @(posedge clk) begin port_reg <= port_next; qn_reg <= qn_next; qn2_reg <= qn2_next; + qtype_reg <= qtype_next; cmd_ptr_reg <= cmd_ptr_next; dp_ptr_reg <= dp_ptr_next; diff --git a/src/cndm/rtl/cndm_micro_queue_state.sv b/src/cndm/rtl/cndm_micro_queue_state.sv index b91621d..b5c3288 100644 --- a/src/cndm/rtl/cndm_micro_queue_state.sv +++ b/src/cndm/rtl/cndm_micro_queue_state.sv @@ -19,6 +19,7 @@ module cndm_micro_queue_state #( parameter QN_W = 5, parameter DQN_W = 5, parameter logic IS_CQ = 1'b0, + parameter logic QTYPE_EN = !IS_CQ, parameter QE_SIZE = 16, parameter DMA_ADDR_W = 64 ) @@ -41,6 +42,7 @@ module cndm_micro_queue_state #( * Queue management interface */ input wire logic [QN_W-1:0] req_qn, + input wire logic [2:0] req_qtype, input wire logic req_valid, output wire logic req_ready, output wire logic [QN_W-1:0] rsp_qn, @@ -130,6 +132,8 @@ assign rsp_valid = rsp_valid_reg; logic [2**QN_W-1:0] queue_enable_reg = '0; (* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) +logic [2:0] queue_mem_qtype[2**QN_W] = '{default: '0}; +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) logic [DQN_W-1:0] queue_mem_dqn[2**QN_W] = '{default: '0}; (* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) logic [3:0] queue_mem_log_size[2**QN_W] = '{default: '0}; @@ -144,6 +148,7 @@ logic queue_mem_wr_en; logic [QN_W-1:0] queue_mem_addr; wire queue_mem_rd_enable = queue_enable_reg[queue_mem_addr]; +wire [2:0] queue_mem_rd_qtype = queue_mem_qtype[queue_mem_addr]; wire [DQN_W-1:0] queue_mem_rd_dqn = queue_mem_dqn[queue_mem_addr]; wire [3:0] queue_mem_rd_log_size = queue_mem_log_size[queue_mem_addr]; wire [DMA_ADDR_W-1:0] queue_mem_rd_base_addr = queue_mem_base_addr[queue_mem_addr]; @@ -151,6 +156,7 @@ wire [PTR_W-1:0] queue_mem_rd_prod_ptr = queue_mem_prod_ptr[queue_mem_addr]; wire [PTR_W-1:0] queue_mem_rd_cons_ptr = queue_mem_cons_ptr[queue_mem_addr]; logic queue_mem_wr_enable; +logic [2:0] queue_mem_wr_qtype; logic [DQN_W-1:0] queue_mem_wr_dqn; logic [3:0] queue_mem_wr_log_size; logic [DMA_ADDR_W-1:0] queue_mem_wr_base_addr; @@ -181,6 +187,7 @@ always_comb begin queue_mem_addr = '0; queue_mem_wr_enable = queue_mem_rd_enable; + queue_mem_wr_qtype = queue_mem_rd_qtype; queue_mem_wr_dqn = queue_mem_rd_dqn; queue_mem_wr_log_size = queue_mem_rd_log_size; queue_mem_wr_base_addr = queue_mem_rd_base_addr; @@ -230,6 +237,7 @@ always_comb begin 3'd0: begin queue_mem_wr_enable = s_apb_dp_ctrl.pwdata[0]; queue_mem_wr_log_size = s_apb_dp_ctrl.pwdata[19:16]; + queue_mem_wr_qtype = 3'(s_apb_dp_ctrl.pwdata[23:20]); end 3'd1: queue_mem_wr_dqn = s_apb_dp_ctrl.pwdata[DQN_W-1:0]; 3'd2: queue_mem_wr_prod_ptr = s_apb_dp_ctrl.pwdata[15:0]; @@ -244,6 +252,7 @@ always_comb begin 3'd0: begin s_apb_dp_ctrl_prdata_next[0] = queue_mem_rd_enable; s_apb_dp_ctrl_prdata_next[19:16] = queue_mem_rd_log_size; + s_apb_dp_ctrl_prdata_next[23:20] = 4'(queue_mem_rd_qtype); end 3'd1: s_apb_dp_ctrl_prdata_next = 32'(queue_mem_rd_dqn); 3'd2: s_apb_dp_ctrl_prdata_next[15:0] = queue_mem_rd_prod_ptr; @@ -261,14 +270,15 @@ always_comb begin rsp_qn_next = req_qn; rsp_dqn_next = queue_mem_rd_dqn; + rsp_error_next = !queue_mem_rd_enable || (QTYPE_EN && req_qtype != queue_mem_rd_qtype); if (IS_CQ) begin rsp_addr_next = queue_mem_rd_base_addr + DMA_ADDR_W'(16'(queue_mem_rd_prod_ptr & ({16{1'b1}} >> (16 - queue_mem_rd_log_size))) * QE_SIZE); rsp_phase_tag_next = !queue_mem_rd_prod_ptr[queue_mem_rd_log_size]; - rsp_error_next = !queue_mem_rd_enable; queue_mem_wr_prod_ptr = queue_mem_rd_prod_ptr + 1; end else begin rsp_addr_next = queue_mem_rd_base_addr + DMA_ADDR_W'(16'(queue_mem_rd_cons_ptr & ({16{1'b1}} >> (16 - queue_mem_rd_log_size))) * QE_SIZE); - rsp_error_next = !queue_mem_rd_enable || queue_mem_rd_prod_ptr == queue_mem_rd_cons_ptr; + if (queue_mem_rd_prod_ptr == queue_mem_rd_cons_ptr) + rsp_error_next = 1'b1; queue_mem_wr_cons_ptr = queue_mem_rd_cons_ptr + 1; end rsp_valid_next = 1'b1; @@ -301,6 +311,7 @@ always @(posedge clk) begin if (queue_mem_wr_en) begin queue_enable_reg[queue_mem_addr] <= queue_mem_wr_enable; + queue_mem_qtype[queue_mem_addr] <= queue_mem_wr_qtype; queue_mem_dqn[queue_mem_addr] <= queue_mem_wr_dqn; queue_mem_log_size[queue_mem_addr] <= queue_mem_wr_log_size; queue_mem_base_addr[queue_mem_addr] <= queue_mem_wr_base_addr;