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: Address register.
|
9 |
|
|
//
|
10 |
|
|
// Additional Comments: See US 2959351, Fig. 71.
|
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 addr_reg (
|
33 |
|
|
input rst,
|
34 |
|
|
input ap, bp,
|
35 |
|
|
input dx, d1, d2, d3, d4, d5, d6, d7, d8, d9,
|
36 |
|
|
input w0, w1, w2, w3, w4, w5, w6, w7, w8, w9,
|
37 |
|
|
input s0, s1, s2, s3, s4,
|
38 |
|
|
|
39 |
|
|
input error_reset,
|
40 |
|
|
input restart_a,
|
41 |
|
|
input set_8000, reset_8000,
|
42 |
|
|
input tlu_band_change,
|
43 |
|
|
input double_write,
|
44 |
|
|
input no_write,
|
45 |
|
|
input bs_to_gs,
|
46 |
27 |
eightycc |
input rigs,
|
47 |
21 |
eightycc |
input [0:6] ps_reg_in, console_in,
|
48 |
|
|
input ri_addr_reg,
|
49 |
|
|
input console_to_addr_reg,
|
50 |
|
|
|
51 |
|
|
output reg[0:6] addr_th, addr_h, addr_t, addr_u,
|
52 |
|
|
output reg dynamic_addr_hit,
|
53 |
|
|
output reg addr_no_800x, addr_8000, addr_8001, addr_8002,
|
54 |
|
|
addr_8003, addr_8002_8003,
|
55 |
|
|
output reg invalid_addr
|
56 |
|
|
);
|
57 |
|
|
|
58 |
|
|
wire reset_to_0000 = (d1 & tlu_band_change)
|
59 |
|
|
| restart_a
|
60 |
|
|
| reset_8000;
|
61 |
|
|
|
62 |
|
|
always @(posedge bp)
|
63 |
|
|
if (rst) begin
|
64 |
|
|
addr_th <= `biq_0;
|
65 |
|
|
addr_h <= `biq_0;
|
66 |
|
|
addr_t <= `biq_0;
|
67 |
|
|
addr_u <= `biq_0;
|
68 |
|
|
end else if (set_8000) begin
|
69 |
|
|
addr_th <= `biq_8;
|
70 |
|
|
addr_h <= `biq_0;
|
71 |
|
|
addr_t <= `biq_0;
|
72 |
|
|
addr_u <= `biq_0;
|
73 |
|
|
end else if (reset_to_0000) begin
|
74 |
|
|
addr_th <= `biq_0;
|
75 |
|
|
addr_h <= `biq_0;
|
76 |
|
|
addr_t <= `biq_0;
|
77 |
|
|
addr_u <= `biq_0;
|
78 |
|
|
end else if (ri_addr_reg) begin
|
79 |
|
|
if (d4 | d8) addr_th <= ps_reg_in;
|
80 |
|
|
else if (d3 | d7) addr_h <= ps_reg_in;
|
81 |
|
|
else if (d2 | d6) addr_t <= ps_reg_in;
|
82 |
|
|
else if (d1 | d5) addr_u <= ps_reg_in;
|
83 |
|
|
end else if (console_to_addr_reg) begin
|
84 |
|
|
if (d4) addr_th <= console_in;
|
85 |
|
|
else if (d3) addr_h <= console_in;
|
86 |
|
|
else if (d2) addr_t <= console_in;
|
87 |
|
|
else if (d1) addr_u <= console_in;
|
88 |
|
|
end;
|
89 |
|
|
|
90 |
|
|
// Find whether next word coincides with address register (dynamic portion of address)
|
91 |
|
|
// Sample at d9:ap
|
92 |
|
|
assign q4un_p = addr_u[`biq_q4] & (w3 | w8);
|
93 |
|
|
assign q3un_p = addr_u[`biq_q3] & (w2 | w7);
|
94 |
|
|
assign q2un_p = addr_u[`biq_q2] & (w1 | w6);
|
95 |
|
|
assign q1un_p = addr_u[`biq_q1] & (w0 | w5);
|
96 |
|
|
assign q0un_p = addr_u[`biq_q0] & (w4 | w9);
|
97 |
|
|
assign b0un_p = addr_u[`biq_b0] & (w0 | w1 | w2 | w3 | w9);
|
98 |
|
|
assign b5un_p = addr_u[`biq_b5] & (w4 | w5 | w6 | w7 | w8);
|
99 |
|
|
assign q4t_p = addr_t[`biq_q4] & w9 & s3 | addr_t[`biq_q4] & ~w9 & s4;
|
100 |
|
|
assign q3t_p = addr_t[`biq_q3] & w9 & s2 | addr_t[`biq_q3] & ~w9 & s3;
|
101 |
|
|
assign q2t_p = addr_t[`biq_q2] & w9 & s1 | addr_t[`biq_q2] & ~w9 & s2;
|
102 |
|
|
assign q1t_p = addr_t[`biq_q1] & w9 & s0 | addr_t[`biq_q1] & ~w9 & s1;
|
103 |
|
|
assign q0t_p = addr_t[`biq_q0] & w9 & s4 | addr_t[`biq_q0] & ~w9 & s0;
|
104 |
|
|
assign dynamic_addr_hit_p = (q4un_p | q3un_p | q2un_p | q1un_p | q0un_p)
|
105 |
|
|
& (b0un_p | b5un_p) & (q4t_p | q3t_p | q2t_p | q1t_p | q0t_p);
|
106 |
|
|
|
107 |
|
|
// Test address register validity
|
108 |
|
|
// Test address == 0xxx or == 1xxx or == 800[0..3]
|
109 |
|
|
assign inv1_p = (addr_th[2] | addr_th[4]) | (addr_th[3] & addr_th[1])
|
110 |
|
|
| (addr_th[6] & addr_th[0]) | (addr_th[5] & addr_th[0]); // 0xxx or 1xxx or 8xxx
|
111 |
|
|
assign inv2_p = (addr_th[3] & addr_th[0]) & ~(addr_h[1] & addr_h[6]); // 80xx
|
112 |
|
|
assign inv3_p = (addr_th[3] & addr_th[0]) & ~(addr_t[1] & addr_t[6]); // 8x0x
|
113 |
|
|
assign inv4_p = (addr_th[3] & addr_th[0]) & (addr_u[0] | addr_u[2]); // 8xx[0..3]
|
114 |
|
|
assign invalid_addr_p = inv1_p | inv2_p | inv3_p | inv4_p;
|
115 |
|
|
|
116 |
|
|
// Decode 8xxx addresses
|
117 |
|
|
assign addr_8xxx_p = (addr_th[`biq_b5] & addr_th[`biq_q3]);
|
118 |
22 |
eightycc |
assign addr_8xx0_p = addr_8xxx_p & addr_u[`biq_q0];
|
119 |
|
|
assign addr_8xx1_p = addr_8xxx_p & addr_u[`biq_q1];
|
120 |
|
|
assign addr_8xx2_p = addr_8xxx_p & addr_u[`biq_q2];
|
121 |
|
|
assign addr_8xx3_p = addr_8xxx_p & addr_u[`biq_q3];
|
122 |
21 |
eightycc |
|
123 |
|
|
// Memory access error
|
124 |
27 |
eightycc |
assign mem_error_p = double_write | ((bs_to_gs | rigs) & ~dx & no_write);
|
125 |
21 |
eightycc |
|
126 |
|
|
always @(posedge ap)
|
127 |
|
|
if (rst) begin
|
128 |
|
|
invalid_addr <= 0;
|
129 |
|
|
end else if (error_reset | ri_addr_reg | console_to_addr_reg) begin
|
130 |
|
|
invalid_addr <= 0;
|
131 |
|
|
end else if (mem_error_p | invalid_addr_p) begin
|
132 |
|
|
invalid_addr <= 1;
|
133 |
|
|
end;
|
134 |
|
|
|
135 |
|
|
always @(posedge ap)
|
136 |
|
|
if (rst) begin
|
137 |
|
|
dynamic_addr_hit <= 0;
|
138 |
|
|
end else if (d9) begin
|
139 |
|
|
dynamic_addr_hit <= dynamic_addr_hit_p;
|
140 |
|
|
end else if (dx) begin
|
141 |
|
|
dynamic_addr_hit <= 0;
|
142 |
|
|
end;
|
143 |
|
|
|
144 |
|
|
always @(posedge bp)
|
145 |
|
|
if (rst) begin
|
146 |
|
|
addr_no_800x <= 1;
|
147 |
|
|
addr_8000 <= 0;
|
148 |
|
|
addr_8001 <= 0;
|
149 |
|
|
addr_8002 <= 0;
|
150 |
|
|
addr_8003 <= 0;
|
151 |
|
|
addr_8002_8003 <= 0;
|
152 |
|
|
end else begin
|
153 |
|
|
addr_no_800x <= ~addr_8xxx_p & ~invalid_addr_p;
|
154 |
|
|
addr_8000 <= addr_8xx0_p & ~invalid_addr_p;
|
155 |
|
|
addr_8001 <= addr_8xx1_p & ~invalid_addr_p;
|
156 |
|
|
addr_8002 <= addr_8xx2_p & ~invalid_addr_p;
|
157 |
|
|
addr_8003 <= addr_8xx3_p & ~invalid_addr_p;
|
158 |
|
|
addr_8002_8003 <= (addr_8xx2_p | addr_8xx3_p) & ~invalid_addr_p;
|
159 |
|
|
end;
|
160 |
|
|
|
161 |
|
|
endmodule
|