From 0f09b8bdaafc330ddcffad80e06d6a63b9aad0ea Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Mon, 2 Mar 2026 00:33:31 -0800 Subject: [PATCH] cndm: Add register access command Signed-off-by: Alex Forencich --- src/cndm/modules/cndm/cndm.h | 1 + src/cndm/modules/cndm/cndm_cmd.c | 29 +++++++++++++++++ src/cndm/modules/cndm/cndm_hw.h | 2 ++ src/cndm/rtl/cndm_micro_dp_mgr.sv | 53 ++++++++++++++++++++++++++++++- src/cndm/tb/cndm.py | 29 +++++++++++++++++ 5 files changed, 113 insertions(+), 1 deletion(-) diff --git a/src/cndm/modules/cndm/cndm.h b/src/cndm/modules/cndm/cndm.h index 26b7a81..0c8649e 100644 --- a/src/cndm/modules/cndm/cndm.h +++ b/src/cndm/modules/cndm/cndm.h @@ -144,6 +144,7 @@ struct cndm_priv { // cndm_cmd.c int cndm_exec_mbox_cmd(struct cndm_dev *cdev, void *cmd, void *rsp); int cndm_exec_cmd(struct cndm_dev *cdev, void *cmd, void *rsp); +int cndm_access_reg(struct cndm_dev *cdev, u32 reg, int raw, int write, u64 *data); // cndm_devlink.c struct devlink *cndm_devlink_alloc(struct device *dev); diff --git a/src/cndm/modules/cndm/cndm_cmd.c b/src/cndm/modules/cndm/cndm_cmd.c index 3cde67a..01bb8bd 100644 --- a/src/cndm/modules/cndm/cndm_cmd.c +++ b/src/cndm/modules/cndm/cndm_cmd.c @@ -45,3 +45,32 @@ int cndm_exec_cmd(struct cndm_dev *cdev, void *cmd, void *rsp) { return cndm_exec_mbox_cmd(cdev, cmd, rsp); } + +int cndm_access_reg(struct cndm_dev *cdev, u32 reg, int raw, int write, u64 *data) +{ + struct cndm_cmd cmd; + struct cndm_cmd rsp; + + cmd.opcode = CNDM_CMD_OP_ACCESS_REG; + cmd.flags = 0x00000000; + cmd.port = 0; + cmd.qn = 0; + cmd.qn2 = 0; + cmd.pd = 0; + cmd.size = 0; + cmd.dboffs = reg; + cmd.ptr1 = *data; + cmd.ptr2 = 0; + + if (write) + cmd.flags |= 0x00000001; + if (raw) + cmd.flags |= 0x00000100; + + cndm_exec_cmd(cdev, &cmd, &rsp); + + if (!write) + *data = rsp.ptr2; + + return 0; +} diff --git a/src/cndm/modules/cndm/cndm_hw.h b/src/cndm/modules/cndm/cndm_hw.h index a43b70d..b661a7d 100644 --- a/src/cndm/modules/cndm/cndm_hw.h +++ b/src/cndm/modules/cndm/cndm_hw.h @@ -15,6 +15,8 @@ Authors: #define CNDM_CMD_OP_NOP 0x0000 +#define CNDM_CMD_OP_ACCESS_REG 0x0180 + #define CNDM_CMD_OP_CREATE_EQ 0x0200 #define CNDM_CMD_OP_MODIFY_EQ 0x0201 #define CNDM_CMD_OP_QUERY_EQ 0x0202 diff --git a/src/cndm/rtl/cndm_micro_dp_mgr.sv b/src/cndm/rtl/cndm_micro_dp_mgr.sv index 4de4362..1b5775c 100644 --- a/src/cndm/rtl/cndm_micro_dp_mgr.sv +++ b/src/cndm/rtl/cndm_micro_dp_mgr.sv @@ -44,6 +44,8 @@ localparam DP_APB_STRB_W = m_apb_dp_ctrl.STRB_W; typedef enum logic [15:0] { CMD_OP_NOP = 16'h0000, + CMD_OP_ACCESS_REG = 16'h0180, + CMD_OP_CREATE_EQ = 16'h0200, CMD_OP_MODIFY_EQ = 16'h0201, CMD_OP_QUERY_EQ = 16'h0202, @@ -73,6 +75,9 @@ typedef enum logic [15:0] { typedef enum logic [4:0] { STATE_IDLE, STATE_START, + STATE_REG_1, + STATE_REG_2, + STATE_REG_3, STATE_Q_RESET_1, STATE_Q_RESET_2, STATE_Q_SET_BASE_L, @@ -259,7 +264,7 @@ always_comb begin endcase case (opcode_reg) - 16'h0000: begin + CMD_OP_NOP: begin // NOP m_axis_rsp_tdata_next = '0; // TODO m_axis_rsp_tvalid_next = 1'b1; @@ -267,6 +272,10 @@ always_comb begin state_next = STATE_SEND_RSP; end + CMD_OP_ACCESS_REG: begin + // access register + state_next = STATE_REG_1; + end CMD_OP_CREATE_EQ, CMD_OP_CREATE_CQ, CMD_OP_CREATE_SQ, @@ -321,6 +330,48 @@ always_comb begin end endcase end + STATE_REG_1: begin + // register access 1 + cmd_ram_rd_addr = 7; + if (!m_apb_dp_ctrl_psel_reg) begin + m_apb_dp_ctrl_paddr_next = DP_APB_ADDR_W'(cmd_ram_rd_data); + + state_next = STATE_REG_2; + end else begin + state_next = STATE_REG_1; + end + end + STATE_REG_2: begin + // register access 2 + cmd_ram_rd_addr = 8; + if (!m_apb_dp_ctrl_psel_reg) begin + m_apb_dp_ctrl_psel_next = 1'b1; + m_apb_dp_ctrl_pwrite_next = flags_reg[0]; + m_apb_dp_ctrl_pwdata_next = cmd_ram_rd_data; + m_apb_dp_ctrl_pstrb_next = '1; + + state_next = STATE_REG_3; + end else begin + state_next = STATE_REG_2; + end + end + STATE_REG_3: begin + // register access 3 + + cmd_ram_wr_data = m_apb_dp_ctrl.prdata; + cmd_ram_wr_addr = 10; + cmd_ram_wr_en = 1'b1; + + if (m_apb_dp_ctrl.pready) begin + m_axis_rsp_tdata_next = '0; // TODO + m_axis_rsp_tvalid_next = 1'b1; + m_axis_rsp_tlast_next = 1'b0; + + state_next = STATE_SEND_RSP; + end else begin + state_next = STATE_REG_3; + end + end STATE_Q_RESET_1: begin // reset queue 1 if (!m_apb_dp_ctrl_psel_reg) begin diff --git a/src/cndm/tb/cndm.py b/src/cndm/tb/cndm.py index cd93574..9dc58de 100644 --- a/src/cndm/tb/cndm.py +++ b/src/cndm/tb/cndm.py @@ -19,6 +19,8 @@ from cocotb.queue import Queue # Command opcodes CNDM_CMD_OP_NOP = 0x0000 +CNDM_CMD_OP_ACCESS_REG = 0x0180 + CNDM_CMD_OP_CREATE_EQ = 0x0200 CNDM_CMD_OP_MODIFY_EQ = 0x0201 CNDM_CMD_OP_QUERY_EQ = 0x0202 @@ -360,6 +362,33 @@ class Driver: self.ports.append(port) + async def access_reg(self, reg, raw, write=False, data=0): + flags = 0 + if raw: + flags |= 0x00000100 + if write: + flags |= 0x00000001 + + rsp = await self.exec_cmd(struct.pack("