1 |
23 |
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: Instruction decode and control.
|
9 |
|
|
//
|
10 |
|
|
// Additional Comments: See US 2959351, Fig. 78.
|
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 decode_ctl (
|
33 |
|
|
input rst,
|
34 |
|
|
input ap, bp, cp,
|
35 |
|
|
input dx, d0, d1, d2, d3, d4, d5, d6, d7, d8, d9, d10,
|
36 |
|
|
input d5_d10, d10_d1_d5, dxl, dxu, d10u,
|
37 |
|
|
input [0:6] opreg_t, opreg_u, addr_u,
|
38 |
|
|
input [0:6] ontime_dist,
|
39 |
|
|
input man_ro_storage, dist_back_sig, d_control, ena_arith_codes,
|
40 |
|
|
input pgm_stop_sw,
|
41 |
|
|
input acc_zero_test, acc_no_zero_test, acc_plus_test, acc_minus_test,
|
42 |
|
|
input single_intlk, arith_restart, overflow_sense_sig, man_acc_reset,
|
43 |
|
|
|
44 |
|
|
output all_restarts, use_d_for_i, turn_on_single_intlk, turn_on_op_intlk,
|
45 |
|
|
output stop_code, code_69, tlu_sig,
|
46 |
|
|
output mult_sig, divide_sig, reset_sig, no_reset_sig, abs_sig, no_abs_sig,
|
47 |
|
|
output lower_sig, upper_sig, add_sig, subt_sig,
|
48 |
|
|
output right_shift_sig, left_shift_sig, half_correct_sig, shift_count_sig,
|
49 |
28 |
eightycc |
output end_shift_control,
|
50 |
23 |
eightycc |
output reg overflow_sense_latch
|
51 |
|
|
);
|
52 |
|
|
|
53 |
|
|
//-----------------------------------------------------------------------------
|
54 |
|
|
// Miscellaneous signals
|
55 |
|
|
//-----------------------------------------------------------------------------
|
56 |
|
|
wire code_90_d_for_i_sig, code_90_restart_sig, code_69_restart_sig,
|
57 |
|
|
code_00_01_restart_sig, code_30_35_restart, shift_restart,
|
58 |
|
|
branch_restart, branch_d_for_i, code_47_d_for_i_sig;
|
59 |
|
|
|
60 |
|
|
assign all_restarts = code_90_restart_sig | code_69_restart_sig
|
61 |
|
|
| code_00_01_restart_sig | code_30_35_restart
|
62 |
|
|
| shift_restart | branch_restart;
|
63 |
|
|
assign use_d_for_i = code_90_d_for_i_sig | branch_d_for_i
|
64 |
|
|
| code_47_d_for_i_sig;
|
65 |
|
|
assign turn_on_single_intlk = end_shift_control;
|
66 |
|
|
|
67 |
|
|
//-----------------------------------------------------------------------------
|
68 |
|
|
// 00 -- No Operation
|
69 |
|
|
// 01 -- Stop
|
70 |
|
|
//-----------------------------------------------------------------------------
|
71 |
|
|
wire code_00_to_04_dctl_p = opreg_t[`biq_b0] & opreg_t[`biq_q0]
|
72 |
|
|
& opreg_u[`biq_b0] & d_control;
|
73 |
|
|
wire code_00_dctl_p = code_00_to_04_dctl_p & opreg_u[`biq_q0];
|
74 |
|
|
wire code_01_dctl_p = code_00_to_04_dctl_p & opreg_u[`biq_q1];
|
75 |
|
|
wire code_00_01_restart_p = code_00_dctl_p | code_01_dctl_p;
|
76 |
|
|
digit_pulse c00_rstrt (rst, ap, code_00_01_restart_p,
|
77 |
|
|
1'b0, code_00_01_restart_sig);
|
78 |
|
|
assign stop_code = pgm_stop_sw & code_01_dctl_p;
|
79 |
|
|
|
80 |
|
|
//-----------------------------------------------------------------------------
|
81 |
|
|
// 14 -- Divide
|
82 |
|
|
// 64 -- Divide and Reset Upper
|
83 |
|
|
//-----------------------------------------------------------------------------
|
84 |
|
|
wire code_14_64_dx_d0_p = (dx | d0) & opreg_t[`biq_q1] // schematic missing term
|
85 |
|
|
& opreg_u[`biq_b0] & opreg_u[`biq_q4];
|
86 |
|
|
assign divide_sig = (code_14_64_dx_d0_p & ena_arith_codes & opreg_t[`biq_b5])
|
87 |
|
|
| (code_14_64_dx_d0_p & ena_arith_codes & opreg_t[`biq_b0]);
|
88 |
|
|
|
89 |
|
|
//-----------------------------------------------------------------------------
|
90 |
|
|
// 19 -- Multiply
|
91 |
|
|
//-----------------------------------------------------------------------------
|
92 |
|
|
assign mult_sig = (dx | d0) & ena_arith_codes
|
93 |
|
|
& code_19_or_69_dctl_p & opreg_t[`biq_b0];
|
94 |
|
|
|
95 |
|
|
//-----------------------------------------------------------------------------
|
96 |
|
|
// 30 -- Shift Right
|
97 |
|
|
// 31 -- Shift and Round
|
98 |
|
|
// 35 -- Shift Left
|
99 |
|
|
// 36 -- Shift Left and Count
|
100 |
|
|
//-----------------------------------------------------------------------------
|
101 |
|
|
reg shift_control_latch;
|
102 |
|
|
digit_pulse end_shift (rst, cp, ~shift_control_latch, 1'b1, end_shift_control);
|
103 |
|
|
wire shift_control_on_p = d_control & d10u & ~single_intlk & opreg_t[`biq_b0]
|
104 |
|
|
& opreg_t[`biq_q3];
|
105 |
|
|
always @(posedge ap)
|
106 |
|
|
if (rst) begin
|
107 |
|
|
shift_control_latch <= 0;
|
108 |
|
|
end else if (dxu) begin
|
109 |
|
|
shift_control_latch <= 0;
|
110 |
|
|
end else if (shift_control_on_p) begin
|
111 |
|
|
shift_control_latch <= 1;
|
112 |
|
|
end;
|
113 |
|
|
|
114 |
|
|
wire zero_shift_number = addr_u[`biq_b0] & addr_u[`biq_q0];
|
115 |
|
|
wire edxl_shift_control = shift_control_latch & dxl;
|
116 |
|
|
wire code_x5 = opreg_u[`biq_b5] & opreg_u[`biq_q0];
|
117 |
|
|
wire code_x0 = opreg_u[`biq_b0] & opreg_u[`biq_q0];
|
118 |
|
|
wire code_x0_or_x5 = code_x0 | code_x5;
|
119 |
|
|
// turn_on_op_intlk: No zero shift num on 30 or 35 codes
|
120 |
|
|
assign turn_on_op_intlk = ~(zero_shift_number & shift_control_latch
|
121 |
|
|
& code_x0_or_x5)
|
122 |
|
|
& edxl_shift_control;
|
123 |
|
|
assign code_30_35_restart = zero_shift_number & edxl_shift_control
|
124 |
|
|
& (code_x0_or_x5);
|
125 |
|
|
|
126 |
|
|
assign right_shift_sig = ~zero_shift_number & edxl_shift_control & code_x0;
|
127 |
|
|
assign left_shift_sig = ~zero_shift_number & edxl_shift_control & code_x5;
|
128 |
|
|
assign half_correct_sig = shift_control_latch & opreg_u[`biq_b0]
|
129 |
|
|
& opreg_u[`biq_q1];
|
130 |
|
|
assign shift_count_sig = shift_control_latch & opreg_u[`biq_b5]
|
131 |
|
|
& opreg_u[`biq_q1];
|
132 |
|
|
assign shift_restart = arith_restart & opreg_t[`biq_q3];
|
133 |
|
|
|
134 |
|
|
//-----------------------------------------------------------------------------
|
135 |
|
|
// 44 -- Branch on non-zero upper acc
|
136 |
|
|
// 45 -- Branch on zero acc
|
137 |
|
|
// 46 -- Branch on minus acc
|
138 |
|
|
// 47 -- Branch on adder overflow
|
139 |
|
|
//-----------------------------------------------------------------------------
|
140 |
|
|
wire code_44_dctl_edxl_p = d_control & dxl
|
141 |
|
|
& opreg_t[`biq_b0] & opreg_t[`biq_q4]
|
142 |
|
|
& opreg_u[`biq_b0] & opreg_u[`biq_q4];
|
143 |
|
|
wire code_45_to_49_dctl_p = d_control & opreg_t[`biq_b0] & opreg_t[`biq_q4]
|
144 |
|
|
& opreg_u[`biq_b5];
|
145 |
|
|
wire code_45_dctl_edxu_p = dxu & code_45_to_49_dctl_p & opreg_u[`biq_q0];
|
146 |
|
|
wire code_46_dctl_p = code_45_to_49_dctl_p & opreg_u[`biq_q1];
|
147 |
|
|
wire code_47_dctl_p = code_45_to_49_dctl_p & opreg_u[`biq_q2];
|
148 |
|
|
|
149 |
|
|
wire code_44_or_45_restart_p = (code_44_dctl_edxl_p | code_45_dctl_edxu_p)
|
150 |
|
|
& acc_zero_test;
|
151 |
|
|
wire code_44_or_45_d_for_i_p = (code_44_dctl_edxl_p | code_45_dctl_edxu_p)
|
152 |
|
|
& acc_no_zero_test;
|
153 |
|
|
wire code_46_restart_p = code_46_dctl_p & acc_plus_test;
|
154 |
|
|
wire code_46_d_for_i_p = code_46_dctl_p & acc_minus_test;
|
155 |
|
|
wire code_47_restart_p = code_47_dctl_p & d5 & ~overflow_sense_latch;
|
156 |
|
|
|
157 |
|
|
wire branch_restart_p = code_44_or_45_restart_p | code_46_restart_p
|
158 |
|
|
| code_47_restart_p;
|
159 |
|
|
digit_pulse br_rstrt (rst, bp, branch_restart_p, 1'b0, branch_restart);
|
160 |
|
|
wire branch_d_for_i_p = code_44_or_45_d_for_i_p | code_46_d_for_i_p;
|
161 |
|
|
digit_pulse br_d4i (rst, bp, branch_d_for_i_p, 1'b0, branch_d_for_i);
|
162 |
|
|
|
163 |
|
|
wire overflow_sense_off_p = man_acc_reset | (code_47_dctl_p & d1);
|
164 |
|
|
always @(posedge ap) begin
|
165 |
|
|
if (rst) overflow_sense_latch <= 0;
|
166 |
|
|
else if (overflow_sense_off_p) overflow_sense_latch <= 0;
|
167 |
|
|
else if (overflow_sense_sig) overflow_sense_latch <= 1;
|
168 |
|
|
end;
|
169 |
|
|
digit_pulse c47_d4i (rst, bp, ~overflow_sense_latch, 1'b1, code_47_d_for_i_sig);
|
170 |
|
|
|
171 |
|
|
//-----------------------------------------------------------------------------
|
172 |
|
|
// 69 -- Load Distributor
|
173 |
|
|
//-----------------------------------------------------------------------------
|
174 |
|
|
wire code_19_or_69_dctl_p = opreg_t[`biq_q1] & opreg_u[`biq_b5]
|
175 |
|
|
& opreg_u[`biq_q4] & d_control;
|
176 |
|
|
assign code_69 = (code_19_or_69_dctl_p & opreg_t[`biq_b5]) | man_ro_storage;
|
177 |
|
|
wire code_69_restart_p = code_69 & dist_back_sig;
|
178 |
|
|
digit_pulse c69_rstrt (rst, ap, code_69_restart_p, 1'b0, code_69_restart_sig);
|
179 |
|
|
|
180 |
|
|
//-----------------------------------------------------------------------------
|
181 |
|
|
// 70 -- Read
|
182 |
|
|
// 71 -- Punch
|
183 |
|
|
//-----------------------------------------------------------------------------
|
184 |
|
|
|
185 |
|
|
|
186 |
|
|
//-----------------------------------------------------------------------------
|
187 |
|
|
// 84 -- Table Lookup
|
188 |
|
|
//-----------------------------------------------------------------------------
|
189 |
|
|
assign tlu_sig = d_control & ~single_intlk
|
190 |
|
|
& opreg_t[`biq_b5] & opreg_t[`biq_q3]
|
191 |
|
|
& opreg_u[`biq_b0] & opreg_u[`biq_q4];
|
192 |
|
|
|
193 |
|
|
//-----------------------------------------------------------------------------
|
194 |
|
|
// 9x -- Branch on Distributor Digit
|
195 |
|
|
//-----------------------------------------------------------------------------
|
196 |
|
|
wire code_9x_dctl_p = opreg_t[`biq_b5] & opreg_t[`biq_q4] & d_control;
|
197 |
|
|
wire code_90_ctrl = (d5_d10 & code_9x_dctl_p & opreg_u[`biq_b5])
|
198 |
|
|
| (d10_d1_d5 & code_9x_dctl_p & opreg_u[`biq_b0]);
|
199 |
|
|
wire code_90_95_p = (d10 | d5) & opreg_u[`biq_q0] & code_90_ctrl;
|
200 |
|
|
wire code_91_96_p = (d1 | d6) & opreg_u[`biq_q1] & code_90_ctrl;
|
201 |
|
|
wire code_92_97_p = (d2 | d7) & opreg_u[`biq_q2] & code_90_ctrl;
|
202 |
|
|
wire code_93_98_p = (d3 | d8) & opreg_u[`biq_q3] & code_90_ctrl;
|
203 |
|
|
wire code_94_99_p = (d4 | d9) & opreg_u[`biq_q4] & code_90_ctrl;
|
204 |
|
|
wire code_90_to_99_p = code_90_95_p | code_91_96_p | code_92_97_p
|
205 |
|
|
| code_93_98_p | code_94_99_p;
|
206 |
|
|
wire code_90_d_for_i_p = code_90_to_99_p & ontime_dist[`biq_b5]
|
207 |
|
|
& ontime_dist[`biq_q3];
|
208 |
|
|
wire code_90_restart_p = code_90_to_99_p & ontime_dist[`biq_b5]
|
209 |
|
|
& ontime_dist[`biq_q4];
|
210 |
|
|
digit_pulse c90_d4i (rst, cp, code_90_d_for_i_p, 1'b0, code_90_d_for_i_sig);
|
211 |
|
|
digit_pulse c90_rstrt (rst, cp, code_90_restart_p, 1'b0, code_90_restart_sig);
|
212 |
|
|
|
213 |
|
|
//-----------------------------------------------------------------------------
|
214 |
|
|
// 10's and 60's Opcode Derived Control Signals
|
215 |
|
|
//
|
216 |
|
|
// SIGNAL OPCODES
|
217 |
|
|
// ------------ ----------------------------------------------
|
218 |
|
|
// reset_sig 60, 61, 64, 65, 66, 67, 68
|
219 |
|
|
// no_reset_sig 10, 11, 14, 15, 16, 17, 18, 19, 69
|
220 |
|
|
// abs_sig 17, 18, 67, 68
|
221 |
|
|
// no_abs_sig 10, 11, 14, 15, 16, 19, 60, 61, 64, 65, 66, 69
|
222 |
|
|
// lower_sig 15, 16, 17, 18, 65, 66, 67, 68
|
223 |
|
|
// upper_sig 10, 11, 14, 60, 61, 64
|
224 |
|
|
// add_sig 10, 15, 17, 60, 65, 67
|
225 |
|
|
// subt_sig 11, 16, 18, 61, 66, 68
|
226 |
|
|
//-----------------------------------------------------------------------------
|
227 |
|
|
assign reset_sig = ~code_19_or_69_dctl_p & d_control & opreg_t[`biq_b5]
|
228 |
|
|
& opreg_t[`biq_q1];
|
229 |
|
|
assign no_reset_sig = code_19_or_69_dctl_p | (d_control & opreg_t[`biq_b0]
|
230 |
|
|
& opreg_t[`biq_q1]);
|
231 |
|
|
assign abs_sig = d_control & opreg_t[`biq_q1] & opreg_u[`biq_b5]
|
232 |
|
|
& (opreg_u[`biq_q2] | opreg_u[`biq_q3]);
|
233 |
|
|
assign no_abs_sig = d_control & opreg_t[`biq_q1]
|
234 |
|
|
& (opreg_u[`biq_q4] | opreg_u[`biq_q1]
|
235 |
|
|
| opreg_u[`biq_q0]);
|
236 |
|
|
assign lower_sig = ena_arith_codes & dx & ~code_19_or_69_dctl_p
|
237 |
|
|
& opreg_u[`biq_b5];
|
238 |
|
|
assign upper_sig = ena_arith_codes & dx & opreg_u[`biq_b0];
|
239 |
|
|
assign add_sig = ena_arith_codes & (dx | d0)
|
240 |
|
|
& (opreg_u[`biq_q2] | opreg_u[`biq_q0]);
|
241 |
|
|
assign subt_sig = ena_arith_codes & (dx | d0)
|
242 |
|
|
& (opreg_u[`biq_q3] | opreg_u[`biq_q1]);
|
243 |
|
|
|
244 |
|
|
endmodule
|