\documentclass[12pt]{ctexart} % 使用 ctexart 文档类支持中文,12pt 字号 \usepackage[utf8]{inputenc} % 输入编码,保持兼容性 \usepackage[margin=2.5cm]{geometry} % 设置页边距 \usepackage{graphicx} % 导入图片 \usepackage{amsmath} % 支持数学公式 \usepackage{listings} % 代码块高亮 \usepackage{xcolor} % 用于代码高亮颜色 \usepackage{hyperref} % 目录、交叉引用可点击,生成PDF书签 \hypersetup{ colorlinks=true, % 这是关键,它会让链接文本以颜色显示,而不是边框 linkcolor=black, % 内部链接(如目录、章节引用)的颜色设为黑色 citecolor=green, % 引用文献的颜色(如果用不到可以忽略或设为黑色) urlcolor=blue, % URL链接的颜色(如果用不到可以忽略或设为黑色) filecolor=magenta, % 文件链接的颜色(如果用不到可以忽略或设为黑色) % 可以添加更多其他 PDF 元数据,让 PDF 文件信息更完整 pdftitle={实验四:总线接口设计与实现}, pdfauthor={朱梓涵}, pdfsubject={AXI4-Lite 总线协议设计与实现报告}, pdfkeywords={RISC-V, CPU, Chisel, AXI4-Lite, 总线, 实验报告} } % 目录、交叉引用可点击,生成PDF书签 \usepackage{fancyhdr} % 自定义页眉页脚 \usepackage{enumitem} % 列表项自定义 \usepackage{ifthen} % 条件判断(用于图片占位) % --- 图片缺失占位宏 --- \newcommand{\includegraphicsorplaceholder}[2][]{% \IfFileExists{#2}{\includegraphics[#1]{#2}}{\fbox{\parbox[c][0.2\textheight][c]{0.9\textwidth}{\centering Missing image: #2}}}% } % --- 页眉页脚设置 --- \pagestyle{fancy} \fancyhf{} % 清除所有页眉页脚字段 \fancyhead[L]{\MakeUppercase{实验四:总线接口设计与实现}} % 左侧页眉:大写实验名称 \fancyfoot[C]{\thepage} % 居中页脚:页码 \renewcommand{\headrulewidth}{0.4pt} % 页眉下方的横线粗细 \renewcommand{\footrulewidth}{0.4pt} % 页脚上方的横线粗细 % 解决 fancyhdr 提示的 \headheight 偏小问题 \setlength{\headheight}{15pt} % --- 标题信息 --- \title{\vspace{-2cm}\textbf{实验四:总线接口设计与实现}} % 标题,垂直间距调整 \author{朱梓涵 \ 学号:24325356} % 作者信息 \date{\today} % 显示当前日期 % --- 代码高亮风格定义 (Solarized-light) --- \definecolor{sol-base03}{HTML}{002b36} \definecolor{sol-base02}{HTML}{073642} \definecolor{sol-base01}{HTML}{586e75} \definecolor{sol-base00}{HTML}{657b83} \definecolor{sol-base0}{HTML}{839496} \definecolor{sol-base1}{HTML}{93a1a1} \definecolor{sol-base2}{HTML}{eee8d5} \definecolor{sol-base3}{HTML}{fdf6e3} \definecolor{sol-yellow}{HTML}{b58900} \definecolor{sol-orange}{HTML}{cb4b16} \definecolor{sol-red}{HTML}{dc322f} \definecolor{sol-magenta}{HTML}{d33682} \definecolor{sol-violet}{HTML}{6c71c4} \definecolor{sol-blue}{HTML}{268bd2} \definecolor{sol-cyan}{HTML}{2aa198} \definecolor{sol-green}{HTML}{859900} \lstdefinestyle{ScalaChiselStyle}{ commentstyle=\color{sol-base01}\itshape, keywordstyle=\color{sol-green}\bfseries, stringstyle=\color{sol-cyan}, basicstyle=\ttfamily\small, breakatwhitespace=false, breaklines=true, captionpos=b, keepspaces=true, numbers=none, showspaces=false, showstringspaces=false, showtabs=false, tabsize=2, frame=single, rulecolor=\color{black}, % 添加 Chisel 相关关键字 morekeywords={when, Mux, MuxLookup, IndexedSeq, U, io, :=, object, val, def, class, override, package, import, extends, with, Bits, UInt, SInt, elsewhen, otherwise, Wire, Bool, RegInit, asSInt, asUInt, switch, is, ChiselEnum, Value}, literate={:}{{\color{sol-base02}:}}1 } \lstset{style=ScalaChiselStyle} % 默认代码风格为 Scala/Chisel % --- 图片计数器与章节联动 --- \counterwithin{figure}{section} \counterwithin{table}{section} % --- 文档开始 --- \begin{document} \maketitle % 生成标题 \thispagestyle{empty} % 标题页无页码 % --- 正文开始 --- \section{实验目的} 本实验的主要目的是: \begin{enumerate}[label=\arabic*.] \item 理解 AXI4-Lite 总线协议的基本原理和通信机制。 \item 学习使用状态机实现总线协议。 \item 掌握主从设备之间的握手通信过程。 \item 理解 MMIO(Memory-Mapped I/O)的工作原理。 \item 将总线协议集成到流水线 CPU 中。 \end{enumerate} \section{实验环境} \begin{itemize} \item \textbf{操作系统}: Windows 11 \item \textbf{开发工具}: IntelliJ IDEA \item \textbf{构建工具}: SBT \item \textbf{仿真与测试}: Verilator, chiseltest \end{itemize} \section{实验原理} \subsection{AXI4-Lite 协议概述} AXI4-Lite 是总线协议的简化版本。它包含 5 个独立的通道: \begin{itemize} \item \textbf{读地址通道(AR)}:主机发送读地址。 \item \textbf{读数据通道(R)}:从机返回读取的数据。 \item \textbf{写地址通道(AW)}:主机发送写地址。 \item \textbf{写数据通道(W)}:主机发送写数据。 \item \textbf{写响应通道(B)}:从机返回写操作响应。 \end{itemize} \subsection{通信框架} 本实验采用的通信框架如下: \begin{itemize} \item \textbf{CPU 侧}:通过 \texttt{AXI4LiteMasterBundle} 接口发起读写请求。 \item \textbf{AXI4LiteMaster}:将简单的读写请求转换为符合 AXI4-Lite 协议的信号。 \item \textbf{AXI4LiteChannels}:5 个通道的信号线,符合 AXI4-Lite 规范。 \item \textbf{AXI4LiteSlave}:接收 AXI4-Lite 协议信号,转换为设备可理解的读写操作。 \item \textbf{设备侧}:通过 \texttt{AXI4LiteSlaveBundle} 接口响应读写请求。 \end{itemize} \subsection{握手机制} AXI4-Lite 协议采用 VALID/READY 握手机制: \begin{itemize} \item 发送方通过 \texttt{VALID} 信号表示数据有效。 \item 接收方通过 \texttt{READY} 信号表示准备接收。 \item 只有当 \texttt{VALID} 和 \texttt{READY} 同时为高时,握手完成,数据传输成功。 \end{itemize} \section{模块实现与分析} \subsection{状态机设计} 本实验使用状态机实现 AXI4-Lite 协议。定义了以下状态: \begin{lstlisting}[caption={状态定义}] object AXI4LiteStates extends ChiselEnum { val Idle, ReadAddr, ReadDataWait, ReadData, WriteAddr, WriteData, WriteResp = Value } \end{lstlisting} \subsection{AXI4LiteMaster 实现} \subsubsection{主机状态机逻辑} \begin{enumerate} \item \textbf{Idle 状态}:等待来自 CPU 的读写请求。收到读请求时,保存地址并转到 \texttt{ReadAddr} 状态;收到写请求时,保存地址和数据并转到 \texttt{WriteAddr} 状态。 \item \textbf{ReadAddr 状态}:拉高 \texttt{ARVALID},发送读地址 \texttt{ARADDR}。等待从机 \texttt{ARREADY} 信号,握手完成后,拉高 \texttt{RREADY},转到 \texttt{ReadData} 状态。 \item \textbf{ReadData 状态}:保持 \texttt{RREADY} 为高,等待从机 \texttt{RVALID}。收到 \texttt{RVALID} 时,锁存 \texttt{RDATA},拉高 \texttt{read_valid} 一个周期,通知 CPU 读取完成,随后返回 \texttt{Idle} 状态。 \item \textbf{WriteAddr 状态}:拉高 \texttt{AWVALID},发送写地址 \texttt{AWADDR}。等待从机 \texttt{AWREADY} 信号,握手完成后,拉高 \texttt{WVALID},转到 \texttt{WriteData} 状态。 \item \textbf{WriteData 状态}:保持 \texttt{WVALID} 为高,发送 \texttt{WDATA} 和 \texttt{WSTRB}。等待从机 \texttt{WREADY} 信号,握手完成后,拉高 \texttt{BREADY},转到 \texttt{WriteResp} 状态。 \item \textbf{WriteResp 状态}:保持 \texttt{BREADY} 为高,等待从机 \texttt{BVALID}。收到 \texttt{BVALID} 时,拉高 \texttt{write_valid} 一个周期,随后返回 \texttt{Idle} 状态。 \end{enumerate} \subsubsection{关键代码实现} \begin{lstlisting}[caption={主机状态机核心代码}, label={lst:master_core}] switch(state) { is(AXI4LiteStates.Idle) { when(io.bundle.read) { addr := io.bundle.address state := AXI4LiteStates.ReadAddr ARVALID := true.B }.elsewhen(io.bundle.write) { addr := io.bundle.address write_data := io.bundle.write_data write_strobe := io.bundle.write_strobe state := AXI4LiteStates.WriteAddr AWVALID := true.B } } } \end{lstlisting} 此外,当主机不在 \texttt{Idle} 状态时,\texttt{busy} 信号为高,拒绝新的请求: \begin{lstlisting} io.bundle.busy := state =/= AXI4LiteStates.Idle \end{lstlisting} 且 \texttt{valid} 信号在状态机执行前清零,确保只持续一个周期: \begin{lstlisting} when(read_valid) { read_valid := false.B } when(write_valid) { write_valid := false.B } \end{lstlisting} \subsection{AXI4LiteSlave 实现} \subsubsection{从机状态机逻辑} \begin{enumerate} \item \textbf{Idle 状态}:清除所有控制信号。优先响应读请求(\texttt{ARVALID}),收到时保存地址,拉高 \texttt{ARREADY},转到 \texttt{ReadAddr}。收到写请求时,保存地址,拉高 \texttt{AWREADY},转到 \texttt{WriteAddr}。 \item \textbf{ReadAddr 状态}:拉低 \texttt{ARREADY},拉高 \texttt{read} 信号通知设备读取数据,转到 \texttt{ReadData} 状态。 \item \textbf{ReadData 状态}:保持 \texttt{read} 为高,等待设备 \texttt{read_valid}。收到时锁存 \texttt{read_data} 到 \texttt{rdataReg},拉高 \texttt{RVALID},等待主机 \texttt{RREADY}。握手完成后返回 \texttt{Idle} 状态。 \item \textbf{WriteAddr 状态}:拉低 \texttt{AWREADY},等待主机 \texttt{WVALID}。收到写数据后,锁存数据和写选通,拉高 \texttt{WREADY} 和 \texttt{write},转到 \texttt{WriteData}。 \item \textbf{WriteData 状态}:拉低 \texttt{WREADY} 和 \texttt{write},拉高 \texttt{BVALID},转到 \texttt{WriteResp}。 \item \textbf{WriteResp 状态}:保持 \texttt{BVALID} 为高,等待主机 \texttt{BREADY}。握手完成后返回 \texttt{Idle} 状态。 \end{enumerate} \subsubsection{关键代码实现} \begin{lstlisting}[caption={从机状态机核心代码}, label={lst:slave_core}] switch(state) { is(AXI4LiteStates.Idle) { when(io.channels.read_address_channel.ARVALID) { addr := io.channels.read_address_channel.ARADDR ARREADY := true.B state := AXI4LiteStates.ReadAddr }.elsewhen(io.channels.write_address_channel.AWVALID) { addr := io.channels.write_address_channel.AWADDR AWREADY := true.B state := AXI4LiteStates.WriteAddr } } } \end{lstlisting} 使用寄存器保证 \texttt{RDATA} 在 \texttt{RVALID} 为高时保持稳定: \begin{lstlisting} val rdataReg = RegInit(0.U(dataWidth.W)) io.channels.read_data_channel.RDATA := rdataReg \end{lstlisting} \subsection{性能优化} 本实现采用了以下优化策略: \begin{enumerate} \item \textbf{流水化握手}:在地址握手完成后立即准备数据握手,减少等待周期。 \item \textbf{优先级处理}:从机优先响应读请求,提高取指效率。 \item \textbf{信号稳定性}:使用寄存器锁存关键数据,避免毛刺。 \end{enumerate} \section{CSR 指令与总线交互} CSR 指令在总线协议中的交互主要体现在 MMIO(Memory-Mapped I/O)上。CPU 通过地址映射访问 CSR 寄存器或外设寄存器: \begin{itemize} \item 读写 CSR 时,控制单元发出相应的读写请求。 \item AXI4-Lite Master 接收请求,将地址和数据转换为总线事务。 \item AXI4-Lite Slave 根据地址将请求路由到具体的 CSR 模块或外设。 \item 通过握手机制,确保数据传输的正确性和稳定性。 \end{itemize} \section{测试结果与分析} \subsection{测试原理} \texttt{BusTest.scala} 包含多个测试用例,验证 AXI4-Lite 实现的正确性: \begin{itemize} \item \textbf{FunctionalTest}:创建 \texttt{TestBox} 模块,模拟主从机忙碌状态,验证读写事务的地址、数据、选通信号及 \texttt{valid} 信号时序。 \item \textbf{连续事务测试}:随机生成 1000 个读写事务,模拟从机忙碌状态,验证高负载下的总线稳定性。 \item \textbf{其他测试}:包括 \texttt{TimerTest}(定时器)、\texttt{MemoryTestF}(内存)和 \texttt{ROMLoaderTestF}(ROM 加载)。 \end{itemize} \subsection{分析} \begin{enumerate} \item \textbf{正确性验证}:所有测试用例通过,说明实现符合 AXI4-Lite 协议规范。数据传输正确,地址、数据、选通信号及 \texttt{valid} 信号时序均符合预期。 \item \textbf{性能分析}:单次读写事务的握手周期符合设计预期(约 3-4 周期)。连续事务测试证明了总线在高负载下的可靠性。 \end{enumerate} \section{改进建议} \begin{enumerate}[label=\arabic*.] \item \textbf{建议:提供更多调试案例和方法指导。} 建议增加具体的调试案例,例如如何追踪一条指令在总线中的完整传输过程,如何分析波形图定位握手失败问题等。 \item \textbf{建议:增加可视化工具。} 建议提供或推荐一些工具,能够将总线上的信号交互以图形化方式展示,辅助理解握手过程。 \end{enumerate} \section{实验结论} 通过本次实验,我深入理解了 AXI4-Lite 总线协议的工作原理,掌握了使用状态机实现复杂通信协议的方法。我成功实现了: \begin{itemize} \item 符合 AXI4-Lite 规范的主机和从机模块。 \item 基于 VALID/READY 握手机制的通信流程。 \item 完善的测试用例,验证了总线的正确性和稳定性。 \end{itemize} 本次实验不仅提升了我的硬件设计能力,也让我对计算机系统中各模块间的互连和通信有了更深刻的认识,为后续更复杂的系统设计打下了坚实基础。 \end{document}