mirror of
https://github.com/handsomezhuzhu/2025-yatcpu.git
synced 2026-02-20 12:00:14 +00:00
288 lines
14 KiB
TeX
288 lines
14 KiB
TeX
\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} |