enable the receiving operands

This commit is contained in:
zeeshanrafique23 2021-07-12 11:41:38 +05:00
parent 76b9169d70
commit 45e0b4b98b
7 changed files with 80 additions and 188 deletions

View file

@ -3,7 +3,7 @@
/* Multiplication Division Unit */
module mdu_top
#(
parameter WIDTH = 1
parameter WIDTH = 32
)(
input wire i_clk,
input wire i_rst,
@ -14,8 +14,8 @@ module mdu_top
output reg o_mdu_ready,
output wire [WIDTH-1:0] o_mdu_rd
);
wire [31:0] rdata_a;
wire [31:0] rdata_b;
reg [31:0] rdata_a;
reg [31:0] rdata_b;
reg [31:0] rs1_d, rs1_q;
reg [31:0] rs2_d, rs2_q;
reg [ 4:0] cnt_d, cnt_q;
@ -24,115 +24,13 @@ module mdu_top
reg [31:0] temp;
reg [63:0] result_64;
reg [31:0] result_32;
/* FSM starts*/
parameter RESET = 3'b000;
parameter IDLE = 3'b001;
parameter GET = 3'b010;
parameter BUSY = 3'b011;
parameter SEND = 3'b100;
reg [2:0] fsm_cs, fsm_ns;
reg valid_d, valid_q;
always @(*) begin
en_d = 1'b1;
o_mdu_rd =1'b0;
cnt_d = cnt_q;
fsm_ns = fsm_cs;
case (fsm_cs)
RESET: begin
o_mdu_rd = 1'b0;
cnt_d = 5'b0;
end
IDLE: begin
cnt_d = 5'b0;
valid_d = 1'b1;
if (i_mdu_valid) begin
fsm_ns = GET;
end else begin
fsm_ns = IDLE;
end
end
GET: begin
if (&cnt_q) begin
fsm_ns = BUSY;
end else begin
rs1_d = {rs1_q[30:0], i_mdu_rs1};
rs2_d = {rs2_q[30:0], i_mdu_rs2};
en_d = 1'b0;
cnt_d += 1'b1;
fsm_ns = GET;
end
end
BUSY: begin
valid_d = 1'b0;
fsm_ns = SEND;
end
SEND: begin
valid_d = 1'b1;
if (&cnt_q) begin
fsm_ns = IDLE;
end else begin
if (done) begin
temp = result_32;
end else begin
o_mdu_rd = temp[31];
temp = {temp[30:0],1'b0};
cnt_d += 1'b1;
fsm_ns = SEND;
end
end
end
default: begin
o_mdu_rd = 1'b0;
fsm_ns = IDLE;
end
endcase
end
assign rdata_a = i_mdu_rs1;
assign rdata_b = i_mdu_rs2;
always @(posedge i_clk) begin
if (i_rst) begin
rs1_q <= 32'b0;
rs2_q <= 32'b0;
cnt_q <= 5'b0;
valid_q <= 1'b0;
en_q <= 1'b0;
fsm_cs <= RESET;
end else begin
rs1_q <= rs1_d;
rs2_q <= rs2_d;
cnt_q <= cnt_d;
valid_q <= valid_d;
en_q <= en_d;
fsm_cs <= fsm_ns;
end
en_q <= i_mdu_valid;
end
/* FSM ends*/
/*
always @(posedge i_clk) begin
if (i_rst) begin
rs1 <= 32'b0;
rs2 <= 32'b0;
cnt <= 5'b0;
en <= 1'b0;
end else if (i_mdu_valid | (!(&cnt))) begin
rs1 <= {rs1[30:0], i_mdu_rs1};
rs2 <= {rs2[30:0], i_mdu_rs2};
en <= 1'b0;
cnt <= cnt + 1'b1;
end
if (&cnt) begin
cnt <= 5'b0;
en <= 1'b1;
o_mdu_ready = 1'b0;
end
end
*/
assign rdata_a = en_q ? rs1_q : 32'b0;
assign rdata_b = en_q ? rs2_q : 32'b0;
always @(posedge i_clk) begin
if (i_rst) begin
@ -140,16 +38,17 @@ module mdu_top
o_mdu_ready = 1'b0;
result_32 = 32'b0;
result_64 = 64'b0;
// en_q = 1'b0;
end else begin
o_mdu_ready = 1'b1;
o_mdu_ready = 1'b0;
result_32 = 32'hffffffff;
result_64 = {result_32,result_32};
case (i_mdu_op)
3'b000: begin // MUL
if (en_q) begin
3'b000: begin
if (en_q) begin // MUL
result_64 = rdata_a * rdata_b;
result_32 = result_64[31:0];
o_mdu_ready = 1'b1;
o_mdu_ready = en_q;
done = 1'b1;
end
end
@ -157,7 +56,7 @@ module mdu_top
if (en_q) begin
result_64 = $signed(rdata_a) * $signed(rdata_b);
result_32 = result_64[63:32];
o_mdu_ready = 1'b1;
o_mdu_ready = en_q;
done = 1'b1;
end
end
@ -165,7 +64,7 @@ module mdu_top
if (en_q) begin
result_64 = $signed(rdata_a) * $unsigned(rdata_b);
result_32 = result_64[63:32];
o_mdu_ready = 1'b1;
o_mdu_ready = en_q;
done = 1'b1;
end
end
@ -173,7 +72,7 @@ module mdu_top
if (en_q) begin
result_64 = $unsigned(rdata_a) * $unsigned(rdata_b);
result_32 = result_64[63:32];
o_mdu_ready = 1'b1;
o_mdu_ready = en_q;
done = 1'b1;
end
end
@ -181,7 +80,7 @@ module mdu_top
if (en_q) begin
result_32 = $signed(rdata_a) / $signed(rdata_b);
// result_32 = result_64[31:0];
o_mdu_ready = 1'b1;
o_mdu_ready = en_q;
done = 1'b1;
end
end
@ -189,7 +88,7 @@ module mdu_top
if (en_q) begin
result_32 = $unsigned(rdata_a) * $unsigned(rdata_b);
// result_32 = result_64[31:0];
o_mdu_ready = 1'b1;
o_mdu_ready = en_q;
done = 1'b1;
end
end
@ -197,7 +96,7 @@ module mdu_top
if (en_q) begin
result_32 = $signed(rdata_a) % $signed(rdata_b);
// result_32 = result_64[31:0];
o_mdu_ready = 1'b1;
o_mdu_ready = en_q;
done = 1'b1;
end
end
@ -205,19 +104,20 @@ module mdu_top
if (en_q) begin
result_32 = $unsigned(rdata_a) % $unsigned(rdata_b);
// result_32 = result_64[31:0];
o_mdu_ready = 1'b1;
o_mdu_ready = en_q;
done = 1'b1;
end
end
default: begin
result_32 = 32'hffffffff;
result_64 = {result_32,result_32};
o_mdu_ready = 1'b1;
o_mdu_ready = 1'b0;
end
endcase
end
end
// TODO: Set the transmission side from core part
assign o_mdu_rd = result_32;
endmodule
`default_nettype wire
`default_nettype wire

View file

@ -6,7 +6,8 @@ module serv_bufreg
input wire i_cnt1,
input wire i_en,
input wire i_init,
output reg [1:0] o_lsb,
input wire i_mdu_en,
output wire [1:0] o_lsb,
//Control
input wire i_rs1_en,
input wire i_imm_en,
@ -17,11 +18,13 @@ module serv_bufreg
input wire i_imm,
output wire o_q,
//External
output wire [31:0] o_dbus_adr);
output wire [31:0] o_dbus_adr,
output wire [31:0] o_mdu_rs1);
wire c, q;
reg c_r;
reg [31:2] data;
reg [1:0] lsb;
wire clr_lsb = i_cnt0 & i_clr_lsb;
@ -35,11 +38,12 @@ module serv_bufreg
data <= {i_init ? q : (data[31] & i_sh_signed), data[31:3]};
if (i_init ? (i_cnt0 | i_cnt1) : i_en)
o_lsb <= {i_init ? q : data[2],o_lsb[1]};
lsb <= {i_init ? q : data[2],lsb[1]};
end
assign o_q = o_lsb[0] & i_en;
assign o_q = lsb[0] & i_en;
assign o_dbus_adr = {data, 2'b00};
assign o_mdu_rs1 = {o_dbus_adr[31:2],lsb};
assign o_lsb = i_mdu_en ? 2'b00 : lsb;
endmodule

View file

@ -17,6 +17,8 @@ module serv_decode #(
output reg o_shift_op,
output reg o_slt_op,
output reg o_rd_op,
output reg o_mdu_op,
output reg [2:0] o_mdu_opcode,
//To bufreg
output reg o_bufreg_rs1_en,
output reg o_bufreg_imm_en,
@ -61,8 +63,13 @@ module serv_decode #(
reg op22;
reg op26;
reg imm25;
reg imm30;
//mdu
wire co_mdu_op = ((opcode == 5'b01100) & imm25);
wire [2:0]co_mdu_opcode = funct3;
//opcode
wire op_or_opimm = (!opcode[4] & opcode[2] & !opcode[0]);
@ -190,7 +197,7 @@ module serv_decode #(
wire co_mem_cmd = opcode[3];
wire co_mem_signed = ~funct3[2];
wire co_mem_word = funct3[1];
wire co_mem_word = co_mdu_op ? co_mdu_op :funct3[1];
wire co_mem_half = funct3[0];
wire [1:0] co_alu_bool_op = funct3[1:0];
@ -229,6 +236,7 @@ module serv_decode #(
if (i_wb_en) begin
funct3 <= i_wb_rdt[14:12];
imm30 <= i_wb_rdt[30];
imm25 <= i_wb_rdt[25];
opcode <= i_wb_rdt[6:2];
op20 <= i_wb_rdt[20];
op21 <= i_wb_rdt[21];
@ -248,6 +256,8 @@ module serv_decode #(
o_shift_op = co_shift_op;
o_slt_op = co_slt_op;
o_rd_op = co_rd_op;
o_mdu_op = co_mdu_op;
o_mdu_opcode = co_mdu_opcode;
o_bufreg_rs1_en = co_bufreg_rs1_en;
o_bufreg_imm_en = co_bufreg_imm_en;
o_bufreg_clr_lsb = co_bufreg_clr_lsb;
@ -285,6 +295,7 @@ module serv_decode #(
always @(*) begin
funct3 = i_wb_rdt[14:12];
imm30 = i_wb_rdt[30];
imm25 = i_wb_rdt[25];
opcode = i_wb_rdt[6:2];
op20 = i_wb_rdt[20];
op21 = i_wb_rdt[21];
@ -304,6 +315,8 @@ module serv_decode #(
o_shift_op <= co_shift_op;
o_slt_op <= co_slt_op;
o_rd_op <= co_rd_op;
o_mdu_op <= co_mdu_op;
o_mdu_opcode <= co_mdu_opcode;
o_bufreg_rs1_en <= co_bufreg_rs1_en;
o_bufreg_imm_en <= co_bufreg_imm_en;
o_bufreg_clr_lsb <= co_bufreg_clr_lsb;

View file

@ -36,9 +36,6 @@ module serv_rf_if
input wire i_csr_rd,
input wire i_rd_csr_en,
input wire i_mem_rd,
`ifdef MDU
input wire i_mdu_rd,
`endif
//RS1 read port
input wire [4:0] i_rs1_raddr,
@ -56,17 +53,10 @@ module serv_rf_if
generate
if (WITH_CSR) begin
`ifdef MDU
wire rd = (i_ctrl_rd ) |
(i_alu_rd & i_rd_alu_en) |
(i_csr_rd & i_rd_csr_en) |
(i_mem_rd) | (i_mdu_rd);
`else
wire rd = (i_ctrl_rd ) |
(i_alu_rd & i_rd_alu_en) |
(i_csr_rd & i_rd_csr_en) |
(i_mem_rd);
`endif
wire mtval = i_mem_op ? i_bufreg_q : i_bad_pc;
@ -129,15 +119,10 @@ module serv_rf_if
assign o_csr_pc = i_rdata1;
end else begin
`ifdef MDU
wire rd = (i_ctrl_rd ) |
(i_alu_rd & i_rd_alu_en) |
(i_mem_rd) | (i_mdu_rd);
`else
wire rd = (i_ctrl_rd ) |
(i_alu_rd & i_rd_alu_en) |
(i_mem_rd);
`endif
assign o_wdata0 = rd;
assign o_wdata1 = 1'b0;

View file

@ -80,12 +80,11 @@ module serv_rf_top
wire [RF_WIDTH-1:0] rdata;
`ifdef MDU
wire mdu_rs1;
wire mdu_rs2;
wire [2:0] mdu_op;
wire mdu_valid;
wire mdu_ready;
wire mdu_rd;
wire [2:0] mdu_op;
wire mdu_valid;
wire mdu_ready;
wire [31:0] mdu_rs1;
wire [31:0] mdu_rd;
`endif
serv_rf_ram_if
@ -130,7 +129,7 @@ module serv_rf_top
(.i_clk(clk),
.i_rst(i_rst),
.i_mdu_rs1(mdu_rs1),
.i_mdu_rs2(mdu_rs2),
.i_mdu_rs2(o_dbus_dat),
.i_mdu_op(mdu_op),
.i_mdu_valid(mdu_valid),
.o_mdu_ready(mdu_ready),
@ -189,20 +188,19 @@ module serv_rf_top
.i_ibus_rdt (i_ibus_rdt),
.i_ibus_ack (i_ibus_ack),
`ifdef MDU
.o_mdu_rs1 (mdu_rs1),
.o_mdu_rs2 (mdu_rs2),
.o_mdu_op (mdu_op),
.o_mdu_opcode (mdu_op),
.o_mdu_valid (mdu_valid),
.i_mdu_ready (mdu_ready),
.i_mdu_rd (mdu_rd),
// .i_mdu_rd (mdu_rd),
`endif
.o_dbus_adr (o_dbus_adr),
.o_dbus_dat (o_dbus_dat),
.o_dbus_sel (o_dbus_sel),
.o_dbus_we (o_dbus_we),
.o_dbus_cyc (o_dbus_cyc),
.i_dbus_rdt (i_dbus_rdt),
.i_dbus_ack (i_dbus_ack));
.i_dbus_rdt (mdu_ready ? mdu_rd:i_dbus_rdt),
.i_dbus_ack (i_dbus_ack | mdu_ready),
.o_mdu_rs1 (mdu_rs1));
endmodule
`default_nettype wire

View file

@ -22,6 +22,9 @@ module serv_state
input wire i_slt_op,
input wire i_e_op,
input wire i_rd_op,
input wire i_mdu_op,
output wire o_mdu_valid,
input wire i_mdu_ready,
output wire o_init,
output wire o_cnt_en,
output wire o_cnt0,
@ -75,7 +78,10 @@ module serv_state
wire take_branch = i_branch_op & (!i_cond_branch | (i_alu_cmp^i_bne_or_bge));
//slt*, branch/jump, shift, load/store
wire two_stage_op = i_slt_op | i_mem_op | i_branch_op | i_shift_op;
wire two_stage_op = i_slt_op | i_mem_op | i_branch_op | i_shift_op | i_mdu_op;
//valid signal for mdu
assign o_mdu_valid = i_mdu_op & o_cnt_done;
assign o_dbus_cyc = !o_cnt_en & init_done & i_mem_op & !i_mem_misalign;
@ -87,7 +93,7 @@ module serv_state
// and the first stage didn't cause a misalign exception
assign o_rf_wreq = !misalign_trap_sync &
((i_shift_op & (i_sh_done | !i_sh_right) & !o_cnt_en & init_done) |
(i_mem_op & i_dbus_ack) |
(i_mem_op & i_dbus_ack) | i_mdu_ready |
(stage_two_req & (i_slt_op | i_branch_op)));
assign o_rf_rd_en = i_rd_op & !o_init;

View file

@ -47,12 +47,9 @@ module serv_top
input wire i_rdata0,
input wire i_rdata1,
`ifdef MDU
output reg o_mdu_rs1,
output reg o_mdu_rs2,
output reg [ 2:0] o_mdu_op,
output reg [ 2:0] o_mdu_opcode,
output reg o_mdu_valid,
input wire i_mdu_ready,
input wire i_mdu_rd,
`endif
output wire [31:0] o_ibus_adr,
output wire o_ibus_cyc,
@ -64,7 +61,8 @@ module serv_top
output wire o_dbus_we ,
output wire o_dbus_cyc,
input wire [31:0] i_dbus_rdt,
input wire i_dbus_ack);
input wire i_dbus_ack,
output wire [31:0] o_mdu_rs1);
wire [4:0] rd_addr;
wire [4:0] rs1_addr;
@ -72,7 +70,7 @@ module serv_top
wire [3:0] immdec_ctrl;
wire [3:0] immdec_en;
wire sh_right;
wire bne_or_bge;
wire cond_branch;
@ -83,6 +81,7 @@ module serv_top
wire shift_op;
wire slt_op;
wire rd_op;
wire mdu_op;
wire rd_alu_en;
wire rd_csr_en;
@ -201,6 +200,9 @@ module serv_top
.i_slt_op (slt_op),
.i_e_op (e_op),
.i_rd_op (rd_op),
.i_mdu_op (mdu_op),
.o_mdu_valid (o_mdu_valid),
.i_mdu_ready (i_mdu_ready),
//External
.o_dbus_cyc (o_dbus_cyc),
.i_dbus_ack (i_dbus_ack),
@ -231,6 +233,9 @@ module serv_top
.o_slt_op (slt_op),
.o_rd_op (rd_op),
.o_sh_right (sh_right),
.o_mdu_op (mdu_op),
.o_mdu_opcode (o_mdu_opcode),
//To bufreg
.o_bufreg_rs1_en (bufreg_rs1_en),
.o_bufreg_imm_en (bufreg_imm_en),
@ -296,6 +301,7 @@ module serv_top
.i_cnt1 (cnt1),
.i_en (bufreg_en),
.i_init (init),
.i_mdu_en (mdu_op),
.o_lsb (lsb),
//Control
.i_sh_signed (bufreg_sh_signed),
@ -307,7 +313,8 @@ module serv_top
.i_imm (imm),
.o_q (bufreg_q),
//External
.o_dbus_adr (o_dbus_adr));
.o_dbus_adr (o_dbus_adr),
.o_mdu_rs1 (o_mdu_rs1));
serv_ctrl
#(.RESET_PC (RESET_PC),
@ -393,9 +400,6 @@ module serv_top
.i_csr_rd (csr_rd),
.i_rd_csr_en (rd_csr_en),
.i_mem_rd (mem_rd),
`ifdef MDU
.i_mdu_rd (i_mdu_rd),
`endif
//RS1 read port
.i_rs1_raddr (rs1_addr),
.o_rs1 (rs1),
@ -534,23 +538,5 @@ module serv_top
`endif
`ifdef MDU
wire [4:0] opcode = i_ibus_rdt[6:2];
always @(*) begin
if ((opcode == 5'b01100) & i_ibus_rdt[25]) begin
o_mdu_valid = 1'b1;
end else begin
o_mdu_valid = 1'b0;
end
o_mdu_op = i_ibus_rdt[14:12];
if (i_mdu_ready) begin
o_mdu_rs1 = rs1;
o_mdu_rs2 = rs2;
end
end
`endif
endmodule
`default_nettype wire