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

Subversion Repositories i650

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

Go to most recent revision | 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
   input bp, dp, c_a, edxu, dx, ed0u, d1, ed1l, d10, d10u, wl,
35
   input [0:6] entry_a, entry_b,
36
   input tlu_on, left_shift_off, left_shift_on,
37
   input no_carry_insert, no_carry_blank, carry_insert, carry_blank,
38
   input zero_insert,
39
 
40
   input error_reset,
41
   input quotient_digit_on, overflow_stop_sw, overflow_sense_sw,
42
   input mult_div_off, dist_true_add_gate, acc_true_add_latch,
43
   input shift_overflow,
44
 
45
   output reg[0:6] adder_out,
46
   output reg carry_test, no_carry_test,
47
   output d0l_carry_sig,
48
 
49
   output overflow_stop, overflow_light, overflow_sense_sig
50
   );
51
 
52
   //-----------------------------------------------------------------------------
53
   // The 650 adder operates like this:
54
   //    The adder output latches are normally reset by AP except when
55
   //    suppressed by reset_cntrl. reset_cntrl is turned
56
   //    off by (plate pullover):
57
   //       tlu_on | (cp & d1 & lt_sh_on) | (cp & ed0u & lt_sh_off)
58
   //    and on by:
59
   //       (bp & wl & d10 & lt_sh_off) | (bp & edxu & lt_sh_on)
60
   //    The carry and no_carry signals are gated by DP, which
61
   //    in turn gates the adder output. The falling edge of DP triggers
62
   //    the output latches, the pulse lasting past the reset action of
63
   //    AP.
64
   //
65
   // Schedule for this implementation:
66
   //    A : --
67
   //    B : Combinational logic begins forming new sum and carry
68
   //        Previous sum and carry brought to adder output
69
   //        Setup reset_cntrl
70
   //        Setup overflow_stop_latch
71
   //    C : --
72
   //    D : Save combinational logic new sum and carry
73
   //-----------------------------------------------------------------------------
74
 
75
   reg [0:6] sum_hold;
76
   reg carry_hold, no_carry_hold, carry_test_hold, no_carry_test_hold;
77
   reg reset_cntrl;
78
   reg carry, no_carry;
79
   reg overflow_stop_latch;
80
   assign d0l_carry_sig = c_a & wl & dx & carry;
81
   assign overflow_stop = overflow_stop_latch;
82
   assign overflow_light = overflow_stop_latch;
83
 
84
   //-----------------------------------------------------------------------------
85
   // Bi-quinary adder, forms biq sum of two biq digits with carry in and out.
86
   // Hand captured from 650 patent fig. 68. 
87
   //-----------------------------------------------------------------------------
88
   wire b0_and_b5 =  (entry_a[`biq_b0] & entry_b[`biq_b5])
89
                   | (entry_a[`biq_b5] & entry_b[`biq_b0]);
90
   wire q4_a_or_b = entry_a[`biq_q4] | entry_b[`biq_q4];
91
   wire q3_a_or_b = entry_a[`biq_q3] | entry_b[`biq_q3];
92
   wire q2_a_or_b = entry_a[`biq_q2] | entry_b[`biq_q2];
93
   wire q1_a_or_b = entry_a[`biq_q1] | entry_b[`biq_q1];
94
   wire q0_a_or_b = entry_a[`biq_q0] | entry_b[`biq_q0];
95
   wire qsum_8 = entry_a[`biq_q4] & entry_b[`biq_q4];
96
   wire qsum_7 = q4_a_or_b & q3_a_or_b;
97
   wire qsum_6 =  (entry_a[`biq_q3] & entry_b[`biq_q3])
98
                | (q4_a_or_b & q2_a_or_b);
99
   wire qsum_5 =  (q4_a_or_b & q3_a_or_b)
100
                | (q3_a_or_b & q2_a_or_b);
101
   wire qsum_4 =  (entry_a[`biq_q2] & entry_b[`biq_q2])
102
                | (q3_a_or_b & q1_a_or_b)
103
                | (q4_a_or_b & q0_a_or_b);
104
   wire qsum_3 =  (q3_a_or_b & q0_a_or_b)
105
                | (q2_a_or_b & q1_a_or_b);
106
   wire qsum_2 =  (entry_a[`biq_q1] & entry_b[`biq_q1])
107
                | (q2_a_or_b & q0_a_or_b);
108
   wire qsum_1 = q1_a_or_b & q0_a_or_b;
109
   wire qsum_0 = (entry_a[`biq_q0] & entry_b[`biq_q0]);
