单指令周期CPU---在fpga上对外设进行操作

代码放在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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值