URL
https://opencores.org/ocsvn/zx_ula/zx_ula/trunk
Subversion Repositories zx_ula
Compare Revisions
- This comparison shows the changes necessary to convert path
/
- from Rev 7 to Rev 8
- ↔ Reverse comparison
Rev 7 → Rev 8
/zx_ula/branches/spectrum_48k_for_digilent_spartan3_starter_kit/rom.ngc
File deleted
\ No newline at end of file
/zx_ula/branches/spectrum_48k_for_digilent_spartan3_starter_kit/bitstreams/spartan3-1000_sp48k.bit
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
zx_ula/branches/spectrum_48k_for_digilent_spartan3_starter_kit/bitstreams/spartan3-1000_sp48k.bit
Property changes :
Deleted: svn:mime-type
## -1 +0,0 ##
-application/octet-stream
\ No newline at end of property
Index: zx_ula/branches/spectrum_48k_for_digilent_spartan3_starter_kit/bitstreams/spartan3-200_sp48k.bit
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: zx_ula/branches/spectrum_48k_for_digilent_spartan3_starter_kit/bitstreams/spartan3-200_sp48k.bit
===================================================================
--- zx_ula/branches/spectrum_48k_for_digilent_spartan3_starter_kit/bitstreams/spartan3-200_sp48k.bit (revision 7)
+++ zx_ula/branches/spectrum_48k_for_digilent_spartan3_starter_kit/bitstreams/spartan3-200_sp48k.bit (nonexistent)
zx_ula/branches/spectrum_48k_for_digilent_spartan3_starter_kit/bitstreams/spartan3-200_sp48k.bit
Property changes :
Deleted: svn:mime-type
## -1 +0,0 ##
-application/octet-stream
\ No newline at end of property
Index: zx_ula/branches/spectrum_48k_for_digilent_spartan3_starter_kit/zx_spectrum_48k.xise
===================================================================
--- zx_ula/branches/spectrum_48k_for_digilent_spartan3_starter_kit/zx_spectrum_48k.xise (revision 7)
+++ zx_ula/branches/spectrum_48k_for_digilent_spartan3_starter_kit/zx_spectrum_48k.xise (nonexistent)
@@ -1,373 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Index: zx_ula/branches/spectrum_48k_for_digilent_spartan3_starter_kit/sp48k_for_spartan3_starter_kit.ucf
===================================================================
--- zx_ula/branches/spectrum_48k_for_digilent_spartan3_starter_kit/sp48k_for_spartan3_starter_kit.ucf (revision 7)
+++ zx_ula/branches/spectrum_48k_for_digilent_spartan3_starter_kit/sp48k_for_spartan3_starter_kit.ucf (nonexistent)
@@ -1,83 +0,0 @@
-NET "clk50" LOC = "T9" | IOSTANDARD = LVCMOS33;
-# Define clock period for 50 MHz oscillator (40%/60% duty-cycle)
-# NET "clk50" PERIOD = 20.0ns HIGH 40%;
-
-NET "reset" LOC = "L14" | IOSTANDARD = LVCMOS33;
-
-# I/O
-NET "r" LOC = "E7" | IOSTANDARD = LVCMOS33;
-NET "g" LOC = "D6" | IOSTANDARD = LVCMOS33;
-NET "b" LOC = "D5" | IOSTANDARD = LVCMOS33;
-NET "i" LOC = "D7" | IOSTANDARD = LVCMOS33;
-
-NET "csync" LOC = "D8" | IOSTANDARD = LVCMOS33;
-NET "audio_out" LOC = "D10" | IOSTANDARD = LVCMOS33;
-NET "ear" LOC = "T13" | IOSTANDARD = LVCMOS33;
-
-NET "kbd_rows<0>" LOC = "E6" | IOSTANDARD = LVCMOS33;
-NET "kbd_rows<1>" LOC = "C5" | IOSTANDARD = LVCMOS33;
-NET "kbd_rows<2>" LOC = "C6" | IOSTANDARD = LVCMOS33;
-NET "kbd_rows<3>" LOC = "C7" | IOSTANDARD = LVCMOS33;
-NET "kbd_rows<4>" LOC = "C8" | IOSTANDARD = LVCMOS33;
-NET "kbd_rows<5>" LOC = "C9" | IOSTANDARD = LVCMOS33;
-NET "kbd_rows<6>" LOC = "A3" | IOSTANDARD = LVCMOS33;
-NET "kbd_rows<7>" LOC = "A4" | IOSTANDARD = LVCMOS33;
-
-NET "kbd_columns<0>" LOC = "B4" | IOSTANDARD = LVCMOS33 | PULLUP;
-NET "kbd_columns<1>" LOC = "B5" | IOSTANDARD = LVCMOS33 | PULLUP;
-NET "kbd_columns<2>" LOC = "B6" | IOSTANDARD = LVCMOS33 | PULLUP;
-NET "kbd_columns<3>" LOC = "A7" | IOSTANDARD = LVCMOS33 | PULLUP;
-NET "kbd_columns<4>" LOC = "A8" | IOSTANDARD = LVCMOS33 | PULLUP;
-
-# Debug LED's
-NET "leds<7>" LOC = "P11" | IOSTANDARD = LVCMOS33;
-NET "leds<6>" LOC = "P12" | IOSTANDARD = LVCMOS33;
-NET "leds<5>" LOC = "N12" | IOSTANDARD = LVCMOS33;
-NET "leds<4>" LOC = "P13" | IOSTANDARD = LVCMOS33;
-NET "leds<3>" LOC = "N14" | IOSTANDARD = LVCMOS33;
-NET "leds<2>" LOC = "L12" | IOSTANDARD = LVCMOS33;
-NET "leds<1>" LOC = "P14" | IOSTANDARD = LVCMOS33;
-NET "leds<0>" LOC = "K12" | IOSTANDARD = LVCMOS33;
-
-# External SRAM
-NET "sa<17>" LOC = "L3" | IOSTANDARD = LVCMOS33;
-NET "sa<16>" LOC = "K5" | IOSTANDARD = LVCMOS33;
-NET "sa<15>" LOC = "K3" | IOSTANDARD = LVCMOS33;
-NET "sa<14>" LOC = "J3" | IOSTANDARD = LVCMOS33;
-NET "sa<13>" LOC = "J4" | IOSTANDARD = LVCMOS33;
-NET "sa<12>" LOC = "H4" | IOSTANDARD = LVCMOS33;
-NET "sa<11>" LOC = "H3" | IOSTANDARD = LVCMOS33;
-NET "sa<10>" LOC = "G5" | IOSTANDARD = LVCMOS33;
-NET "sa<9>" LOC = "E4" | IOSTANDARD = LVCMOS33;
-NET "sa<8>" LOC = "E3" | IOSTANDARD = LVCMOS33;
-NET "sa<7>" LOC = "F4" | IOSTANDARD = LVCMOS33;
-NET "sa<6>" LOC = "F3" | IOSTANDARD = LVCMOS33;
-NET "sa<5>" LOC = "G4" | IOSTANDARD = LVCMOS33;
-NET "sa<4>" LOC = "L4" | IOSTANDARD = LVCMOS33;
-NET "sa<3>" LOC = "M3" | IOSTANDARD = LVCMOS33;
-NET "sa<2>" LOC = "M4" | IOSTANDARD = LVCMOS33;
-NET "sa<1>" LOC = "N3" | IOSTANDARD = LVCMOS33;
-NET "sa<0>" LOC = "L5" | IOSTANDARD = LVCMOS33;
-
-#NET "sd1<15>" LOC = "R1" | IOSTANDARD = LVCMOS33;
-#NET "sd1<14>" LOC = "P1" | IOSTANDARD = LVCMOS33;
-#NET "sd1<13>" LOC = "L2" | IOSTANDARD = LVCMOS33;
-#NET "sd1<12>" LOC = "J2" | IOSTANDARD = LVCMOS33;
-#NET "sd1<11>" LOC = "H1" | IOSTANDARD = LVCMOS33;
-#NET "sd1<10>" LOC = "F2" | IOSTANDARD = LVCMOS33;
-#NET "sd1<9>" LOC = "P8" | IOSTANDARD = LVCMOS33;
-#NET "sd1<8>" LOC = "D3" | IOSTANDARD = LVCMOS33;
-NET "sd1<7>" LOC = "B1" | IOSTANDARD = LVCMOS33;
-NET "sd1<6>" LOC = "C1" | IOSTANDARD = LVCMOS33;
-NET "sd1<5>" LOC = "C2" | IOSTANDARD = LVCMOS33;
-NET "sd1<4>" LOC = "R5" | IOSTANDARD = LVCMOS33;
-NET "sd1<3>" LOC = "T5" | IOSTANDARD = LVCMOS33;
-NET "sd1<2>" LOC = "R6" | IOSTANDARD = LVCMOS33;
-NET "sd1<1>" LOC = "T8" | IOSTANDARD = LVCMOS33;
-NET "sd1<0>" LOC = "N7" | IOSTANDARD = LVCMOS33;
-
-NET "sramce1" LOC = "P7" | IOSTANDARD = LVCMOS33;
-NET "sramub1" LOC = "T4" | IOSTANDARD = LVCMOS33;
-NET "sramlb1" LOC = "P6" | IOSTANDARD = LVCMOS33;
-NET "sramwe" LOC = "G3" | IOSTANDARD = LVCMOS33;
-NET "sramoe" LOC = "K4" | IOSTANDARD = LVCMOS33;
Index: zx_ula/branches/spectrum_48k_for_digilent_spartan3_starter_kit/ram.v
===================================================================
--- zx_ula/branches/spectrum_48k_for_digilent_spartan3_starter_kit/ram.v (revision 7)
+++ zx_ula/branches/spectrum_48k_for_digilent_spartan3_starter_kit/ram.v (nonexistent)
@@ -1,207 +0,0 @@
-`timescale 1ns / 1ps
-//////////////////////////////////////////////////////////////////////////////////
-// Company: Dept. Architecture and Computing Technology. University of Seville
-// Engineer: Miguel Angel Rodriguez Jodar. rodriguj@atc.us.es
-//
-// Create Date: 19:13:39 4-Apr-2012
-// Design Name: ZX Spectrum
-// Module Name: ram32k
-// Project Name:
-// Target Devices:
-// Tool versions:
-// Description:
-//
-// Dependencies:
-//
-// Revision:
-// Revision 1.00 - File Created
-// Additional Comments: GPL License policies apply to the contents of this file.
-//
-//////////////////////////////////////////////////////////////////////////////////
-
-/*
-This module generates a high level on "isfalling" when "a" changes from high to low.
-*/
-module getfedge (
- input clk,
- input a,
- output isfalling
- );
-
- reg sh = 1'b1;
- assign isfalling = sh & ~a;
- always @(posedge clk)
- sh <= a;
-endmodule
-
-
-/*
-This module implements a shared RAM controller. The Spartan 3 Starter Kit has two 256Kx16 SRAM chips.
-It uses half the size of one of these chips (8 bit data bus instead of 16).
-As the ZX Spectrum needs two independent memory banks, and bus cycles may happen to both at the same
-time, it's necessary to emulate those two banks with one chip.
-
-I tried a simple round-robin multiplexing, but didn't work as expected. This module is a bit more complicated
-as it implements a first-come-first-serve approach, with fixed priority scheme when several petitions happen
-at the same time.
-
-Each bank can be up to 64Kx8, so implementing a 128K memory scheme is very easy (I hope so) using this module
-and the external SRAM on board.
-
-This may be my first 100% synchronous implementation for a FPGA (that is, only one clock and all the ff's are
-activated at the same edge)
-
-*/
-module ram_controller (
- input clk,
- // Bank 1 (VRAM)
- input [15:0] a1,
- input cs1_n,
- input oe1_n,
- input we1_n,
- input [7:0] din1,
- output [7:0] dout1,
- // Bank 2 (upper RAM)
- input [15:0] a2,
- input cs2_n,
- input oe2_n,
- input we2_n,
- input [7:0] din2,
- output [7:0] dout2,
- // Outputs to actual SRAM on board
- output [17:0] sa,
- inout [7:0] sd,
- output sramce,
- output sramub,
- output sramlb,
- output sramoe,
- output sramwe
- );
-
- // Permanently enable SRAM and set it to use only LSB
- assign sramub = 1;
- assign sramlb = 0;
- assign sramce = 0;
- assign sramoe = 0;
-
- reg rsramwe = 1;
- assign sramwe = rsramwe;
-
- reg [17:0] rsa;
- reg [7:0] rsd;
- assign sa = rsa;
- assign sd = rsd;
-
- // set when there has been a high to low transition in the corresponding signal
- wire bank1read, bank1write, bank2read, bank2write;
- getfedge detectbank1read (clk, cs1_n | oe1_n, bank1read);
- getfedge detectbank2read (clk, cs2_n | oe2_n, bank2read);
- getfedge detectbank1write (clk, cs1_n | we1_n, bank1write);
- getfedge detectbank2write (clk, cs2_n | we2_n, bank2write);
-
- reg [15:0] ra1;
- reg [15:0] ra2;
- reg [7:0] rdin1;
- reg [7:0] rdin2;
-
- reg [7:0] rdout1;
- assign dout1 = rdout1;
- reg [7:0] rdout2;
- assign dout2 = rdout2;
-
- // ff's to store pending memory requests
- reg pendingreadb1 = 0;
- reg pendingwriteb1 = 0;
- reg pendingreadb2 = 0;
- reg pendingwriteb2 = 0;
-
- // ff's to store current memory requests
- reg reqreadb1 = 0;
- reg reqreadb2 = 0;
- reg reqwriteb1 = 0;
- reg reqwriteb2 = 0;
-
- reg state = 1;
- always @(posedge clk) begin
- // get requests from the two banks
- if (bank1read) begin
- ra1 <= a1;
- pendingreadb1 <= 1;
- pendingwriteb1 <= 0;
- end
- else if (bank1write) begin
- ra1 <= a1;
- rdin1 <= din1;
- pendingwriteb1 <= 1;
- pendingreadb1 <= 0;
- end
- if (bank2read) begin
- ra2 <= a2;
- pendingreadb2 <= 1;
- pendingwriteb2 <= 0;
- end
- else if (bank2write) begin
- ra2 <= a2;
- rdin2 <= din2;
- pendingwriteb2 <= 1;
- pendingreadb2 <= 0;
- end
-
- // reads from bank1 have the higher priority, then writes to bank1,
- // the reads from bank2, then writes from bank2.
- // Reads and writes to bank2 are mutually exclusive, though, as only the CPU
- // performs those operations. So they are with respect to bank1.
- case (state)
- 0 : begin
- if (reqreadb1 || reqwriteb1) begin
- rsa <= {2'b00,ra1}; // operation to bank1 accepted. We put the memory address on the SRAM address bus
- if (reqwriteb1) begin // if this is a write operation...
- pendingwriteb1 <= 0; // accept it, and mark pending operation as cleared
- rsd <= rdin1; // put the data to be written in the SRAM data bus
- rsramwe <= 0; // pulse /WE in SRAM to begin write
- end
- else begin
- pendingreadb1 <= 0; // else, this is a read operation...
- rsd <= 8'bzzzzzzzz; // disconnect the output bus from the data register to the SRAM data bus, so
- rsramwe <= 1; // we can read from the SRAM data bus itself. Deassert /WE to enable data output bus
- end
- state <= 1; // if either request has been accepted, proceed to next phase.
- end
- else if (reqreadb2 || reqwriteb2) begin // do the same with requests to bank 2...
- rsa <= {2'b01,ra2};
- if (reqwriteb2) begin
- pendingwriteb2 <= 0;
- rsd <= rdin2;
- rsramwe <= 0;
- end
- else begin
- pendingreadb2 <= 0;
- rsd <= 8'bzzzzzzzz;
- rsramwe <= 1;
- end
- state <= 1;
- end
- end
- 1 : begin
- if (reqreadb1) begin // for read requests, read the SRAM data bus and store into the corresponding data output register
- rdout1 <= sd;
- end
- else if (reqreadb2) begin
- rdout2 <= sd;
- end
- if (reqwriteb1) begin // for write requests, deassert /WE, as writting has already been happened.
- rsramwe <= 1;
- end
- else if (reqwriteb2) begin
- rsramwe <= 1;
- end
- reqreadb1 <= pendingreadb1; // current request has finished, so update current requests with pending requests to serve the next one
- reqreadb2 <= pendingreadb2;
- reqwriteb1 <= pendingwriteb1;
- reqwriteb2 <= pendingwriteb2;
- if (pendingreadb1 || pendingreadb2 || pendingwriteb1 || pendingwriteb2)
- state <= 0;
- end
- endcase
- end
-endmodule
Index: zx_ula/branches/spectrum_48k_for_digilent_spartan3_starter_kit/tv80n.v
===================================================================
--- zx_ula/branches/spectrum_48k_for_digilent_spartan3_starter_kit/tv80n.v (revision 7)
+++ zx_ula/branches/spectrum_48k_for_digilent_spartan3_starter_kit/tv80n.v (nonexistent)
@@ -1,182 +0,0 @@
-//
-// TV80 8-Bit Microprocessor Core
-// Based on the VHDL T80 core by Daniel Wallner (jesus@opencores.org)
-//
-// Copyright (c) 2004 Guy Hutchison (ghutchis@opencores.org)
-//
-// Permission is hereby granted, free of charge, to any person obtaining a
-// copy of this software and associated documentation files (the "Software"),
-// to deal in the Software without restriction, including without limitation
-// the rights to use, copy, modify, merge, publish, distribute, sublicense,
-// and/or sell copies of the Software, and to permit persons to whom the
-// Software is furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included
-// in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
-// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
-// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
-// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-// Negative-edge based wrapper allows memory wait_n signal to work
-// correctly without resorting to asynchronous logic.
-
-module tv80n (/*AUTOARG*/
- // Outputs
- m1_n, mreq_n, iorq_n, rd_n, wr_n, rfsh_n, halt_n, busak_n, A, dout,
- // Inputs
- reset_n, clk, wait_n, int_n, nmi_n, busrq_n, di
- );
-
- parameter Mode = 0; // 0 => Z80, 1 => Fast Z80, 2 => 8080, 3 => GB
- parameter T2Write = 0; // 0 => wr_n active in T3, /=0 => wr_n active in T2
- parameter IOWait = 1; // 0 => Single cycle I/O, 1 => Std I/O cycle
-
-
- input reset_n;
- input clk;
- input wait_n;
- input int_n;
- input nmi_n;
- input busrq_n;
- output m1_n;
- output mreq_n;
- output iorq_n;
- output rd_n;
- output wr_n;
- output rfsh_n;
- output halt_n;
- output busak_n;
- output [15:0] A;
- input [7:0] di;
- output [7:0] dout;
-
- reg mreq_n;
- reg iorq_n;
- reg rd_n;
- reg wr_n;
- reg nxt_mreq_n;
- reg nxt_iorq_n;
- reg nxt_rd_n;
- reg nxt_wr_n;
-
- wire cen;
- wire intcycle_n;
- wire no_read;
- wire write;
- wire iorq;
- reg [7:0] di_reg;
- wire [6:0] mcycle;
- wire [6:0] tstate;
-
- assign cen = 1;
-
- tv80_core #(Mode, IOWait) i_tv80_core
- (
- .cen (cen),
- .m1_n (m1_n),
- .iorq (iorq),
- .no_read (no_read),
- .write (write),
- .rfsh_n (rfsh_n),
- .halt_n (halt_n),
- .wait_n (wait_n),
- .int_n (int_n),
- .nmi_n (nmi_n),
- .reset_n (reset_n),
- .busrq_n (busrq_n),
- .busak_n (busak_n),
- .clk (clk),
- .IntE (),
- .stop (),
- .A (A),
- .dinst (di),
- .di (di_reg),
- .dout (dout),
- .mc (mcycle),
- .ts (tstate),
- .intcycle_n (intcycle_n)
- );
-
- always @*
- begin
- nxt_mreq_n = 1;
- nxt_rd_n = 1;
- nxt_iorq_n = 1;
- nxt_wr_n = 1;
-
- if (mcycle[0])
- begin
- if (tstate[1] || tstate[2])
- begin
- nxt_rd_n = ~ intcycle_n;
- nxt_mreq_n = ~ intcycle_n;
- nxt_iorq_n = intcycle_n;
- end
- end // if (mcycle[0])
- else
- begin
- if ((tstate[1] || tstate[2]) && !no_read && !write)
- begin
- nxt_rd_n = 1'b0;
- nxt_iorq_n = ~ iorq;
- nxt_mreq_n = iorq;
- end
- if (T2Write == 0)
- begin
- if (tstate[2] && write)
- begin
- nxt_wr_n = 1'b0;
- nxt_iorq_n = ~ iorq;
- nxt_mreq_n = iorq;
- end
- end
- else
- begin
- if ((tstate[1] || (tstate[2] && !wait_n)) && write)
- begin
- nxt_wr_n = 1'b0;
- nxt_iorq_n = ~ iorq;
- nxt_mreq_n = iorq;
- end
- end // else: !if(T2write == 0)
- end // else: !if(mcycle[0])
- end // always @ *
-
- always @(negedge clk)
- begin
- if (!reset_n)
- begin
- rd_n <= #1 1'b1;
- wr_n <= #1 1'b1;
- iorq_n <= #1 1'b1;
- mreq_n <= #1 1'b1;
- end
- else
- begin
- rd_n <= #1 nxt_rd_n;
- wr_n <= #1 nxt_wr_n;
- iorq_n <= #1 nxt_iorq_n;
- mreq_n <= #1 nxt_mreq_n;
- end // else: !if(!reset_n)
- end // always @ (posedge clk or negedge reset_n)
-
- always @(posedge clk)
- begin
- if (!reset_n)
- begin
- di_reg <= #1 0;
- end
- else
- begin
- if (tstate[2] && wait_n == 1'b1)
- di_reg <= #1 di;
- end // else: !if(!reset_n)
- end // always @ (posedge clk)
-
-endmodule // t80n
-
Index: zx_ula/branches/spectrum_48k_for_digilent_spartan3_starter_kit/ula.v
===================================================================
--- zx_ula/branches/spectrum_48k_for_digilent_spartan3_starter_kit/ula.v (revision 7)
+++ zx_ula/branches/spectrum_48k_for_digilent_spartan3_starter_kit/ula.v (nonexistent)
@@ -1,333 +0,0 @@
-`timescale 1ns / 1ps
-//////////////////////////////////////////////////////////////////////////////////
-// Company: Dept. Architecture and Computing Technology. University of Seville
-// Engineer: Miguel Angel Rodriguez Jodar. rodriguj@atc.us.es
-//
-// Create Date: 19:13:39 4-Apr-2012
-// Design Name: ZX Spectrum
-// Module Name: ula
-// Project Name:
-// Target Devices:
-// Tool versions:
-// Description:
-//
-// Dependencies:
-//
-// Revision:
-// Revision 1.00 - File Created
-// Additional Comments: GPL License policies apply to the contents of this file.
-//
-//////////////////////////////////////////////////////////////////////////////////
-
-`define cyclestart(a,b) ((a)==(b))
-`define cycleend(a,b) ((a)==(b+1))
-
-module ula(
- input clk14, // 14MHz master clock
- // CPU interfacing
- input [15:0] a, // Address bus from CPU (not all lines are used)
- input [7:0] din, // Input data bus from CPU
- output [7:0] dout, // Output data bus to CPU
- input mreq_n, // MREQ from CPU
- input iorq_n, // IORQ from CPU
- input rd_n, // RD from CPU
- input wr_n, // WR from CPU
- input rfsh_n, // RFSH from CPU
- output clkcpu, // CLK to CPU
- output msk_int_n, // Vertical retrace interrupt, to CPU
- // VRAM interfacing
- output [13:0] va, // Address bus to VRAM (16K)
- input [7:0] vramdout,// Data from VRAM to ULA/CPU
- output [7:0] vramdin,// Data from CPU to VRAM
- output vramoe, //
- output vramcs, // Control signals for VRAM
- output vramwe, //
- // ULA I/O
- input ear, //
- output mic, // I/O ports
- output spk, //
- output [7:0] kbrows, // Keyboard rows
- input [4:0] kbcolumns, // Keyboard columns
- // Video output
- output r, //
- output g, // RGB TTL signal
- output b, // with separate bright
- output i, // and composite sync
- output csync //
- );
-
- reg [2:0] BorderColor = 3'b100;
-
- // Pixel clock
- reg clk7 = 0;
- always @(posedge clk14)
- clk7 <= !clk7;
-
- // Horizontal counter
- reg [8:0] hc = 0;
- always @(posedge clk7) begin
- if (hc==447)
- hc <= 0;
- else
- hc <= hc + 1;
- end
-
- // Vertical counter
- reg [8:0] vc = 0;
- always @(posedge clk7) begin
- if (hc==447) begin
- if (vc == 311)
- vc <= 0;
- else
- vc <= vc + 1;
- end
- end
-
- // HBlank generation
- reg HBlank_n = 1;
- always @(negedge clk7) begin
- if (`cyclestart(hc,320))
- HBlank_n <= 0;
- else if (`cycleend(hc,415))
- HBlank_n <= 1;
- end
-
- // HSync generation (6C ULA version)
- reg HSync_n = 1;
- always @(negedge clk7) begin
- if (`cyclestart(hc,344))
- HSync_n <= 0;
- else if (`cycleend(hc,375))
- HSync_n <= 1;
- end
-
- // VBlank generation
- reg VBlank_n = 1;
- always @(negedge clk7) begin
- if (`cyclestart(vc,248))
- VBlank_n <= 0;
- else if (`cycleend(vc,255))
- VBlank_n <= 1;
- end
-
- // VSync generation (PAL)
- reg VSync_n = 1;
- always @(negedge clk7) begin
- if (`cyclestart(vc,248))
- VSync_n <= 0;
- else if (`cycleend(vc,251))
- VSync_n <= 1;
- end
-
- // INT generation
- reg INT_n = 1;
- assign msk_int_n = INT_n;
- always @(negedge clk7) begin
- if (`cyclestart(vc,248) && `cyclestart(hc,0))
- INT_n <= 0;
- else if (`cyclestart(vc,248) && `cycleend(hc,31))
- INT_n <= 1;
- end
-
- // Border control signal (=0 when we're not displaying paper/ink pixels)
- reg Border_n = 1;
- always @(negedge clk7) begin
- if ( (vc[7] & vc[6]) | vc[8] | hc[8])
- Border_n <= 0;
- else
- Border_n <= 1;
- end
-
- // VidEN generation (delaying Border 8 clocks)
- reg VidEN_n = 1;
- always @(negedge clk7) begin
- if (hc[3])
- VidEN_n <= !Border_n;
- end
-
- // DataLatch generation (posedge to capture data from memory)
- reg DataLatch_n = 1;
- always @(negedge clk7) begin
- if (hc[0] & !hc[1] & Border_n & hc[3])
- DataLatch_n <= 0;
- else
- DataLatch_n <= 1;
- end
-
- // AttrLatch generation (posedge to capture data from memory)
- reg AttrLatch_n = 1;
- always @(negedge clk7) begin
- if (hc[0] & hc[1] & Border_n & hc[3])
- AttrLatch_n <= 0;
- else
- AttrLatch_n <= 1;
- end
-
- // SLoad generation (negedge to load shift register)
- reg SLoad = 0;
- always @(negedge clk7) begin
- if (!hc[0] & !hc[1] & hc[2] & !VidEN_n)
- SLoad <= 1;
- else
- SLoad <= 0;
- end
-
- // AOLatch generation (negedge to update attr output latch)
- reg AOLatch_n = 1;
- always @(negedge clk7) begin
- if (hc[0] & !hc[1] & hc[2])
- AOLatch_n <= 0;
- else
- AOLatch_n <= 1;
- end
-
- // First buffer for bitmap
- reg [7:0] BitmapReg = 0;
- always @(negedge DataLatch_n) begin
- BitmapReg <= vramdout;
- end
-
- // Shift register (second bitmap register)
- reg [7:0] SRegister = 0;
- always @(negedge clk7) begin
- if (SLoad)
- SRegister <= BitmapReg;
- else
- SRegister <= {SRegister[6:0],1'b0};
- end
-
- // First buffer for attribute
- reg [7:0] AttrReg = 0;
- always @(negedge AttrLatch_n) begin
- AttrReg <= vramdout;
- end
-
- // Second buffer for attribute
- reg [7:0] AttrOut = 0;
- always @(negedge AOLatch_n) begin
- if (!VidEN_n)
- AttrOut <= AttrReg;
- else
- AttrOut <= {2'b00,BorderColor,BorderColor};
- end
-
- // Flash counter and pixel generation
- reg [4:0] FlashCnt = 0;
- always @(negedge VSync_n) begin
- FlashCnt <= FlashCnt + 1;
- end
- wire Pixel = SRegister[7] ^ (AttrOut[7] & FlashCnt[4]);
-
- // RGB generation
- reg rI,rG,rR,rB;
- assign r = rR;
- assign g = rG;
- assign b = rB;
- assign i = rI;
- always @(*) begin
- if (HBlank_n && VBlank_n)
- {rI,rG,rR,rB} = (Pixel)? {AttrOut[6],AttrOut[2:0]} : {AttrOut[6],AttrOut[5:3]};
- else
- {rI,rG,rR,rB} = 4'b0000;
- end
-
- //CSync generation
- assign csync = HSync_n & VSync_n;
-
- // VRAM address and control line generation
- reg [13:0] rVA = 0;
- reg rVCS = 0;
- reg rVOE = 0;
- reg rVWE = 0;
- assign va = rVA;
- assign vramcs = rVCS;
- assign vramoe = rVOE;
- assign vramwe = rVWE;
- // Latches to hold delayed versions of V and H counters
- reg [8:0] v = 0;
- reg [8:0] c = 0;
- // Address and control line multiplexor ULA/CPU
- always @(negedge clk7) begin
- if (Border_n && (hc[3:0]==4'b0111 || hc[3:0]==4'b1011)) begin // cycles 7 and 11: load V and C from VC and HC
- c <= hc;
- v <= vc;
- end
- end
- // Address and control line multiplexor ULA/CPU
- always @(*) begin
- if (Border_n && (hc[3:0]==4'b1000 || hc[3:0]==4'b1001 || hc[3:0]==4'b1100 || hc[3:0]==4'b1101)) begin // cycles 8 and 12: present display address to VRAM
- rVA = {1'b0,v[7:6],v[2:0],v[5:3],c[7:3]}; // (cycles 9 and 13 load display byte)
- rVCS = 1;
- rVOE = !hc[0];
- rVWE = 0;
- end
- else if (Border_n && (hc[3:0]==4'b1010 || hc[3:0]==4'b1011 || hc[3:0]==4'b1110 || hc[3:0]==4'b1111)) begin // cycles 10 and 14: present attribute address to VRAM
- rVA = {4'b0110,v[7:3],c[7:3]}; // (cycles 11 and 15 load attr byte)
- rVCS = 1;
- rVOE = !hc[0];
- rVWE = 0;
- end
- else if (Border_n && hc[3:0]==4'b0000) begin
- rVA = a[13:0];
- rVCS = 0;
- rVOE = 0;
- rVWE = 0;
- end
- else begin // when VRAM is not in use by ULA, give it to CPU
- rVA = a[13:0];
- rVCS = !a[15] & a[14] & !mreq_n;
- rVOE = !rd_n;
- rVWE = !wr_n;
- end
- end
-
- // CPU contention
- reg CPUClk = 0;
- assign clkcpu = CPUClk;
- reg ioreqtw3 = 0;
- reg mreqt23 = 0;
- wire ioreq_n = a[0] | iorq_n;
- wire Nor1 = (~(a[14] | ~ioreq_n)) |
- (~(~a[15] | ~ioreq_n)) |
- (~(hc[2] | hc[3])) |
- (~Border_n | ~ioreqtw3 | ~CPUClk | ~mreqt23);
- wire Nor2 = (~(hc[2] | hc[3])) |
- ~Border_n |
- ~CPUClk |
- ioreq_n |
- ~ioreqtw3;
- wire CLKContention = ~Nor1 | ~Nor2;
- always @(posedge clk7) begin // change clk7 by clk14 for 7MHz CPU clock operation
- if (CPUClk && !CLKContention) // if there's no contention, the clock can go low
- CPUClk <= 0;
- else
- CPUClk <= 1;
- end
- always @(posedge CPUClk) begin
- ioreqtw3 <= ioreq_n;
- mreqt23 <= mreq_n;
- end
-
- // ULA-CPU interface
- assign dout = (!a[15] & a[14] & !mreq_n)? vramdout : // CPU reads VRAM through ULA as in the +3, not directly
- (!iorq_n & !a[0])? {1'b1,ear,1'b1,kbcolumns} : // CPU reads keyboard and EAR state
- (Border_n)? AttrReg : // to emulate
- 8'hFF; // port FF
- assign vramdin = din; // The CPU doesn't need to share the memory input data bus with the ULA
- assign kbrows = {a[11]? 1'bz : 1'b0, // high impedance or 0, as if diodes were been placed in between
- a[10]? 1'bz : 1'b0, // if the keyboard matrix is to be implemented within the FPGA, then
- a[9]? 1'bz : 1'b0, // there's no need to do this.
- a[12]? 1'bz : 1'b0,
- a[13]? 1'bz : 1'b0,
- a[8]? 1'bz : 1'b0,
- a[14]? 1'bz : 1'b0,
- a[15]? 1'bz : 1'b0 };
- reg rMic = 0;
- reg rSpk = 0;
- assign mic = rMic;
- assign spk = rSpk;
- always @(negedge clk7) begin
- if (!iorq_n & !a[0] & !wr_n)
- {rSpk,rMic,BorderColor} <= din[5:0];
- end
-endmodule
Index: zx_ula/branches/xilinx/spectrum_48k_for_digilent_spartan3_starter_kit/zx_spectrum_48k.xise
===================================================================
--- zx_ula/branches/xilinx/spectrum_48k_for_digilent_spartan3_starter_kit/zx_spectrum_48k.xise (nonexistent)
+++ zx_ula/branches/xilinx/spectrum_48k_for_digilent_spartan3_starter_kit/zx_spectrum_48k.xise (revision 8)
@@ -0,0 +1,373 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Index: zx_ula/branches/xilinx/spectrum_48k_for_digilent_spartan3_starter_kit/sp48k_for_spartan3_starter_kit.ucf
===================================================================
--- zx_ula/branches/xilinx/spectrum_48k_for_digilent_spartan3_starter_kit/sp48k_for_spartan3_starter_kit.ucf (nonexistent)
+++ zx_ula/branches/xilinx/spectrum_48k_for_digilent_spartan3_starter_kit/sp48k_for_spartan3_starter_kit.ucf (revision 8)
@@ -0,0 +1,83 @@
+NET "clk50" LOC = "T9" | IOSTANDARD = LVCMOS33;
+# Define clock period for 50 MHz oscillator (40%/60% duty-cycle)
+# NET "clk50" PERIOD = 20.0ns HIGH 40%;
+
+NET "reset" LOC = "L14" | IOSTANDARD = LVCMOS33;
+
+# I/O
+NET "r" LOC = "E7" | IOSTANDARD = LVCMOS33;
+NET "g" LOC = "D6" | IOSTANDARD = LVCMOS33;
+NET "b" LOC = "D5" | IOSTANDARD = LVCMOS33;
+NET "i" LOC = "D7" | IOSTANDARD = LVCMOS33;
+
+NET "csync" LOC = "D8" | IOSTANDARD = LVCMOS33;
+NET "audio_out" LOC = "D10" | IOSTANDARD = LVCMOS33;
+NET "ear" LOC = "T13" | IOSTANDARD = LVCMOS33;
+
+NET "kbd_rows<0>" LOC = "E6" | IOSTANDARD = LVCMOS33;
+NET "kbd_rows<1>" LOC = "C5" | IOSTANDARD = LVCMOS33;
+NET "kbd_rows<2>" LOC = "C6" | IOSTANDARD = LVCMOS33;
+NET "kbd_rows<3>" LOC = "C7" | IOSTANDARD = LVCMOS33;
+NET "kbd_rows<4>" LOC = "C8" | IOSTANDARD = LVCMOS33;
+NET "kbd_rows<5>" LOC = "C9" | IOSTANDARD = LVCMOS33;
+NET "kbd_rows<6>" LOC = "A3" | IOSTANDARD = LVCMOS33;
+NET "kbd_rows<7>" LOC = "A4" | IOSTANDARD = LVCMOS33;
+
+NET "kbd_columns<0>" LOC = "B4" | IOSTANDARD = LVCMOS33 | PULLUP;
+NET "kbd_columns<1>" LOC = "B5" | IOSTANDARD = LVCMOS33 | PULLUP;
+NET "kbd_columns<2>" LOC = "B6" | IOSTANDARD = LVCMOS33 | PULLUP;
+NET "kbd_columns<3>" LOC = "A7" | IOSTANDARD = LVCMOS33 | PULLUP;
+NET "kbd_columns<4>" LOC = "A8" | IOSTANDARD = LVCMOS33 | PULLUP;
+
+# Debug LED's
+NET "leds<7>" LOC = "P11" | IOSTANDARD = LVCMOS33;
+NET "leds<6>" LOC = "P12" | IOSTANDARD = LVCMOS33;
+NET "leds<5>" LOC = "N12" | IOSTANDARD = LVCMOS33;
+NET "leds<4>" LOC = "P13" | IOSTANDARD = LVCMOS33;
+NET "leds<3>" LOC = "N14" | IOSTANDARD = LVCMOS33;
+NET "leds<2>" LOC = "L12" | IOSTANDARD = LVCMOS33;
+NET "leds<1>" LOC = "P14" | IOSTANDARD = LVCMOS33;
+NET "leds<0>" LOC = "K12" | IOSTANDARD = LVCMOS33;
+
+# External SRAM
+NET "sa<17>" LOC = "L3" | IOSTANDARD = LVCMOS33;
+NET "sa<16>" LOC = "K5" | IOSTANDARD = LVCMOS33;
+NET "sa<15>" LOC = "K3" | IOSTANDARD = LVCMOS33;
+NET "sa<14>" LOC = "J3" | IOSTANDARD = LVCMOS33;
+NET "sa<13>" LOC = "J4" | IOSTANDARD = LVCMOS33;
+NET "sa<12>" LOC = "H4" | IOSTANDARD = LVCMOS33;
+NET "sa<11>" LOC = "H3" | IOSTANDARD = LVCMOS33;
+NET "sa<10>" LOC = "G5" | IOSTANDARD = LVCMOS33;
+NET "sa<9>" LOC = "E4" | IOSTANDARD = LVCMOS33;
+NET "sa<8>" LOC = "E3" | IOSTANDARD = LVCMOS33;
+NET "sa<7>" LOC = "F4" | IOSTANDARD = LVCMOS33;
+NET "sa<6>" LOC = "F3" | IOSTANDARD = LVCMOS33;
+NET "sa<5>" LOC = "G4" | IOSTANDARD = LVCMOS33;
+NET "sa<4>" LOC = "L4" | IOSTANDARD = LVCMOS33;
+NET "sa<3>" LOC = "M3" | IOSTANDARD = LVCMOS33;
+NET "sa<2>" LOC = "M4" | IOSTANDARD = LVCMOS33;
+NET "sa<1>" LOC = "N3" | IOSTANDARD = LVCMOS33;
+NET "sa<0>" LOC = "L5" | IOSTANDARD = LVCMOS33;
+
+#NET "sd1<15>" LOC = "R1" | IOSTANDARD = LVCMOS33;
+#NET "sd1<14>" LOC = "P1" | IOSTANDARD = LVCMOS33;
+#NET "sd1<13>" LOC = "L2" | IOSTANDARD = LVCMOS33;
+#NET "sd1<12>" LOC = "J2" | IOSTANDARD = LVCMOS33;
+#NET "sd1<11>" LOC = "H1" | IOSTANDARD = LVCMOS33;
+#NET "sd1<10>" LOC = "F2" | IOSTANDARD = LVCMOS33;
+#NET "sd1<9>" LOC = "P8" | IOSTANDARD = LVCMOS33;
+#NET "sd1<8>" LOC = "D3" | IOSTANDARD = LVCMOS33;
+NET "sd1<7>" LOC = "B1" | IOSTANDARD = LVCMOS33;
+NET "sd1<6>" LOC = "C1" | IOSTANDARD = LVCMOS33;
+NET "sd1<5>" LOC = "C2" | IOSTANDARD = LVCMOS33;
+NET "sd1<4>" LOC = "R5" | IOSTANDARD = LVCMOS33;
+NET "sd1<3>" LOC = "T5" | IOSTANDARD = LVCMOS33;
+NET "sd1<2>" LOC = "R6" | IOSTANDARD = LVCMOS33;
+NET "sd1<1>" LOC = "T8" | IOSTANDARD = LVCMOS33;
+NET "sd1<0>" LOC = "N7" | IOSTANDARD = LVCMOS33;
+
+NET "sramce1" LOC = "P7" | IOSTANDARD = LVCMOS33;
+NET "sramub1" LOC = "T4" | IOSTANDARD = LVCMOS33;
+NET "sramlb1" LOC = "P6" | IOSTANDARD = LVCMOS33;
+NET "sramwe" LOC = "G3" | IOSTANDARD = LVCMOS33;
+NET "sramoe" LOC = "K4" | IOSTANDARD = LVCMOS33;
Index: zx_ula/branches/xilinx/spectrum_48k_for_digilent_spartan3_starter_kit/tv80n.v
===================================================================
--- zx_ula/branches/xilinx/spectrum_48k_for_digilent_spartan3_starter_kit/tv80n.v (nonexistent)
+++ zx_ula/branches/xilinx/spectrum_48k_for_digilent_spartan3_starter_kit/tv80n.v (revision 8)
@@ -0,0 +1,182 @@
+//
+// TV80 8-Bit Microprocessor Core
+// Based on the VHDL T80 core by Daniel Wallner (jesus@opencores.org)
+//
+// Copyright (c) 2004 Guy Hutchison (ghutchis@opencores.org)
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+// Negative-edge based wrapper allows memory wait_n signal to work
+// correctly without resorting to asynchronous logic.
+
+module tv80n (/*AUTOARG*/
+ // Outputs
+ m1_n, mreq_n, iorq_n, rd_n, wr_n, rfsh_n, halt_n, busak_n, A, dout,
+ // Inputs
+ reset_n, clk, wait_n, int_n, nmi_n, busrq_n, di
+ );
+
+ parameter Mode = 0; // 0 => Z80, 1 => Fast Z80, 2 => 8080, 3 => GB
+ parameter T2Write = 0; // 0 => wr_n active in T3, /=0 => wr_n active in T2
+ parameter IOWait = 1; // 0 => Single cycle I/O, 1 => Std I/O cycle
+
+
+ input reset_n;
+ input clk;
+ input wait_n;
+ input int_n;
+ input nmi_n;
+ input busrq_n;
+ output m1_n;
+ output mreq_n;
+ output iorq_n;
+ output rd_n;
+ output wr_n;
+ output rfsh_n;
+ output halt_n;
+ output busak_n;
+ output [15:0] A;
+ input [7:0] di;
+ output [7:0] dout;
+
+ reg mreq_n;
+ reg iorq_n;
+ reg rd_n;
+ reg wr_n;
+ reg nxt_mreq_n;
+ reg nxt_iorq_n;
+ reg nxt_rd_n;
+ reg nxt_wr_n;
+
+ wire cen;
+ wire intcycle_n;
+ wire no_read;
+ wire write;
+ wire iorq;
+ reg [7:0] di_reg;
+ wire [6:0] mcycle;
+ wire [6:0] tstate;
+
+ assign cen = 1;
+
+ tv80_core #(Mode, IOWait) i_tv80_core
+ (
+ .cen (cen),
+ .m1_n (m1_n),
+ .iorq (iorq),
+ .no_read (no_read),
+ .write (write),
+ .rfsh_n (rfsh_n),
+ .halt_n (halt_n),
+ .wait_n (wait_n),
+ .int_n (int_n),
+ .nmi_n (nmi_n),
+ .reset_n (reset_n),
+ .busrq_n (busrq_n),
+ .busak_n (busak_n),
+ .clk (clk),
+ .IntE (),
+ .stop (),
+ .A (A),
+ .dinst (di),
+ .di (di_reg),
+ .dout (dout),
+ .mc (mcycle),
+ .ts (tstate),
+ .intcycle_n (intcycle_n)
+ );
+
+ always @*
+ begin
+ nxt_mreq_n = 1;
+ nxt_rd_n = 1;
+ nxt_iorq_n = 1;
+ nxt_wr_n = 1;
+
+ if (mcycle[0])
+ begin
+ if (tstate[1] || tstate[2])
+ begin
+ nxt_rd_n = ~ intcycle_n;
+ nxt_mreq_n = ~ intcycle_n;
+ nxt_iorq_n = intcycle_n;
+ end
+ end // if (mcycle[0])
+ else
+ begin
+ if ((tstate[1] || tstate[2]) && !no_read && !write)
+ begin
+ nxt_rd_n = 1'b0;
+ nxt_iorq_n = ~ iorq;
+ nxt_mreq_n = iorq;
+ end
+ if (T2Write == 0)
+ begin
+ if (tstate[2] && write)
+ begin
+ nxt_wr_n = 1'b0;
+ nxt_iorq_n = ~ iorq;
+ nxt_mreq_n = iorq;
+ end
+ end
+ else
+ begin
+ if ((tstate[1] || (tstate[2] && !wait_n)) && write)
+ begin
+ nxt_wr_n = 1'b0;
+ nxt_iorq_n = ~ iorq;
+ nxt_mreq_n = iorq;
+ end
+ end // else: !if(T2write == 0)
+ end // else: !if(mcycle[0])
+ end // always @ *
+
+ always @(negedge clk)
+ begin
+ if (!reset_n)
+ begin
+ rd_n <= #1 1'b1;
+ wr_n <= #1 1'b1;
+ iorq_n <= #1 1'b1;
+ mreq_n <= #1 1'b1;
+ end
+ else
+ begin
+ rd_n <= #1 nxt_rd_n;
+ wr_n <= #1 nxt_wr_n;
+ iorq_n <= #1 nxt_iorq_n;
+ mreq_n <= #1 nxt_mreq_n;
+ end // else: !if(!reset_n)
+ end // always @ (posedge clk or negedge reset_n)
+
+ always @(posedge clk)
+ begin
+ if (!reset_n)
+ begin
+ di_reg <= #1 0;
+ end
+ else
+ begin
+ if (tstate[2] && wait_n == 1'b1)
+ di_reg <= #1 di;
+ end // else: !if(!reset_n)
+ end // always @ (posedge clk)
+
+endmodule // t80n
+
Index: zx_ula/branches/xilinx/spectrum_48k_for_digilent_spartan3_starter_kit/ram.v
===================================================================
--- zx_ula/branches/xilinx/spectrum_48k_for_digilent_spartan3_starter_kit/ram.v (nonexistent)
+++ zx_ula/branches/xilinx/spectrum_48k_for_digilent_spartan3_starter_kit/ram.v (revision 8)
@@ -0,0 +1,207 @@
+`timescale 1ns / 1ps
+//////////////////////////////////////////////////////////////////////////////////
+// Company: Dept. Architecture and Computing Technology. University of Seville
+// Engineer: Miguel Angel Rodriguez Jodar. rodriguj@atc.us.es
+//
+// Create Date: 19:13:39 4-Apr-2012
+// Design Name: ZX Spectrum
+// Module Name: ram32k
+// Project Name:
+// Target Devices:
+// Tool versions:
+// Description:
+//
+// Dependencies:
+//
+// Revision:
+// Revision 1.00 - File Created
+// Additional Comments: GPL License policies apply to the contents of this file.
+//
+//////////////////////////////////////////////////////////////////////////////////
+
+/*
+This module generates a high level on "isfalling" when "a" changes from high to low.
+*/
+module getfedge (
+ input clk,
+ input a,
+ output isfalling
+ );
+
+ reg sh = 1'b1;
+ assign isfalling = sh & ~a;
+ always @(posedge clk)
+ sh <= a;
+endmodule
+
+
+/*
+This module implements a shared RAM controller. The Spartan 3 Starter Kit has two 256Kx16 SRAM chips.
+It uses half the size of one of these chips (8 bit data bus instead of 16).
+As the ZX Spectrum needs two independent memory banks, and bus cycles may happen to both at the same
+time, it's necessary to emulate those two banks with one chip.
+
+I tried a simple round-robin multiplexing, but didn't work as expected. This module is a bit more complicated
+as it implements a first-come-first-serve approach, with fixed priority scheme when several petitions happen
+at the same time.
+
+Each bank can be up to 64Kx8, so implementing a 128K memory scheme is very easy (I hope so) using this module
+and the external SRAM on board.
+
+This may be my first 100% synchronous implementation for a FPGA (that is, only one clock and all the ff's are
+activated at the same edge)
+
+*/
+module ram_controller (
+ input clk,
+ // Bank 1 (VRAM)
+ input [15:0] a1,
+ input cs1_n,
+ input oe1_n,
+ input we1_n,
+ input [7:0] din1,
+ output [7:0] dout1,
+ // Bank 2 (upper RAM)
+ input [15:0] a2,
+ input cs2_n,
+ input oe2_n,
+ input we2_n,
+ input [7:0] din2,
+ output [7:0] dout2,
+ // Outputs to actual SRAM on board
+ output [17:0] sa,
+ inout [7:0] sd,
+ output sramce,
+ output sramub,
+ output sramlb,
+ output sramoe,
+ output sramwe
+ );
+
+ // Permanently enable SRAM and set it to use only LSB
+ assign sramub = 1;
+ assign sramlb = 0;
+ assign sramce = 0;
+ assign sramoe = 0;
+
+ reg rsramwe = 1;
+ assign sramwe = rsramwe;
+
+ reg [17:0] rsa;
+ reg [7:0] rsd;
+ assign sa = rsa;
+ assign sd = rsd;
+
+ // set when there has been a high to low transition in the corresponding signal
+ wire bank1read, bank1write, bank2read, bank2write;
+ getfedge detectbank1read (clk, cs1_n | oe1_n, bank1read);
+ getfedge detectbank2read (clk, cs2_n | oe2_n, bank2read);
+ getfedge detectbank1write (clk, cs1_n | we1_n, bank1write);
+ getfedge detectbank2write (clk, cs2_n | we2_n, bank2write);
+
+ reg [15:0] ra1;
+ reg [15:0] ra2;
+ reg [7:0] rdin1;
+ reg [7:0] rdin2;
+
+ reg [7:0] rdout1;
+ assign dout1 = rdout1;
+ reg [7:0] rdout2;
+ assign dout2 = rdout2;
+
+ // ff's to store pending memory requests
+ reg pendingreadb1 = 0;
+ reg pendingwriteb1 = 0;
+ reg pendingreadb2 = 0;
+ reg pendingwriteb2 = 0;
+
+ // ff's to store current memory requests
+ reg reqreadb1 = 0;
+ reg reqreadb2 = 0;
+ reg reqwriteb1 = 0;
+ reg reqwriteb2 = 0;
+
+ reg state = 1;
+ always @(posedge clk) begin
+ // get requests from the two banks
+ if (bank1read) begin
+ ra1 <= a1;
+ pendingreadb1 <= 1;
+ pendingwriteb1 <= 0;
+ end
+ else if (bank1write) begin
+ ra1 <= a1;
+ rdin1 <= din1;
+ pendingwriteb1 <= 1;
+ pendingreadb1 <= 0;
+ end
+ if (bank2read) begin
+ ra2 <= a2;
+ pendingreadb2 <= 1;
+ pendingwriteb2 <= 0;
+ end
+ else if (bank2write) begin
+ ra2 <= a2;
+ rdin2 <= din2;
+ pendingwriteb2 <= 1;
+ pendingreadb2 <= 0;
+ end
+
+ // reads from bank1 have the higher priority, then writes to bank1,
+ // the reads from bank2, then writes from bank2.
+ // Reads and writes to bank2 are mutually exclusive, though, as only the CPU
+ // performs those operations. So they are with respect to bank1.
+ case (state)
+ 0 : begin
+ if (reqreadb1 || reqwriteb1) begin
+ rsa <= {2'b00,ra1}; // operation to bank1 accepted. We put the memory address on the SRAM address bus
+ if (reqwriteb1) begin // if this is a write operation...
+ pendingwriteb1 <= 0; // accept it, and mark pending operation as cleared
+ rsd <= rdin1; // put the data to be written in the SRAM data bus
+ rsramwe <= 0; // pulse /WE in SRAM to begin write
+ end
+ else begin
+ pendingreadb1 <= 0; // else, this is a read operation...
+ rsd <= 8'bzzzzzzzz; // disconnect the output bus from the data register to the SRAM data bus, so
+ rsramwe <= 1; // we can read from the SRAM data bus itself. Deassert /WE to enable data output bus
+ end
+ state <= 1; // if either request has been accepted, proceed to next phase.
+ end
+ else if (reqreadb2 || reqwriteb2) begin // do the same with requests to bank 2...
+ rsa <= {2'b01,ra2};
+ if (reqwriteb2) begin
+ pendingwriteb2 <= 0;
+ rsd <= rdin2;
+ rsramwe <= 0;
+ end
+ else begin
+ pendingreadb2 <= 0;
+ rsd <= 8'bzzzzzzzz;
+ rsramwe <= 1;
+ end
+ state <= 1;
+ end
+ end
+ 1 : begin
+ if (reqreadb1) begin // for read requests, read the SRAM data bus and store into the corresponding data output register
+ rdout1 <= sd;
+ end
+ else if (reqreadb2) begin
+ rdout2 <= sd;
+ end
+ if (reqwriteb1) begin // for write requests, deassert /WE, as writting has already been happened.
+ rsramwe <= 1;
+ end
+ else if (reqwriteb2) begin
+ rsramwe <= 1;
+ end
+ reqreadb1 <= pendingreadb1; // current request has finished, so update current requests with pending requests to serve the next one
+ reqreadb2 <= pendingreadb2;
+ reqwriteb1 <= pendingwriteb1;
+ reqwriteb2 <= pendingwriteb2;
+ if (pendingreadb1 || pendingreadb2 || pendingwriteb1 || pendingwriteb2)
+ state <= 0;
+ end
+ endcase
+ end
+endmodule
Index: zx_ula/branches/xilinx/spectrum_48k_for_digilent_spartan3_starter_kit/ula.v
===================================================================
--- zx_ula/branches/xilinx/spectrum_48k_for_digilent_spartan3_starter_kit/ula.v (nonexistent)
+++ zx_ula/branches/xilinx/spectrum_48k_for_digilent_spartan3_starter_kit/ula.v (revision 8)
@@ -0,0 +1,333 @@
+`timescale 1ns / 1ps
+//////////////////////////////////////////////////////////////////////////////////
+// Company: Dept. Architecture and Computing Technology. University of Seville
+// Engineer: Miguel Angel Rodriguez Jodar. rodriguj@atc.us.es
+//
+// Create Date: 19:13:39 4-Apr-2012
+// Design Name: ZX Spectrum
+// Module Name: ula
+// Project Name:
+// Target Devices:
+// Tool versions:
+// Description:
+//
+// Dependencies:
+//
+// Revision:
+// Revision 1.00 - File Created
+// Additional Comments: GPL License policies apply to the contents of this file.
+//
+//////////////////////////////////////////////////////////////////////////////////
+
+`define cyclestart(a,b) ((a)==(b))
+`define cycleend(a,b) ((a)==(b+1))
+
+module ula(
+ input clk14, // 14MHz master clock
+ // CPU interfacing
+ input [15:0] a, // Address bus from CPU (not all lines are used)
+ input [7:0] din, // Input data bus from CPU
+ output [7:0] dout, // Output data bus to CPU
+ input mreq_n, // MREQ from CPU
+ input iorq_n, // IORQ from CPU
+ input rd_n, // RD from CPU
+ input wr_n, // WR from CPU
+ input rfsh_n, // RFSH from CPU
+ output clkcpu, // CLK to CPU
+ output msk_int_n, // Vertical retrace interrupt, to CPU
+ // VRAM interfacing
+ output [13:0] va, // Address bus to VRAM (16K)
+ input [7:0] vramdout,// Data from VRAM to ULA/CPU
+ output [7:0] vramdin,// Data from CPU to VRAM
+ output vramoe, //
+ output vramcs, // Control signals for VRAM
+ output vramwe, //
+ // ULA I/O
+ input ear, //
+ output mic, // I/O ports
+ output spk, //
+ output [7:0] kbrows, // Keyboard rows
+ input [4:0] kbcolumns, // Keyboard columns
+ // Video output
+ output r, //
+ output g, // RGB TTL signal
+ output b, // with separate bright
+ output i, // and composite sync
+ output csync //
+ );
+
+ reg [2:0] BorderColor = 3'b100;
+
+ // Pixel clock
+ reg clk7 = 0;
+ always @(posedge clk14)
+ clk7 <= !clk7;
+
+ // Horizontal counter
+ reg [8:0] hc = 0;
+ always @(posedge clk7) begin
+ if (hc==447)
+ hc <= 0;
+ else
+ hc <= hc + 1;
+ end
+
+ // Vertical counter
+ reg [8:0] vc = 0;
+ always @(posedge clk7) begin
+ if (hc==447) begin
+ if (vc == 311)
+ vc <= 0;
+ else
+ vc <= vc + 1;
+ end
+ end
+
+ // HBlank generation
+ reg HBlank_n = 1;
+ always @(negedge clk7) begin
+ if (`cyclestart(hc,320))
+ HBlank_n <= 0;
+ else if (`cycleend(hc,415))
+ HBlank_n <= 1;
+ end
+
+ // HSync generation (6C ULA version)
+ reg HSync_n = 1;
+ always @(negedge clk7) begin
+ if (`cyclestart(hc,344))
+ HSync_n <= 0;
+ else if (`cycleend(hc,375))
+ HSync_n <= 1;
+ end
+
+ // VBlank generation
+ reg VBlank_n = 1;
+ always @(negedge clk7) begin
+ if (`cyclestart(vc,248))
+ VBlank_n <= 0;
+ else if (`cycleend(vc,255))
+ VBlank_n <= 1;
+ end
+
+ // VSync generation (PAL)
+ reg VSync_n = 1;
+ always @(negedge clk7) begin
+ if (`cyclestart(vc,248))
+ VSync_n <= 0;
+ else if (`cycleend(vc,251))
+ VSync_n <= 1;
+ end
+
+ // INT generation
+ reg INT_n = 1;
+ assign msk_int_n = INT_n;
+ always @(negedge clk7) begin
+ if (`cyclestart(vc,248) && `cyclestart(hc,0))
+ INT_n <= 0;
+ else if (`cyclestart(vc,248) && `cycleend(hc,31))
+ INT_n <= 1;
+ end
+
+ // Border control signal (=0 when we're not displaying paper/ink pixels)
+ reg Border_n = 1;
+ always @(negedge clk7) begin
+ if ( (vc[7] & vc[6]) | vc[8] | hc[8])
+ Border_n <= 0;
+ else
+ Border_n <= 1;
+ end
+
+ // VidEN generation (delaying Border 8 clocks)
+ reg VidEN_n = 1;
+ always @(negedge clk7) begin
+ if (hc[3])
+ VidEN_n <= !Border_n;
+ end
+
+ // DataLatch generation (posedge to capture data from memory)
+ reg DataLatch_n = 1;
+ always @(negedge clk7) begin
+ if (hc[0] & !hc[1] & Border_n & hc[3])
+ DataLatch_n <= 0;
+ else
+ DataLatch_n <= 1;
+ end
+
+ // AttrLatch generation (posedge to capture data from memory)
+ reg AttrLatch_n = 1;
+ always @(negedge clk7) begin
+ if (hc[0] & hc[1] & Border_n & hc[3])
+ AttrLatch_n <= 0;
+ else
+ AttrLatch_n <= 1;
+ end
+
+ // SLoad generation (negedge to load shift register)
+ reg SLoad = 0;
+ always @(negedge clk7) begin
+ if (!hc[0] & !hc[1] & hc[2] & !VidEN_n)
+ SLoad <= 1;
+ else
+ SLoad <= 0;
+ end
+
+ // AOLatch generation (negedge to update attr output latch)
+ reg AOLatch_n = 1;
+ always @(negedge clk7) begin
+ if (hc[0] & !hc[1] & hc[2])
+ AOLatch_n <= 0;
+ else
+ AOLatch_n <= 1;
+ end
+
+ // First buffer for bitmap
+ reg [7:0] BitmapReg = 0;
+ always @(negedge DataLatch_n) begin
+ BitmapReg <= vramdout;
+ end
+
+ // Shift register (second bitmap register)
+ reg [7:0] SRegister = 0;
+ always @(negedge clk7) begin
+ if (SLoad)
+ SRegister <= BitmapReg;
+ else
+ SRegister <= {SRegister[6:0],1'b0};
+ end
+
+ // First buffer for attribute
+ reg [7:0] AttrReg = 0;
+ always @(negedge AttrLatch_n) begin
+ AttrReg <= vramdout;
+ end
+
+ // Second buffer for attribute
+ reg [7:0] AttrOut = 0;
+ always @(negedge AOLatch_n) begin
+ if (!VidEN_n)
+ AttrOut <= AttrReg;
+ else
+ AttrOut <= {2'b00,BorderColor,BorderColor};
+ end
+
+ // Flash counter and pixel generation
+ reg [4:0] FlashCnt = 0;
+ always @(negedge VSync_n) begin
+ FlashCnt <= FlashCnt + 1;
+ end
+ wire Pixel = SRegister[7] ^ (AttrOut[7] & FlashCnt[4]);
+
+ // RGB generation
+ reg rI,rG,rR,rB;
+ assign r = rR;
+ assign g = rG;
+ assign b = rB;
+ assign i = rI;
+ always @(*) begin
+ if (HBlank_n && VBlank_n)
+ {rI,rG,rR,rB} = (Pixel)? {AttrOut[6],AttrOut[2:0]} : {AttrOut[6],AttrOut[5:3]};
+ else
+ {rI,rG,rR,rB} = 4'b0000;
+ end
+
+ //CSync generation
+ assign csync = HSync_n & VSync_n;
+
+ // VRAM address and control line generation
+ reg [13:0] rVA = 0;
+ reg rVCS = 0;
+ reg rVOE = 0;
+ reg rVWE = 0;
+ assign va = rVA;
+ assign vramcs = rVCS;
+ assign vramoe = rVOE;
+ assign vramwe = rVWE;
+ // Latches to hold delayed versions of V and H counters
+ reg [8:0] v = 0;
+ reg [8:0] c = 0;
+ // Address and control line multiplexor ULA/CPU
+ always @(negedge clk7) begin
+ if (Border_n && (hc[3:0]==4'b0111 || hc[3:0]==4'b1011)) begin // cycles 7 and 11: load V and C from VC and HC
+ c <= hc;
+ v <= vc;
+ end
+ end
+ // Address and control line multiplexor ULA/CPU
+ always @(*) begin
+ if (Border_n && (hc[3:0]==4'b1000 || hc[3:0]==4'b1001 || hc[3:0]==4'b1100 || hc[3:0]==4'b1101)) begin // cycles 8 and 12: present display address to VRAM
+ rVA = {1'b0,v[7:6],v[2:0],v[5:3],c[7:3]}; // (cycles 9 and 13 load display byte)
+ rVCS = 1;
+ rVOE = !hc[0];
+ rVWE = 0;
+ end
+ else if (Border_n && (hc[3:0]==4'b1010 || hc[3:0]==4'b1011 || hc[3:0]==4'b1110 || hc[3:0]==4'b1111)) begin // cycles 10 and 14: present attribute address to VRAM
+ rVA = {4'b0110,v[7:3],c[7:3]}; // (cycles 11 and 15 load attr byte)
+ rVCS = 1;
+ rVOE = !hc[0];
+ rVWE = 0;
+ end
+ else if (Border_n && hc[3:0]==4'b0000) begin
+ rVA = a[13:0];
+ rVCS = 0;
+ rVOE = 0;
+ rVWE = 0;
+ end
+ else begin // when VRAM is not in use by ULA, give it to CPU
+ rVA = a[13:0];
+ rVCS = !a[15] & a[14] & !mreq_n;
+ rVOE = !rd_n;
+ rVWE = !wr_n;
+ end
+ end
+
+ // CPU contention
+ reg CPUClk = 0;
+ assign clkcpu = CPUClk;
+ reg ioreqtw3 = 0;
+ reg mreqt23 = 0;
+ wire ioreq_n = a[0] | iorq_n;
+ wire Nor1 = (~(a[14] | ~ioreq_n)) |
+ (~(~a[15] | ~ioreq_n)) |
+ (~(hc[2] | hc[3])) |
+ (~Border_n | ~ioreqtw3 | ~CPUClk | ~mreqt23);
+ wire Nor2 = (~(hc[2] | hc[3])) |
+ ~Border_n |
+ ~CPUClk |
+ ioreq_n |
+ ~ioreqtw3;
+ wire CLKContention = ~Nor1 | ~Nor2;
+ always @(posedge clk7) begin // change clk7 by clk14 for 7MHz CPU clock operation
+ if (CPUClk && !CLKContention) // if there's no contention, the clock can go low
+ CPUClk <= 0;
+ else
+ CPUClk <= 1;
+ end
+ always @(posedge CPUClk) begin
+ ioreqtw3 <= ioreq_n;
+ mreqt23 <= mreq_n;
+ end
+
+ // ULA-CPU interface
+ assign dout = (!a[15] & a[14] & !mreq_n)? vramdout : // CPU reads VRAM through ULA as in the +3, not directly
+ (!iorq_n & !a[0])? {1'b1,ear,1'b1,kbcolumns} : // CPU reads keyboard and EAR state
+ (Border_n)? AttrReg : // to emulate
+ 8'hFF; // port FF
+ assign vramdin = din; // The CPU doesn't need to share the memory input data bus with the ULA
+ assign kbrows = {a[11]? 1'bz : 1'b0, // high impedance or 0, as if diodes were been placed in between
+ a[10]? 1'bz : 1'b0, // if the keyboard matrix is to be implemented within the FPGA, then
+ a[9]? 1'bz : 1'b0, // there's no need to do this.
+ a[12]? 1'bz : 1'b0,
+ a[13]? 1'bz : 1'b0,
+ a[8]? 1'bz : 1'b0,
+ a[14]? 1'bz : 1'b0,
+ a[15]? 1'bz : 1'b0 };
+ reg rMic = 0;
+ reg rSpk = 0;
+ assign mic = rMic;
+ assign spk = rSpk;
+ always @(negedge clk7) begin
+ if (!iorq_n & !a[0] & !wr_n)
+ {rSpk,rMic,BorderColor} <= din[5:0];
+ end
+endmodule
Index: zx_ula/branches/xilinx/spectrum_48k_for_digilent_spartan3_starter_kit/zx_spectrum_48k.gise
===================================================================
--- zx_ula/branches/xilinx/spectrum_48k_for_digilent_spartan3_starter_kit/zx_spectrum_48k.gise (nonexistent)
+++ zx_ula/branches/xilinx/spectrum_48k_for_digilent_spartan3_starter_kit/zx_spectrum_48k.gise (revision 8)
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 11.1
+
+
+
+
+
+
+
+
+
+
Index: zx_ula/branches/xilinx/spectrum_48k_for_digilent_spartan3_starter_kit/spectrum48k_tld.v
===================================================================
--- zx_ula/branches/xilinx/spectrum_48k_for_digilent_spartan3_starter_kit/spectrum48k_tld.v (nonexistent)
+++ zx_ula/branches/xilinx/spectrum_48k_for_digilent_spartan3_starter_kit/spectrum48k_tld.v (revision 8)
@@ -0,0 +1,278 @@
+`timescale 1ns / 1ps
+//////////////////////////////////////////////////////////////////////////////////
+// Company: Dept. Architecture and Computing Technology. University of Seville
+// Engineer: Miguel Angel Rodriguez Jodar. rodriguj@atc.us.es
+//
+// Create Date: 19:13:39 4-Apr-2012
+// Design Name: ZX Spectrum
+// Module Name: tld_spartan3_sp48k
+// Project Name:
+// Target Devices:
+// Tool versions:
+// Description:
+//
+// Dependencies:
+//
+// Revision:
+// Revision 1.00 - File Created
+// Additional Comments: GPL License policies apply to the contents of this file.
+//
+//////////////////////////////////////////////////////////////////////////////////
+module tld_spartan3_sp48k (
+ input clk50,
+ input reset,
+ output r,
+ output g,
+ output b,
+ output i,
+ output csync,
+ // ULA I/O
+ input ear,
+ output audio_out,
+ output [7:0] kbd_rows,
+ input [4:0] kbd_columns,
+ // diagnostics
+ output [7:0] leds,
+ // SRAM memory
+ output [17:0] sa,
+ inout [7:0] sd1,
+ output sramce1,
+ output sramub1,
+ output sramlb1,
+ output sramoe,
+ output sramwe
+ );
+
+ // CPU signals
+ wire [15:0] a;
+ wire [7:0] cpudout;
+ wire [7:0] cpudin;
+ wire clkcpu;
+ wire mreq_n;
+ wire iorq_n;
+ wire wr_n;
+ wire rd_n;
+ wire rfsh_n;
+ wire int_n;
+
+ // VRAM signals
+ wire [13:0] va;
+ wire [7:0] vramdin;
+ wire [7:0] vramdout;
+ wire vramoe;
+ wire vramcs;
+ wire vramwe;
+
+ // I/O
+ wire mic;
+ wire spk;
+ assign audio_out = spk;
+
+ // ULA data bus
+ wire [7:0] uladout;
+ wire [7:0] uladin;
+
+ // SRAM data bus
+ wire [7:0] sramdout;
+ wire [7:0] sramdin;
+
+ // ROM data bus
+ wire [7:0] romdout;
+
+ wire sram_cs = a[15] & !mreq_n;
+ wire ula_cs = !a[0] & !iorq_n;
+ wire vram_cs = !a[15] & a[14] & !mreq_n;
+ wire port255_cs = !iorq_n && a[7:0]==8'hFF && !rd_n;
+ wire rom_cs = !a[15] & !a[14] & !mreq_n & !rd_n;
+
+ /////////////////////////////////////
+ // Master clock (14MHz) generation
+ /////////////////////////////////////
+ wire clk28mhz;
+ master_clock clock28mhz (
+ .CLKIN_IN(clk50),
+ .CLKFX_OUT(clk28mhz),
+ .CLKIN_IBUFG_OUT(),
+ .CLK0_OUT()
+ );
+ reg clk14 = 0;
+ always @(posedge clk28mhz) begin
+ clk14 = !clk14;
+ end
+ wire clkula = clk14;
+ wire clkmem = clk28mhz;
+
+ /////////////////////////////////////
+ // ROM
+ /////////////////////////////////////
+ rom the_rom (
+ .clka(clkmem),
+ .ena(rom_cs),
+ .addra(a[13:0]),
+ .douta(romdout)
+ );
+
+// /////////////////////////////////////
+// // VRAM (first 16K of RAM)
+// /////////////////////////////////////
+// vram lower_ram (
+// .clka(clkmem),
+// .addra(va),
+// .dina(vramdin),
+// .douta(vramdout),
+// .ena(vramcs),
+// .wea(vramwe)
+// );
+
+// /////////////////////////////////////
+// // SRAM (top 32K of RAM). External SRAM chip
+// /////////////////////////////////////
+// ram32k upper_ram (
+// .a(a[14:0]),
+// .cs_n(!sram_cs),
+// .oe_n(rd_n),
+// .we_n(wr_n),
+// .din(sramdin),
+// .dout(sramdout),
+// .sa(sa),
+// .sd(sd1),
+// .sramce(sramce1),
+// .sramub(sramub1),
+// .sramlb(sramlb1),
+// .sramoe(sramoe),
+// .sramwe(sramwe)
+// );
+
+ /////////////////////////////////////
+ // VRAM and upper RAM banks
+ /////////////////////////////////////
+ ram_controller vram_and_upper_ram (
+ .clk(clkmem),
+ // Bank 1 (VRAM)
+ .a1({2'b00,va}),
+ .cs1_n(!vramcs),
+ .oe1_n(!vramoe),
+ .we1_n(!vramwe),
+ .din1(vramdin),
+ .dout1(vramdout),
+ // Bank 2 (upper RAM)
+ .a2({1'b0,a[14:0]}),
+ .cs2_n(!sram_cs),
+ .oe2_n(rd_n),
+ .we2_n(wr_n),
+ .din2(sramdin),
+ .dout2(sramdout),
+ // Outputs to actual SRAM on board
+ .sa(sa),
+ .sd(sd1),
+ .sramce(sramce1),
+ .sramub(sramub1),
+ .sramlb(sramlb1),
+ .sramoe(sramoe),
+ .sramwe(sramwe)
+ );
+
+ /////////////////////////////////////
+ // The ULA
+ /////////////////////////////////////
+ ula the_ula (
+ .clk14(clkula),
+ .a(a),
+ .din(uladin),
+ .dout(uladout),
+ .mreq_n(mreq_n),
+ .iorq_n(iorq_n),
+ .rd_n(rd_n),
+ .wr_n(wr_n),
+ .rfsh_n(rfsh_n),
+ .clkcpu(clkcpu),
+ .msk_int_n(int_n),
+ .va(va),
+ .vramdout(vramdout),
+ .vramdin(vramdin),
+ .vramoe(vramoe),
+ .vramcs(vramcs),
+ .vramwe(vramwe),
+ .ear(ear),
+ .mic(mic),
+ .spk(spk),
+ .kbrows(kbd_rows),
+ .kbcolumns(kbd_columns),
+ .r(r),
+ .g(g),
+ .b(b),
+ .i(i),
+ .csync(csync)
+ );
+
+ /////////////////////////////////////
+ // The CPU Z80A
+ /////////////////////////////////////
+ tv80n cpu (
+ // Outputs
+ .m1_n(),
+ .mreq_n(mreq_n),
+ .iorq_n(iorq_n),
+ .rd_n(rd_n),
+ .wr_n(wr_n),
+ .rfsh_n(rfsh_n),
+ .halt_n(),
+ .busak_n(),
+ .A(a),
+ .dout(cpudout),
+ // Inputs
+ .reset_n(!reset),
+ .clk(clkcpu),
+ .wait_n(1'b1),
+ .int_n(int_n),
+ .nmi_n(1'b1),
+ .busrq_n(1'b1),
+ .di(cpudin)
+ );
+
+// T80s cpu (
+// // Outputs
+// .M1_n(),
+// .MREQ_n(mreq_n),
+// .IORQ_n(iorq_n),
+// .RD_n(rd_n),
+// .WR_n(wr_n),
+// .RFSH_n(rfsh_n),
+// .HALT_n(),
+// .BUSAK_n(),
+// .A(a),
+// .DO(cpudout),
+// // Inputs
+// .RESET_n(!reset),
+// .CLK_n(clkcpu),
+// .WAIT_n(1'b1),
+// .INT_n(int_n),
+// .NMI_n(1'b1),
+// .BUSRQ_n(1'b1),
+// .DI(cpudin)
+// );
+
+ /////////////////////////////////////
+ // Connecting all togther
+ /////////////////////////////////////
+ assign sramdin = cpudout;
+ assign uladin = cpudout;
+ assign cpudin = (rom_cs)? romdout :
+ (ula_cs | vram_cs | port255_cs)? uladout :
+ (sram_cs)? sramdout :
+ 8'hFF;
+
+ /////////////////////////////////////
+ // Diagnostics
+ /////////////////////////////////////
+ reg [7:0] rLeds = 8'b10000000;
+ assign leds = rLeds;
+ reg [1:0] cntleds = 2'b00;
+ always @(posedge int_n) begin
+ cntleds <= cntleds + 1;
+ if (cntleds == 2'b11) begin
+ rLeds <= { rLeds[0], rLeds[7:1] };
+ end
+ end
+
+endmodule
Index: zx_ula/branches/xilinx/spectrum_48k_for_digilent_spartan3_starter_kit/rom.v
===================================================================
--- zx_ula/branches/xilinx/spectrum_48k_for_digilent_spartan3_starter_kit/rom.v (nonexistent)
+++ zx_ula/branches/xilinx/spectrum_48k_for_digilent_spartan3_starter_kit/rom.v (revision 8)
@@ -0,0 +1,158 @@
+/*******************************************************************************
+* (c) Copyright 1995 - 2010 Xilinx, Inc. All rights reserved. *
+* *
+* This file contains confidential and proprietary information *
+* of Xilinx, Inc. and is protected under U.S. and *
+* international copyright and other intellectual property *
+* laws. *
+* *
+* DISCLAIMER *
+* This disclaimer is not a license and does not grant any *
+* rights to the materials distributed herewith. Except as *
+* otherwise provided in a valid license issued to you by *
+* Xilinx, and to the maximum extent permitted by applicable *
+* law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND *
+* WITH ALL FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES *
+* AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY, INCLUDING *
+* BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON- *
+* INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE; and *
+* (2) Xilinx shall not be liable (whether in contract or tort, *
+* including negligence, or under any other theory of *
+* liability) for any loss or damage of any kind or nature *
+* related to, arising under or in connection with these *
+* materials, including for any direct, or any indirect, *
+* special, incidental, or consequential loss or damage *
+* (including loss of data, profits, goodwill, or any type of *
+* loss or damage suffered as a result of any action brought *
+* by a third party) even if such damage or loss was *
+* reasonably foreseeable or Xilinx had been advised of the *
+* possibility of the same. *
+* *
+* CRITICAL APPLICATIONS *
+* Xilinx products are not designed or intended to be fail- *
+* safe, or for use in any application requiring fail-safe *
+* performance, such as life-support or safety devices or *
+* systems, Class III medical devices, nuclear facilities, *
+* applications related to the deployment of airbags, or any *
+* other applications that could lead to death, personal *
+* injury, or severe property or environmental damage *
+* (individually and collectively, "Critical *
+* Applications"). Customer assumes the sole risk and *
+* liability of any use of Xilinx products in Critical *
+* Applications, subject only to applicable laws and *
+* regulations governing limitations on product liability. *
+* *
+* THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS *
+* PART OF THIS FILE AT ALL TIMES. *
+*******************************************************************************/
+// The synthesis directives "translate_off/translate_on" specified below are
+// supported by Xilinx, Mentor Graphics and Synplicity synthesis
+// tools. Ensure they are correct for your synthesis tool(s).
+
+// You must compile the wrapper file rom.v when simulating
+// the core, rom. When compiling the wrapper file, be sure to
+// reference the XilinxCoreLib Verilog simulation library. For detailed
+// instructions, please refer to the "CORE Generator Help".
+
+`timescale 1ns/1ps
+
+module rom(
+ clka,
+ ena,
+ addra,
+ douta);
+
+
+input clka;
+input ena;
+input [13 : 0] addra;
+output [7 : 0] douta;
+
+// synthesis translate_off
+
+ BLK_MEM_GEN_V4_3 #(
+ .C_ADDRA_WIDTH(14),
+ .C_ADDRB_WIDTH(14),
+ .C_ALGORITHM(1),
+ .C_BYTE_SIZE(9),
+ .C_COMMON_CLK(0),
+ .C_DEFAULT_DATA("0"),
+ .C_DISABLE_WARN_BHV_COLL(0),
+ .C_DISABLE_WARN_BHV_RANGE(0),
+ .C_FAMILY("spartan3"),
+ .C_HAS_ENA(1),
+ .C_HAS_ENB(0),
+ .C_HAS_INJECTERR(0),
+ .C_HAS_MEM_OUTPUT_REGS_A(0),
+ .C_HAS_MEM_OUTPUT_REGS_B(0),
+ .C_HAS_MUX_OUTPUT_REGS_A(0),
+ .C_HAS_MUX_OUTPUT_REGS_B(0),
+ .C_HAS_REGCEA(0),
+ .C_HAS_REGCEB(0),
+ .C_HAS_RSTA(0),
+ .C_HAS_RSTB(0),
+ .C_HAS_SOFTECC_INPUT_REGS_A(0),
+ .C_HAS_SOFTECC_OUTPUT_REGS_B(0),
+ .C_INITA_VAL("0"),
+ .C_INITB_VAL("0"),
+ .C_INIT_FILE_NAME("rom.mif"),
+ .C_LOAD_INIT_FILE(1),
+ .C_MEM_TYPE(3),
+ .C_MUX_PIPELINE_STAGES(0),
+ .C_PRIM_TYPE(1),
+ .C_READ_DEPTH_A(16384),
+ .C_READ_DEPTH_B(16384),
+ .C_READ_WIDTH_A(8),
+ .C_READ_WIDTH_B(8),
+ .C_RSTRAM_A(0),
+ .C_RSTRAM_B(0),
+ .C_RST_PRIORITY_A("CE"),
+ .C_RST_PRIORITY_B("CE"),
+ .C_RST_TYPE("SYNC"),
+ .C_SIM_COLLISION_CHECK("ALL"),
+ .C_USE_BYTE_WEA(0),
+ .C_USE_BYTE_WEB(0),
+ .C_USE_DEFAULT_DATA(0),
+ .C_USE_ECC(0),
+ .C_USE_SOFTECC(0),
+ .C_WEA_WIDTH(1),
+ .C_WEB_WIDTH(1),
+ .C_WRITE_DEPTH_A(16384),
+ .C_WRITE_DEPTH_B(16384),
+ .C_WRITE_MODE_A("WRITE_FIRST"),
+ .C_WRITE_MODE_B("WRITE_FIRST"),
+ .C_WRITE_WIDTH_A(8),
+ .C_WRITE_WIDTH_B(8),
+ .C_XDEVICEFAMILY("spartan3"))
+ inst (
+ .CLKA(clka),
+ .ENA(ena),
+ .ADDRA(addra),
+ .DOUTA(douta),
+ .RSTA(),
+ .REGCEA(),
+ .WEA(),
+ .DINA(),
+ .CLKB(),
+ .RSTB(),
+ .ENB(),
+ .REGCEB(),
+ .WEB(),
+ .ADDRB(),
+ .DINB(),
+ .DOUTB(),
+ .INJECTSBITERR(),
+ .INJECTDBITERR(),
+ .SBITERR(),
+ .DBITERR(),
+ .RDADDRECC());
+
+
+// synthesis translate_on
+
+// XST black box declaration
+// box_type "black_box"
+// synthesis attribute box_type of rom is "black_box"
+
+endmodule
+
Index: zx_ula/branches/xilinx/spectrum_48k_for_digilent_spartan3_starter_kit/tv80_reg.v
===================================================================
--- zx_ula/branches/xilinx/spectrum_48k_for_digilent_spartan3_starter_kit/tv80_reg.v (nonexistent)
+++ zx_ula/branches/xilinx/spectrum_48k_for_digilent_spartan3_starter_kit/tv80_reg.v (revision 8)
@@ -0,0 +1,77 @@
+//
+// TV80 8-Bit Microprocessor Core
+// Based on the VHDL T80 core by Daniel Wallner (jesus@opencores.org)
+//
+// Copyright (c) 2004 Guy Hutchison (ghutchis@opencores.org)
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+module tv80_reg (/*AUTOARG*/
+ // Outputs
+ DOBH, DOAL, DOCL, DOBL, DOCH, DOAH,
+ // Inputs
+ AddrC, AddrA, AddrB, DIH, DIL, clk, CEN, WEH, WEL
+ );
+ input [2:0] AddrC;
+ output [7:0] DOBH;
+ input [2:0] AddrA;
+ input [2:0] AddrB;
+ input [7:0] DIH;
+ output [7:0] DOAL;
+ output [7:0] DOCL;
+ input [7:0] DIL;
+ output [7:0] DOBL;
+ output [7:0] DOCH;
+ output [7:0] DOAH;
+ input clk, CEN, WEH, WEL;
+
+ reg [7:0] RegsH [0:7];
+ reg [7:0] RegsL [0:7];
+
+ always @(posedge clk)
+ begin
+ if (CEN)
+ begin
+ if (WEH) RegsH[AddrA] <= DIH;
+ if (WEL) RegsL[AddrA] <= DIL;
+ end
+ end
+
+ assign DOAH = RegsH[AddrA];
+ assign DOAL = RegsL[AddrA];
+ assign DOBH = RegsH[AddrB];
+ assign DOBL = RegsL[AddrB];
+ assign DOCH = RegsH[AddrC];
+ assign DOCL = RegsL[AddrC];
+
+ // break out ram bits for waveform debug
+// synopsys translate_off
+ wire [7:0] B = RegsH[0];
+ wire [7:0] C = RegsL[0];
+ wire [7:0] D = RegsH[1];
+ wire [7:0] E = RegsL[1];
+ wire [7:0] H = RegsH[2];
+ wire [7:0] L = RegsL[2];
+
+ wire [15:0] IX = { RegsH[3], RegsL[3] };
+ wire [15:0] IY = { RegsH[7], RegsL[7] };
+// synopsys translate_on
+
+endmodule
+
Index: zx_ula/branches/xilinx/spectrum_48k_for_digilent_spartan3_starter_kit/rom.ngc
===================================================================
--- zx_ula/branches/xilinx/spectrum_48k_for_digilent_spartan3_starter_kit/rom.ngc (nonexistent)
+++ zx_ula/branches/xilinx/spectrum_48k_for_digilent_spartan3_starter_kit/rom.ngc (revision 8)
@@ -0,0 +1,3 @@
+XILINX-XDB 0.1 STUB 0.1 ASCII
+XILINX-XDM V1.6e
+$21740<,[o}e~g`n;"2*726&;$?,)?40528456789:;<=>?0123456789:;<=>?0123456789:;<=>?0123456789:;<=>?012305=789:;<=>?01234567892?<=>?0123456789:;<=>?012345648?:;<=>>01233@6382:;<=>?03:;=325=1;>:>>=516E1C018J:>8IKKC@03GF479H:9<;?90722A611K0>;7=>?0123<=67IJ;:H8;9276114CDNH<3O=;9FCA@F527K?;?M=<;0123756C:O401235567<9:9<=??0103456?89:JIH9?812;<=6D0?;:>?;=357A73E78=23?>L<41934577:;OH==>>5D0572>0N>O>438M3H=<<;01A74>678=>;:OJ90@217DD7>:N?I8796DC75DG>1>L>M97MFB@3201F1>99H?6JB9023@2739:8<=O7D00;BD478::JONLNF@003G17:=?;8I=9A5@B636?98979362616?80;?<=>?01214G@ANOOH:>6L30033G0D;;;?8=5?0931B16?KJ<><<=<1971167E8=>3<=<>D8014A2>8:K?=9>;300377>388?8JH7;0:23E=3B;J?JMHH;=>JNCC12=D1111;3M<>71@50<<@098N<:L>6BB63?56DK?:<54?=4@:665E709?;=?<>700;5=6?8<2;=5M<8@471A601:;35;L<9DF1116<89N2459<7C@A01E39=8:<7C750F5E6JML<:N:69305B2>AN=;JF<91;M=IJO;6K9C@A2=CF;0;>J;<=5G;06FGFNMK?<6>>01272361=>8>4>>?21:5446?89:>8N>I2EG;727FK9:;38J=H<5:?;13;1<31=1:;:46:14G24D>600ON5O==3D16G@1401N>92O:=NC52844BBK8K>8;79B8;26@>E8>:>O5;77E6E3A51K1<8449MD2336DG1>:H3=4L:5C5B05=7:9:;4=>=0123<56589:;4=>?8127456389:9<=:?0127456589:;>=>?2123<57382:9<=<701:34535;>;<=??0133552589:;99<95B5F436789>;7=<=0123456789:;<=6?05234165;HN?5;767C@EB=10J12=IHH>6GAE67?AI93:N9>4030;7;9M?O?A021E17?KKNMNL;:45;:1171>9L3=?:941324466:?9:8?664193612508:=896:25C561G3I;>?>8<;2401436681::<8:98=>:E1274>65?8=;O8JMCB0A2DB0:K2N8NML95FBE45>L1HJ:9K<39607225>L=M>::LC9:B7227398H=?L>225;700CM;I>>=:>C@5B776D=8O;H:MN9G7G1230?;KJ85EFE@C12N=:06013B15BCLKK8859MB7CF<54EI9<>8=5?3103GFC7>===5O?:032B255701:9?9M94D;AAC>B11K3=966091B4706<9N=857;0:20EA67:6F71147B??>OHH5LI8126007A?KN8;>88CG2A@L;;?<9882214A>BN?01234F538;9H>H=?2547455D89:;<=>?01234567898;8;>?25234567<91;8=>=81234564K:>;:>><232001E38:I;8=>>0122446789:;<8>92661056789:?<6>;0923654388:?<56=41:3454781:2=96=EE7550C389;9IH8<0B1A6FBE:J;8M::?;161640B8;;=O5;M8831606E?8?1?INK>81C64@07>;:<8O7896;<=26808?<9?=0567076>998;49<;1027652681298;447105=72;9N:H3OL69A4F1=A1382:?JK69DEDF=CEEL:NH>L:666D7=7ECLD8:>;7=8;4B;622E7JO32=407CAG04C=MHNJ89JEC1054G>L1?O>8=M45G115C6=?I??J9813526B@74>61MHJD147346DJ;8=OIO?322G3G7?1K9?89:=EB16A6273909K?<8;C@207F341O<2N>9840CFB4EB;=:0<:99C70@740AN0>I788LN::K:6BAF7433@A50AM=:ON;K;0:24@<66?1=;<9>?1B66=641:8:HOH>?C7CE351E0=>?3C33F=E3L89I>N8J0763?5>5K13:O:8N49664<048=K;H5;?21:3G47>008:546720F25F4>KH28?:?3:M;M?49:1=7568K>8=>MJ86DEGA34:0K=8O9?8BC@<054<91;5>?=D@AF2761=?OJJ?:K56A33EA065>4099I49JL6536BA3BLJ:?<6>63D322255=?H8=;7L130;0<>7M08J<>:>40G33=428>2;0123=F27;J:<4;:?;1C35CBD?OO9OOH?39C55ACF=OIN>N??C9D01CDA09I;9LLIF5@5=6350>H:>8K7D5284D77:1>?<=>?536B4D2F=??;H>9012305=7IM:;9H6<2807A<43:0I;566:32F778=;JJ>10:?9:J?99A@6CC382:IN=:<4523<145;;=I=>7;8H3O5M77304E3739J:N>IML77F;75G70;>;7=M7412;7DB30<;>?LMK3B2010?6>:::54L7C1;5G@2CK9O:9>40E3@7@350=>?H4L?0D755F271>9JI<6?6112G1030:>M<>J<4@32665F;=H88L?K4193A2>2:;HJ>5?=C0660D37:LN:M87LBE55E553?<J:H:7GD74>6AN1;MJK9IFCDE@C@AJOLMI:802B40G6=0?J44=I9E:6==5<9':?<6??0D2B3776;=8OJ=<659272=?>MLHN:H:613;:E5?49;=<4<704A@F67>812?>??>616G8::=<6M55@2<=EEK;I0528554E<9:N4=>;C52B@3C3>8>?:;=?8@@@3402IH?<<;>N3@502D7?0HHI?=>=01C205=68=93=>:J30A1<567<9:I=5:=2BC54CE3:J3H<>H?67152@EEJK::?B127<51382;:=5<>333AE141I=LN84;9B516=4B6IJ8<=H6;7>F913B<>2982?==?<717;<2H9>4130;@<7D;<82=8:=4123456FI9:34K8<141B1==2O=?MJ41926A32:H2J<979EGG0EDE1N:>4O64D5:<4660;9:85J710026@?F;=3HN??605;74>748L::;9J;FC67F7E7L>K2<:9?2@57<9G67@427389:?A5;:47E799>;<9M955G31=47<9:;=<><64635466:98:5<<=80022G678=:0=9:N4445B11E?:I29OK9CE@:A303L<9=;;CN<8<=95>4;KMTPR=IMNYM1?<:1<20>732@D[YY4NDEPA845=87;?7<:5IORVP?gcl{k7=>4?>0685127?69901:87AZTQWW>wbflmxnon2>3;2=05=6:;K>N<:6C4;;E346N1:H>9J=140:574?0=>N;K=8=6977D545@319LJM87M49:@3?KJ2HON<7930BG341<=ONNO:<2DGFGG36J8>;7<8=0E3B25G>88:29I?=A1;47G?2M;:3?5>?121356>>=89==488855G07?790;;M9>417;;4=678;:;<9>>01234565N133:H=8646G@C@?0L8;4;><83F@4=?C4MLB263<30C98?70I82?=>;7327715B3J;EB274A1AI9H>=NJ;812;542738=J>9J=C715AA43?1H>MH?L98F74206J8O85@624>489>9<9<97723676F8?;J<=:792G2@36>99MH;;0:3;<391;3O<=79E72FAGD==3:4<7?2435116<90H?O?MJ674317E7>8398;M;B3071AC7:K>;<4>?0521457B99?:8<>705035@?5<91:5O7;67G5@2D2:>?=94<;256A65E2LH89N;>K20@5466C10<;:47J1003=3?>>9>:<6?5IORVP?BNI5:1<3??;08JJUSS2MCI0=4?>0285?OIX\^1{ho30;2=55=62@D[YY4xec>3>58692;1CXZ_UU8GKD:7294:=6?5OTVSQQ8O9<>NC345E023=8>=I?9?01214F558OKN=8;8E25211638H;;>=>KC763?4G2=H?;O>=74C77=G03K:2:5?>>41F745>78=:99E6;71E689<=>?0723516<9H3?M?:7406@A5578;:M>=9MF163E50F;ML25>JJA2:17144N=:>>4:N53220002<91:ML?L25:G6<5699II58?;44323A?E>HK><=H9514;F=ED=92IH=>>85D;157E88:?<6?M9BG1@D51;83=HN015EB032:H;K=J69:536EA=0=>IH=J5GD240EAKJLJN:<:D7;;BG6?0K:=?=8JMONIL>8E2A510?BJK9==5?>19;6GGDFKJHHH8?=B4D305=6K0NHH5KMB8F02D@2?9IM>8MKD04E213C9MO2J4KJ567F6D4E18N>:87IC012G@5382;O>KMN8EAA06E2;<<2:K6L3@C;6@E6>O>;7HHKJ573E3C1B>1III:I<;?MMABA0723481:N?9>41D3F@GDD?8?986?61AEGF721:9NJHO757F31GG>>1I:N>M<0BC23=>CL0?O=;L7F837@ABAK:ON9N8695774>47:8924==K3123F7C7:93ON4??1043==?F=0;=?5??00@30101;8:;:=8;DC3A=<273;:<>6?0L:?H<>=:0>=M86E4027?6=8?=M:881212G@02?9;:4;3;=M;23@ABCB3092J;=?9B1:;@@5789H39>6?0215G=C>1?2H=4O;0:0230E0J13H85MLC835@10A1:;>HKJJCCG77@3A8:NN>;6E01G466>38>::C@D4FF>50KLN;4JIBD1@0G7DJO<=N9MF9A0E77?ML=2HILLF9:5F7DELL=;>K9>B2:BAF0><919>8?N6151156?IHK;9;;61B6345DE<1I;NN<6B9200D64<9:;>:L7464:F047L0;?<6<;C802FG54;;NH:;J6C0532G0D=0:8=?7938C0FD2701OON979EE@AFCE5KJ>;N;:?;373<5058;:J;>97>09:32D550O>;<;J=A@720G25NK:;:HMLC52863@FNL9II>>KF@D4FCMJ=?;>6IC2GGB<@EL=:NO=7IC6@7@6G6<>?II9=<717EF0@3828=O=62FAGFGFI12<=?<;2C1AA1?FI<98447?23;A7<76=1I<>;LL7D@7AFE4::>;7?9628;0B99?8;?865B0?L9NM<=>;840260E58JK3H9<899:2A17581H:89>4281B566D19:MNL:JA62G6GG5=K9??N;M034G<@>0>?K?I9<97BFBAF?>M19;H?=?4191E5>1J=>9:;??141;4526=0>=<5>62E;@F<7>:<::<=O<7EFB7<7>I8>9;K8908474>4F90;N<=;<8GA;E067<99=M4;6AB@4E104L;9N8<7JA14A31278?9399;:A63115273;I;9HH:4@1@4C1A=O::;H>77253E5>30=:0>IO95B0737D?:=L:<4LL586@6166:93H<79C7221G>2I8<88=5=E51521230LLM=468276;@GGDMLNI;;K=651:FFEBN;NMNK8944;7F52AJHO<>L6;0:0F1415M18N49;?71234D>3>8:;9=>J85GB5=64J1H;;O76E0F@30DB>=;2::::9663?7CE8K9?4N>M6310325>J8HH;>?622;11<4D0=O8;O9NC062GCC1=LO<:I6865:B61?2IML24KJ=B07F252E=;L:>KLMC932G<34<918<4?6014305701:9?8?=:95;2BGGE>:L88;H?C4G@<@5F=:;249L?9D431D57I9<6=>25:560?5K9IO8A35B547DJ1:J856?8B5@64E58<:95<>?002745450KH8NI:?;2361540=8<>9K8?062F2G4D=9<;5>86603020GC9L989?==7203767F=82:4==?C52874039;I?5=>I654B73048;<:HL>63170@<>A90N9O8L9523:1A2F?8KJ9;6=B3;A05=4:LO?ONMJCB47B2C1:;?MO47JC76@7G0CL>NNH=HK7BAFE6DA80K;<;KLDE3346ILK>>I<56DAAF7C0>>;7>:6730:GG?7<=H=I:O8873B41G09;KJJ?7JFCF0=615?O;M?KM=AC3F2F@2?8>>;9>435CAAG?CNHK?48=611A:=33D9<228:>71BC75165M1O=9997725E36DE>;3JMH??<=JO8O;2EGA157AM9;;958=48C@5@G18M:3J9<97E0;0611;JLH5<7?C1774>52:JN:HLHL902@G063;:>OJ4K9F0D7B666>8K8:?7OI4;?J3116F4CA;LL2?8JNFGDB5C?3NMIJ9O6<3G37557EM:;38=5<5B46616E>8:<:=89A31@A1EAK9=>832:A@F6?8LK;O?=;0:15@G3E?KN948>?19AE=601:8I=4;=?94C47C1EM>>?>NL>3233F3H;;IF8311D11=O:9>=H9EC;G5G560;>?ON8LA3AAG9;5N>7317B557??>:J:7EFF0<56N8N2I49N8G14<<>6IKHM4I9M6C56082O><9F633B72DNL=3O8K93G137114?JI?<6=76CC30@@>?H9M48;>D@F:@72F0M8>5L>M4N:?;2;AG@@1JO>O>>;<2874003A9J2;=<;:2534=A3>K=I?9>:KF60:269=
;9?J4LI9C4AEGB30OIN;9>;7B3F36>D=K9;?H6>5CC405=4IJ238O?J68335452KM:3<=<=443E65>??25AG26>F88I3:?>?2212=305L1:N<86?5706FF2F<9>;7>L6246:1153<0<3NLM74062G<6F1J:N<<8LB36F@GD3L;<43C;BB573?KNI;:=?B5G25A?C98I:H=MM4>O:6D310G@2JJO2N>:IC@C53@2>J:K?>H?6196A2F?A8>9?5???42474>5D89:;<=>?0123456789:;<=>?0123456789:;<=>?0123456789:;<=>?012345273:I99<=?1G@1GD22=?8988=?89:6567690;:9N8:2C07=642::>;>=?>00;76A418=:0?N;93B:A47E?KJ92O;:KDBGB5GCBJ3=NL<9CA;G3>?;8I<>98<30:5GF7EIL3O:=6N5EGE4C@590I94N?;0:1G7F@6JL2H49JKB123133?09K<;;K:C1G27401M=3M8:?>9@6@E4569JL2;O795D63?6BF9:3;<>J8A94A6C>00MN25IOIB62GA4G61O9MN:JM3C:FB704;9:<:;:LB0;:=16<;MK9O;:741A1GFC?98?9>O:=01:3=0C2I=?=O46I4C06ADCF<8:===;;5107216D<918HILI49G0=C7FM0LHK<7340BC5?I>3=IK=6E2DG3A@BJH=MJHHIBG34EGGA80O2<4j43r3345`s:<<&89>441@5G4>789<3<=6?137@30279HOH89K7C13B:>O<:A1;E3367J9I=JHM9419751B2;?K?=I?;4C4@0343I;H;<>89D9AE2253I=K9HN:95C13<105KJHO=OH6CC:74>2589:;<=:=0123456789:;<=>?01:3456789:;<=>?0123456789:;<=>?312301273=8;<9012704E3<:I;O>M?05:344>AK:26<012347630=:08?>:38@733C48=>J46FEEDC?L