内部模块设计
处理器内部模块的实现。难度是没有的,工作量是巨大的。话不多说,直接进入模块描述。
Decoder
查表法确定各指令的op,funct3,funct7,使用op和funct3无法判定的指令(add/sub srl/sra srli/srai)再用funct7进行判定。
自己定义一组alu_op,使每一条需要进行计算的指令都有对应的op,并把其送入ALU。
`timescale 1ns / 1ps
module decoder
#(
localparam INS_WIDTH = 32,
localparam JUMP_OP = 7'b1101111,
localparam BRANCH_OP = 7'b1100011,
localparam LOAD_OP = 7'b0000011,
localparam STORE_OP = 7'b0100011,
localparam I_TYPE_OP = 7'b0010011,
localparam R_TYPE_OP = 7'b0110011,
localparam BEQ_FUNCT = 3'b000,
localparam BNE_FUNCT = 3'b001,
localparam BLT_FUNCT = 3'b100,
localparam BGE_FUNCT = 3'b101,
localparam BLTU_FUNCT = 3'b110,
localparam BGEU_FUNCT = 3'b111,
localparam LW_FUNCT = 3'b010,
localparam LH_FUNCT = 3'b001,
localparam LB_FUNCT = 3'b000,
localparam SW_FUNCT = 3'b010,
localparam ADDI_FUNCT = 3'b000,
localparam SLTI_FUNCT = 3'b010,
localparam SLTIU_FUNCT = 3'b011,
localparam XORI_FUNCT = 3'b100,
localparam ORI_FUNCT = 3'b110,
localparam ANDI_FUNCT = 3'b111,
localparam SLLI_FUNCT = 3'b001,
localparam SRLI_FUNCT = 3'b101,
localparam SRAI_FUNCT = 3'b101,
localparam ADD_FUNCT = 3'b000,
localparam SUB_FUNCT = 3'b000,
localparam SLL_FUNCT = 3'b001,
localparam SLT_FUNCT = 3'b010,
localparam SLTU_FUNCT = 3'b011,
localparam XOR_FUNCT = 3'b100,
localparam SRL_FUNCT = 3'b101,
localparam SRA_FUNCT = 3'b101,
localparam OR_FUNCT = 3'b110,
localparam AND_FUNCT = 3'b111,
localparam SUB_SRA_FUNCT = 7'b0100000
)
(
input [31 : 0] ins,
input reg [31 : 0] rs1_data,
input reg [31 : 0] rs2_data,
output reg J,
output reg JR,
output reg Branch,
output reg ram_read,
output reg ram_write,
output reg regs_write,
output reg [1 : 0] op_b_sel,
output reg [1 : 0] load_type,
output reg [5 : 0] alu_op
);
//==========================================================
//== op定义
//==========================================================
wire [6 : 0] op,
funct7;
wire [2 : 0] funct3;
assign op = ins[6 : 0];
assign funct3 = ins[14 : 12];
assign funct7 = ins[31 : 25];
//==========================================================
//== Jump
//==========================================================
assign J = op == JUMP_OP;
assign JR = op == JR_OP;
//==========================================================
//== Branch是否跳转的判断