OpenCores
URL https://opencores.org/ocsvn/cpu8080/cpu8080/trunk

Subversion Repositories cpu8080

[/] [cpu8080/] [tags/] [update/] [project/] [testbench.v] - Blame information for rev 33

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 samiam9512
`timescale 1ns / 1ps
2
//////////////////////////////////////////////////////////////////////////////////
3
// Company: 
4
// Engineer: 
5
// 
6
// Create Date:    23:25:07 09/20/2006 
7
// Design Name: 
8
// Module Name:    testbench 
9
// Project Name:                            
10
// Target Devices: 
11
// Tool versions: 
12
// Description: 
13
//
14
// Dependencies: 
15
//
16
// Revision: 
17
// Revision 0.01 - File Created
18
// Additional Comments:                                             
19
//
20
//////////////////////////////////////////////////////////////////////////////////
21
 
22
module testbench(addr,     // Address out
23
                 data,     // Data bus
24
                 readmem,  // Memory read
25
                 writemem, // Memory write
26
                 readio,   // Read I/O space
27
                 writeio,  // Write I/O space
28
                 intr,     // Interrupt request 
29
                 inta,     // Interrupt request 
30
                 waitr,    // Wait request
31 11 samiam9512
                 r, g, b,  // vga colors
32
                 hsync_n,  // vga horizontal sync negative
33
                 vsync_n,  // vga vertical sync negative
34 18 samiam9512
                 ps2_clk,  // keyboard clock
35
                 ps2_data, // keyboard data
36 11 samiam9512
                 reset_n,  // Reset
37 18 samiam9512
                 clock,    // System clock
38
                 diag);    // diagnostic port
39 2 samiam9512
 
40
   output [15:0] addr;
41
   inout  [7:0] data;
42
   output readmem;
43
   output writemem;
44
   output readio;
45
   output writeio;
46 9 samiam9512
   output intr;
47 2 samiam9512
   output inta;
48 18 samiam9512
   output waitr;
49 11 samiam9512
   output [2:0] r, g, b; // R,G,B color output buses
50 18 samiam9512
   output hsync_n; // horizontal sync pulse
51
   output vsync_n; // vertical sync pulse
52
   input  ps2_clk;  // clock from keyboard
53
   input  ps2_data; // data from keyboard
54 11 samiam9512
   input  reset_n;
55 2 samiam9512
   input  clock;
56 18 samiam9512
   output [7:0] diag; // diagnostic 8 bit port
57 2 samiam9512
 
58 11 samiam9512
   //
59
   // Instantiations
60
   //
61
 
62 9 samiam9512
   // selector block, we only use select 1, 2 and 3
63
   select select1(addr, data, readio, writeio, romsel, ramsel, intsel,
64 18 samiam9512
                  trmsel, bootstrap, clock, reset);
65 2 samiam9512
 
66 11 samiam9512
   // 8080 CPU
67 2 samiam9512
   cpu8080 cpu(addr, data, readmem, writemem, readio, writeio, intr, inta, waitr,
68 18 samiam9512
               reset, clock);
69 11 samiam9512
 
70
   // Program rom
71 24 samiam9512
   rom rom(addr[10:0], data, romsel&readmem); // unclocked rom
72 11 samiam9512
 
73 9 samiam9512
   // neg clocked ram
74 18 samiam9512
   ram ram(addr[9:0], data, ramsel, readmem, writemem, bootstrap, clock);
75 11 samiam9512
 
76 9 samiam9512
   // neg clocked interrupt controller
77
   intcontrol intc(addr[2:0], data, writeio, readio, intsel, intr, inta, int0, int1,
78 18 samiam9512
                   int2, int3, int4, int5, int6, int7, reset, clock);
79 2 samiam9512
 
80 11 samiam9512
   // ADM3A dumb terminal
81
   terminal adm3a(addr[0], data, writeio, readio, trmsel, r, g, b, hsync_n, vsync_n,
82 18 samiam9512
                  ps2_clk, ps2_data, reset, clock, diag);
83 11 samiam9512
 
84
   // generate reset
85
   assign reset = !reset_n;
86
 
87 18 samiam9512
   // pull up or down unused lines
88
   assign int0 = 0;
89
   assign int1 = 0;
90
   assign int2 = 0;
91
   assign int3 = 0;
92
   assign int4 = 0;
93
   assign int5 = 0;
94
   assign int6 = 0;
95
   assign int7 = 0;
96
   assign waitr = 0;
97 2 samiam9512
 
98
endmodule
99
 
100
////////////////////////////////////////////////////////////////////////////////
101
//
102
// Peripheral select unit
103
//
104
// This block implements a general purpose select generator. It has 4 select
105
// units, each capable of matching up to 6 bits of address, or 1kb of address
106
// resolution. The length and base address of each generated select can be
107
// specified, and each select can be mapped either to memory or I/O. In the case
108
// of I/O, the match for the select takes place on the lower 8 bits of the
109
// address, corresponding to the 0-255 addresses in the I/O space.
110
// Note that the selects must still be qualified with readmem, writemem,
111
// readio and writeio signals at the selected peripheral.
112
//
113
// The selector itself has an I/O address of 0, but this can be moved as well.
114
// However, the selector must remain in I/O space.
115
//
116
// A special "bootstrap" mode is implemented. After power on, and until the
117
// selector is configured by the processor, both select1 and select2 will be
118
// active, along with the output signal bootstrap. These should be connected as
119
// follows:
120
//
121
// select1:   Connect to bootstrap ROM
122
// select2:   Connect to RAM
123
// bootstrap: Connect to RAM output buffers to disable them when true
124
//
125
// In bootstrap mode, ROM and RAM selects are on until the bootstrap mode is
126
// turned off by a CPU I/O operation. The bootstrap signal indicates that 
127
// bootstrap mode is active, and should be used to disable the RAM output 
128
// buffers.
129
//
130
// Because the ROM does not perform writes, and the RAM is disabled from reads,
131
// the RAM will overlay the ROM in memory, with the ROM providing read data,
132
// and the RAM accepting write data. This is sometimes called "shadow mode".
133
// What it does is allow the CPU to copy the ROM to RAM by performing a block
134
// read and write to the same address, ie., it picks up the content at each
135
// address, then writes it back, effectively copying the ROM contents to the
136
// RAM. The CPU can then program the selects, exit bootstrap mode, and then
137
// execute entirely from the RAM copy of the bootstrap ROM.
138
//
139
// Bootstrapping this way accomplishes a few ends. First, because memory
140
// is limited on a 64kb machine, it allows RAM to occupy all of memory, without
141
// having to reserve a block of space permanently for the boostrap ROM. Second,
142
// ROM is usually a lot slower than RAM nowdays, so it is common to want to
143
// run from RAM instead of trying to execute directly from ROM.
144
//
145
// The reason that we gate the RAM output buffers with the bootstrap signal,
146
// instead of trying to gate the select signal with readmem, is that the latter
147
// would generate glitches, since the readmem signal is enveloped by the 
148
// address, instead of vice versa. It also gives the RAM logic a chance to cut
149
// down on the delay of readmem to output drive enable.
150
//
151
// The Format of the registers in the select unit are:
152
//
153
//    7 6 5 4 3 2 1 0
154
// 0: C C C C X X X B - Main control register
155
// 1: X X X X X X X X - Unused
156
// 2: M M M M M M I E - Select 1 mask
157
// 3: C C C C C C X X - Select 1 compare
158
// 4: M M M M M M I E - Select 2 mask
159
// 5: C C C C C C X X - Select 2 compare
160
// 6: M M M M M M I E - Select 3 mask
161
// 7: C C C C C C X X - Select 3 compare
162
// 8: M M M M M M I E - Select 4 mask
163 9 samiam9512
// 9: C C C C C C X X - Select 4 compare
164 2 samiam9512
//
165
// The main control bits 7:4 contain the one of 16 base addresses for the
166
// select controller. It occupies 16 locations in the address space, of
167
// which only 9 are actually used. The compare bits reset to 0, so that the
168
// select unit occupies the I/O addresses $00-$0A on power up. The base address
169
// can be changed by writing the main control register, and the new address will
170
// take place on the next access. The select unit can only be addressed in the
171
// I/O space.
172
//
173
// The bootstrap bit is reset to 1, and can be written to 0 to turn off 
174
// bootstrap mode.
175
//
176
 
177
module select(addr, data, readio, writeio, select1, select2, select3, select4,
178
              bootstrap, clock, reset);
179
 
180
   input [15:0] addr;      // CPU address
181
   inout [7:0]  data;      // CPU data bus
182
   input        readio;    // I/O read
183
   input        writeio;   // I/O write
184
   output       select1;   // select 1
185
   output       select2;   // select 1
186
   output       select3;   // select 1
187
   output       select4;   // select 1
188
   output       bootstrap; // bootstrap status
189
   input        clock;     // CPU clock
190
   input        reset;     // reset
191
   reg          bootstrap; // bootstrap mode
192
 
193
   reg [7:4]    seladr; // base I/O address of selector
194
   reg [7:0]    datai; // internal data
195
 
196
   assign selacc = seladr == addr[7:4]; // form selector access
197
   assign accmain = selacc && (addr[3:1] == 3'b000); // select main
198
   assign acca = selacc && (addr[3:1] == 3'b001); // select 1
199
   assign accb = selacc && (addr[3:1] == 3'b010); // select 2
200
   assign accc = selacc && (addr[3:1] == 3'b011); // select 3
201
   assign accd = selacc && (addr[3:1] == 3'b100); // select 4
202
 
203
   // Control access to main select unit address. This has to be clocked to
204
   // activate the address only after the cycle is over.
205
   always @(posedge clock)
206
      if (reset) begin
207
 
208
         seladr <= 4'b0; // clear master select
209
         bootstrap <= 1; // enable bootstrap mode
210
 
211
      end else if (writeio&accmain) begin
212
 
213
         seladr <= data[7:4]; // write master select
214
         bootstrap <= data[0]; // write bootstrap mode bit
215
 
216
      end else if (readio&accmain)
217
         datai <= {seladr, 4'b0}; // read master select
218
 
219
   selectone selecta(addr, data, writeio, readio, acca, select1i, reset);
220
   selectone selectb(addr, data, writeio, readio, accb, select2i, reset);
221
   selectone selectc(addr, data, writeio, readio, accc, select3, reset);
222
   selectone selectd(addr, data, writeio, readio, accd, select4, reset);
223
 
224
   assign data = readio&accmain ? datai: 8'bz; // enable output data
225
 
226
   assign select1 = select1i | bootstrap; // enable select 1 via bootstrap
227
   assign select2 = select2i | bootstrap; // enable select 2 via bootstrap
228
 
229
endmodule
230
 
231
//
232
// Individual select cell.
233
//
234
// This cell contains the mask and compare registers for each address. It
235
// handles the write and read of these registers, and forms a select signal
236
// based on them.
237
//
238
// Each register pair has the appearance:
239
//
240
//    7 6 5 4 3 2 1 0 
241
//   ================
242
// 0: M M M M M M I E - Mask register.
243
// 1: C C C C C C X X - Compare register.
244
//
245
// The mask register selects which bits will be used to form the compare
246
// value. This can be used to select any size from the combinations:
247
//
248
// 1 1 1 1 1 1 - Any 1kb block of memory, or 4 I/O address bits.
249
// 1 1 1 1 1 0 - Any 2kb block of memory, or 8 I/O address bits.
250
// 1 1 1 1 0 0 - Any 4kb block of memory, or 16 I/O address bits.
251
// 1 1 1 0 0 0 - Any 8kb block of memory, or 32 I/O address bits.
252
// 1 1 0 0 0 0 - Any 16kb block of memory, or 64 I/O address bits.
253
// 1 0 0 0 0 0 - Any 32kb block of memory, or 128 I/O address bits.
254
// 0 0 0 0 0 0 - All 64kb of memory, or all 256 I/O addresses
255
//
256
// Each block must be on its size, so for example, a 16kb block can only
257
// be on one of 4 positions in memory. If you use a pattern that isn't
258
// listed above, you are on your own to figure out the consequences.
259
// The selector does not weed out bad combinations, and you can select
260
// multiple blocks at once.
261
//
262
// Each of the mask and compare bytes can be both read and written.
263
//
264
// Note that the lower bits of the compare register aren't used, and always
265
// return zero.
266
//
267
// On reset, the mask and compare registers are both set to zero, which leaves
268
// the select block disabled.
269
//
270
 
271
module selectone(addr, data, write, read, selectin, selectout, reset);
272
 
273
   input [15:0] addr;     // address to match, 6 bits
274
   inout [7:0] data;      // CPU data
275
   input       write;     // CPU write
276
   input       read;      // CPU read
277
   input       selectin;  // select for read/write
278
   output      selectout; // resulting select
279
   input       reset;     // reset
280
 
281
   reg  [7:0] mask;  // mask/control, 7:2 is mask, 1: I/O or /mem, 0: on/off
282
   reg  [7:2] comp;  // Compare value
283
   wire [5:0] iaddr; // multiplexed address
284
   reg  [7:0] datai; // data from output selector
285
 
286
   // select what part of address, upper or lower byte, we compare, based on
287
   // I/O or memory address
288
   assign iaddr = mask[1] ? addr[7:2]: addr[15:10];
289
 
290
   // Form select based on match
291
   assign selectout = ((iaddr & mask[7:2]) == comp) & mask[0];
292
 
293 9 samiam9512
   always @(addr, write, read, reset, selectin, data, comp, mask)
294 2 samiam9512
      if (reset) begin
295
 
296
      comp <= 6'b0; // clear registers
297
      mask <= 8'b0;
298
 
299
   end else if (write&selectin) begin
300
 
301
      if (addr[0]) comp <= data[7:2]; // write comparitor data
302
      else mask <= data; // write mask data
303
 
304
   end else begin
305
 
306
      if (addr[0]) datai <= {comp, 2'b0}; // read comparitor data
307
      else datai <= mask; // read mask data
308
 
309
   end
310
 
311
   assign data = read&selectin ? datai: 8'bz; // enable output data
312
 
313
endmodule
314
 
315 9 samiam9512
////////////////////////////////////////////////////////////////////////////////
316
//
317
// INTERRUPT CONTROLLER
318
//
319
// Implements an 8 input interrupt controller. Each of the 8 interrupt lines has
320
// selectable positive edge, negative edge, positive level, and negative level
321
// triggering. Interrupts can be masked, and can be examined for state even when
322
// they are masked. Each interrupt can be triggered under software control.
323
// The priority for interrupts is fixed, with 0 being the highest, and 7 being
324
// the lowest.
325
//
326
// The controller can be connected to I/O or memory addresses. The control
327
// registers appear as:
328
//
329
//     7 6 5 4 3 2 1 0
330
// 00: M M M M M M M M - Mask register
331
// 01: S S S S S S S S - Status register
332
// 02: A A A A A A A A - Active register
333
// 03: P P P P P P P P - Polarity register
334
// 04: E E E E E E E E - Edge enable register
335
// 05: B B B B B B B B - Vector base address
336
//
337
// The mask register indicates if the interrupt source is to generate an 
338
// interrupt. If the associated bit is 1, the interrupt is enabled, otherwise
339
// disabled.
340
//
341
// The status register indicates the current interrupt line status, for direct
342
// polling purposes.
343
//
344
// The active register is a flip/flop that goes to 1 anytime the trigger 
345
// condition is satisfied. A 1 in this register will cause an interrupt to 
346
// occur. If the mask for the interrupt is not enabled, the active bit will not
347
// be set no matter what the trigger states.
348
//
349
// The polarity register gives the line polarity that will trigger an interrupt.
350
// If the edge trigger bit is set, then the polarity indicates the resulting 
351
// line AFTER the trigger. For example, an edge trigger with a 1 in the polarity
352
// register indicates that the trigger is a positive edge trigger.
353
//
354
// The edge enable register places an edge detector on the line. This will
355
// cause the interrupt to be triggered when an appropriate edge indicated by the
356
// polarity occurs. The edge mode is selected by a 1 bit, and the level mode is
357
// selected by a 0 bit. If the level mode is selected, the interrupt will occur
358
// anytime the interrupt line matches the state of the polarity bit.
359
//
360
// The vector registers each provide the lower 8 bits of a 16 bit vector for 
361
// each interrupt.
362
//
363
// The base register provides the upper 8 bits of a 16 bit vector for each
364
// interrupt.
365
//
366
// An interrupt is generated anytime any bit is true in the active register. 
367
// The interrupt request line is set true, and the controller will hold until
368
// an interrupt acknowledge occurs. When an interrupt acknowledge occurs, the
369
// controller will cycle through a three step sequence, with each sequence
370
// activated by the interrupt acknowledge signal.
371
//
372
// First, a $cd is placed on the data lines, indicating a call instruction.
373
// Second, the number of the interrupt that is highest priority is multipled 
374
// * 4, and this is placed on the data lines.
375
// Third, the vector base address is placed on the data lines.
376
//
377
// The net result is that the CPU is vectored to one of 256 pages in the address
378
// space, with an offset of 4 bytes for each interrupt, as follows:
379
//
380
// 00: Vector 0
381
// 04: Vector 1
382
// 08: Vector 2
383
// 0C: Vector 3
384
// 10: Vector 4
385
// 14: Vector 5
386
// 18: Vector 6
387
// 1C: Vector 7
388
//
389
 
390
module intcontrol(addr, data, write, read, select, intr, inta, int0, int1, int2,
391
                  int3, int4, int5, int6, int7, reset, clock);
392
 
393
   input [2:0] addr;   // control register address
394
   inout [7:0] data;   // CPU data
395
   input       write;  // CPU write
396
   input       read;   // CPU read
397
   input       select; // controller select
398
   output      intr;   // interrupt request
399
   input       inta;   // interrupt acknowledge
400
   input       int0;   // interrupt line 0
401
   input       int1;   // interrupt line 1
402
   input       int2;   // interrupt line 2
403
   input       int3;   // interrupt line 3
404
   input       int4;   // interrupt line 4
405
   input       int5;   // interrupt line 5
406
   input       int6;   // interrupt line 6
407
   input       int7;   // interrupt line 7
408
   input       reset;  // CPU reset
409
   input       clock;  // CPU clock
410
 
411
   reg [7:0] mask;     // interrupt mask register
412
   reg [7:0] active;   // interrupt active register
413
   reg [7:0] polarity; // interrupt polarity register
414
   reg [7:0] edges;    // interrupt edge control
415
   reg [7:0] vbase;    // vector base
416
   reg [7:0] intpe;    // positive edge interrupt detection
417
   reg [7:0] intne;    // negative edge interrupt detection
418
   reg [7:0] datai; // data from output selector
419
   reg [3:0] state; // state machine to run vectors
420 11 samiam9512
 
421 9 samiam9512
   wire [7:0] activep;  // interrupt active pending
422
 
423 11 samiam9512
   // handle register reads and writes  
424 9 samiam9512
 
425
   always @(negedge clock)
426
      if (reset) begin // reset
427
 
428
      mask     <= 8'b0; // clear mask
429
      active   <= 8'b0; // clear active
430
      polarity <= 8'b0; // clear polarity
431
      edges    <= 8'b0; // clear edge
432
      vbase    <= 8'b0; // clear base
433
      state    <= 4'b0; // clear state machine
434
 
435
   end else if (write&select) begin // CPU write
436
 
437
      case (addr)
438
 
439
         0: mask     <= data; // set mask register
440
         2: active   <= data|activep; // set active register
441
         3: polarity <= data; // set polarity register
442
         4: edges    <= data; // set edge register
443
         5: vbase    <= data; // set base register
444
 
445
      endcase
446
 
447
   end else if (read&select) begin // CPU read
448
 
449
      case (addr)
450
 
451
         0: datai <= mask; // get mask register
452
         // get current line statuses
453
         1: datai <= { int7, int6, int5, int4, int3, int2, int1, int0 };
454
         2: datai <= active; // get active register
455
         3: datai <= polarity; // get polarity register
456
         4: datai <= edges; // get edge register
457
         5: datai <= vbase; // get base register
458
 
459
      endcase
460
 
461
   end else if (inta) begin // CPU interrupt acknowledge 
462
 
463
      // run vectoring state machine
464
      case (state)
465
 
466
         // wait for inta, and assert 1st instruction byte
467
 
468
         0: begin
469
 
470
            datai <= 8'hcd; // place call instruction on datalines
471
            state <= 1; // advance to low address
472
 
473
         end
474
 
475
         // assert low byte address
476
         1: begin
477
 
478
            // decode priority
479
            if (active&8'h01)      datai <= 8'h00;
480
            else if (active&8'h02) datai <= 8'h04;
481
            else if (active&8'h04) datai <= 8'h08;
482
            else if (active&8'h08) datai <= 8'h0C;
483
            else if (active&8'h10) datai <= 8'h10;
484
            else if (active&8'h20) datai <= 8'h14;
485
            else if (active&8'h40) datai <= 8'h18;
486
            else if (active&8'h80) datai <= 8'h1C;
487
            state <= 2; // advance to high address
488
 
489
         end
490
 
491
         // assert high address
492
         2: if (inta) begin
493
 
494
            datai <= vbase; // place page to vector
495
            // reset highest priority interrupt
496
            if (active&8'h01)      active[0] <= activep[0];
497
            else if (active&8'h02) active[1] <= activep[1];
498
            else if (active&8'h04) active[2] <= activep[2];
499
            else if (active&8'h08) active[3] <= activep[3];
500
            else if (active&8'h10) active[4] <= activep[4];
501
            else if (active&8'h20) active[5] <= activep[5];
502
            else if (active&8'h40) active[6] <= activep[6];
503
            else if (active&8'h80) active[7] <= activep[7];
504
            state <= 0; // back to start state
505
 
506
         end
507
 
508
      endcase
509
 
510
   end else active <= active|activep; // set active interrupts
511
 
512
   // form active interrupt bits
513
   assign activep = mask & (({ int7, int6, int5, int4, // levels
514
                               int3, int2, int1, int0 }^polarity & ~edges)|
515
                           (intpe&polarity&edges)| // positive edges
516
                           (intne&~polarity&edges)); // negative edges
517
 
518
   // form interrupt edges
519
   always @(posedge int0) intpe[0] <= 1;
520
   always @(posedge int1) intpe[1] <= 1;
521
   always @(posedge int2) intpe[2] <= 1;
522
   always @(posedge int3) intpe[3] <= 1;
523
   always @(posedge int4) intpe[4] <= 1;
524
   always @(posedge int5) intpe[5] <= 1;
525
   always @(posedge int6) intpe[6] <= 1;
526
   always @(posedge int7) intpe[7] <= 1;
527
   always @(negedge int0) intne[0] <= 1;
528
   always @(negedge int1) intne[1] <= 1;
529
   always @(negedge int2) intne[2] <= 1;
530
   always @(negedge int3) intne[3] <= 1;
531
   always @(negedge int4) intne[4] <= 1;
532
   always @(negedge int5) intne[5] <= 1;
533
   always @(negedge int6) intne[6] <= 1;
534
   always @(negedge int7) intne[7] <= 1;
535
 
536
   assign data = read&select|inta ? datai: 8'bz; // enable output data
537
   assign intr = |active; // request interrupt on any active
538
 
539
endmodule
540 11 samiam9512
 
541 9 samiam9512
////////////////////////////////////////////////////////////////////////////////
542
//
543
// ROM CELL
544
//
545
// Hold the test instructions. Forms a simple read only cell, with tri-state
546
// enable outputs only.
547
//
548
 
549 2 samiam9512
module rom(addr, data, dataeno);
550
 
551 24 samiam9512
   input [10:0] addr;
552 2 samiam9512
   inout [7:0] data;
553
   input dataeno;
554
 
555
   reg [7:0] datao;
556 24 samiam9512
 
557 2 samiam9512
   always @(addr) case (addr)
558
 
559 18 samiam9512
      `include "test.rom" // get contents of memory
