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

Subversion Repositories i650

[/] [i650/] [trunk/] [rtl/] [adder.v] - Blame information for rev 22

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 21 eightycc
`timescale 1ns / 1ps
2
//////////////////////////////////////////////////////////////////////////////////
3
// IBM 650 Reconstruction in Verilog (i650)
4
// 
5
// This file is part of the IBM 650 Reconstruction in Verilog (i650) project
6
// http:////www.opencores.org/project,i650
7
//
8
// Description: Bi-quinary adder.
9
// 
10
// Additional Comments: 
11
//
12
// Copyright (c) 2015 Robert Abeles
13
//
14
// This source file is free software; you can redistribute it
15
// and/or modify it under the terms of the GNU Lesser General
16
// Public License as published by the Free Software Foundation;
17
// either version 2.1 of the License, or (at your option) any
18
// later version.
19
//
20
// This source is distributed in the hope that it will be
21
// useful, but WITHOUT ANY WARRANTY; without even the implied
22
// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
23
// PURPOSE.  See the GNU Lesser General Public License for more
24
// details.
25
//
26
// You should have received a copy of the GNU Lesser General
27
// Public License along with this source; if not, download it
28
// from http://www.opencores.org/lgpl.shtml
29
//////////////////////////////////////////////////////////////////////////////////
30
`include "defines.v"
31
 
32
module adder (
33
   input rst,
34 22 eightycc
   input ap, bp, dp,
35
         dxu, dx, d0u, d1, d1l, d10, d10u, wl,
36 21 eightycc
   input [0:6] entry_a, entry_b,
37
   input tlu_on, left_shift_off, left_shift_on,
38
   input no_carry_insert, no_carry_blank, carry_insert, carry_blank,
39
   input zero_insert,
40
 
41
   input error_reset,
42
   input quotient_digit_on, overflow_stop_sw, overflow_sense_sw,
43
   input mult_div_off, dist_true_add_gate, acc_true_add_latch,
44
   input shift_overflow,
45
 
46
   output reg[0:6] adder_out,
47 22 eightycc
   output reg carry_test, no_carry_test, d0l_carry_sig, overflow_stop,
48 21 eightycc
 
49 22 eightycc
   output overflow_light, overflow_sense_sig
50 21 eightycc
   );
51
 
52
   //-----------------------------------------------------------------------------
53 22 eightycc
   // The 650 bi-quinary adder accepts its inputs early (i.e., one clock ahead),
54
   // producing a result during the next digit time. This implementation retains
55
   // sum and carries in _hold flip-flops, the 650 used other tricky means.
56 21 eightycc
   //-----------------------------------------------------------------------------
57
   reg [0:6] sum_hold;
58
   reg carry_hold, no_carry_hold, carry_test_hold, no_carry_test_hold;
59 22 eightycc
   reg reset_ctl;
60
   reg carry, no_carry;
61 21 eightycc
 
62
   //-----------------------------------------------------------------------------
63
   // Bi-quinary adder, forms biq sum of two biq digits with carry in and out.
64 22 eightycc
   // Hand captured from 650 patent fig. 68.
65
   //
66
   // By design, this logic produces a sum of all zeroes with zero carry_out and 
67
   // no_carry_out whenever entry_a or entry_b or both carry and no_carry are
68
   // zero.
69 21 eightycc
   //-----------------------------------------------------------------------------
70
   wire b0_and_b5 =  (entry_a[`biq_b0] & entry_b[`biq_b5])
71
                   | (entry_a[`biq_b5] & entry_b[`biq_b0]);
72
   wire q4_a_or_b = entry_a[`biq_q4] | entry_b[`biq_q4];
73
   wire q3_a_or_b = entry_a[`biq_q3] | entry_b[`biq_q3];
74
   wire q2_a_or_b = entry_a[`biq_q2] | entry_b[`biq_q2];
75
   wire q1_a_or_b = entry_a[`biq_q1] | entry_b[`biq_q1];
76
   wire q0_a_or_b = entry_a[`biq_q0] | entry_b[`biq_q0];
77
   wire qsum_8 = entry_a[`biq_q4] & entry_b[`biq_q4];
78
   wire qsum_7 = q4_a_or_b & q3_a_or_b;
79
   wire qsum_6 =  (entry_a[`biq_q3] & entry_b[`biq_q3])
80
                | (q4_a_or_b & q2_a_or_b);
81
   wire qsum_5 =  (q4_a_or_b & q3_a_or_b)
82
                | (q3_a_or_b & q2_a_or_b);
83
   wire qsum_4 =  (entry_a[`biq_q2] & entry_b[`biq_q2])
84
                | (q3_a_or_b & q1_a_or_b)
85
                | (q4_a_or_b & q0_a_or_b);
86
   wire qsum_3 =  (q3_a_or_b & q0_a_or_b)
87
                | (q2_a_or_b & q1_a_or_b);
88
   wire qsum_2 =  (entry_a[`biq_q1] & entry_b[`biq_q1])
89
                | (q2_a_or_b & q0_a_or_b);
90
   wire qsum_1 = q1_a_or_b & q0_a_or_b;
91
   wire qsum_0 = (entry_a[`biq_q0] & entry_b[`biq_q0]);
92
   wire three_or_eight = qsum_3 | qsum_8;
93
   wire two_or_seven   = qsum_2 | qsum_7;
94
   wire six_or_one     = qsum_6 | qsum_1;
