cndm: Move SQ/RQ state into distributed RAM

Signed-off-by: Alex Forencich <alex@alexforencich.com>
This commit is contained in:
Alex Forencich
2026-03-05 20:49:35 -08:00
parent 7dbe6df56a
commit 8263ebab24
6 changed files with 211 additions and 265 deletions

View File

@@ -37,7 +37,8 @@ module cndm_micro_core #(
parameter PORTS = 2, parameter PORTS = 2,
// Queue configuration // Queue configuration
parameter CQN_W = 5, parameter WQN_W = 5,
parameter CQN_W = WQN_W,
// PTP configuration // PTP configuration
parameter logic PTP_TS_EN = 1'b1, parameter logic PTP_TS_EN = 1'b1,
@@ -312,6 +313,7 @@ apb_dp_ctrl();
cndm_micro_dp_mgr #( cndm_micro_dp_mgr #(
.PORTS(PORTS), .PORTS(PORTS),
.WQN_W(WQN_W),
.CQN_W(CQN_W), .CQN_W(CQN_W),
.PTP_EN(PTP_TS_EN), .PTP_EN(PTP_TS_EN),
@@ -498,6 +500,7 @@ for (genvar p = 0; p < PORTS; p = p + 1) begin : port
cndm_micro_port #( cndm_micro_port #(
// Queue configuration // Queue configuration
.WQN_W(WQN_W),
.CQN_W(CQN_W), .CQN_W(CQN_W),
// PTP configuration // PTP configuration

View File