560 2 samiam9512
 
561
      default datao = 8'h76; // hlt
562
 
563
   endcase
564
 
565
   // Enable drive for data output
566
   assign data = dataeno ? datao: 8'bz;
567
 
568
endmodule
569
 
570 9 samiam9512
////////////////////////////////////////////////////////////////////////////////
571
//
572
// RAM CELL
573
//
574
// A clocked ram cell with individual select, read and write signals. Data is
575
// written on the positive edge when write is true. Data is enabled for output
576
// by the read signal asyncronously.
577
//
578
// A bootstrap mode is implemented that, when true, overrides the read signal
579
// and keeps the output drivers off.
580
//
581
 
582 2 samiam9512
module ram(addr, data, select, read, write, bootstrap, clock);
583
 
584
   input [9:0] addr;
585
   inout [7:0] data;
586
   input select;
587
   input read;
588
   input write;
589
   input clock;
590
   input bootstrap;
591
 
592
   reg [7:0] ramcore [1023:0]; // The ram store
593
   reg [7:0] datao;
594
 
595 9 samiam9512
   always @(negedge clock)
596 2 samiam9512
      if (select) begin
597
 
598
         if (write) ramcore[addr] <= data;
599
         datao <= ramcore[addr];
600
 
601
      end
602
 
603
   // Enable drive for data output
604
   assign data = (select&read&~bootstrap) ? datao: 8'bz;
605
 
606
endmodule

powered by: WebSVN 2.1.0

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