CA-模块体系

Molaters Lv5
  1. IMEM模块用于指令存储器的读取,将PC地址传递给存储器,读取当前指令到IRin

  2. PC模块用于管理程序计数器,包括在时钟上升沿时选择下一条指令的地址,以及处理复位信号。

  3. ADD模块用于计算下一条指令的地址,将当前PC地址传递给PC模块。

  4. NPC模块用于存储下一条指令的地址。

  5. IR模块用于指令寄存器的加载,将当前指令传递给IRout

ID (Instruction Decode) 模块:

  1. Regfile模块用于管理寄存器堆的读和写操作,根据指令选择寄存器读取和写入。

  2. CU模块用于控制单元,解析指令并生成相应的控制信号,例如ALU操作码、写寄存器使能等。

  3. AB模块用于选择和加载寄存器A和B的数据。

  4. Extender模块用于符号扩展立即数。

  5. Imm模块用于加载立即数。

EX (Execution) 模块:

  1. A_MUXB_MUX模块用于选择ALU的输入数据,可以选择寄存器数据、NPC、基址或立即数。

  2. ALU模块执行ALU操作,并生成结果和零标志。

MEM (Memory) 模块:

  1. ALU_out模块用于加载ALU的结果。

  2. PC_MUX模块用于选择下一个PC地址,可以选择NPC、ALU结果或分支指令的目标地址。

  3. WB_Reg_MUX模块用于选择写回数据,可以选择ALU结果、内存读取结果或寄存器A的数据。

  4. WB_Reg_Addr_MUX模块用于选择写回寄存器的地址。

  5. DMEM模块用于数据存储器的读写操作。

  6. LDM模块用于加载内存数据。

其他:

  • debug_wb_pcdebug_wb_rf_wendebug_wb_rf_addrdebug_wb_rf_wdata用于调试目的,输出当前执行指令的信息。

这个CPU的基本架构是一个五级流水线,包括IF、ID、EX、MEM和WB(写回)阶段。每个阶段由不同的模块负责执行特定的任务,并在时钟上升沿进行数据传递。各个模块之间通过信号进行通信,根据指令的不同,选择不同的数据路径和操作。

以下是在前面的叙述中添加了原始Verilog代码的版本:

IF (Instruction Fetch) 模块:

  1. IMEM模块用于指令存储器的读取,将PC地址传递给存储器,读取当前指令到IRin

verilog

1
2
3
4
5
IMEM U_IMEM (
.clk(clk), // 时钟信号
.imem_addr(PCout[7:0]), // 选定存储地址
.imem_rdata(IRin) // 读出的指令
);
  1. PC模块用于管理程序计数器,包括在时钟上升沿时选择下一条指令的地址,以及处理复位信号。

verilog

