[Add] add div.w[u], mod.w[u]

This commit is contained in:
2023-05-27 23:52:30 +08:00
parent 9a72e27ca4
commit 3b43e06054
9 changed files with 271 additions and 35 deletions

View File

@@ -15,6 +15,24 @@ module mycpu_top(
output [31:0] data_sram_addr,
output [31:0] data_sram_wdata,
input [31:0] data_sram_rdata,
//div
output [31:0] div_divisor_data,
output div_divisor_valid,
input div_divisor_ready,
output [31:0] div_dividend_data,
output div_dividend_valid,
input div_dividend_ready,
input div_dout_valid,
input [63:0] div_dout_data,
//divu
output [31:0] divu_divisor_data,
output divu_divisor_valid,
input divu_divisor_ready,
output [31:0] divu_dividend_data,
output divu_dividend_valid,
input divu_dividend_ready,
input divu_dout_valid,
input [63:0] divu_dout_data,
// trace debug interface
output [31:0] debug_wb_pc,
output [ 3:0] debug_wb_rf_wen,
@@ -107,7 +125,25 @@ module mycpu_top(
.data_sram_en (data_sram_en ),
.data_sram_wen (data_sram_wen ),
.data_sram_addr (data_sram_addr ),
.data_sram_wdata(data_sram_wdata)
.data_sram_wdata(data_sram_wdata),
//div
.div_divisor_data (div_divisor_data ),
.div_divisor_valid (div_divisor_valid ),
.div_divisor_ready (div_divisor_ready ),
.div_dividend_data (div_dividend_data ),
.div_dividend_valid (div_dividend_valid ),
.div_dividend_ready (div_dividend_ready ),
.div_dout_valid (div_dout_valid ),
.div_dout_data (div_dout_data ),
//divu
.divu_divisor_data (divu_divisor_data ),
.divu_divisor_valid (divu_divisor_valid ),
.divu_divisor_ready (divu_divisor_ready ),
.divu_dividend_data (divu_dividend_data ),
.divu_dividend_valid(divu_dividend_valid),
.divu_dividend_ready(divu_dividend_ready),
.divu_dout_valid (divu_dout_valid ),
.divu_dout_data (divu_dout_data )
);
// MEM stage
mem_stage mem_stage(

View File

@@ -24,14 +24,32 @@ module exe_stage(
//from ms
input [`MS_TO_ES_BUS_WD -1:0] ms_to_ds_bus ,
//from ws
input [`WS_TO_ES_BUS_WD -1:0] ws_to_ds_bus
input [`WS_TO_ES_BUS_WD -1:0] ws_to_ds_bus ,
//div
output [31:0] div_divisor_data ,
output div_divisor_valid ,
input div_divisor_ready ,
output [31:0] div_dividend_data ,
output div_dividend_valid ,
input div_dividend_ready ,
input div_dout_valid ,
input [63:0] div_dout_data ,
//divu
output [31:0] divu_divisor_data ,
output divu_divisor_valid ,
input divu_divisor_ready ,
output [31:0] divu_dividend_data ,
output divu_dividend_valid ,
input divu_dividend_ready ,
input divu_dout_valid ,
input [63:0] divu_dout_data
);
reg es_valid ;
wire es_ready_go ;
reg [`DS_TO_ES_BUS_WD -1:0] ds_to_es_bus_r;
wire [11:0] es_alu_op;
wire [18:0] es_alu_op;
wire es_src1_is_pc;
wire es_src2_is_imm;
wire es_src2_is_4;
@@ -56,8 +74,7 @@ module exe_stage(
wire es_src2_is_ms_dest;
wire es_data_is_rf_wdata;
assign {es_alu_op , //169:155
assign {es_alu_op , //173:155
es_src1_is_pc , //154:154
es_src2_is_imm , //153:153
es_src2_is_4 , //152:152
@@ -93,6 +110,26 @@ module exe_stage(
wire es_Sign ;
wire es_Overflow ;
wire es_Zero ;
wire [31:0] es_result ;
reg div_divisor_valid_reg;
reg div_divisor_ready_flag;
reg div_dividend_valid_reg;
reg div_dividend_ready_flag;
reg divu_divisor_valid_reg;
reg divu_divisor_ready_flag;
reg divu_dividend_valid_reg;
reg divu_dividend_ready_flag;
wire es_inst_divw ;
wire es_inst_modw ;
wire es_inst_divwu;
wire es_inst_modwu;
wire is_div_mod;
wire [31:0] div_mod_result;
assign es_result = is_div_mod ? div_mod_result : es_alu_result;
assign es_to_ms_bus = {br_target , //120:89
es_branch_op , //88 :80
@@ -104,7 +141,7 @@ module exe_stage(
es_mem_to_reg , //70 :70
es_reg_we , //69 :69
es_dest , //68 :64
es_alu_result , //63 :32
es_result , //63 :32
es_pc //31 :0
};
@@ -114,7 +151,7 @@ module exe_stage(
es_mem_we
};
assign es_ready_go = 1'b1;
assign es_ready_go = (is_div_mod && !(div_dout_valid || divu_dout_valid)) ? 1'b1 : 1'b0;
assign es_allowin = !es_valid || es_ready_go && ms_allowin;
assign es_to_ms_valid = es_valid && es_ready_go;
always @(posedge clk) begin
@@ -140,8 +177,95 @@ module exe_stage(
es_src2_is_ms_dest ? ws_rf_wdata :
es_rf_rdata2;
assign is_div_mod = es_inst_divw | es_inst_modw | es_inst_divwu | es_inst_modwu;
assign es_inst_divw = es_alu_op[15];
assign es_inst_modw = es_alu_op[16];
assign es_inst_divwu = es_alu_op[17];
assign es_inst_modwu = es_alu_op[18];
assign div_divisor_data = es_alu_src1;
assign div_dividend_data = es_alu_src2;
assign divu_divisor_data = es_alu_src1;
assign divu_dividend_data = es_alu_src2;
always @(posedge clk) begin
if(reset) begin
div_divisor_valid_reg <= 0'b0;
div_divisor_ready_flag <= 0'b0;
end
else if(div_divisor_valid_reg && div_divisor_ready) begin
div_divisor_valid_reg <= 0'b0;
div_divisor_ready_flag <= 0'b1;
end
else if((es_inst_divw || es_inst_modw) && !div_divisor_ready_flag) begin
div_divisor_valid_reg <= 0'b1;
end
else if(es_ready_go) begin
div_divisor_ready_flag <= 1'b0;
end
end
always @(posedge clk) begin
if(reset) begin
div_dividend_valid_reg <= 0'b0;
div_dividend_ready_flag <= 0'b0;
end
else if(div_dividend_valid_reg && div_dividend_ready) begin
div_dividend_valid_reg <= 0'b0;
div_dividend_ready_flag <= 0'b1;
end
else if((es_inst_divw || es_inst_modw) && !div_dividend_ready_flag) begin
div_dividend_valid_reg <= 0'b1;
end
else if(es_ready_go) begin
div_dividend_ready_flag <= 1'b0;
end
end
always @(posedge clk) begin
if(reset) begin
divu_divisor_valid_reg <= 0'b0;
divu_divisor_ready_flag <= 0'b0;
end
else if(divu_divisor_valid_reg && divu_divisor_ready) begin
divu_divisor_valid_reg <= 0'b0;
divu_divisor_ready_flag <= 0'b1;
end
else if((es_inst_divw || es_inst_modw) && !divu_divisor_ready_flag) begin
divu_divisor_valid_reg <= 0'b1;
end
else if(es_ready_go) begin
divu_divisor_ready_flag <= 1'b0;
end
end
always @(posedge clk) begin
if(reset) begin
divu_dividend_valid_reg <= 0'b0;
divu_dividend_ready_flag <= 0'b0;
end
else if(divu_dividend_valid_reg && divu_dividend_ready) begin
divu_dividend_valid_reg <= 0'b0;
divu_dividend_ready_flag <= 0'b1;
end
else if((es_inst_divw || es_inst_modw) && !divu_dividend_ready_flag) begin
divu_dividend_valid_reg <= 0'b1;
end
else if(es_ready_go) begin
divu_dividend_ready_flag <= 1'b0;
end
end
assign div_divisor_valid = div_divisor_valid_reg;
assign div_dividend_valid = div_dividend_valid_reg;
assign divu_divisor_valid = divu_divisor_valid_reg;
assign divu_dividend_valid = divu_dividend_valid_reg;
assign div_mod_result = es_inst_divw ? div_dout_data[63:32] :
es_inst_modw ? div_dout_data[31: 0] :
es_inst_divwu ? divu_dout_data[63:32] :
es_inst_modwu ? divu_dout_data[31: 0] :
32'b0;
alu u_alu(
.alu_op (es_alu_op ),
.alu_op (es_alu_op[14:0]),
.alu_src1 (es_alu_src1 ),
.alu_src2 (es_alu_src2 ),
.alu_result (es_alu_result),

View File

@@ -31,7 +31,7 @@ module forward(
wire data_is_rf_wdata;
assign {ds_rf_raddr1, ds_rf_raddr2 } = ds_to_fw_bus_r;
assign {es_rf_rdata2, es_dest, es_reg_we, es_mem_we} = es_to_fw_bus_r;
assign {es_rf_raddr2, es_dest, es_reg_we, es_mem_we} = es_to_fw_bus_r;
assign {ms_dest , ms_reg_we} = ms_to_fw_bus_r;
assign fw_to_es_bus = {src1_is_es_dest , //4:4

View File

@@ -40,7 +40,7 @@ module id_stage(
rf_wdata //31:0
} = ws_to_rf_bus;
wire [14:0] alu_op;
wire [18:0] alu_op;
wire src1_is_pc;
wire src2_is_imm;
wire src2_is_4;
@@ -84,6 +84,10 @@ module id_stage(
wire inst_sraw;
wire inst_slliw;
wire inst_srliw;
wire inst_sraiw;
wire inst_mulw;
wire inst_mulhw;
wire inst_mulhwu;
wire inst_beq;
wire inst_bne;
wire inst_blt;
@@ -101,6 +105,12 @@ module id_stage(
wire inst_stb;
wire inst_sth;
wire inst_stw;
wire inst_divw;
wire inst_modw;
wire inst_divwu;
wire inst_modwu;
wire dst_is_r1;
@@ -113,7 +123,7 @@ module id_stage(
wire rj_lt_rd;
wire rj_ltu_rd;
assign ds_to_es_bus = {alu_op , //169:155
assign ds_to_es_bus = {alu_op , //173:155
src1_is_pc , //154:154
src2_is_imm , //153:153
src2_is_4 , //152:152
@@ -177,6 +187,10 @@ module id_stage(
assign inst_mulw = (op[21: 5] == 12'b0000_0000_0001) & op17_d[5'b11000];
assign inst_mulhw = (op[21: 5] == 12'b0000_0000_0001) & op17_d[5'b11001];
assign inst_mulhwu = (op[21: 5] == 12'b0000_0000_0001) & op17_d[5'b11010];
assign inst_divw = (op[21: 5] == 12'b0000_0000_0010) & op17_d[5'b00000];
assign inst_modw = (op[21: 5] == 12'b0000_0000_0010) & op17_d[5'b00001];
assign inst_divwu = (op[21: 5] == 12'b0000_0000_0010) & op17_d[5'b00010];
assign inst_modwu = (op[21: 5] == 12'b0000_0000_0010) & op17_d[5'b00011];
assign inst_slti = (op[21:11] == 7'b0000_001 ) & op10_d[3'b000];
assign inst_sltui = (op[21:11] == 7'b0000_001 ) & op10_d[3'b001];
assign inst_addiw = (op[21:11] == 7'b0000_001 ) & op10_d[3'b010];
@@ -203,9 +217,6 @@ module id_stage(
assign inst_bltu = (op[21:15] == 3'b011 ) & op6_d[3'b010];
assign inst_bgeu = (op[21:15] == 3'b011 ) & op6_d[3'b011];
assign alu_op[ 0] = inst_addw | inst_addiw | inst_pcaddu12i | inst_ldb | inst_ldh | inst_ldbu | inst_ldhu | inst_ldw | inst_stb | inst_sth | inst_stw | inst_bl | inst_jirl;
assign alu_op[ 1] = inst_subw;
assign alu_op[ 2] = inst_slt | inst_slti;
@@ -221,6 +232,10 @@ module id_stage(
assign alu_op[12] = inst_mulw;
assign alu_op[13] = inst_mulhw;
assign alu_op[14] = inst_mulhwu;
assign alu_op[15] = inst_divw;
assign alu_op[16] = inst_modw;
assign alu_op[17] = inst_divwu;
assign alu_op[18] = inst_modwu;
assign imm = {32{inst_slti | inst_sltui | inst_addiw | inst_ldb | inst_ldh | inst_ldw | inst_stb | inst_sth | inst_stw | inst_ldbu | inst_ldhu}} & {{20{ds_inst[21]}}, ds_inst[21:10]}
| {32{inst_beq | inst_bne | inst_bge | inst_bgeu | inst_blt | inst_bltu | inst_jirl}} & {{14{ds_inst[25]}}, ds_inst[25:10], 2'b0}

View File

@@ -3,7 +3,7 @@
`define BR_BUS_WD 33
`define FS_TO_DS_BUS_WD 64
`define DS_TO_ES_BUS_WD 170
`define DS_TO_ES_BUS_WD 174
`define ES_TO_MS_BUS_WD 121
`define MS_TO_WS_BUS_WD 70
`define WS_TO_RF_BUS_WD 38

View File

@@ -33,7 +33,25 @@ module soc_lite_top
wire [31:0] cpu_data_addr;
wire [31:0] cpu_data_wdata;
wire [31:0] cpu_data_rdata;
//div
wire [31:0] div_divisor_data;
wire div_divisor_valid;
wire div_divisor_ready;
wire [31:0] div_dividend_data;
wire div_dividend_valid;
wire div_dividend_ready;
wire div_dout_valid;
wire [63:0] div_dout_data;
//divu
wire [31:0] divu_divisor_data;
wire divu_divisor_valid;
wire divu_divisor_ready;
wire [31:0] divu_dividend_data;
wire divu_dividend_valid;
wire divu_dividend_ready;
wire divu_dout_valid;
wire [63:0] divu_dout_data;
//cpu
mycpu_top cpu(
.clk (cpu_clk ),
@@ -51,6 +69,25 @@ module soc_lite_top
.data_sram_wdata (cpu_data_wdata),
.data_sram_rdata (cpu_data_rdata),
//div
.div_divisor_data (div_divisor_data ),
.div_divisor_valid (div_divisor_valid ),
.div_divisor_ready (div_divisor_ready ),
.div_dividend_data (div_dividend_data ),
.div_dividend_valid (div_dividend_valid ),
.div_dividend_ready (div_dividend_ready ),
.div_dout_valid (div_dout_valid ),
.div_dout_data (div_dout_data ),
//divu
.divu_divisor_data (divu_divisor_data ),
.divu_divisor_valid (divu_divisor_valid ),
.divu_divisor_ready (divu_divisor_ready ),
.divu_dividend_data (divu_dividend_data ),
.divu_dividend_valid(divu_dividend_valid),
.divu_dividend_ready(divu_dividend_ready),
.divu_dout_valid (divu_dout_valid ),
.divu_dout_data (divu_dout_data ),
//debug
.debug_wb_pc (debug_wb_pc ),
.debug_wb_rf_wen (debug_wb_rf_wen ),
@@ -84,6 +121,32 @@ module soc_lite_top
.dina (cpu_data_wdata ), //31:0
.douta (cpu_data_rdata ) //31:0
);
//div
div div(
.aclk (cpu_clk ),
.s_axis_divisor_tdata (div_divisor_data ),
.s_axis_divisor_tvalid (div_divisor_valid ),
.s_axis_divisor_tready (div_divisor_ready ),
.s_axis_dividend_tdata (div_dividend_data ),
.s_axis_dividend_tvalid (div_dividend_valid ),
.s_axis_dividend_tready (div_dividend_ready ),
.m_axis_dout_tvalid (div_dout_valid ),
.m_axis_dout_tdata (div_dout_data )
);
//divu
divu divu(
.aclk (cpu_clk ),
.s_axis_divisor_tdata (divu_divisor_data ),
.s_axis_divisor_tvalid (divu_divisor_valid ),
.s_axis_divisor_tready (divu_divisor_ready ),
.s_axis_dividend_tdata (divu_dividend_data ),
.s_axis_dividend_tvalid (divu_dividend_valid),
.s_axis_dividend_tready (divu_dividend_ready),
.m_axis_dout_tvalid (divu_dout_valid ),
.m_axis_dout_tdata (divu_dout_data )
);
`endif
endmodule