代码放在github上
在实现访存指令的基础上,增加了使用Load/Store指令对fpga开发板上的外设(发光二极管、数码管、按键、开关)读写的功能
之前操作的传送门:
单指令周期ori指令的实现
单指令周期CPU—–逻辑、移位操作和空指令
单指令周期CPU——移动操作指令的实现
单指令周期CPU—算术操作指令(1)—简单算术操作指令的实现
单指令周期CPU—转移指令的实现
单指令周期CPU—加载存储指令的实现
使用fpga开发板为EGO1
将外设跟内存统一编址
将32位内存地址的后3位划给外设
即地址为0000_0000~ffff_efff依旧作为普通内存地址,使用Load/Store进行内存的读写
而地址为ffff_f000~ffff_ffff作为外设地址,使用Load/Store指令进行对外设的读写
内存示意图如下:
从图中可以看出来对应的地址分别是
外设 | 地址 |
---|---|
LED(发光二极管) | fffff000 |
SW(按键) | fffff010 |
SEG(数码管) | fffff020 |
BUTTON(按键) | fffff030 |
define.v:
`define LED 32'hFFFF_F000
`define SW 32'hFFFF_F010
`define SEG 32'hFFFF_F020
`define BTN 32'hFFFF_F030
更改系统结构
增加IO控制模块与访存模块相连,增加了MEM访存模块与IO模块的数据和地址线
通过在WB访存模块中对要访问的地址进行判断,决定要对IO或者data_ram模块两者之一进行操作
增加IO模块后的系统结构图:
1. 增加IO模块
IO模块代码:
`include "defines.v"
module io(
input wire clk,
input wire ce,
input wire we,
input wire[`DataAddrBus] addr,
input wire[`DataBus] data_i,
output reg[`DataBus] data_o,
input wire[15:0] sw,
input wire[3:0] btn,
output reg[15:0] led,
output reg[31:0] seg
);
always@(posedge clk)begin
if(ce==`ChipDisable)begin
//data_o <= ZeroWord;
// led<=16'h000F;
end
else if(we == `WriteEnable) begin
if(addr== `LED)begin //led
led<=data_i[15:0];//data_i[15:0];
end
else if(addr == `SEG)begin
seg <= data_i;
end
else
led<=16'h0011;
end
end
always @ (*) begin
if (ce == `ChipDisable) begin
data_o <= `ZeroWord;
end else if(we == `WriteDisable) begin
if(addr== `SW)//sw
data_o <= {16'b0,sw[15:0]};
else if(addr == `BTN)
data_o <= {28'b0,btn[3:0]};
end else begin
data_o <= `ZeroWord;
end
end
endmodule
2. 修改MEM访存模块
增加MEM访存模块对内存地址的判断,如果是00000000~ffffefff则使能data_ram模块,否侧使能IO模块,并进行相应地址和数据的传输工作:
`include "defines.v"
module mem(
input wire rst,
//来自执行阶段的信息
input wire[`RegAddrBus] wd_i,
input wire wreg_i,
input wire[`RegBus] wdata_i,
input wire[`RegBus] hi_i,
input wire[`RegBus] lo_i,
input wire whilo_i,
input wire[`AluOpBus] aluop_i,
input wire[`RegBus] mem_addr_i,
input wire[`RegBus] reg2_i,
//送到回写阶段的信息
output reg[`RegAddrBus] wd_o,
output reg wreg_o,
output reg[`RegBus] wdata_o,
output reg[`RegBus] hi_o,
output reg[`RegBus] lo_o,
output reg whilo_o,
//来自me