Files
2025-yatcpu/lab4/实验报告/lab4_report.tex
2025-12-21 23:11:21 +08:00

288 lines
14 KiB
TeX
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

\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 理解 MMIOMemory-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 指令在总线协议中的交互主要体现在 MMIOMemory-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}