mirror of
https://github.com/handsomezhuzhu/2025-yatcpu.git
synced 2026-02-20 20:10:14 +00:00
lab4差MemoryTestF
This commit is contained in:
@@ -60,8 +60,6 @@ class CPU extends Module {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// lab1(cpu) end
|
// lab1(cpu) end
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -44,7 +44,6 @@ class InstructionFetch extends Module {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// la1(InstructionFetch) end
|
// la1(InstructionFetch) end
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
|
Before Width: | Height: | Size: 421 KiB After Width: | Height: | Size: 38 KiB |
@@ -35,17 +35,17 @@
|
|||||||
\@writefile{toc}{\contentsline {subsection}{\numberline {5.1}单元测试:InstructionDecoderTest 分析}{6}{subsection.5.1}\protected@file@percent }
|
\@writefile{toc}{\contentsline {subsection}{\numberline {5.1}单元测试:InstructionDecoderTest 分析}{6}{subsection.5.1}\protected@file@percent }
|
||||||
\@writefile{toc}{\contentsline {subsubsection}{\numberline {5.1.1}L-Type 指令测试分析}{6}{subsubsection.5.1.1}\protected@file@percent }
|
\@writefile{toc}{\contentsline {subsubsection}{\numberline {5.1.1}L-Type 指令测试分析}{6}{subsubsection.5.1.1}\protected@file@percent }
|
||||||
\@writefile{toc}{\contentsline {subsubsection}{\numberline {5.1.2}波形图分析}{7}{subsubsection.5.1.2}\protected@file@percent }
|
\@writefile{toc}{\contentsline {subsubsection}{\numberline {5.1.2}波形图分析}{7}{subsubsection.5.1.2}\protected@file@percent }
|
||||||
\@writefile{lof}{\contentsline {figure}{\numberline {5.1}{\ignorespaces \texttt {L-Type} 指令 \texttt {lw x10, 32(x5)} 的译码波形图}}{7}{figure.5.1}\protected@file@percent }
|
\@writefile{lof}{\contentsline {figure}{\numberline {5.1}{\ignorespaces \texttt {L-Type} 指令 \texttt {lw x3, 0(x8)} 的译码波形图}}{7}{figure.5.1}\protected@file@percent }
|
||||||
\newlabel{fig:lw_decode_waveform}{{5.1}{7}{\texttt {L-Type} 指令 \texttt {lw x10, 32(x5)} 的译码波形图}{figure.5.1}{}}
|
\newlabel{fig:lw_decode_waveform}{{5.1}{7}{\texttt {L-Type} 指令 \texttt {lw x3, 0(x8)} 的译码波形图}{figure.5.1}{}}
|
||||||
\@writefile{toc}{\contentsline {subsection}{\numberline {5.2}整体测试:CPUTest (以 \texttt {FibonacciTest} 为例)}{8}{subsection.5.2}\protected@file@percent }
|
\@writefile{toc}{\contentsline {subsection}{\numberline {5.2}整体测试:CPUTest (以 \texttt {FibonacciTest} 为例)}{8}{subsection.5.2}\protected@file@percent }
|
||||||
\@writefile{toc}{\contentsline {subsubsection}{\numberline {5.2.1}\texttt {fibonacci.c} 程序分析}{8}{subsubsection.5.2.1}\protected@file@percent }
|
\@writefile{toc}{\contentsline {subsubsection}{\numberline {5.2.1}\texttt {fibonacci.c} 程序分析}{8}{subsubsection.5.2.1}\protected@file@percent }
|
||||||
\newlabel{lst:fib_c}{{5}{8}{Fibonacci 递归程序 \texttt {fibonacci.c}}{lstlisting.5}{}}
|
\newlabel{lst:fib_c}{{5}{8}{Fibonacci 递归程序 \texttt {fibonacci.c}}{lstlisting.5}{}}
|
||||||
\@writefile{lol}{\contentsline {lstlisting}{\numberline {5}Fibonacci 递归程序 \texttt {fibonacci.c}}{8}{lstlisting.5}\protected@file@percent }
|
\@writefile{lol}{\contentsline {lstlisting}{\numberline {5}Fibonacci 递归程序 \texttt {fibonacci.c}}{8}{lstlisting.5}\protected@file@percent }
|
||||||
\newlabel{lst:chisel_test}{{6}{8}{Chisel 测试代码片段}{lstlisting.6}{}}
|
\newlabel{lst:chisel_test}{{6}{8}{Chisel 测试代码片段}{lstlisting.6}{}}
|
||||||
\@writefile{lol}{\contentsline {lstlisting}{\numberline {6}Chisel 测试代码片段}{8}{lstlisting.6}\protected@file@percent }
|
\@writefile{lol}{\contentsline {lstlisting}{\numberline {6}Chisel 测试代码片段}{8}{lstlisting.6}\protected@file@percent }
|
||||||
|
\@writefile{toc}{\contentsline {subsubsection}{\numberline {5.2.2}波形图分析}{9}{subsubsection.5.2.2}\protected@file@percent }
|
||||||
\@writefile{lof}{\contentsline {figure}{\numberline {5.2}{\ignorespaces Fibonacci 程序执行末期及结果写入内存的波形图}}{9}{figure.5.2}\protected@file@percent }
|
\@writefile{lof}{\contentsline {figure}{\numberline {5.2}{\ignorespaces Fibonacci 程序执行末期及结果写入内存的波形图}}{9}{figure.5.2}\protected@file@percent }
|
||||||
\newlabel{fig:fibonacci_waveform}{{5.2}{9}{Fibonacci 程序执行末期及结果写入内存的波形图}{figure.5.2}{}}
|
\newlabel{fig:fibonacci_waveform}{{5.2}{9}{Fibonacci 程序执行末期及结果写入内存的波形图}{figure.5.2}{}}
|
||||||
\@writefile{toc}{\contentsline {subsubsection}{\numberline {5.2.2}波形图分析}{9}{subsubsection.5.2.2}\protected@file@percent }
|
|
||||||
\@writefile{toc}{\contentsline {section}{\numberline {6}遇到的问题与改进建议}{10}{section.6}\protected@file@percent }
|
\@writefile{toc}{\contentsline {section}{\numberline {6}遇到的问题与改进建议}{10}{section.6}\protected@file@percent }
|
||||||
\@writefile{toc}{\contentsline {section}{\numberline {7}实验结论}{10}{section.7}\protected@file@percent }
|
\@writefile{toc}{\contentsline {section}{\numberline {7}实验结论}{10}{section.7}\protected@file@percent }
|
||||||
\gdef \@abspage@last{10}
|
\gdef \@abspage@last{10}
|
||||||
|
|||||||
Binary file not shown.
@@ -21,6 +21,12 @@
|
|||||||
% 目录、交叉引用可点击,生成PDF书签
|
% 目录、交叉引用可点击,生成PDF书签
|
||||||
\usepackage{fancyhdr} % 自定义页眉页脚
|
\usepackage{fancyhdr} % 自定义页眉页脚
|
||||||
\usepackage{enumitem} % 列表项自定义
|
\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}
|
\pagestyle{fancy}
|
||||||
@@ -29,6 +35,8 @@
|
|||||||
\fancyfoot[C]{\thepage} % 居中页脚:页码
|
\fancyfoot[C]{\thepage} % 居中页脚:页码
|
||||||
\renewcommand{\headrulewidth}{0.4pt} % 页眉下方的横线粗细
|
\renewcommand{\headrulewidth}{0.4pt} % 页眉下方的横线粗细
|
||||||
\renewcommand{\footrulewidth}{0.4pt} % 页脚上方的横线粗细
|
\renewcommand{\footrulewidth}{0.4pt} % 页脚上方的横线粗细
|
||||||
|
% 解决 fancyhdr 提示的 \headheight 偏小问题
|
||||||
|
\setlength{\headheight}{15pt}
|
||||||
|
|
||||||
% --- 标题信息 ---
|
% --- 标题信息 ---
|
||||||
\title{\vspace{-2cm}\textbf{实验一:单周期 RISC-V CPU 设计与实现}} % 标题,垂直间距调整
|
\title{\vspace{-2cm}\textbf{实验一:单周期 RISC-V CPU 设计与实现}} % 标题,垂直间距调整
|
||||||
@@ -155,7 +163,7 @@ when(io.jump_flag_id) {
|
|||||||
\subsubsection{波形图}
|
\subsubsection{波形图}
|
||||||
\begin{figure}[htbp]
|
\begin{figure}[htbp]
|
||||||
\centering
|
\centering
|
||||||
\includegraphics[width=0.9\textwidth]{b1.png}
|
\includegraphicsorplaceholder[width=0.9\textwidth]{b1.png}
|
||||||
\caption{取指模块 (\texttt{InstructionFetch}) 波形图}
|
\caption{取指模块 (\texttt{InstructionFetch}) 波形图}
|
||||||
\label{fig:if_waveform}
|
\label{fig:if_waveform}
|
||||||
\end{figure}
|
\end{figure}
|
||||||
@@ -191,7 +199,7 @@ io.wb_reg_write_source := MuxLookup(
|
|||||||
\subsubsection{波形图}
|
\subsubsection{波形图}
|
||||||
\begin{figure}[htbp]
|
\begin{figure}[htbp]
|
||||||
\centering
|
\centering
|
||||||
\includegraphics[width=0.9\textwidth]{b2.png}
|
\includegraphicsorplaceholder[width=0.9\textwidth]{b2.png}
|
||||||
\caption{译码模块 (\texttt{InstructionDecode}) 波形图}
|
\caption{译码模块 (\texttt{InstructionDecode}) 波形图}
|
||||||
\label{fig:id_waveform}
|
\label{fig:id_waveform}
|
||||||
\end{figure}
|
\end{figure}
|
||||||
@@ -205,7 +213,7 @@ io.wb_reg_write_source := MuxLookup(
|
|||||||
\subsubsection{波形图}
|
\subsubsection{波形图}
|
||||||
\begin{figure}[htbp]
|
\begin{figure}[htbp]
|
||||||
\centering
|
\centering
|
||||||
\includegraphics[width=0.9\textwidth]{b3.png}
|
\includegraphicsorplaceholder[width=0.9\textwidth]{b3.png}
|
||||||
\caption{执行模块 (\texttt{Execute}) 波形图}
|
\caption{执行模块 (\texttt{Execute}) 波形图}
|
||||||
\label{fig:ex_waveform}
|
\label{fig:ex_waveform}
|
||||||
\end{figure}
|
\end{figure}
|
||||||
@@ -264,19 +272,20 @@ ex.io.aluop2_source := id.io.ex_aluop2_source
|
|||||||
\subsubsection{波形图分析}
|
\subsubsection{波形图分析}
|
||||||
\begin{figure}[htbp]
|
\begin{figure}[htbp]
|
||||||
\centering
|
\centering
|
||||||
\includegraphics[width=0.9\textwidth]{b2.png}
|
\includegraphicsorplaceholder[width=0.9\textwidth]{b2.png}
|
||||||
\caption{\texttt{L-Type} 指令 \texttt{lw x10, 32(x5)} 的译码波形图}
|
\caption{\texttt{L-Type} 指令 \texttt{lw x3, 0(x8)} 的译码波形图}
|
||||||
\label{fig:lw_decode_waveform}
|
\label{fig:lw_decode_waveform}
|
||||||
\end{figure}
|
\end{figure}
|
||||||
图 \ref{fig:lw_decode_waveform} 所示波形图展示了 \texttt{lw x10, 32(x5)} 指令(机器码 \texttt{0x02028503})的译码过程。在时钟上升沿之后:
|
如图所示,波形图展示了指令 lw x3, 0(x8)(机器码 0x00404183)的译码过程。在时钟上升沿之后:
|
||||||
|
|
||||||
\begin{itemize}
|
\begin{itemize}
|
||||||
\item \texttt{id\_io\_instruction} 端口稳定为 \texttt{0x02028503}。
|
\item \verb|id_io_instruction| 端口稳定为 \texttt{0x00404183},对应 I-type 的 Load 指令 \texttt{lw x3, 0(x8)}。
|
||||||
\item \texttt{id\_io\_memory\_read\_enable}
|
\item \verb|id_io_memory_read_enable| 和 \verb|id_io_reg_write_enable| 信号被置为高电平(1),表示该指令需要从存储器读取数据并写回寄存器。
|
||||||
和 \texttt{id\_io\_reg\_write\_enable} 信号被置为高电平 (1)。
|
\item \verb|id_io_wb_reg_write_source| 信号值为 \texttt{01} (二进制),表示写回数据的来源是 Memory。
|
||||||
\item \texttt{id\_io\_wb\_reg\_write\_source} 信号变为 \texttt{01} (二进制),对应 \texttt{RegWriteSource.Memory}。
|
\item \verb|id_io_ex_immediate| 的值为 \texttt{0x00000000},即偏移量 0。
|
||||||
\item \texttt{id\_io\_ex\_immediate} 的值为 \texttt{0x00000020},即十进制的 32。
|
|
||||||
\end{itemize}
|
\end{itemize}
|
||||||
波形图直观地验证了译码模块对于 L-Type 指令的响应与 \texttt{expect} 语句的预期完全一致。
|
|
||||||
|
波形验证了译码模块对 I-type (Load)指令的控制信号输出与 \texttt{InstructionDecoderTest.scala} 中的 \texttt{expect} 语句一致,说明译码单元能够正确识别 Load 指令并产生相应控制信号。
|
||||||
|
|
||||||
\subsection{整体测试:CPUTest (以 \texttt{FibonacciTest} 为例)}
|
\subsection{整体测试:CPUTest (以 \texttt{FibonacciTest} 为例)}
|
||||||
|
|
||||||
@@ -307,23 +316,31 @@ c.io.mem_debug_read_data.expect(55.U) // 期望从地址 0x4 读出的数据为
|
|||||||
\subsubsection{波形图分析}
|
\subsubsection{波形图分析}
|
||||||
\begin{figure}[htbp]
|
\begin{figure}[htbp]
|
||||||
\centering
|
\centering
|
||||||
\includegraphics[width=0.9\textwidth]{b41.png}
|
\includegraphicsorplaceholder[width=0.9\textwidth]{b41.png}
|
||||||
\caption{Fibonacci 程序执行末期及结果写入内存的波形图}
|
\caption{Fibonacci 程序执行末期及结果写入内存的波形图}
|
||||||
\label{fig:fibonacci_waveform}
|
\label{fig:fibonacci_waveform}
|
||||||
\end{figure}
|
\end{figure}
|
||||||
图 \ref{fig:fibonacci_waveform} 展示了 \texttt{fibonacci} 程序执行的最后几个周期以及结果检查阶段。
|
基于 VCD 文件分析,斐波那契程序执行过程中的关键信号包括:
|
||||||
\begin{itemize}
|
\begin{itemize}
|
||||||
\item \textbf{执行分析}: 在波形图的前半部分,可以看到 CPU 正在执行 \texttt{main} 函数中对 \texttt{fib(10)} 的调用,并最终将结果存储到内存地址 \texttt{0x4}。由于斐波那契数列的递归特性,PC 会在函数调用和返回的过程中不断跳转。在程序即将结束时,PC 会最终指向退出或停机指令。
|
\item \verb|cpu_io_instruction_address|:程序计数器(PC),显示指令的执行流程;
|
||||||
\item \textbf{结果检查}: \texttt{main} 函数的核心是 \texttt{*(int *)(4) = fib(10);} 这条语句,它会在 \texttt{fib(10)} 的计算结果(即 55)准备好后,将其写入数据存储器的 \texttt{0x4} 地址。
|
\item \verb|mem_io_bundle_write_enable|:内存写使能信号,用于标识数据写入操作;
|
||||||
在波形图的最后几个周期,我们会观察到以下关键信号变化:
|
\item \verb|mem_io_bundle_address|:内存访问地址;
|
||||||
\begin{itemize}
|
\item \verb|mem_io_bundle_write_data|:写入内存的数据;
|
||||||
\item \texttt{mem\_io\_memory\_write\_enable} 信号短暂置高(为 \texttt{1}),表明数据存储器发生了写入操作。
|
\item \verb|io_mem_debug_read_data|:调试接口读取的内存数据,用于结果验证。
|
||||||
\item \texttt{mem\_io\_memory\_bundle\_address} 信号会显示为 \texttt{0x00000004},确认写入目标是内存地址 \texttt{0x4}。
|
|
||||||
\item \texttt{mem\_io\_memory\_bundle\_write\_data[31:0]} 信号会显示为 \texttt{0x00000037}(十六进制的 55),这是 \texttt{fib(10)} 的计算结果。
|
|
||||||
\item 在这之后,由于测试使用 \texttt{c.io.mem\_debug\_read\_address.poke(4.U)} 来读取内存,波形图上 \texttt{mem\_io\_debug\_read\_address} 会变为 \texttt{0x4},同时 \texttt{io\_mem\_debug\_read\_data}(或类似输出调试信号)会稳定显示出 \texttt{0x00000037}。
|
|
||||||
\end{itemize}
|
\end{itemize}
|
||||||
\end{itemize}
|
|
||||||
这些波形特征与 Chisel 测试中 \texttt{mem\_debug\_read\_data.expect(55.U)} 的断言完美吻合,证明 CPU 正确地执行了 \texttt{fibonacci} 程序并存储了预期结果。
|
所选测试程序为斐波那契数列求解程序,其功能是计算第 10 项的值(即 55),并在程序结束时将结果写入数据存储器地址 \texttt{0x00000004}。在 \texttt{CPUTest.scala} 的测试中,系统通过监测访存信号或从调试接口读取该地址的值,验证处理器输出是否正确。
|
||||||
|
|
||||||
|
在程序执行的最后阶段,可以在波形中观察到以下现象:
|
||||||
|
|
||||||
|
\begin{enumerate}
|
||||||
|
\item \verb|mem_io_bundle_write_enable| 信号置高,表示 CPU 正在执行 \verb|sw| 指令;
|
||||||
|
\item \verb|mem_io_bundle_address| 显示为 \verb|0x00000004|,即目标内存地址为 4;
|
||||||
|
\item \verb|mem_io_bundle_write_data| 显示为 \verb|0x00000037|(十进制 55),即 \verb|fib(10)| 的计算结果;
|
||||||
|
\item 随后,调试接口 \verb|io_mem_debug_read_data| 读出并稳定为相同的值 \verb|0x00000037|。
|
||||||
|
\end{enumerate}
|
||||||
|
|
||||||
|
由此可知,CPU 成功将计算结果 55 写入目标地址,测试检查结果正确,验证了数据通路及访存阶段的功能实现。
|
||||||
|
|
||||||
\section{遇到的问题与改进建议}
|
\section{遇到的问题与改进建议}
|
||||||
|
|
||||||
@@ -340,14 +357,9 @@ c.io.mem_debug_read_data.expect(55.U) // 期望从地址 0x4 读出的数据为
|
|||||||
\item \textbf{建议}:实验文档中可以附加一个简单的调试案例,例如追踪一条 \texttt{add} 指令的数据流,展示如何从取指 PC 开始,逐步添加 `instruction`, `reg\_read\_data`, `alu\_result`, `reg\_write\_data` 等信号,并解释它们在波形图上的时序关系。
|
\item \textbf{建议}:实验文档中可以附加一个简单的调试案例,例如追踪一条 \texttt{add} 指令的数据流,展示如何从取指 PC 开始,逐步添加 `instruction`, `reg\_read\_data`, `alu\_result`, `reg\_write\_data` 等信号,并解释它们在波形图上的时序关系。
|
||||||
\end{itemize}
|
\end{itemize}
|
||||||
|
|
||||||
\item \textbf{问题:部分模块接口和控制信号的设计意图不够明确。}
|
|
||||||
例如,\texttt{ALUOp1Source} 和 \texttt{ALUOp2Source} 这类控制信号的设计初衷,需要通过阅读多个模块的代码才能完全理解其作用。
|
|
||||||
\begin{itemize}
|
|
||||||
\item \textbf{建议}:在代码框架的注释中,对关键的 `object` 或 `Enum`(如 \texttt{ALUOp1Source}),增加注释来说明每个选项的用途和对应的指令场景。
|
|
||||||
\end{itemize}
|
|
||||||
\end{enumerate}
|
\end{enumerate}
|
||||||
|
|
||||||
\section{实验结论}
|
\section{实验结论}
|
||||||
通过本次实验,我成功设计并实现了一个功能基本完备的 RISC-V 单周期 CPU。在实现过程中,我深入理解了数据通路与控制信号在指令执行过程中的协同作用,并掌握了模块化的硬件设计思想。通过编写和分析单元测试与集成测试,我学会了如何利用 \texttt{chiseltest} 和波形图对硬件设计进行验证和调试。本次实验极大地加深了我对计算机组成原理中理论知识的实践理解,为后续更复杂的处理器设计打下了坚实的基础。
|
通过本次实验,我成功设计并实现了一个功能基本完备的 RISC-V 单周期 CPU。在实现过程中,我深入理解了数据通路与控制信号在指令执行过程中的协同作用,并掌握了模块化的硬件设计思想。通过编写和分析单元测试与集成测试,我学会了如何利用波形图对硬件设计进行验证和调试。本次实验极大地加深了我对计算机组成原理中理论知识的实践理解,为后续更复杂的处理器设计打下了坚实的基础。
|
||||||
|
|
||||||
\end{document}
|
\end{document}
|
||||||
|
|||||||
@@ -134,6 +134,7 @@ class AXI4LiteSlave(addrWidth: Int, dataWidth: Int) extends Module {
|
|||||||
val write_strobe = RegInit(VecInit(Seq.fill(Parameters.WordSize)(false.B)))
|
val write_strobe = RegInit(VecInit(Seq.fill(Parameters.WordSize)(false.B)))
|
||||||
io.bundle.write_strobe := write_strobe
|
io.bundle.write_strobe := write_strobe
|
||||||
|
|
||||||
|
val read_issued = RegInit(false.B)
|
||||||
val ARREADY = RegInit(false.B)
|
val ARREADY = RegInit(false.B)
|
||||||
io.channels.read_address_channel.ARREADY := ARREADY
|
io.channels.read_address_channel.ARREADY := ARREADY
|
||||||
val RVALID = RegInit(false.B)
|
val RVALID = RegInit(false.B)
|
||||||
@@ -153,6 +154,94 @@ class AXI4LiteSlave(addrWidth: Int, dataWidth: Int) extends Module {
|
|||||||
val BRESP = WireInit(0.U(AXI4Lite.respWidth))
|
val BRESP = WireInit(0.U(AXI4Lite.respWidth))
|
||||||
io.channels.write_response_channel.BRESP := BRESP
|
io.channels.write_response_channel.BRESP := BRESP
|
||||||
//lab4(BUS)
|
//lab4(BUS)
|
||||||
|
switch(state) {
|
||||||
|
is(AXI4LiteStates.Idle) {
|
||||||
|
// 默认状态:所有控制信号为低
|
||||||
|
ARREADY := false.B
|
||||||
|
RVALID := false.B
|
||||||
|
AWREADY := false.B
|
||||||
|
WREADY := false.B
|
||||||
|
BVALID := false.B
|
||||||
|
|
||||||
|
// 检测读地址通道的请求
|
||||||
|
when(io.channels.read_address_channel.ARVALID) {
|
||||||
|
read := false.B // 清除之前的read
|
||||||
|
state := AXI4LiteStates.ReadAddr
|
||||||
|
addr := io.channels.read_address_channel.ARADDR
|
||||||
|
ARREADY := true.B
|
||||||
|
}.elsewhen(io.channels.write_address_channel.AWVALID) {
|
||||||
|
write := false.B // 清除之前的write
|
||||||
|
// 检测写地址通道的请求
|
||||||
|
state := AXI4LiteStates.WriteAddr
|
||||||
|
addr := io.channels.write_address_channel.AWADDR
|
||||||
|
AWREADY := true.B
|
||||||
|
}.otherwise {
|
||||||
|
// 没有新请求时,延迟清除read/write信号
|
||||||
|
read := false.B
|
||||||
|
write := false.B
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
is(AXI4LiteStates.ReadAddr) {
|
||||||
|
// 读地址握手完成,发起读请求并进入ReadData
|
||||||
|
ARREADY := false.B
|
||||||
|
read := true.B
|
||||||
|
read_issued := false.B
|
||||||
|
state := AXI4LiteStates.ReadData
|
||||||
|
}
|
||||||
|
|
||||||
|
is(AXI4LiteStates.ReadData) {
|
||||||
|
// 保持read信号有效
|
||||||
|
read := true.B
|
||||||
|
|
||||||
|
when(!read_issued) {
|
||||||
|
// 第一个周期:等待Memory准备数据
|
||||||
|
read_issued := true.B
|
||||||
|
}.otherwise {
|
||||||
|
// 第二个周期及之后:检查数据是否准备好
|
||||||
|
when(!RVALID && io.bundle.read_valid) {
|
||||||
|
// 数据准备好,置RVALID
|
||||||
|
RVALID := true.B
|
||||||
|
}.elsewhen(RVALID && io.channels.read_data_channel.RREADY) {
|
||||||
|
// 握手完成,返回Idle(read会在Idle状态延迟清除)
|
||||||
|
RVALID := false.B
|
||||||
|
read_issued := false.B
|
||||||
|
state := AXI4LiteStates.Idle
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
is(AXI4LiteStates.WriteAddr) {
|
||||||
|
// 写地址握手完成,等待写数据
|
||||||
|
AWREADY := false.B
|
||||||
|
when(io.channels.write_data_channel.WVALID) {
|
||||||
|
// 收到写数据
|
||||||
|
state := AXI4LiteStates.WriteData
|
||||||
|
for (i <- 0 until Parameters.WordSize) {
|
||||||
|
write_strobe(i) := io.channels.write_data_channel.WSTRB(i)
|
||||||
|
}
|
||||||
|
WREADY := true.B
|
||||||
|
write := true.B
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
is(AXI4LiteStates.WriteData) {
|
||||||
|
// 写数据握手完成,等待写入完成后发送响应
|
||||||
|
WREADY := false.B
|
||||||
|
write := false.B
|
||||||
|
state := AXI4LiteStates.WriteResp
|
||||||
|
BVALID := true.B
|
||||||
|
}
|
||||||
|
|
||||||
|
is(AXI4LiteStates.WriteResp) {
|
||||||
|
// 等待写响应握手
|
||||||
|
when(io.channels.write_response_channel.BREADY) {
|
||||||
|
// 写响应握手完成
|
||||||
|
BVALID := false.B
|
||||||
|
state := AXI4LiteStates.Idle
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -180,7 +269,7 @@ class AXI4LiteMaster(addrWidth: Int, dataWidth: Int) extends Module {
|
|||||||
val RREADY = RegInit(false.B)
|
val RREADY = RegInit(false.B)
|
||||||
io.channels.read_data_channel.RREADY := RREADY
|
io.channels.read_data_channel.RREADY := RREADY
|
||||||
|
|
||||||
io.bundle.read_data := io.channels.read_data_channel.RDATA
|
io.bundle.read_data := read_data
|
||||||
val AWVALID = RegInit(false.B)
|
val AWVALID = RegInit(false.B)
|
||||||
io.channels.write_address_channel.AWADDR := 0.U
|
io.channels.write_address_channel.AWADDR := 0.U
|
||||||
io.channels.write_address_channel.AWVALID := AWVALID
|
io.channels.write_address_channel.AWVALID := AWVALID
|
||||||
@@ -192,5 +281,95 @@ class AXI4LiteMaster(addrWidth: Int, dataWidth: Int) extends Module {
|
|||||||
val BREADY = RegInit(false.B)
|
val BREADY = RegInit(false.B)
|
||||||
io.channels.write_response_channel.BREADY := BREADY
|
io.channels.write_response_channel.BREADY := BREADY
|
||||||
//lab4(BUS)
|
//lab4(BUS)
|
||||||
|
// 清零valid信号(如果不是刚刚被置1)
|
||||||
|
when(read_valid) {
|
||||||
|
read_valid := false.B
|
||||||
|
}
|
||||||
|
when(write_valid) {
|
||||||
|
write_valid := false.B
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(state) {
|
||||||
|
is(AXI4LiteStates.Idle) {
|
||||||
|
// 默认状态:所有控制信号为低
|
||||||
|
ARVALID := false.B
|
||||||
|
RREADY := false.B
|
||||||
|
AWVALID := false.B
|
||||||
|
WVALID := false.B
|
||||||
|
BREADY := false.B
|
||||||
|
|
||||||
|
// 检测读请求
|
||||||
|
when(io.bundle.read) {
|
||||||
|
state := AXI4LiteStates.ReadAddr
|
||||||
|
addr := io.bundle.address
|
||||||
|
ARVALID := true.B
|
||||||
|
}.elsewhen(io.bundle.write) {
|
||||||
|
// 检测写请求
|
||||||
|
state := AXI4LiteStates.WriteAddr
|
||||||
|
addr := io.bundle.address
|
||||||
|
write_data := io.bundle.write_data
|
||||||
|
write_strobe := io.bundle.write_strobe
|
||||||
|
AWVALID := true.B
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
is(AXI4LiteStates.ReadAddr) {
|
||||||
|
// 发送读地址,等待从机响应
|
||||||
|
ARVALID := true.B
|
||||||
|
io.channels.read_address_channel.ARADDR := addr
|
||||||
|
when(io.channels.read_address_channel.ARREADY) {
|
||||||
|
// 读地址握手完成
|
||||||
|
ARVALID := false.B
|
||||||
|
state := AXI4LiteStates.ReadData
|
||||||
|
RREADY := true.B
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
is(AXI4LiteStates.ReadData) {
|
||||||
|
// 等待读数据,保持RREADY为高
|
||||||
|
RREADY := true.B
|
||||||
|
when(io.channels.read_data_channel.RVALID) {
|
||||||
|
// 读数据握手完成
|
||||||
|
read_data := io.channels.read_data_channel.RDATA
|
||||||
|
RREADY := false.B
|
||||||
|
read_valid := true.B
|
||||||
|
state := AXI4LiteStates.Idle
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
is(AXI4LiteStates.WriteAddr) {
|
||||||
|
// 发送写地址,等待从机响应
|
||||||
|
AWVALID := true.B
|
||||||
|
io.channels.write_address_channel.AWADDR := addr
|
||||||
|
when(io.channels.write_address_channel.AWREADY) {
|
||||||
|
// 写地址握手完成
|
||||||
|
AWVALID := false.B
|
||||||
|
state := AXI4LiteStates.WriteData
|
||||||
|
WVALID := true.B
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
is(AXI4LiteStates.WriteData) {
|
||||||
|
// 发送写数据,保持WVALID为高
|
||||||
|
WVALID := true.B
|
||||||
|
when(io.channels.write_data_channel.WREADY) {
|
||||||
|
// 写数据握手完成
|
||||||
|
WVALID := false.B
|
||||||
|
state := AXI4LiteStates.WriteResp
|
||||||
|
BREADY := true.B
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
is(AXI4LiteStates.WriteResp) {
|
||||||
|
// 等待写响应,保持BREADY为高
|
||||||
|
BREADY := true.B
|
||||||
|
when(io.channels.write_response_channel.BVALID) {
|
||||||
|
// 写响应握手完成
|
||||||
|
BREADY := false.B
|
||||||
|
write_valid := true.B
|
||||||
|
state := AXI4LiteStates.Idle
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user