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

Subversion Repositories m1_core

[/] [m1_core/] [trunk/] [hdl/] [rtl/] [m1_core/] [m1_div.v] - Blame information for rev 64

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 33 fafa1971
/*
2 64 albert.wat
 * M1 Divider
3 33 fafa1971
 *
4
 * Simple RTL-level divider with Alternating Bit Protocol (ABP) interface.
5
 */
6
 
7
// 32-bit / 32-bit Integer Divider (this version is not optimized and always takes 32 cycles)
8
module m1_div(
9
    input            sys_reset_i,      // System Reset
10
    input            sys_clock_i,      // System Clock
11
    input[31:0]      a_i,              // Operand A
12
    input[31:0]      b_i,              // Operand B
13
    input            signed_i,         // If division is signed
14
    output reg[31:0] quotient_o,       // Quotient of division
15
    output reg[31:0] remainder_o,      // Remainder of division
16
    input            abp_req_i,        // ABP Request
17
    output reg       abp_ack_o         // ABP Acknowledgement
18
  );
19
 
20
  // Registers
21
  reg[63:0]    a_latched;        // Latched 'a' input
22
  reg[63:0]    b_latched;        // Latched 'b' input
23
  reg[31:0]    quotient_tmp;     // Temporary result
24
  reg[31:0]    remainder_tmp;    // Temporary result
25
  reg          negative_output;  // If output is negative
26
  reg[5:0]     count;            // Downward counter (32->0)
27
  reg          abp_last;         // Level of last ABP request
28
  reg[63:0]    diff;             // Difference
29
 
30
  // Sequential logic
31
  always @(posedge sys_clock_i) begin
32
 
33
    // Initialization
34
    if(sys_reset_i) begin
35
 
36
      quotient_o = 0;
37
      remainder_o = 0;
38
      abp_ack_o = 0;
39
      negative_output = 0;
40
      count = 6'd0;
41
      abp_last = 0;
42
 
43
    // New request
44
    end else if(abp_req_i!=abp_last) begin
45
 
46
      abp_last = abp_req_i;     // Latch level of ABP request
47
      count  = 6'd32;           // Start counter
48
      quotient_tmp = 0;         // Initialize result
49
      remainder_tmp = 0;        // Initialize result
50
      a_latched = (!signed_i || !a_i[31]) ? { 32'd0, a_i } : { 32'd0, (~a_i + 1'b1) };
51
      b_latched = (!signed_i || !b_i[31]) ? { 1'b0, b_i, 31'd0 } : { 1'b0, ~b_i + 1'b1, 31'd0 };
52
      negative_output = signed_i && (a_i[31] ^ b_i[31]);
53
      quotient_o = (!negative_output) ? quotient_tmp : (~quotient_tmp+1);  // Debugging only
54
      remainder_o = (!negative_output) ? a_latched[31:0] : (~a_latched[31:0]+1);  // Debugging only
55
 
56
    // Calculating
57
    end else if(count>0) begin
58
 
59
      count = count-1;
60
      diff = a_latched-b_latched;
61
      quotient_tmp = quotient_tmp << 1;
62
      if(!diff[63]) begin
63
        a_latched = diff;
64
        quotient_tmp[0] = 1;
65
      end
66
      b_latched = b_latched >> 1;
67
      quotient_o = (!negative_output) ? quotient_tmp : (~quotient_tmp+1);  // Debugging only
68
      remainder_o = (!negative_output) ? a_latched[31:0] : (~a_latched[31:0]+1);  // Debugging only
69
 
70
    // Return the result
71
    end else if(count==0) begin
72
 
73
      abp_ack_o = abp_req_i;    // Return the result
74
      quotient_o = (!negative_output) ? quotient_tmp : (~quotient_tmp+1);
75
      remainder_o = (!negative_output) ? a_latched[31:0] : (~a_latched[31:0]+1);
76
 
77
    end
78
 
79
  end
80
 
81
endmodule
82
 

powered by: WebSVN 2.1.0

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