cmod/glb/gen/glb_reg_model.h
File Name: glb_reg_model.h
// ================================================================
// NVDLA Open Source Project
//
// Copyright(c) 2016 - 2017 NVIDIA Corporation. Licensed under the
// NVDLA Open Hardware License; Check "LICENSE" which comes with
// this distribution for more information.
// ================================================================
// File Name: glb_reg_model.h
#ifndef _GLB_REG_MODEL_H_
#define _GLB_REG_MODEL_H_
#include <systemc.h>
#include <tlm.h>
#include "scsim_common.h"
SCSIM_NAMESPACE_START(clib)
SCSIM_NAMESPACE_END()
SCSIM_NAMESPACE_START(cmod)
// Forward declarating cmacro parsed register model class
class CNVDLA_GLB_REGSET;
这是一个名为 glb_reg_model.h
的头文件,该文件属于 NVIDIA 的 NVDLA(NVIDIA Deep Learning Accelerator)开源项目。以下是该头文件的主要内容和功能:
-
文件开头注释:文件包含了版权信息和许可协议,指出了代码的版权和许可信息。
-
#ifndef
和#define
指令:这些指令用于包装头文件的内容,以避免多重包含。它们定义了一个预处理器宏_GLB_REG_MODEL_H_
,以确保文件只会被包含一次。 -
包含其他头文件:头文件包含了一些系统级的头文件,如
systemc.h
和tlm.h
,以及自定义的scsim_common.h
。 -
命名空间:代码中使用了命名空间来组织代码。
SCSIM_NAMESPACE_START(clib)
和SCSIM_NAMESPACE_END()
定义了名为clib
的命名空间,而SCSIM_NAMESPACE_START(cmod)
则定义了名为cmod
的命名空间。 -
类的前向声明:文件中有一个前向声明
class CNVDLA_GLB_REGSET;
,它声明了一个名为CNVDLA_GLB_REGSET
的类,但没有提供该类的定义。这可能是因为该类的定义位于其他文件中,并且该头文件只需要知道该类的存在,而不需要包含其完整定义。
总之,这个头文件的主要作用是为后续代码提供必要的包含和命名空间定义,并声明了一个名为 CNVDLA_GLB_REGSET
的类,该类的定义位于其他文件中。
class glb_reg_model {
public:
glb_reg_model();
~glb_reg_model();
sc_event operation_enable_event_;
sc_event intr_status_w;
protected:
// bool is_there_ongoing_glb_csb_response_;
CNVDLA_GLB_REGSET *glb_register_group;
// Register field variables
uint8_t s_nvdla_hw_version_major_;
uint16_t s_nvdla_hw_version_minor_;
uint8_t s_intr_mask_sdp_done_mask0_;
uint8_t s_intr_mask_sdp_done_mask1_;
uint8_t s_intr_mask_cdp_done_mask0_;
uint8_t s_intr_mask_cdp_done_mask1_;
uint8_t s_intr_mask_pdp_done_mask0_;
uint8_t s_intr_mask_pdp_done_mask1_;
uint8_t s_intr_mask_bdma_done_mask0_;
uint8_t s_intr_mask_bdma_done_mask1_;
uint8_t s_intr_mask_rubik_done_mask0_;
uint8_t s_intr_mask_rubik_done_mask1_;
uint8_t s_intr_mask_cdma_dat_done_mask0_;
uint8_t s_intr_mask_cdma_dat_done_mask1_;
uint8_t s_intr_mask_cdma_wt_done_mask0_;
uint8_t s_intr_mask_cdma_wt_done_mask1_;
uint8_t s_intr_mask_cacc_done_mask0_;
uint8_t s_intr_mask_cacc_done_mask1_;
uint8_t s_intr_set_sdp_done_set0_;
uint8_t s_intr_set_sdp_done_set1_;
uint8_t s_intr_set_cdp_done_set0_;
uint8_t s_intr_set_cdp_done_set1_;
uint8_t s_intr_set_pdp_done_set0_;
uint8_t s_intr_set_pdp_done_set1_;
uint8_t s_intr_set_bdma_done_set0_;
uint8_t s_intr_set_bdma_done_set1_;
uint8_t s_intr_set_rubik_done_set0_;
uint8_t s_intr_set_rubik_done_set1_;
uint8_t s_intr_set_cdma_dat_done_set0_;
uint8_t s_intr_set_cdma_dat_done_set1_;
uint8_t s_intr_set_cdma_wt_done_set0_;
uint8_t s_intr_set_cdma_wt_done_set1_;
uint8_t s_intr_set_cacc_done_set0_;
uint8_t s_intr_set_cacc_done_set1_;
uint8_t s_intr_status_sdp_done_status0_;
uint8_t s_intr_status_sdp_done_status1_;
uint8_t s_intr_status_cdp_done_status0_;
uint8_t s_intr_status_cdp_done_status1_;
uint8_t s_intr_status_pdp_done_status0_;
uint8_t s_intr_status_pdp_done_status1_;
uint8_t s_intr_status_bdma_done_status0_;
uint8_t s_intr_status_bdma_done_status1_;
uint8_t s_intr_status_rubik_done_status0_;
uint8_t s_intr_status_rubik_done_status1_;
uint8_t s_intr_status_cdma_dat_done_status0_;
uint8_t s_intr_status_cdma_dat_done_status1_;
uint8_t s_intr_status_cdma_wt_done_status0_;
uint8_t s_intr_status_cdma_wt_done_status1_;
uint8_t s_intr_status_cacc_done_status0_;
uint8_t s_intr_status_cacc_done_status1_;
// CSB request target socket
// void csb2glb_b_transport (int ID, NV_MSDEC_csb2xx_16m_secure_be_lvl_t* payload, sc_time& delay);
// CSB response send function
// void GlbSendCsbResponse(uint32_t date, uint8_t error_id);
// Register accessing
bool GlbAccessRegister(uint32_t reg_addr, uint32_t & data, bool is_write);
// Reset
void GlbRegReset();
// Update configuration from register to variable
void GlbUpdateVariables(CNVDLA_GLB_REGSET *reg_group_ptr);
//void GlbUpdateIdleStatus(bool status);
void GlbUpdateBdmaIntrStatus_0(bool status);
void GlbUpdateBdmaIntrStatus_1(bool status);
void GlbUpdateCdmaDatIntrStatus_0(bool status);
void GlbUpdateCdmaDatIntrStatus_1(bool status);
void GlbUpdateCdmaWtIntrStatus_0(bool status);
void GlbUpdateCdmaWtIntrStatus_1(bool status);
void GlbUpdatePdpIntrStatus_0(bool status);
void GlbUpdatePdpIntrStatus_1(bool status);
void GlbUpdateSdpIntrStatus_0(bool status);
void GlbUpdateSdpIntrStatus_1(bool status);
void GlbUpdateCdpIntrStatus_0(bool status);
void GlbUpdateCdpIntrStatus_1(bool status);
void GlbUpdateRbkIntrStatus_0(bool status);
void GlbUpdateRbkIntrStatus_1(bool status);
void GlbUpdateCaccIntrStatus_0(bool status);
void GlbUpdateCaccIntrStatus_1(bool status);
};
SCSIM_NAMESPACE_END()
#endif
这是一个名为 glb_reg_model.h
的头文件,定义了一个名为 glb_reg_model
的类。以下是该类的主要成员和功能:
-
构造函数和析构函数:类
glb_reg_model
包括构造函数和析构函数,用于对象的创建和销毁。 -
成员变量:
operation_enable_event_
和intr_status_w
:这些是 SystemC 事件对象,用于控制操作的启用和中断状态的监测。glb_register_group
:指向CNVDLA_GLB_REGSET
类型的指针,用于管理寄存器组的操作。- 一系列的成员变量,用于保存不同寄存器字段的值,这些字段包括硬件版本号、中断屏蔽寄存器、中断设置寄存器和中断状态寄存器。
-
函数成员:
GlbAccessRegister
:用于访问寄存器,可以读取或写入指定地址的寄存器值。GlbRegReset
:用于重置寄存器和内部状态。GlbUpdateVariables
:用于从寄存器更新配置到变量。- 一系列的函数,用于更新不同中断状态的函数,例如
GlbUpdateBdmaIntrStatus_0
、GlbUpdateBdmaIntrStatus_1
等。
这个类的主要目的是管理 NVDLA 的全局寄存器集合,包括配置、中断状态和中断屏蔽等。它提供了访问和更新这些寄存器的功能,以及处理中断状态和中断屏蔽的逻辑。这些功能将用于控制 NVDLA 模块的配置和中断处理。
glb_reg_model.cpp
// ================================================================
// NVDLA Open Source Project
//
// Copyright(c) 2016 - 2017 NVIDIA Corporation. Licensed under the
// NVDLA Open Hardware License; Check "LICENSE" which comes with
// this distribution for more information.
// ================================================================
// File Name: glb_reg_model.cpp
#include "glb_reg_model.h"
#include "arnvdla.uh"
#include "arnvdla.h"
#include "cmacros.uh"
#include "log.h"
#define __STDC_FORMAT_MACROS
#include <inttypes.h>
SCSIM_NAMESPACE_START(cmod)
MK_UREGSET_CLASS(NVDLA_GLB)
SCSIM_NAMESPACE_END()
USING_SCSIM_NAMESPACE(cmod)
USING_SCSIM_NAMESPACE(clib)
using namespace tlm;
using namespace sc_core;
using namespace std;
glb_reg_model & :~glb_reg_model
glb_reg_model::glb_reg_model() {
glb_register_group = new CNVDLA_GLB_REGSET;
GlbRegReset();
}
glb_reg_model::~glb_reg_model() {
delete glb_register_group;
}
这是 glb_reg_model
类的构造函数和析构函数的实现。
在构造函数中:
- 创建了一个名为
glb_register_group
的指针,并用new
运算符分配了一个CNVDLA_GLB_REGSET
类型的对象。 - 调用
GlbRegReset
函数,用于初始化寄存器和内部状态。
在析构函数中:
- 释放了在构造函数中分配的
glb_register_group
对象的内存,以避免内存泄漏。
这些构造函数和析构函数的目的是在对象的创建和销毁时执行必要的操作,以确保资源的正确管理和释放。在构造函数中,对象创建后会初始化寄存器和内部状态,而在析构函数中,对象销毁时会释放相应的内存资源。
GlbAccessRegister
bool glb_reg_model::GlbAccessRegister(uint32_t reg_addr, uint32_t & data, bool is_write) {
uint32_t offset;
uint32_t rdata = 0;
uint32_t new_value = 0;
offset = (reg_addr & 0xFFF); // each sub-unit has only 4KBytes
if (is_write) {
// Write Request
if (offset == REG_off(NVDLA_GLB_S_INTR_STATUS)) {
glb_register_group->Get(offset, &rdata);
new_value = rdata & (~data);
glb_register_group->SetWritable(offset, new_value);
GlbUpdateVariables(glb_register_group);
if((new_value&0xf03ff)==0)
intr_status_w.notify();
} else {
glb_register_group->SetWritable(offset, data);
}
} else {
// Read Request
glb_register_group->Get(offset, &rdata);
data = rdata;
}
return true;
}
这是 glb_reg_model
类的 GlbAccessRegister
函数的实现,它用于访问寄存器并执行读写操作。
reg_addr
参数表示要访问的寄存器地址。data
参数是一个引用,用于存储从寄存器读取的数据或要写入寄存器的数据。is_write
参数是一个布尔值,指示是否执行写操作。如果为true
,则执行写操作;如果为false
,则执行读操作。
在函数内部,它执行以下操作:
- 根据
reg_addr
计算出相对于寄存器组的偏移量offset
。 - 如果
is_write
为true
,表示执行写操作,根据offset
判断是否为特定寄存器(例如NVDLA_GLB_S_INTR_STATUS
)。如果是特定寄存器,它会按位清零(AND 操作)寄存器的相应位,并将新的值写入寄存器。如果新的值的特定位(这里是0xf03ff
)都为零,它会触发intr_status_w
事件。 - 如果
is_write
为false
,表示执行读操作,它从寄存器中读取数据,并将数据存储在data
参数中。 - 最后,函数返回
true
,表示操作成功完成。
这个函数允许对寄存器进行读写操作,并在写操作时触发相应的事件。
GlbUpdate*
void glb_reg_model::GlbRegReset() {
glb_register_group->ResetAll();
}
//void glb_reg_model::GlbUpdateIdleStatus(bool status) {
//}
void glb_reg_model::GlbUpdateBdmaIntrStatus_0(bool status) {
glb_register_group->rS_INTR_STATUS.uBDMA_DONE_STATUS0(status);
}
void glb_reg_model::GlbUpdateBdmaIntrStatus_1(bool status) {
glb_register_group->rS_INTR_STATUS.uBDMA_DONE_STATUS1(status);
}
void glb_reg_model::GlbUpdatePdpIntrStatus_0(bool status) {
glb_register_group->rS_INTR_STATUS.uPDP_DONE_STATUS0(status);
}
void glb_reg_model::GlbUpdatePdpIntrStatus_1(bool status) {
glb_register_group->rS_INTR_STATUS.uPDP_DONE_STATUS1(status);
}
void glb_reg_model::GlbUpdateSdpIntrStatus_0(bool status) {
glb_register_group->rS_INTR_STATUS.uSDP_DONE_STATUS0(status);
}
void glb_reg_model::GlbUpdateSdpIntrStatus_1(bool status) {
glb_register_group->rS_INTR_STATUS.uSDP_DONE_STATUS1(status);
}
void glb_reg_model::GlbUpdateCdpIntrStatus_0(bool status) {
glb_register_group->rS_INTR_STATUS.uCDP_DONE_STATUS0(status);
}
void glb_reg_model::GlbUpdateCdpIntrStatus_1(bool status) {
glb_register_group->rS_INTR_STATUS.uCDP_DONE_STATUS1(status);
}
void glb_reg_model::GlbUpdateRbkIntrStatus_0(bool status) {
glb_register_group->rS_INTR_STATUS.uRUBIK_DONE_STATUS0(status);
}
void glb_reg_model::GlbUpdateRbkIntrStatus_1(bool status) {
glb_register_group->rS_INTR_STATUS.uRUBIK_DONE_STATUS1(status);
}
void glb_reg_model::GlbUpdateCaccIntrStatus_0(bool status) {
glb_register_group->rS_INTR_STATUS.uCACC_DONE_STATUS0(status);
}
void glb_reg_model::GlbUpdateCaccIntrStatus_1(bool status) {
glb_register_group->rS_INTR_STATUS.uCACC_DONE_STATUS1(status);
}
void glb_reg_model::GlbUpdateCdmaDatIntrStatus_0(bool status) {
glb_register_group->rS_INTR_STATUS.uCDMA_DAT_DONE_STATUS0(status);
}
void glb_reg_model::GlbUpdateCdmaDatIntrStatus_1(bool status) {
glb_register_group->rS_INTR_STATUS.uCDMA_DAT_DONE_STATUS1(status);
}
void glb_reg_model::GlbUpdateCdmaWtIntrStatus_0(bool status) {
glb_register_group->rS_INTR_STATUS.uCDMA_WT_DONE_STATUS0(status);
}
void glb_reg_model::GlbUpdateCdmaWtIntrStatus_1(bool status) {
glb_register_group->rS_INTR_STATUS.uCDMA_WT_DONE_STATUS1(status);
}
这些是 glb_reg_model
类的一系列函数,用于更新不同子单元(如 BDMA、PDP、SDP、CDP 等)的中断状态寄存器的值,以及在中断状态发生变化时将其写入对应的寄存器字段。以下是这些函数的功能:
-
GlbUpdateBdmaIntrStatus_0
和GlbUpdateBdmaIntrStatus_1
:更新 BDMA 子单元的中断状态寄存器的第 0 和第 1 位。 -
GlbUpdatePdpIntrStatus_0
和GlbUpdatePdpIntrStatus_1
:更新 PDP 子单元的中断状态寄存器的第 0 和第 1 位。 -
GlbUpdateSdpIntrStatus_0
和GlbUpdateSdpIntrStatus_1
:更新 SDP 子单元的中断状态寄存器的第 0 和第 1 位。 -
GlbUpdateCdpIntrStatus_0
和GlbUpdateCdpIntrStatus_1
:更新 CDP 子单元的中断状态寄存器的第 0 和第 1 位。 -
GlbUpdateRbkIntrStatus_0
和GlbUpdateRbkIntrStatus_1
:更新 RBK 子单元的中断状态寄存器的第 0 和第 1 位。 -
GlbUpdateCaccIntrStatus_0
和GlbUpdateCaccIntrStatus_1
:更新 CACC 子单元的中断状态寄存器的第 0 和第 1 位。 -
GlbUpdateCdmaDatIntrStatus_0
和GlbUpdateCdmaDatIntrStatus_1
:更新 CDMA_DAT 子单元的中断状态寄存器的第 0 和第 1 位。 -
GlbUpdateCdmaWtIntrStatus_0
和GlbUpdateCdmaWtIntrStatus_1
:更新 CDMA_WT 子单元的中断状态寄存器的第 0 和第 1 位。
这些函数用于根据不同子单元的中断状态更新对应的寄存器字段的值。在某些情况下,当特定条件满足时,它们还会触发其他事件或操作。
GlbUpdateVariables
void glb_reg_model::GlbUpdateVariables(CNVDLA_GLB_REGSET *reg_group_ptr) {
s_nvdla_hw_version_major_ = reg_group_ptr->rS_NVDLA_HW_VERSION.uMAJOR();
s_nvdla_hw_version_minor_ = reg_group_ptr->rS_NVDLA_HW_VERSION.uMINOR();
s_intr_mask_sdp_done_mask0_ = reg_group_ptr->rS_INTR_MASK.uSDP_DONE_MASK0();
s_intr_mask_sdp_done_mask1_ = reg_group_ptr->rS_INTR_MASK.uSDP_DONE_MASK1();
s_intr_mask_cdp_done_mask0_ = reg_group_ptr->rS_INTR_MASK.uCDP_DONE_MASK0();
s_intr_mask_cdp_done_mask1_ = reg_group_ptr->rS_INTR_MASK.uCDP_DONE_MASK1();
s_intr_mask_pdp_done_mask0_ = reg_group_ptr->rS_INTR_MASK.uPDP_DONE_MASK0();
s_intr_mask_pdp_done_mask1_ = reg_group_ptr->rS_INTR_MASK.uPDP_DONE_MASK1();
s_intr_mask_bdma_done_mask0_ = reg_group_ptr->rS_INTR_MASK.uBDMA_DONE_MASK0();
s_intr_mask_bdma_done_mask1_ = reg_group_ptr->rS_INTR_MASK.uBDMA_DONE_MASK1();
s_intr_mask_rubik_done_mask0_ = reg_group_ptr->rS_INTR_MASK.uRUBIK_DONE_MASK0();
s_intr_mask_rubik_done_mask1_ = reg_group_ptr->rS_INTR_MASK.uRUBIK_DONE_MASK1();
s_intr_mask_cdma_dat_done_mask0_ = reg_group_ptr->rS_INTR_MASK.uCDMA_DAT_DONE_MASK0();
s_intr_mask_cdma_dat_done_mask1_ = reg_group_ptr->rS_INTR_MASK.uCDMA_DAT_DONE_MASK1();
s_intr_mask_cdma_wt_done_mask0_ = reg_group_ptr->rS_INTR_MASK.uCDMA_WT_DONE_MASK0();
s_intr_mask_cdma_wt_done_mask1_ = reg_group_ptr->rS_INTR_MASK.uCDMA_WT_DONE_MASK1();
s_intr_mask_cacc_done_mask0_ = reg_group_ptr->rS_INTR_MASK.uCACC_DONE_MASK0();
s_intr_mask_cacc_done_mask1_ = reg_group_ptr->rS_INTR_MASK.uCACC_DONE_MASK1();
s_intr_set_sdp_done_set0_ = reg_group_ptr->rS_INTR_SET.uSDP_DONE_SET0();
s_intr_set_sdp_done_set1_ = reg_group_ptr->rS_INTR_SET.uSDP_DONE_SET1();
s_intr_set_cdp_done_set0_ = reg_group_ptr->rS_INTR_SET.uCDP_DONE_SET0();
s_intr_set_cdp_done_set1_ = reg_group_ptr->rS_INTR_SET.uCDP_DONE_SET1();
s_intr_set_pdp_done_set0_ = reg_group_ptr->rS_INTR_SET.uPDP_DONE_SET0();
s_intr_set_pdp_done_set1_ = reg_group_ptr->rS_INTR_SET.uPDP_DONE_SET1();
s_intr_set_bdma_done_set0_ = reg_group_ptr->rS_INTR_SET.uBDMA_DONE_SET0();
s_intr_set_bdma_done_set1_ = reg_group_ptr->rS_INTR_SET.uBDMA_DONE_SET1();
s_intr_set_rubik_done_set0_ = reg_group_ptr->rS_INTR_SET.uRUBIK_DONE_SET0();
s_intr_set_rubik_done_set1_ = reg_group_ptr->rS_INTR_SET.uRUBIK_DONE_SET1();
s_intr_set_cdma_dat_done_set0_ = reg_group_ptr->rS_INTR_SET.uCDMA_DAT_DONE_SET0();
s_intr_set_cdma_dat_done_set1_ = reg_group_ptr->rS_INTR_SET.uCDMA_DAT_DONE_SET1();
s_intr_set_cdma_wt_done_set0_ = reg_group_ptr->rS_INTR_SET.uCDMA_WT_DONE_SET0();
s_intr_set_cdma_wt_done_set1_ = reg_group_ptr->rS_INTR_SET.uCDMA_WT_DONE_SET1();
s_intr_set_cacc_done_set0_ = reg_group_ptr->rS_INTR_SET.uCACC_DONE_SET0();
s_intr_set_cacc_done_set1_ = reg_group_ptr->rS_INTR_SET.uCACC_DONE_SET1();
s_intr_status_sdp_done_status0_ = reg_group_ptr->rS_INTR_STATUS.uSDP_DONE_STATUS0();
s_intr_status_sdp_done_status1_ = reg_group_ptr->rS_INTR_STATUS.uSDP_DONE_STATUS1();
s_intr_status_cdp_done_status0_ = reg_group_ptr->rS_INTR_STATUS.uCDP_DONE_STATUS0();
s_intr_status_cdp_done_status1_ = reg_group_ptr->rS_INTR_STATUS.uCDP_DONE_STATUS1();
s_intr_status_pdp_done_status0_ = reg_group_ptr->rS_INTR_STATUS.uPDP_DONE_STATUS0();
s_intr_status_pdp_done_status1_ = reg_group_ptr->rS_INTR_STATUS.uPDP_DONE_STATUS1();
s_intr_status_bdma_done_status0_ = reg_group_ptr->rS_INTR_STATUS.uBDMA_DONE_STATUS0();
s_intr_status_bdma_done_status1_ = reg_group_ptr->rS_INTR_STATUS.uBDMA_DONE_STATUS1();
s_intr_status_rubik_done_status0_ = reg_group_ptr->rS_INTR_STATUS.uRUBIK_DONE_STATUS0();
s_intr_status_rubik_done_status1_ = reg_group_ptr->rS_INTR_STATUS.uRUBIK_DONE_STATUS1();
s_intr_status_cdma_dat_done_status0_ = reg_group_ptr->rS_INTR_STATUS.uCDMA_DAT_DONE_STATUS0();
s_intr_status_cdma_dat_done_status1_ = reg_group_ptr->rS_INTR_STATUS.uCDMA_DAT_DONE_STATUS1();
s_intr_status_cdma_wt_done_status0_ = reg_group_ptr->rS_INTR_STATUS.uCDMA_WT_DONE_STATUS0();
s_intr_status_cdma_wt_done_status1_ = reg_group_ptr->rS_INTR_STATUS.uCDMA_WT_DONE_STATUS1();
s_intr_status_cacc_done_status0_ = reg_group_ptr->rS_INTR_STATUS.uCACC_DONE_STATUS0();
s_intr_status_cacc_done_status1_ = reg_group_ptr->rS_INTR_STATUS.uCACC_DONE_STATUS1();
}
GlbUpdateVariables
函数用于从 CNVDLA_GLB_REGSET
类对象中读取寄存器字段的值,并将这些值保存在 glb_reg_model
类的成员变量中。这些成员变量在后续的操作中可能会用于检查和更新中断状态以及其他功能。以下是此函数的功能:
- 从
reg_group_ptr
中读取CNVDLA_GLB_REGSET
类对象中的不同寄存器字段的值,并将它们保存在glb_reg_model
类的成员变量中。
例如,从 reg_group_ptr
中读取 rS_NVDLA_HW_VERSION
寄存器的 uMAJOR()
和 uMINOR()
字段的值,并将它们保存在 s_nvdla_hw_version_major_
和 s_nvdla_hw_version_minor_
成员变量中。类似地,它也从其他寄存器字段中读取值并保存在相应的成员变量中。
这样,glb_reg_model
类就可以在需要时访问这些成员变量,以执行不同的操作,例如检查中断状态、生成中断、响应 CSB 请求等等。