diff --git a/src/cndm/rtl/cndm_micro_core.sv b/src/cndm/rtl/cndm_micro_core.sv index 6be7e75..9fc0e18 100644 --- a/src/cndm/rtl/cndm_micro_core.sv +++ b/src/cndm/rtl/cndm_micro_core.sv @@ -37,7 +37,8 @@ module cndm_micro_core #( parameter PORTS = 2, // Queue configuration - parameter CQN_W = 5, + parameter WQN_W = 5, + parameter CQN_W = WQN_W, // PTP configuration parameter logic PTP_TS_EN = 1'b1, @@ -312,6 +313,7 @@ apb_dp_ctrl(); cndm_micro_dp_mgr #( .PORTS(PORTS), + .WQN_W(WQN_W), .CQN_W(CQN_W), .PTP_EN(PTP_TS_EN), @@ -498,6 +500,7 @@ for (genvar p = 0; p < PORTS; p = p + 1) begin : port cndm_micro_port #( // Queue configuration + .WQN_W(WQN_W), .CQN_W(CQN_W), // PTP configuration diff --git a/src/cndm/rtl/cndm_micro_cpl_wr.sv b/src/cndm/rtl/cndm_micro_cpl_wr.sv index 067a487..7572a45 100644 --- a/src/cndm/rtl/cndm_micro_cpl_wr.sv +++ b/src/cndm/rtl/cndm_micro_cpl_wr.sv @@ -50,7 +50,7 @@ logic [CQN_W-1:0] cq_req_cqn_reg = '0; logic cq_req_valid_reg = 1'b0; logic cq_req_ready; logic [DMA_ADDR_W-1:0] cq_rsp_addr; -logic cq_rsp_phase; +logic cq_rsp_phase_tag; logic cq_rsp_error; logic cq_rsp_valid; logic cq_rsp_ready_reg = 1'b0; @@ -58,7 +58,8 @@ logic cq_rsp_ready_reg = 1'b0; cndm_micro_queue_state #( .QN_W(CQN_W), .DQN_W(CQN_W), // TODO - .CPL_SIZE(16), + .IS_CQ(1), + .QE_SIZE(16), .DMA_ADDR_W(DMA_ADDR_W) ) cq_mgr_inst ( @@ -77,7 +78,7 @@ cq_mgr_inst ( .s_apb_dp_ctrl(s_apb_dp_ctrl), /* - * CQ management interface + * Queue management interface */ .req_qn(cq_req_cqn_reg), .req_valid(cq_req_valid_reg), @@ -85,7 +86,7 @@ cq_mgr_inst ( .rsp_qn(), .rsp_dqn(), .rsp_addr(cq_rsp_addr), - .rsp_phase(cq_rsp_phase), + .rsp_phase_tag(cq_rsp_phase_tag), .rsp_error(cq_rsp_error), .rsp_valid(cq_rsp_valid), .rsp_ready(cq_rsp_ready_reg) @@ -130,7 +131,7 @@ always_ff @(posedge clk) begin STATE_IDLE: begin dma_wr_desc_req.req_src_addr <= '0; - cq_req_cqn_reg <= CQN_W'(s_axis_cpl.tdest); + cq_req_cqn_reg <= s_axis_cpl.tdest; if (s_axis_cpl.tvalid && !s_axis_cpl.tready) begin cq_req_valid_reg <= 1'b1; @@ -143,11 +144,11 @@ always_ff @(posedge clk) begin dma_wr_desc_req.req_src_addr <= '0; cq_rsp_ready_reg <= 1'b1; - if (cq_rsp_valid) begin + if (cq_rsp_valid && cq_rsp_ready_reg) begin cq_rsp_ready_reg <= 1'b0; dma_wr_desc_req.req_dst_addr <= cq_rsp_addr; - phase_tag_reg <= cq_rsp_phase; + phase_tag_reg <= cq_rsp_phase_tag; if (cq_rsp_error) begin // drop completion diff --git a/src/cndm/rtl/cndm_micro_desc_rd.sv b/src/cndm/rtl/cndm_micro_desc_rd.sv index 3dda7ca..f56da0a 100644 --- a/src/cndm/rtl/cndm_micro_desc_rd.sv +++ b/src/cndm/rtl/cndm_micro_desc_rd.sv @@ -15,7 +15,10 @@ Authors: /* * Corundum-micro descriptor read module */ -module cndm_micro_desc_rd +module cndm_micro_desc_rd #( + parameter WQN_W = 5, + parameter CQN_W = 5 +) ( input wire logic clk, input wire logic rst, @@ -42,190 +45,55 @@ module cndm_micro_desc_rd taxi_axis_if.src m_axis_desc ); -localparam AXIL_ADDR_W = s_axil_ctrl_wr.ADDR_W; -localparam AXIL_DATA_W = s_axil_ctrl_wr.DATA_W; - -localparam APB_ADDR_W = s_apb_dp_ctrl.ADDR_W; -localparam APB_DATA_W = s_apb_dp_ctrl.DATA_W; +localparam DMA_ADDR_W = dma_rd_desc_req.SRC_ADDR_W; localparam RAM_ADDR_W = 16; -logic txq_en_reg = '0; -logic [3:0] txq_size_reg = '0; -logic [7:0] txq_cqn_reg = '0; -logic [63:0] txq_base_addr_reg = '0; -logic [15:0] txq_prod_reg = '0; -logic rxq_en_reg = '0; -logic [3:0] rxq_size_reg = '0; -logic [7:0] rxq_cqn_reg = '0; -logic [63:0] rxq_base_addr_reg = '0; -logic [15:0] rxq_prod_reg = '0; +logic [WQN_W-1:0] wq_req_wqn_reg = '0; +logic wq_req_valid_reg = 1'b0; +logic wq_req_ready; +logic [CQN_W-1:0] wq_rsp_cqn; +logic [DMA_ADDR_W-1:0] wq_rsp_addr; +logic wq_rsp_error; +logic wq_rsp_valid; +logic wq_rsp_ready_reg = 1'b0; -logic [15:0] txq_cons_ptr_reg = '0; -logic [15:0] rxq_cons_ptr_reg = '0; +cndm_micro_queue_state #( + .QN_W(WQN_W), + .DQN_W(CQN_W), + .IS_CQ(0), + .QE_SIZE(16), + .DMA_ADDR_W(DMA_ADDR_W) +) +wq_mgr_inst ( + .clk(clk), + .rst(rst), -logic s_axil_ctrl_awready_reg = 1'b0; -logic s_axil_ctrl_wready_reg = 1'b0; -logic s_axil_ctrl_bvalid_reg = 1'b0; + /* + * Control register interface + */ + .s_axil_ctrl_wr(s_axil_ctrl_wr), + .s_axil_ctrl_rd(s_axil_ctrl_rd), -logic s_axil_ctrl_arready_reg = 1'b0; -logic [AXIL_DATA_W-1:0] s_axil_ctrl_rdata_reg = '0; -logic s_axil_ctrl_rvalid_reg = 1'b0; + /* + * Datapath control register interface + */ + .s_apb_dp_ctrl(s_apb_dp_ctrl), -assign s_axil_ctrl_wr.awready = s_axil_ctrl_awready_reg; -assign s_axil_ctrl_wr.wready = s_axil_ctrl_wready_reg; -assign s_axil_ctrl_wr.bresp = '0; -assign s_axil_ctrl_wr.buser = '0; -assign s_axil_ctrl_wr.bvalid = s_axil_ctrl_bvalid_reg; - -assign s_axil_ctrl_rd.arready = s_axil_ctrl_arready_reg; -assign s_axil_ctrl_rd.rdata = s_axil_ctrl_rdata_reg; -assign s_axil_ctrl_rd.rresp = '0; -assign s_axil_ctrl_rd.ruser = '0; -assign s_axil_ctrl_rd.rvalid = s_axil_ctrl_rvalid_reg; - -logic s_apb_dp_ctrl_pready_reg = 1'b0; -logic [AXIL_DATA_W-1:0] s_apb_dp_ctrl_prdata_reg = '0; - -assign s_apb_dp_ctrl.pready = s_apb_dp_ctrl_pready_reg; -assign s_apb_dp_ctrl.prdata = s_apb_dp_ctrl_prdata_reg; -assign s_apb_dp_ctrl.pslverr = 1'b0; -assign s_apb_dp_ctrl.pruser = '0; -assign s_apb_dp_ctrl.pbuser = '0; - -always_ff @(posedge clk) begin - s_axil_ctrl_awready_reg <= 1'b0; - s_axil_ctrl_wready_reg <= 1'b0; - s_axil_ctrl_bvalid_reg <= s_axil_ctrl_bvalid_reg && !s_axil_ctrl_wr.bready; - - s_axil_ctrl_arready_reg <= 1'b0; - s_axil_ctrl_rvalid_reg <= s_axil_ctrl_rvalid_reg && !s_axil_ctrl_rd.rready; - - s_apb_dp_ctrl_pready_reg <= 1'b0; - - if (s_axil_ctrl_wr.awvalid && s_axil_ctrl_wr.wvalid && !s_axil_ctrl_bvalid_reg) begin - s_axil_ctrl_awready_reg <= 1'b1; - s_axil_ctrl_wready_reg <= 1'b1; - s_axil_ctrl_bvalid_reg <= 1'b1; - - case ({s_axil_ctrl_wr.awaddr[9:2], 2'b00}) - // 10'h000: begin - // txq_en_reg <= s_axil_ctrl_wr.wdata[0]; - // txq_size_reg <= s_axil_ctrl_wr.wdata[19:16]; - // end - 10'h004: txq_prod_reg <= s_axil_ctrl_wr.wdata[15:0]; - // 10'h008: txq_base_addr_reg[31:0] <= s_axil_ctrl_wr.wdata; - // 10'h00c: txq_base_addr_reg[63:32] <= s_axil_ctrl_wr.wdata; - - // 10'h100: begin - // rxq_en_reg <= s_axil_ctrl_wr.wdata[0]; - // rxq_size_reg <= s_axil_ctrl_wr.wdata[19:16]; - // end - 10'h104: rxq_prod_reg <= s_axil_ctrl_wr.wdata[15:0]; - // 10'h108: rxq_base_addr_reg[31:0] <= s_axil_ctrl_wr.wdata; - // 10'h10c: rxq_base_addr_reg[63:32] <= s_axil_ctrl_wr.wdata; - default: begin end - endcase - end - - if (s_axil_ctrl_rd.arvalid && !s_axil_ctrl_rvalid_reg) begin - s_axil_ctrl_rdata_reg <= '0; - - s_axil_ctrl_arready_reg <= 1'b1; - s_axil_ctrl_rvalid_reg <= 1'b1; - - // case ({s_axil_ctrl_rd.araddr[9:2], 2'b00}) - // 10'h000: begin - // s_axil_ctrl_rdata_reg[0] <= txq_en_reg; - // s_axil_ctrl_rdata_reg[19:16] <= txq_size_reg; - // end - // 10'h004: begin - // s_axil_ctrl_rdata_reg[15:0] <= txq_prod_reg; - // s_axil_ctrl_rdata_reg[31:16] <= txq_cons_ptr_reg; - // end - // 10'h008: s_axil_ctrl_rdata_reg <= txq_base_addr_reg[31:0]; - // 10'h00c: s_axil_ctrl_rdata_reg <= txq_base_addr_reg[63:32]; - - // 10'h100: begin - // s_axil_ctrl_rdata_reg[0] <= rxq_en_reg; - // s_axil_ctrl_rdata_reg[19:16] <= rxq_size_reg; - // end - // 10'h104: begin - // s_axil_ctrl_rdata_reg[15:0] <= rxq_prod_reg; - // s_axil_ctrl_rdata_reg[31:16] <= rxq_cons_ptr_reg; - // end - // 10'h108: s_axil_ctrl_rdata_reg <= rxq_base_addr_reg[31:0]; - // 10'h10c: s_axil_ctrl_rdata_reg <= rxq_base_addr_reg[63:32]; - // default: begin end - // endcase - end - - if (s_apb_dp_ctrl.penable && s_apb_dp_ctrl.psel && !s_apb_dp_ctrl_pready_reg) begin - s_apb_dp_ctrl_pready_reg <= 1'b1; - s_apb_dp_ctrl_prdata_reg <= '0; - - if (s_apb_dp_ctrl.pwrite) begin - case ({s_apb_dp_ctrl.paddr[9:2], 2'b00}) - 10'h000: begin - txq_en_reg <= s_apb_dp_ctrl.pwdata[0]; - txq_size_reg <= s_apb_dp_ctrl.pwdata[19:16]; - txq_cqn_reg <= s_apb_dp_ctrl.pwdata[31:24]; - end - 10'h004: txq_prod_reg <= s_apb_dp_ctrl.pwdata[15:0]; - 10'h008: txq_base_addr_reg[31:0] <= s_apb_dp_ctrl.pwdata; - 10'h00c: txq_base_addr_reg[63:32] <= s_apb_dp_ctrl.pwdata; - - 10'h100: begin - rxq_en_reg <= s_apb_dp_ctrl.pwdata[0]; - rxq_size_reg <= s_apb_dp_ctrl.pwdata[19:16]; - rxq_cqn_reg <= s_apb_dp_ctrl.pwdata[31:24]; - end - 10'h104: rxq_prod_reg <= s_apb_dp_ctrl.pwdata[15:0]; - 10'h108: rxq_base_addr_reg[31:0] <= s_apb_dp_ctrl.pwdata; - 10'h10c: rxq_base_addr_reg[63:32] <= s_apb_dp_ctrl.pwdata; - default: begin end - endcase - end - - case ({s_apb_dp_ctrl.paddr[9:2], 2'b00}) - 10'h000: begin - s_apb_dp_ctrl_prdata_reg[0] <= txq_en_reg; - s_apb_dp_ctrl_prdata_reg[19:16] <= txq_size_reg; - s_apb_dp_ctrl_prdata_reg[31:24] <= txq_cqn_reg; - end - 10'h004: begin - s_apb_dp_ctrl_prdata_reg[15:0] <= txq_prod_reg; - s_apb_dp_ctrl_prdata_reg[31:16] <= txq_cons_ptr_reg; - end - 10'h008: s_apb_dp_ctrl_prdata_reg <= txq_base_addr_reg[31:0]; - 10'h00c: s_apb_dp_ctrl_prdata_reg <= txq_base_addr_reg[63:32]; - - 10'h100: begin - s_apb_dp_ctrl_prdata_reg[0] <= rxq_en_reg; - s_apb_dp_ctrl_prdata_reg[19:16] <= rxq_size_reg; - s_apb_dp_ctrl_prdata_reg[31:24] <= rxq_cqn_reg; - end - 10'h104: begin - s_apb_dp_ctrl_prdata_reg[15:0] <= rxq_prod_reg; - s_apb_dp_ctrl_prdata_reg[31:16] <= rxq_cons_ptr_reg; - end - 10'h108: s_apb_dp_ctrl_prdata_reg <= rxq_base_addr_reg[31:0]; - 10'h10c: s_apb_dp_ctrl_prdata_reg <= rxq_base_addr_reg[63:32]; - default: begin end - endcase - end - - if (rst) begin - s_axil_ctrl_awready_reg <= 1'b0; - s_axil_ctrl_wready_reg <= 1'b0; - s_axil_ctrl_bvalid_reg <= 1'b0; - - s_axil_ctrl_arready_reg <= 1'b0; - s_axil_ctrl_rvalid_reg <= 1'b0; - - s_apb_dp_ctrl_pready_reg <= 1'b0; - end -end + /* + * Queue management interface + */ + .req_qn(wq_req_wqn_reg), + .req_valid(wq_req_valid_reg), + .req_ready(wq_req_ready), + .rsp_qn(), + .rsp_dqn(wq_rsp_cqn), + .rsp_addr(wq_rsp_addr), + .rsp_phase_tag(), + .rsp_error(wq_rsp_error), + .rsp_valid(wq_rsp_valid), + .rsp_ready(wq_rsp_ready_reg) +); taxi_dma_desc_if #( .SRC_ADDR_W(RAM_ADDR_W), @@ -247,8 +115,8 @@ taxi_dma_desc_if #( typedef enum logic [1:0] { STATE_IDLE, + STATE_QUERY_WQ, STATE_READ_DESC, - STATE_READ_DATA, STATE_TX_DESC } state_t; @@ -257,8 +125,6 @@ state_t state_reg = STATE_IDLE; logic [1:0] desc_req_reg = '0; always_ff @(posedge clk) begin - // axis_desc.tready <= 1'b0; - dma_rd_desc_req.req_src_sel <= '0; dma_rd_desc_req.req_src_asid <= '0; dma_rd_desc_req.req_dst_sel <= '0; @@ -284,46 +150,50 @@ always_ff @(posedge clk) begin dma_desc.req_user <= '0; dma_desc.req_valid <= dma_desc.req_valid && !dma_desc.req_ready; + wq_req_valid_reg <= wq_req_valid_reg && !wq_req_ready; + wq_rsp_ready_reg <= 1'b0; + desc_req_reg <= desc_req_reg | desc_req; - if (!txq_en_reg) begin - txq_cons_ptr_reg <= '0; - end - - if (!rxq_en_reg) begin - rxq_cons_ptr_reg <= '0; - end - case (state_reg) STATE_IDLE: begin + wq_req_wqn_reg <= 0; + if (desc_req_reg[1]) begin - dma_rd_desc_req.req_src_addr <= rxq_base_addr_reg + 64'(16'(rxq_cons_ptr_reg & ({16{1'b1}} >> (16 - rxq_size_reg))) * 16); - dma_desc.req_id <= 1'b1; - dma_desc.req_dest <= rxq_cqn_reg; desc_req_reg[1] <= 1'b0; - if (rxq_cons_ptr_reg == rxq_prod_reg || !rxq_en_reg) begin - dma_desc.req_user <= 1'b1; - dma_desc.req_valid <= 1'b1; - state_reg <= STATE_TX_DESC; - end else begin - dma_desc.req_user <= 1'b0; - dma_rd_desc_req.req_valid <= 1'b1; - rxq_cons_ptr_reg <= rxq_cons_ptr_reg + 1; - state_reg <= STATE_READ_DESC; - end + wq_req_wqn_reg <= 1; + 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 - dma_rd_desc_req.req_src_addr <= txq_base_addr_reg + 64'(16'(txq_cons_ptr_reg & ({16{1'b1}} >> (16 - txq_size_reg))) * 16); - dma_desc.req_id <= 1'b0; - dma_desc.req_dest <= txq_cqn_reg; desc_req_reg[0] <= 1'b0; - if (txq_cons_ptr_reg == txq_prod_reg || !txq_en_reg) begin + wq_req_wqn_reg <= 0; + wq_req_valid_reg <= 1'b1; + dma_desc.req_id <= 1'b0; + state_reg <= STATE_QUERY_WQ; + end else begin + state_reg <= STATE_IDLE; + end + end + STATE_QUERY_WQ: begin + wq_rsp_ready_reg <= 1'b1; + + if (wq_rsp_valid && wq_rsp_ready_reg) begin + wq_rsp_ready_reg <= 1'b0; + + dma_rd_desc_req.req_src_addr <= wq_rsp_addr; + + dma_desc.req_dest <= wq_rsp_cqn; + + if (wq_rsp_error) begin + // report error dma_desc.req_user <= 1'b1; dma_desc.req_valid <= 1'b1; state_reg <= STATE_TX_DESC; end else begin + // read desc dma_desc.req_user <= 1'b0; dma_rd_desc_req.req_valid <= 1'b1; - txq_cons_ptr_reg <= txq_cons_ptr_reg + 1; state_reg <= STATE_READ_DESC; end end diff --git a/src/cndm/rtl/cndm_micro_dp_mgr.sv b/src/cndm/rtl/cndm_micro_dp_mgr.sv index 6945e66..cba8b66 100644 --- a/src/cndm/rtl/cndm_micro_dp_mgr.sv +++ b/src/cndm/rtl/cndm_micro_dp_mgr.sv @@ -19,7 +19,8 @@ module cndm_micro_dp_mgr # ( parameter PORTS = 2, - parameter CQN_W = 5, + parameter WQN_W = 5, + parameter CQN_W = WQN_W, parameter logic PTP_EN = 1'b1, parameter PTP_BASE_ADDR_DP = 0, @@ -90,8 +91,10 @@ typedef enum logic [4:0] { STATE_CREATE_Q_FIND_2, STATE_CREATE_Q_RESET_1, STATE_CREATE_Q_RESET_2, + STATE_CREATE_Q_RESET_3, STATE_CREATE_Q_SET_BASE_L, STATE_CREATE_Q_SET_BASE_H, + STATE_CREATE_Q_SET_DQN, STATE_CREATE_Q_ENABLE, STATE_DESTROY_Q_DISABLE, STATE_PTP_READ_1, @@ -297,15 +300,15 @@ always_comb begin CMD_OP_CREATE_RQ: begin cnt_next = 0; - dp_ptr_next = DP_APB_ADDR_W'({port_reg, 16'd0} | 'h0100) + DP_APB_ADDR_W'(PORT_BASE_ADDR_DP); - host_ptr_next = 32'({port_reg, 16'd0} | 'h0100) + PORT_BASE_ADDR_HOST; + 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 CMD_OP_MODIFY_RQ, CMD_OP_QUERY_RQ, CMD_OP_DESTROY_RQ: begin - dp_ptr_next = DP_APB_ADDR_W'({port_reg, 16'd0} | 'h0100) + DP_APB_ADDR_W'(PORT_BASE_ADDR_DP); - host_ptr_next = 32'({port_reg, 16'd0} | 'h0100) + PORT_BASE_ADDR_HOST; + 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 default: begin end endcase @@ -512,12 +515,27 @@ always_comb begin // reset queue 2 // store doorbell offset - cmd_ram_wr_data = host_ptr_reg + 'h0004; + cmd_ram_wr_data = host_ptr_reg + 'h0008; cmd_ram_wr_addr = 7; cmd_ram_wr_en = 1'b1; if (!m_apb_dp_ctrl_psel_reg) begin - m_apb_dp_ctrl_paddr_next = dp_ptr_reg + 'h0004; + m_apb_dp_ctrl_paddr_next = dp_ptr_reg + 'h0008; + m_apb_dp_ctrl_psel_next = 1'b1; + m_apb_dp_ctrl_pwrite_next = 1'b1; + m_apb_dp_ctrl_pwdata_next = 32'h00000000; + m_apb_dp_ctrl_pstrb_next = '1; + + state_next = STATE_CREATE_Q_RESET_3; + end else begin + state_next = STATE_CREATE_Q_RESET_2; + end + end + STATE_CREATE_Q_RESET_3: begin + // reset queue 2 + + if (!m_apb_dp_ctrl_psel_reg) begin + m_apb_dp_ctrl_paddr_next = dp_ptr_reg + 'h000c; m_apb_dp_ctrl_psel_next = 1'b1; m_apb_dp_ctrl_pwrite_next = 1'b1; m_apb_dp_ctrl_pwdata_next = 32'h00000000; @@ -525,14 +543,14 @@ always_comb begin state_next = STATE_CREATE_Q_SET_BASE_L; end else begin - state_next = STATE_CREATE_Q_RESET_2; + state_next = STATE_CREATE_Q_RESET_3; end end STATE_CREATE_Q_SET_BASE_L: begin // set queue base addr (LSB) cmd_ram_rd_addr = 8; if (!m_apb_dp_ctrl_psel_reg) begin - m_apb_dp_ctrl_paddr_next = dp_ptr_reg + 'h0008; + m_apb_dp_ctrl_paddr_next = dp_ptr_reg + 'h0018; m_apb_dp_ctrl_psel_next = 1'b1; m_apb_dp_ctrl_pwrite_next = 1'b1; m_apb_dp_ctrl_pwdata_next = cmd_ram_rd_data; @@ -547,7 +565,7 @@ always_comb begin // set queue base addr (MSB) cmd_ram_rd_addr = 9; if (!m_apb_dp_ctrl_psel_reg) begin - m_apb_dp_ctrl_paddr_next = dp_ptr_reg + 'h000C; + m_apb_dp_ctrl_paddr_next = dp_ptr_reg + 'h001C; m_apb_dp_ctrl_psel_next = 1'b1; m_apb_dp_ctrl_pwrite_next = 1'b1; m_apb_dp_ctrl_pwdata_next = cmd_ram_rd_data; @@ -555,7 +573,22 @@ always_comb begin state_next = STATE_CREATE_Q_ENABLE; end else begin - state_next = STATE_CREATE_Q_SET_BASE_H; + state_next = STATE_CREATE_Q_SET_DQN; + end + end + STATE_CREATE_Q_SET_DQN: begin + // set CQN/EQN/IRQN + cmd_ram_rd_addr = 4; + if (!m_apb_dp_ctrl_psel_reg) begin + m_apb_dp_ctrl_paddr_next = dp_ptr_reg + 'h0004; + m_apb_dp_ctrl_psel_next = 1'b1; + m_apb_dp_ctrl_pwrite_next = 1'b1; + m_apb_dp_ctrl_pwdata_next = cmd_ram_rd_data; + m_apb_dp_ctrl_pstrb_next = '1; + + state_next = STATE_CREATE_Q_ENABLE; + end else begin + state_next = STATE_CREATE_Q_SET_DQN; end end STATE_CREATE_Q_ENABLE: begin @@ -566,7 +599,6 @@ always_comb begin m_apb_dp_ctrl_psel_next = 1'b1; m_apb_dp_ctrl_pwrite_next = 1'b1; m_apb_dp_ctrl_pwdata_next = '0; - m_apb_dp_ctrl_pwdata_next[31:24] = qn2_reg[7:0]; m_apb_dp_ctrl_pwdata_next[19:16] = cmd_ram_rd_data[3:0]; m_apb_dp_ctrl_pwdata_next[0] = 1'b1; m_apb_dp_ctrl_pstrb_next = '1; diff --git a/src/cndm/rtl/cndm_micro_port.sv b/src/cndm/rtl/cndm_micro_port.sv index aa65e6a..fd6a605 100644 --- a/src/cndm/rtl/cndm_micro_port.sv +++ b/src/cndm/rtl/cndm_micro_port.sv @@ -17,7 +17,8 @@ Authors: */ module cndm_micro_port #( // Queue configuration - parameter CQN_W = 5, + parameter WQN_W = 5, + parameter CQN_W = WQN_W, // PTP configuration parameter logic PTP_TS_EN = 1'b1, @@ -275,12 +276,15 @@ taxi_axis_if #( .ID_EN(1), .ID_W(1), .DEST_EN(1), - .DEST_W(8), + .DEST_W(WQN_W), .USER_EN(1), .USER_W(1) ) axis_desc(); -cndm_micro_desc_rd +cndm_micro_desc_rd #( + .WQN_W(WQN_W), + .CQN_W(CQN_W) +) desc_rd_inst ( .clk(clk), .rst(rst), @@ -354,7 +358,7 @@ taxi_axis_if #( .LAST_EN(1), .ID_EN(0), .DEST_EN(1), - .DEST_W(8), + .DEST_W(CQN_W), .USER_EN(0) ) axis_cpl(); diff --git a/src/cndm/rtl/cndm_micro_queue_state.sv b/src/cndm/rtl/cndm_micro_queue_state.sv index 9a7ffd3..b91621d 100644 --- a/src/cndm/rtl/cndm_micro_queue_state.sv +++ b/src/cndm/rtl/cndm_micro_queue_state.sv @@ -18,7 +18,8 @@ Authors: module cndm_micro_queue_state #( parameter QN_W = 5, parameter DQN_W = 5, - parameter CPL_SIZE = 16, + parameter logic IS_CQ = 1'b0, + parameter QE_SIZE = 16, parameter DMA_ADDR_W = 64 ) ( @@ -37,7 +38,7 @@ module cndm_micro_queue_state #( taxi_apb_if.slv s_apb_dp_ctrl, /* - * CQ management interface + * Queue management interface */ input wire logic [QN_W-1:0] req_qn, input wire logic req_valid, @@ -45,7 +46,7 @@ module cndm_micro_queue_state #( output wire logic [QN_W-1:0] rsp_qn, output wire logic [DQN_W-1:0] rsp_dqn, output wire logic [DMA_ADDR_W-1:0] rsp_addr, - output wire logic rsp_phase, + output wire logic rsp_phase_tag, output wire logic rsp_error, output wire logic rsp_valid, input wire logic rsp_ready @@ -115,7 +116,7 @@ logic req_ready_reg = 1'b0, req_ready_next; logic [QN_W-1:0] rsp_qn_reg = '0, rsp_qn_next; logic [DQN_W-1:0] rsp_dqn_reg = '0, rsp_dqn_next; logic [DMA_ADDR_W-1:0] rsp_addr_reg = '0, rsp_addr_next; -logic rsp_phase_reg = 1'b0, rsp_phase_next; +logic rsp_phase_tag_reg = 1'b0, rsp_phase_tag_next; logic rsp_error_reg = 1'b0, rsp_error_next; logic rsp_valid_reg = 1'b0, rsp_valid_next; @@ -123,30 +124,38 @@ assign req_ready = req_ready_reg; assign rsp_qn = rsp_qn_reg; assign rsp_dqn = rsp_dqn_reg; assign rsp_addr = rsp_addr_reg; -assign rsp_phase = rsp_phase_reg; +assign rsp_phase_tag = rsp_phase_tag_reg; assign rsp_error = rsp_error_reg; 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 [3:0] queue_mem_size[2**QN_W] = '{default: '0}; +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}; (* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) logic [DMA_ADDR_W-1:0] queue_mem_base_addr[2**QN_W] = '{default: '0}; (* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) -logic [PTR_W-1:0] queue_mem_prod[2**QN_W] = '{default: '0}; +logic [PTR_W-1:0] queue_mem_prod_ptr[2**QN_W] = '{default: '0}; +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) +logic [PTR_W-1:0] queue_mem_cons_ptr[2**QN_W] = '{default: '0}; 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 [3:0] queue_mem_rd_size = queue_mem_size[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]; -wire [PTR_W-1:0] queue_mem_rd_prod = queue_mem_prod[queue_mem_addr]; +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 [3:0] queue_mem_wr_size; +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; -logic [PTR_W-1:0] queue_mem_wr_prod; +logic [PTR_W-1:0] queue_mem_wr_prod_ptr; +logic [PTR_W-1:0] queue_mem_wr_cons_ptr; always_comb begin s_axil_ctrl_awready_next = 1'b0; @@ -164,7 +173,7 @@ always_comb begin rsp_qn_next = rsp_qn_reg; rsp_dqn_next = rsp_dqn_reg; rsp_addr_next = rsp_addr_reg; - rsp_phase_next = rsp_phase_reg; + rsp_phase_tag_next = rsp_phase_tag_reg; rsp_error_next = rsp_error_reg; rsp_valid_next = rsp_valid_reg && !rsp_ready; @@ -172,12 +181,14 @@ always_comb begin queue_mem_addr = '0; queue_mem_wr_enable = queue_mem_rd_enable; - queue_mem_wr_size = queue_mem_rd_size; + 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; - queue_mem_wr_prod = queue_mem_rd_prod; + queue_mem_wr_prod_ptr = queue_mem_rd_prod_ptr; + queue_mem_wr_cons_ptr = queue_mem_rd_cons_ptr; // terminate AXI lite writes - if (s_axil_ctrl_wr.awvalid && s_axil_ctrl_wr.wvalid && !s_axil_ctrl_bvalid_reg) begin + if (IS_CQ && s_axil_ctrl_wr.awvalid && s_axil_ctrl_wr.wvalid && !s_axil_ctrl_bvalid_reg) begin s_axil_ctrl_awready_next = 1'b1; s_axil_ctrl_wready_next = 1'b1; s_axil_ctrl_bvalid_next = 1'b1; @@ -191,7 +202,21 @@ always_comb begin s_axil_ctrl_rvalid_next = 1'b1; end - if (s_apb_dp_ctrl.penable && s_apb_dp_ctrl.psel && !s_apb_dp_ctrl_pready_reg) begin + if (!IS_CQ && s_axil_ctrl_wr.awvalid && s_axil_ctrl_wr.wvalid && !s_axil_ctrl_bvalid_reg) begin + // AXI lite write + s_axil_ctrl_awready_next = 1'b1; + s_axil_ctrl_wready_next = 1'b1; + s_axil_ctrl_bvalid_next = 1'b1; + + queue_mem_wr_en = 1'b1; + queue_mem_addr = s_axil_ctrl_awaddr_queue_index; + + case (s_axil_ctrl_awaddr_reg_index) + 3'd2: queue_mem_wr_prod_ptr = s_axil_ctrl_wr.wdata[15:0]; + default: begin end + endcase + + end else if (s_apb_dp_ctrl.penable && s_apb_dp_ctrl.psel && !s_apb_dp_ctrl_pready_reg) begin // APB read/write s_apb_dp_ctrl_pready_next = 1'b1; s_apb_dp_ctrl_prdata_next = '0; @@ -204,11 +229,13 @@ always_comb begin case (s_apb_dp_ctrl_paddr_reg_index) 3'd0: begin queue_mem_wr_enable = s_apb_dp_ctrl.pwdata[0]; - queue_mem_wr_size = s_apb_dp_ctrl.pwdata[19:16]; + queue_mem_wr_log_size = s_apb_dp_ctrl.pwdata[19:16]; end - 3'd1: queue_mem_wr_prod = s_apb_dp_ctrl.pwdata[15:0]; - 3'd2: queue_mem_wr_base_addr[31:0] = s_apb_dp_ctrl.pwdata; - 3'd3: queue_mem_wr_base_addr[63:32] = s_apb_dp_ctrl.pwdata; + 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]; + 3'd3: queue_mem_wr_cons_ptr = s_apb_dp_ctrl.pwdata[15:0]; + 3'd6: queue_mem_wr_base_addr[31:0] = s_apb_dp_ctrl.pwdata; + 3'd7: queue_mem_wr_base_addr[63:32] = s_apb_dp_ctrl.pwdata; default: begin end endcase end @@ -216,11 +243,13 @@ always_comb begin case (s_apb_dp_ctrl_paddr_reg_index) 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_size; + s_apb_dp_ctrl_prdata_next[19:16] = queue_mem_rd_log_size; end - 3'd1: s_apb_dp_ctrl_prdata_next[15:0] = queue_mem_rd_prod; - 3'd2: s_apb_dp_ctrl_prdata_next = queue_mem_rd_base_addr[31:0]; - 3'd3: s_apb_dp_ctrl_prdata_next = queue_mem_rd_base_addr[63:32]; + 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; + 3'd3: s_apb_dp_ctrl_prdata_next[15:0] = IS_CQ ? '0 : queue_mem_rd_cons_ptr; + 3'd6: s_apb_dp_ctrl_prdata_next = queue_mem_rd_base_addr[31:0]; + 3'd7: s_apb_dp_ctrl_prdata_next = queue_mem_rd_base_addr[63:32]; default: begin end endcase @@ -231,15 +260,20 @@ always_comb begin queue_mem_addr = req_qn; rsp_qn_next = req_qn; - rsp_dqn_next = '0; // TODO - rsp_addr_next = queue_mem_rd_base_addr + DMA_ADDR_W'(16'(queue_mem_rd_prod & ({16{1'b1}} >> (16 - queue_mem_rd_size))) * CPL_SIZE); - rsp_phase_next = !queue_mem_rd_prod[queue_mem_rd_size]; - rsp_error_next = !queue_mem_rd_enable; + rsp_dqn_next = queue_mem_rd_dqn; + 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; + queue_mem_wr_cons_ptr = queue_mem_rd_cons_ptr + 1; + end rsp_valid_next = 1'b1; - queue_mem_wr_prod = queue_mem_rd_prod + 1; - - if (queue_mem_rd_enable) begin + if (!rsp_error_next) begin queue_mem_wr_en = 1'b1; end end @@ -261,15 +295,17 @@ always @(posedge clk) begin rsp_qn_reg <= rsp_qn_next; rsp_dqn_reg <= rsp_dqn_next; rsp_addr_reg <= rsp_addr_next; - rsp_phase_reg <= rsp_phase_next; + rsp_phase_tag_reg <= rsp_phase_tag_next; rsp_error_reg <= rsp_error_next; rsp_valid_reg <= rsp_valid_next; if (queue_mem_wr_en) begin queue_enable_reg[queue_mem_addr] <= queue_mem_wr_enable; - queue_mem_size[queue_mem_addr] <= queue_mem_wr_size; + 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; - queue_mem_prod[queue_mem_addr] <= queue_mem_wr_prod; + queue_mem_prod_ptr[queue_mem_addr] <= queue_mem_wr_prod_ptr; + queue_mem_cons_ptr[queue_mem_addr] <= queue_mem_wr_cons_ptr; end if (rst) begin