Still need to fix
This commit is contained in:
697
TopOrigin.sv
697
TopOrigin.sv
@ -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),
|
||||||
|
|||||||
@ -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
|
||||||
@ -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) // 立即数操作数2(immI)
|
val OP2_IMI = 2.U(OP2_LEN.W) // 立即数操作数2(immI)
|
||||||
val OP2_IMS = 3.U(OP2_LEN.W) // 立即数操作数2(immS)
|
val OP2_IMS = 3.U(OP2_LEN.W) // 立即数操作数2(immS)
|
||||||
val OP2_IMJ = 4.U(OP2_LEN.W) // 立即数操作数2(immJ)
|
val OP2_IMJ = 4.U(OP2_LEN.W) // 立即数操作数2(immJ)
|
||||||
@ -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位无符号字节访问
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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")
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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"
|
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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 {
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
@ -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
@ -1,2 +1,17 @@
|
|||||||
[0m[[0m[0mdebug[0m] [0m[0mCreated transactional ClassFileManager with tempDir = /run/media/gh0s7/Data/project/ddca2024/micore/target/scala-2.13/classes.bak[0m
|
[0m[[0m[0mdebug[0m] [0m[0mCreated transactional ClassFileManager with tempDir = /run/media/gh0s7/Data/project/ddca2024/micore/target/scala-2.13/classes.bak[0m
|
||||||
|
[0m[[0m[0mdebug[0m] [0m[0mAbout to delete class files:[0m
|
||||||
|
[0m[[0m[0mdebug[0m] [0m[0m Consts$.class[0m
|
||||||
|
[0m[[0m[0mdebug[0m] [0m[0m Consts.class[0m
|
||||||
|
[0m[[0m[0mdebug[0m] [0m[0m Core$$anon$1.class[0m
|
||||||
|
[0m[[0m[0mdebug[0m] [0m[0m Core.class[0m
|
||||||
|
[0m[[0m[0mdebug[0m] [0m[0mWe backup class files:[0m
|
||||||
|
[0m[[0m[0mdebug[0m] [0m[0m Consts$.class[0m
|
||||||
|
[0m[[0m[0mdebug[0m] [0m[0m Consts.class[0m
|
||||||
|
[0m[[0m[0mdebug[0m] [0m[0m Core$$anon$1.class[0m
|
||||||
|
[0m[[0m[0mdebug[0m] [0m[0m Core.class[0m
|
||||||
|
[0m[[0m[0mdebug[0m] [0m[0mRegistering generated classes:[0m
|
||||||
|
[0m[[0m[0mdebug[0m] [0m[0m Consts.class[0m
|
||||||
|
[0m[[0m[0mdebug[0m] [0m[0m Consts$.class[0m
|
||||||
|
[0m[[0m[0mdebug[0m] [0m[0m Core$$anon$1.class[0m
|
||||||
|
[0m[[0m[0mdebug[0m] [0m[0m Core.class[0m
|
||||||
[0m[[0m[0mdebug[0m] [0m[0mRemoving the temporary directory used for backing up class files: /run/media/gh0s7/Data/project/ddca2024/micore/target/scala-2.13/classes.bak[0m
|
[0m[[0m[0mdebug[0m] [0m[0mRemoving the temporary directory used for backing up class files: /run/media/gh0s7/Data/project/ddca2024/micore/target/scala-2.13/classes.bak[0m
|
||||||
|
|||||||
@ -1 +1 @@
|
|||||||
-153958634
|
-627113868
|
||||||
@ -14,14 +14,6 @@
|
|||||||
[0m[[0m[0mdebug[0m] [0m[0m /run/media/gh0s7/Data/project/ddca2024/micore/target/scala-2.13/classes/micore[0m
|
[0m[[0m[0mdebug[0m] [0m[0m /run/media/gh0s7/Data/project/ddca2024/micore/target/scala-2.13/classes/micore[0m
|
||||||
[0m[[0m[0mdebug[0m] [0m[0m micore/Core$$anon$1.class[0m
|
[0m[[0m[0mdebug[0m] [0m[0m micore/Core$$anon$1.class[0m
|
||||||
[0m[[0m[0mdebug[0m] [0m[0m /run/media/gh0s7/Data/project/ddca2024/micore/target/scala-2.13/classes/micore/Core$$anon$1.class[0m
|
[0m[[0m[0mdebug[0m] [0m[0m /run/media/gh0s7/Data/project/ddca2024/micore/target/scala-2.13/classes/micore/Core$$anon$1.class[0m
|
||||||
[0m[[0m[0mdebug[0m] [0m[0m micore/Core$$anon$2.class[0m
|
|
||||||
[0m[[0m[0mdebug[0m] [0m[0m /run/media/gh0s7/Data/project/ddca2024/micore/target/scala-2.13/classes/micore/Core$$anon$2.class[0m
|
|
||||||
[0m[[0m[0mdebug[0m] [0m[0m micore/Core$$anon$3.class[0m
|
|
||||||
[0m[[0m[0mdebug[0m] [0m[0m /run/media/gh0s7/Data/project/ddca2024/micore/target/scala-2.13/classes/micore/Core$$anon$3.class[0m
|
|
||||||
[0m[[0m[0mdebug[0m] [0m[0m micore/Core$$anon$4.class[0m
|
|
||||||
[0m[[0m[0mdebug[0m] [0m[0m /run/media/gh0s7/Data/project/ddca2024/micore/target/scala-2.13/classes/micore/Core$$anon$4.class[0m
|
|
||||||
[0m[[0m[0mdebug[0m] [0m[0m micore/Core$$anon$5.class[0m
|
|
||||||
[0m[[0m[0mdebug[0m] [0m[0m /run/media/gh0s7/Data/project/ddca2024/micore/target/scala-2.13/classes/micore/Core$$anon$5.class[0m
|
|
||||||
[0m[[0m[0mdebug[0m] [0m[0m micore/Core.class[0m
|
[0m[[0m[0mdebug[0m] [0m[0m micore/Core.class[0m
|
||||||
[0m[[0m[0mdebug[0m] [0m[0m /run/media/gh0s7/Data/project/ddca2024/micore/target/scala-2.13/classes/micore/Core.class[0m
|
[0m[[0m[0mdebug[0m] [0m[0m /run/media/gh0s7/Data/project/ddca2024/micore/target/scala-2.13/classes/micore/Core.class[0m
|
||||||
[0m[[0m[0mdebug[0m] [0m[0m micore/DmemPortIo.class[0m
|
[0m[[0m[0mdebug[0m] [0m[0m micore/DmemPortIo.class[0m
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user