OpenCores
URL https://opencores.org/ocsvn/mcs-4/mcs-4/trunk

Subversion Repositories mcs-4

[/] [mcs-4/] [trunk/] [rtl/] [verilog/] [i4004/] [alu.v] - Blame information for rev 6

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 rrpollack
`timescale 1ns / 1ps
2
`default_nettype none
3
////////////////////////////////////////////////////////////////////////
4 6 rrpollack
//
5 2 rrpollack
// 4004 Arithmetic Logic Unit
6 6 rrpollack
//
7 2 rrpollack
// This file is part of the MCS-4 project hosted at OpenCores:
8
//      http://www.opencores.org/cores/mcs-4/
9 6 rrpollack
//
10
// Copyright © 2012, 2021 by Reece Pollack <rrpollack@opencores.org>
11
//
12 2 rrpollack
// These materials are provided under the Creative Commons
13 6 rrpollack
// "Attribution-NonCommercial-ShareAlike" (CC BY-NC-SA) Public License.
14
// They are NOT "public domain", and are protected by copyright.
15
//
16 2 rrpollack
// This work based on materials provided by Intel Corporation and
17
// others under the same license. See the file doc/License for
18
// details of this license.
19
//
20
////////////////////////////////////////////////////////////////////////
21
 
22
module alu(
23 6 rrpollack
    input  wire         sysclk,
24 2 rrpollack
 
25 6 rrpollack
    // Inputs from the Timing and I/O board
26
    input  wire         a12,
27
    input  wire         m12,
28
    input  wire         x12,
29
    input  wire         poc,
30 2 rrpollack
 
31 6 rrpollack
    // Common 4-bit data bus
32
    inout  wire [3:0]   data,
33 2 rrpollack
 
34 6 rrpollack
    // Outputs to the Instruction Decode board
35
    output wire         acc_0,
36
    output wire         add_0,
37
    output reg          cy_1,
38 2 rrpollack
 
39 6 rrpollack
    // Inputs from the Instruction Decode board
40
    input  wire         cma,
41
    input  wire         write_acc_1,
42
    input  wire         write_carry_2,
43
    input  wire         read_acc_3,
44
    input  wire         add_group_4,
45
    input  wire         inc_group_5,
46
    input  wire         sub_group_6,
47
    input  wire         ior,
48
    input  wire         iow,
49
    input  wire         ral,
50
    input  wire         rar,
51
    input  wire         ope_n,
52
    input  wire         daa,
53
    input  wire         dcl,
54
    input  wire         inc_isz,
55
    input  wire         kbp,
56
    input  wire         o_ib,
57
    input  wire         tcs,
58
    input  wire         xch,
59
    input  wire         n0342,
60
    input  wire         x21_clk2,
61
    input  wire         x31_clk2,
62
    input  wire         com_n,
63 2 rrpollack
 
64 6 rrpollack
    // Outputs to external pins
65
    output wire         cmram0,
66
    output wire         cmram1,
67
    output wire         cmram2,
68
    output wire         cmram3,
69
    output wire         cmrom
70
    );
71 2 rrpollack
 
72 6 rrpollack
    reg [3:0]   acc;
73
    reg         cy;
74 2 rrpollack
 
75 6 rrpollack
    // Decode logic
76
    wire n0854      = ~(~x12);
77
    wire n0351      = ~(x21_clk2 | ~dcl);
78
    wire n0415      = ~(x21_clk2 | ope_n);
79
    wire add_ib     = ~(x31_clk2 | ~inc_isz);
80
    wire cy_ib      = ~(x31_clk2 | ~iow);
81
    wire acb_ib     = ~((x31_clk2 | ~xch) & (x21_clk2 | ~iow));
82
    wire n0477      = ~((~x31_clk2 & ~ior) | (a12 & ior));
83
    wire adc_cy     = ~(write_carry_2 | n0477);
84
    wire add_acc    = ~(write_acc_1 | n0477);
85
    wire adsr       = ~(x31_clk2 | ~rar);
86
    wire adsl       = ~(x31_clk2 | ~ral);
87
    wire acc_adac   = ~(~cma | n0342);
88
    wire acc_ada    = ~(read_acc_3 | n0342);
89
    wire cy_ada     = ~(add_group_4 | n0342);
90
    wire cy_adac    = ~(sub_group_6 | n0342);
91 2 rrpollack
 
92 6 rrpollack
    // Latch the incoming data bus
93
    reg [3:0] tmp;                  // It's the name used in simulator!
94
    always @(posedge sysclk) begin
95
        if (~n0342)
96
            tmp <= data;
97
        if (m12)
98
            tmp <= 4'b1111;
99
    end
100 2 rrpollack
 
101 6 rrpollack
    // Invert some of the incoming data
102
    reg n0893, n0891, n0889, n0887; // D3, D2, D1, D0
103
    always @(posedge sysclk) begin
104
        if (sub_group_6) begin
105
            n0887 <=  tmp[0];
106
            n0889 <= ~tmp[1];
107
            n0891 <=  tmp[2];
108
            n0893 <= ~tmp[3];
109
        end
110
        if (~(sub_group_6 | m12)) begin
111
            n0887 <= ~tmp[0];
112
            n0889 <=  tmp[1];
113
            n0891 <= ~tmp[2];
114
            n0893 <=  tmp[3];
115
        end
116
    end
117 2 rrpollack
 
118 6 rrpollack
    // Feedback from Accumulator
119
    reg n0873, n0872, n0871, n0870;
120
    always @(posedge sysclk) begin
121
        if (acc_ada)
122
            {n0873, n0872, n0871, n0870} <= acc ^ 4'b1010;
123
        if (acc_adac)
