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

Subversion Repositories i650

[/] [i650/] [trunk/] [rtl/] [ctl_commutator.v] - Blame information for rev 27

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 27 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: Control commutator.
9
// 
10
// Additional Comments: See US 2959351, Fig. 81.
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 ctl_commutator (
33
   input rst,
34
   input ap, bp, cp, dp,
35
   input dx, d1, d3, d7, d9, d10,
36
   input dxu, dxl,
37
   input wu, wl,
38
 
39
   input invalid_addr,
40
   input man_prog_reset, run_control_sw, program_start_sw, manual_ri_storage_sw,
41
   input manual_ro_storage_sw, manual_error_reset_sw,
42
   input half_or_pgm_stop,
43
 
44
   input prog_restart, error_stop, error_sense_restart, arith_restart,
45
   input stop_code, code_69, start_10s_60s, end_shift_cntrl, tlu_on,
46
   input end_of_operation, turn_on_op_intlk, decode_restarts,
47
 
48
   input use_d_for_i, dist_back_signal,
49
   input error_stop_ed0u, divide_overflow_stop,
50
         exceed_address_or_stor_select_light,
51
   input [0:6] opreg_t, opreg_u,
52
   input addr_no_800x, addr_8001,
53
   input dynamic_addr_hit,
54
 
55
   output reg restart_a, restart_b,
56
   output reg i_alt, d_alt,
57
   output reg manual_stop_start, run_latch,
58
   output reg enable_ri,
59
   output manual_ri_storage, manual_ro_storage,
60
   output reg manual_start_ri_dist_latch,
61
   output i_control_pulse,
62
   output i_control, d_control, d_control_no_8001,
63
   output reg start_ri,
64
   output reg rips_ri_dist_intlk_a, rips_ri_dist_intlk_b, op_intlk, single_intlk,
65
   output rips, ri_dist,
66
   output reg acc_to_dist_ri_latch,
67
   output start_acc_to_dist_ri, end_acc_to_dist_ri,
68
   output reg rigs,
69
   output end_rigs
70
   );
71
 
72
   //-----------------------------------------------------------------------------
73
   // Restart control
74
   //-----------------------------------------------------------------------------
75
   wire ri_dist_restart, arith_codes_restart;
76
   assign all_restarts =   decode_restarts
77
                         | prog_restart
78
                         | ri_dist_restart
79
                         | arith_codes_restart;
80
 
81
   always @(posedge ap)
82
      if (rst) begin
83
         restart_a <= 0;
84
      end else if (~invalid_addr & all_restarts & ~restart_b) begin
85
         restart_a <= 1;
86
      end else if (man_prog_reset | (restart_b & dx)) begin
87
         restart_a <= 0;
88
      end;
89
 
90
   always @(posedge ap)
91
      if (rst) begin
92
         restart_b <= 0;
93
      end else if (restart_a & dx) begin
94
         restart_b <= 1;
95
      end else if (restart_b & dx) begin
96
         restart_b <= 0;
97
      end;
98
 
99
   //-----------------------------------------------------------------------------
100
   // I / D alternation
101
   //-----------------------------------------------------------------------------
102
   assign run_control = run_control_sw & run_latch;
103
   assign d_control_no_8001 = opreg_t[`biq_q1] & d_control & ~addr_8001;
104
   wire   d_control_8001    = opreg_t[`biq_q1] & d_control & addr_8001;
105
   assign i_control = i_alt & ~restart_b & run_latch;
106
   assign d_control = d_alt & ~op_intlk & ~restart_b & run_control;
107
 
108
   always @(posedge dp)
109
      if (rst) begin
110
         i_alt <= 0;
111
         d_alt <= 1;
112
      end else if (man_prog_reset | use_d_for_i ) begin
113
         i_alt <= 0;
114
         d_alt <= 1;
115
      end else if (dx & restart_b & run_control) begin
116
         i_alt <= d_alt;
117
         d_alt <= i_alt;
118
      end;
119
 
120
   //-----------------------------------------------------------------------------
121
   // 8uS i_control_pulse is emited at the rising edge of (ap & i_control)
122
   //-----------------------------------------------------------------------------
