1 |
4 |
tomburkeii |
`timescale 1ns / 1ps
|
2 |
|
|
//////////////////////////////////////////////////////////////////////////////////
|
3 |
|
|
// Company:
|
4 |
|
|
// Engineer:
|
5 |
|
|
//
|
6 |
|
|
// Create Date: 19:39:14 08/24/2011
|
7 |
|
|
// Design Name:
|
8 |
|
|
// Module Name: divider
|
9 |
|
|
// Project Name:
|
10 |
|
|
// Target Devices:
|
11 |
|
|
// Tool versions:
|
12 |
|
|
// Description:
|
13 |
|
|
//
|
14 |
|
|
// Dependencies:
|
15 |
|
|
//
|
16 |
|
|
// Revision:
|
17 |
|
|
// Revision 0.01 - File Created
|
18 |
|
|
// Additional Comments: Based on my description on youtube:
|
19 |
|
|
// http://youtu.be/TEnaPMYiuR8
|
20 |
|
|
//
|
21 |
|
|
//////////////////////////////////////////////////////////////////////////////////
|
22 |
|
|
|
23 |
|
|
module qdiv #(
|
24 |
|
|
//Parameterized values
|
25 |
|
|
parameter Q = 15,
|
26 |
|
|
parameter N = 32
|
27 |
|
|
)
|
28 |
|
|
(
|
29 |
|
|
input [N-1:0] i_dividend,
|
30 |
|
|
input [N-1:0] i_divisor,
|
31 |
|
|
input i_start,
|
32 |
|
|
input i_clk,
|
33 |
|
|
output [N-1:0] o_quotient_out,
|
34 |
|
|
output o_complete,
|
35 |
|
|
output o_overflow
|
36 |
|
|
);
|
37 |
|
|
|
38 |
|
|
reg [2*N+Q-3:0] reg_working_quotient; // Our working copy of the quotient
|
39 |
|
|
reg [N-1:0] reg_quotient; // Final quotient
|
40 |
|
|
reg [N-2+Q:0] reg_working_dividend; // Working copy of the dividend
|
41 |
|
|
reg [2*N+Q-3:0] reg_working_divisor; // Working copy of the divisor
|
42 |
|
|
|
43 |
7 |
tomburkeii |
reg [N-1:0] reg_count; // This is obviously a lot bigger than it needs to be, as we only need
|
44 |
8 |
tomburkeii |
// count to N-1+Q but, computing that number of bits requires a
|
45 |
|
|
// logarithm (base 2), and I don't know how to do that in a
|
46 |
|
|
// way that will work for everyone
|
47 |
4 |
tomburkeii |
|
48 |
8 |
tomburkeii |
reg reg_done; // Computation completed flag
|
49 |
|
|
reg reg_sign; // The quotient's sign bit
|
50 |
|
|
reg reg_overflow; // Overflow flag
|
51 |
4 |
tomburkeii |
|
52 |
8 |
tomburkeii |
initial reg_done = 1'b1; // Initial state is to not be doing anything
|
53 |
|
|
initial reg_overflow = 1'b0; // And there should be no woverflow present
|
54 |
|
|
initial reg_sign = 1'b0; // And the sign should be positive
|
55 |
|
|
|
56 |
|
|
initial reg_working_quotient = 0;
|
57 |
|
|
initial reg_quotient = 0;
|
58 |
|
|
initial reg_working_dividend = 0;
|
59 |
|
|
initial reg_working_divisor = 0;
|
60 |
|
|
initial reg_count = 0;
|
61 |
|
|
|
62 |
4 |
tomburkeii |
|
63 |
8 |
tomburkeii |
assign o_quotient_out[N-2:0] = reg_quotient[N-2:0]; // The division results
|
64 |
4 |
tomburkeii |
assign o_quotient_out[N-1] = reg_sign; // The sign of the quotient
|
65 |
|
|
assign o_complete = reg_done;
|
66 |
|
|
assign o_overflow = reg_overflow;
|
67 |
|
|
|
68 |
|
|
always @( posedge i_clk ) begin
|
69 |
|
|
if( reg_done && i_start ) begin // This is our startup condition
|
70 |
|
|
// Need to check for a divide by zero right here, I think....
|
71 |
|
|
reg_done <= 1'b0; // We're not done
|
72 |
8 |
tomburkeii |
reg_count <= N+Q-1; // Set the count
|
73 |
4 |
tomburkeii |
reg_working_quotient <= 0; // Clear out the quotient register
|
74 |
|
|
reg_working_dividend <= 0; // Clear out the dividend register
|
75 |
|
|
reg_working_divisor <= 0; // Clear out the divisor register
|
76 |
|
|
reg_overflow <= 1'b0; // Clear the overflow register
|
77 |
|
|
|
78 |
|
|
reg_working_dividend[N+Q-2:Q] <= i_dividend[N-2:0]; // Left-align the dividend in its working register
|
79 |
|
|
reg_working_divisor[2*N+Q-3:N+Q-1] <= i_divisor[N-2:0]; // Left-align the divisor into its working register
|
80 |
|
|
|
81 |
|
|
reg_sign <= i_dividend[N-1] ^ i_divisor[N-1]; // Set the sign bit
|
82 |
|
|
end
|
83 |
|
|
else if(!reg_done) begin
|
84 |
|
|
reg_working_divisor <= reg_working_divisor >> 1; // Right shift the divisor (that is, divide it by two - aka reduce the divisor)
|
85 |
|
|
reg_count <= reg_count - 1; // Decrement the count
|
86 |
|
|
|
87 |
|
|
// If the dividend is greater than the divisor
|
88 |
|
|
if(reg_working_dividend >= reg_working_divisor) begin
|
89 |
|
|
reg_working_quotient[reg_count] <= 1'b1; // Set the quotient bit
|
90 |
|
|
reg_working_dividend <= reg_working_dividend - reg_working_divisor; // and subtract the divisor from the dividend
|
91 |
|
|
end
|
92 |
|
|
|
93 |
|
|
//stop condition
|
94 |
|
|
if(reg_count == 0) begin
|
95 |
|
|
reg_done <= 1'b1; // If we're done, it's time to tell the calling process
|
96 |
8 |
tomburkeii |
reg_quotient <= reg_working_quotient; // Move in our working copy to the outside world
|
97 |
4 |
tomburkeii |
if (reg_working_quotient[2*N+Q-3:N]>0)
|
98 |
|
|
reg_overflow <= 1'b1;
|
99 |
|
|
end
|
100 |
|
|
else
|
101 |
|
|
reg_count <= reg_count - 1;
|
102 |
|
|
end
|
103 |
|
|
end
|
104 |
|
|
endmodule
|