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

Subversion Repositories mcs-4

[/] [mcs-4/] [trunk/] [rtl/] [verilog/] [i4001/] [i4001_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 ROM testbench
6
//
7
// This module is a testbench for the i4001 and i4001_rom modules.
8
//
9
// This testbench instantiates i4001 and i4001_rom modules, and
10
// and enough of the i4004 system bus logic to be able to test
11
// ROM access. The testbench dumps the contents of ROM in a
12
// textual hex dump format that can be reviewed by a human; not
13
// the ideal testbench operation but useful at the time.
14
//
15
// This file is part of the MCS-4 project hosted at OpenCores:
16
//      http://www.opencores.org/cores/mcs-4/
17
//
18
// Copyright © 2021 by Reece Pollack <rrpollack@opencores.org>
19
//
20
// These materials are provided under the Creative Commons
21
// "Attribution-NonCommercial-ShareAlike" (CC BY-NC-SA) Public License.
22
// They are NOT "public domain", and are protected by copyright.
23
//
24
// This work based on materials provided by Intel Corporation and
25
// others under the same license. See the file doc/License for
26
// details of this license.
27
//
28
////////////////////////////////////////////////////////////////////////
29
 
30
module i4001_tb;
31
 
32
    localparam SYSCLK_TCY = 50;     // 20 MHz Oscillator period in ns
33
    // localparam SYSCLK_TCY = 20;     // 50 MHz Oscillator period in ns
34
 
35
    // Inputs
36
    reg         sysclk;
37
    wire        clk1;
38
    wire        clk2;
39
    reg         poc;
40
    reg         clear_pad = 1'b0;
41
 
42
    wire [11:0] rom_addr;
43
    wire [ 7:0] rom_data;
44
 
45
    // Bidirs
46
    wire [3:0]  data_pad;
47
    wire [3:0]  io_pad;
48
 
49
    // Generate a system clock
50
    always begin
51
        sysclk = 1'b0;
52
        #(SYSCLK_TCY / 2);
53
        sysclk = 1'b1;
54
        #(SYSCLK_TCY / 2);
55
    end
56
 
57
    // Instantiate the 2-phase clock generator
58
    clockgen #(
59
        .SYSCLK_TCY (SYSCLK_TCY)
60
     ) clockgen (
61
        .sysclk     (sysclk),
62
        .clk1       (clk1),
63
        .clk2       (clk2)
64
    );
65
 
66
    // Timing generator outputs
67
    wire        a12;
68
    wire        a22;
69
    wire        a32;
70
    wire        m12;
71
    wire        m22;
72
    wire        x12;
73
    wire        x22;
74
    wire        x32;
75
    wire        sync;
76
 
77
    // Generate the 8 execution phase indicators
78
    timing_generator timing_generator (
79
        .clk1   (clk1),
80
        .clk2   (clk2),
81
        .a12    (a12),
82
        .a22    (a22),
83
        .a32    (a32),
84
        .m12    (m12),
85
        .m22    (m22),
86
        .x12    (x12),
87
        .x22    (x22),
88
        .x32    (x32),
89
        .sync   (sync)
90
    );
91
 
92
    reg [3:0] opr, opa;
93
    always @(*) begin
94
        if (clk2) begin
95
            if (m12) opr <= data_pad;
96
            if (m22) opa <= data_pad;
97
        end
98
    end
99
 
100
    // Manage the CPU tristate buffers
101
    reg ior = 1'b0;
102
    reg L;
103
    always @(*) begin
104
        if (clk2)
105
            L <= a32 | m12 | (x12 & (ior | poc));
106
    end
107
 
108
    wire n0702 = ~clk2;
109
    reg n0707;
110
    always @(*) begin
111
        if (clk1) begin
112
            n0707 <=  L;
113
        end
114
    end
115
    wire n0700 = n0707 | (L & n0702) | poc;
116
 
117
 
118
    reg  [11:0] addr;
119
    reg  [ 3:0] data_out;
120
    always @(*) begin
121
        if (poc)
122
            data_out = 4'bzzzz;
123
        else begin
124
            (* PARALLEL_CASE *)
125
            case (1'b1)
126
            a12:        data_out = addr[ 3:0];
127
            a22:        data_out = addr[ 7:4];
128
            a32:        data_out = addr[11:8];
129
            m12:        data_out = 4'bxxxx;
130
            m22:        data_out = 4'bxxxx;
131
            x12:        data_out = opa;
132
            x22:        data_out = 4'b1111;
133
            x32:        data_out = 4'b1111;
134
            default:    data_out = 4'bxxxx;
135
            endcase
136
        end
137
    end
138
    assign data_pad = n0700 ? 4'bzzzz : data_out;
139
 
140
    // Instantiate the Units Under Test (UUT)
141
    i4001 #(
142
        .ROM_NUMBER (4'd0)
143
    ) rom_0 (
144
        .sysclk     (sysclk),
145
        .clk1_pad   (clk1),
146
        .clk2_pad   (clk2),
147
        .sync_pad   (sync),
148
        .poc_pad    (poc),
149
        .cmrom_pad  (a32),
150
        .data_pad   (data_pad),
151
        .io_pad     (io_pad),
152
        .clear_pad  (clear_pad),
153
        .rom_addr   (rom_addr),
154
        .rom_data   (rom_data)
155
    );
156
 
157
    i4001 #(
158
        .ROM_NUMBER (4'd1)
159
    ) rom_1 (
160
        .sysclk     (sysclk),
161
        .clk1_pad   (clk1),
162
        .clk2_pad   (clk2),
163
        .sync_pad   (sync),
164
        .poc_pad    (poc),
165
        .cmrom_pad  (a32),
166
        .data_pad   (data_pad),
167
        .io_pad     (io_pad),
168
        .clear_pad  (clear_pad),
169
        .rom_addr   (rom_addr),
170
        .rom_data   (rom_data)
171
    );
172
 
173
    i4001_rom #(
174
        .ROM_FILE   ("busicom.mem"),
175
        .ROM_NUMBER (4'd0)
176
    ) rom_store (
177
        .sysclk     (sysclk),
178
        .rom_addr   (rom_addr),
179
        .rom_data   (rom_data)
180
    );
181
 
182
 
183
    always @(posedge sync) begin
184
        if (poc)
185
            addr <= 12'h000;
186
        else begin
187
            if (addr[3:0] == 4'h0)
188
                $write("\n@%03x", addr);
189
            $write(" %x%x", opr, opa);
190
            if (addr == 1279) begin
191
                $write("\n");
192
                $finish;
193
            end
194
            addr <= addr + 1'b1;
195
        end
196
    end
197
 
198
    initial begin
199
        // Initialize Inputs
200
        poc = 1'b1;
201
        clear_pad = 1'b1;
202
 
203
        // Wait 3 SYNCs to reset
204
        @(posedge sync);
205
        @(posedge sync);
206
        @(posedge sync);
207
        #10;
208
        poc = 1'b0;
209
        clear_pad = 1'b0;
210
 
211
    end
212
 
213
endmodule
214
 

powered by: WebSVN 2.1.0

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