124
            {n0873, n0872, n0871, n0870} <= acc ^ 4'b0101;
125
        if (m12)
126
            {n0873, n0872, n0871, n0870} <= 4'b1010;
127
    end
128 2 rrpollack
 
129 6 rrpollack
    // Carry generator
130
    wire n0546 = ~(inc_group_5 | n0342);
131
    reg n0550;
132
    always @(posedge sysclk) begin
133
        if (m12)        n0550 <= 1'b0;
134
        if (n0546)      n0550 <= 1'b1;
135
        if (cy_adac)    n0550 <= ~cy;
136
        if (cy_ada)     n0550 <= cy;
137
    end
138
    wire n0911 = ~(n0550 ? (n0887 | n0870) : (n0887 & n0870));
139
    wire n0553 = n0911;
140
    wire n0912 = ~(n0553 ? (n0889 | n0871) : (n0889 & n0871));
141
    wire n0556 = n0912;
142
    wire n0913 = ~(n0556 ? (n0891 | n0872) : (n0891 & n0872));
143
    wire n0559 = n0913;
144
    wire n0914 = ~(n0559 ? (n0893 | n0873) : (n0893 & n0873));
145
    wire n0861 = n0914;
146 2 rrpollack
 
147 6 rrpollack
    // Adder
148
    wire n0878 = ~((n0887 & n0550 & n0870) | (n0553 & (n0887 | n0870 | n0550)));
149
    wire n0875 = ~((n0889 & n0553 & n0871) | (n0556 & (n0889 | n0871 | n0553)));
150
    wire n0879 = ~((n0891 & n0556 & n0872) | (n0559 & (n0891 | n0872 | n0556)));
151
    wire n0877 = ~((n0893 & n0559 & n0873) | (n0861 & (n0893 | n0873 | n0559)));
152
    wire n0846 = ~n0878;
153
    wire n0847 =  n0875;
154
    wire n0848 = ~n0879;
155
    wire n0514 =  n0877;
156
 
157
    // Shifter / Accumulator and Carry
158
    reg [3:0] acc_out;                  // {n0356, n0348, n0347, n0346}
159
    wire n0803 = ~((acc_out[3] & (acc_out[2] | acc_out[1])) | cy_1);
160
    wire n0403 = ~(~daa | n0803);
161
    wire [3:0] acc_in = {n0514, n0848, n0847, n0846};
162
    always @(posedge sysclk) begin
163
        if (adsr)
164
            {acc, cy} <= {cy_1, acc_in};
165
        if (add_acc)
166
            acc <= acc_in;
167
        if (adsl)
168
            {cy, acc} <= {acc_in, cy_1};
169
        if (adc_cy)
170
            cy <= n0861;
171
        if (n0403 & n0415)
172
            cy <= 1'b1;
173
        // Dynamic refresh would occur during M12
174
    end
175
 
176
    // Accumulator output latch
177
    always @(posedge sysclk) begin
178
        if (n0854) begin
179
            cy_1 <= cy;
180
            acc_out <= acc;
181
        end
182
    end
183
    assign acc_0 = ~|acc_out;
184
    assign add_0 = ~|acc_in;
185
 
186
    // Keyboard Process logic
187
    wire n0378 = ~((daa & n0803) | o_ib);
188
    wire n0345 =  kbp & (acc_out == 4'b1000);
189
    wire n0354 =  kbp & (acc_out == 4'b0100);
190
    wire n0363 =  kbp & (acc_out == 4'b0010);
191
    wire n0370 =  kbp & (acc_out == 4'b0001);
192
    wire n0377 = (kbp & (acc_out == 4'b0000)) | ~n0378;
193
    wire n0358 = ~(n0345 | n0354 | n0363 | n0370 | n0377 |       n0403);
194
    wire n0366 = ~(        n0354 | n0363 | n0370 | n0377 | tcs        );
195
    wire n0359 = ~(n0345 |                 n0370 | n0377 | tcs        );
196
    wire n0357 = ~(n0345 |         n0363 |         n0377 |       n0403);
197
 
198
    // Data output mux
199
    reg [3:0] dout;
200
    always @(*) begin
201
        dout = 4'bzzzz;
202
        if (acb_ib)
203
            dout = acc_out;
204
        if (add_ib)
205
            dout = acc_in;
206
        if (cy_ib)
207
            dout = {3'bxxx, cy_1};
208
        if (n0415)
209
            dout = {n0358, n0366, n0359, n0357};
210
    end
211
    assign data = dout;
212
 
213
    // Generate CMROM / CMRAMn
214
    // This may get moved to the Timing & I/O board
215
    // Inputs: {n0355, n0364, n0371}, n0351, poc, com_n
216
    wire n0355 = ~acc_out[2];
217
    wire n0364 = ~acc_out[1];
218
    wire n0371 = ~acc_out[0];
219
    reg n0749, n0750, n0751;
220
    always @(posedge sysclk) begin
221
        if (poc) begin
222
            n0749 <= 1'b1;
223
            n0750 <= 1'b1;
224
            n0751 <= 1'b1;
225
        end
226
        else begin
227
            if (n0351) begin
228
                n0749 <= n0355;
229
                n0750 <= n0364;
230
                n0751 <= n0371;
231
            end
232
        end
233
    end
234
 
235
    assign cmram3 = ~(com_n | n0749);
236
    assign cmram2 = ~(com_n | n0750);
237
    assign cmram1 = ~(com_n | n0751);
238
    assign cmram0 = ~(com_n | ~n0749 | ~n0750 | ~n0751);
239
    assign cmrom  = ~(com_n | poc);
240
 
241 2 rrpollack
endmodule

powered by: WebSVN 2.1.0

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