从零开始设计riscv cpu记录之二

目前写的代码,是最简单的基本的思路,后期再慢慢添加控制逻辑,逐步完善。

八、pc_reg.v代码

c 复制代码
`include "defines.v"

module pc_reg(

    input  wire clk                      ,
    input  wire rst                      ,
    input  wire jump_i                   ,
    input  wire[AW-1:0] jump_addr_i      ,
    input  wire stall_i                  ,
    output reg[AW-1:0] pc_o

    );
    
    always@(posedge clk)begin
        if(rst == `RstEnable )begin
            pc_o <= `RstAddr;
        end
        else if(jump_i == `JumpEnable)begin
            pc_o <= jump_addr_i;
        end
        else if(stall_i == `StallEnable)begin
            pc_o <= pc_o;
        end
        else begin
            pc_o <= pc_o + 32'd4;
        end
        
    end
    
        
endmodule

九、ifetch.v代码

c 复制代码
`include "defines.v"


module ifetch(

    //from pc_reg.v
    input [AW-1:0] pc_i ,
    
    // rom
    output [AW-1:0] rom_raddr_o  ,
    input  [DW-1:0] rom_rdata_i  ,
    
    // to if_id.v
    output [DW-1:0] inst_o       ,
    output [AW-1:0] inst_addr_o

    );
    
    assign rom_raddr_o = pc_i;
    assign inst_o  = rom_rdata_i ;
    assign inst_addr_o = pc_i ;
    
endmodule

十、if_id.v代码

c 复制代码
`include "defines.v"
module if_id(
    input wire clk    ,
    input wire rst    ,
    
    input wire  hold_i    ,
    input wire  flush_i   ,
    input wire [DW-1:0] inst_i       ,
    input wire [AW-1:0] inst_addr_i  ,
    
    output reg [DW-1:0] inst_o        ,
    output reg [AW-1:0] inst_addr_o

    );
    always@(posedge clk)begin
        if(rst == `RstEnable)begin
            inst_o      <= `INST_NOP;
            inst_addr_o <= `ZeroWord;
        end
        else if(flush_i == `FlushEnable)begin
            inst_o      <= `INST_NOP;
            inst_addr_o <= `ZeroWord;
        end
        else if(hold_i == `HoldEnable )begin
            inst_o      <= inst_o     ;
            inst_addr_o <= inst_addr_o;
        end
        else begin
            inst_o     <= inst_i      ;
            inst_addr_o<= inst_addr_i ;
        end
    end
endmodule

十一、id.v代码