@@ -50,7 +50,7 @@ logic [CQN_W-1:0] cq_req_cqn_reg = '0;
logic cq_req_valid_reg = 1'b0; logic cq_req_valid_reg = 1'b0;
logic cq_req_ready; logic cq_req_ready;
logic [DMA_ADDR_W-1:0] cq_rsp_addr; 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_error;
logic cq_rsp_valid; logic cq_rsp_valid;
logic cq_rsp_ready_reg = 1'b0; logic cq_rsp_ready_reg = 1'b0;
@@ -58,7 +58,8 @@ logic cq_rsp_ready_reg = 1'b0;
cndm_micro_queue_state #( cndm_micro_queue_state #(
.QN_W(CQN_W), .QN_W(CQN_W),
.DQN_W(CQN_W), // TODO .DQN_W(CQN_W), // TODO
.CPL_SIZE(16), .IS_CQ(1),
.QE_SIZE(16),
.DMA_ADDR_W(DMA_ADDR_W) .DMA_ADDR_W(DMA_ADDR_W)
) )
cq_mgr_inst ( cq_mgr_inst (
@@ -77,7 +78,7 @@ cq_mgr_inst (
.s_apb_dp_ctrl(s_apb_dp_ctrl), .s_apb_dp_ctrl(s_apb_dp_ctrl),
/* /*
* CQ management interface * Queue management interface
*/ */
.req_qn(cq_req_cqn_reg), .req_qn(cq_req_cqn_reg),
.req_valid(cq_req_valid_reg), .req_valid(cq_req_valid_reg),
@@ -85,7 +86,7 @@ cq_mgr_inst (
.rsp_qn(), .rsp_qn(),
.rsp_dqn(), .rsp_dqn(),
.rsp_addr(cq_rsp_addr), .rsp_addr(cq_rsp_addr),
.rsp_phase(cq_rsp_phase), .rsp_phase_tag(cq_rsp_phase_tag),
.rsp_error(cq_rsp_error), .rsp_error(cq_rsp_error),
.rsp_valid(cq_rsp_valid), .rsp_valid(cq_rsp_valid),
.rsp_ready(cq_rsp_ready_reg) .rsp_ready(cq_rsp_ready_reg)
@@ -130,7 +131,7 @@ always_ff @(posedge clk) begin
STATE_IDLE: begin STATE_IDLE: begin
dma_wr_desc_req.req_src_addr <= '0; 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 if (s_axis_cpl.tvalid && !s_axis_cpl.tready) begin
cq_req_valid_reg <= 1'b1; cq_req_valid_reg <= 1'b1;
@@ -143,11 +144,11 @@ always_ff @(posedge clk) begin
dma_wr_desc_req.req_src_addr <= '0; dma_wr_desc_req.req_src_addr <= '0;
cq_rsp_ready_reg <= 1'b1; 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; cq_rsp_ready_reg <= 1'b0;
dma_wr_desc_req.req_dst_addr <= cq_rsp_addr; 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 if (cq_rsp_error) begin
// drop completion // drop completion

View File

@@ -15,7 +15,10 @@ Authors:
/* /*
* Corundum-micro descriptor read module * 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 clk,
input wire logic rst, input wire logic rst,
@@ -42,190 +45,55 @@ module cndm_micro_desc_rd
taxi_axis_if.src m_axis_desc taxi_axis_if.src m_axis_desc
); );
localparam AXIL_ADDR_W = s_axil_ctrl_wr.ADDR_W; localparam DMA_ADDR_W = dma_rd_desc_req.SRC_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 RAM_ADDR_W = 16; localparam RAM_ADDR_W = 16;
logic txq_en_reg = '0; logic [WQN_W-1:0] wq_req_wqn_reg = '0;
logic [3:0] txq_size_reg = '0; logic wq_req_valid_reg = 1'b0;
logic [7:0] txq_cqn_reg = '0; logic wq_req_ready;
logic [63:0] txq_base_addr_reg = '0; logic [CQN_W-1:0] wq_rsp_cqn;
logic [15:0] txq_prod_reg = '0; logic [DMA_ADDR_W-1:0] wq_rsp_addr;
logic rxq_en_reg = '0; logic wq_rsp_error;
logic [3:0] rxq_size_reg = '0; logic wq_rsp_valid;
logic [7:0] rxq_cqn_reg = '0; logic wq_rsp_ready_reg = 1'b0;
logic [63:0] rxq_base_addr_reg = '0;
logic [15:0] rxq_prod_reg = '0;
logic [15:0] txq_cons_ptr_reg = '0; cndm_micro_queue_state #(
logic [15:0] rxq_cons_ptr_reg = '0; .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; * Control register interface
logic s_axil_ctrl_bvalid_reg = 1'b0; */
.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; * Datapath control register interface
logic s_axil_ctrl_rvalid_reg = 1'b0; */
.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; * Queue management interface
assign s_axil_ctrl_wr.bresp = '0; */
assign s_axil_ctrl_wr.buser = '0; .req_qn(wq_req_wqn_reg),
assign s_axil_ctrl_wr.bvalid = s_axil_ctrl_bvalid_reg; .req_valid(wq_req_valid_reg),
.req_ready(wq_req_ready),
assign s_axil_ctrl_rd.arready = s_axil_ctrl_arready_reg; .rsp_qn(),
assign s_axil_ctrl_rd.rdata = s_axil_ctrl_rdata_reg; .rsp_dqn(wq_rsp_cqn),
assign s_axil_ctrl_rd.rresp = '0; .rsp_addr(wq_rsp_addr),
assign s_axil_ctrl_rd.ruser = '0; .rsp_phase_tag(),
assign s_axil_ctrl_rd.rvalid = s_axil_ctrl_rvalid_reg; .rsp_error(wq_rsp_error),
.rsp_valid(wq_rsp_valid),
logic s_apb_dp_ctrl_pready_reg = 1'b0; .rsp_ready(wq_rsp_ready_reg)
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
taxi_dma_desc_if #( taxi_dma_desc_if #(
.SRC_ADDR_W(RAM_ADDR_W), .SRC_ADDR_W(RAM_ADDR_W),
@@ -247,8 +115,8 @@ taxi_dma_desc_if #(
typedef enum logic [1:0] { typedef enum logic [1:0] {
STATE_IDLE, STATE_IDLE,
STATE_QUERY_WQ,
STATE_READ_DESC, STATE_READ_DESC,
STATE_READ_DATA,
STATE_TX_DESC STATE_TX_DESC
} state_t; } state_t;
@@ -257,8 +125,6 @@ state_t state_reg = STATE_IDLE;
logic [1:0] desc_req_reg = '0; logic [1:0] desc_req_reg = '0;
always_ff @(posedge clk) begin always_ff @(posedge clk) begin
// axis_desc.tready <= 1'b0;
dma_rd_desc_req.req_src_sel <= '0; dma_rd_desc_req.req_src_sel <= '0;
dma_rd_desc_req.req_src_asid <= '0; dma_rd_desc_req.req_src_asid <= '0;
dma_rd_desc_req.req_dst_sel <= '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_user <= '0;
dma_desc.req_valid <= dma_desc.req_valid && !dma_desc.req_ready; 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; 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) case (state_reg)
STATE_IDLE: begin STATE_IDLE: begin
wq_req_wqn_reg <= 0;
if (desc_req_reg[1]) 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_id <= 1'b1;
dma_desc.req_dest <= rxq_cqn_reg;
desc_req_reg[1] <= 1'b0; desc_req_reg[1] <= 1'b0;
if (rxq_cons_ptr_reg == rxq_prod_reg || !rxq_en_reg) begin wq_req_wqn_reg <= 1;
dma_desc.req_user <= 1'b1; wq_req_valid_reg <= 1'b1;
dma_desc.req_valid <= 1'b1; dma_desc.req_id <= 1'b1;
state_reg <= STATE_TX_DESC; state_reg <= STATE_QUERY_WQ;
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
end else if (desc_req_reg[0]) begin 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; 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_user <= 1'b1;
dma_desc.req_valid <= 1'b1; dma_desc.req_valid <= 1'b1;
state_reg <= STATE_TX_DESC; state_reg <= STATE_TX_DESC;
end else begin end else begin
// read desc
dma_desc.req_user <= 1'b0; dma_desc.req_user <= 1'b0;
dma_rd_desc_req.req_valid <= 1'b1; dma_rd_desc_req.req_valid <= 1'b1;
txq_cons_ptr_reg <= txq_cons_ptr_reg + 1;
state_reg <= STATE_READ_DESC; state_reg <= STATE_READ_DESC;
end end
end end

View File

@@ -19,7 +19,8 @@ module cndm_micro_dp_mgr #
( (
parameter PORTS = 2, parameter PORTS = 2,
parameter CQN_W = 5, parameter WQN_W = 5,
parameter CQN_W = WQN_W,
parameter logic PTP_EN = 1'b1, parameter logic PTP_EN = 1'b1,
parameter PTP_BASE_ADDR_DP = 0, parameter PTP_BASE_ADDR_DP = 0,
@@ -90,8 +91,10 @@ typedef enum logic [4:0] {
STATE_CREATE_Q_FIND_2, STATE_CREATE_Q_FIND_2,
STATE_CREATE_Q_RESET_1, STATE_CREATE_Q_RESET_1,
STATE_CREATE_Q_RESET_2, STATE_CREATE_Q_RESET_2,
STATE_CREATE_Q_RESET_3,
STATE_CREATE_Q_SET_BASE_L, STATE_CREATE_Q_SET_BASE_L,
STATE_CREATE_Q_SET_BASE_H, STATE_CREATE_Q_SET_BASE_H,
STATE_CREATE_Q_SET_DQN,
STATE_CREATE_Q_ENABLE, STATE_CREATE_Q_ENABLE,
STATE_DESTROY_Q_DISABLE, STATE_DESTROY_Q_DISABLE,
STATE_PTP_READ_1, STATE_PTP_READ_1,
@@ -297,15 +300,15 @@ always_comb begin
CMD_OP_CREATE_RQ: CMD_OP_CREATE_RQ:
begin begin
cnt_next = 0; cnt_next = 0;
dp_ptr_next = DP_APB_ADDR_W'({port_reg, 16'd0} | 'h0100) + DP_APB_ADDR_W'(PORT_BASE_ADDR_DP); 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} | 'h0100) + PORT_BASE_ADDR_HOST; host_ptr_next = 32'({port_reg, 16'd0} | 'h0020) + PORT_BASE_ADDR_HOST;
end end
CMD_OP_MODIFY_RQ, CMD_OP_MODIFY_RQ,
CMD_OP_QUERY_RQ, CMD_OP_QUERY_RQ,
CMD_OP_DESTROY_RQ: CMD_OP_DESTROY_RQ:
begin begin
dp_ptr_next = DP_APB_ADDR_W'({port_reg, 16'd0} | 'h0100) + DP_APB_ADDR_W'(PORT_BASE_ADDR_DP); 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} | 'h0100) + PORT_BASE_ADDR_HOST; host_ptr_next = 32'({port_reg, 16'd0} | 'h0020) + PORT_BASE_ADDR_HOST;
end end
default: begin end default: begin end
endcase endcase
@@ -512,12 +515,27 @@ always_comb begin
// reset queue 2 // reset queue 2
// store doorbell offset // 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_addr = 7;
cmd_ram_wr_en = 1'b1; cmd_ram_wr_en = 1'b1;
if (!m_apb_dp_ctrl_psel_reg) begin 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_psel_next = 1'b1;
m_apb_dp_ctrl_pwrite_next = 1'b1; m_apb_dp_ctrl_pwrite_next = 1'b1;
m_apb_dp_ctrl_pwdata_next = 32'h00000000; m_apb_dp_ctrl_pwdata_next = 32'h00000000;
@@ -525,14 +543,14 @@ always_comb begin
state_next = STATE_CREATE_Q_SET_BASE_L; state_next = STATE_CREATE_Q_SET_BASE_L;
end else begin end else begin
state_next = STATE_CREATE_Q_RESET_2; state_next = STATE_CREATE_Q_RESET_3;
end end
end end
STATE_CREATE_Q_SET_BASE_L: begin STATE_CREATE_Q_SET_BASE_L: begin
// set queue base addr (LSB) // set queue base addr (LSB)
cmd_ram_rd_addr = 8; cmd_ram_rd_addr = 8;
if (!m_apb_dp_ctrl_psel_reg) begin 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_psel_next = 1'b1;
m_apb_dp_ctrl_pwrite_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_pwdata_next = cmd_ram_rd_data;
@@ -547,7 +565,7 @@ always_comb begin
// set queue base addr (MSB) // set queue base addr (MSB)
cmd_ram_rd_addr = 9; cmd_ram_rd_addr = 9;
if (!m_apb_dp_ctrl_psel_reg) begin 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_psel_next = 1'b1;
m_apb_dp_ctrl_pwrite_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_pwdata_next = cmd_ram_rd_data;
@@ -555,7 +573,22 @@ always_comb begin
state_next = STATE_CREATE_Q_ENABLE; state_next = STATE_CREATE_Q_ENABLE;
end else begin 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
end end
STATE_CREATE_Q_ENABLE: begin STATE_CREATE_Q_ENABLE: begin
@@ -566,7 +599,6 @@ always_comb begin
m_apb_dp_ctrl_psel_next = 1'b1; m_apb_dp_ctrl_psel_next = 1'b1;
m_apb_dp_ctrl_pwrite_next = 1'b1; m_apb_dp_ctrl_pwrite_next = 1'b1;
m_apb_dp_ctrl_pwdata_next = '0; 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[19:16] = cmd_ram_rd_data[3:0];
m_apb_dp_ctrl_pwdata_next[0] = 1'b1; m_apb_dp_ctrl_pwdata_next[0] = 1'b1;
m_apb_dp_ctrl_pstrb_next = '1; m_apb_dp_ctrl_pstrb_next = '1;

View File

@@ -17,7 +17,8 @@ Authors:
*/ */
module cndm_micro_port #( module cndm_micro_port #(
// Queue configuration // Queue configuration
parameter CQN_W = 5, parameter WQN_W = 5,
parameter CQN_W = WQN_W,
// PTP configuration // PTP configuration
parameter logic PTP_TS_EN = 1'b1, parameter logic PTP_TS_EN = 1'b1,
@@ -275,12 +276,15 @@ taxi_axis_if #(
.ID_EN(1), .ID_EN(1),
.ID_W(1), .ID_W(1),
.DEST_EN(1), .DEST_EN(1),
.DEST_W(8), .DEST_W(WQN_W),
.USER_EN(1), .USER_EN(1),
.USER_W(1) .USER_W(1)
) axis_desc(); ) axis_desc();
cndm_micro_desc_rd cndm_micro_desc_rd #(
.WQN_W(WQN_W),
.CQN_W(CQN_W)
)
desc_rd_inst ( desc_rd_inst (
.clk(clk), .clk(clk),
.rst(rst), .rst(rst),
@@ -354,7 +358,7 @@ taxi_axis_if #(
.LAST_EN(1), .LAST_EN(1),
.ID_EN(0), .ID_EN(0),
.DEST_EN(1), .DEST_EN(1),
.DEST_W(8), .DEST_W(CQN_W),
.USER_EN(0) .USER_EN(0)
) axis_cpl(); ) axis_cpl();

View File

@@ -18,7 +18,8 @@ Authors:
module cndm_micro_queue_state #( module cndm_micro_queue_state #(
parameter QN_W = 5, parameter QN_W = 5,
parameter DQN_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 parameter DMA_ADDR_W = 64
) )
( (
@@ -37,7 +38,7 @@ module cndm_micro_queue_state #(
taxi_apb_if.slv s_apb_dp_ctrl, 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 [QN_W-1:0] req_qn,
input wire logic req_valid, 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 [QN_W-1:0] rsp_qn,
output wire logic [DQN_W-1:0] rsp_dqn, output wire logic [DQN_W-1:0] rsp_dqn,
output wire logic [DMA_ADDR_W-1:0] rsp_addr, 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_error,
output wire logic rsp_valid, output wire logic rsp_valid,
input wire logic rsp_ready 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 [QN_W-1:0] rsp_qn_reg = '0, rsp_qn_next;
logic [DQN_W-1:0] rsp_dqn_reg = '0, rsp_dqn_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 [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_error_reg = 1'b0, rsp_error_next;
logic rsp_valid_reg = 1'b0, rsp_valid_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_qn = rsp_qn_reg;
assign rsp_dqn = rsp_dqn_reg; assign rsp_dqn = rsp_dqn_reg;
assign rsp_addr = rsp_addr_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_error = rsp_error_reg;
assign rsp_valid = rsp_valid_reg; assign rsp_valid = rsp_valid_reg;
logic [2**QN_W-1:0] queue_enable_reg = '0; logic [2**QN_W-1:0] queue_enable_reg = '0;
(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) (* 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" *) (* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *)
logic [DMA_ADDR_W-1:0] queue_mem_base_addr[2**QN_W] = '{default: '0}; logic [DMA_ADDR_W-1:0] queue_mem_base_addr[2**QN_W] = '{default: '0};
(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) (* 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 queue_mem_wr_en;
logic [QN_W-1:0] queue_mem_addr; logic [QN_W-1:0] queue_mem_addr;
wire queue_mem_rd_enable = queue_enable_reg[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 [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 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 [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 always_comb begin
s_axil_ctrl_awready_next = 1'b0; s_axil_ctrl_awready_next = 1'b0;
@@ -164,7 +173,7 @@ always_comb begin
rsp_qn_next = rsp_qn_reg; rsp_qn_next = rsp_qn_reg;
rsp_dqn_next = rsp_dqn_reg; rsp_dqn_next = rsp_dqn_reg;
rsp_addr_next = rsp_addr_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_error_next = rsp_error_reg;
rsp_valid_next = rsp_valid_reg && !rsp_ready; rsp_valid_next = rsp_valid_reg && !rsp_ready;
@@ -172,12 +181,14 @@ always_comb begin
queue_mem_addr = '0; queue_mem_addr = '0;
queue_mem_wr_enable = queue_mem_rd_enable; 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_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 // 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_awready_next = 1'b1;
s_axil_ctrl_wready_next = 1'b1; s_axil_ctrl_wready_next = 1'b1;
s_axil_ctrl_bvalid_next = 1'b1; s_axil_ctrl_bvalid_next = 1'b1;
@@ -191,7 +202,21 @@ always_comb begin
s_axil_ctrl_rvalid_next = 1'b1; s_axil_ctrl_rvalid_next = 1'b1;
end 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 // APB read/write
s_apb_dp_ctrl_pready_next = 1'b1; s_apb_dp_ctrl_pready_next = 1'b1;
s_apb_dp_ctrl_prdata_next = '0; s_apb_dp_ctrl_prdata_next = '0;
@@ -204,11 +229,13 @@ always_comb begin
case (s_apb_dp_ctrl_paddr_reg_index) case (s_apb_dp_ctrl_paddr_reg_index)
3'd0: begin 3'd0: begin
queue_mem_wr_enable = s_apb_dp_ctrl.pwdata[0]; 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 end
3'd1: queue_mem_wr_prod = s_apb_dp_ctrl.pwdata[15:0]; 3'd1: queue_mem_wr_dqn = s_apb_dp_ctrl.pwdata[DQN_W-1:0];
3'd2: queue_mem_wr_base_addr[31:0] = s_apb_dp_ctrl.pwdata; 3'd2: queue_mem_wr_prod_ptr = s_apb_dp_ctrl.pwdata[15:0];
3'd3: queue_mem_wr_base_addr[63:32] = s_apb_dp_ctrl.pwdata; 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 default: begin end
endcase endcase
end end
@@ -216,11 +243,13 @@ always_comb begin
case (s_apb_dp_ctrl_paddr_reg_index) case (s_apb_dp_ctrl_paddr_reg_index)
3'd0: begin 3'd0: begin
s_apb_dp_ctrl_prdata_next[0] = queue_mem_rd_enable; 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 end
3'd1: s_apb_dp_ctrl_prdata_next[15:0] = queue_mem_rd_prod; 3'd1: s_apb_dp_ctrl_prdata_next = 32'(queue_mem_rd_dqn);
3'd2: s_apb_dp_ctrl_prdata_next = queue_mem_rd_base_addr[31:0]; 3'd2: s_apb_dp_ctrl_prdata_next[15:0] = queue_mem_rd_prod_ptr;
3'd3: s_apb_dp_ctrl_prdata_next = queue_mem_rd_base_addr[63:32]; 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 default: begin end
endcase endcase
@@ -231,15 +260,20 @@ always_comb begin
queue_mem_addr = req_qn; queue_mem_addr = req_qn;
rsp_qn_next = req_qn; rsp_qn_next = req_qn;
rsp_dqn_next = '0; // TODO rsp_dqn_next = queue_mem_rd_dqn;
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); if (IS_CQ) begin
rsp_phase_next = !queue_mem_rd_prod[queue_mem_rd_size]; 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; 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; rsp_valid_next = 1'b1;
queue_mem_wr_prod = queue_mem_rd_prod + 1; if (!rsp_error_next) begin
if (queue_mem_rd_enable) begin
queue_mem_wr_en = 1'b1; queue_mem_wr_en = 1'b1;
end end
end end
@@ -261,15 +295,17 @@ always @(posedge clk) begin
rsp_qn_reg <= rsp_qn_next; rsp_qn_reg <= rsp_qn_next;
rsp_dqn_reg <= rsp_dqn_next; rsp_dqn_reg <= rsp_dqn_next;
rsp_addr_reg <= rsp_addr_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_error_reg <= rsp_error_next;
rsp_valid_reg <= rsp_valid_next; rsp_valid_reg <= rsp_valid_next;
if (queue_mem_wr_en) begin if (queue_mem_wr_en) begin
queue_enable_reg[queue_mem_addr] <= queue_mem_wr_enable; 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_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 end
if (rst) begin if (rst) begin