设计文档综述
数据通路设计
数据通路和实验指导书相仿。
如下图所示:
模块文件结构
新增系统桥(Bridge
)、协处理器(CP0
)、计时器(Timer
)、异常流水线(Exception Pipeline
)。
文件结构如下:
新增模块描述
系统桥 - Bridge
系统桥用于连接 CPU 和外设。系统桥能接收 CPU 传来的写存地址,自动的选择对应的外设(包括内存、异常、计时器)进行读写操作。
端口描述如下:
module Bridge (
// Bridge
input [31:0] b_data_addr,
output [31:0] b_data_rdata,
input [31:0] b_data_wdata,
input [3: 0] b_data_byteen,
input [31:0] b_inst_addr,
// DM
output [31:0] m_data_addr,
input [31:0] m_data_rdata,
output [31:0] m_data_wdata,
output [3: 0] m_data_byteen,
output [31:0] m_inst_addr,
// Timer 1
output [31:2] T1_Addr,
output T1_WE,
output [31:0] T1_Din,
input [31:0] T1_Dout,
// Timer 2
output [31:2] T2_Addr,
output T2_WE,
output [31:0] T2_Din,
input [31:0] T2_Dout,
// Interrupt
output [31:0] m_int_addr,
output [3 :0] m_int_byteen
);
协处理器 - CP0
协处理器用于处理异常信息。内置 SR
、Cause
、EPC
三个寄存器,用于表示异常信息。
端口定义如下:
module CP0 (
input clk,
input reset,
input cp_reg_we,
input [4: 0] cp_reg_addr,
input [31:0] cp_reg_wd,
output [31:0] cp_reg_rd,
input [31:0] cp_vpc,
input cp_bd,
input [4: 0] cp_exc_code,
input [5: 0] cp_HWInt,
input cp_exl_clr,
output [31:0] cp_epc,
output cp_int_req
);
计时器 - Timer
计时器用于产生定时中断或稳定中断脉冲。
代码已由课程组提供。
异常流水线 - Exception Pipeline
异常流水线专用于流水异常信息。可以理解为就是将原有的流水线寄存器独立出来了。
端口定义如下:
module ExceptionPipeline (
input clk,
input reset,
input D_bd,
input D_eret,
output cp_bd,
output cp_eret,
input [4:0] F_excCode,
input [4:0] D_excCode,
input [4:0] E_excCode,
input [4:0] M_excCode,
output [4:0] cp_exc_code
);
思考题
请查阅相关资料,说明鼠标和键盘的输入信号是如何被 CPU 知晓的?
鼠标和键盘的输入信号都会转化为不同的系统中断信号。CPU根据中断信号的值可以执行对应的汇编指令,这样就达到了相应鼠标和键盘的目的。
请思考为什么我们的 CPU 处理中断异常必须是已经指定好的地址?如果你的 CPU 支持用户自定义入口地址,即处理中断异常的程序由用户提供,其还能提供我们所希望的功能吗?如果可以,请说明这样可能会出现什么问题?否则举例说明。(假设用户提供的中断处理程序合法)
我认为是可以支持用户自定义入口地址的。
为何与外设通信需要 Bridge?
让CPU不需要关心具体的数据从何而来,只需要知道地址就可以了。一个模块只做一件事情。达到了高聚合的目的。
请阅读官方提供的定时器源代码,阐述两种中断模式的异同,并针对每一种模式绘制状态移图。
计数器模式 0:
当计数器倒计数为 0 后,计数器停止计数,Ctrl 寄存器的计数使能自动变为 0,并且中断信号始终保持有效,直到屏蔽中断或重新开始计数。
状态转移图如下:
计数器模式 1:
当计数器倒计时为 0 后,会自动的重新读取 preset 寄存器的值,然后重新开始倒计数。在这种模式下,中断信号只会产生一个周期。
状态转移图如下:
倘若中断信号流入的时候,在检测宏观 PC 的一级如果是一条空泡(你的 CPU 该级所有信息均为空)指令,此时会发生什么问题?在此例基础上请思考:在 P7 中,清空流水线产生的空泡指令应该保留原指令的哪些信息?
会导致宏观PC突然为0或者为x。在清空流水线的时候,应该保留PC信息。
为什么
jalr
指令为什么不能写成jalr $31, $31
?如果
jalr $31 $31
的延迟槽内发生异常或需要响应中断。那么$31
寄存器的值已经被jalr
改变,但是处理异常结束后,会再次执行jalr
指令,这就会跳转到不正确的PC
地址。