c 复制代码
`timescale 1ns / 1ps
`include "defines.v"
module id(

    // from if_id.v
    input wire [DW-1:0]inst_i       ,
    input wire [AW-1:0]inst_addr_i  ,
    
    //regs.v
    output reg  [4:0] reg1_raddr_o   , 
    output reg  [4:0] reg2_raddr_o   ,
    input  wire [DW-1:0]reg1_rdata_i ,
    input  wire [DW-1:0]reg2_rdata_i ,
    
    
    //to id_ex.v
    output reg reg_we_o,
    output reg [4:0]    reg_waddr_o,
    output reg [DW-1:0] inst_o       ,
    output reg [AW-1:0] inst_addr_O  ,
    output reg [DW-1:0]  op1_o       ,
    output reg [DW-1:0]  op2_o       ,
    output reg [DW-1:0] op1_jump_o   ,
    output reg [DW-1:0] op2_jump_o
    
    

    );
    // inst slice
    wire [6:0] opcode = inst_i[6:0];
    wire [4:0] rd = inst_i[11:7];
    wire [2:0] func3 = inst_i[14:12];
    wire [4:0] rs1 = inst_i[19:15];
    wire [4:0] rs2 = inst_i[24:20];
    wire [6:0] func7 = inst_i[31:25];
    
    
    always@(*)begin
        reg_we_o       = `WriteDisable;
        reg_waddr_o    =  `ZeroReg;
        inst_o         = inst_i ;
        inst_addr_O    = inst_addr_i ;
        op1_o          = `ZeroWord ;
        op2_o          = `ZeroWord ;
        op1_jump_o     = `ZeroWord ;
        op2_jump_o     = `ZeroWord ;
        reg1_raddr_o   = `ZeroReg ;
        reg2_raddr_o   = `ZeroReg ;
        
        case(opcode)
            `INST_TYPE_LUI    : begin
                reg_we_o       = `WriteEnable;
                reg_waddr_o    = rd;
                op1_o          = {inst_i[31:12],12'h0};
                op2_o          = `ZeroWord ;
             end
            `INST_TYPE_AUIPC  : begin
                reg_we_o       = `WriteEnable;
                reg_waddr_o    = rd;
                op1_o          = inst_addr_i ;
                op2_o          = {inst_i[31:12],12'h0};
                               
             end
            `INST_TYPE_JAL    : begin
                reg_we_o       = `WriteEnable; 
                reg_waddr_o    = rd;           
                op1_o          = inst_addr_i ;  
                op2_o          = 32'h4;
                op1_jump_o     = inst_addr_i ;
                op2_jump_o     = {{12{inst_i[31]}}, inst_i[19:12], inst_i[20], inst_i[30:21], 1'b0};
                                
             end
            `INST_TYPE_JALR   : begin
                reg_we_o      = `WriteEnable;
                reg_waddr_o   = rd;
                reg1_raddr_o  = rs1;           
                op1_o          =inst_addr_i ;  
                op2_o          =32'h4;         
                op1_jump_o     =reg1_rdata_i;
                op2_jump_o     ={{20{inst_i[31]}}, inst_i[31:20]};
             end
            `INST_TYPE_B      : begin
                case(func3)                       
                    `INST_BEQ,`INST_BNE,`INST_BLT,`INST_BGE,`INST_BLTU,`INST_BGEU: begin
                        reg1_raddr_o = rs1    ;
                        reg2_raddr_o = rs2    ;
                        op1_o = reg1_rdata_i;
                        op2_o = reg2_rdata_i;
                        op1_jump_o   = inst_addr_i;
                        op2_jump_o   = {{20{inst_i[31]}}, inst_i[7], inst_i[30:25], inst_i[11:8], 1'b0};
                     end 
                    default:begin end
                endcase
             end
            `INST_TYPE_LOAD: begin
                case(func3)
                    `INST_LB ,`INST_LH ,`INST_LW ,`INST_LBU ,`INST_LHU: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
                    end                  
                endcase
           
             end
            `INST_TYPE_STORE  : begin
                case(func3)
                    `INST_SB,`INST_SH,`INST_SW:begin
                        reg1_raddr_o   = rs1; 
                        reg2_raddr_o   = rs2; 
                        op1_o          = reg1_rdata_i;
                        op2_o          = {{20{inst_i[31]}}, inst_i[31:25], inst_i[11:7]};
                    end
                    default:begin
                    end
                    
                endcase
             end
            `INST_TYPE_I      : begin
                case(func3)
                    `INST_ADDI ,`INST_SLTI ,`INST_SLTIU,`INST_XORI , `INST_ORI,`INST_ANDI ,`INST_SLLI,  `INST_SRI:begin
                        reg1_raddr_o   = rs1;
                        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
                    end
                                       
                endcase
             end
            `INST_TYPE_R_M    : begin
                if(func7 ==`func7_R  || func7 == `func7_sub_sra )begin
                    case(func3)
                    `INST_ADD_SUB ,`INST_SLL ,`INST_SLT ,`INST_SLTU ,`INST_XOR ,`INST_SR ,`INST_OR ,`INST_AND :begin
                           reg1_raddr_o   = rs1;    
                           reg2_raddr_o   = rs2;    
                           reg_we_o       = `WriteEnable;  
                           reg_waddr_o    = rd;    
                           op1_o          = reg1_rdata_i; 
                           op2_o          = reg2_rdata_i;         
                       
                    end
                    default:begin    
                    end
                       
                    endcase
                end
                else if(func7 == `func7_M)begin
                    case(func3)
                    `INST_MUL  ,`INST_MULH    ,`INST_MULHSU  ,`INST_MULHU :begin
                           reg1_raddr_o   = rs1;           
                           reg2_raddr_o   = rs2;           
                           reg_we_o       = `WriteEnable;  
                           reg_waddr_o    = rd;            
                           op1_o          = reg1_rdata_i;  
                           op2_o          = reg2_rdata_i;  

  
                    end
                    `INST_DIV ,`INST_DIVU,`INST_REM ,`INST_REMU:begin
                           reg1_raddr_o   = rs1;  
                           reg2_raddr_o   = rs2;  
                           op1_o          = reg1_rdata_i; 
                           op2_o          = reg2_rdata_i; 
                           reg_waddr_o    = rd; 
                           op1_jump_o   = inst_addr_i;
                           op2_jump_o   = 32'h4;
                            
                    end
                    default:begin
                    end  
                    endcase
                end
                else begin
                end
                
             end
            `INST_TYPE_FENCE  : begin
                op1_jump_o = inst_addr_i;
                op2_jump_o = 32'h4;
             end
             default:begin end
        endcase
     
    end
        
endmodule

十二、id_ex.v代码

c 复制代码
`include "defines.v"
module id_ex(
    input  wire clk       ,
    input  wire rst       ,
    input  wire flush_i   ,
    input  wire stall_i   ,
    input  wire [DW-1:0]inst_i       ,
    input  wire [AW-1:0]inst_addr_i  ,
    input  wire reg_we_i             ,
    input  wire [4:0]reg_waddr_i     ,
    input  wire [DW-1:0] op1_i       ,
    input  wire [DW-1:0] op2_i       ,
    input  wire [DW-1:0] op1_jump_i  ,
    input  wire [DW-1:0] op2_jump_i  ,
    output reg  [DW-1:0] inst_o     ,
    output reg  [AW-1:0] inst_addr_o  ,
    output reg           reg_we_o             ,
    output reg  [4:0]    reg_waddr_o    ,
    output reg  [DW-1:0] op1_o       ,
    output reg  [DW-1:0] op2_o       ,
    output reg  [DW-1:0] op1_jump_o  ,
    output reg  [DW-1:0] op2_jump_o
    

    );
    always@(posedge clk)begin
        if(rst || flush_i)begin
            inst_o        <= `INST_NOP;
            inst_addr_o   <=  `ZeroWord;
            reg_we_o      <= `WriteDisable;
            reg_waddr_o   <= `ZeroReg;
            op1_o         <=  `ZeroWord;
            op2_o         <= `ZeroWord;
            op1_jump_o    <= `ZeroWord;
            op2_jump_o    <= `ZeroWord;
                   
        end
        else if(stall_i == `StallEnable) begin
            inst_o        <=  inst_o      ;
            inst_addr_o   <=  inst_addr_o ;
            reg_we_o      <=  reg_we_o    ;
            reg_waddr_o   <=  reg_waddr_o ;
            op1_o         <=  op1_o       ;
            op2_o         <=  op2_o       ;
            op1_jump_o    <=  op1_jump_o  ;
            op2_jump_o    <=  op2_jump_o  ;
                             
        end
        else begin
            inst_o        <= inst_i        ;
            inst_addr_o   <= inst_addr_i   ;
            reg_we_o      <= reg_we_i      ;
            reg_waddr_o   <= reg_waddr_i   ;
            op1_o         <= op1_i         ;
            op2_o         <= op2_i         ;
            op1_jump_o    <= op1_jump_i    ;
            op2_jump_o    <= op2_jump_i    ;
        end
    end
