cv32e40p系列文章概览
cv32e40p系列<1> cv32e40p_top.sv
cv32e40p_top
模块是基于 RISC-V 架构的 CV32E40P 核心的顶层模块,这是一个高性能的32位嵌入式处理器。这个模块的参数和I/O信号定义在配置和接口核心中起着至关重要的作用。
参数
COREV_PULP
: 启用 PULP ISA 扩展。这包括自定义的 CSR 和硬件循环功能,但不包括cv.elw
指令。COREV_CLUSTER
: 激活 PULP 集群接口,包括cv.elw
。FPU
: 启用浮点单元,通过 APU 接口进行接口。FPU_ADDMUL_LAT
: 指定浮点加法/乘法通道的流水线寄存器数量。FPU_OTHERS_LAT
: 定义浮点比较/转换通道的流水线寄存器数量。ZFINX
: 启用通用寄存器中的浮点扩展。NUM_MHPMCOUNTERS
: 设置机器硬件性能监视计数器的数量。
I/O 信号
时钟和复位
clk_i
,rst_ni
: 标准时钟和低电平有效复位。pulp_clock_en_i
: PULP的时钟使能,仅在启用COREV_CLUSTER
时相关。scan_cg_en_i
: 用于测试以启用所有时钟门。
核心配置
boot_addr_i
,mtvec_addr_i
,dm_halt_addr_i
,hart_id_i
,dm_exception_addr_i
: 这些输入提供了如引导地址、机器陷阱向量基地址、调试模块停止地址、硬件线程 ID 和调试模块异常地址等重要的静态信息。
指令内存接口
- 这组信号(
instr_req_o
,instr_gnt_i
等)管理着从指令内存中取出指令的过程。
数据内存接口
- 与指令内存接口类似,但用于数据。它包括读/写操作、数据地址和数据传输的信号。
中断
irq_i
,irq_ack_o
,irq_id_o
: 管理中断,包括确认和识别。
调试接口
- 这些信号(
debug_req_i
,debug_havereset_o
等)用于调试目的,指示诸如重置、运行或停止等状态。
CPU 控制信号
fetch_enable_i
和core_sleep_o
控制取指过程和核心的睡眠模式。
使用
这个模块封装了 CV32E40P 处理器的核心功能,包括内存接口、调试和处理中断。参数允许进行相当大的定制,根据嵌入式应用的要求启用或禁用诸如 FPU 或 PULP 特定扩展等功能。
将此模块集成到更大的系统中时,正确配置这些参数并确保所有I/O信号正确连接到系统的其余部分,如内存控制器、外围设备和调试工具,至关重要。为了可靠的操作,与系统的时钟和复位信号正确同步也非常重要。
cv32e40p系列<1-3> cv32e40p_core.sv
模块和参数
cv32e40p_sleep_unit
: 这是处理器的睡眠单元,用于控制时钟门控和处理器的睡眠状态。.COREV_CLUSTER(COREV_CLUSTER)
: 该参数用于配置睡眠单元,具体是否与 PULP 集群相关。
输入和输出信号
-
时钟和复位接口:
clk_ungated_i
: 未门控的时钟输入。rst_n
: 复位信号。clk_gated_o
: 门控后的时钟输出,用于降低功耗。scan_cg_en_i
: 扫描时钟门控使能信号,用于测试。
-
核心睡眠控制:
core_sleep_o
: 核心睡眠输出信号,表明处理器是否进入睡眠模式。
-
指令获取使能:
fetch_enable_i
: 输入信号,表示是否允许指令获取。fetch_enable_o
: 输出信号,经过睡眠单元处理后的指令获取使能信号。
-
核心状态:
if_busy_i
,ctrl_busy_i
,lsu_busy_i
,apu_busy_i
: 这些信号输入表示不同部分的忙碌状态,用于决定是否可以进入睡眠模式。
-
PULP 集群和调试:
pulp_clock_en_i
: PULP 集群时钟使能信号。p_elw_start_i
,p_elw_finish_i
: 与cv.elw
指令相关的信号。debug_p_elw_no_sleep_i
: 调试模式下,cv.elw
指令不进入睡眠的信号。
-
从睡眠中唤醒:
wake_from_sleep_i
: 从睡眠状态唤醒的信号。
功能和用途
- 时钟门控: 睡眠单元根据处理器的状态动态控制时钟信号,以降低功耗。在处理器不活跃时,时钟可以被门控(关闭),从而节省能源。
- 睡眠管理: 当核心可进入睡眠模式时(例如,当没有活跃的任务或等待事件发生时),
core_sleep_o
信号被激活。 - 与 PULP 集群的兼容性: 如果处理器配置了 PULP 集群支持,睡眠单元将相应地管理与 PULP 相关的时钟和睡眠行为。
- 调试支持: 在调试模式下,处理器可能需要避免进入睡眠状态,特别是在执行特定指令(如
cv.elw
)时。
cv32e40p系列<4> cv32e40p_sleep_unit.sv
CV32E40P处理器的睡眠单元(Sleep Unit),特别是其有限状态机(FSM)的实现和时钟门控逻辑。
-
逻辑变量定义:
fetch_enable_q
和fetch_enable_d
:用于维护fetch_enable_i
信号的“粘性”版本,即使fetch_enable_i
变为低,该信号也保持高,直到条件允许它变低。core_busy_q
和core_busy_d
:表示核心是否忙碌,需要时钟继续运行。p_elw_busy_q
和p_elw_busy_d
:用于跟踪cv.elw指令的执行状态。
-
睡眠FSM逻辑:
- 在
COREV_CLUSTER
为1的情况下(即PULP集群环境),核心忙碌状态取决于是否在执行cv.elw指令以及指令取回(IF)或APU是否忙碌。 - 在非PULP集群环境下,核心忙碌状态由指令取回、控制器、LSU或APU的忙碌状态决定。
- 在
-
时钟门控逻辑:
clock_en
变量决定了是否使能时钟门控。在PULP集群环境下,时钟门控取决于fetch_enable_q
以及pulp_clock_en_i
或core_busy_q
。在非PULP集群环境下,时钟门控取决于fetch_enable_q
和wake_from_sleep_i
或core_busy_q
。
-
睡眠控制:
core_sleep_o
输出信号表示核心是否应该进入睡眠状态。在PULP集群环境下,这取决于cv.elw的执行状态和核心忙碌状态。在非PULP集群环境下,它基于fetch_enable_q
和clock_en
。
-
状态更新:
- 使用
always_ff
块在每个未门控时钟周期的上升沿更新状态变量,如core_busy_q
、p_elw_busy_q
和fetch_enable_q
。
- 使用
-
取指令使能:
fetch_enable_o
信号用于控制指令取回。它直接从fetch_enable_q
获取值。
-
时钟门控单元实例化:
cv32e40p_clock_gate
是时钟门控单元的实例化,负责根据clock_en
信号控制核心时钟clk_gated_o
。
总体而言,睡眠单元的设计旨在优化功耗,通过智能地控制时钟门控,来降低在处理器空闲或执行特定操作(如cv.elw或WFI指令)时的能耗。
cv32e40p系列<5> cv32e40p_if_stage.sv
CV32E40P处理器中的指令取回(Instruction Fetch, IF)阶段模块。该模块负责从内存中取回指令,并将它们传递到指令解码(ID)阶段。
-
模块参数:
COREV_PULP
、PULP_OBI
、PULP_SECURE
、FPU
和ZFINX
等参数用于配置模块的特定特性,例如PULP ISA扩展、安全特性和浮点单元。
-
输入信号:
clk
和rst_n
分别为时钟和复位信号。- 与异常处理相关的信号,如
m_trap_base_addr_i
和u_trap_base_addr_i
,用于计算异常偏移地址。 boot_addr_i
、dm_exception_addr_i
和dm_halt_addr_i
用于处理启动、调试异常和调试暂停地址。req_i
信号用于控制指令请求。
-
与指令缓存接口:
instr_req_o
、instr_addr_o
用于向指令缓存发出指令请求和提供地址。instr_gnt_i
、instr_rvalid_i
、instr_rdata_i
、instr_err_i
和instr_err_pmp_i
用于接收指令和错误信号。
-
IF阶段的输出:
- 包括指令的有效性、指令数据、是否压缩指令、是否非法指令和当前PC值等。
-
前向端口和控制信号:
- 用于控制程序计数器(PC)的信号,如
clear_instr_valid_i
、pc_set_i
、mepc_i
、uepc_i
、depc_i
、pc_mux_i
和exc_pc_mux_i
等。 m_exc_vec_pc_mux_i
和u_exc_vec_pc_mux_i
用于向量化中断处理。jump_target_id_i
和jump_target_ex_i
用于跳转和分支目标。
- 用于控制程序计数器(PC)的信号,如
-
硬件循环控制器信号:
hwlp_jump_i
和hwlp_target_i
用于硬件循环功能。
-
流水线控制:
halt_if_i
和id_ready_i
用于控制流水线的暂停和准备就绪状态。
-
杂项信号:
if_busy_o
和perf_imiss_o
用于指示IF阶段是否忙碌以及性能计数器。
cv32e40p系列<6> cv32e40p_prefetch_buffer.sv
-
主要内容:CV32E40P处理器的预取缓冲区(Prefetch Buffer)模块。预取缓冲区是一个关键组件,用于缓存指令,以减少对指令缓存的直接访问,从而优化指令取回性能。
-
功能描述:
- 预取缓冲区的主要作用是提前取指并缓存,减少了对指令存储器的直接访问次数,从而优化了指令取回的性能。
- 它能够处理分支指令和硬件循环,快速更新取指地址。
- 该模块还与指令存储器或指令缓存交互,发送指令请求,接收指令数据。
预取缓冲区是现代处理器设计中一个重要的组件,尤其是在那些需要高性能指令取回的场景。通过预先取出并缓存一定数量的指令,处理器能够减少等待指令存储器响应的时间,从而提高整体性能。
cv32e40p系列<7> cv32e40p_prefetch_controller.sv
- 主要内容:CV32E40P处理器中预取控制器(Prefetch Controller)模块。预取控制器负责根据取指阶段的控制流信息(如分支请求、硬件循环信号)来管理指令的预取过程,并与总线接口适配器进行通信,以确保连续的指令供应。以下是对代码的详细解释:
cv32e40p系列<8> cv32e40p_fifo.sv & cv32e40p_obi_interface.sv
- 主要内容:CV32E40P处理器中的FIFO(先进先出队列)模块。FIFO是处理器设计中用于存储和管理数据流的一个关键组件,常用于缓存和临时存储数据。以下是对FIFO模块的代码的详细解释:
cv32e40p系列<9> cv32e40p_aligner.sv & cv32e40p_compressed_decoder.sv
- 主要内容:CV32E40P处理器中的对齐器(Aligner)模块。对齐器的主要作用是处理取指(Fetch)阶段获取的指令数据,确保它们正确地对齐,并将它们传递到后续的阶段
cv32e40p系列<10-11> cv32e40p_id_stage.sv
- 主要内容:cv32e40p_id_stage 模块是 CV32E40P RISC-V 处理器的核心组件,代表处理器流水线中的指令解码(ID)阶段。这个模块负责解码从指令存储器中获取的指令,并为执行做准备。
- 参数:
- COREV_PULP, COREV_CLUSTER:指示是否包含 PULP ISA 扩展和集群扩展。
N_HWLP, N_HWLP_BITS:硬件循环相关配置。 - PULP_SECURE, USE_PMP:表示对安全特性的支持,如物理内存保护(PMP)。
- A_EXTENSION, APU, FPU, ZFINX:控制各种扩展的包含,例如原子操作(A 扩展)、应用处理单元(APU)、浮点单元(FPU)和 ZFINX 扩展。
- FPU_ADDMUL_LAT, FPU_OTHERS_LAT:FPU 操作的延迟。
- APU_NARGS_CPU, APU_WOP_CPU, APU_NDSFLAGS_CPU, APU_NUSFLAGS_CPU:APU 接口的参数。
- DEBUG_TRIGGER_EN:表示是否启用调试触发器。
cv32e40p系列<12-13> cv32e40p_register_file_ff.sv
- 主要内容:CV32E40P RISC-V 处理器的寄存器文件(cv32e40p_register_file)模块的实例化。寄存器文件是处理器核心的关键部分,用于存储和检索指令执行过程中使用的寄存器数据。
- 功能
- 每个读取端口包含一个地址输入(raddr_x_i)和一个数据输出(rdata_x_o)。
- 每个写入端口包含一个地址输入(waddr_x_i)、一个数据输入(wdata_x_i)和一个写使能信号(we_x_i)。
- 这个模块支持三个独立的读取端口和两个独立的写入端口,允许在同一周期内进行多个独立的读写操作。
通过这种方式,cv32e40p_register_file 模块为处理器核心提供高效、灵活的寄存器存储和访问机制
cv32e40p系列<14-16> cv32e40p_decoder.sv
- 主要内容:解码器负责解析指令,并生成相应的控制信号来驱动后续的执行单元,例如 ALU、乘法器、FPU 和 APU。
cv32e40p系列<17-19> cv32e40p_controller.sv
- 主要内容:该文件实现了处理器控制器模块,负责生成和管理处理器的控制信号。
- 功能
- 指令解码: 根据输入的指令 instr_rdata_i 生成一系列的控制信号。
- ALU 控制: 确定 ALU 操作的类型和所需的操作数。
- 乘法器控制: 根据指令配置乘法器操作和操作数。
- FPU 配置: 设置浮点单元的操作格式和舍入模式。
- APU 配置: 配置应用处理单元的操作。
- 寄存器文件控制: 控制寄存器文件的写操作。
- CSR 操作: 解析和执行 CSR 相关指令。
cv32e40p系列<20> cv32e40p_int_controller.sv
-
主要内容:中断控制器模块(cv32e40p_int_controller)。中断控制器是处理器的重要部分,用于处理来自外部和内部源的中断请求。
中断控制器模块是处理器中断管理机制的核心部分,它确保了处理器能够响应和处理外部和内部产生的中断。它通过监控各个中断线(irq_i)和中断安全状态(irq_sec_i)来做到这一点,并根据中断使能状态(由mie_bypass_i、m_ie_i和u_ie_i提供)和当前的权限等级(current_priv_lvl_i)来判断是否应该激活中断。
如果中断被激活,中断控制器将通过irq_req_ctrl_o信号通知处理器核心控制器,同时通过irq_id_ctrl_o提供激活的中断ID,并通过irq_sec_ctrl_o标识中断是否为安全中断。此外,irq_wu_ctrl_o用于从睡眠模式中唤醒处理器以响应中断。
该模块还通过mip_o输出更新机器中断挂起(MIP)寄存器的状态,该寄存器记录了哪些中断正在等待处理。处理器可以检查这个寄存器来确定当前有哪些挂起的中断需要处理。
cv32e40p系列<20-21> cv32e40p_ex_stage.sv
- 主要内容:这段代码描述了处理器执行阶段(EX stage)中的两个关键部分:算术逻辑单元(ALU)和加载存储单元(LSU)的写回逻辑,以及分支处理逻辑。
cv32e40p系列<22-23> cv32e40p_alu.sv
- 主要内容:CV32E40P 处理器的算术逻辑单元(ALU)模块。ALU 是处理器的核心部分之一,负责执行各种算术和逻辑操作。
cv32e40p系列<24> cv32e40p_popcnt.sv & cv32e40p_ff_one.sv & cv32e40p_alu_div.sv
- 主要内容:这些文件实现了不同的运算单元,包括位计数器、前导零计数器和除法器模块。
cv32e40p系列<25> cv32e40p_mult.sv
- 主要内容:cv32e40p_mult是为CV32E40P核心设计的多功能乘法器单元。这个模块能够处理包括整数、短字(subword)和点积乘法在内的各种类型的乘法操作,并且特别支持复数运算。
cv32e40p系列<26-28> cv32e40p_apu_disp.sv & cv32e40p_load_store_unit.sv
-
主要内容:cv32e40p_apu_disp是一个处理器内的算术处理单元调度器(APU Dispatcher),用于管理和调度算术处理单元(APU)的任务和资源。它是CV32E40P处理器架构的一部分,用于优化处理器内部的算术操作处理。
-
cv32e40p_load_store_unit是加载存储单元(LSU),用于处理数据的加载和存储操作。它是CV32E40P处理器架构的一部分,用于管理数据访问,包括对数据的读写、地址计算、数据对齐以及处理存取冲突等。
cv32e40p系列<29-32> cv32e40p_cs_registers.sv
- 主要内容:这篇文章描述了一个名为cv32e40p_cs_registers的SystemVerilog模块,它实现了遵循RISC-Vv1.9特权指令集的控制和状态寄存器,包括浮点数支持、中断管理、调试功能及性能计数器。模块参数涵盖了多种配置选项,如硬件循环、APU支持和安全特性。
cv32e40p系列<33> cv32e40p_fp_wrapper.sv & fpnew_top.sv & fpnew_opgroup_block.sv
- 主要内容:cv32e40p_fp_wrapper集成浮点运算单元(Floating-Point Unit, FPU)它将fpnew包中的浮点单元集成到CV32E40P核心中。
- fpnew_top模块的定义,它是浮点运算单元(Floating-Point Unit, FPU)的顶层模块,
- fpnew_opgroup_block模块,它是fpnew包中的一个子模块,用于执行特定类型的浮点运算操作。这个模块是在fpnew包的顶层模块fpnew_top内部使用的,用于处理具体的浮点运算操作
cv32e40p系列<34> cv32e40p_hwloop_regs.sv & cv32e40p_register_file_latch.sv
- 主要内容:这些文件实现了硬件循环寄存器和基于锁存器的寄存器文件模块,用于管理循环操作和寄存器存储。