目前写的代码,是最简单的基本的思路,后期再慢慢添加控制逻辑,逐步完善。
八、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