自己手写RISCV架构CPU-4其它指令

自己手写RISCV架构CPU-4其它指令

实现了RVI指令中除ori指令的其它指令。

4.1、逻辑、移位操作与空指令

4.1.1、基本整数指令RV32I

RISCV指令集架构定义的基本整数指令RV32I有9条:

ADDI、SLTI、SLTIU、ANDI、ORI、XORI、SLLI、SRLI、SRAI

其格式如下

addi rd, rs1, imm[11:0]

指令详解:

addi指令将操作数rs1中的整数与12为立即数(进行符号位扩展)进行家吗操作,结果写回寄存器rd中。

4.1.2、修改defines.v

在I指令定义的后面添加其它I类型指令

`define INST_ADDI   3'b000
`define INST_SLTI   3'b010
`define INST_SLTIU  3'b011
`define INST_XORI   3'b100
`define INST_ORI    3'b110
`define INST_ANDI   3'b111
`define INST_SLLI   3'b001
`define INST_SRI    3'b101
4.1.3 修改译码阶段id模块
case (opcode)
    `INST_TYPE_I: begin
        case (funct3)
            `INST_ADDI, `INST_SLTI, `INST_SLTIU, `INST_XORI, `INST_ORI, `INST_ANDI, `INST_SLLI, `INST_SRI: begin
                reg_we_o = `WriteEnable;
                reg_waddr_o = rd;
                reg1_raddr_o = rs1;
                reg2_raddr_o = `ZeroReg;
                op1_o = reg1_rdata_i;
                op2_o = {{20{inst_i[31]}}, inst_i[31:20]};
            end
            default: begin
                reg_we_o = `WriteDisable;
                reg_waddr_o = `ZeroReg;
                reg1_raddr_o = `ZeroReg;
                reg2_raddr_o = `ZeroReg;
            end
        endcase
    end
    ...
4.1.4 修改执行阶段ex模块
case (opcode)
            `INST_TYPE_I: begin
                case (funct3)
                    `INST_ADDI: begin
                        reg_wdata = op1_add_op2_res;
                    end
                    `INST_SLTI: begin
                        reg_wdata = {32{(~op1_ge_op2_signed)}} & 32'h1;
                    end
                    `INST_SLTIU: begin
                        reg_wdata = {32{(~op1_ge_op2_unsigned)}} & 32'h1;
                    end
                    `INST_XORI: begin
                        reg_wdata = op1_i ^ op2_i;
                    end
                    `INST_ORI: begin
                        reg_wdata = op1_i | op2_i;
                    end
                    `INST_ANDI: begin
                        reg_wdata = op1_i & op2_i;
                    end
                    `INST_SLLI: begin
                        reg_wdata = reg1_rdata_i << inst_i[24:20];
                    end
                    `INST_SRI: begin
                        if (inst_i[30] == 1'b1) begin
                            reg_wdata = (sri_shift & sri_shift_mask) | ({32{reg1_rdata_i[31]}} & (~sri_shift_mask));
                        end else begin
                            reg_wdata = reg1_rdata_i >> inst_i[24:20];
                        end
                    end
                    default: begin
                        reg_wdata = `ZeroWord;
                    end
                endcase
            end
    ...

对于addi指令,添加

wire[31:0] op1_add_op2_res;
assign op1_add_op2_res = op1_i + op2_i;

对于stli指令,添加

wire op1_ge_op2_signed;
assign op1_ge_op2_signed = $signed(op1_i) >= $signed(op2_i);

对于stliu指令,添加

wire op1_ge_op2_unsigned;
assign op1_ge_op2_unsigned = op1_i >= op2_i;

对于rsi指令,添加

wire[31:0] sri_shift;
wire[31:0] sri_shift_mask;
assign sri_shift = reg1_rdata_i >> inst_i[24:20];
assign sri_shift_mask = 32'hffffffff >> inst_i[24:20];

4.2、R类型指令

R类型指令有ADD、SUB、SLT、SLTU、AND、OR、XOR、SLL、SRL、SRA指令

4.2.1、defines.v添加
// R and M type inst
`define INST_TYPE_R 7'b0110011
// R type inst
`define INST_ADD_SUB 3'b000
`define INST_SLL    3'b001
`define INST_SLT    3'b010
`define INST_SLTU   3'b011
`define INST_XOR    3'b100
`define INST_SR     3'b101
`define INST_OR     3'b110
`define INST_AND    3'b111
4.2.2、id模块修改
`INST_TYPE_R: begin
    if ((funct7 == 7'b0000000) || (funct7 == 7'b0100000)) begin
        case (funct3)
            `INST_ADD_SUB, `INST_SLL, `INST_SLT, `INST_SLTU, `INST_XOR, `INST_SR, `INST_OR, `INST_AND: begin
                reg_we_o = `WriteEnable;
                reg_waddr_o = rd;
                reg1_raddr_o = rs1;
                reg2_raddr_o = rs2;
                op1_o = reg1_rdata_i;
                op2_o = reg2_rdata_i;
            end
            default: begin
                reg_we_o = `WriteDisable;
                reg_waddr_o = `ZeroReg;
                reg1_raddr_o = `ZeroReg;
                reg2_raddr_o = `ZeroReg;
            end
        endcase
    end else begin
        reg_we_o = `WriteDisable;
        reg_waddr_o = `ZeroReg;
        reg1_raddr_o = `ZeroReg;
        reg2_raddr_o = `ZeroReg;
    end
end

4.2.3、ex模块修改
`INST_TYPE_R: begin
    if ((funct7 == 7'b0000000) || (funct7 == 7'b0100000)) begin
        case (funct3)
            `INST_ADD_SUB: begin
                if (inst_i[30] == 1'b0) begin
                    reg_wdata = op1_add_op2_res;
                end else begin
                    reg_wdata = op1_i - op2_i;
                end
            end
            `INST_SLL: begin
                reg_wdata = op1_i << op2_i[4:0];
            end
            `INST_SLT: begin
                reg_wdata = {32{(~op1_ge_op2_signed)}} & 32'h1;
            end
            `INST_SLTU: begin
                reg_wdata = {32{(~op1_ge_op2_unsigned)}} & 32'h1;
            end
            `INST_XOR: begin
                reg_wdata = op1_i ^ op2_i;
            end
            `INST_SR: begin
                if (inst_i[30] == 1'b1) begin
                    reg_wdata = (sr_shift & sr_shift_mask) | ({32{reg1_rdata_i[31]}} & (~sr_shift_mask));
                end else begin
                    reg_wdata = reg1_rdata_i >> reg2_rdata_i[4:0];
                end
            end
            `INST_OR: begin
                reg_wdata = op1_i | op2_i;
            end
            `INST_AND: begin
                reg_wdata = op1_i & op2_i;
            end
            default: begin
                reg_wdata = `ZeroWord;
            end
        endcase
    end else begin
        reg_wdata = `ZeroWord;
    end
end

4.3、整数Load/Store指令

LW、LH、LHU、LB、LBU、SW、SH、SB指令

lw rd, offset[11:0] (rs1)

4.3.1、defines.v
// L type inst
`define INST_TYPE_L 7'b0000011
`define INST_LB     3'b000
`define INST_LH     3'b001
`define INST_LW     3'b010
`define INST_LBU    3'b100
`define INST_LHU    3'b101

// S type inst
`define INST_TYPE_S 7'b0100011
`define INST_SB     3'b000
`define INST_SH     3'b001
`define INST_SW     3'b010
4.3.2、id.v
`INST_TYPE_L: begin
    case (funct3)
        `INST_LB, `INST_LH, `INST_LW, `INST_LBU, `INST_LHU: begin
            reg1_raddr_o = rs1;
            reg2_raddr_o = `ZeroReg;
            reg_we_o = `WriteEnable;
            reg_waddr_o = rd;
            op1_o = reg1_rdata_i;
            op2_o = {{20{inst_i[31]}}, inst_i[31:20]};
        end
        default: begin
            reg1_raddr_o = `ZeroReg;
            reg2_raddr_o = `ZeroReg;
            reg_we_o = `WriteDisable;
            reg_waddr_o = `ZeroReg;
        end
    endcase
end
`INST_TYPE_S: begin
    case (funct3)
        `INST_SB, `INST_SW, `INST_SH: begin
            reg1_raddr_o = rs1;
            reg2_raddr_o = rs2;
            reg_we_o = `WriteDisable;
            reg_waddr_o = `ZeroReg;
            op1_o = reg1_rdata_i;
            op2_o = {{20{inst_i[31]}}, inst_i[31:25], inst_i[11:7]};
        end
        default: begin
            reg1_raddr_o = `ZeroReg;
            reg2_raddr_o = `ZeroReg;
            reg_we_o = `WriteDisable;
            reg_waddr_o = `ZeroReg;
        end
    endcase
end
4.3.3、ex.v
assign mem_raddr_index = (reg1_rdata_i + {{20{inst_i[31]}}, inst_i[31:20]}) & 2'b11;
assign mem_waddr_index = (reg1_rdata_i + {{20{inst_i[31]}}, inst_i[31:25], inst_i[11:7]}) & 2'b11; 

`INST_TYPE_L: begin
    case (funct3)
        mem_wdata_o = `ZeroWord;
        mem_waddr_o = `ZeroWord;
        mem_we = `WriteDisable;
        mem_req = `RIB_REQ;
        `INST_LB: begin
            mem_raddr_o = op1_add_op2_res;
            case (mem_raddr_index)
                2'b00: begin
                    reg_wdata = {{24{mem_rdata_i[7]}}, mem_rdata_i[7:0]};
                end
                2'b01: begin
                    reg_wdata = {{24{mem_rdata_i[15]}}, mem_rdata_i[15:8]};
                end
                2'b10: begin
                    reg_wdata = {{24{mem_rdata_i[23]}}, mem_rdata_i[23:16]};
                end
                default: begin
                    reg_wdata = {{24{mem_rdata_i[31]}}, mem_rdata_i[31:24]};
                end
            endcase
        end
        `INST_LH: begin
            mem_raddr_o = op1_add_op2_res;
            if (mem_raddr_index == 2'b0) begin
                reg_wdata = {{16{mem_rdata_i[15]}}, mem_rdata_i[15:0]};
            end else begin
                reg_wdata = {{16{mem_rdata_i[31]}}, mem_rdata_i[31:16]};
            end
        end
        `INST_LW: begin
            mem_raddr_o = op1_add_op2_res;
            reg_wdata = mem_rdata_i;
        end
        `INST_LBU: begin
            mem_raddr_o = op1_add_op2_res;
            case (mem_raddr_index)
                2'b00: begin
                    reg_wdata = {24'h0, mem_rdata_i[7:0]};
                end
                2'b01: begin
                    reg_wdata = {24'h0, mem_rdata_i[15:8]};
                end
                2'b10: begin
                    reg_wdata = {24'h0, mem_rdata_i[23:16]};
                end
                default: begin
                    reg_wdata = {24'h0, mem_rdata_i[31:24]};
                end
            endcase
        end
        `INST_LHU: begin
            mem_raddr_o = op1_add_op2_res;
            if (mem_raddr_index == 2'b0) begin
                reg_wdata = {16'h0, mem_rdata_i[15:0]};
            end else begin
                reg_wdata = {16'h0, mem_rdata_i[31:16]};
            end
        end
        default: begin
            reg_wdata = `ZeroWord;
        end
    endcase
end
`INST_TYPE_S: begin
    case (funct3)
        `INST_SB: begin
            reg_wdata = `ZeroWord;
            mem_we = `WriteEnable;
            mem_req = `RIB_REQ;
            mem_waddr_o = op1_add_op2_res;
            mem_raddr_o = op1_add_op2_res;
            case (mem_waddr_index)
                2'b00: begin
                    mem_wdata_o = {mem_rdata_i[31:8], reg2_rdata_i[7:0]};
                end
                2'b01: begin
                    mem_wdata_o = {mem_rdata_i[31:16], reg2_rdata_i[7:0], mem_rdata_i[7:0]};
                end
                2'b10: begin
                    mem_wdata_o = {mem_rdata_i[31:24], reg2_rdata_i[7:0], mem_rdata_i[15:0]};
                end
                default: begin
                    mem_wdata_o = {reg2_rdata_i[7:0], mem_rdata_i[23:0]};
                end
            endcase
        end
        `INST_SH: begin
            reg_wdata = `ZeroWord;
            mem_we = `WriteEnable;
            mem_req = `RIB_REQ;
            mem_waddr_o = op1_add_op2_res;
            mem_raddr_o = op1_add_op2_res;
            if (mem_waddr_index == 2'b00) begin
                mem_wdata_o = {mem_rdata_i[31:16], reg2_rdata_i[15:0]};
            end else begin
                mem_wdata_o = {reg2_rdata_i[15:0], mem_rdata_i[15:0]};
            end
        end
        `INST_SW: begin
            reg_wdata = `ZeroWord;
            mem_we = `WriteEnable;
            mem_req = `RIB_REQ;
            mem_waddr_o = op1_add_op2_res;
            mem_raddr_o = op1_add_op2_res;
            mem_wdata_o = reg2_rdata_i;
        end
        default: begin
            mem_wdata_o = `ZeroWord;
            mem_raddr_o = `ZeroWord;
            mem_waddr_o = `ZeroWord;
            mem_we = `WriteDisable;
            reg_wdata = `ZeroWord;
        end
    endcase
end
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
当然可以!以下是一个简单的示例,展示了如何手写一个Spring Boot Starter: 首先,创建一个 Maven 项目,并添加以下依赖项: ```xml <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> <version>2.5.4</version> </dependency> </dependencies> ``` 接下来,创建一个自定义的自动配置类,用于配置你的 Starter: ```java @Configuration @EnableConfigurationProperties(MyStarterProperties.class) public class MyStarterAutoConfiguration { private final MyStarterProperties properties; public MyStarterAutoConfiguration(MyStarterProperties properties) { this.properties = properties; } // 在此处定义你的自动配置逻辑 @Bean public MyStarterService myStarterService() { return new MyStarterService(properties); } } ``` 然后,创建一个属性类,用于将外部配置绑定到属性上: ```java @ConfigurationProperties("my.starter") public class MyStarterProperties { private String message; // 提供 getter 和 setter } ``` 最后,创建一个自定义的服务类,该服务类将在你的 Starter 中使用: ```java public class MyStarterService { private final MyStarterProperties properties; public MyStarterService(MyStarterProperties properties) { this.properties = properties; } public void showMessage() { System.out.println(properties.getMessage()); } } ``` 现在,你的 Spring Boot Starter 已经准备就绪了!你可以将其打包并使用在其他 Spring Boot 项目中。在其他项目的 `pom.xml` 文件中,添加你的 Starter 依赖: ```xml <dependencies> <dependency> <groupId>com.example</groupId> <artifactId>my-starter</artifactId> <version>1.0.0</version> </dependency> </dependencies> ``` 然后,在你的应用程序中使用 `MyStarterService`: ```java @SpringBootApplication public class MyApplication implements CommandLineRunner { private final MyStarterService myStarterService; public MyApplication(MyStarterService myStarterService) { this.myStarterService = myStarterService; } public static void main(String[] args) { SpringApplication.run(MyApplication.class, args); } @Override public void run(String... args) throws Exception { myStarterService.showMessage(); } } ``` 这样,你就成功地创建了一个简单的 Spring Boot Starter!当其他项目引入你的 Starter 并运行时,将会输出预定义的消息。 当然,这只是一个简单的示例,真实的 Starter 可能包含更多的配置和功能。你可以根据自己的需求进行扩展和定制。希望对你有所帮助!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

skyer_lhb

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值