endmodule
相关推荐
-To be number.wan8 小时前
数据库系统 | 数据库安全与完整性
数据库·学习
czysoft8 小时前
se被限速
科技·学习·it·技术·魔法·先进·领先
techdashen8 小时前
从网络栈继续往下:micro:bit、2.4GHz、调制方式,以及一个不太靠谱但很有趣的想法
网络·fpga开发
FPGA小徐9 小时前
FIR 数字滤波器 --verilog设计实现
fpga开发
zlinear数据采集卡9 小时前
从协议解析到波形实时显示:硬核拆解ZLinear采集卡上位机软件的开发架构
arm开发·单片机·嵌入式硬件·fpga开发·架构·开源
子不语1809 小时前
从0开始学习S7-1200+ET200SP(3)——两台S7-1200通过TCP连接
网络协议·学习·tcp/ip
pcjiushizhu9 小时前
ModelSim 仿真时 Simulate 无反应或只显示 Loading 的解决方法:网卡问题排查
fpga开发
llllliznc9 小时前
LLM 学习笔记 Day 5:Agent 核心组件——Planner、Memory 与 Reflection
笔记·学习
hyhsandy180310 小时前
STM32F103 TIM学习笔记
笔记·stm32·学习
GuHenryCheng10 小时前
【ESP32】ESP-IDF开发环境搭建(cursor)
git·stm32·单片机·学习