95
   wire zero_or_five   = qsum_0 | qsum_5;
96
   wire five_and_up = qsum_8 | qsum_7 | qsum_6 | qsum_5 | (qsum_4 & carry);
97
   wire below_five  = (qsum_4 & no_carry) | qsum_3 | qsum_2 | qsum_1 | qsum_0;
98
   wire b5_carry    = five_and_up & entry_a[`biq_b5] & entry_b[`biq_b5];
99
   wire b5_no_carry =  (five_and_up & entry_a[`biq_b0] & entry_b[`biq_b0])
100
                     | (below_five & b0_and_b5);
101
   wire b0_carry    =  (five_and_up & b0_and_b5)
102
                     | (below_five & entry_a[`biq_b5] & entry_b[`biq_b5]);
103
   wire b0_no_carry = below_five & entry_a[`biq_b0] & entry_b[`biq_b0];
104
   wire sum_q0 = (carry & qsum_4) | (no_carry & zero_or_five);
105
   wire sum_q1 = (carry & zero_or_five) | (no_carry & six_or_one);
106
   wire sum_q2 = (carry & six_or_one) | (no_carry & two_or_seven);
107
   wire sum_q3 = (carry & two_or_seven) | (no_carry & three_or_eight);
108
   wire sum_q4 = (carry & three_or_eight) | (no_carry & qsum_4);
109
   wire sum_b0 = b0_no_carry | b0_carry;
110
   wire sum_b5 = b5_no_carry | b5_carry;
111
   wire [0:6] sum_out = {sum_b5, sum_b0, sum_q4, sum_q3, sum_q2, sum_q1, sum_q0};
112
   wire carry_out = b0_carry | b5_carry;
113
   wire no_carry_out = b0_no_carry | b5_no_carry;
114 22 eightycc
 
115 21 eightycc
   //-----------------------------------------------------------------------------
116 22 eightycc
   // A : Supply sum and carries from previous digit time
117 21 eightycc
   //-----------------------------------------------------------------------------
118 22 eightycc
   always @(posedge ap)
119 21 eightycc
      if (rst) begin
120 22 eightycc
         adder_out     <= `biq_blank;
121
         carry_test    <= 0;
122 21 eightycc
         no_carry_test <= 0;
123 22 eightycc
         carry         <= 0;
124
         no_carry      <= 0;
125 21 eightycc
      end else begin
126 22 eightycc
         adder_out     <= sum_hold;
127
         carry_test    <= carry_test_hold;
128 21 eightycc
         no_carry_test <= no_carry_test_hold;
129 22 eightycc
         carry         <= carry_hold;
130
         no_carry      <= no_carry_hold;
131 21 eightycc
      end
132
 
133 22 eightycc
   wire reset_ctl_on_p  = (wl & d10 & left_shift_off) | (dxu & left_shift_on);
134
   wire reset_ctl_off_p = tlu_on | (d1 & left_shift_on) | (d0u & left_shift_off);
135
   always @(posedge ap)
136 21 eightycc
      if (rst) begin
137 22 eightycc
         reset_ctl <= 0;
138
      end else if (reset_ctl_on_p) begin
139
         reset_ctl <= 1;
140
      end else if (reset_ctl_off_p) begin
141
         reset_ctl <= 0;
142
      end;
143
 
144
   wire overflow =  shift_overflow
145
                  | (carry_test & d10u & dist_true_add_gate
146
                                & acc_true_add_latch & mult_div_off);
147
   assign overflow_sense_sig = overflow & overflow_sense_sw;
148
   wire overflow_stop_p =  (d1l & carry_test & quotient_digit_on)
149
                         | (overflow & overflow_stop_sw);
150
   assign overflow_light = overflow_stop;
151
   always @(posedge bp)
152
      if (rst) begin
153
         overflow_stop <= 1;
154
      end else if (error_reset) begin
155
         overflow_stop <= 0;
156
      end else if (overflow_stop_p) begin
157
         overflow_stop <= 1;
158
      end;
159
 
160
   always @(posedge dp)
161
      if (rst)                      d0l_carry_sig <= 0;
162
      else if (wl & d1)             d0l_carry_sig <= 0;
163
      else if (wl & dx & carry_out) d0l_carry_sig <= 1;
164
 
165
   always @(posedge dp)
166
      if (rst) begin
167 21 eightycc
         sum_hold <= `biq_blank;
168
         carry_hold <= 0;
169
         no_carry_hold <= 0;
170
         carry_test_hold <= 0;
171
         no_carry_test_hold <= 0;
172
      end else begin
173 22 eightycc
         sum_hold      <= zero_insert? `biq_0
174
                        : reset_ctl?  sum_hold
175 21 eightycc
                        : sum_out;
176 22 eightycc
         carry_hold    <= (reset_ctl | carry_blank)? 1'b0
177 21 eightycc
                        : carry_insert? 1'b1
178
                        : carry_out;
179 22 eightycc
         no_carry_hold <= (reset_ctl | no_carry_blank)? 1'b0
180 21 eightycc
                        : no_carry_insert? 1'b1
181
                        : no_carry_out;
182 22 eightycc
         carry_test_hold    <= reset_ctl? 1'b0 : carry_out;
183
         no_carry_test_hold <= reset_ctl? 1'b0 : no_carry_out;
184
      end;
185 21 eightycc
 
186
 
187
endmodule

powered by: WebSVN 2.1.0

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