| 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 |
|
|
input ri_gs,
|
| 47 |
|
|
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 |
|
|
assign mem_error_p = double_write | ((bs_to_gs | ri_gs) & ~dx & no_write);
|
| 125 |
|
|
|
| 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
|