From 6bf7240686b08f5fd7ae758e1c1832f6ec93b289 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Tue, 3 Mar 2026 18:09:38 -0800 Subject: [PATCH] cndm: Rework desc/cpl mux/demux logic, add support for CQNs, implement queue allocation Signed-off-by: Alex Forencich --- src/cndm/modules/cndm/cndm.h | 4 + src/cndm/modules/cndm/cndm_netdev.c | 38 ++++--- src/cndm/rtl/cndm_micro_cpl_wr.sv | 49 ++------- src/cndm/rtl/cndm_micro_desc_rd.sv | 67 ++++-------- src/cndm/rtl/cndm_micro_dp_mgr.sv | 154 +++++++++++++++++++++------- src/cndm/rtl/cndm_micro_port.sv | 116 +++++++++++++++++---- src/cndm/rtl/cndm_micro_rx.sv | 41 ++++---- src/cndm/rtl/cndm_micro_tx.sv | 41 ++++---- src/cndm/tb/cndm.py | 32 ++++-- 9 files changed, 326 insertions(+), 216 deletions(-) diff --git a/src/cndm/modules/cndm/cndm.h b/src/cndm/modules/cndm/cndm.h index ad3aa8f..43e3c77 100644 --- a/src/cndm/modules/cndm/cndm.h +++ b/src/cndm/modules/cndm/cndm.h @@ -108,6 +108,7 @@ struct cndm_priv { u32 txq_prod; u32 txq_cons; u32 txq_db_offs; + u32 tx_sqn; size_t rxq_region_len; void *rxq_region; @@ -119,6 +120,7 @@ struct cndm_priv { u32 rxq_prod; u32 rxq_cons; u32 rxq_db_offs; + u32 rx_rqn; size_t txcq_region_len; void *txcq_region; @@ -129,6 +131,7 @@ struct cndm_priv { u32 txcq_mask; u32 txcq_prod; u32 txcq_cons; + u32 tx_cqn; size_t rxcq_region_len; void *rxcq_region; @@ -139,6 +142,7 @@ struct cndm_priv { u32 rxcq_mask; u32 rxcq_prod; u32 rxcq_cons; + u32 rx_cqn; }; // cndm_cmd.c diff --git a/src/cndm/modules/cndm/cndm_netdev.c b/src/cndm/modules/cndm/cndm_netdev.c index 98f980d..7b99bcd 100644 --- a/src/cndm/modules/cndm/cndm_netdev.c +++ b/src/cndm/modules/cndm/cndm_netdev.c @@ -289,7 +289,7 @@ struct net_device *cndm_create_netdev(struct cndm_dev *cdev, int port) cmd.flags = 0x00000000; cmd.port = port; cmd.qn = 0; - cmd.qn2 = 0; + cmd.qn2 = port; cmd.pd = 0; cmd.size = priv->rxcq_log_size; cmd.dboffs = 0; @@ -298,11 +298,13 @@ struct net_device *cndm_create_netdev(struct cndm_dev *cdev, int port) cndm_exec_cmd(cdev, &cmd, &rsp); + priv->rx_cqn = rsp.qn; + cmd.opcode = CNDM_CMD_OP_CREATE_RQ; cmd.flags = 0x00000000; cmd.port = port; cmd.qn = 0; - cmd.qn2 = 0; + cmd.qn2 = priv->rx_cqn; cmd.pd = 0; cmd.size = priv->rxq_log_size; cmd.dboffs = 0; @@ -311,13 +313,14 @@ struct net_device *cndm_create_netdev(struct cndm_dev *cdev, int port) cndm_exec_cmd(cdev, &cmd, &rsp); + priv->rx_rqn = rsp.qn; priv->rxq_db_offs = rsp.dboffs; cmd.opcode = CNDM_CMD_OP_CREATE_CQ; cmd.flags = 0x00000000; cmd.port = port; - cmd.qn = 1; - cmd.qn2 = 0; + cmd.qn = 0; + cmd.qn2 = port; cmd.pd = 0; cmd.size = priv->txcq_log_size; cmd.dboffs = 0; @@ -326,11 +329,13 @@ struct net_device *cndm_create_netdev(struct cndm_dev *cdev, int port) cndm_exec_cmd(cdev, &cmd, &rsp); + priv->tx_cqn = rsp.qn; + cmd.opcode = CNDM_CMD_OP_CREATE_SQ; cmd.flags = 0x00000000; cmd.port = port; cmd.qn = 0; - cmd.qn2 = 0; + cmd.qn2 = priv->tx_cqn; cmd.pd = 0; cmd.size = priv->txq_log_size; cmd.dboffs = 0; @@ -339,6 +344,7 @@ struct net_device *cndm_create_netdev(struct cndm_dev *cdev, int port) cndm_exec_cmd(cdev, &cmd, &rsp); + priv->tx_sqn = rsp.qn; priv->txq_db_offs = rsp.dboffs; netif_carrier_off(ndev); @@ -376,33 +382,31 @@ void cndm_destroy_netdev(struct net_device *ndev) struct cndm_cmd_queue cmd; struct cndm_cmd_queue rsp; + cmd.opcode = CNDM_CMD_OP_DESTROY_SQ; + cmd.flags = 0x00000000; + cmd.port = ndev->dev_port; + cmd.qn = priv->tx_sqn; + + cndm_exec_cmd(cdev, &cmd, &rsp); + cmd.opcode = CNDM_CMD_OP_DESTROY_CQ; cmd.flags = 0x00000000; cmd.port = ndev->dev_port; - cmd.qn = 0; + cmd.qn = priv->tx_cqn; cndm_exec_cmd(cdev, &cmd, &rsp); cmd.opcode = CNDM_CMD_OP_DESTROY_RQ; cmd.flags = 0x00000000; cmd.port = ndev->dev_port; - cmd.qn = 0; + cmd.qn = priv->rx_rqn; cndm_exec_cmd(cdev, &cmd, &rsp); - priv->rxq_db_offs = rsp.dboffs; - cmd.opcode = CNDM_CMD_OP_DESTROY_CQ; cmd.flags = 0x00000000; cmd.port = ndev->dev_port; - cmd.qn = 1; - - cndm_exec_cmd(cdev, &cmd, &rsp); - - cmd.opcode = CNDM_CMD_OP_DESTROY_SQ; - cmd.flags = 0x00000000; - cmd.port = ndev->dev_port; - cmd.qn = 0; + cmd.qn = priv->rx_cqn; cndm_exec_cmd(cdev, &cmd, &rsp); diff --git a/src/cndm/rtl/cndm_micro_cpl_wr.sv b/src/cndm/rtl/cndm_micro_cpl_wr.sv index 0b7589e..77f1feb 100644 --- a/src/cndm/rtl/cndm_micro_cpl_wr.sv +++ b/src/cndm/rtl/cndm_micro_cpl_wr.sv @@ -38,7 +38,7 @@ module cndm_micro_cpl_wr taxi_dma_desc_if.sts_snk dma_wr_desc_sts, taxi_dma_ram_if.rd_slv dma_ram_rd, - taxi_axis_if.snk axis_cpl[2], + taxi_axis_if.snk s_axis_cpl, output wire logic irq ); @@ -201,20 +201,6 @@ always_ff @(posedge clk) begin end end -taxi_axis_if #( - .DATA_W(axis_cpl[0].DATA_W), - .KEEP_EN(axis_cpl[0].KEEP_EN), - .KEEP_W(axis_cpl[0].KEEP_W), - .STRB_EN(axis_cpl[0].STRB_EN), - .LAST_EN(axis_cpl[0].LAST_EN), - .ID_EN(1), - .ID_W(1), - .DEST_EN(axis_cpl[0].DEST_EN), - .DEST_W(axis_cpl[0].DEST_W), - .USER_EN(axis_cpl[0].USER_EN), - .USER_W(axis_cpl[0].USER_W) -) cpl_comb(); - typedef enum logic [1:0] { STATE_IDLE, STATE_RX_CPL, @@ -230,7 +216,7 @@ logic irq_reg = 1'b0; assign irq = irq_reg; always_ff @(posedge clk) begin - cpl_comb.tready <= 1'b0; + s_axis_cpl.tready <= 1'b0; dma_wr_desc_req.req_src_sel <= '0; dma_wr_desc_req.req_src_asid <= '0; @@ -259,10 +245,10 @@ always_ff @(posedge clk) begin STATE_IDLE: begin dma_wr_desc_req.req_src_addr <= '0; - if (cpl_comb.tid == 0) begin + if (s_axis_cpl.tdest == 0) begin dma_wr_desc_req.req_dst_addr <= txcq_base_addr_reg + 64'(16'(txcq_prod_ptr_reg & ({16{1'b1}} >> (16 - txcq_size_reg))) * 16); phase_tag_reg <= !txcq_prod_ptr_reg[txcq_size_reg]; - if (cpl_comb.tvalid && !cpl_comb.tready) begin + if (s_axis_cpl.tvalid && !s_axis_cpl.tready) begin txcq_prod_ptr_reg <= txcq_prod_ptr_reg + 1; if (txcq_en_reg) begin dma_wr_desc_req.req_valid <= 1'b1; @@ -274,7 +260,7 @@ always_ff @(posedge clk) begin end else begin dma_wr_desc_req.req_dst_addr <= rxcq_base_addr_reg + 64'(16'(rxcq_prod_ptr_reg & ({16{1'b1}} >> (16 - rxcq_size_reg))) * 16); phase_tag_reg <= !rxcq_prod_ptr_reg[rxcq_size_reg]; - if (cpl_comb.tvalid && !cpl_comb.tready) begin + if (s_axis_cpl.tvalid && !s_axis_cpl.tready) begin rxcq_prod_ptr_reg <= rxcq_prod_ptr_reg + 1; if (rxcq_en_reg) begin dma_wr_desc_req.req_valid <= 1'b1; @@ -287,7 +273,7 @@ always_ff @(posedge clk) begin end STATE_WRITE_DATA: begin if (dma_wr_desc_sts.sts_valid) begin - cpl_comb.tready <= 1'b1; + s_axis_cpl.tready <= 1'b1; irq_reg <= 1'b1; state_reg <= STATE_IDLE; end @@ -305,27 +291,6 @@ always_ff @(posedge clk) begin end end -taxi_axis_arb_mux #( - .S_COUNT(2), - .UPDATE_TID(1), - .ARB_ROUND_ROBIN(1), - .ARB_LSB_HIGH_PRIO(1) -) -mux_inst ( - .clk(clk), - .rst(rst), - - /* - * AXI4-Stream input (sink) - */ - .s_axis(axis_cpl), - - /* - * AXI4-Stream output (source) - */ - .m_axis(cpl_comb) -); - // extract parameters localparam SEGS = dma_ram_rd.SEGS; localparam SEG_ADDR_W = dma_ram_rd.SEG_ADDR_W; @@ -335,7 +300,7 @@ localparam SEG_BE_W = dma_ram_rd.SEG_BE_W; if (SEGS*SEG_DATA_W < 128) $fatal(0, "Total segmented interface width must be at least 128 (instance %m)"); -wire [SEGS-1:0][SEG_DATA_W-1:0] ram_data = (SEG_DATA_W*SEGS)'({phase_tag_reg, cpl_comb.tdata[126:0]}); +wire [SEGS-1:0][SEG_DATA_W-1:0] ram_data = (SEG_DATA_W*SEGS)'({phase_tag_reg, s_axis_cpl.tdata[126:0]}); for (genvar n = 0; n < SEGS; n = n + 1) begin diff --git a/src/cndm/rtl/cndm_micro_desc_rd.sv b/src/cndm/rtl/cndm_micro_desc_rd.sv index 3b84fee..3dda7ca 100644 --- a/src/cndm/rtl/cndm_micro_desc_rd.sv +++ b/src/cndm/rtl/cndm_micro_desc_rd.sv @@ -39,7 +39,7 @@ module cndm_micro_desc_rd taxi_dma_ram_if.wr_slv dma_ram_wr, input wire logic [1:0] desc_req, - taxi_axis_if.src axis_desc[2] + taxi_axis_if.src m_axis_desc ); localparam AXIL_ADDR_W = s_axil_ctrl_wr.ADDR_W; @@ -52,10 +52,12 @@ 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; @@ -167,6 +169,7 @@ always_ff @(posedge clk) begin 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; @@ -175,6 +178,7 @@ always_ff @(posedge clk) begin 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; @@ -187,6 +191,7 @@ always_ff @(posedge clk) begin 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; @@ -198,6 +203,7 @@ always_ff @(posedge clk) begin 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; @@ -231,11 +237,12 @@ taxi_dma_desc_if #( .IMM_EN(1'b0), .LEN_W(5), .TAG_W(1), - .ID_EN(0), - .DEST_EN(1), - .DEST_W(1), - .USER_EN(1), - .USER_W(1) + .ID_EN(m_axis_desc.ID_EN), + .ID_W(m_axis_desc.ID_W), + .DEST_EN(m_axis_desc.DEST_EN), + .DEST_W(m_axis_desc.DEST_W), + .USER_EN(m_axis_desc.USER_EN), + .USER_W(m_axis_desc.USER_W) ) dma_desc(); typedef enum logic [1:0] { @@ -274,7 +281,6 @@ always_ff @(posedge clk) begin dma_desc.req_imm_en <= '0; dma_desc.req_len <= 16; dma_desc.req_tag <= '0; - dma_desc.req_id <= '0; dma_desc.req_user <= '0; dma_desc.req_valid <= dma_desc.req_valid && !dma_desc.req_ready; @@ -292,7 +298,8 @@ always_ff @(posedge clk) begin STATE_IDLE: begin 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_dest <= 1'b1; + 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; @@ -306,7 +313,8 @@ always_ff @(posedge clk) begin end 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_dest <= 1'b0; + 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 dma_desc.req_user <= 1'b1; @@ -367,19 +375,6 @@ ram_inst ( .dma_ram_rd(dma_ram_rd) ); -taxi_axis_if #( - .DATA_W(axis_desc[0].DATA_W), - .KEEP_EN(axis_desc[0].KEEP_EN), - .KEEP_W(axis_desc[0].KEEP_W), - .LAST_EN(axis_desc[0].LAST_EN), - .ID_EN(axis_desc[0].ID_EN), - .ID_W(axis_desc[0].ID_W), - .DEST_EN(1), - .DEST_W(1), - .USER_EN(axis_desc[0].USER_EN), - .USER_W(axis_desc[0].USER_W) -) m_axis_rd_data(); - taxi_dma_client_axis_source dma_inst ( .clk(clk), @@ -394,7 +389,7 @@ dma_inst ( /* * AXI stream read data output */ - .m_axis_rd_data(m_axis_rd_data), + .m_axis_rd_data(m_axis_desc), /* * RAM interface @@ -407,32 +402,6 @@ dma_inst ( .enable(1'b1) ); -taxi_axis_demux #( - .M_COUNT(2), - .TDEST_ROUTE(1) -) -demux_inst ( - .clk(clk), - .rst(rst), - - /* - * AXI4-Stream input (sink) - */ - .s_axis(m_axis_rd_data), - - /* - * AXI4-Stream output (source) - */ - .m_axis(axis_desc), - - /* - * Control - */ - .enable(1'b1), - .drop(1'b0), - .select('0) -); - endmodule `resetall diff --git a/src/cndm/rtl/cndm_micro_dp_mgr.sv b/src/cndm/rtl/cndm_micro_dp_mgr.sv index 6c0a920..2748c9b 100644 --- a/src/cndm/rtl/cndm_micro_dp_mgr.sv +++ b/src/cndm/rtl/cndm_micro_dp_mgr.sv @@ -82,12 +82,14 @@ typedef enum logic [4:0] { STATE_REG_1, STATE_REG_2, STATE_REG_3, - STATE_Q_RESET_1, - STATE_Q_RESET_2, - STATE_Q_SET_BASE_L, - STATE_Q_SET_BASE_H, - STATE_Q_ENABLE, - STATE_Q_DISABLE, + STATE_CREATE_Q_FIND_1, + STATE_CREATE_Q_FIND_2, + STATE_CREATE_Q_RESET_1, + STATE_CREATE_Q_RESET_2, + STATE_CREATE_Q_SET_BASE_L, + STATE_CREATE_Q_SET_BASE_H, + STATE_CREATE_Q_ENABLE, + STATE_DESTROY_Q_DISABLE, STATE_PTP_READ_1, STATE_PTP_READ_2, STATE_PTP_SET, @@ -152,6 +154,7 @@ logic [15:0] opcode_reg = '0, opcode_next; 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 [3:0] cmd_ptr_reg = '0, cmd_ptr_next; logic [DP_APB_ADDR_W-1:0] dp_ptr_reg = '0, dp_ptr_next; @@ -190,6 +193,7 @@ always_comb begin flags_next = flags_reg; port_next = port_reg; qn_next = qn_reg; + qn2_next = qn2_reg; cmd_ptr_next = cmd_ptr_reg; dp_ptr_next = dp_ptr_reg; @@ -220,6 +224,7 @@ always_comb begin 4'd1: flags_next = s_axis_cmd.tdata; 4'd2: port_next = s_axis_cmd.tdata[15:0]; 4'd3: qn_next = s_axis_cmd.tdata[23:0]; + 4'd4: qn2_next = s_axis_cmd.tdata[23:0]; default: begin end endcase @@ -242,30 +247,43 @@ always_comb begin // determine block base address case (opcode_reg) - CMD_OP_CREATE_EQ, - CMD_OP_MODIFY_EQ, - CMD_OP_QUERY_EQ, - CMD_OP_DESTROY_EQ: + // CMD_OP_CREATE_EQ: + // begin + // // EQ + // qn_next = 0; + // 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 + // CMD_OP_MODIFY_EQ, + // CMD_OP_QUERY_EQ, + // CMD_OP_DESTROY_EQ: + // begin + // // EQ + // 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 + CMD_OP_CREATE_CQ: begin - // EQ + // CQ + cnt_next = 1; 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 - CMD_OP_CREATE_CQ, CMD_OP_MODIFY_CQ, CMD_OP_QUERY_CQ, CMD_OP_DESTROY_CQ: begin // CQ - if (qn_reg[0]) begin - 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 else begin - dp_ptr_next = DP_APB_ADDR_W'({port_reg, 16'd0} | 'h8100) + DP_APB_ADDR_W'(PORT_BASE_ADDR_DP); - host_ptr_next = 32'({port_reg, 16'd0} | 'h8100) + PORT_BASE_ADDR_HOST; - end + dp_ptr_next = DP_APB_ADDR_W'({port_reg, 16'd0} | 'h8000 | {qn_reg, 8'd00}) + DP_APB_ADDR_W'(PORT_BASE_ADDR_DP); + host_ptr_next = 32'({port_reg, 16'd0} | 'h8000 | {qn_reg, 8'd00}) + PORT_BASE_ADDR_HOST; + end + CMD_OP_CREATE_SQ: + begin + // SQ + cnt_next = 0; + 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 - CMD_OP_CREATE_SQ, CMD_OP_MODIFY_SQ, CMD_OP_QUERY_SQ, CMD_OP_DESTROY_SQ: @@ -274,7 +292,13 @@ always_comb begin 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 - CMD_OP_CREATE_RQ, + CMD_OP_CREATE_RQ: + begin + // RQ + 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; + end CMD_OP_MODIFY_RQ, CMD_OP_QUERY_RQ, CMD_OP_DESTROY_RQ: @@ -330,7 +354,8 @@ always_comb begin CMD_OP_CREATE_RQ: begin // create queue operation - state_next = STATE_Q_RESET_1; + qn_next = '0; + state_next = STATE_CREATE_Q_FIND_1; end CMD_OP_MODIFY_EQ, CMD_OP_MODIFY_CQ, @@ -366,7 +391,7 @@ always_comb begin CMD_OP_DESTROY_RQ: begin // destroy queue operation - state_next = STATE_Q_DISABLE; + state_next = STATE_DESTROY_Q_DISABLE; end default: begin // unknown opcode @@ -420,8 +445,56 @@ always_comb begin state_next = STATE_REG_3; end end - STATE_Q_RESET_1: begin + STATE_CREATE_Q_FIND_1: begin + // read queue enable bit + if (!m_apb_dp_ctrl_psel_reg) begin + m_apb_dp_ctrl_paddr_next = dp_ptr_reg + 'h0000; + m_apb_dp_ctrl_psel_next = 1'b1; + m_apb_dp_ctrl_pwrite_next = 1'b0; + m_apb_dp_ctrl_pwdata_next = 32'h00000000; + m_apb_dp_ctrl_pstrb_next = '1; + + state_next = STATE_CREATE_Q_FIND_2; + end else begin + state_next = STATE_CREATE_Q_FIND_1; + end + end + STATE_CREATE_Q_FIND_2: begin + // check queue enable bit + if (m_apb_dp_ctrl.pready) begin + cnt_next = cnt_reg - 1; + + if (m_apb_dp_ctrl.prdata[0] == 0) begin + // queue is inactive + state_next = STATE_CREATE_Q_RESET_1; + end else begin + // queue is active + qn_next = qn_reg + 1; + dp_ptr_next = dp_ptr_reg + 'h100; + if (cnt_reg == 0) begin + // no more queues + m_axis_rsp_tdata_next = '0; // TODO + m_axis_rsp_tvalid_next = 1'b1; + m_axis_rsp_tlast_next = 1'b0; + + state_next = STATE_PAD_RSP; + end else begin + // try next queue + state_next = STATE_CREATE_Q_FIND_1; + end + end + end else begin + state_next = STATE_CREATE_Q_FIND_2; + end + end + STATE_CREATE_Q_RESET_1: begin // reset queue 1 + + // store queue number + cmd_ram_wr_data = 32'(qn_reg); + cmd_ram_wr_addr = 3; + cmd_ram_wr_en = 1'b1; + if (!m_apb_dp_ctrl_psel_reg) begin m_apb_dp_ctrl_paddr_next = dp_ptr_reg + 'h0000; m_apb_dp_ctrl_psel_next = 1'b1; @@ -429,14 +502,15 @@ always_comb begin m_apb_dp_ctrl_pwdata_next = 32'h00000000; m_apb_dp_ctrl_pstrb_next = '1; - state_next = STATE_Q_RESET_2; + state_next = STATE_CREATE_Q_RESET_2; end else begin - state_next = STATE_Q_RESET_1; + state_next = STATE_CREATE_Q_RESET_1; end end - STATE_Q_RESET_2: begin + STATE_CREATE_Q_RESET_2: begin // reset queue 2 + // store doorbell offset cmd_ram_wr_data = host_ptr_reg + 'h0004; cmd_ram_wr_addr = 7; cmd_ram_wr_en = 1'b1; @@ -448,12 +522,12 @@ always_comb begin m_apb_dp_ctrl_pwdata_next = 32'h00000000; m_apb_dp_ctrl_pstrb_next = '1; - state_next = STATE_Q_SET_BASE_L; + state_next = STATE_CREATE_Q_SET_BASE_L; end else begin - state_next = STATE_Q_RESET_2; + state_next = STATE_CREATE_Q_RESET_2; end end - STATE_Q_SET_BASE_L: begin + 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 @@ -463,12 +537,12 @@ always_comb begin m_apb_dp_ctrl_pwdata_next = cmd_ram_rd_data; m_apb_dp_ctrl_pstrb_next = '1; - state_next = STATE_Q_SET_BASE_H; + state_next = STATE_CREATE_Q_SET_BASE_H; end else begin - state_next = STATE_Q_SET_BASE_L; + state_next = STATE_CREATE_Q_SET_BASE_L; end end - STATE_Q_SET_BASE_H: begin + STATE_CREATE_Q_SET_BASE_H: begin // set queue base addr (MSB) cmd_ram_rd_addr = 9; if (!m_apb_dp_ctrl_psel_reg) begin @@ -478,12 +552,12 @@ always_comb begin m_apb_dp_ctrl_pwdata_next = cmd_ram_rd_data; m_apb_dp_ctrl_pstrb_next = '1; - state_next = STATE_Q_ENABLE; + state_next = STATE_CREATE_Q_ENABLE; end else begin - state_next = STATE_Q_SET_BASE_H; + state_next = STATE_CREATE_Q_SET_BASE_H; end end - STATE_Q_ENABLE: begin + STATE_CREATE_Q_ENABLE: begin // enable queue cmd_ram_rd_addr = 6; if (!m_apb_dp_ctrl_psel_reg) begin @@ -491,6 +565,7 @@ 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; @@ -501,10 +576,10 @@ always_comb begin state_next = STATE_SEND_RSP; end else begin - state_next = STATE_Q_ENABLE; + state_next = STATE_CREATE_Q_ENABLE; end end - STATE_Q_DISABLE: begin + STATE_DESTROY_Q_DISABLE: begin // disable queue if (!m_apb_dp_ctrl_psel_reg) begin m_apb_dp_ctrl_paddr_next = dp_ptr_reg + 'h0000; @@ -519,7 +594,7 @@ always_comb begin state_next = STATE_SEND_RSP; end else begin - state_next = STATE_Q_DISABLE; + state_next = STATE_DESTROY_Q_DISABLE; end end STATE_PTP_READ_1: begin @@ -746,6 +821,7 @@ always_ff @(posedge clk) begin flags_reg <= flags_next; port_reg <= port_next; qn_reg <= qn_next; + qn2_reg <= qn2_next; cmd_ptr_reg <= cmd_ptr_next; dp_ptr_reg <= dp_ptr_next; diff --git a/src/cndm/rtl/cndm_micro_port.sv b/src/cndm/rtl/cndm_micro_port.sv index 97f5d87..8a2485b 100644 --- a/src/cndm/rtl/cndm_micro_port.sv +++ b/src/cndm/rtl/cndm_micro_port.sv @@ -261,26 +261,20 @@ wr_dma_mux_inst ( .client_ram_rd(dma_ram_rd_int) ); +// descriptor fetch wire [1:0] desc_req; taxi_axis_if #( .DATA_W(16*8), .KEEP_EN(1), .LAST_EN(1), - .ID_EN(0), - .DEST_EN(1), // TODO + .ID_EN(1), + .ID_W(1), + .DEST_EN(1), + .DEST_W(8), .USER_EN(1), .USER_W(1) -) axis_desc[2](); - -taxi_axis_if #( - .DATA_W(16*8), - .KEEP_EN(1), - .LAST_EN(1), - .ID_EN(1), // TODO - .DEST_EN(0), - .USER_EN(0) -) axis_cpl[2](); +) axis_desc(); cndm_micro_desc_rd desc_rd_inst ( @@ -306,7 +300,91 @@ desc_rd_inst ( .dma_ram_wr(dma_ram_wr_int[0]), .desc_req(desc_req), - .axis_desc(axis_desc) + .m_axis_desc(axis_desc) +); + +// desc demux +taxi_axis_if #( + .DATA_W(axis_desc.DATA_W), + .KEEP_EN(axis_desc.KEEP_EN), + .KEEP_W(axis_desc.KEEP_W), + .LAST_EN(axis_desc.LAST_EN), + .ID_EN(axis_desc.ID_EN), + .ID_W(axis_desc.ID_W), + .DEST_EN(axis_desc.DEST_EN), + .DEST_W(axis_desc.DEST_W), + .USER_EN(axis_desc.USER_EN), + .USER_W(axis_desc.USER_W) +) axis_desc_txrx[2](); + +taxi_axis_demux #( + .M_COUNT(2), + .TID_ROUTE(1) +) +desc_demux_inst ( + .clk(clk), + .rst(rst), + + /* + * AXI4-Stream input (sink) + */ + .s_axis(axis_desc), + + /* + * AXI4-Stream output (source) + */ + .m_axis(axis_desc_txrx), + + /* + * Control + */ + .enable(1'b1), + .drop(1'b0), + .select('0) +); + +// completion write +taxi_axis_if #( + .DATA_W(16*8), + .KEEP_EN(1), + .LAST_EN(1), + .ID_EN(0), + .DEST_EN(1), + .DEST_W(8), + .USER_EN(0) +) axis_cpl(); + +taxi_axis_if #( + .DATA_W(axis_cpl.DATA_W), + .KEEP_EN(axis_cpl.KEEP_EN), + .KEEP_W(axis_cpl.KEEP_W), + .LAST_EN(axis_cpl.LAST_EN), + .ID_EN(axis_cpl.ID_EN), + .ID_W(axis_cpl.ID_W), + .DEST_EN(axis_cpl.DEST_EN), + .DEST_W(axis_cpl.DEST_W), + .USER_EN(axis_cpl.USER_EN), + .USER_W(axis_cpl.USER_W) +) axis_cpl_txrx[2](); + +taxi_axis_arb_mux #( + .S_COUNT(2), + .ARB_ROUND_ROBIN(1), + .ARB_LSB_HIGH_PRIO(1) +) +cpl_mux_inst ( + .clk(clk), + .rst(rst), + + /* + * AXI4-Stream input (sink) + */ + .s_axis(axis_cpl_txrx), + + /* + * AXI4-Stream output (source) + */ + .m_axis(axis_cpl) ); cndm_micro_cpl_wr @@ -332,10 +410,11 @@ cpl_wr_inst ( .dma_wr_desc_sts(dma_wr_desc_int[0]), .dma_ram_rd(dma_ram_rd_int[0]), - .axis_cpl(axis_cpl), + .s_axis_cpl(axis_cpl), .irq(irq) ); +// TX path taxi_axis_if #( .DATA_W(mac_axis_tx.DATA_W), .USER_EN(1), @@ -470,12 +549,13 @@ tx_inst ( .dma_ram_wr(dma_ram_wr_int[1]), .desc_req(desc_req[0]), - .axis_desc(axis_desc[0]), + .s_axis_desc(axis_desc_txrx[0]), .tx_data(mac_tx_int), .tx_cpl(mac_tx_cpl_int), - .axis_cpl(axis_cpl[0]) + .m_axis_cpl(axis_cpl_txrx[0]) ); +// RX path taxi_axis_if #( .DATA_W(mac_axis_rx.DATA_W), .USER_EN(1), @@ -554,8 +634,8 @@ rx_inst ( .rx_data(mac_rx_int), .desc_req(desc_req[1]), - .axis_desc(axis_desc[1]), - .axis_cpl(axis_cpl[1]) + .s_axis_desc(axis_desc_txrx[1]), + .m_axis_cpl(axis_cpl_txrx[1]) ); endmodule diff --git a/src/cndm/rtl/cndm_micro_rx.sv b/src/cndm/rtl/cndm_micro_rx.sv index 2755d69..7acbbee 100644 --- a/src/cndm/rtl/cndm_micro_rx.sv +++ b/src/cndm/rtl/cndm_micro_rx.sv @@ -39,8 +39,8 @@ module cndm_micro_rx #( taxi_axis_if.snk rx_data, output wire logic desc_req, - taxi_axis_if.snk axis_desc, - taxi_axis_if.src axis_cpl + taxi_axis_if.snk s_axis_desc, + taxi_axis_if.src m_axis_cpl ); localparam RAM_ADDR_W = 16; @@ -155,7 +155,7 @@ end always_ff @(posedge clk) begin desc_req_reg <= 1'b0; - axis_desc.tready <= 1'b0; + s_axis_desc.tready <= 1'b0; dma_wr_desc_req.req_src_sel <= '0; dma_wr_desc_req.req_src_asid <= '0; @@ -184,17 +184,16 @@ always_ff @(posedge clk) begin dma_desc.req_user <= '0; dma_desc.req_valid <= dma_desc.req_valid && !dma_desc.req_ready; - axis_cpl.tkeep <= '0; - axis_cpl.tid <= '0; - axis_cpl.tdest <= '0; - axis_cpl.tuser <= '0; - axis_cpl.tlast <= 1'b1; - axis_cpl.tvalid <= axis_cpl.tvalid && !axis_cpl.tready; + m_axis_cpl.tkeep <= '0; + m_axis_cpl.tid <= '0; + m_axis_cpl.tuser <= '0; + m_axis_cpl.tlast <= 1'b1; + m_axis_cpl.tvalid <= m_axis_cpl.tvalid && !m_axis_cpl.tready; if (rx_ptp_ts_valid) begin - axis_cpl.tdata[127:112] <= rx_ptp_ts[63:48]; // sec - axis_cpl.tdata[95:64] <= rx_ptp_ts[47:16]; // ns - axis_cpl.tdata[111:96] <= rx_ptp_ts[15:0]; // fns + m_axis_cpl.tdata[127:112] <= rx_ptp_ts[63:48]; // sec + m_axis_cpl.tdata[95:64] <= rx_ptp_ts[47:16]; // ns + m_axis_cpl.tdata[111:96] <= rx_ptp_ts[15:0]; // fns end case (state_reg) @@ -204,24 +203,26 @@ always_ff @(posedge clk) begin end STATE_RX_DATA: begin dma_wr_desc_req.req_len <= 20'(dma_desc.sts_len); - axis_cpl.tdata[47:32] <= 16'(dma_desc.sts_len); + m_axis_cpl.tdata[47:32] <= 16'(dma_desc.sts_len); if (dma_desc.sts_valid) begin desc_req_reg <= 1'b1; state_reg <= STATE_READ_DESC; end end STATE_READ_DESC: begin - axis_desc.tready <= 1'b1; + s_axis_desc.tready <= 1'b1; dma_wr_desc_req.req_src_addr <= '0; - dma_wr_desc_req.req_dst_addr <= axis_desc.tdata[127:64]; + dma_wr_desc_req.req_dst_addr <= s_axis_desc.tdata[127:64]; - if (axis_desc.tvalid && axis_desc.tready) begin - if (dma_wr_desc_req.req_len > 20'(axis_desc.tdata[47:32])) begin - dma_wr_desc_req.req_len <= 20'(axis_desc.tdata[47:32]); + m_axis_cpl.tdest <= s_axis_desc.tdest; // CQN + + if (s_axis_desc.tvalid && s_axis_desc.tready) begin + if (dma_wr_desc_req.req_len > 20'(s_axis_desc.tdata[47:32])) begin + dma_wr_desc_req.req_len <= 20'(s_axis_desc.tdata[47:32]); end - if (axis_desc.tuser) begin + if (s_axis_desc.tuser) begin // failed to read desc state_reg <= STATE_IDLE; end else begin @@ -232,7 +233,7 @@ always_ff @(posedge clk) begin end STATE_WRITE_DATA: begin if (dma_wr_desc_sts.sts_valid) begin - axis_cpl.tvalid <= 1'b1; + m_axis_cpl.tvalid <= 1'b1; state_reg <= STATE_IDLE; end end diff --git a/src/cndm/rtl/cndm_micro_tx.sv b/src/cndm/rtl/cndm_micro_tx.sv index 6c8cf52..e7a491c 100644 --- a/src/cndm/rtl/cndm_micro_tx.sv +++ b/src/cndm/rtl/cndm_micro_tx.sv @@ -38,10 +38,10 @@ module cndm_micro_tx #( taxi_dma_ram_if.wr_slv dma_ram_wr, output wire logic desc_req, - taxi_axis_if.snk axis_desc, + taxi_axis_if.snk s_axis_desc, taxi_axis_if.src tx_data, taxi_axis_if.snk tx_cpl, - taxi_axis_if.src axis_cpl + taxi_axis_if.src m_axis_cpl ); localparam RAM_ADDR_W = 16; @@ -140,7 +140,7 @@ end always_ff @(posedge clk) begin desc_req_reg <= 1'b0; - axis_desc.tready <= 1'b0; + s_axis_desc.tready <= 1'b0; dma_rd_desc_req.req_src_sel <= '0; dma_rd_desc_req.req_src_asid <= '0; @@ -167,12 +167,11 @@ always_ff @(posedge clk) begin dma_desc.req_user <= '0; dma_desc.req_valid <= dma_desc.req_valid && !dma_desc.req_ready; - axis_cpl.tkeep <= '0; - axis_cpl.tid <= '0; - axis_cpl.tdest <= '0; - axis_cpl.tuser <= '0; - axis_cpl.tlast <= 1'b1; - axis_cpl.tvalid <= axis_cpl.tvalid && !axis_cpl.tready; + m_axis_cpl.tkeep <= '0; + m_axis_cpl.tid <= '0; + m_axis_cpl.tuser <= '0; + m_axis_cpl.tlast <= 1'b1; + m_axis_cpl.tvalid <= m_axis_cpl.tvalid && !m_axis_cpl.tready; case (state_reg) STATE_IDLE: begin @@ -180,19 +179,21 @@ always_ff @(posedge clk) begin state_reg <= STATE_READ_DESC; end STATE_READ_DESC: begin - axis_desc.tready <= 1'b1; + s_axis_desc.tready <= 1'b1; - dma_rd_desc_req.req_src_addr <= axis_desc.tdata[127:64]; + dma_rd_desc_req.req_src_addr <= s_axis_desc.tdata[127:64]; dma_rd_desc_req.req_dst_addr <= '0; - dma_rd_desc_req.req_len <= 20'(axis_desc.tdata[47:32]); + dma_rd_desc_req.req_len <= 20'(s_axis_desc.tdata[47:32]); dma_desc.req_src_addr <= '0; - dma_desc.req_len <= axis_desc.tdata[47:32]; + dma_desc.req_len <= s_axis_desc.tdata[47:32]; - axis_cpl.tdata[47:32] <= axis_desc.tdata[47:32]; + m_axis_cpl.tdata[47:32] <= s_axis_desc.tdata[47:32]; - if (axis_desc.tvalid && axis_desc.tready) begin - if (axis_desc.tuser) begin + m_axis_cpl.tdest <= s_axis_desc.tdest; // CQN + + if (s_axis_desc.tvalid && s_axis_desc.tready) begin + if (s_axis_desc.tuser) begin // failed to read desc state_reg <= STATE_IDLE; end else begin @@ -208,11 +209,11 @@ always_ff @(posedge clk) begin end end STATE_TX_DATA: begin - axis_cpl.tdata[127:112] <= tx_cpl_ptp_ts[63:48]; // sec - axis_cpl.tdata[95:64] <= tx_cpl_ptp_ts[47:16]; // ns - axis_cpl.tdata[111:96] <= tx_cpl_ptp_ts[15:0]; // fns + m_axis_cpl.tdata[127:112] <= tx_cpl_ptp_ts[63:48]; // sec + m_axis_cpl.tdata[95:64] <= tx_cpl_ptp_ts[47:16]; // ns + m_axis_cpl.tdata[111:96] <= tx_cpl_ptp_ts[15:0]; // fns if (tx_cpl_valid) begin - axis_cpl.tvalid <= 1'b1; + m_axis_cpl.tvalid <= 1'b1; state_reg <= STATE_IDLE; end end diff --git a/src/cndm/tb/cndm.py b/src/cndm/tb/cndm.py index dd653ba..824997a 100644 --- a/src/cndm/tb/cndm.py +++ b/src/cndm/tb/cndm.py @@ -115,7 +115,7 @@ class Port: 0x00000000, # flags self.index, # port 0, # cqn - 0, # eqn + self.index, # eqn 0, # pd self.rxcq_log_size, # size 0, # dboffs @@ -126,7 +126,10 @@ class Port: 0, # rsvd 0, # rsvd )) - print(rsp) + + rsp_unpacked = struct.unpack("