mirror of
https://github.com/WangXuan95/USTC-RVSoC.git
synced 2025-01-30 23:02:55 +08:00
219 lines
9.4 KiB
Systemverilog
219 lines
9.4 KiB
Systemverilog
|
|
module core_top(
|
|
input logic clk, rstn,
|
|
input logic [31:0] i_boot_addr,
|
|
naive_bus.master instr_master, data_master
|
|
);
|
|
|
|
// ID stage
|
|
logic [31:0] id_instr, id_pc;
|
|
logic id_src1_reg_en, id_src2_reg_en;
|
|
logic [ 4:0] id_src1_reg_addr, id_src2_reg_addr, id_dst_reg_addr;
|
|
logic id_jal, id_alures2reg, id_memory2reg, id_memwrite;
|
|
logic [ 6:0] id_opcode, id_funct7;
|
|
logic [ 2:0] id_funct3;
|
|
logic [31:0] id_imm;
|
|
|
|
// EX stage
|
|
logic ex_branch_jalr, ex_alures2reg=1'b0, ex_memory2reg=1'b0, ex_memwrite=1'b0;
|
|
logic [6:0] ex_opcode=7'h0, ex_funct7=7'h0;
|
|
logic [2:0] ex_funct3=3'h0;
|
|
logic [4:0] ex_dst_reg_addr=5'h0;
|
|
logic [31:0] ex_alu_res, ex_src1_reg_data, ex_src2_reg_data, ex_pc=0, ex_imm=0, ex_branch_jalr_target;
|
|
|
|
// MEM stage
|
|
logic [2:0] mem_funct3=3'b0;
|
|
logic mem_alures2reg=1'b0, mem_memory2reg=1'b0, mem_memwrite=1'b0;
|
|
logic [31:0] mem_alu_res=0, mem_mem_wdata=0, mem_mem_addr=0;
|
|
logic [4:0] mem_dst_reg_addr=5'h0;
|
|
|
|
// WB stage
|
|
logic wb_memory2reg=1'b0, wb_regwrite=1'b0;
|
|
logic [31:0] wb_alu_res=0, wb_reg_wdata, wb_memout;
|
|
logic [4:0] wb_dst_reg_addr=5'h0;
|
|
|
|
// hazard signal
|
|
logic id_read_disable, id_stall, ex_stall, ex_nop, mem_stall, wb_nop;
|
|
logic loaduse, mem_data_bus_conflict;
|
|
|
|
|
|
// -------------------------------------------------------------------------------
|
|
// hazard - comb logic
|
|
// -------------------------------------------------------------------------------
|
|
assign id_read_disable = loaduse;
|
|
assign id_stall = mem_data_bus_conflict;
|
|
assign ex_stall = mem_data_bus_conflict;
|
|
assign ex_nop = loaduse;
|
|
assign mem_stall = mem_data_bus_conflict;
|
|
assign wb_nop = mem_data_bus_conflict;
|
|
|
|
assign loaduse =
|
|
(id_src1_reg_en & ex_memory2reg & (id_src1_reg_addr== ex_dst_reg_addr) ) |
|
|
(id_src2_reg_en & ex_memory2reg & (id_src2_reg_addr== ex_dst_reg_addr) ) |
|
|
(id_src1_reg_en & mem_memory2reg & (id_src1_reg_addr==mem_dst_reg_addr) ) |
|
|
(id_src2_reg_en & mem_memory2reg & (id_src2_reg_addr==mem_dst_reg_addr) ) ;
|
|
|
|
|
|
// -------------------------------------------------------------------------------
|
|
// Instruction Bus Adapter - timing logic
|
|
// -------------------------------------------------------------------------------
|
|
core_instr_bus_adapter core_instr_bus_i(
|
|
.clk ( clk ),
|
|
.rstn ( rstn ),
|
|
.i_boot_addr ( i_boot_addr ),
|
|
.i_stall ( id_read_disable | id_stall ),
|
|
.i_bus_disable ( id_read_disable ),
|
|
.i_ex_jmp ( ex_branch_jalr ),
|
|
.i_ex_target ( ex_branch_jalr_target ),
|
|
.i_id_jmp ( id_jal ),
|
|
.i_id_target ( id_pc + id_imm ),
|
|
.o_pc ( id_pc ),
|
|
.o_instr ( id_instr ),
|
|
.bus_master ( instr_master )
|
|
);
|
|
|
|
// -------------------------------------------------------------------------------
|
|
// ID stage - comb logic
|
|
// -------------------------------------------------------------------------------
|
|
core_id_stage core_id_stage_i (
|
|
.i_instr ( id_instr ),
|
|
.o_src1_reg_en ( id_src1_reg_en ),
|
|
.o_src2_reg_en ( id_src2_reg_en ),
|
|
.o_jal ( id_jal ),
|
|
.o_alures2reg ( id_alures2reg ),
|
|
.o_memory2reg ( id_memory2reg ),
|
|
.o_mem_write ( id_memwrite ),
|
|
.o_src1_reg_addr ( id_src1_reg_addr ),
|
|
.o_src2_reg_addr ( id_src2_reg_addr ),
|
|
.o_dst_reg_addr ( id_dst_reg_addr ),
|
|
.o_opcode ( id_opcode ),
|
|
.o_funct7 ( id_funct7 ),
|
|
.o_funct3 ( id_funct3 ),
|
|
.o_imm ( id_imm )
|
|
);
|
|
|
|
|
|
// -------------------------------------------------------------------------------
|
|
// ID-EX stage seg reg - timing logic
|
|
// -------------------------------------------------------------------------------
|
|
core_regfile core_regfile_i ( // regfile is a part of ID-EX seg reg
|
|
.clk ( clk ),
|
|
.rstn ( rstn ),
|
|
.rd_latch ( ex_stall ),
|
|
.i_re1 ( id_src1_reg_en ),
|
|
.i_raddr1 ( id_src1_reg_addr ),
|
|
.o_rdata1 ( ex_src1_reg_data ),
|
|
.i_re2 ( id_src2_reg_en ),
|
|
.i_raddr2 ( id_src2_reg_addr ),
|
|
.o_rdata2 ( ex_src2_reg_data ),
|
|
.i_forward1 ( ex_alures2reg ),
|
|
.i_faddr1 ( ex_dst_reg_addr ),
|
|
.i_fdata1 ( ex_alu_res ),
|
|
.i_forward2 ( mem_alures2reg ),
|
|
.i_faddr2 ( mem_dst_reg_addr ),
|
|
.i_fdata2 ( mem_alu_res ),
|
|
.i_we ( wb_regwrite ),
|
|
.i_waddr ( wb_dst_reg_addr ),
|
|
.i_wdata ( wb_reg_wdata )
|
|
);
|
|
always @ (posedge clk or negedge rstn)
|
|
if(~rstn) begin
|
|
ex_alures2reg <= 1'b0;
|
|
ex_memory2reg <= 1'b0;
|
|
ex_memwrite <= 1'b0;
|
|
ex_dst_reg_addr <= 5'h0;
|
|
ex_opcode <= 7'h0;
|
|
ex_funct3 <= 3'h0;
|
|
ex_funct7 <= 7'h0;
|
|
ex_imm <= 0;
|
|
ex_pc <= 0;
|
|
end else if(~ex_stall) begin
|
|
ex_alures2reg <= ex_nop ? 1'b0 : id_alures2reg;
|
|
ex_memory2reg <= ex_nop ? 1'b0 : id_memory2reg;
|
|
ex_memwrite <= ex_nop ? 1'b0 : id_memwrite;
|
|
ex_dst_reg_addr <= ex_nop ? 5'h0 : id_dst_reg_addr;
|
|
ex_opcode <= ex_nop ? 7'h0 : id_opcode;
|
|
ex_funct7 <= ex_nop ? 7'h0 : id_funct7;
|
|
ex_funct3 <= ex_nop ? 3'h0 : id_funct3;
|
|
ex_imm <= ex_nop ? 0 : id_imm;
|
|
ex_pc <= ex_nop ? 0 : id_pc;
|
|
end
|
|
|
|
|
|
// -------------------------------------------------------------------------------
|
|
// EX stage - comb logic
|
|
// -------------------------------------------------------------------------------
|
|
core_alu core_alu_i (
|
|
.i_opcode ( ex_opcode ),
|
|
.i_funct7 ( ex_funct7 ),
|
|
.i_funct3 ( ex_funct3 ),
|
|
.i_num1u ( ex_src1_reg_data ),
|
|
.i_num2u ( ex_src2_reg_data ),
|
|
.i_pc ( ex_pc ),
|
|
.i_immu ( ex_imm ),
|
|
.o_branch_jalr ( ex_branch_jalr ),
|
|
.o_branch_jalr_target ( ex_branch_jalr_target ),
|
|
.o_res ( ex_alu_res )
|
|
);
|
|
|
|
|
|
// -------------------------------------------------------------------------------
|
|
// EX-MEM stage - timing logic
|
|
// -------------------------------------------------------------------------------
|
|
always @ (posedge clk or negedge rstn)
|
|
if(~rstn) begin
|
|
mem_memory2reg <= 1'b0;
|
|
mem_alures2reg <= 1'b0;
|
|
mem_alu_res <= 0;
|
|
mem_dst_reg_addr<= 5'h0;
|
|
mem_memwrite <= 1'b0;
|
|
mem_mem_addr <= 0;
|
|
mem_mem_wdata <= 0;
|
|
mem_funct3 <= 3'b0;
|
|
end else if(~mem_stall) begin
|
|
mem_memory2reg <= ex_memory2reg;
|
|
mem_alures2reg <= ex_alures2reg;
|
|
mem_dst_reg_addr<= ex_dst_reg_addr;
|
|
mem_alu_res <= ex_alu_res;
|
|
mem_memwrite <= ex_memwrite;
|
|
mem_mem_addr <= ex_src1_reg_data + ex_imm;
|
|
mem_mem_wdata <= ex_src2_reg_data;
|
|
mem_funct3 <= ex_funct3;
|
|
end
|
|
|
|
|
|
// -------------------------------------------------------------------------------
|
|
// MEM-WB stage - timing logic
|
|
// -------------------------------------------------------------------------------
|
|
core_bus_wrapper core_bus_wrapper_i (
|
|
.clk ( clk ),
|
|
.rstn ( rstn ),
|
|
.i_re ( mem_memory2reg ),
|
|
.i_we ( mem_memwrite ),
|
|
.o_conflict ( mem_data_bus_conflict ),
|
|
.i_funct3 ( mem_funct3 ),
|
|
.i_addr ( mem_mem_addr ),
|
|
.i_wdata ( mem_mem_wdata ),
|
|
.o_rdata ( wb_memout ),
|
|
.bus_master ( data_master )
|
|
);
|
|
always @ (posedge clk or negedge rstn)
|
|
if(~rstn) begin
|
|
wb_regwrite <= 1'b0;
|
|
wb_memory2reg <= 1'b0;
|
|
wb_dst_reg_addr <= 5'h0;
|
|
wb_alu_res <= 0;
|
|
end else begin
|
|
wb_regwrite <= wb_nop ? 1'b0 : (mem_alures2reg | mem_memory2reg);
|
|
wb_memory2reg <= wb_nop ? 1'b0 : mem_memory2reg;
|
|
wb_dst_reg_addr <= wb_nop ? 5'h0 : mem_dst_reg_addr;
|
|
wb_alu_res <= wb_nop ? 0 : mem_alu_res;
|
|
end
|
|
|
|
// -------------------------------------------------------------------------------
|
|
// WB stage - comb logic
|
|
// -------------------------------------------------------------------------------
|
|
assign wb_reg_wdata = wb_memory2reg ? wb_memout : wb_alu_res;
|
|
|
|
endmodule
|