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

Subversion Repositories mcs-4

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 6 rrpollack
`timescale 1ns / 1ps
2
`default_nettype none
3
////////////////////////////////////////////////////////////////////////
4
//
5
// MCS-4 i4001 RAM testbench
6
//
7
// This module is a testbench for the i4002 and i4002_ram modules.
8
//
9
// This testbench instantiates an i4002 RAM module, and enough of
10
// the i4004 system bus logic to be able to test RAM access.
11
//
12
// This file is part of the MCS-4 project hosted at OpenCores:
13
//      http://www.opencores.org/cores/mcs-4/
14
//
15
// Copyright © 2021 by Reece Pollack <rrpollack@opencores.org>
16
//
17
// These materials are provided under the Creative Commons
18
// "Attribution-NonCommercial-ShareAlike" (CC BY-NC-SA) Public License.
19
// They are NOT "public domain", and are protected by copyright.
20
//
21
// This work based on materials provided by Intel Corporation and
22
// others under the same license. See the file doc/License for
23
// details of this license.
24
//
25
////////////////////////////////////////////////////////////////////////
26
 
27
module i4002_tb;
28
 
29
    localparam SYSCLK_TCY    = 20;   // sysclk period in nanoseconds
30
 
31
    // Inputs
32
    reg         rst;
33
    reg         reset;
34
    reg         cm;
35
    reg  [4:0]  ram0_addr2;
36
    reg  [4:0]  ram1_addr2;
37
    reg  [4:0]  ram2_addr2;
38
    reg  [4:0]  ram3_addr2;
39
 
40
    // Outputs
41
    wire [3:0]  oport;
42
    wire [3:0]  ram0_data2_out;
43
    wire [3:0]  ram1_data2_out;
44
    wire [3:0]  ram2_data2_out;
45
    wire [3:0]  ram3_data2_out;
46
 
47
    // Bidirs
48
    wire [3:0]  data;
49
 
50
    // Simulate the system clock
51
    reg     sysclk;
52
    always begin
53
        sysclk = 1'b0;
54
        #(SYSCLK_TCY / 2);
55
        sysclk = 1'b1;
56
        #(SYSCLK_TCY / 2);
57
    end
58
 
59
    // Instantiate a 2-phase clock generator
60
    wire    clk1, clk2;
61
    clockgen #(
62
        .SYSCLK_TCY (SYSCLK_TCY)
63
    ) clockgen (
64
        .sysclk     (sysclk),
65
        .clk1       (clk1),
66
        .clk2       (clk2)
67
    );
68
 
69
    // Generate the 8 execution phase indicators
70
    wire    a12, a22, a32, m12, m22, x12, x22, x32, sync;
71
    timing_generator timing_generator (
72
        .clk1   (clk1),
73
        .clk2   (clk2),
74
        .a12    (a12),
75
        .a22    (a22),
76
        .a32    (a32),
77
        .m12    (m12),
78
        .m22    (m22),
79
        .x12    (x12),
80
        .x22    (x22),
81
        .x32    (x32),
82
        .sync   (sync)
83
    );
84
 
85
 
86
    // Instantiate the Unit Under Test (UUT)
87
    i4002 uut (
88
        .sysclk         (sysclk),
89
        .clk1           (clk1),
90
        .clk2           (clk2),
91
        .sync           (sync),
92
        .reset          (reset),
93
        .cm             (cm),
94
        .data           (data),
95
        .oport          (oport),
96
        .ram0_addr2     (ram0_addr2),
97
        .ram0_data2_out (ram0_data2_out),
98
        .ram1_addr2     (ram1_addr2),
99
        .ram1_data2_out (ram1_data2_out),
100
        .ram2_addr2     (ram2_addr2),
101
        .ram2_data2_out (ram2_data2_out),
102
        .ram3_addr2     (ram3_addr2),
103
        .ram3_data2_out (ram3_data2_out)
104
    );
105
 
106
    reg         data_dir    = 1'b0;
107
    reg  [3:0]  data_out    = 4'bxxxx;
108
    reg  [3:0]  data_in     = 4'bxxxx;
109
    assign data = data_dir ? data_out : 4'bzzzz;
110
 
111
    initial begin
112
        // Initialize Inputs
113
        rst         = 1;
114
        reset       = 1;
115
        cm          = 0;
116
        ram0_addr2  = 5'h00;
117
        ram1_addr2  = 5'h00;
118
        ram2_addr2  = 5'h00;
