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

Subversion Repositories mcs-4

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

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 rrpollack
`timescale 1ns / 1ps
2
`default_nettype none
3
////////////////////////////////////////////////////////////////////////
4
// 
5
// 4004 Instruction Pointer Array
6
// 
7
// This file is part of the MCS-4 project hosted at OpenCores:
8
//      http://www.opencores.org/cores/mcs-4/
9
// 
10 4 rrpollack
// Copyright © 2012, 2020 by Reece Pollack <rrpollack@opencores.org>
11 2 rrpollack
// 
12
// These materials are provided under the Creative Commons
13
// "Attribution-NonCommercial-ShareAlike" Public License. They
14
// are NOT "public domain" and are protected by copyright.
15
// 
16
// 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 instruction_pointer (
23
        input  wire                     sysclk,                                 // 50 MHz FPGA clock
24
 
25
        // Inputs from the Timing and I/O board
26
        input  wire                     clk1,
27
        input  wire                     clk2,
28
        input  wire                     a12,
29
        input  wire                     a22,
30
        input  wire                     a32,
31
        input  wire                     m12,
32
        input  wire                     m22,
33
        input  wire                     x12,
34
        input  wire                     x22,
35
        input  wire                     x32,
36
        input  wire                     poc,                                    // Power-On Clear (reset)
37
        input  wire                     m12_m22_clk1_m11_m12,   // M12+M22+CLK1~(M11+M12)
38
 
39
        // Common 4-bit data bus
40
        inout  wire     [3:0]    data,
41
 
42
        // Inputs from the Instruction Decode board
43
        input  wire                     jcn_isz,                                // JCN+ISZ
44
        input  wire                     jin_fin,                                // JIN+FIN
45
        input  wire                     jun_jms,                                // JUN+JMS
46
        input  wire                     cn_n,                                   // ~CN
47
        input  wire                     bbl,                                    // BBL
48
        input  wire                     jms,                                    // JMS
49
        input  wire                     sc,                                             // SC (Single Cycle)
50
        input  wire                     dc                                              // DC (Double Cycle, ~SC)
51
        );
52
 
53
        reg  [11:0]      dram_array [0:3];
54
        reg  [11:0]      dram_temp;
55
        wire  [3:0]      din_n;
56
 
57
        wire inh = (jin_fin & sc) | ((jun_jms | (jcn_isz & ~cn_n)) & dc);
58
 
59
        // Row Counter stuff
60
        wire [1:0]       addr_ptr;                               // Effective Address counter
61
        wire            addr_ptr_step;                  // CLK2(JMS&DC&M22+BBL(M22+X12+X22))
62
 
63
        assign addr_ptr_step = ~(~clk2 | ~(((m22 | x12 | x22) & bbl) |
64
                                                                           (m22 & dc & jms)));
65
        counter addr_ptr_0 (
66
                .sysclk(sysclk),
67
                .step_a(clk1),
68
                .step_b(addr_ptr_step),
69
                .q(addr_ptr[0])
70
        );
71
        counter addr_ptr_1 (
72
                .sysclk(sysclk),
73
                .step_a( addr_ptr[0]),
74
                .step_b(~addr_ptr[0]),
75
                .q(addr_ptr[1])
76
        );
77
 
78
        // Refresh counter stuff
79
        wire [1:0]       addr_rfsh;                              // Row Refresh counter
80
        wire            addr_rfsh_step;                 // (~INH)&X32&CLK2
81
 
82
        assign addr_rfsh_step = ~inh & x32 & clk2;
83
 
84
        counter addr_rfsh_0 (
85
                .sysclk(sysclk),
86
                .step_a(clk1),
87
                .step_b(addr_rfsh_step),
88
                .q(addr_rfsh[0])
89
        );
90
        counter addr_rfsh_1 (
91
                .sysclk(sysclk),
92
                .step_a( addr_rfsh[0]),
93
                .step_b(~addr_rfsh[0]),
94
                .q(addr_rfsh[1])
95
        );
96
 
97
        // Row selection mux
98
        reg  [1:0]       row;                                    // {N0409, N0420}
99
        always @(posedge sysclk) begin
100
                if (x12)
101
                        row <= addr_rfsh;
102
                if (x32)
103
                        row <= addr_ptr;