123
   digit_pulse i_ctl (rst, ap, (i_control | manual_ro_storage | d_control_no_8001), 1'b0, i_control_pulse);
124
 
125
   //-----------------------------------------------------------------------------
126
   // CPU running control
127
   //-----------------------------------------------------------------------------
128
   assign manual_ri_storage = manual_ri_storage_sw & run_latch;
129
   assign manual_ro_storage = manual_ro_storage_sw & run_latch;
130
 
131
   always @(posedge ap)
132
      if (rst) begin
133
         manual_stop_start <= 0;
134
      end else if (dxl) begin
135
         manual_stop_start <= 0;
136
      end else if (program_start_sw & dxu & ~error_stop) begin
137
         manual_stop_start <= 1;
138
      end;
139
 
140
   wire turn_off_run_latch = half_or_pgm_stop & ~invalid_addr & all_restarts & ~restart_b;
141
 
142
   always @(posedge bp)
143
      if (rst) begin
144
         run_latch <= 0;
145
      end else if (   (manual_ri_storage & end_rigs)
146
                    | (manual_ro_storage & dist_back_signal)
147
                    | manual_error_reset_sw
148
                    | error_stop_ed0u
149
                    | divide_overflow_stop
150
                    | exceed_address_or_stor_select_light
151
                    | stop_code
152
                    | turn_off_run_latch ) begin
153
         run_latch <= 0;
154
      end else if (manual_stop_start | error_sense_restart) begin
155
         run_latch <= 1;
156
      end;
157
 
158
 
159
   //-----------------------------------------------------------------------------
160
   // Accumulator to distributor read-in control
161
   //-----------------------------------------------------------------------------
162
 
163
   //-----------------------------------------------------------------------------
164
   // Predicates for accumulator to distributor read-in. Instructions decoded:
165
   //  20 STL Store Lower in Memory
166
   //  21 STU Store Upper in Memory
167
   //  22 STDA Store Lower Data Address
168
   //  23 STIA Store Lower Inst Address
169
   //  24 STD Store Distributor
170
   //-----------------------------------------------------------------------------
171
   assign op_20_24_d_p         = opreg_t[`biq_b0] & opreg_t[`biq_q2] & opreg_u[`biq_q0] & d_control;
172
 
173
   assign op_20_24_d_intlk_p   = op_20_24_d_p & ~single_intlk;
174
 
175
   assign op_20_d_intlk_d10u_p = op_20_24_d_intlk_p & opreg_u[`biq_q0] & wu & d10;
176
   assign op_21_d_intlk_d10l_p = op_20_24_d_intlk_p & opreg_u[`biq_q1] & wl & d10;
177
   assign op_22_d_intlk_d3l_p  = op_20_24_d_intlk_p & opreg_u[`biq_q2] & wl & d3;
178
   assign op_23_d_intlk_dxl_p  = op_20_24_d_intlk_p & opreg_u[`biq_q3] & wl & dx;
179
   assign acc_to_dist_ri_on_p  = op_20_d_intlk_d10u_p | op_21_d_intlk_d10l_p | op_22_d_intlk_d3l_p | op_23_d_intlk_dxl_p;
180
 
181
   assign op_20_d_intlk_d9_p   = op_20_24_d_intlk_p & opreg_u[`biq_q0] & d9;
182
 
183
   assign op_21_d_intlk_d9u_p  = op_20_24_d_intlk_p & opreg_u[`biq_q1] & wu & d9;
184
 
185
   assign op_22_d_intlk_d7_p   = op_20_24_d_intlk_p & opreg_u[`biq_q2] & d7;
186
 
187
   assign op_23_d_intlk_d3_p   = op_20_24_d_intlk_p & opreg_u[`biq_q3] & d3;
188
   assign acc_to_dist_ri_off_p = op_20_d_intlk_d9_p | op_21_d_intlk_d9u_p | op_22_d_intlk_d7_p | op_23_d_intlk_d3_p;
189
 
190
   assign op_24_d_intlk_p      = op_20_24_d_intlk_p & opreg_u[`biq_q4];
191
 
192
   always @(posedge bp)
193
      if (rst) begin
194
         acc_to_dist_ri_latch <= 0;
195
      end else if (acc_to_dist_ri_off_p) begin
196
         acc_to_dist_ri_latch <= 0;
197
      end else if (acc_to_dist_ri_on_p) begin
198
         acc_to_dist_ri_latch <= 1;
199
      end;
200
   digit_pulse a2d_ri_on (rst, cp, acc_to_dist_ri_latch, 1'b0, start_acc_to_dist_ri);
201
   digit_pulse a2d_ri_off(rst, cp, ~acc_to_dist_ri_latch, 1'b1, end_acc_to_dist_ri);
202
 
203
   //-----------------------------------------------------------------------------
204
   // Manual read-in control
205
   //-----------------------------------------------------------------------------
206
   wire man_start_ri_dist_sig;
207
   digit_pulse ri_dist_sig (rst, ap, manual_ri_storage, 1'b0, man_start_ri_dist_sig);
208
 
209
   always @(posedge bp)
210
      if (rst) begin
211
         manual_start_ri_dist_latch <= 0;
212
      end
213
 
214
   //-----------------------------------------------------------------------------
215
   // Read-in control
216
   //-----------------------------------------------------------------------------
217
   always @(posedge dp)
218
      if (rst) begin
219
         enable_ri <= 0;
220
      end else if (man_prog_reset | start_ri) begin
221
         enable_ri <= 0;
222
      end else if (   start_acc_to_dist_ri
223
                    | man_start_ri_dist_sig
224
                    | i_control_pulse
225
                    | op_24_d_intlk_p ) begin
226
         enable_ri <= 1;
227
      end;
228
 
229
   always @(posedge cp)
230
      if (rst) begin
231
         start_ri <= 0;
232
      end else if (d1) begin
233
         start_ri <= 0;
234
      end else if (d9 & addr_no_800x & enable_ri & dynamic_addr_hit) begin
235
         start_ri <= 1;
236
      end;
237
 
238
   //-----------------------------------------------------------------------------
239
   // Read-in general storage
240
   //-----------------------------------------------------------------------------
241
   always @(posedge bp)
242
      if (rst) begin
243
         rigs <= 0;
244
      end else if (d10 & ~start_ri) begin
245
         rigs <= 0;
246
      end else if ((d10 & manual_ri_storage & start_ri) | (d10 & op_20_24_d_p & start_ri)) begin
247
         rigs <= 1;
248
      end;
249
 
250
   digit_pulse end_rigs_sig (rst, cp, ~rigs, 1'b1, end_rigs);
251
 
252
   //-----------------------------------------------------------------------------
253
   // Read-in distributor
254
   //-----------------------------------------------------------------------------
255
   assign ri_dist = (dx & start_ri & ~rips_ri_dist_intlk_b & (manual_ro_storage | d_control_no_8001)) | man_start_ri_dist_sig;
256
   assign ri_dist_restart = dist_back_sig_latch & end_rigs;
257
   reg dist_back_sig_latch;
258
 
259
   always @(posedge bp)
260
      if (rst) begin
261
         dist_back_sig_latch <= 0;
262
      end else if (man_prog_reset | dist_back_signal) begin
263
         dist_back_sig_latch <= 1;
264
      end else if (ri_dist | start_acc_to_dist_ri) begin
265
         dist_back_sig_latch <= 0;
266
      end;
267
 
268
   //-----------------------------------------------------------------------------
269
   // Read-in program step
270
   //-----------------------------------------------------------------------------
271
   assign rips = dx & start_ri & i_control & ~rips_ri_dist_intlk_b;
272
 
273
   //-----------------------------------------------------------------------------
274
   // Enable arithmetic codes latch
275
   //-----------------------------------------------------------------------------
276
   reg enable_arith_codes_latch;
277
   wire d_control_8001_sig;
278
 
279
   digit_pulse ac_on_sig (rst, ap, d_control_8001, 1'b0, d_control_8001_sig);
280
 
281
   always @(posedge bp)
282
      if (rst) begin
283
         enable_arith_codes_latch <= 0;
284
      end else if ((arith_restart & dist_back_sig_latch) | code_69) begin
285
         enable_arith_codes_latch <= 0;
286
      end else if (d_control_8001_sig | (d_control_no_8001 & dist_back_signal)) begin
287
         enable_arith_codes_latch <= 1;
288
      end;
289
 
290
   digit_pulse ac_restart (rst, cp, ~arith_restart, 1'b1, arith_codes_restart);
291
 
292
   //-----------------------------------------------------------------------------
293
   // Interlocks
294
   //-----------------------------------------------------------------------------
295
 
296
   // RIPS-RID interlock A and B latches: These latches provide an interlock to
297
   // insure that only one RIPS or storage to distributor RI signal will be
298
   // developed on any commutator half cycle. Interlock B must be off to obtain
299
   // either RIPS or storage to distributor RI. Either signal when developed
300
   // turns on interlock A which turns off with the next D1 and turns interlock
301
   // B on. With interlock B on, one of the conditions necessary for RIPS or 
302
   // storage to distributor RI is removed. Interlock B is reset by any restart,
303
   // program reset, or manual RI.
304
   always @(posedge bp)
305
      if (rst) begin
306
         rips_ri_dist_intlk_a <= 0;
307
         rips_ri_dist_intlk_b <= 0;
308
      end else begin
309
         if (d1) begin
310
            rips_ri_dist_intlk_a <= 0;
311
         end else if (ri_dist | rips) begin
312
            rips_ri_dist_intlk_a <= 1;
313
         end
314
         if (all_restarts | man_prog_reset) begin
315
            rips_ri_dist_intlk_b <= 0;
316
         end else if (d1 & rips_ri_dist_intlk_a) begin
317
            rips_ri_dist_intlk_b <= 1;
318
         end
319
      end;
320
 
321
   // Operation interlock latch (791, Fig 81i): The off output of this latch is
322
   // one of the conditions needed for the development of the "D" control signal
323
   // and for the turning of the start RI latch on an 800X address. The arith-
324
   // metic and shift operations make use of the accumulator and distributor and
325
   // may require several word times for their completion. The restart signal on
326
   // these operations is developed during the first operation word interval.
327
   // Thus the commutator can advance concurrently with the performance of the
328
   // operation and allow the next instruction to be located, read into program
329
   // step storage, restart to "D" and transfer the new Op. code and "D" address
330
   // to the registers. At this point further advance of the commutator cannot
331
   // be allowed until the preceeding operation is completed. This interlocking
332
   // is done by allowing arithmetic and shift signals to turn on the operation
333
   // interlock latch, removing one of the necessary conditions for "D" control.
334
   // When an arithmetic or shift instruction has an 800X "I" address, the
335
   // location of the next instruction must be prevented until the preceeding
336
   // operation is complete, since the instruction itself is in the process of
337
   // being developed by the operation. This is accomplished by the Op.
338
   // interlock off condition necessary for turning on the start RI.
339
   wire set_op_intlk_sig;
340
   wire set_op_intlk_p = wl & opreg_t[`biq_q1] & enable_arith_codes_latch & ~single_intlk;
341
   digit_pulse op_ilk_sig (rst, ap, ~set_op_intlk_p, 1'b1, set_op_intlk_sig);
342
   always @(posedge bp)
343
      if (rst) begin
344
         op_intlk <= 0;
345
      end else if (man_prog_reset | end_of_operation) begin
346
         op_intlk <= 0;
347
      end else if (set_op_intlk_sig | turn_on_op_intlk) begin
348
         op_intlk <= 1;
349
      end;
350
 
351
   // Single interlock latch (857, Fig 81i): This latch when off, conditions
352
   // the development of arithmetic code signals, store code signals, shift
353
   // code signals and TLU signals. When any of these signals are developed
354
   // they cause the single interlock latch to be turned on thus preventing
355
   // further development of the same signals during successive word intervals
356
   // of the same commutator half cycle. The latch is turned off by any
357
   // restart or by program reset.
358
   wire single_intlk_set_p = (enable_ri & op_24_d_intlk_p)
359
                           | start_10s_60s
360
                           | end_shift_cntrl
361
                           | end_acc_to_dist_ri
362
                           | tlu_on;
363
   always @(posedge dp)
364
      if (rst) begin
365
         single_intlk <= 0;
366
      end else if (man_prog_reset | all_restarts) begin
367
         single_intlk <= 0;
368
      end else if (single_intlk_set_p) begin
369
         single_intlk <= 1;
370
      end;
371
 
372
endmodule

powered by: WebSVN 2.1.0

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