Verilog MIPS32 CPU(六)-- MDU

 

 

module MDU(
        input clk,rst,
        input [2:0] mdu,
        input [31:0] rdata1,rdata2,
        output [63:0] mul_out,
        output reg pc_ena,
        output reg [31:0] hi,lo);
    
    wire div_start,divu_start,div_busy,divu_busy,div_over,divu_over;
    wire [63:0] mult_out,multu_out,div_out,divu_out;
    
    assign    mul_out    =    mult_out;
    /*
        1    mult
        2    multu
        3    div    
        4    divu
        5    mthi
        6    mtlo
    */
    //assign pc_ena=1'b1;
    
    always@(*)begin
        case(mdu)
            3'h3:    pc_ena    =    div_over ||mdu!=3'h3;
            3'h4:    pc_ena    =    divu_over||mdu!=3'h4;
            default:pc_ena    =    1'b1;
        endcase
    end
    
    assign    div_start    =    mdu==3'h3&&!div_busy;
    assign    divu_start    =    mdu==3'h4&&!divu_busy;
    
    always@(posedge clk or posedge rst)begin
        if(rst) begin
            hi<=32'b0;
            lo<=32'b0;
        end
        else begin
            case(mdu)
                3'h1:    {hi,lo}    <=    mult_out;
                3'h2:    {hi,lo}    <=    multu_out;
                3'h3:    {lo,hi}    <=    div_out;
                3'h4:    {lo,hi}    <=    divu_out;
                3'h5:    hi         <=    rdata1;
                3'h6:    lo        <=    rdata1;
            endcase
        end 
    end
    mult_gen_0 multiplier(
        .A(rdata1),
        .B(rdata2),
        .P(mult_out));
    
    mult_gen_1 multiplier_unsigned(
        .A(rdata1),
        .B(rdata2),
        .P(multu_out));
    
    DIV DIV(
        .dividend(rdata1),
        .divisor(rdata2),
        .clock(clk),
        .reset(mdu!=3'h3),
        .start(div_start),
        .q(div_out[63:32]),
        .r(div_out[31:0]),
        .over(div_over),
        .busy(div_busy));
    
    DIVU DIVU(
        .dividend(rdata1),
        .divisor(rdata2),
        .clock(clk),
        .reset(mdu!=3'h4),
        .start(divu_start),
        .q(divu_out[63:32]),
        .r(divu_out[31:0]),
        .over(divu_over),
        .busy(divu_busy));
endmodule

 

posted @ 2017-10-01 09:54  liutianchen  阅读(1882)  评论(0编辑  收藏  举报