104
        end
105
 
106
 
107
        // Row Precharge/Read/Write stuff
108
        wire            precharge;                              // (~INH)(X11+X31)CLK1
109
        wire            row_read;                               // (~POC)CLK2(X12+X32)~INH
110
        wire            row_write;                              // ((~SC)(JIN+FIN))CLK1(M11+X21~INH)
111
 
112
        reg n0517;
113
        always @(posedge sysclk) begin
114
                if (clk2)
115
                        n0517 <= ~(m22 | x22);
116
        end
117
        assign precharge = ~(n0517 | inh | ~clk1);
118
 
119
        assign row_read = ~poc & clk2 & (x12 | x32) & ~inh;
120
 
121
        reg n0438;
122
        always @(posedge sysclk) begin
123
                if (clk2)
124
                        n0438 <= ~((x12 & ~inh) | a32);
125
        end
126
        assign row_write = ~(n0438 | (jin_fin & ~sc) | ~clk1);
127
 
128
 
129
        // Column Read selection stuff
130
        reg n0416;
131
        always @(posedge sysclk) begin
132
                if (clk2)
133
                        n0416 <= ~x32;
134
        end
135
        wire radb0 = ~(n0416 | clk2);
136
 
137
        reg n0384;
138
        always @(posedge sysclk) begin
139
                if (clk2)
140
                        n0384 <= ~a12;
141
        end
142
        wire radb1 = ~(n0384 | clk2);
143
 
144
        reg n0374;
145
        always @(posedge sysclk) begin
146
                if (clk2)
147
                        n0374 <= ~a22;
148
        end
149
        wire radb2 = ~(n0374 | clk2);
150
 
151
 
152
        // Column Write selection stuff
153
        wire n0322 = ~(sc | cn_n);
154
        wire wadb0 = ~(~clk2 | ~(a12 | (sc & jin_fin & x32) |
155
                                                (((jcn_isz & n0322) | (jun_jms & ~sc)) & m22)));
156
        wire wadb1 = ~(~clk2 | ~(a22 | (sc & jin_fin & x22) |
157
                                                (((jcn_isz & n0322) | (jun_jms & ~sc)) & m12)));
158
        wire wadb2 = ~(~clk2 | ~(a32 | (jun_jms & ~sc & x22)));
159
 
160
 
161
        // Manage the row data buffer
162
        always @(posedge sysclk) begin
163
                if (precharge)
164
                        dram_temp <= 12'b0;
165
 
166
                if (row_read)
167
                        dram_temp <= dram_array[row];
168
 
169
                if (wadb0)
170
                        dram_temp[ 3:0] <= ~din_n;
171
                if (wadb1)
172
                        dram_temp[ 7:4] <= ~din_n;
173
                if (wadb2)
174
                        dram_temp[11:8] <= ~din_n;
175
        end
176
 
177
        // Handle row writes
178
        always @(posedge sysclk) begin
179
                if (row_write)
180
                        dram_array[row] <= dram_temp;
181
        end
182
 
183
        // Manage the data output mux
184
        reg   [3:0]      dout;
185
        always @* begin
186
                (* PARALLEL_CASE *)
187
                case (1'b1)
188
                        radb0:          dout = dram_temp[ 3:0];
189
                        radb1:          dout = dram_temp[ 7:4];
190
                        radb2:          dout = dram_temp[11:8];
191
                        default:        dout = 4'bzzzz;
192
                endcase
193
        end
194
        assign data = dout;
195
 
196
        // Data In mux and incrementer
197
        reg [3:0] incr_in;
198
        always @(posedge sysclk) begin
199
                if (m12_m22_clk1_m11_m12)
200
                        incr_in <= data;
201
        end
202
 
203
        reg carry_out, carry_in;
204
        wire [4:0] incr_out = (a12 | ((a22 | a32) & carry_in)) ?
205
                        (incr_in + 4'b0001) : {1'b0, incr_in};
206
        always @(posedge sysclk) begin
207
                if (clk2)
208
                        carry_out <= incr_out[4];
209
                if (clk1)
210
                        carry_in <= carry_out;
211
        end
212
        assign din_n = ~incr_out[3:0];
213
 
214
endmodule

powered by: WebSVN 2.1.0

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