119
        ram3_addr2  = 5'h00;
120
 
121
        // Wait 100 ns for global reset to finish
122
        #100;
123
        rst     = 0;
124
        @(negedge sync);
125
        reset   = 0;
126
    end
127
 
128
    // Simulate enough of a i4004 CPU to access RAM
129
    always @(*) begin
130
        data_dir = 1'b1;
131
        data_out = 4'bxxxx;
132
        cm       = 1'b0;
133
        case (1'b1)
134
                a12 :   task_a12;
135
                a22 :   task_a22;
136
                a32 :   task_a32;
137
                m12 :   task_m12;
138
                m22 :   task_m22;
139
                x12 :   task_x12;
140
                x22 :   task_x22;
141
                x32 :   task_x32;
142
            default : /* default */;
143
        endcase
144
    end
145
 
146
    //
147
    // i4004 simulation registers
148
    //
149
    //
150
    reg  [11:0] ip       = 12'h000;
151
    reg  [1:0]  chip_num = 2'b00;
152
    reg  [1:0]  reg_num  = 2'b01;
153
    reg  [3:0]  char_num = 4'ha;
154
    reg  [3:0]  acc;
155
 
156
    reg  [7:0]  rom[0:'hfff];
157
    wire [7:0]  rom_data = rom[ip];
158
    initial begin
159
`ifdef USE_READMEMH
160
        $readmemh("i4002_tb.mem", rom, 0);
161
`else
162
        rom[ 0] = 8'hFD;    // DCL
163
        rom[ 1] = 8'h21;    // SRC R0
164
        rom[ 2] = 8'hE9;    // RDM
165
        rom[ 3] = 8'hE0;    // WRM
166
        rom[ 4] = 8'h21;    // SRC R0
167
        rom[ 5] = 8'hE9;    // RDM
168
        rom[ 6] = 8'hE0;    // WRM
169
        rom[ 7] = 8'hFF;    // HLT (sim only)
170
`endif
171
    end
172
 
173
    // Capture OPR during the M1 phase
174
    reg  [3:0]  opr;
175
    always @(*) begin
176
        if (clk2 & m12)
177
            opr = data;
178
    end
179
 
180
    // Capture OPA during the M2 phase
181
    reg  [3:0]  opa;
182
    always @(*) begin
183
        if (clk2 & m22)
184
            opa = data;
185
    end
186
 
187
    // Instruction decode
188
    wire        src = (opr == 4'b0010) & opa[0];
189
    wire        io  = (opr == 4'b1110);
190
    wire        ior = io &  opa[3];
191
    wire        iow = io & ~opa[3];
192
    wire        ag  = (opr == 4'b1111);
193
    wire        iac = ag & (opa == 4'b0010);
194
 
195
    always @(*) begin
196
        if (clk2 & ior) begin
197
            acc = data;
198
        end
199
    end
200
 
201
    task task_a12();
202
    begin
203
        data_out = ip[3:0];
204
        data_dir = 1'b1;
205
    end
206
    endtask : task_a12
207
 
208
    task task_a22();
209
    begin
210
        data_out = ip[7:4];
211
    end
212
    endtask : task_a22
213
 
214
    task task_a32();
215
    begin
216
        data_out = ip[11:8];
217
        cm = 1'b1;
218
    end
219
    endtask : task_a32
220
 
221
    task task_m12();
222
    begin
223
        data_out = rom_data[7:4];
224
    end
225
    endtask : task_m12
226
 
227
    task task_m22();
228
    begin
229
        data_out = rom_data[3:0];
230
        cm = io;
231
        if (~reset) begin
232
            ip = ip + 'd1;
233
        end
234
    end
235
    endtask : task_m22
236
 
237
    task task_x12();
238
    begin
239
        data_out = opa;
240
        if ({opr, opa} == 8'hFF)
241
            $stop();
242
    end
243
    endtask : task_x12
244
 
245
    task task_x22();
246
    begin
247
        if (src) begin
248
            data_out = {chip_num, reg_num};
249
            cm       = 1'b1;
250
        end
251
        if (iow) begin
252
            data_out = acc + 'd1;
253
        end
254
        if (ior) begin
255
            data_dir = 1'b0;
256
        end
257
    end
258
    endtask : task_x22
259
 
260
    task task_x32();
261
    begin
262
        if (src) begin
263
            data_out = char_num;
264
        end
265
    end
266
    endtask : task_x32
267
 
268
 
269
endmodule

powered by: WebSVN 2.1.0

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