110
   wire three_or_eight = qsum_3 | qsum_8;
111
   wire two_or_seven   = qsum_2 | qsum_7;
112
   wire six_or_one     = qsum_6 | qsum_1;
113
   wire zero_or_five   = qsum_0 | qsum_5;
114
   wire five_and_up = qsum_8 | qsum_7 | qsum_6 | qsum_5 | (qsum_4 & carry);
115
   wire below_five  = (qsum_4 & no_carry) | qsum_3 | qsum_2 | qsum_1 | qsum_0;
116
   wire b5_carry    = five_and_up & entry_a[`biq_b5] & entry_b[`biq_b5];
117
   wire b5_no_carry =  (five_and_up & entry_a[`biq_b0] & entry_b[`biq_b0])
118
                     | (below_five & b0_and_b5);
119
   wire b0_carry    =  (five_and_up & b0_and_b5)
120
                     | (below_five & entry_a[`biq_b5] & entry_b[`biq_b5]);
121
   wire b0_no_carry = below_five & entry_a[`biq_b0] & entry_b[`biq_b0];
122
   wire sum_q0 = (carry & qsum_4) | (no_carry & zero_or_five);
123
   wire sum_q1 = (carry & zero_or_five) | (no_carry & six_or_one);
124
   wire sum_q2 = (carry & six_or_one) | (no_carry & two_or_seven);
125
   wire sum_q3 = (carry & two_or_seven) | (no_carry & three_or_eight);
126
   wire sum_q4 = (carry & three_or_eight) | (no_carry & qsum_4);
127
   wire sum_b0 = b0_no_carry | b0_carry;
128
   wire sum_b5 = b5_no_carry | b5_carry;
129
   wire [0:6] sum_out = {sum_b5, sum_b0, sum_q4, sum_q3, sum_q2, sum_q1, sum_q0};
130
   wire carry_out = b0_carry | b5_carry;
131
   wire no_carry_out = b0_no_carry | b5_no_carry;
132
 
133
   wire overflow =  shift_overflow
134
                  | (carry_test & d10u & dist_true_add_gate
135
                                & acc_true_add_latch & mult_div_off);
136
   assign overflow_sense_sig = overflow & overflow_sense_sw;
137
 
138
   //-----------------------------------------------------------------------------
139
   // B -- 
140
   //-----------------------------------------------------------------------------
141
   always @(posedge rst, posedge bp) begin
142
      if (rst) begin
143
         adder_out <= `biq_blank;
144
         reset_cntrl <= 0;
145
         carry_test <= 0;
146
         no_carry_test <= 0;
147
         carry <= 0;
148
         no_carry <= 0;
149
         overflow_stop_latch <= 0;
150
      end else begin
151
         adder_out <= sum_hold;
152
         carry_test <= carry_test_hold;
153
         no_carry_test <= no_carry_test_hold;
154
         carry <= carry_hold;
155
         no_carry <= no_carry_hold;
156
         if (tlu_on | (d1 & left_shift_on) | (ed0u & left_shift_off)) begin
157
            reset_cntrl <= 0;
158
         end else if ((wl & d10 & left_shift_off) | (edxu & left_shift_on)) begin
159
            reset_cntrl <= 1;
160
         end
161
         if (error_reset) begin
162
            overflow_stop_latch <= 0;
163
         end else if ((ed1l & carry_test & quotient_digit_on)
164
                    | (overflow & overflow_stop_sw)) begin
165
            overflow_stop_latch <= 1;
166
         end
167
      end
168
   end;
169
 
170
   always @(posedge rst, posedge dp) begin
171
      if (rst) begin
172
         sum_hold <= `biq_blank;
173
         carry_hold <= 0;
174
         no_carry_hold <= 0;
175
         carry_test_hold <= 0;
176
         no_carry_test_hold <= 0;
177
      end else begin
178
         sum_hold <=      zero_insert? `biq_0
179
                        : reset_cntrl?  sum_hold
180
                        : sum_out;
181
         carry_hold <=   (reset_cntrl | carry_blank)? 1'b0
182
                        : carry_insert? 1'b1
183
                        : carry_out;
184
         no_carry_hold <= (reset_cntrl | no_carry_blank)? 1'b0
185
                        : no_carry_insert? 1'b1
186
                        : no_carry_out;
187
         carry_test_hold    <= reset_cntrl? 1'b0 : carry_out;
188
         no_carry_test_hold <= reset_cntrl? 1'b0 : no_carry_out;
189
      end
190
   end;
191
 
192
 
193
endmodule

powered by: WebSVN 2.1.0

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