Still need to fix

This commit is contained in:
2024-12-30 00:36:45 +08:00
parent 582917df99
commit e8e6b6ddb3
16 changed files with 1317 additions and 921 deletions

View File

@ -1,4 +1,15 @@
// Generated by CIRCT firtool-1.62.0 // Generated by CIRCT firtool-1.62.0
// Standard header to adapt well known macros for prints and assertions.
// Users can define 'PRINTF_COND' to add an extra gate to prints.
`ifndef PRINTF_COND_
`ifdef PRINTF_COND
`define PRINTF_COND_ (`PRINTF_COND)
`else // PRINTF_COND
`define PRINTF_COND_ 1
`endif // PRINTF_COND
`endif // not def PRINTF_COND_
// VCS coverage exclude_file // VCS coverage exclude_file
module regfile_32x32( module regfile_32x32(
input [4:0] R0_addr, input [4:0] R0_addr,
@ -9,6 +20,10 @@ module regfile_32x32(
input R1_en, input R1_en,
R1_clk, R1_clk,
output [31:0] R1_data, output [31:0] R1_data,
input [4:0] R2_addr,
input R2_en,
R2_clk,
output [31:0] R2_data,
input [4:0] W0_addr, input [4:0] W0_addr,
input W0_en, input W0_en,
W0_clk, W0_clk,
@ -16,24 +31,13 @@ module regfile_32x32(
); );
reg [31:0] Memory[0:31]; reg [31:0] Memory[0:31];
reg _R0_en_d0;
reg [4:0] _R0_addr_d0;
always @(posedge R0_clk) begin
_R0_en_d0 <= R0_en;
_R0_addr_d0 <= R0_addr;
end // always @(posedge)
reg _R1_en_d0;
reg [4:0] _R1_addr_d0;
always @(posedge R1_clk) begin
_R1_en_d0 <= R1_en;
_R1_addr_d0 <= R1_addr;
end // always @(posedge)
always @(posedge W0_clk) begin always @(posedge W0_clk) begin
if (W0_en & 1'h1) if (W0_en & 1'h1)
Memory[W0_addr] <= W0_data; Memory[W0_addr] <= W0_data;
end // always @(posedge) end // always @(posedge)
assign R0_data = _R0_en_d0 ? Memory[_R0_addr_d0] : 32'bx; assign R0_data = R0_en ? Memory[R0_addr] : 32'bx;
assign R1_data = _R1_en_d0 ? Memory[_R1_addr_d0] : 32'bx; assign R1_data = R1_en ? Memory[R1_addr] : 32'bx;
assign R2_data = R2_en ? Memory[R2_addr] : 32'bx;
endmodule endmodule
module Core( module Core(
@ -45,277 +49,279 @@ module Core(
input [31:0] io_dmem_rdata, input [31:0] io_dmem_rdata,
output io_dmem_wen, output io_dmem_wen,
output [31:0] io_dmem_wdata, output [31:0] io_dmem_wdata,
output io_exit output io_exit,
output [31:0] io_gp
); );
wire [31:0] _regfile_ext_R0_data; wire [31:0] mem_wb_data;
wire [31:0] _regfile_ext_R1_data; wire exe_jmp_flg;
reg [31:0] id_reg_pc; wire exe_br_flg;
reg [31:0] id_reg_inst; wire [31:0] _regfile_ext_R1_data;
reg [31:0] exe_reg_pc; wire [31:0] _regfile_ext_R2_data;
reg [4:0] exe_reg_wb_addr; reg [31:0] id_reg_pc;
reg [31:0] exe_reg_op1_data; reg [31:0] id_reg_inst;
reg [31:0] exe_reg_op2_data; reg [31:0] exe_reg_pc;
reg [31:0] exe_reg_rs2_data; reg [4:0] exe_reg_wb_addr;
reg [4:0] exe_reg_exe_fun; reg [31:0] exe_reg_op1_data;
reg [1:0] exe_reg_mem_wen; reg [31:0] exe_reg_op2_data;
reg [1:0] exe_reg_rf_wen; reg [31:0] exe_reg_rs2_data;
reg [2:0] exe_reg_wb_sel; reg [4:0] exe_reg_exe_fun;
reg [31:0] exe_reg_imm_b_sext; reg [1:0] exe_reg_mem_wen;
reg [31:0] mem_reg_pc; reg [1:0] exe_reg_rf_wen;
reg [4:0] mem_reg_wb_addr; reg [2:0] exe_reg_wb_sel;
reg [31:0] mem_reg_alu_out; reg [31:0] exe_reg_imm_b_sext;
reg [31:0] mem_reg_rs2_data; reg [31:0] mem_reg_pc;
reg [1:0] mem_reg_rf_wen; reg [4:0] mem_reg_wb_addr;
reg [2:0] mem_reg_wb_sel; reg [31:0] mem_reg_rs2_data;
reg [1:0] mem_reg_mem_wen; reg [1:0] mem_reg_mem_wen;
reg [4:0] wb_reg_wb_addr; reg [1:0] mem_reg_rf_wen;
reg [1:0] wb_reg_rf_wen; reg [2:0] mem_reg_wb_sel;
reg [31:0] wb_reg_wb_data; reg [31:0] mem_reg_alu_out;
reg [31:0] if_reg_pc; reg [4:0] wb_reg_wb_addr;
wire _id_rs2_data_T_5 = wb_reg_rf_wen == 2'h1; reg [1:0] wb_reg_rf_wen;
wire exe_br_flg = reg [31:0] wb_reg_wb_data;
exe_reg_exe_fun == 5'hC reg [31:0] if_reg_pc;
? exe_reg_op1_data != exe_reg_op2_data wire _id_inst_T = exe_br_flg | exe_jmp_flg;
: exe_reg_exe_fun == 5'hB & exe_reg_op1_data == exe_reg_op2_data; wire _id_rs2_data_hazard_T = exe_reg_rf_wen == 2'h1;
wire exe_jmp_flg = exe_reg_wb_sel == 3'h3; wire stall_flg =
_id_rs2_data_hazard_T & (|(id_reg_inst[25:21]))
& id_reg_inst[25:21] == exe_reg_wb_addr | _id_rs2_data_hazard_T
& (|(id_reg_inst[20:16])) & id_reg_inst[20:16] == exe_reg_wb_addr;
wire [31:0] id_inst = _id_inst_T | stall_flg ? 32'h0 : id_reg_inst;
wire _id_rs2_data_T_2 = mem_reg_rf_wen == 2'h1;
wire _id_rs2_data_T_5 = wb_reg_rf_wen == 2'h1;
wire [31:0] id_rs1_data =
id_inst[25:21] == 5'h0
? 32'h0
: id_inst[25:21] == mem_reg_wb_addr & _id_rs2_data_T_2
? mem_wb_data
: id_inst[25:21] == wb_reg_wb_addr & _id_rs2_data_T_5
? wb_reg_wb_data
: _regfile_ext_R2_data;
wire [31:0] id_rs2_data =
id_inst[20:16] == 5'h0
? 32'h0
: id_inst[20:16] == mem_reg_wb_addr & _id_rs2_data_T_2
? mem_wb_data
: id_inst[20:16] == wb_reg_wb_addr & _id_rs2_data_T_5
? wb_reg_wb_data
: _regfile_ext_R1_data;
wire [16:0] _GEN = {id_inst[31:26], id_inst[10:0]};
wire _csignals_T_5 = _GEN == 17'h20;
wire [19:0] _GEN_0 = {id_inst[31:28], id_inst[15:0]};
wire _csignals_T_7 = _GEN_0 == 20'h80000;
wire _csignals_T_9 = _GEN == 17'h22;
wire _csignals_T_11 = _GEN == 17'h24;
wire _csignals_T_13 = _GEN == 17'h25;
wire _csignals_T_15 = _GEN == 17'h26;
wire _csignals_T_17 = _GEN_0 == 20'hC0000;
wire _csignals_T_19 = _GEN_0 == 20'hD0000;
wire _csignals_T_21 = _GEN == 17'h2A;
wire _csignals_T_23 = _GEN_0 == 20'h40000;
wire _csignals_T_25 = _GEN_0 == 20'h50000;
wire _csignals_T_27 = id_inst == 32'hC000000;
wire _csignals_T_29 = {id_inst[31:22], id_inst[9:0]} == 20'h78000;
wire _GEN_1 = _csignals_T_23 | _csignals_T_25;
wire _GEN_2 = _csignals_T_21 | _GEN_1;
wire [2:0] _csignals_T_70 =
_csignals_T_5
? 3'h1
: _csignals_T_7
? 3'h2
: _csignals_T_9 | _csignals_T_11 | _csignals_T_13 | _csignals_T_15
? 3'h1
: _csignals_T_17 | _csignals_T_19
? 3'h2
: _GEN_2 ? 3'h1 : _csignals_T_27 ? 3'h4 : {_csignals_T_29, 2'h1};
wire [3:0][31:0] _GEN_3 =
{{{27'h0, id_inst[15:11]}}, {32'h0}, {id_reg_pc}, {id_rs1_data}};
wire [31:0] id_op1_data =
_GEN_3[_csignals_T_5 | _csignals_T_7 | _csignals_T_9 | _csignals_T_11 | _csignals_T_13
| _csignals_T_15 | _csignals_T_17 | _csignals_T_19 | _GEN_2
? 2'h0
: _csignals_T_27 ? 2'h1 : {_csignals_T_29, 1'h0}];
wire [33:0] id_op2_data =
_csignals_T_70 == 3'h1
? {2'h0, id_rs2_data}
: _csignals_T_70 == 3'h2
? {2'h0, {16{id_inst[15]}}, id_inst[15:0]}
: _csignals_T_70 == 3'h3
? {2'h0, {22{id_inst[15]}}, id_inst[15:11], id_inst[25:21]}
: _csignals_T_70 == 3'h4
? {{6{id_inst[23]}}, id_inst[25:0], 2'h0}
: {2'h0, _csignals_T_70 == 3'h5 ? {id_inst[15:0], 16'h0} : 32'h0};
wire [31:0] _exe_alu_out_T_30 = exe_reg_op1_data + exe_reg_op2_data;
wire [62:0] _exe_alu_out_T_14 = {31'h0, exe_reg_op1_data} << exe_reg_op2_data[4:0];
wire [31:0] _GEN_4 = {27'h0, exe_reg_op2_data[4:0]};
wire [31:0] _exe_alu_out_T_46 =
exe_reg_exe_fun == 5'h1
? _exe_alu_out_T_30
: exe_reg_exe_fun == 5'h2
? exe_reg_op1_data - exe_reg_op2_data
: exe_reg_exe_fun == 5'h3
? exe_reg_op1_data & exe_reg_op2_data
: exe_reg_exe_fun == 5'h4
? exe_reg_op1_data | exe_reg_op2_data
: exe_reg_exe_fun == 5'h5
? exe_reg_op1_data ^ exe_reg_op2_data
: exe_reg_exe_fun == 5'h6
? _exe_alu_out_T_14[31:0]
: exe_reg_exe_fun == 5'h7
? exe_reg_op1_data >> _GEN_4
: exe_reg_exe_fun == 5'h8
? $signed($signed(exe_reg_op1_data) >>> _GEN_4)
: exe_reg_exe_fun == 5'h9
? {31'h0,
$signed(exe_reg_op1_data) < $signed(exe_reg_op2_data)}
: exe_reg_exe_fun == 5'hA
? {31'h0, exe_reg_op1_data < exe_reg_op2_data}
: exe_reg_exe_fun == 5'h11
? _exe_alu_out_T_30 & 32'hFFFFFFFE
: exe_reg_exe_fun == 5'h12
? exe_reg_op1_data
: 32'h0;
wire _exe_br_flg_T_3 = exe_reg_op1_data == exe_reg_op2_data;
assign exe_br_flg =
exe_reg_exe_fun == 5'hB
? _exe_br_flg_T_3
: exe_reg_exe_fun == 5'hC & ~_exe_br_flg_T_3;
assign exe_jmp_flg = exe_reg_wb_sel == 3'h3;
assign mem_wb_data =
mem_reg_wb_sel == 3'h2
? io_dmem_rdata
: mem_reg_wb_sel == 3'h3 ? mem_reg_pc + 32'h4 : mem_reg_alu_out;
`ifndef SYNTHESIS
always @(posedge clock) begin
if ((`PRINTF_COND_) & ~reset) begin
$fwrite(32'h80000002, "---------------------\n");
$fwrite(32'h80000002, "if_reg_pc: 0x%x\n", if_reg_pc);
$fwrite(32'h80000002, "id_reg_pc: 0x%x\n", id_reg_pc);
$fwrite(32'h80000002, "id_reg_inst: 0x%x\n", id_reg_inst);
$fwrite(32'h80000002, "id_inst: 0x%x\n", id_inst);
$fwrite(32'h80000002, "id_rs1_data: 0x%x\n", id_rs1_data);
$fwrite(32'h80000002, "id_rs2_data: 0x%x\n", id_rs2_data);
$fwrite(32'h80000002, "exe_reg_pc: 0x%x\n", exe_reg_pc);
$fwrite(32'h80000002, "exe_reg_op1_data: 0x%x\n", id_op1_data);
$fwrite(32'h80000002, "exe_reg_op2_data: 0x%x\n", id_op2_data);
$fwrite(32'h80000002, "exe_alu_out: 0x%x\n", _exe_alu_out_T_46);
$fwrite(32'h80000002, "mem_reg_pc: 0x%x\n", mem_reg_pc);
$fwrite(32'h80000002, "mem_wb_data: 0x%x\n", mem_wb_data);
$fwrite(32'h80000002, "wb_reg_wb_data: 0%x\n", wb_reg_wb_data);
$fwrite(32'h80000002, "---------------------\n");
end
end // always @(posedge)
`endif // not def SYNTHESIS
always @(posedge clock) begin always @(posedge clock) begin
automatic logic _id_inst_T = exe_br_flg | exe_jmp_flg; if (reset) begin
automatic logic _id_rs2_data_hazard_T = exe_reg_rf_wen == 2'h1; id_reg_pc <= 32'h0;
automatic logic stall_flg;
automatic logic [31:0] id_inst;
automatic logic _id_rs2_data_T_2;
automatic logic _id_rs2_data_T;
automatic logic [31:0] _id_rs2_data_T_8;
automatic logic [16:0] _GEN;
automatic logic _csignals_T_5;
automatic logic [19:0] _GEN_0;
automatic logic _csignals_T_7;
automatic logic _csignals_T_9;
automatic logic _csignals_T_11;
automatic logic _csignals_T_13;
automatic logic _csignals_T_15;
automatic logic _csignals_T_17;
automatic logic _csignals_T_19;
automatic logic [16:0] _GEN_1;
automatic logic _csignals_T_21;
automatic logic _csignals_T_23;
automatic logic _csignals_T_25;
automatic logic _csignals_T_27;
automatic logic _csignals_T_29;
automatic logic _csignals_T_31;
automatic logic _csignals_T_33;
automatic logic _csignals_T_35;
automatic logic _csignals_T_37;
automatic logic _csignals_T_39;
automatic logic _GEN_2;
automatic logic _GEN_3;
automatic logic [1:0] csignals_1;
automatic logic [2:0] _csignals_T_95;
automatic logic [31:0] _GEN_4 = {27'h0, exe_reg_op2_data[4:0]};
automatic logic [62:0] _exe_alu_out_T_8 =
{31'h0, exe_reg_op1_data} << exe_reg_op2_data[4:0];
automatic logic [31:0] exe_alu_out;
stall_flg =
_id_rs2_data_hazard_T & (|(id_reg_inst[25:21]))
& id_reg_inst[25:21] == exe_reg_wb_addr | _id_rs2_data_hazard_T
& (|(id_reg_inst[20:16])) & id_reg_inst[20:16] == exe_reg_wb_addr;
id_inst = _id_inst_T | stall_flg ? 32'h0 : id_reg_inst;
_id_rs2_data_T_2 = mem_reg_rf_wen == 2'h1;
_id_rs2_data_T = id_reg_inst[20:16] == 5'h0;
_id_rs2_data_T_8 =
id_reg_inst[20:16] == mem_reg_wb_addr & _id_rs2_data_T_2
? mem_reg_alu_out
: id_reg_inst[20:16] == wb_reg_wb_addr & _id_rs2_data_T_5
? wb_reg_wb_data
: _regfile_ext_R0_data;
_GEN = {id_inst[31:26], id_inst[10:0]};
_csignals_T_5 = _GEN == 17'h20;
_GEN_0 = {id_inst[31:28], id_inst[15:0]};
_csignals_T_7 = _GEN_0 == 20'h80000;
_csignals_T_9 = _GEN == 17'h22;
_csignals_T_11 = _GEN == 17'h24;
_csignals_T_13 = _GEN == 17'h25;
_csignals_T_15 = _GEN == 17'h26;
_csignals_T_17 = _GEN_0 == 20'hC0000;
_csignals_T_19 = _GEN_0 == 20'hD0000;
_GEN_1 = {id_inst[30:20], id_inst[5:0]};
_csignals_T_21 = _GEN_1 == 17'h0;
_csignals_T_23 = _GEN_1 == 17'h2;
_csignals_T_25 = _GEN_1 == 17'h3;
_csignals_T_27 = _GEN == 17'h2A;
_csignals_T_29 = _GEN_0 == 20'h40000;
_csignals_T_31 = _GEN_0 == 20'h50000;
_csignals_T_33 = id_inst == 32'hC000000;
_csignals_T_35 = _GEN_0 == 20'h8;
_csignals_T_37 = {id_inst[31:22], id_inst[9:0]} == 20'h78000;
_csignals_T_39 = id_inst == 32'h0;
_GEN_2 = _csignals_T_29 | _csignals_T_31;
_GEN_3 = _csignals_T_21 | _csignals_T_23 | _csignals_T_25 | _csignals_T_27 | _GEN_2;
csignals_1 =
_csignals_T_5 | _csignals_T_7 | _csignals_T_9 | _csignals_T_11 | _csignals_T_13
| _csignals_T_15 | _csignals_T_17 | _csignals_T_19 | _GEN_3
? 2'h0
: _csignals_T_33
? 2'h1
: _csignals_T_35 ? 2'h0 : {_csignals_T_37 | _csignals_T_39, 1'h0};
_csignals_T_95 =
_csignals_T_5
? 3'h1
: _csignals_T_7
? 3'h2
: _csignals_T_9 | _csignals_T_11 | _csignals_T_13 | _csignals_T_15
? 3'h1
: _csignals_T_17 | _csignals_T_19
? 3'h2
: _GEN_3
? 3'h1
: _csignals_T_33
? 3'h4
: _csignals_T_35
? 3'h0
: _csignals_T_37 ? 3'h5 : {2'h0, ~_csignals_T_39};
exe_alu_out =
exe_reg_exe_fun == 5'hE
? exe_reg_op1_data
: exe_reg_exe_fun == 5'h9
? {31'h0, $signed(exe_reg_op1_data) < $signed(exe_reg_op2_data)}
: exe_reg_exe_fun == 5'h8
? $signed($signed(exe_reg_op1_data) >>> _GEN_4)
: exe_reg_exe_fun == 5'h7
? exe_reg_op1_data >> _GEN_4
: exe_reg_exe_fun == 5'h6
? _exe_alu_out_T_8[31:0]
: exe_reg_exe_fun == 5'h5
? exe_reg_op1_data ^ exe_reg_op2_data
: exe_reg_exe_fun == 5'h4
? exe_reg_op1_data | exe_reg_op2_data
: exe_reg_exe_fun == 5'h3
? exe_reg_op1_data & exe_reg_op2_data
: exe_reg_exe_fun == 5'h2
? exe_reg_op1_data - exe_reg_op2_data
: exe_reg_exe_fun == 5'h1
? exe_reg_op1_data + exe_reg_op2_data
: 32'h0;
if (~stall_flg)
id_reg_pc <= if_reg_pc;
if (_id_inst_T)
id_reg_inst <= 32'h0; id_reg_inst <= 32'h0;
else if (~stall_flg) exe_reg_pc <= 32'h0;
id_reg_inst <= io_imem_inst; exe_reg_wb_addr <= 5'h0;
exe_reg_pc <= id_reg_pc;
exe_reg_wb_addr <= id_reg_inst[15:11];
if (csignals_1 == 2'h0)
exe_reg_op1_data <=
id_reg_inst[25:21] == 5'h0
? 32'h0
: id_reg_inst[25:21] == mem_reg_wb_addr & _id_rs2_data_T_2
? mem_reg_alu_out
: id_reg_inst[25:21] == wb_reg_wb_addr & _id_rs2_data_T_5
? wb_reg_wb_data
: _regfile_ext_R1_data;
else if (csignals_1 == 2'h1)
exe_reg_op1_data <= id_reg_pc;
else
exe_reg_op1_data <= 32'h0; exe_reg_op1_data <= 32'h0;
if (_csignals_T_95 == 3'h5)
exe_reg_op2_data <= {id_inst[15:0], 16'h0};
else if (_csignals_T_95 == 3'h4)
exe_reg_op2_data <= {{4{id_inst[25]}}, id_inst[25:0], 2'h0};
else if (_csignals_T_95 == 3'h3 | _csignals_T_95 == 3'h2)
exe_reg_op2_data <= {{16{id_inst[15]}}, id_inst[15:0]};
else if (_csignals_T_95 != 3'h1 | _id_rs2_data_T)
exe_reg_op2_data <= 32'h0; exe_reg_op2_data <= 32'h0;
else exe_reg_rs2_data <= 32'h0;
exe_reg_op2_data <= _id_rs2_data_T_8; exe_reg_exe_fun <= 5'h0;
exe_reg_rs2_data <= _id_rs2_data_T ? 32'h0 : _id_rs2_data_T_8; exe_reg_mem_wen <= 2'h0;
if (_csignals_T_5 | _csignals_T_7)
exe_reg_exe_fun <= 5'h1;
else if (_csignals_T_9)
exe_reg_exe_fun <= 5'h2;
else if (_csignals_T_11)
exe_reg_exe_fun <= 5'h3;
else if (_csignals_T_13)
exe_reg_exe_fun <= 5'h4;
else if (_csignals_T_15)
exe_reg_exe_fun <= 5'h5;
else if (_csignals_T_17)
exe_reg_exe_fun <= 5'h3;
else if (_csignals_T_19)
exe_reg_exe_fun <= 5'h4;
else if (_csignals_T_21)
exe_reg_exe_fun <= 5'h6;
else if (_csignals_T_23)
exe_reg_exe_fun <= 5'h7;
else if (_csignals_T_25)
exe_reg_exe_fun <= 5'h8;
else if (_csignals_T_27)
exe_reg_exe_fun <= 5'h9;
else if (_csignals_T_29)
exe_reg_exe_fun <= 5'hB;
else if (_csignals_T_31)
exe_reg_exe_fun <= 5'hC;
else if (_csignals_T_33)
exe_reg_exe_fun <= 5'h1;
else if (_csignals_T_35)
exe_reg_exe_fun <= 5'hE;
else
exe_reg_exe_fun <= {4'h0, _csignals_T_37};
exe_reg_mem_wen <= 2'h0;
if (_csignals_T_5 | _csignals_T_7 | _csignals_T_9 | _csignals_T_11 | _csignals_T_13
| _csignals_T_15 | _csignals_T_17 | _csignals_T_19 | _csignals_T_21
| _csignals_T_23 | _csignals_T_25 | _csignals_T_27) begin
exe_reg_rf_wen <= 2'h1;
exe_reg_wb_sel <= 3'h1;
end
else if (_GEN_2) begin
exe_reg_rf_wen <= 2'h0;
exe_reg_wb_sel <= 3'h0;
end
else if (_csignals_T_33) begin
exe_reg_rf_wen <= 2'h1;
exe_reg_wb_sel <= 3'h3;
end
else if (_csignals_T_35) begin
exe_reg_rf_wen <= 2'h0; exe_reg_rf_wen <= 2'h0;
exe_reg_wb_sel <= 3'h0; exe_reg_wb_sel <= 3'h0;
exe_reg_imm_b_sext <= 32'h0;
mem_reg_pc <= 32'h0;
mem_reg_wb_addr <= 5'h0;
mem_reg_rs2_data <= 32'h0;
mem_reg_mem_wen <= 2'h0;
mem_reg_rf_wen <= 2'h0;
mem_reg_wb_sel <= 3'h0;
mem_reg_alu_out <= 32'h0;
wb_reg_wb_addr <= 5'h0;
wb_reg_rf_wen <= 2'h0;
wb_reg_wb_data <= 32'h0;
if_reg_pc <= 32'h400000;
end end
else begin else begin
exe_reg_rf_wen <= {1'h0, _csignals_T_37}; automatic logic _GEN_5;
exe_reg_wb_sel <= {2'h0, _csignals_T_37}; _GEN_5 = _csignals_T_27 | _csignals_T_29;
if (~stall_flg)
id_reg_pc <= if_reg_pc;
if (_id_inst_T)
id_reg_inst <= 32'h0;
else if (~stall_flg)
id_reg_inst <= io_imem_inst;
exe_reg_pc <= id_reg_pc;
exe_reg_wb_addr <= id_inst[15:11];
exe_reg_op1_data <= id_op1_data;
exe_reg_op2_data <= id_op2_data[31:0];
exe_reg_rs2_data <= id_rs2_data;
if (_csignals_T_5 | _csignals_T_7)
exe_reg_exe_fun <= 5'h1;
else if (_csignals_T_9)
exe_reg_exe_fun <= 5'h2;
else if (_csignals_T_11)
exe_reg_exe_fun <= 5'h3;
else if (_csignals_T_13)
exe_reg_exe_fun <= 5'h4;
else if (_csignals_T_15)
exe_reg_exe_fun <= 5'h5;
else if (_csignals_T_17)
exe_reg_exe_fun <= 5'h3;
else if (_csignals_T_19)
exe_reg_exe_fun <= 5'h4;
else if (_csignals_T_21)
exe_reg_exe_fun <= 5'h9;
else if (_csignals_T_23)
exe_reg_exe_fun <= 5'hB;
else if (_csignals_T_25)
exe_reg_exe_fun <= 5'hC;
else
exe_reg_exe_fun <= {4'h0, _GEN_5};
exe_reg_mem_wen <= 2'h0;
if (_csignals_T_5 | _csignals_T_7 | _csignals_T_9 | _csignals_T_11 | _csignals_T_13
| _csignals_T_15 | _csignals_T_17 | _csignals_T_19 | _csignals_T_21) begin
exe_reg_rf_wen <= 2'h1;
exe_reg_wb_sel <= 3'h1;
end
else if (_GEN_1) begin
exe_reg_rf_wen <= 2'h0;
exe_reg_wb_sel <= 3'h0;
end
else begin
exe_reg_rf_wen <= {1'h0, _GEN_5};
if (_csignals_T_27)
exe_reg_wb_sel <= 3'h3;
else
exe_reg_wb_sel <= {2'h0, _csignals_T_29};
end
exe_reg_imm_b_sext <= {{14{id_inst[15]}}, id_inst[15:0], 2'h0};
mem_reg_pc <= exe_reg_pc;
mem_reg_wb_addr <= exe_reg_wb_addr;
mem_reg_rs2_data <= exe_reg_rs2_data;
mem_reg_mem_wen <= exe_reg_mem_wen;
mem_reg_rf_wen <= exe_reg_rf_wen;
mem_reg_wb_sel <= exe_reg_wb_sel;
mem_reg_alu_out <= _exe_alu_out_T_46;
wb_reg_wb_addr <= mem_reg_wb_addr;
wb_reg_rf_wen <= mem_reg_rf_wen;
wb_reg_wb_data <= mem_wb_data;
if (exe_br_flg)
if_reg_pc <= exe_reg_pc + exe_reg_imm_b_sext;
else if (exe_jmp_flg)
if_reg_pc <= _exe_alu_out_T_46;
else if (~stall_flg)
if_reg_pc <= if_reg_pc + 32'h4;
end end
exe_reg_imm_b_sext <= {{16{id_inst[15]}}, id_inst[15:0]};
mem_reg_pc <= exe_reg_pc;
mem_reg_wb_addr <= exe_reg_wb_addr;
mem_reg_alu_out <= exe_alu_out;
mem_reg_rs2_data <= exe_reg_rs2_data;
mem_reg_rf_wen <= exe_reg_rf_wen;
mem_reg_wb_sel <= exe_reg_wb_sel;
mem_reg_mem_wen <= exe_reg_mem_wen;
wb_reg_wb_addr <= mem_reg_wb_addr;
wb_reg_rf_wen <= mem_reg_rf_wen;
wb_reg_wb_data <=
mem_reg_wb_sel == 3'h3
? mem_reg_pc + 32'h4
: mem_reg_wb_sel == 3'h2 ? io_dmem_rdata : mem_reg_alu_out;
if (reset)
if_reg_pc <= 32'h0;
else if (exe_br_flg)
if_reg_pc <= exe_reg_pc + exe_reg_imm_b_sext;
else if (exe_jmp_flg)
if_reg_pc <= exe_alu_out;
else if (~stall_flg)
if_reg_pc <= if_reg_pc + 32'h4;
end // always @(posedge) end // always @(posedge)
regfile_32x32 regfile_ext ( regfile_32x32 regfile_ext (
.R0_addr (id_reg_inst[20:16]), .R0_addr (5'h3),
.R0_en (1'h1), .R0_en (1'h1),
.R0_clk (clock), .R0_clk (clock),
.R0_data (_regfile_ext_R0_data), .R0_data (io_gp),
.R1_addr (id_reg_inst[25:21]), .R1_addr (id_inst[20:16]),
.R1_en (1'h1), .R1_en (1'h1),
.R1_clk (clock), .R1_clk (clock),
.R1_data (_regfile_ext_R1_data), .R1_data (_regfile_ext_R1_data),
.R2_addr (id_inst[25:21]),
.R2_en (1'h1),
.R2_clk (clock),
.R2_data (_regfile_ext_R2_data),
.W0_addr (wb_reg_wb_addr), .W0_addr (wb_reg_wb_addr),
.W0_en (_id_rs2_data_T_5), .W0_en (_id_rs2_data_T_5),
.W0_clk (clock), .W0_clk (clock),
@ -325,48 +331,84 @@ module Core(
assign io_dmem_addr = mem_reg_alu_out; assign io_dmem_addr = mem_reg_alu_out;
assign io_dmem_wen = mem_reg_mem_wen[0]; assign io_dmem_wen = mem_reg_mem_wen[0];
assign io_dmem_wdata = mem_reg_rs2_data; assign io_dmem_wdata = mem_reg_rs2_data;
assign io_exit = id_reg_inst == 32'hC0000000; assign io_exit = id_reg_inst == 32'h114514;
endmodule endmodule
// VCS coverage exclude_file // VCS coverage exclude_file
module mem_512x32( module mem_4096x8(
input [8:0] R0_addr, input [11:0] R0_addr,
input R0_en, input R0_en,
R0_clk, R0_clk,
output [31:0] R0_data, output [7:0] R0_data,
input [8:0] R1_addr, input [11:0] R1_addr,
input R1_en, input R1_en,
R1_clk, R1_clk,
output [31:0] R1_data, output [7:0] R1_data,
input [8:0] W0_addr, input [11:0] R2_addr,
input R2_en,
R2_clk,
output [7:0] R2_data,
input [11:0] R3_addr,
input R3_en,
R3_clk,
output [7:0] R3_data,
input [11:0] R4_addr,
input R4_en,
R4_clk,
output [7:0] R4_data,
input [11:0] R5_addr,
input R5_en,
R5_clk,
output [7:0] R5_data,
input [11:0] R6_addr,
input R6_en,
R6_clk,
output [7:0] R6_data,
input [11:0] R7_addr,
input R7_en,
R7_clk,
output [7:0] R7_data,
input [11:0] W0_addr,
input W0_en, input W0_en,
W0_clk, W0_clk,
input [31:0] W0_data input [7:0] W0_data,
input [11:0] W1_addr,
input W1_en,
W1_clk,
input [7:0] W1_data,
input [11:0] W2_addr,
input W2_en,
W2_clk,
input [7:0] W2_data,
input [11:0] W3_addr,
input W3_en,
W3_clk,
input [7:0] W3_data
); );
reg [31:0] Memory[0:511]; reg [7:0] Memory[0:4095];
reg _R0_en_d0;
reg [8:0] _R0_addr_d0;
always @(posedge R0_clk) begin
_R0_en_d0 <= R0_en;
_R0_addr_d0 <= R0_addr;
end // always @(posedge)
reg _R1_en_d0;
reg [8:0] _R1_addr_d0;
always @(posedge R1_clk) begin
_R1_en_d0 <= R1_en;
_R1_addr_d0 <= R1_addr;
end // always @(posedge)
always @(posedge W0_clk) begin always @(posedge W0_clk) begin
if (W0_en & 1'h1) if (W0_en & 1'h1)
Memory[W0_addr] <= W0_data; Memory[W0_addr] <= W0_data;
if (W1_en & 1'h1)
Memory[W1_addr] <= W1_data;
if (W2_en & 1'h1)
Memory[W2_addr] <= W2_data;
if (W3_en & 1'h1)
Memory[W3_addr] <= W3_data;
end // always @(posedge) end // always @(posedge)
`ifdef ENABLE_INITIAL_MEM_ `ifdef ENABLE_INITIAL_MEM_
initial initial
$readmemh("src/hex/mem.hex", Memory); $readmemh("src/hex/mem.hex", Memory);
`endif // ENABLE_INITIAL_MEM_ `endif // ENABLE_INITIAL_MEM_
assign R0_data = _R0_en_d0 ? Memory[_R0_addr_d0] : 32'bx; assign R0_data = R0_en ? Memory[R0_addr] : 8'bx;
assign R1_data = _R1_en_d0 ? Memory[_R1_addr_d0] : 32'bx; assign R1_data = R1_en ? Memory[R1_addr] : 8'bx;
assign R2_data = R2_en ? Memory[R2_addr] : 8'bx;
assign R3_data = R3_en ? Memory[R3_addr] : 8'bx;
assign R4_data = R4_en ? Memory[R4_addr] : 8'bx;
assign R5_data = R5_en ? Memory[R5_addr] : 8'bx;
assign R6_data = R6_en ? Memory[R6_addr] : 8'bx;
assign R7_data = R7_en ? Memory[R7_addr] : 8'bx;
endmodule endmodule
module Memory( module Memory(
@ -379,26 +421,78 @@ module Memory(
input [31:0] io_dmem_wdata input [31:0] io_dmem_wdata
); );
mem_512x32 mem_ext ( wire [7:0] _mem_ext_R0_data;
.R0_addr (io_imem_addr[10:2]), wire [7:0] _mem_ext_R1_data;
wire [7:0] _mem_ext_R2_data;
wire [7:0] _mem_ext_R3_data;
wire [7:0] _mem_ext_R4_data;
wire [7:0] _mem_ext_R5_data;
wire [7:0] _mem_ext_R6_data;
wire [7:0] _mem_ext_R7_data;
wire [11:0] _io_dmem_rdata_T = io_dmem_addr[11:0] + 12'h3;
wire [11:0] _io_dmem_rdata_T_3 = io_dmem_addr[11:0] + 12'h2;
wire [11:0] _io_dmem_rdata_T_6 = io_dmem_addr[11:0] + 12'h1;
mem_4096x8 mem_ext (
.R0_addr (io_imem_addr[11:0]),
.R0_en (1'h1), .R0_en (1'h1),
.R0_clk (clock), .R0_clk (clock),
.R0_data (io_imem_inst), .R0_data (_mem_ext_R0_data),
.R1_addr (io_dmem_addr[10:2]), .R1_addr (io_imem_addr[11:0] + 12'h1),
.R1_en (1'h1), .R1_en (1'h1),
.R1_clk (clock), .R1_clk (clock),
.R1_data (io_dmem_rdata), .R1_data (_mem_ext_R1_data),
.W0_addr (io_dmem_addr[10:2]), .R2_addr (io_imem_addr[11:0] + 12'h2),
.R2_en (1'h1),
.R2_clk (clock),
.R2_data (_mem_ext_R2_data),
.R3_addr (io_imem_addr[11:0] + 12'h3),
.R3_en (1'h1),
.R3_clk (clock),
.R3_data (_mem_ext_R3_data),
.R4_addr (io_dmem_addr[11:0]),
.R4_en (1'h1),
.R4_clk (clock),
.R4_data (_mem_ext_R4_data),
.R5_addr (_io_dmem_rdata_T_6),
.R5_en (1'h1),
.R5_clk (clock),
.R5_data (_mem_ext_R5_data),
.R6_addr (_io_dmem_rdata_T_3),
.R6_en (1'h1),
.R6_clk (clock),
.R6_data (_mem_ext_R6_data),
.R7_addr (_io_dmem_rdata_T),
.R7_en (1'h1),
.R7_clk (clock),
.R7_data (_mem_ext_R7_data),
.W0_addr (_io_dmem_rdata_T),
.W0_en (io_dmem_wen), .W0_en (io_dmem_wen),
.W0_clk (clock), .W0_clk (clock),
.W0_data (io_dmem_wdata) .W0_data (io_dmem_wdata[31:24]),
.W1_addr (_io_dmem_rdata_T_3),
.W1_en (io_dmem_wen),
.W1_clk (clock),
.W1_data (io_dmem_wdata[23:16]),
.W2_addr (_io_dmem_rdata_T_6),
.W2_en (io_dmem_wen),
.W2_clk (clock),
.W2_data (io_dmem_wdata[15:8]),
.W3_addr (io_dmem_addr[11:0]),
.W3_en (io_dmem_wen),
.W3_clk (clock),
.W3_data (io_dmem_wdata[7:0])
); );
assign io_imem_inst =
{_mem_ext_R3_data, _mem_ext_R2_data, _mem_ext_R1_data, _mem_ext_R0_data};
assign io_dmem_rdata =
{_mem_ext_R7_data, _mem_ext_R6_data, _mem_ext_R5_data, _mem_ext_R4_data};
endmodule endmodule
module TopOrigin( module TopOrigin(
input clock, input clock,
reset, reset,
output io_exit output io_exit,
output [31:0] io_gp
); );
wire [31:0] _memory_io_imem_inst; wire [31:0] _memory_io_imem_inst;
@ -416,7 +510,8 @@ module TopOrigin(
.io_dmem_rdata (_memory_io_dmem_rdata), .io_dmem_rdata (_memory_io_dmem_rdata),
.io_dmem_wen (_core_io_dmem_wen), .io_dmem_wen (_core_io_dmem_wen),
.io_dmem_wdata (_core_io_dmem_wdata), .io_dmem_wdata (_core_io_dmem_wdata),
.io_exit (io_exit) .io_exit (io_exit),
.io_gp (io_gp)
); );
Memory memory ( Memory memory (
.clock (clock), .clock (clock),

View File

@ -1,8 +1,36 @@
00 01 08 20 01
00 00 10 20 00
65 00 12 20 08
20 80 08 02 20
01 00 08 21 00
2A 50 12 01 00
FC FF 40 15 10
00 00 00 00 20
65
00
12
20
20
80
08
02
01
00
08
21
2a
50
12
01
fc
ff
40
15
00
00
00
00
14
45
11
00

View File

@ -6,12 +6,12 @@ import chisel3.util._
object Consts { object Consts {
// 数据宽度和地址 // 数据宽度和地址
val WORD_LEN = 32 // 指令和数据的宽度为32位 val WORD_LEN = 32 // 指令和数据的宽度为32位
val START_ADDR = 0.U(WORD_LEN.W) // 起始地址,设为0 val START_ADDR = 0x00400000.U(WORD_LEN.W) // MIPS程序的起始地址通常为0x00400000
val BUBBLE = 0x00000000.U(WORD_LEN.W) // 用于冒泡的指令 [NOP] val BUBBLE = 0x00000000.U(WORD_LEN.W) // 用于冒泡的指令 [NOP]
val UNIMP = "x_c0000000".U(WORD_LEN.W) val UNIMP = 0x00114514.U(WORD_LEN.W) // 未实现指令 [NOP]
// 寄存器地址长度 // 寄存器地址长度
val ADDR_LEN = 5 // rs1、rs2和写回寄存器的地址宽度为5位 val ADDR_LEN = 5 // rs、rt和rd的地址宽度为5位
// 执行功能定义 // 执行功能定义
val EXE_FUN_LEN = 5 // 执行功能的编码长度为5位 val EXE_FUN_LEN = 5 // 执行功能的编码长度为5位
@ -28,18 +28,22 @@ object Consts {
val ALU_SLTU = 10.U(EXE_FUN_LEN.W) // 无符号比较小于操作 val ALU_SLTU = 10.U(EXE_FUN_LEN.W) // 无符号比较小于操作
val BR_BEQ = 11.U(EXE_FUN_LEN.W) // 分支相等 val BR_BEQ = 11.U(EXE_FUN_LEN.W) // 分支相等
val BR_BNE = 12.U(EXE_FUN_LEN.W) // 分支不等 val BR_BNE = 12.U(EXE_FUN_LEN.W) // 分支不等
val ALU_JAL = 13.U(EXE_FUN_LEN.W) // JAL跳转 val BR_BLT = 13.U(EXE_FUN_LEN.W) // 有符号小于分支
val ALU_COPY1 = 14.U(EXE_FUN_LEN.W) // 复制操作 val BR_BGE = 14.U(EXE_FUN_LEN.W) // 有符号大于等于分支
val BR_BLTU = 15.U(EXE_FUN_LEN.W) // 无符号小于分支
val BR_BGEU = 16.U(EXE_FUN_LEN.W) // 无符号大于等于分支
val ALU_JALR = 17.U(EXE_FUN_LEN.W) // JALR跳转MIPS中没有JALR但可以模拟
val ALU_COPY1 = 18.U(EXE_FUN_LEN.W) // 复制操作
// 操作数选择 // 操作数选择
val OP1_LEN = 2 // 操作数1的选择宽度为2位 val OP1_LEN = 2 // 操作数1的选择宽度为2位
val OP1_RS1 = 0.U(OP1_LEN.W) // 选择rs1 val OP1_X = 0.U(OP1_LEN.W) // 未定义操作数1
val OP1_PC = 1.U(OP1_LEN.W) // 选择PC val OP1_RS = 1.U(OP1_LEN.W) // 选择rs
val OP1_X = 2.U(OP1_LEN.W) // 未定义操作数1 val OP1_PC = 2.U(OP1_LEN.W) // 选择PC
val OP2_LEN = 3 // 操作数2的选择宽度为3位 val OP2_LEN = 3 // 操作数2的选择宽度为3位
val OP2_X = 0.U(OP2_LEN.W) // 未定义操作数2 val OP2_X = 0.U(OP2_LEN.W) // 未定义操作数2
val OP2_RS2 = 1.U(OP2_LEN.W) // 选择rs2 val OP2_RT = 1.U(OP2_LEN.W) // 选择rt
val OP2_IMI = 2.U(OP2_LEN.W) // 立即数操作数2immI val OP2_IMI = 2.U(OP2_LEN.W) // 立即数操作数2immI
val OP2_IMS = 3.U(OP2_LEN.W) // 立即数操作数2immS val OP2_IMS = 3.U(OP2_LEN.W) // 立即数操作数2immS
val OP2_IMJ = 4.U(OP2_LEN.W) // 立即数操作数2immJ val OP2_IMJ = 4.U(OP2_LEN.W) // 立即数操作数2immJ
@ -62,12 +66,4 @@ object Consts {
val WB_MEM = 2.U(WB_SEL_LEN.W) // 内存数据写回 val WB_MEM = 2.U(WB_SEL_LEN.W) // 内存数据写回
val WB_PC = 3.U(WB_SEL_LEN.W) // PC写回 val WB_PC = 3.U(WB_SEL_LEN.W) // PC写回
// 内存宽度
val MW_LEN = 3 // 内存宽度控制信号宽度为3位
val MW_X = 0.U(MW_LEN.W) // 未定义
val MW_W = 1.U(MW_LEN.W) // 32位字访问
val MW_H = 2.U(MW_LEN.W) // 16位半字访问
val MW_B = 3.U(MW_LEN.W) // 8位字节访问
val MW_HU = 4.U(MW_LEN.W) // 16位无符号半字访问
val MW_BU = 5.U(MW_LEN.W) // 8位无符号字节访问
} }

View File

@ -5,13 +5,13 @@ import chisel3.util._
object Instructions { object Instructions {
// * 加载 / 存储 // * 加载 / 存储
val LW = BitPat("b100011????????????0000000000000000") // lw rt, offset(rs) val LW = BitPat("b100011????????????????????????????") // lw rt, offset(rs)
val SW = BitPat("b101011????????????0000000000000000") // sw rt, offset(rs) val SW = BitPat("b101011????????????????????????????") // sw rt, offset(rs)
// * 算术运算 // * 算术运算
val ADD = BitPat("b000000???????????????00000100000") // add rd, rs, rt val ADD = BitPat("b000000???????????????00000100000") // add rd, rs, rt
val ADDI = BitPat( val ADDI = BitPat(
"b001000????????????0000000000000000" "b001000????????????????????????????"
) // addi rt, rs, immediate ) // addi rt, rs, immediate
val SUB = BitPat("b000000???????????????00000100010") // sub rd, rs, rt val SUB = BitPat("b000000???????????????00000100010") // sub rd, rs, rt
@ -20,30 +20,31 @@ object Instructions {
val OR = BitPat("b000000???????????????00000100101") // or rd, rs, rt val OR = BitPat("b000000???????????????00000100101") // or rd, rs, rt
val XOR = BitPat("b000000???????????????00000100110") // xor rd, rs, rt val XOR = BitPat("b000000???????????????00000100110") // xor rd, rs, rt
val ANDI = BitPat( val ANDI = BitPat(
"b001100????????????0000000000000000" "b001100????????????????????????????"
) // andi rt, rs, immediate ) // andi rt, rs, immediate
val ORI = BitPat( val ORI = BitPat(
"b001101????????????0000000000000000" "b001101????????????????????????????"
) // ori rt, rs, immediate ) // ori rt, rs, immediate
// * 比较 // * 比较
val SLT = BitPat("b000000???????????????00000101010") // slt rd, rs, rt val SLT = BitPat("b000000???????????????00000101010") // slt rd, rs, rt
// * 条件分支 // * 条件分支
val BEQ = BitPat("b000100????????????0000000000000000") // beq rs, rt, offset val BEQ = BitPat("b000100????????????????????????????") // beq rs, rt, offset
val BNE = BitPat("b000101????????????0000000000000000") // bne rs, rt, offset val BNE = BitPat("b000101????????????????????????????") // bne rs, rt, offset
// * 移位 // * 移位
val SLL = BitPat("b00000000000??????????????000000") // sll rd, rt, shamt val SLL = BitPat("b00000000000???????????????000000") // sll rd, rt, shamt
val SRL = BitPat("b00000000000??????????????000010") // srl rd, rt, shamt val SRL = BitPat("b00000000000???????????????000010") // srl rd, rt, shamt
val SRA = BitPat("b00000000000??????????????000011") // sra rd, rt, shamt val SRA = BitPat("b00000000000???????????????000011") // sra rd, rt, shamt
// * 跳转 // * 跳转
val JR = BitPat("b000000????????????0000000000001000") // jr rs val JR = BitPat("b000000????????????0000000000001000") // jr rs
val JAL = BitPat("b00001100000000000000000000000000") // jal target val JAL = BitPat("b000011????????????????????????????") // jal target
// * 立即数加载 // * 立即数加载
val LUI = BitPat("b00111100000????????????0000000000") // lui rt, immediate val LUI = BitPat("b00111100000???????????????????????") // lui rt, immediate
val NOP = BitPat("b000000000000000000000000000000000") // nop // * NOP
val NOP = BitPat("b00000000000000000000000000000000") // nop (sll $0, $0, 0)
} }

View File

@ -7,48 +7,50 @@ import common.Instructions._
class Core extends Module { class Core extends Module {
val io = IO(new Bundle { val io = IO(new Bundle {
val imem = Flipped(new ImemPortIo) val imem = Flipped(new ImemPortIo())
val dmem = Flipped(new DmemPortIo) val dmem = Flipped(new DmemPortIo())
val exit = Output(Bool()) val exit = Output(Bool())
val gp = Output(UInt(WORD_LEN.W))
}) })
// Block RAM for data memory val regfile = Mem(32, UInt(WORD_LEN.W))
val regfile = SyncReadMem(32, UInt(WORD_LEN.W))
// ********* Pipeline Registers ********* // ********* Pipeline Registers *********
val id_reg = Reg(new Bundle { // IF/ID state
val pc = UInt(WORD_LEN.W) val id_reg_pc = RegInit(0.U(WORD_LEN.W))
val inst = UInt(WORD_LEN.W) val id_reg_inst = RegInit(0.U(WORD_LEN.W))
})
val exe_reg = Reg(new Bundle { // ID/EX state
val pc = UInt(WORD_LEN.W) val exe_reg_pc = RegInit(0.U(WORD_LEN.W))
val wb_addr = UInt(ADDR_LEN.W) val exe_reg_wb_addr = RegInit(0.U(ADDR_LEN.W))
val op1_data = UInt(WORD_LEN.W) val exe_reg_op1_data = RegInit(0.U(WORD_LEN.W))
val op2_data = UInt(WORD_LEN.W) val exe_reg_op2_data = RegInit(0.U(WORD_LEN.W))
val rs2_data = UInt(WORD_LEN.W) val exe_reg_rs2_data = RegInit(0.U(WORD_LEN.W))
val exe_fun = UInt(EXE_FUN_LEN.W) val exe_reg_exe_fun = RegInit(0.U(EXE_FUN_LEN.W))
val mem_wen = UInt(MEN_LEN.W) val exe_reg_mem_wen = RegInit(0.U(MEN_LEN.W))
val rf_wen = UInt(REN_LEN.W) val exe_reg_rf_wen = RegInit(0.U(REN_LEN.W))
val wb_sel = UInt(WB_SEL_LEN.W) val exe_reg_wb_sel = RegInit(0.U(WB_SEL_LEN.W))
val imm_b_sext = UInt(WORD_LEN.W) val exe_reg_imm_i_sext = RegInit(0.U(WORD_LEN.W))
}) val exe_reg_imm_s_sext = RegInit(0.U(WORD_LEN.W))
val exe_reg_imm_b_sext = RegInit(0.U(WORD_LEN.W))
val exe_reg_imm_u_shifted = RegInit(0.U(WORD_LEN.W))
val exe_reg_imm_z_uext = RegInit(0.U(WORD_LEN.W))
val mem_reg = Reg(new Bundle { // EX/MEM state
val pc = UInt(WORD_LEN.W) val mem_reg_pc = RegInit(0.U(WORD_LEN.W))
val wb_addr = UInt(ADDR_LEN.W) val mem_reg_wb_addr = RegInit(0.U(ADDR_LEN.W))
val alu_out = UInt(WORD_LEN.W) val mem_reg_op1_data = RegInit(0.U(WORD_LEN.W))
val rs2_data = UInt(WORD_LEN.W) val mem_reg_rs2_data = RegInit(0.U(WORD_LEN.W))
val rf_wen = UInt(REN_LEN.W) val mem_reg_mem_wen = RegInit(0.U(MEN_LEN.W))
val wb_sel = UInt(WB_SEL_LEN.W) val mem_reg_rf_wen = RegInit(0.U(REN_LEN.W))
val mem_wen = UInt(MEN_LEN.W) val mem_reg_wb_sel = RegInit(0.U(WB_SEL_LEN.W))
}) val mem_reg_imm_z_uext = RegInit(0.U(WORD_LEN.W))
val mem_reg_alu_out = RegInit(0.U(WORD_LEN.W))
val wb_reg = Reg(new Bundle { // MEM/WB state
val wb_addr = UInt(ADDR_LEN.W) val wb_reg_wb_addr = RegInit(0.U(ADDR_LEN.W))
val rf_wen = UInt(REN_LEN.W) val wb_reg_rf_wen = RegInit(0.U(REN_LEN.W))
val wb_data = UInt(WORD_LEN.W) val wb_reg_wb_data = RegInit(0.U(WORD_LEN.W))
})
// ********* Instruction Fetch (IF) Stage ********* // ********* Instruction Fetch (IF) Stage *********
val if_reg_pc = RegInit(START_ADDR) val if_reg_pc = RegInit(START_ADDR)
@ -67,193 +69,232 @@ class Core extends Module {
Seq( Seq(
exe_br_flg -> exe_br_target, exe_br_flg -> exe_br_target,
exe_jmp_flg -> exe_alu_out, exe_jmp_flg -> exe_alu_out,
stall_flg -> if_reg_pc stall_flg -> if_reg_pc // stall
) )
) )
if_reg_pc := if_pc_next if_reg_pc := if_pc_next
// ********* IF/ID Stage ********* // ********* IF/ID Stage *********
id_reg.pc := Mux(stall_flg, id_reg.pc, if_reg_pc) id_reg_pc := Mux(stall_flg, id_reg_pc, if_reg_pc)
id_reg.inst := MuxCase( id_reg_inst := MuxCase(
if_inst, if_inst,
Seq( Seq(
(exe_br_flg || exe_jmp_flg) -> BUBBLE, (exe_br_flg || exe_jmp_flg) -> BUBBLE,
stall_flg -> id_reg.inst stall_flg -> id_reg_inst
) )
) )
// ********* Decode (ID) Stage ********* // ********* Decode (ID) Stage *********
val id_rs1_addr = id_reg.inst(25, 21) val id_rs1_addr_b = id_reg_inst(25, 21) // MIPS rs字段
val id_rs2_addr = id_reg.inst(20, 16) val id_rs2_addr_b = id_reg_inst(20, 16) // MIPS rt字段
val id_wb_addr = id_reg.inst(15, 11)
// Data Hazard // 与EX数据冒险 -> stall
val id_rs1_data_hazard = val id_rs1_data_hazard =
(exe_reg.rf_wen === REN_S) && (id_rs1_addr =/= 0.U) && (id_rs1_addr === exe_reg.wb_addr) (exe_reg_rf_wen === REN_S) && (id_rs1_addr_b =/= 0.U) && (id_rs1_addr_b === exe_reg_wb_addr)
val id_rs2_data_hazard = val id_rs2_data_hazard =
(exe_reg.rf_wen === REN_S) && (id_rs2_addr =/= 0.U) && (id_rs2_addr === exe_reg.wb_addr) (exe_reg_rf_wen === REN_S) && (id_rs2_addr_b =/= 0.U) && (id_rs2_addr_b === exe_reg_wb_addr)
stall_flg := (id_rs1_data_hazard || id_rs2_data_hazard) stall_flg := (id_rs1_data_hazard || id_rs2_data_hazard)
val id_inst = val id_inst =
Mux((exe_br_flg || exe_jmp_flg || stall_flg), BUBBLE, id_reg.inst) Mux((exe_br_flg || exe_jmp_flg || stall_flg), BUBBLE, id_reg_inst)
val id_rs1_data = Mux( val id_rs1_addr = id_inst(25, 21) // MIPS rs字段
id_rs1_addr === 0.U, val id_rs2_addr = id_inst(20, 16) // MIPS rt字段
0.U(WORD_LEN.W), val id_wb_addr = id_inst(15, 11) // MIPS rt字段写回地址
Mux(
(id_rs1_addr === mem_reg.wb_addr) && (mem_reg.rf_wen === REN_S), val mem_wb_data = Wire(UInt(WORD_LEN.W))
mem_reg.alu_out, val id_rs1_data = MuxCase(
Mux( regfile(id_rs1_addr),
(id_rs1_addr === wb_reg.wb_addr) && (wb_reg.rf_wen === REN_S), Seq(
wb_reg.wb_data, (id_rs1_addr === 0.U) -> 0.U(WORD_LEN.W),
regfile(id_rs1_addr) ((id_rs1_addr === mem_reg_wb_addr) && (mem_reg_rf_wen === REN_S)) -> mem_wb_data, // 从MEM直通
) ((id_rs1_addr === wb_reg_wb_addr) && (wb_reg_rf_wen === REN_S)) -> wb_reg_wb_data // 从WB直通
) )
) )
val id_rs2_data = Mux( val id_rs2_data = MuxCase(
id_rs2_addr === 0.U, regfile(id_rs2_addr),
0.U(WORD_LEN.W), Seq(
Mux( (id_rs2_addr === 0.U) -> 0.U(WORD_LEN.W),
(id_rs2_addr === mem_reg.wb_addr) && (mem_reg.rf_wen === REN_S), ((id_rs2_addr === mem_reg_wb_addr) && (mem_reg_rf_wen === REN_S)) -> mem_wb_data, // 从MEM直通
mem_reg.alu_out, ((id_rs2_addr === wb_reg_wb_addr) && (wb_reg_rf_wen === REN_S)) -> wb_reg_wb_data // 从WB直通
Mux(
(id_rs2_addr === wb_reg.wb_addr) && (wb_reg.rf_wen === REN_S),
wb_reg.wb_data,
regfile(id_rs2_addr)
)
) )
) )
// 立即数扩展 val id_imm_i = id_inst(15, 0) // MIPS立即数字段
val id_imm_i_sext = Cat(Fill(16, id_inst(15)), id_inst(15, 0)) val id_imm_i_sext = Cat(Fill(16, id_imm_i(15)), id_imm_i)
val id_imm_b_sext = Cat(Fill(16, id_inst(15)), id_inst(15, 0)) val id_imm_s = Cat(id_inst(15, 11), id_inst(25, 21)) // 生成 10 位的立即数字段
val id_imm_s_sext = Cat(Fill(22, id_imm_s(9)), id_imm_s) // 符号扩展到 32 位
val id_imm_b = Cat(id_inst(15, 0), 0.U(2.W)) // MIPS分支指令的立即数字段
val id_imm_b_sext = Cat(Fill(14, id_imm_b(17)), id_imm_b)
val id_imm_j = Cat(id_inst(25, 0), 0.U(2.W)) // MIPS跳转指令的立即数字段
val id_imm_j_sext = Cat(Fill(6, id_imm_j(25)), id_imm_j, 0.U(2.W))
val id_imm_u = id_inst(15, 0) // MIPS lui指令的立即数字段
val id_imm_u_shifted = Cat(id_imm_u, Fill(16, 0.U))
val id_imm_z = id_inst(15, 11) // MIPS立即数字段
val id_imm_z_uext = Cat(Fill(27, 0.U), id_imm_z)
// 控制信号解码
val csignals = ListLookup( val csignals = ListLookup(
id_inst, id_inst,
List(ALU_X, OP1_RS1, OP2_RS2, MEN_X, REN_X, WB_X), List(ALU_X, OP1_RS, OP2_RT, MEN_X, REN_X, WB_X),
Array( Array(
LW -> List(ALU_ADD, OP1_RS1, OP2_IMI, MEN_X, REN_S, WB_MEM), LW -> List(ALU_ADD, OP1_RS, OP2_IMI, MEN_X, REN_S, WB_MEM),
SW -> List(ALU_ADD, OP1_RS1, OP2_IMS, MEN_S, REN_X, WB_X), SW -> List(ALU_ADD, OP1_RS, OP2_IMS, MEN_S, REN_X, WB_X),
ADD -> List(ALU_ADD, OP1_RS1, OP2_RS2, MEN_X, REN_S, WB_ALU), ADD -> List(ALU_ADD, OP1_RS, OP2_RT, MEN_X, REN_S, WB_ALU),
ADDI -> List(ALU_ADD, OP1_RS1, OP2_IMI, MEN_X, REN_S, WB_ALU), ADDI -> List(ALU_ADD, OP1_RS, OP2_IMI, MEN_X, REN_S, WB_ALU),
SUB -> List(ALU_SUB, OP1_RS1, OP2_RS2, MEN_X, REN_S, WB_ALU), SUB -> List(ALU_SUB, OP1_RS, OP2_RT, MEN_X, REN_S, WB_ALU),
AND -> List(ALU_AND, OP1_RS1, OP2_RS2, MEN_X, REN_S, WB_ALU), AND -> List(ALU_AND, OP1_RS, OP2_RT, MEN_X, REN_S, WB_ALU),
OR -> List(ALU_OR, OP1_RS1, OP2_RS2, MEN_X, REN_S, WB_ALU), OR -> List(ALU_OR, OP1_RS, OP2_RT, MEN_X, REN_S, WB_ALU),
XOR -> List(ALU_XOR, OP1_RS1, OP2_RS2, MEN_X, REN_S, WB_ALU), XOR -> List(ALU_XOR, OP1_RS, OP2_RT, MEN_X, REN_S, WB_ALU),
ANDI -> List(ALU_AND, OP1_RS1, OP2_IMI, MEN_X, REN_S, WB_ALU), ANDI -> List(ALU_AND, OP1_RS, OP2_IMI, MEN_X, REN_S, WB_ALU),
ORI -> List(ALU_OR, OP1_RS1, OP2_IMI, MEN_X, REN_S, WB_ALU), ORI -> List(ALU_OR, OP1_RS, OP2_IMI, MEN_X, REN_S, WB_ALU),
SLL -> List(ALU_SLL, OP1_RS1, OP2_RS2, MEN_X, REN_S, WB_ALU), SLT -> List(ALU_SLT, OP1_RS, OP2_RT, MEN_X, REN_S, WB_ALU),
SRL -> List(ALU_SRL, OP1_RS1, OP2_RS2, MEN_X, REN_S, WB_ALU), BEQ -> List(BR_BEQ, OP1_RS, OP2_RT, MEN_X, REN_X, WB_X),
SRA -> List(ALU_SRA, OP1_RS1, OP2_RS2, MEN_X, REN_S, WB_ALU), BNE -> List(BR_BNE, OP1_RS, OP2_RT, MEN_X, REN_X, WB_X),
SLT -> List(ALU_SLT, OP1_RS1, OP2_RS2, MEN_X, REN_S, WB_ALU),
BEQ -> List(BR_BEQ, OP1_RS1, OP2_RS2, MEN_X, REN_X, WB_X),
BNE -> List(BR_BNE, OP1_RS1, OP2_RS2, MEN_X, REN_X, WB_X),
JAL -> List(ALU_ADD, OP1_PC, OP2_IMJ, MEN_X, REN_S, WB_PC), JAL -> List(ALU_ADD, OP1_PC, OP2_IMJ, MEN_X, REN_S, WB_PC),
JR -> List(ALU_COPY1, OP1_RS1, OP2_X, MEN_X, REN_X, WB_X), LUI -> List(ALU_ADD, OP1_X, OP2_IMU, MEN_X, REN_S, WB_ALU)
LUI -> List(ALU_ADD, OP1_X, OP2_IMU, MEN_X, REN_S, WB_ALU),
NOP -> List(ALU_X, OP1_X, OP2_X, MEN_X, REN_X, WB_X)
) )
) )
val id_exe_fun :: id_op1_sel :: id_op2_sel :: id_mem_wen :: id_rf_wen :: id_wb_sel :: Nil = val id_exe_fun :: id_op1_sel :: id_op2_sel :: id_mem_wen :: id_rf_wen :: id_wb_sel :: Nil =
csignals csignals
val id_op1_data = Mux( val id_op1_data = MuxCase(
id_op1_sel === OP1_RS1, 0.U(WORD_LEN.W),
id_rs1_data,
Mux(id_op1_sel === OP1_PC, id_reg.pc, 0.U(WORD_LEN.W))
)
val id_op2_data = MuxLookup(
id_op2_sel,
0.U(WORD_LEN.W)
)(
Seq( Seq(
OP2_RS2 -> id_rs2_data, (id_op1_sel === OP1_RS) -> id_rs1_data,
OP2_IMI -> id_imm_i_sext, (id_op1_sel === OP1_PC) -> id_reg_pc
OP2_IMS -> id_imm_i_sext, // (id_op1_sel === OP1_IMZ) -> id_imm_z_uext
OP2_IMJ -> Cat(Fill(4, id_inst(25)), id_inst(25, 0), 0.U(2.W)), )
OP2_IMU -> Cat(id_inst(15, 0), Fill(16, 0.U)) )
val id_op2_data = MuxCase(
0.U(WORD_LEN.W),
Seq(
(id_op2_sel === OP2_RT) -> id_rs2_data,
(id_op2_sel === OP2_IMI) -> id_imm_i_sext,
(id_op2_sel === OP2_IMS) -> id_imm_s_sext,
(id_op2_sel === OP2_IMJ) -> id_imm_j_sext,
(id_op2_sel === OP2_IMU) -> id_imm_u_shifted
) )
) )
// ********* Decode/Execute (ID/EX) Stage ********* // ********* Decode/Execute (ID/EX) Stage *********
exe_reg.pc := id_reg.pc exe_reg_pc := id_reg_pc
exe_reg.op1_data := id_op1_data exe_reg_op1_data := id_op1_data
exe_reg.op2_data := id_op2_data exe_reg_op2_data := id_op2_data
exe_reg.rs2_data := id_rs2_data exe_reg_rs2_data := id_rs2_data
exe_reg.wb_addr := id_wb_addr exe_reg_wb_addr := id_wb_addr
exe_reg.wb_sel := id_wb_sel exe_reg_wb_sel := id_wb_sel
exe_reg.mem_wen := id_mem_wen exe_reg_mem_wen := id_mem_wen
exe_reg.rf_wen := id_rf_wen exe_reg_rf_wen := id_rf_wen
exe_reg.imm_b_sext := id_imm_b_sext exe_reg_imm_i_sext := id_imm_i_sext
exe_reg.exe_fun := id_exe_fun exe_reg_imm_s_sext := id_imm_s_sext
exe_reg_imm_b_sext := id_imm_b_sext
exe_reg_imm_u_shifted := id_imm_u_shifted
exe_reg_imm_z_uext := id_imm_z_uext
exe_reg_exe_fun := id_exe_fun
// ********* Execute (EX) Stage ********* // ********* Execute (EX) Stage *********
exe_alu_out := MuxLookup( exe_alu_out := MuxCase(
exe_reg.exe_fun, 0.U(WORD_LEN.W),
0.U(WORD_LEN.W)
)(
Seq( Seq(
ALU_ADD -> (exe_reg.op1_data + exe_reg.op2_data), (exe_reg_exe_fun === ALU_ADD) -> (exe_reg_op1_data + exe_reg_op2_data),
ALU_SUB -> (exe_reg.op1_data - exe_reg.op2_data), (exe_reg_exe_fun === ALU_SUB) -> (exe_reg_op1_data - exe_reg_op2_data),
ALU_AND -> (exe_reg.op1_data & exe_reg.op2_data), (exe_reg_exe_fun === ALU_AND) -> (exe_reg_op1_data & exe_reg_op2_data),
ALU_OR -> (exe_reg.op1_data | exe_reg.op2_data), (exe_reg_exe_fun === ALU_OR) -> (exe_reg_op1_data | exe_reg_op2_data),
ALU_XOR -> (exe_reg.op1_data ^ exe_reg.op2_data), (exe_reg_exe_fun === ALU_XOR) -> (exe_reg_op1_data ^ exe_reg_op2_data),
ALU_SLL -> (exe_reg.op1_data << exe_reg.op2_data(4, 0))(31, 0), (exe_reg_exe_fun === ALU_SLL) -> (exe_reg_op1_data << exe_reg_op2_data(
ALU_SRL -> (exe_reg.op1_data >> exe_reg.op2_data(4, 0)).asUInt, 4,
ALU_SRA -> (exe_reg.op1_data.asSInt >> exe_reg.op2_data(4, 0)).asUInt, 0
ALU_SLT -> (exe_reg.op1_data.asSInt < exe_reg.op2_data.asSInt).asUInt, )),
ALU_COPY1 -> exe_reg.op1_data (exe_reg_exe_fun === ALU_SRL) -> (exe_reg_op1_data >> exe_reg_op2_data(
4,
0
)).asUInt,
(exe_reg_exe_fun === ALU_SRA) -> (exe_reg_op1_data.asSInt >> exe_reg_op2_data(
4,
0
)).asUInt,
(exe_reg_exe_fun === ALU_SLT) -> (exe_reg_op1_data.asSInt < exe_reg_op2_data.asSInt).asUInt,
(exe_reg_exe_fun === ALU_SLTU) -> (exe_reg_op1_data < exe_reg_op2_data).asUInt,
(exe_reg_exe_fun === ALU_JALR) -> ((exe_reg_op1_data + exe_reg_op2_data) & (~1
.U(WORD_LEN.W))),
(exe_reg_exe_fun === ALU_COPY1) -> exe_reg_op1_data
) )
) )
exe_br_flg := MuxLookup( exe_br_flg := MuxCase(
exe_reg.exe_fun, false.B,
false.B
)(
Seq( Seq(
BR_BEQ -> (exe_reg.op1_data === exe_reg.op2_data), (exe_reg_exe_fun === BR_BEQ) -> (exe_reg_op1_data === exe_reg_op2_data).asBool,
BR_BNE -> (exe_reg.op1_data =/= exe_reg.op2_data) (exe_reg_exe_fun === BR_BNE) -> !(exe_reg_op1_data === exe_reg_op2_data).asBool
) )
) )
exe_br_target := exe_reg.pc + exe_reg.imm_b_sext exe_br_target := exe_reg_pc + exe_reg_imm_b_sext
exe_jmp_flg := (exe_reg.wb_sel === WB_PC)
// ********* Execute/Memory (EX/MEM) Stage ********* exe_jmp_flg := (exe_reg_wb_sel === WB_PC)
mem_reg.pc := exe_reg.pc
mem_reg.wb_addr := exe_reg.wb_addr // ********** Execute/Memory (EX/MEM) Stage ***********
mem_reg.alu_out := exe_alu_out mem_reg_pc := exe_reg_pc
mem_reg.rs2_data := exe_reg.rs2_data mem_reg_op1_data := exe_reg_op1_data
mem_reg.rf_wen := exe_reg.rf_wen mem_reg_rs2_data := exe_reg_rs2_data
mem_reg.wb_sel := exe_reg.wb_sel mem_reg_wb_addr := exe_reg_wb_addr
mem_reg.mem_wen := exe_reg.mem_wen mem_reg_alu_out := exe_alu_out
mem_reg_rf_wen := exe_reg_rf_wen
mem_reg_wb_sel := exe_reg_wb_sel
mem_reg_imm_z_uext := exe_reg_imm_z_uext
mem_reg_mem_wen := exe_reg_mem_wen
// ********* Memory (MEM) Stage ********* // ********* Memory (MEM) Stage *********
io.dmem.addr := mem_reg.alu_out io.dmem.addr := mem_reg_alu_out
io.dmem.wen := mem_reg.mem_wen io.dmem.wen := mem_reg_mem_wen
io.dmem.wdata := mem_reg.rs2_data io.dmem.wdata := mem_reg_rs2_data
val mem_wb_data = MuxLookup( mem_wb_data := MuxCase(
mem_reg.wb_sel, mem_reg_alu_out,
mem_reg.alu_out
)(
Seq( Seq(
WB_MEM -> io.dmem.rdata, (mem_reg_wb_sel === WB_MEM) -> io.dmem.rdata,
WB_PC -> (mem_reg.pc + 4.U(WORD_LEN.W)) (mem_reg_wb_sel === WB_PC) -> (mem_reg_pc + 4.U(WORD_LEN.W))
) )
) )
// ********* Memory/Write Back (MEM/WB) Stage ********* // ********** Memory/Write Back (MEM/WB) Stage ***********
wb_reg.wb_addr := mem_reg.wb_addr wb_reg_wb_data := mem_wb_data
wb_reg.rf_wen := mem_reg.rf_wen wb_reg_rf_wen := mem_reg_rf_wen
wb_reg.wb_data := mem_wb_data wb_reg_wb_addr := mem_reg_wb_addr
// ********* Write Back (WB) Stage ********* // ********* Write Back (WB) Stage *********
when(wb_reg.rf_wen === REN_S) { when(wb_reg_rf_wen === REN_S) { regfile(wb_reg_wb_addr) := wb_reg_wb_data }
regfile(wb_reg.wb_addr) := wb_reg.wb_data
}
io.exit := (id_reg.inst === UNIMP) // ********* Debugging *********
io.gp := regfile(3)
io.exit := (id_reg_inst === UNIMP)
printf(p"---------------------\n")
// printf(p"if_reg_pc: 0x${Hexadecimal(if_reg_pc)}\n")
printf(p"id_reg_pc: 0x${Hexadecimal(id_reg_pc)}\n")
printf(p"id_reg_inst: 0x${Hexadecimal(id_reg_inst)}\n")
printf(p"id_inst: 0x${Hexadecimal(id_inst)}\n")
printf(p"id_rs1_addr: 0x${Hexadecimal(id_rs1_addr)}\n")
printf(p"id_rs2_addr: 0x${Hexadecimal(id_rs2_addr)}\n")
printf(p"id_wb_addr: 0x${Hexadecimal(id_wb_addr)}\n")
printf(p"id_exe_fun: 0x${Hexadecimal(id_exe_fun)}\n")
printf(p"id_op1_sel: 0x${Hexadecimal(id_op1_sel)}\n")
printf(p"id_op1_data: 0x${Hexadecimal(id_op1_data)}\n")
printf(p"id_op2_sel: 0x${Hexadecimal(id_op2_sel)}\n")
printf(p"id_op2_data: 0x${Hexadecimal(id_op2_data)}\n")
printf(p"id_mem_wen: 0x${Hexadecimal(id_mem_wen)}\n")
printf(p"id_rf_wen: 0x${Hexadecimal(id_rf_wen)}\n")
printf(p"id_wb_sel: 0x${Hexadecimal(id_wb_sel)}\n")
printf(p"id_rs1_data: 0x${Hexadecimal(id_rs1_data)}\n")
printf(p"id_rs2_data: 0x${Hexadecimal(id_rs2_data)}\n")
// printf(p"exe_reg_pc: 0x${Hexadecimal(exe_reg_pc)}\n")
// printf(p"exe_reg_op1_data: 0x${Hexadecimal(id_op1_data)}\n")
// printf(p"exe_reg_op2_data: 0x${Hexadecimal(id_op2_data)}\n")
printf(p"exe_alu_out: 0x${Hexadecimal(exe_alu_out)}\n")
printf(p"mem_reg_pc: 0x${Hexadecimal(mem_reg_pc)}\n")
printf(p"mem_reg_alu_out: 0x${Hexadecimal(mem_reg_alu_out)}\n")
printf(p"mem_wb_data: 0x${Hexadecimal(mem_wb_data)}\n")
printf(p"wb_reg_wb_data: 0${Hexadecimal(wb_reg_wb_data)}\n")
printf(p"---------------------\n")
} }

View File

@ -2,14 +2,19 @@ package micore
import chisel3._ import chisel3._
import chisel3.util._ import chisel3.util._
import chisel3.util.experimental.loadMemoryFromFileInline import chisel3.util.experimental.loadMemoryFromFile
import common.Consts._ import common.Consts._
import chisel3.util.experimental.loadMemoryFromFileInline
/** 表示一个指令内存端口接口的类
*/
class ImemPortIo extends Bundle { class ImemPortIo extends Bundle {
val addr = Input(UInt(WORD_LEN.W)) val addr = Input(UInt(WORD_LEN.W))
val inst = Output(UInt(WORD_LEN.W)) val inst = Output(UInt(WORD_LEN.W))
} }
/** 表示一个数据内存端口接口的类
*/
class DmemPortIo extends Bundle { class DmemPortIo extends Bundle {
val addr = Input(UInt(WORD_LEN.W)) val addr = Input(UInt(WORD_LEN.W))
val rdata = Output(UInt(WORD_LEN.W)) val rdata = Output(UInt(WORD_LEN.W))
@ -19,20 +24,37 @@ class DmemPortIo extends Bundle {
class Memory extends Module { class Memory extends Module {
val io = IO(new Bundle { val io = IO(new Bundle {
val imem = new ImemPortIo val imem = new ImemPortIo()
val dmem = new DmemPortIo val dmem = new DmemPortIo()
}) })
// val mem = Mem(8192, UInt(8.W)) // 生成八位宽x4096(4KB)寄存器的存储器。
val mem = SyncReadMem(512, UInt(WORD_LEN.W)) val mem = Mem(4096, UInt(8.W))
// 加载存储器的初始值。
loadMemoryFromFileInline(mem, "src/hex/mem.hex") loadMemoryFromFileInline(mem, "src/hex/mem.hex")
io.imem.inst := mem.read(io.imem.addr >> 2) // 连接四个地址存储的八位数据形成一个32位的指令。
io.imem.inst := Cat(
mem(io.imem.addr + 3.U(WORD_LEN.W)),
mem(io.imem.addr + 2.U(WORD_LEN.W)),
mem(io.imem.addr + 1.U(WORD_LEN.W)),
mem(io.imem.addr)
)
io.dmem.rdata := mem.read(io.dmem.addr >> 2) // 连接四个地址存储的八位数据形成一个32位的数据。
io.dmem.rdata := Cat(
mem(io.dmem.addr + 3.U(WORD_LEN.W)),
mem(io.dmem.addr + 2.U(WORD_LEN.W)),
mem(io.dmem.addr + 1.U(WORD_LEN.W)),
mem(io.dmem.addr)
)
// 写数据到存储器。
when(io.dmem.wen) { when(io.dmem.wen) {
mem.write(io.dmem.addr >> 2, io.dmem.wdata) mem(io.dmem.addr) := io.dmem.wdata(7, 0)
mem(io.dmem.addr + 1.U(WORD_LEN.W)) := io.dmem.wdata(15, 8)
mem(io.dmem.addr + 2.U(WORD_LEN.W)) := io.dmem.wdata(23, 16)
mem(io.dmem.addr + 3.U(WORD_LEN.W)) := io.dmem.wdata(31, 24)
} }
} }

View File

@ -8,14 +8,14 @@ import common.Consts._
class TopOrigin extends Module { class TopOrigin extends Module {
val io = IO(new Bundle { val io = IO(new Bundle {
val exit = Output(Bool()) val exit = Output(Bool())
val gp = Output(UInt(WORD_LEN.W))
}) })
val core = Module(new Core) val core = Module(new Core())
val memory = Module(new Memory) val memory = Module(new Memory())
core.io.imem <> memory.io.imem core.io.imem <> memory.io.imem
core.io.dmem <> memory.io.dmem core.io.dmem <> memory.io.dmem
io.exit := core.io.exit io.exit := core.io.exit
io.gp := core.io.gp
} }
/** Generate Verilog sources and save it in file /** Generate Verilog sources and save it in file
@ -26,8 +26,7 @@ object TopOrigin extends App {
firtoolOpts = Array( firtoolOpts = Array(
"--disable-all-randomization", "--disable-all-randomization",
"--strip-debug-info", "--strip-debug-info",
"--O=release", "--O=release"
"--mlir-timing"
) )
) )
} }

View File

@ -1,8 +1,9 @@
package micore package micore
import chisel3._ import chisel3._
import org.scalatest.flatspec._
import chiseltest._ import chiseltest._
import org.scalatest.flatspec.AnyFlatSpec
import org.scalatest.matchers.should.Matchers
class CTest extends AnyFlatSpec with ChiselScalatestTester { class CTest extends AnyFlatSpec with ChiselScalatestTester {
"Micore" should "run the C program" in { "Micore" should "run the C program" in {

View File

@ -1 +1 @@
["sbt.Task[scala.collection.Seq[java.nio.file.Path]]",["/run/media/gh0s7/Data/project/ddca2024/micore/target/scala-2.13/classes/micore/Core$$anon$1.class","/run/media/gh0s7/Data/project/ddca2024/micore/target/scala-2.13/classes/common/Consts$.class","/run/media/gh0s7/Data/project/ddca2024/micore/target/scala-2.13/classes/micore/TopOrigin$delayedInit$body.class","/run/media/gh0s7/Data/project/ddca2024/micore/target/scala-2.13/classes/common/Instructions$.class","/run/media/gh0s7/Data/project/ddca2024/micore/target/scala-2.13/classes/micore/Core$$anon$4.class","/run/media/gh0s7/Data/project/ddca2024/micore/target/scala-2.13/classes/micore/Core$$anon$2.class","/run/media/gh0s7/Data/project/ddca2024/micore/target/scala-2.13/classes/micore/TopOrigin.class","/run/media/gh0s7/Data/project/ddca2024/micore/target/scala-2.13/classes/micore/TopOrigin$$anon$1.class","/run/media/gh0s7/Data/project/ddca2024/micore/target/scala-2.13/classes/micore/Memory$$anon$1.class","/run/media/gh0s7/Data/project/ddca2024/micore/target/scala-2.13/classes/micore/ImemPortIo.class","/run/media/gh0s7/Data/project/ddca2024/micore/target/scala-2.13/classes/micore/Core.class","/run/media/gh0s7/Data/project/ddca2024/micore/target/scala-2.13/classes/micore/Core$$anon$5.class","/run/media/gh0s7/Data/project/ddca2024/micore/target/scala-2.13/classes/common/Consts.class","/run/media/gh0s7/Data/project/ddca2024/micore/target/scala-2.13/classes/micore/Core$$anon$3.class","/run/media/gh0s7/Data/project/ddca2024/micore/target/scala-2.13/classes/micore/DmemPortIo.class","/run/media/gh0s7/Data/project/ddca2024/micore/target/scala-2.13/classes/micore/Memory.class","/run/media/gh0s7/Data/project/ddca2024/micore/target/scala-2.13/classes/micore/TopOrigin$.class","/run/media/gh0s7/Data/project/ddca2024/micore/target/scala-2.13/classes/common/Instructions.class","/run/media/gh0s7/Data/project/ddca2024/micore/target/scala-2.13/zinc/inc_compile_2.13.zip"]] ["sbt.Task[scala.collection.Seq[java.nio.file.Path]]",["/run/media/gh0s7/Data/project/ddca2024/micore/target/scala-2.13/classes/micore/Core$$anon$1.class","/run/media/gh0s7/Data/project/ddca2024/micore/target/scala-2.13/classes/common/Consts$.class","/run/media/gh0s7/Data/project/ddca2024/micore/target/scala-2.13/classes/micore/TopOrigin$delayedInit$body.class","/run/media/gh0s7/Data/project/ddca2024/micore/target/scala-2.13/classes/common/Instructions$.class","/run/media/gh0s7/Data/project/ddca2024/micore/target/scala-2.13/classes/micore/TopOrigin.class","/run/media/gh0s7/Data/project/ddca2024/micore/target/scala-2.13/classes/micore/TopOrigin$$anon$1.class","/run/media/gh0s7/Data/project/ddca2024/micore/target/scala-2.13/classes/micore/Memory$$anon$1.class","/run/media/gh0s7/Data/project/ddca2024/micore/target/scala-2.13/classes/micore/ImemPortIo.class","/run/media/gh0s7/Data/project/ddca2024/micore/target/scala-2.13/classes/micore/Core.class","/run/media/gh0s7/Data/project/ddca2024/micore/target/scala-2.13/classes/common/Consts.class","/run/media/gh0s7/Data/project/ddca2024/micore/target/scala-2.13/classes/micore/DmemPortIo.class","/run/media/gh0s7/Data/project/ddca2024/micore/target/scala-2.13/classes/micore/Memory.class","/run/media/gh0s7/Data/project/ddca2024/micore/target/scala-2.13/classes/micore/TopOrigin$.class","/run/media/gh0s7/Data/project/ddca2024/micore/target/scala-2.13/classes/common/Instructions.class","/run/media/gh0s7/Data/project/ddca2024/micore/target/scala-2.13/zinc/inc_compile_2.13.zip"]]

File diff suppressed because one or more lines are too long

View File

@ -1,2 +1,17 @@
[debug] Created transactional ClassFileManager with tempDir = /run/media/gh0s7/Data/project/ddca2024/micore/target/scala-2.13/classes.bak [debug] Created transactional ClassFileManager with tempDir = /run/media/gh0s7/Data/project/ddca2024/micore/target/scala-2.13/classes.bak
[debug] About to delete class files:
[debug]  Consts$.class
[debug]  Consts.class
[debug]  Core$$anon$1.class
[debug]  Core.class
[debug] We backup class files:
[debug]  Consts$.class
[debug]  Consts.class
[debug]  Core$$anon$1.class
[debug]  Core.class
[debug] Registering generated classes:
[debug]  Consts.class
[debug]  Consts$.class
[debug]  Core$$anon$1.class
[debug]  Core.class
[debug] Removing the temporary directory used for backing up class files: /run/media/gh0s7/Data/project/ddca2024/micore/target/scala-2.13/classes.bak [debug] Removing the temporary directory used for backing up class files: /run/media/gh0s7/Data/project/ddca2024/micore/target/scala-2.13/classes.bak

View File

@ -1 +1 @@
-153958634 -627113868

View File

@ -14,14 +14,6 @@
[debug]  /run/media/gh0s7/Data/project/ddca2024/micore/target/scala-2.13/classes/micore [debug]  /run/media/gh0s7/Data/project/ddca2024/micore/target/scala-2.13/classes/micore
[debug]  micore/Core$$anon$1.class [debug]  micore/Core$$anon$1.class
[debug]  /run/media/gh0s7/Data/project/ddca2024/micore/target/scala-2.13/classes/micore/Core$$anon$1.class [debug]  /run/media/gh0s7/Data/project/ddca2024/micore/target/scala-2.13/classes/micore/Core$$anon$1.class
[debug]  micore/Core$$anon$2.class
[debug]  /run/media/gh0s7/Data/project/ddca2024/micore/target/scala-2.13/classes/micore/Core$$anon$2.class
[debug]  micore/Core$$anon$3.class
[debug]  /run/media/gh0s7/Data/project/ddca2024/micore/target/scala-2.13/classes/micore/Core$$anon$3.class
[debug]  micore/Core$$anon$4.class
[debug]  /run/media/gh0s7/Data/project/ddca2024/micore/target/scala-2.13/classes/micore/Core$$anon$4.class
[debug]  micore/Core$$anon$5.class
[debug]  /run/media/gh0s7/Data/project/ddca2024/micore/target/scala-2.13/classes/micore/Core$$anon$5.class
[debug]  micore/Core.class [debug]  micore/Core.class
[debug]  /run/media/gh0s7/Data/project/ddca2024/micore/target/scala-2.13/classes/micore/Core.class [debug]  /run/media/gh0s7/Data/project/ddca2024/micore/target/scala-2.13/classes/micore/Core.class
[debug]  micore/DmemPortIo.class [debug]  micore/DmemPortIo.class

File diff suppressed because it is too large Load Diff