OpenCores
URL https://opencores.org/ocsvn/aor3000/aor3000/trunk

Subversion Repositories aor3000

[/] [aor3000/] [trunk/] [rtl/] [block/] [block_muldiv.v] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 alfik
/*
2
 * This file is subject to the terms and conditions of the BSD License. See
3
 * the file "LICENSE" in the main directory of this archive for more details.
4
 *
5
 * Copyright (C) 2014 Aleksander Osman
6
 */
7
 
8
`include "defines.v"
9
 
10
module block_muldiv(
11
    input               clk,
12
    input               rst_n,
13
 
14
    input       [6:0]   exe_cmd_for_muldiv,
15
    input       [31:0]  exe_a,
16
    input       [31:0]  exe_b,
17
    input       [4:0]   exe_instr_rd,
18
 
19
    output              muldiv_busy,
20
 
21
    output      [4:0]   muldiv_result_index,
22
    output      [31:0]  muldiv_result
23
); /* verilator public_module */
24
 
25
//------------------------------------------------------------------------------ lo, hi, busy
26
 
27
reg [31:0] hi;
28
always @(posedge clk or negedge rst_n) begin
29
    if(rst_n == 1'b0)                               hi <= 32'd0;
30
    else if(exe_cmd_for_muldiv == `CMD_muldiv_mthi) hi <= exe_a;
31
    else if(mult_ready)                             hi <= mult_result[63:32];
32
    else if(div_ready && div_busy)                  hi <= div_remainder;
33
end
34
 
35
reg [31:0] lo;
36
always @(posedge clk or negedge rst_n) begin
37
    if(rst_n == 1'b0)                               lo <= 32'd0;
38
    else if(exe_cmd_for_muldiv == `CMD_muldiv_mtlo) lo <= exe_a;
39
    else if(mult_ready)                             lo <= mult_result[31:0];
40
    else if(div_ready && div_busy)                  lo <= div_quotient;
41
end
42
 
43
reg busy;
44
always @(posedge clk or negedge rst_n) begin
45
    if(rst_n == 1'b0)                                                                                   busy <= `FALSE;
46
    else if(exe_cmd_for_muldiv == `CMD_muldiv_mfhi || exe_cmd_for_muldiv == `CMD_muldiv_mflo || busy)   busy <= mult_busy || div_busy;
47
end
48
 
49
wire muldiv_busy_start = ((exe_cmd_for_muldiv == `CMD_muldiv_mfhi || exe_cmd_for_muldiv == `CMD_muldiv_mflo) && (mult_busy || div_busy));
50
 
51
assign muldiv_busy = muldiv_busy_start || busy;
52
 
53
reg [4:0] muldiv_index_value;
54
always @(posedge clk or negedge rst_n) begin
55
    if(rst_n == 1'b0)                       muldiv_index_value <= 5'd0;
56
    else if(muldiv_busy_start)              muldiv_index_value <= exe_instr_rd;
57
    else if(~(mult_busy) && ~(div_busy))    muldiv_index_value <= 5'd0;
58
end
59
 
60
reg muldiv_index_type_is_lo;
61
always @(posedge clk or negedge rst_n) begin
62
    if(rst_n == 1'b0)                                                                           muldiv_index_type_is_lo <= `FALSE;
63
    else if(exe_cmd_for_muldiv == `CMD_muldiv_mfhi || exe_cmd_for_muldiv == `CMD_muldiv_mflo)   muldiv_index_type_is_lo <= exe_cmd_for_muldiv == `CMD_muldiv_mflo;
64
end
65
 
66
assign muldiv_result_index =
67
    (muldiv_busy && (~(busy) || mult_busy || div_busy))?                                    5'd0 :
68
    (exe_cmd_for_muldiv == `CMD_muldiv_mfhi || exe_cmd_for_muldiv == `CMD_muldiv_mflo)?     exe_instr_rd :
69
                                                                                            muldiv_index_value;
70
assign muldiv_result =
71
    (exe_cmd_for_muldiv == `CMD_muldiv_mfhi)?   hi :
72
    (exe_cmd_for_muldiv == `CMD_muldiv_mflo)?   lo :
73
    (muldiv_index_type_is_lo)?                  lo :
74
                                                hi;
75
 
76
//------------------------------------------------------------------------------ multiply
77
 
78
wire mult_busy = mult_counter > 2'd0;
79
wire mult_ready= mult_counter == 2'd1;
80
 
81
reg [1:0] mult_counter;
82
always @(posedge clk or negedge rst_n) begin
83
    if(rst_n == 1'b0)                                                                           mult_counter <= 2'd0;
84
    else if(exe_cmd_for_muldiv == `CMD_muldiv_mult || exe_cmd_for_muldiv == `CMD_muldiv_multu)  mult_counter <= 2'd2;
85
    else if(mult_counter != 2'd0)                                                               mult_counter <= mult_counter - 2'd1;
86
end
87
 
88
wire [65:0] mult_result;
89
 
90
model_mult
91
#(
92
    .widtha     (33),
93
    .widthb     (33),
94
    .widthp     (66)
95
)
96
model_mult_inst(
97
    .clk        (clk),
98
    .a          ((exe_cmd_for_muldiv == `CMD_muldiv_mult)? { exe_a[31], exe_a[31:0] } : { 1'b0, exe_a[31:0] }),
99
    .b          ((exe_cmd_for_muldiv == `CMD_muldiv_mult)? { exe_b[31], exe_b[31:0] } : { 1'b0, exe_b[31:0] }),
100
    .out        (mult_result)
101
);
102
 
103
//------------------------------------------------------------------------------ divide
104
 
105
reg div_busy;
106
always @(posedge clk or negedge rst_n) begin
107
    if(rst_n == 1'b0)                                                                       div_busy <= `FALSE;
108
    else if(exe_cmd_for_muldiv ==`CMD_muldiv_div || exe_cmd_for_muldiv == `CMD_muldiv_divu) div_busy <= `TRUE;
109
    else if(div_ready)                                                                      div_busy <= `FALSE;
110
end
111
 
112
wire        div_ready;
113
wire [31:0] div_quotient;
114
wire [31:0] div_remainder;
115
 
116
block_long_div block_long_div_inst(
117
    .clk        (clk),
118
    .rst_n      (rst_n),
119
 
120
    .start      (exe_cmd_for_muldiv == `CMD_muldiv_div || exe_cmd_for_muldiv == `CMD_muldiv_divu),  //input
121
    .dividend   ({ exe_cmd_for_muldiv == `CMD_muldiv_div & exe_a[31], exe_a[31:0] }),               //input [32:0]
122
    .divisor    ({ exe_cmd_for_muldiv == `CMD_muldiv_div & exe_b[31], exe_b[31:0] }),               //input [32:0]
123
 
124
    .ready      (div_ready),                                                    //output
125
    .quotient   (div_quotient),                                                 //output [31:0]
126
    .remainder  (div_remainder)                                                 //output [31:0]
127
);
128
 
129
//------------------------------------------------------------------------------
130
// synthesis translate_off
131
wire _unused_ok = &{ 1'b0, mult_result[65:64],  1'b0 };
132
// synthesis translate_on
133
//------------------------------------------------------------------------------
134
 
135
 
136
endmodule

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.