1
2
3
4
5
6
7
PC U_PC (
.Reset(!resetn),
.Clk(clk),
.PCwen(1'b1),
.NPC(PC_chosen), // 是由选择器给出的
.PC(PCout)
);
  1. ADD模块用于计算下一条指令的地址,将当前PC地址传递给PC模块。

verilog

1
2
3
4
ADD U_ADD (
.PC(PCout),
.NextPC(NewPC)
);
  1. NPC模块用于存储下一条指令的地址。

verilog

1
2
3
4
5
6
7
NPC U_NPC (
.clk(clk), // 时钟输入
.rst(!resetn), // 复位输入
.NPCin(NewPC),
.load(1'b1), // 载入使能
.NPCout(NPC)
);
  1. IR模块用于指令寄存器的加载,将当前指令传递给IRout

verilog

1
2
3
4
5
6
7
IR U_IR (
.clk(clk), // 时钟输入
.rst(!resetn), // 复位输入
.IRin(IRin),
.load(1'b1), // 载入使能
.IRout(IRout)
);

ID (Instruction Decode) 模块:

  1. Regfile模块用于管理寄存器堆的读和写操作,根据指令选择寄存器读取和写入。

verilog

1
2
3
4
5
6
7
8
9
10
Regfile U_regfile (
.clk(clk), // 时钟信号
.raddr1(IRout[25:21]), // 寄存器堆读地址1
.rdata1(reg_a_out), // 返回数据1
.raddr2(IRout[20:16]), // 寄存器堆读地址2
.rdata2(reg_b_out), // 返回数据2
.we(reg_w && IRout), // 写使能
.waddr(reg_addr_choose[4:0]), // 写地址
.wdata(reg_mux_out) // 写数据
);
  1. CU模块用于控制单元,解析指令并生成相应的控制信号,例如ALU操作码、写寄存器使能等。

verilog

1
2
3
4
5
6
7
8
9
10
11
12
CU U_CU (
.Instruct(IRout), // 输入指令
.Zero(zero), // 零标志位
.ram_w(ram_w), // 存储器写使能
.reg_w(reg_w), // 寄存器写使能
.Card(Card), // ALU 功能码
.PC_s(PC_s), // PC 数据来源选择
.regfile_s(regfile_s), // 寄存器文件数据来源选择
.regfile_addr_s(regfile_addr_s), // 寄存器文件地址来源选择
.ALU_As(A_s), // ALU 输入 A 来源选择
.ALU_Bs(B_s) // ALU 输入 B 来源选择
);
  1. AB模块用于选择和加载寄存器A和B的数据。

verilog

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
A U_A (
.clk(clk), // 时钟输入
.rst(!resetn), // 复位输入
.din(reg_a_out), // 数据输入
.load(1'b1), // 载入控制输入
.dout(A_out) // 数据输出
);

B U_B (
.clk(clk), // 时钟输入
.rst(!resetn), // 复位输入
.din(reg_b_out), // 数据输入
.load(1'b1), // 载入控制输入
.dout(B_out) // 数据输出
);
  1. Extender模块用于符号扩展立即数。

verilog

1
2
3
4
Extender U_Extender (
.Immin(IRout[15:0]),
.Immout(Imm)
);
  1. Imm模块用于加载立即数。

verilog

1
2
3
4
5
6
7
Imm U_Imm (
.clk(clk), // 时钟输入
.rst(!resetn), // 复位输入
.din(Imm), // 数据输入
.load(1'b1), // 载入控制输入
.dout(Imm_out) // 数据输出
);

这些Verilog模块构成了IF和ID阶段的核心逻辑,负责指令的获取、寄存器堆的读写、控制信号的生成等任务。

EX (Execution) 模块:

  1. A_MUXB_MUX模块用于选择ALU的输入数据,可以选择寄存器数据、NPC、基址或立即数。

verilog

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
A_MUX A_MUX (
.A_data1(A_out), // A寄存器的输出
.A_data2(NPC), // 根据现在的PC产生的NPC值
.A_data3(A_out), // 代表base的值
.A_data4({27'b0,IRout[10:6]}), // 代表左移的偏置量sa
.A_select(A_s),
.A_data_chosen(ALU_A_in)
);

B_MUX B_MUX (
.B_data1(B_out), // B寄存器的输出
.B_data2(Imm_out), // 立即数扩展符号位之后的输出
.B_data3(32'b0),
.B_data4(32'b0),
.B_select(B_s),
.B_data_chosen(ALU_B_in)
);

ALU U_ALU (
.A(ALU_A_in),
.B(ALU_B_in),
.Cin(1'b0),
.Card(Card),
.F(alu_out),
.Cout(cout),
.Zero(zero)
);

这些模块构成了EX阶段的核心逻辑,负责执行ALU操作、选择ALU输入数据等任务。

MEM (Memory) 模块:

  1. ALU_out模块用于加载ALU的结果。

verilog

1
2
3
4
5
6
7
ALU_out U_ALU_output (
.clk(clk), // 时钟输入
.rst(!resetn), // 复位输入
.din(alu_out), // 数据输入
.load(1'b1), // 载入控制输入
.dout(result) // 数据输出
);
  1. PC_MUX模块用于选择下一个PC地址,可以选择NPC、ALU结果或分支指令的目标地址。

verilog

1
2
3
4
5
6
7
8
PC_MUX PC_MUX (
.data1(NPC),
.data2(result),
.data3({NPC[31:28],IRout[25:0],2'b0}),
.data4(32'b0),
.select(PC_s),
.data_chosen(PC_chosen)
);
  1. WB_Reg_MUX模块用于选择写回数据,可以选择ALU结果、内存读取结果或寄存器A的数据。

verilog

1
2
3
4
5
6
7
8
WB_DATA_MUX WB_Reg_MUX (
.data1(result),
.data2(ldm_out),
.data3(A_out),
.data4(32'b0),
.select(regfile_s),
.data_chosen(reg_mux_out)
);
  1. WB_Reg_Addr_MUX模块用于选择写回寄存器的地址。

verilog

1
2
3
4
5
6
7
8
WB_ADDR_MUX WB_Reg_Addr_MUX (
.data1({27'b0,IRout[15:11]}),
.data2({27'b0,IRout[20:16]}),
.data3(32'b0),
.data4(32'b0),
.select(regfile_addr_s),
.data_chosen(reg_addr_choose)
);
  1. DMEM模块用于数据存储器的读写操作。

verilog

1
2
3
4
5
6
7
DMEM U_DMEM (
.clk(clk), // 时钟信号
.dmem_addr(result[7:0]), // 选定存储地址
.dmem_wdata(reg_b_out), // 输入的数据
.dmem_wen(ram_w), // 写使能
.dmem_rdata(ldm_in) // 读出的数据
);
  1. LDM模块用于加载内存数据。

verilog

1
2
3
4
5
6
7
LDM LDM (
.clk(clk), // 时钟输入
.rst(!resetn), // 复位输入
.din(ldm_in), // 数据输入
.load(1'b1), // 载入控制输入
.dout(ldm_out) // 数据输出
);

这些模块构成了MEM阶段的核心逻辑,负责执行内存操作、选择写回数据和地址等任务。

  • 标题: CA-模块体系
  • 作者: Molaters
  • 创建于 : 2023-11-24 11:30:49
  • 更新于 : 2023-10-12 17:02:26
  • 链接: https://molaters.github.io/2023/11/24/计算机体系结构/CA-模块体系/
  • 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。
 评论
此页目录
CA-模块体系