OpenCores
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 26 to Rev 27
    Reverse comparison

Rev 26 → Rev 27

/zx_ula/branches/xilinx/spectrum_16k_with_rom_game_for_ols/rom.v
0,0 → 1,178
/*******************************************************************************
* This file is owned and controlled by Xilinx and must be used solely *
* for design, simulation, implementation and creation of design files *
* limited to Xilinx devices or technologies. Use with non-Xilinx *
* devices or technologies is expressly prohibited and immediately *
* terminates your license. *
* *
* XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" SOLELY *
* FOR USE IN DEVELOPING PROGRAMS AND SOLUTIONS FOR XILINX DEVICES. BY *
* PROVIDING THIS DESIGN, CODE, OR INFORMATION AS ONE POSSIBLE *
* IMPLEMENTATION OF THIS FEATURE, APPLICATION OR STANDARD, XILINX IS *
* MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION IS FREE FROM ANY *
* CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE FOR OBTAINING ANY *
* RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION. XILINX EXPRESSLY *
* DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE *
* IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR *
* REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF *
* INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
* PARTICULAR PURPOSE. *
* *
* Xilinx products are not intended for use in life support appliances, *
* devices, or systems. Use in such applications are expressly *
* prohibited. *
* *
* (c) Copyright 1995-2012 Xilinx, Inc. *
* All rights reserved. *
*******************************************************************************/
// 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".
 
// 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).
 
`timescale 1ns/1ps
 
module rom(
clka,
ena,
addra,
douta
);
 
input clka;
input ena;
input [12 : 0] addra;
output [7 : 0] douta;
 
// synthesis translate_off
 
BLK_MEM_GEN_V7_3 #(
.C_ADDRA_WIDTH(13),
.C_ADDRB_WIDTH(13),
.C_ALGORITHM(1),
.C_AXI_ID_WIDTH(4),
.C_AXI_SLAVE_TYPE(0),
.C_AXI_TYPE(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_ENABLE_32BIT_ADDRESS(0),
.C_FAMILY("spartan3"),
.C_HAS_AXI_ID(0),
.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_INIT_FILE("BlankString"),
.C_INIT_FILE_NAME("rom.mif"),
.C_INITA_VAL("0"),
.C_INITB_VAL("0"),
.C_INTERFACE_TYPE(0),
.C_LOAD_INIT_FILE(1),
.C_MEM_TYPE(3),
.C_MUX_PIPELINE_STAGES(0),
.C_PRIM_TYPE(1),
.C_READ_DEPTH_A(6400),
.C_READ_DEPTH_B(6400),
.C_READ_WIDTH_A(8),
.C_READ_WIDTH_B(8),
.C_RST_PRIORITY_A("CE"),
.C_RST_PRIORITY_B("CE"),
.C_RST_TYPE("SYNC"),
.C_RSTRAM_A(0),
.C_RSTRAM_B(0),
.C_SIM_COLLISION_CHECK("ALL"),
.C_USE_BRAM_BLOCK(0),
.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(6400),
.C_WRITE_DEPTH_B(6400),
.C_WRITE_MODE_A("WRITE_FIRST"),
.C_WRITE_MODE_B("WRITE_FIRST"),
.C_WRITE_WIDTH_A(8),
.C_WRITE_WIDTH_B(8),
.C_XDEVICEFAMILY("spartan3e")
)
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(),
.S_ACLK(),
.S_ARESETN(),
.S_AXI_AWID(),
.S_AXI_AWADDR(),
.S_AXI_AWLEN(),
.S_AXI_AWSIZE(),
.S_AXI_AWBURST(),
.S_AXI_AWVALID(),
.S_AXI_AWREADY(),
.S_AXI_WDATA(),
.S_AXI_WSTRB(),
.S_AXI_WLAST(),
.S_AXI_WVALID(),
.S_AXI_WREADY(),
.S_AXI_BID(),
.S_AXI_BRESP(),
.S_AXI_BVALID(),
.S_AXI_BREADY(),
.S_AXI_ARID(),
.S_AXI_ARADDR(),
.S_AXI_ARLEN(),
.S_AXI_ARSIZE(),
.S_AXI_ARBURST(),
.S_AXI_ARVALID(),
.S_AXI_ARREADY(),
.S_AXI_RID(),
.S_AXI_RDATA(),
.S_AXI_RRESP(),
.S_AXI_RLAST(),
.S_AXI_RVALID(),
.S_AXI_RREADY(),
.S_AXI_INJECTSBITERR(),
.S_AXI_INJECTDBITERR(),
.S_AXI_SBITERR(),
.S_AXI_DBITERR(),
.S_AXI_RDADDRECC()
);
 
// synthesis translate_on
 
endmodule
/zx_ula/branches/xilinx/spectrum_16k_with_rom_game_for_ols/tv80_reg.v
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
 
/zx_ula/branches/xilinx/spectrum_16k_with_rom_game_for_ols/ram.v
0,0 → 1,149
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: Dept. Architecture and Computing Technology. University of Seville
// Engineer: Miguel Angel Rodriguez Jodar. rodriguj@atc.us.es
// Revision: Joseba Epalza Ramos <jepalza@gmail.com>
//
// Create Date: 20-December-2012
// Design Name: ZX Spectrum
// Module Name: Ram16K
// Project Name:
// Target Devices:
// Tool versions:
// Description: Spectrum 16k OLS (Open Logic Sniffer) Dangerous Prototypes, "http://dangerousprototypes.com"
//
// Dependencies:
//
// Revision:
// Revision 2.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.
 
Notes from <jepalza>:
OLS (Open Logic Sniffer) from Dangerous Prototypes, hasn't any SRAM connected in board.
We need to create it into Spartan. At this point, only has enought logic to implement
16k rom and 8k ram, in order to run basic Spectrum 16k!!
but it's unusable with only 8k of ram. For this reason, it's best implement 8k rom and 16k ram
with any of 8k rom games or demos, in the first 0x0000-0x1fff space.
 
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.
 
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,
input [15:0] a1,
input cs1_n,
input oe1_n,
input we1_n,
input [7:0] din1,
output [7:0] dout1
);
// SRAM into OLS (16k max with 8k ROM, or 8k max with 16k ROM)
reg [7:0] mem [0:16383]; //[0:7900] //7900: test with spectrum rom
// Permanently enable SRAM and set it to use only LSB
assign sramce = 0;
assign sramoe = 0;
reg rsramwe = 1;
assign sramwe = rsramwe;
 
// set when there has been a high to low transition in the corresponding signal
wire bank1read, bank1write;
getfedge detectbank1read (clk, cs1_n | oe1_n, bank1read);
getfedge detectbank1write (clk, cs1_n | we1_n, bank1write);
 
reg [15:0] ra1;
reg [7:0] rdin1;
reg [7:0] rdout1;
assign dout1 = rdout1;
 
// ff's to store pending memory requests
reg pendingreadb1 = 0;
reg pendingwriteb1 = 0;
// ff's to store current memory requests
reg reqreadb1 = 0;
reg reqwriteb1 = 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
// 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
if (reqwriteb1) begin // if this is a write operation...
pendingwriteb1 <= 0; // accept it, and mark pending operation as cleared
mem[ra1[13:0]] <= rdin1; // put data into virtual SRAM
rsramwe <= 0; // pulse /WE in SRAM to begin write
end
else begin
pendingreadb1 <= 0; // else, this is a read operation...
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
end
1 : begin
if (reqreadb1) begin // for read requests, read the SRAM data bus and store into the corresponding data output register
rdout1 <= mem[ra1[13:0]]; // get data from SRAM OLS
end
if (reqwriteb1) begin // for write requests, deassert /WE, as writting has already been happened.
rsramwe <= 1;
end
reqreadb1 <= pendingreadb1; // current request has finished, so update current requests with pending requests to serve the next one
reqwriteb1 <= pendingwriteb1;
if (pendingreadb1 || pendingwriteb1)
state <= 0;
end
endcase
end
 
endmodule
/zx_ula/branches/xilinx/spectrum_16k_with_rom_game_for_ols/rom.ngc
0,0 → 1,3
XILINX-XDB 0.1 STUB 0.1 ASCII
XILINX-XDM V1.6e
$0`544<,[o}e~g`n;"2*73>(-80!<?40528456789:;<=>?0123456789:;<=>?0123456789:;<=>?0123456789:;<=>?012305=789:;<=>?0123456789:;<=>?01:3456789:;<=>?0123456789:;<=>?0123456382:;<=>?0123456789:;<=>?01C345678;:9<N>?0123456789:;<?>?8323<5670;>;7=>?0123456789:;<=>?011E7F66K9;O4K>>F75EBF6C8=8;:=M?341E@<@2M9?3?9>40123456789:;<=>?014F5C06N?:<H59LC6F1G04A0==>=8;:54734532=<?>=8;?4193456789:;<=>?01234F>B9:?99<;?39135A2B8O3?H97;0D70G4@2:<:;=N?KDB774>6789:;<=:?0022056789>:<=>?012345678OI2????0173B5378KII;5>;7127342739:;<=>?23236=6?:H8;<5<?0123456789:;95?K46375CGE>93J98K6C02GBC6C;=:0<=>?002063271;28?O>=EC:347>69<>;<=><EG3356E5=:N88NJ7040@6=47818?8=5?0123G56789:;<=>?01234567?9>?<=9?452315@7K8>;<=?;312AG<24N9:;<=>;0:23456D<=>?<=>;412301678=??59=;15;7756F<:2ON96?3E1F7F6BM:;88?89AD63?565MJ;??N;83E60@0@D;8I<4=>I2BD@45268:?;OI:?1B17416A=8>;<:>74020416<89>;98:?1463102789I;8<>>54631066=<>;98>>54621026=<>:98:?51234566<91;<5>NA921E=6FI1:;<5>N0103E56FI9:;M=>NA10BE=4FI18;<=<?012BE=47818?<6>>0176456289?><=>?0027456789;?<8;:0177443288?><=>?0123456789:;<<:?;13165D51J<J8NKN3BG@GF5?KOHI4;J=783B420DM=38I9J<003FG5G4;L2IIO?<25284427<9:O<H:?01234567NOL;<=>?AGDEBC@A=9:MJKHLC2A0G66C81H<<O8?B71:05=79=O<N5OKC113=536:0<?:8KM5E472D>C>=KJJ>:KF2AABADAL:>O;;MI4G6G415382::;9?L015;G4@49LL;<:=>54761032=<?>98;:54761032=<?>98;:54761032=<>;7=?K15250567<>L;=LM>FB2:A14D98N;=I>;7G375127<8:;<9><461@51669J9?;9>403324AEB<?<J8;>94D;724>B;OLHM<K631;2=73>9:<><9:<93A;5=E1=9<=9>;=419367C5LMN24O<9E8:B=1?7=J8HM?H;C774@C46;;>=:?7?98;A20EF1H2>988NE4;74>640L9O8>M=0BD27<7>JMH8M=>?391FG2D4I9LH;:=7C320=5209H:9O=H70B20E327399HO:?K00204C64:O:?<=>?D51015731;9?59:80D33FC7AK>>H;=KLBC244F63K=:0<9O72@:F45>DL8H2<?9>6624=FBF<;:I=;9LCB04F<05?9:;<=>?01234577KH;;8=5?51157G>1:>:3HOO:91:5174>193=:?<6C9A:6142112J:9<:95:B21440?32<58;0:2;30528::;<=>?CE:44562;:9>==?K043@467?89I;<=>LB52341230J2HO=M<3G63?5D6<;?:O4MKD4613077;J=MJKHIFGCBEDG2=<?;<=HIE@;6156AMH3><>HN9420A16<8K??>:6=472:=434813H5;7L11@;63>69<;;5N;I60:1503?I882=46=E54@63>A<91;O=>?21234567:;:?=8;:54CB=52789;;98M722236167K98JM5=N2B13F5?C=9;?<6>L0223G56DK::HO>>?C223G66DK99;O>?;C123G46689IH<=??086244638:9;O>:?;1A3766D89IH?=ML253;756D;9IH<>>L324@672D802;<NM?19;3456789:;?>>L35284F62=8>>9<;?01360037:JLH<=>?0273GA27<9>:<=JL451:44E78=:M9:H>406605=7K9IH?=?:51107557K9;J5==NE910755FM=I;<=?:75161F6609:;<==60B36<56382:H<KM709521011<KOJ==K:B815ED>09H894KH<D84E<<B>:M<H5H>:294E21G2N=>;7=M<92F6@0@C0O<<::8<5674B311??9=?I6:7G2@@554<J8MO:=IF1D;0115NO>;89>40B:F44>?I;8>89:N2275G4E5>:KJ4L=L5677<76D;12><9?>3BA4<0449?<8J=L:4193GF65<J9;ON=?CB0FE=57KJ98<N=NA913=F65<983<=><010;454EI9;I5=>?01374>6DK8>;O>>LC22@G5E>8::;O>=?C22106?7K;>;<<:?01134167899;<<=>0376<52739N?=I:;53F6@16D8=:I8=9?41231065L9::=N?J403@3F@E9=;?=K?83BA4G5E7L=:0<H;<A5D:7@2419O>?4:J90@1G56?:H<9:<6:AE76<<1BL:O34OH=0875F0EF:K=88=5?F123456D89:;<=>?012345678::;<=>?0123456789:;O=>?0123456789:;<==;0:2EB@GF=<>;<>HIA@;61565K:2;=N;9F3C00@@E<98=H?K62B04B<C>=:IN89L<3@63?46799:;==>>01334567I:;34N6L8E::<675:?9HI><MA230EF6F81OJONO?80@@<16<99:9<N>?0123476789:;<=>?0123456789::ML:?0122452789:;<=>>00235066<91:<>M>C0A3<4E6K8><J<HL3G;74@37;:I8O:?:F0620657K9:;<NL?36:44=170>??<6?=853147448>O<>>88135AA2@4;;98<==7C1F54FG4;=O:;8;780;2762B892354?;;019MKVR\3KOH_O31383:42<9:0BB][[:@FGVG:6:3:5=95>3;KMTPR=imnym1?=:1<74>72?H><I8LJEDGFA21A8OKN;L:J9GD;5=668MH:I>K73D1F<<BA:L9J;HJ>0B@;7D2738<=I?664@12<1B7892:<KHI04DE4567NH:;JKHIFGDE0D>50;228;K:07732063K=:0=:>M5E5;<444I;==8I9I6G7E<@6?19:9>4=7DC074=>498;;8=6=41:1076>I:O88=5>B00;6@2E<;8I5=J?BE0;6C4?IO83>=;79E33@C6C0=I:N?L;2E2A=7BD<;8I5?J;0:3G41679L938=>K547G10B2=<=>9:MI31D047B?;828<O8?C72@24>7>9:I:=M90B63?4B?91988O;>2E66456DJJ=?N9L:5G;346EA8998H=>;3B731450K<:><=>=D52@G16<9L:=JK:;C713B4@>M98J:L9I88;FE16AI8:3>9H9380775BDN<><4=K;BBD5G@2?<91:IH?L4D;F5=6>;K2:4H99F2@356BFK><HII=>CGF0<5EF8H>2J>MICB:46F5E>L8?<6?I40AF0427M<;?==6K042776778=:H=>??463@315DJ8:8=:><3B@0@56D>=;:J>:?;33345B6=<;O9<;>D4274F27<92:H?:?B0F14530M:I:4=>9B9;5==03MMI;M;KN2528614AK9H;?9<L45@A5DD79==845>6A04@G56DL9N84HM?0CF30F07LL:9ONH7CE;655=52@D[YY4KI@>2>5868281EC^ZT;FJF97=87;:7?4@UURVP?BHI5;1<3?>;38LQQVR\3NDN1?50?63?7GDM;>24?8<27A@5D17892MINO<01GFFCCDIHOHNKKLA22FBDD4;;=I5OL<26C;@16<:K3O44O8E1;@=FGCJ0LI5H9=6C;@A2?B?0O<??:NA31B2GG>0H9:8=7;05C1G=E><919OLJ=99@115?F0J88;?HLF36FB47ENMLH4>:9F16@265A8=O2;HL?762E<=@5<O;?<6<LD9;:GC6789:;>;>L310;GFE>M?;9:>??E34A0563K=>;8?:6D4;G1537K=:H<=:?;3F;74>491<;=5>927233167?=:;;9>?F522476A<9;;?>>?41205F5389:;<5?L35286@C5KH8H>:=8361EFC6F:JK=OOLJ88:3461E183354?789;21@4?IHONMO9MA@0B05=5N;HNJ?KI70@A@=77K=:INI:905@@FGCA?LL9J=>?0123<163NJI?8O=?01234173829:J>6?0BC@A664:K9:;>6761:;A5>3<;K88=?<A0@0G16>9K>9H=6<0C5@24648K>;7><=7GC4F223<=>?54;;E6@B37?DM0I;=5?;9E::B<@?1O3H8=<M9D513<B71H=9;9>439:EBCEFK=92?LHKB1@5GD33LK==OL6:6@ABF13A?08>9L9:A43B2AD1=0<J4L;?4190=4540JI8O;=>FGA3=4658:N<49JM3B27@=@79M3O8K8LF130E516M=>H><>L97374>5>=O:M58>?D4F7B5E0;9=MO5;804134457N9I::=:<B223467D=>;H9:?K5G3751273:LH896N450G@143<K?39K8KC806E1?7:88;>8>78901=1C51;H>>5<J400345421=:0?KHIFG517F66;1IMO=MLF86E6A26<8IM9=;;512@306D8M>O8=;?842G4C6D;8IHh6=|242frt778$??<6:?B2336A7C8=:I8::?72337177;=;;<>6881644114L?>:8<7?652A024C8=:I8::?;53304>1993;MLO61323016319N>:<>;F9304D@FMK9?4577EC13G5??81<=M:K88528040F0;K<<4<<2@510=B2;=N395<>01;0=6G28=L3=>6<01CEEF2FIH;38=?=942005=3::925LO93@AEB6@DNO:MJK>?02236C@ANJLMH=HIFG2E45678=8I49:;476701C382>94NK;27F0F<E5>JON8O?L7B62<<CE098;=<HJ275B=G@7::8JJ=>?92D15766NO>;79<N51;E5<258?=:8=7K3C6B0G6FL8K8?LJ?A22:7=5?>;2N<>6;537201?7=08259>442234567K=:;8=>?41274527899:<=??0033446799:;<N:?05230167<9:?<=><41971122<=>>8=<?03216G26N;:;<4>6BE@0GF6AL;>949MLD83B45G4;8:N4O6NFB274>21J?H25=?7C140<FBB=J;?;K9ME1:FF55DN9:8??L<9@4;B=E7KH2M4N>?531053273=<OJN69F12AEC2D8J=J?>J?CD16@6659;>J?N?8B10F5632N?NHN;JLB7D1A66A:=:08L?=832@A70481328L7932::63340::3I9>9CD26<56789:?O=MLC92345678=:?8=5;A3A@E155KJ?;?NL<C3A07C@ANOLMJKHIFGDEBC@ANOLMJKHIFGDEBC@ANOLMJHO;0:6G=6350K>;O5:?4244E344NOL:4?9;2D565@CB:<>=M;79716345670829I4;>2463?1@D9K:9?=H?F1@E7@5D;9;H?==L310@755D8M:8<<M?9322472E=9H9<5>?013EG16<=9O88NJ?2G731556M=:<5==L72A4=566K>3;>NH?C20@B4EE:JL;OK<LB1F;2763<91>==>?05261563==:><=>;1137556789:>9=>?0123456789:;<=>?0123456789:?<6;>48613D1?M;N3>58798G:A4>50?224OO<9D:35C67JJ3=<4:922:@A@45<;8H<=:?;403B7EA:M>HO:;<E420<665L9?9<?H?31234G>4;9:O88=?D5567056<JN?59>?75281664:92?M<?750234567NOL;<<H?011EB@6ANOIMJKH78@CBED1D<LH;>O>=B10705=2==::8=>?0126056289:;<=>?01274577<9I;<=>?4133416799:;<=??05235=7382?>8=;:00760432<8?>8=;:0076043289?><=>>0123456789:;<=>?0123456289>;78;:5066102289:;98;:C1407654K:98<=>L02274AB?KJN?H>=<415750@0098NJ9>454761032=<?>98;:54761032=<?>98;:54761032=<?;<=>?0123456789:;<=>?4196<5?C?9:;4N==6116@157;99;O==86113<FE789:;:=>?013;455FIJ9;5N>?91274>3?>9H==5M=6042256189<:4<6>613;24>191::=N>?C4:22517L9>OOO>?167@5F273<I===>=F37557E6>9N;<I>:72D;6144;O;28KM<B1127C6FK92H?N9L2E1E4DE7K=:09HML412@G56781234OJ<52D045678H;9<OJ>92D045678=>?;KHIFDA@0567;;2H8=590CAB0GEEM82HNHH=2G0EF<758MHH8=6JFC0304D>9>OM?:L:063;57@4=9HNO5=;0:43G2GB=13>:O8:426G35?B>8KO:4;>21A@146AN;:>H;<?2426FA63JM:=J:<96763?347?M:O>46<DC;254D7MJ:O5H6L7@DF4CGAJ19;J?H>FCA;0C>EN:<HJ=L86BDGF16<>;834?8=00C@=A279J:>O9;?7137@61?N9:=>;<NA0;;==GF0?KN;>OLD9;;ED>5<91=>;<NA1CA=FCE;0O2ON>7EB2;@F6?LJI3HH<M8B:@A77E>:22<9=?48:F4567KKL?<68<371E2542;9:;<=>?0123456789:;O=>?0123456789:;<=><0123456789:;<=:?;76E5646N=>;<=>6346054DBML:3OOMJ7CG35C01=12;4:K701;G50?21<KN;H9NE52820D?<13IMOM?B2C57FCBM13>88=M95@E4@DC>=3259<;E163207310>N>NJ=AG7105=1=JH38I=6D3@G34@B:M?;IK=M85CA2721>HN<>?8=A9CB61??18KO89O=23D65GB382<=>HK8B8GF237>8MNOHIJKDEFG@ABCL123456789:;<=>?0MNOHIJKDEFG@ABCL1>;7;7?19236167;9:;<=>L31A@426D;1:H<>>L312@4367893;?=>?07077567;HKH<9>46CGB=2?3JL?:?=<9A72A<<73;<?>:O<>705:<AB0813>O<;LC23@4<26KO?3=N9M4195B111;:><HO?I2B0@4@1>?=HJ?O>J4720GC67;:2???>7C2AA==ED;J3MJ9H?35:74>1798:MJN<K41204A24=8>>?>HK4913742D;1I:O=ML71A3G0570:;HH9J;512@05273>:284880EAB@4G0K:=2>IM;21@:4A@3:;3;5?JJ425G4=GB<K=:<5<J470G6G?7L=:0;?68674E6DG7<J<3?4MN21D@@F05;?>MH56<7777646BI0;2HL978BC07G4AIJK88=582E37GGED<OHM5NO<D91GF117;M8M4KL7FC6A<DCF9KL;?N7;9C;7=A1?0>=HI5J;0:501=0>0?>8?>=<35A3BA>0L1<==K8?013;B357>9<8<;>930D6<37?=1<;J;?79963?2379=L8:I>>D16454278:?:O5<>C53304E?80:H8<M720F24166KM>??9>>D560G16<?<:<?>=?521G0427N9N?9=9<FE665=60>8>3H5:K4433A@26>9HO8<:<3G2A6F64<91<9?L60@;@1AC>=039O?O;A34;5<248O>98LHIFBG:172B89:;<=>?01234576:9:?<69J49A001?6I9:;<8M8154G0=46J;NMI?88A8305=240J>8498:1B20=664;9>H:=:?;6D705678M;>=<;>10734=67092I8::;75673165898;>?J:D07G503C8=I;8N>LB528<17708L;H9MI1521@15C<=;?<NMK40AEA057;9I;8H?IC1D375>6K9I:JN<LB41605=??>O;OL><4B7FF5BE:?O8?KHIFGDEBC@ANOLMJKHIA@CBEDGFI<?>98;;012346@38223:L:923@7310D188J9=8863::4626<=8;8O:=73:03G1CN98?>H;>1G57=F1291>;756789:;<=>?0123<;>?95G40@3C;0?8M=H:1BD2A1EEN>NMJ:JI547EB2EAN>IMJ9>489:;<=>?0123456KDEFG@ABCLMNOHIJ789:;<=>?0123456KDEFG@ABCLMNOHIJ7419;=542=9:J9=<:51136541:9:;?=;K712:2542>9;>:=?:6113457?:93>89<?01374>>>=H?J<L:N3@DB1D2789:359<=21:;2@6BK9<H5?H;6@7B11?C1MK2ML8>937:5174310DYY^ZT;flqqg;?3:58=57A162G56789:;<>??147610@AN9=;=8HN08061=6789:;<=>?01034=6789:;<=>;0::@36>DK=K8I4=7FBAB3A750K9M??L>39:7<@2F89:;<=>?09A3GFE389:;<=>70963?=B3:H<?><O<882;2=B?:H934H=L8D03<C4D:18;4?8=09A;A3570M:3:8<=882;216<1892>N=K4B0@7F>19L>=58MLE@@3=<41?;3?;8>=43FG=F>780<><L?>996:4A?6<912>:9<DBD47A?580LMJKONA@76106789LMJKONA@76106789LMJKONA@76106789L?<67:84204307<9:;>;M:7B65B547:18><567230;6=41:=;;4N<6D933E07C<9<?:<:?;843616791:;?=>?147@75ED8::H?<>L022@756D89<;<=8?312345E7;9:;?=>L0528=227K1>;JOL=6733015E;;K9==9IDE@BE255:OLONO782G1AE7CC89IM?>O=282E05=>098>8=?N01134562?=98?=<N912@756D;99;?=>?31362562==8II58?0116G163823H<N=<2C13=C?DK89JO9KM21:241CE:::3IO=?002704>78=:;O<>;20:36DG?M0>;74K?12727312KM22?5J799124<?B::<HH<6:8E:G4=>B?039I:<6C8GF3C40I>99<9>4A12BEDGF:HK;<=>NA@C70A@ANL?;NK97D0F3B@66M>>OJHHKBG5:0CEFK>3H=KL:419B6567:1:J<=>N092;456F:98;M=<?012BE567:9:;<=>=0123456589:9<=>?01274>G28:O29=HN51DB15@F=9LJ8>K60G;77D34M<9N9=K60D70A05F<:K?J4>J52G77<273H?;JL;?F@73BD3789<;>;>J61G:<6B?10>3<;M?7DF;B6CANKOM<=>IFCGEB6CA8=:0M8>IA42EE06AI<:MM8>IA42EE06AI<:MM8>IA42EE06AI<:MM8>IA42EE06AI<:M8=5N54761032=<>;<=>?01234A0C89N;8?9<A52;21CC?;?3N87LC1G7AF060=O<=I:;0:C54=5D89:;<=><0123456789:8<=>?01234F0>;9:98>;>C123456D8:38<NM?0163?D1380I?MK<<EC17@567088I>>6L4@AA<F2FKK3HMKOK36GA7D@?0H>9?5>N43;@G16<I12J9=7773725303JM3>=?K>A341E745==ON<5OM982:E6??91K?I=K?07AF705><91JM9>?0905657319HIN5?K7523516789:;<=O728214=6CNJ9N<NH7626356GF9K=?<6ON81C145670;:;4=<701:145G58;KJ<=<N012145678923<=>?0123456789KJ<=:?;@C:=C47KJ9H?=H9DE@B@G501OK88KO=9G:;B=EB1LK8<N?JB9AF<=EFI1O?M=K=3528EDGFIHKJMLONA@C61032=<?>98;:54761032=<?>98;:5473456789:;<=>?012305=FIHKJMLONA@CBEDG2=<?>98;:5476116789:;<=>?01DEBC@ANOLMJLONA@CBEDG382KO;LMIAD@:B47699:;=<>?00334576K9:?8=>?4523412789:8<=??012245679920MIJ]A=2==>GCL[K7==06;@FGVD:697h0MIJ]A=31>58>3HNO^L2>2?:8EABUI5;546OKDSC?6;><IMNYM1=18:CG@WG;<720MIJ]A=7=<>GCL[K7:364AEFQE91902KOH_O38?:8EABUI53546OKDS@?4;?<IMNYN1??>89B@ATE48;5n6OKDS@?57<7601JHI\M<00=<>GCL[H7=364AEFQF94902KOH_L33?:8EABUJ5>546OKDS@?1;><IMNYN1818:CG@WD;?720MIJ]B=:=<>GCL[H753=4AMN74>D69J>N8I6LCBGE7A6B898;>L;MCE4@464F=;I;H><N5CAGG@46KO2NH>>>CBG161273K?;9H=7BBG3F75>JLL?<I;73CD;6FGB=;LI:?O<E2@BFDC7<K3HN;9?2211G<6E:=:0N8O;483001G>9<KMM8>IA42EE06AI<:MM8>IA42EE06AI<:MM8>IA42EE06AI<:M8=5M87@;AD>48KI2:;;;420246CBLJI28K<K10F:<16D0>98JOOK3GC433328:8:<KH;0:@A3767;::;<=?>1030G<>EKJI;<=??4970GDEEKJI;<=<=231FA@@A?;:;<=>K73:8FPUXAGLD8=5L06247720=9<?=HJ>CC646A638K><=I>;252737B6K>>:<?J>CC6247B7<>>;N99;0:A3GFED<9:;<=>?09A@G=>?K9:;<=>?09A@G=E?K9:;<=>;45A@GFEDKJI;<=>?0163?F6DKJI3<=>?01230FED<J>H<=>?01230FED<=>H<=>?01:;<FE3<=IHON>?0123416<K=:>8=:?12D2547C<O:;8=HLD82344@0N8I<9:8:941E06@1818:8>;J07F3=0@7<91H:<J>15004GEF19I;98M9C3525<D718:2N=7>0@305DD7K9H;4N6=1B:@<57799O?<6M6351054DD><:3H5OL32@4G347;8H>O;?>0@3A4F4C?82?<N<KF0:74FC5J9:8>O:?;BA;<=EDKM:><9KK5B75=1EC=02N8HO991@;67>4<M8I9?:K4D03FA4E0?=:<I<84528GF>DK98IIO=IFE22610F>;>:?H>;C31;B11B;9N=>?6L9507556C;>IOJNJ90BC305=DKJIHONMJCD213F>?MJ:=85KK05A5@C558JK9?NM829F2G=E3?;9H>=:NA2604FE382IM?N:JB716AD3?LHN355JND4:GEA>>I0<>4I;=092;6123=>3899?7FC@:101>:O>;7NH:0173G6@E0>9??=;;2E61BF6E8>:<<?J;32160155L=:;<=>?0123456?0;?3<<<4CIG@OZJNKLDXIRZVPD68GIM7>2IGG<6?6:AOO717=2IGG?V7;BNH6]7?8<1H@F7?4:AOOD3<KEAJ=:5LLJC2@71<KEAJ=I:8;BNHE4B?<2IGGO;4CMIA50=DDBI:96MCKE36?FJLL_i0OAEKV^FJRLBB=2IGGKV7;BNHB]7?801HC@CFTUGG51=DG[OTKH@JR@VJKKYNFOE<7N\JAUGG05=C8>>:<=7?0B074G5DK9I98===CG63617780:><=>?01226544;O89==ML0123654382N;45J:0E61414?9:>=9LJ?8B;E41@?9:2H4KM>E0:@=C608?9><:M=94264104==>;7I>69905E60E88:9>>6NE2:EA<441198M?;78D16<F2C>9IN44;LD261635?KJ:3H9>4D1;GBC@790<3I9KL5D615<?>==O;ML6J9900ED@?>:2=<>=M89;7E1GCL<;2::<6419G56540JI8?4:?45CBEDGFIHKJMLONA@23456789:;<=>?01CBEDGFIHKJMLONA@C74>B5;988?5K91@52AGGD<9>H?46;21220707I<2ON4O:9533ED1B?<;>89<;DDG7<5273M>8J8>M412055@4K99?N<J?2D733165=9=?<?;<41607FB7K=8H<9>;EB274137;=:0H;8=A@356GGF>;2IN57:2@;66G?2:02:>L6=4531E=4E?:8;:L?:C80:=5678>=I8=5K8CF;BAG68K?>999954642177;;;:=I;>50;6507>=9>;49>?75673333=><>8==;0:F:GA>?0O3H<H9J73;162?DL88=;4KM3GCF35GE8;92IK9<ABCGG71B?0394=??4163?ACBM;?>O?:N377503450?9I58:=C847002EL8==<57624;250661:<3998?9931<3=CAH6;255KI@>2>5813MCJ0<09;EKA858?3MCI0<4?>79GMG:66?1OCL2?>99GKD:6294=7IAN<0<5?AIE49437IAM<083:3=CGK6:29>4E3;A7<G18<3INO7718C2EDCBMLK2M;7NA@C561D2=;:N:HOMFB45111>=9H::;<:419FFDE2;;L;IO8JFCGAADEEK:KM?H=J2E140F559;O?O>LN6B20EA3?M=I?I:MNE0F74>CCLH=MI<;:1EA;05EE?>9MI<J82E0@104C>=>;58??F16G2=45>0LHOH<;092;4=273LL;>9>=4CGF0CDCJ8IH=NM:F63E4701I<IHIHK;AE10G=6789:;<=>?012367778:1NBL=4EO@74>@7IJ2;5=<L81:3660A9KI8<H=>39A;55E68;:3MOKM9813552381=8>9J9CEC@@=273O>9<O?J7BG1=A@>9?NO?I7LBG@455169O?JH;8?A@041<>FI1;3MH<68C7:<7G?L=:0JLOI3BDEFF@2=<?MMLH=39:;<0>><=2:4H?<41A1==769;N889662B264D0D:=O98=5ICDF3EFBD>9N8:H:M203@44?BN>?NJ>??2GCBGGEEKKIONOM7EG0EAC4BN;L?<OH;0:DE4C1CNO9OJLONAG76B<6C>?<9>N<=2333E=C209KM=47N9@01644F<?3N?9><1963?C@0?>OHO9KL01AB4@E389OJ8?KMEC13<DGBIHLN8IOJ424B2G5F0HKH>O<7D815016<NONJM4;=20DG@G?>=;?2?9;>80@0<<E>>>>>;:6LE54@A1D61?9O?O?6A3G0G2?4<91MJIM<412E6F16L9I?;?MI052G44EC8::8H=L?E5377167:=:;H=J?112:4065N=:?<6HIF@CBE032=9:;<;>?0746A33BL0=25N96775A61@E1HKJMLONA@CBEDG?IHK3M=:?;GDEEDGF=<?><=>?FGDEEDGF=<?><=>?FGDEEDGF=<?><=>?FGDEEDGF=<?><=>?F528BC@D808J4L=83@@BF4GFI1KI=<<687@25475I8H3;?>69123F2GE><>2IL;JD87F05=ANON>>I;;B623<1G?M?K355OJFD54A76CKMOJ:NJ7CC@5=7@?9>NNJK7M2G13FC5382LMJH<=B@:42<7C8M9JJ;J=D@:;F3B0>M325O87CD212A419M<I>IJIDD@21<00N0>;7KHIE@CBE032=9:;<KHIF@CB=03289:8JKKNA8761567NOOJM4;:412EBCGF1<??<9>4FGDEG11788L;O;=92EF;2505KJN2H<6;CBAG<F44:9==<9>;D11575719O:>4N>:1:E0?BHC?2CEEYQ?069JJLRX88=0ECG[_104?LHN\V:8;6GAIU]302=NF@^T<894IOKW[5003@DBXR>87:KMMQY70>1BBDZP0858MKOSW9K<7D@FT^2A3>OIA]U;O:5FNHV\4A1<AGC_S=K8;HLJPZ6A?2CEEYQ>069JJLRX98=0ECG[_004?LHN\V;8;6GAIU]202=NF@^T=894IOKW[4003@DBXR?87:KMMQY60>1BBDZP1858MKOSW8K<7D@FT^3A3>OIA]U:O:5FNHV\5A1<AGC_S<K8;HLJPZ7A?2CEEYQ=069JJLRX:8=0ECG[_304?LHN\V88;6GAIU]102=NF@^T>894IOKW[7003@DBXR<87:KMMQY50>1BBDZP2858MKOSW;K<7D@FT^0A3>OIA]U9O:5FNHV\6A1<AGC_S?K8;HLJPZ4A?2CEEYQ<069JJLRX;8=0ECG[_204?LHN\V98;6GAIU]002=NF@^T?894IOKW[6003@DBXR=87:KMMQY40>1BBDZP3858MKOSW:K<7D@FT^1A3>OIA]U8O:5FNHV\7A1<AGC_S>K8;HLJPZ5A>2CEEYQN6:KMMQYE>2FDMIKK6:NLGNCC?2FDKDMNLb9Neoiu^lxxeb`l;LkmkwPbzzcdb?5A169MAQQHZB;<7B^[ILKYAZVUADC_E[K\_OE@<>V)<9roSA:4P@PWe>VNFVH^_DJWb:RJJZDR[GKFI;5_SEMMAf=UIDH::R]=_R025>UOZLMTIUZ]ABV\JBEb3ZBYIJQBIO]PM_C6;2YBARM@LMKPMJHXKAOHG;5\OTP@A2=TZ_KGSL94SSTBHZD33ZYYM95\SS@5?VRF\\Y?7YW_E7g8Q5){}Ui`fQbel]dakcui}ey#j`nthtffha)fh~bzhQmlj]nahY`mg%}magk.bqwv*tfeeed|V>R.scn*w)t;Vceey }al-gtwgj&mz9t? }al4f?P6(pz~TnaePmdo\c`hbzh~d~"iaaukuagk`&gke{kPbmi\i`kXold$zlbfd/appw)uidfdc}U>]/pbi+t({:Ubbdz!r`o,`utfe'n{>u<!r`o5a>S7'qySobd_lgn[bcim{kc!hn`vjr`djo'djxdxj_cnh[hcjWnoe#{ocie,`wqt(zhggcb~T2\,qeh(u'z9Tecg{.scn+avuid$o|?v=.scn2`=R8&rxxRlck^ofiZabflxjxb| gocwmsceen$emygye^`ooZkbeVmnb"xnlhf-gvru'{kf`ba[2_-vdk)z&y8Sd`ft/pbi*bwzhg%h}<w2/pbif=R[LXTZD]FBMG:?SOB_V^R\H=4WDC0?RCEj2]YEYKPFHPPPf=PZ@^NS@AKE^C`?RTN\LUFCIKPB0f8\LJNFQ'SHO.?.0"PPPD'8';+M^MFI79[WQJNJ>1S_YQHNE`8\ZEHZLUBBKA9;Yfa[Lba3QncS]|fmWgqwlii991Sh`QBakmqR`ttafd:<6Vkm^OjjjtQm{ybcc=4Xrv0?\ct02koho30?;8eabui5;;245ndepb8479j2koho31383:<=flmxj0<<18:cg`wg;9720mij}a=0=<>gcl{k7?364aefqe92902koho35?:8eabui5<546okdsc?3;><imnym1618:cg`wg;17;37obd_lgn[bciWnoeigl_bqwv4><jeaTahcPgdl\twojW~coxeQ>199ahnYjmdUlicQrho\slbs`V8:46lck^ofiZabfVzye`Qxievk[67?3kf`S`kb_fgm[utneV}bhyfP4308fimXelgTkh`Ppskn[rtfxyoyS~=Piokw[4453kf`S`kb_fgm[utneV}ym}~jr^q0[lhn|V89>6lck^ofiZabfVzye`Qxr`rsawYt;VceeyQ<239ahnYjmdUlicQrho\swgwxlxT>Qfnhv\0c=edbUfi`Qheo]wku773kf`S`kb_fgm[s1X;;i0naePmdo\c`hX~>U8 -Vflhl{$FIUM)Mnbh|ntnp#51(49=1i`fQbel]dakYq?V9Tt~z>3:`ooZkbeVce|xzPbmm`o42<jeaTahcPotvsqqYedfi`86mck`:8`jssi5:546j`uuc?5;><lfm1<18:flqqg;;720hb{{a=6=<>bh}}k79364dnwwe909i2ndyyo37;2=<>bh}}k7;3=4eoc;?kadj|cgh?5ao29qkh2c92xda!lck^ofiZabfV|<S>"tc^cg`wgX`nd0?<,b]b`ateW~coxe3>3-a\eiahz`~ca0?#c^c{mZocW~coxe3;,b]b|lYtdh|nSywe<2/gZgaV~r|h3>,b]a}qcX{`pn14"l_bmnijhXkea6<!mPdddbqirXlh~j1="l_ekpegjbW~kybRlgv^alhi;7$jUoe~omld]tewhXja|T~l`he<2/gZckikeymyg`n^fjv8EX'h%Seagax.qsafru}dU::fQ`lr-qkh)sey%Toj!#c^gmegjbW:8ieyQndepfwv;7$jUmm`gcy<qsewrff:&hSeo|_`zj[lb:8%iTdl}Peoc>5)eX`hyTicl20-a\lduXag`noyk}r<2/gZnf{VgnaRaztqww[wc`{Vk6<!mPh`q\i`kXg|~{yyQ}efq\f86+kVbjRczx^mvpussW{olRo20-a\lduXe|rTcxzuu]qabuXj4:'oRfns^pfcfcf59&hSeo|_sgdg`d:8%iTdl}Prrvb95*dWakxS}{b<2/gZnf{Vydjyklc^kmtprXzlmxSl3?,b]kevYtgo~nonQ`uurvpZtbozUi1="l_hljpZ`ndl7I`l`dSupjjb*dW`dbxRhfld]mehc:zfg%adh#c^kmmqgX~hf6<!mPiokwfZpfd4:'oRgatdpeefcX|pzn1="l_mmb`Zoia}Umeak21-a\i`kX|pzn1>"l_lw{[uowmeceiR}{afgp95*dWyxbaRzvpd?2(fYumhnThh~{h^c>2167$jUyiljPddrwlZd:>=:; nQ}e`f\slbs`Vk64!mPrdcg[roc|aUi15"l_sqw[utng{cuRo2CD.`[wusWyxbcg{y^`>G@*dW{ySywe<QZJF*dW{y~lcPa<2/gZtt|{kfSo3?,b]pmhYdgefbdaa_bjfgn;FDE&hSx}j_cpbiZdkgja6<!mPurg\f|rbW~oj1="l_tqf[gsmV}nn0>#c^wpaZbbnhgxRjnt`?3(fYr{lUnon3?,b]vw`Ytgo~non3?,b]tadYpam~c1<"l_vga[roc|a7: nQxrhvf[acw|aUj1;:?0-a\swosmVnn|yfPb<4745*dW~xbxhQboeg\e8QUA]OTJD\\T-a\swosmVgdhhQm=VPJP@YAA[Y_ nQxrhvf[roc|aUj15"l_vpjp`Ypam~cSo37,b]{``pnklljadbv=rrbvqgi;lw:;6|`m-`ooZkbeVmnbRx8_2.xyxFGx8:;7MNw1c19B?2=9rYnn7?77;350?74;9<3?7?jbdfxj4>2281e=5856:&2<6<6?o1v_h751959532=9:9;:5=51d`ee>U6=j0:n<4?:01043>428oijh5\e882f4<72898<;6<:0g`45=c9k91<7?51zQff?7??3;=87?<314;7?7bjok0zY?9d;295?7=91qXio4>868221<6;::=4>4>ecdb?!7013;>i6X>8581p72n3;0y<8?:19~ 4022<80n<l<:1823?3=91qC=:64$050>4d43Si26?u<4;:`>x"60;0:m?5+d482f0=#mh0:n95+17`95>"6>h0:455f19f94?"6>>0:4n5a17494>=n91h1<7*>6682<f=i9?<1=65f19c94?"6>>0:4n5a17496>=n90<1<7*>6682<f=i9?<1?65f18794?"6>>0:4n5a17490>=n90>1<7*>6682<f=i9?<1965f18194?"6>>0:4n5a17492>=n9081<7*>6682<f=i9?<1;65f18394?"6>>0:4n5a1749<>=n90:1<7*>6682<f=i9?<1565f19d94?"6>>0:4n5a1749e>=n91o1<7*>6682<f=i9?<1n65f19;94?"6>>0:4n5a1749g>=n9h<1<75f1c294?=h9hl1<7*>6682e`=i9?<1<65`1`f94?"6>>0:mh5a17495>=h9hi1<7*>6682e`=i9?<1>65`1``94?"6>>0:mh5a17497>=h9hk1<7*>6682e`=i9?<1865`1`;94?"6>>0:mh5a17491>=h9h21<7*>6682e`=i9?<1:65`1`594?"6>>0:mh5a17493>=e91;1<7?50;2x 41428;27E?70:J23==h9821<75rb057>5<5i3:1<v*>72822<=O91:0D<97;[a:>3}4:39869>540876?242t.::>4>b39'54g=n:1/=<l511c8 47d2:20(<?k:6a8 47b2h1/=<h5989'576=i;1/=??5119'574==2.:>>4;;%310?>c3-;997:k;%312?3?3-;9;768;%31<??53-;957??5:&26d<d?2.:>o4>f:&26f<2n2.:>i4jf:&26`<?j2.:>k4>7:&275<?:2.:?<4:0:&277<bl2.:?>460:&271<68o1/=>;5959'560=n?1/=>95d19'56>=kk1/=>755e9'56g=i91/=>l5749'56e=??1/=>j5379'56c=911/=>h56g9'516=?01/=9?5999'514=98;0(<:<:031?!73<33:7)?;5;f0?!73>38i7)?;7;;b?!7303;n7)?;9;337>"6<h0?56*>4c8251=#9=i1?6*>4e80?!73m390(<:i:29'506=;2.:9<4<;%366?5<,8?86>5+14697>"6=<087)?:6;18 4302:1/=8653:&21<<43-;>m7<4$07a>7=#9?i1o>5+17g96>"6>o097)?8d;34g>"6?l0:;n5fdb83>>ob93:17d??7;29?l7703:17d?80;29?l7093:17d?8a;29?l70j3:17dom:18'531=ih1e=;850:9je<<72-;=;7on;o352?7<3`k36=4+1759ed=i9?<1>65fb583>!71?3kj7c?96;18?ld4290/=;95a`9m530=<21bn?4?:%353?gf3g;=:7;4;h`2>5<#9?=1ml5a17492>=nj90;6)?97;cb?k71>3=07doi:18'531=ih1e=;858:9je`<72-;=;7on;o352??<3`ko6=4+1759ed=i9?<1m65fab83>!71?3kj7c?96;`8?lg0290/=;95a`9m530=k21bn44?:%353?d?3g;=:7>4;h`4>5<#9?=1n55a17495>=nj?0;6)?97;`;?k71>3807dm=:18'531=j11e=;853:9jg4<72-;=;7l7;o352?2<3`i;6=4+1759f==i9?<1965fbg83>!71?3h37c?96;48?ldb290/=;95b99m530=?21bni4?:%353?d?3g;=:764;h``>5<#9?=1n55a1749=>=njk0;6)?97;`;?k71>3k07dln:18'531=j11e=;85b:9jf0<72-;=;7l7;o352?e<3`l26=4+1759b==i9?<1<65ff683>!71?3l37c?96;38?l`d290/=;95fc9m530=821bjl4?:%353?`e3g;=:7?4;nde>5<#9?=1jh5a17494>=hnm0;6)?97;df?k71>3;07b??2;29 40028::7c?96;28?j7783:1(<88:022?k71>3;07pl>7483>7g=83:p(<9<:04:?M7?82B:;55Uc88564=;:0?<7:>:50906<z,8<86<l=;%32e?073-;:n78l;%32g?2e3-;:h7mi;%32a?g63-;:j7<7;%314?453-;9=797;%316?0f3-;9?76n;%310?473-;997?;;%312?eb3-;9;7=i;%31<?>43-;957=j;%31e?`33-;9n7?6;%31g?133-;9h79k;%31a?5e3-;9j7?=;%304?77>2.:?<4:7:&277<d<2.:?>4;6:&271<2i2.:?8474:&273<3m2.:?:4k2:&27=<dk2.:?447e:&27d<f;2.:?o4<c:&27f<082.:?i495:&27`<0i2.:?k4:c:&205<5=2.:8<4>0e9'514=011/=9=5889'512=?>1/=9;51168 4212;n0(<:8:035?!73032=7)?;9;5f?!73i39>7)?;b;321>"6<j087)?;d;18 42b2:1/=9h53:&215<43-;>=7=4$071>6=#9<91?6*>5580?!72=390(<;9:29'501=;2.:954<;%36=?5<,8?j6?5+14`96>"6>j0h?6*>6d81?!71n380(<9k:05`?!70m3;<o6gkc;29?lc62900e<>8:188m46?2900e<9?:188m4162900e<9n:188m41e2900ell50;&222<fi2d::;4?;:kb=?6=,8<<6lo4n045>4=<ah21<7*>668be>h6>?0976gm4;29 4002hk0b<89:298mg5=83.:::4na:l223<332ci>7>5$044>dg<f8<=6854ic394?"6>>0jm6`>6785?>oe83:1(<88:`c8j4012>10elh50;&222<fi2d::;47;:kba?6=,8<<6lo4n045><=<ahn1<7*>668be>h6>?0j76gnc;29 4002hk0b<89:c98md1=83.:::4na:l223<d32ci57>5$044>g><f8<=6=54ic594?"6>>0i46`>6782?>oe>3:1(<88:c:8j4012;10en<50;&222<e02d::;4<;:k`5?6=,8<<6o64n045>1=<aj:1<7*>668a<>h6>?0>76gmf;29 4002k20b<89:798mgc=83.:::4m8:l223<032cih7>5$044>g><f8<=6554ica94?"6>>0i46`>678:?>oej3:1(<88:c:8j4012h10eoo50;&222<e02d::;4m;:ka1?6=,8<<6o64n045>f=<ao31<7*>668e<>h6>?0;76gi7;29 4002o20b<89:098mce=83.:::4ib:l223<732cmm7>5$044>cd<f8<=6<54ogd94?"6>>0mi6`>6783?>ial3:1(<88:gg8j4012810c<>=:18'531=99;0b<89:198k467290/=;951138j4012810qo?86;296d<729q/=:=517;8L4>73A;<46Tl9;4x77<4;3>;69?543877?{#9?91=o<4$03b>24<,8;i6:?4$03`>=`<,8;o6<m4$03f>g=#98l1>45+132964=#9;;15>5+130961=#9;91585+1369=`=#9;?15;5+1349=c=#9;=1j<5+13:911=#9;31h6*>2`8b2>"6:k02;6*>2b873>"6:m0m96*>2d8g5>"6:o08=6*>3182f>"6;80>96*>33870>"6;:0:<45+12696`=#9:?1945+1249a`=#9:=1==k4$01;>3b<,89269o4$01b>46d3-;8n78j;%30g?e23-;8h7;9;%30a?3e3-;8j7=8;%374?403-;?=7??b:&207<>j2.:8>46c:&201<d>2.:88493:&203<>l2.:8:4n5:&20=<2m2.:844;5:&20d<3k2.:8o4>129'51e=;2.:8i4<;%37a?5<,8>m6>5+14297>"6=8087)?:2;18 4342:1/=8:53:&210<43-;>:7=4$074>6=#9<21?6*>5880?!72i380(<;m:39'53e=k:1/=;k52:&22c<53-;<h7?8c:&23`<6?j1bhn4?::kf5?6=3`;;;7>5;h33<?6=3`;<<7>5;h345?6=3`;<m7>5;h34f?6=3`ki6=4+1759ed=i9?<1<65fa883>!71?3kj7c?96;38?lg?290/=;95a`9m530=:21bn94?:%353?gf3g;=:7=4;h`0>5<#9?=1ml5a17490>=nj;0;6)?97;cb?k71>3?07dl>:18'531=ih1e=;856:9jf5<72-;=;7on;o352?1<3`km6=4+1759ed=i9?<1465fad83>!71?3kj7c?96;;8?lgc290/=;95a`9m530=i21bmn4?:%353?gf3g;=:7l4;hc4>5<#9?=1ml5a1749g>=nj00;6)?97;`;?k71>3:07dl8:18'531=j11e=;851:9jf3<72-;=;7l7;o352?4<3`i96=4+1759f==i9?<1?65fc083>!71?3h37c?96;68?le7290/=;95b99m530==21bnk4?:%353?d?3g;=:784;h`f>5<#9?=1n55a17493>=njm0;6)?97;`;?k71>3207dll:18'531=j11e=;859:9jfg<72-;=;7l7;o352?g<3`hj6=4+1759f==i9?<1n65fb483>!71?3h37c?96;a8?l`>290/=;95f99m530=821bj:4?:%353?`?3g;=:7?4;hd`>5<#9?=1jo5a17494>=nnh0;6)?97;da?k71>3;07bhi:18'531=nl1e=;850:9lba<72-;=;7hj;o352?7<3f;;>7>5$044>4663g;=:7>4;n334?6=,8<<6<>>;o352?7<3th:;:4?:3c94?6|,8=86<86;I3;4>N6?11Qo449{20976<383>:69<5428~ 40428h97)?>a;6;?!76j3927)?>c;70?!76l3ij7)?>e;;8 47a2?80(<<?:758 4462o1/=?<5679'575=981/=?:52g9'573=>81/=?85f39'571=:h1/=?65229'57?=k2.:>l483:&26g<1<2.:>n4>d:&26a<?92.:>h4>a:&26c<?=2.:?=4k4:&274<b3-;8>76?;%307?573-;88764$016>7e<,89=6:l4$014>07<,8936n64$01:>`e<,89j6<??;%30f?5c3-;8o7?9;%30`?743-;8i7=n;%30b?2a3-;?<7mk;%375?0?3-;?>794$060>d2<,8>?6k>4$066>70<,8>=6;5+15592<=#9=21=85+15;92g=#9=k1;k5+15`9541<,8>h6>5+15f97>"6<l087)?;f;18 4372:1/=8?53:&217<43-;>?7=4$077>6=#9<?1?6*>5780?!72?390(<;7:29'50?=;2.:9l4=;%36f?4<,8<h6n=4$04f>7=#9?l1>6*>7e823f=#9>o1=:m4iea94?=nm80;66g>0683>>o6810;66g>7183>>o6?80;66g>7`83>>o6?k0;66gnb;29 4002hk0b<89:198md?=83.:::4na:l223<632cj47>5$044>dg<f8<=6?54ic694?"6>>0jm6`>6780?>oe;3:1(<88:`c8j4012=10eo<50;&222<fi2d::;4:;:ka5?6=,8<<6lo4n045>3=<ak:1<7*>668be>h6>?0<76gnf;29 4002hk0b<89:998mdc=83.:::4na:l223<>32cjh7>5$044>dg<f8<=6l54i`a94?"6>>0jm6`>678a?>of?3:1(<88:`c8j4012j10eo750;&222<e02d::;4?;:ka3?6=,8<<6o64n045>4=<ak<1<7*>668a<>h6>?0976gl2;29 4002k20b<89:298mf7=83.:::4m8:l223<332ch<7>5$044>g><f8<=6854icd94?"6>>0i46`>6785?>oem3:1(<88:c:8j4012>10eoj50;&222<e02d::;47;:kag?6=,8<<6o64n045><=<akh1<7*>668a<>h6>?0j76gma;29 4002k20b<89:c98mg3=83.:::4m8:l223<d32cm57>5$044>c><f8<=6=54ig594?"6>>0m46`>6782?>oak3:1(<88:g`8j4012910eko50;&222<aj2d::;4>;:meb?6=,8<<6kk4n045>5=<gon1<7*>668ea>h6>?0:76a>0383>!71?3;;=6`>6783?>i6890;6)?97;335>h6>?0:76s|17394?3cs4;3=7?>8:?231<e127:;94m7:?231<e>27:;94l2:?231<d927:;94l0:?231<en27:;94me:?231<el27:;94mc:?231<ej27:;94ma:?231<e=27:;94i9:?231<a?27:;94ic:?231<ai27:;94j1:?231<68116=::51628941328=:70?84;34e>;6?=0:;o521679f<=:9>?1n:521679f3=:9>?1o?521679g4=:9>?1o=521679fc=:9>?1nh521679fa=:9>?1nn521679fg=:9>?1nl521679f0=:9>?1j4521679b2=:9>?1jn521679bd=:9>?1i<52167955><58=>6<9?;<341?70927:;84>7`9>523=9>h01<99:c;894112k=01<99:c4894112j801<99:b3894112j:01<99:cd894112ko01<99:cf894112ki01<99:c`894112kk01<99:c7894112o301<99:g5894112oi01<99:gc894112l;01<99:02;?870>3;<<63>778234=:9><1=:o4=055>41e34;<;7l6;<343?d034;<;7l9;<343?e534;<;7m>;<343?e734;<;7li;<343?db34;<;7lk;<343?dd34;<;7lm;<343?df34;<;7l:;<343?`>34;<;7h8;<343?`d34;<;7hn;<343?c634;<;7??8:?232<6?916=:951638941028=j70?87;34f>{t9h=1<7<t^0c4?870<3lo7p}>a983>7}Y9h201<9;:gd8yv7f13:1>vP>a89>523=nm1v<on:181[7fi27:;84if:p5dd=838pR<om;<342?`c3ty:mn4?:3y]5de<58==6kh4}r3b`?6=:rT:mi521659ba=z{8km6=4={_3bb>;6?>0mj6s|1c294?3|V8h;70?84;333>;6?<0:<:521649551<58=<6<>8;|q2e3<72<qU=l84=057>ae<58=>6im4=055>ae<58=<6im4}r3;=?6==rT:44521669e2=:9>?1m:521649e2=:9>=1m:5rs0:f>5<2sW;3i63>758bg>;6?<0jo63>778bg>;6?>0jo6s|19d94?3|V82m70?84;cg?870=3ko70?86;cg?870?3ko7p}>9183>0}Y90:01<9;:`g894122ho01<99:`g894102ho0q~?61;291~X61816=::5ag9>523=io16=:85ag9>521=io1v<7=:186[7>:27:;94m0:?230<e827:;;4m0:?232<e82wx=4=50;7xZ4?434;<87l>;<341?d634;<:7l>;<343?d63ty:594?:4y]5<2<58=?6o<4=056>g4<58==6o<4=054>g4<uz;297>55z\2=0=:9>>1n>521679f6=:9><1n>521659f6=z{83=6=4:{_3:2>;6?=0i863>748a0>;6??0i863>768a0>{t91k1<7;t^0:b?870<3k370?85;c;?870>3k370?87;c;?xu60k0;68uQ19`894132h301<9::`;894112h301<98:`;8yv7?l3:19vP>8e9>522=ik16=:;5ac9>520=ik16=:95ac9~ykb7290:wE?88:m`4<728qC=:64}of1>5<6sA;<46sad283>4}O9>20qcj;:182M7002weh84?:0yK52><ugn=6=4>{I34<>{il>0;6<uG16:8ykb?290:wE?88:m`<<728qC=:64}ofb>5<6sA;<46sadc83>4}O9>20qcjl:182M7002wehi4?:0yK52><ugnn6=4>{I34<>{ilo0;6<uG16:8ykc7290:wE?88:ma4<728qC=:64}og1>5<6sA;<46sae283>4}O9>20qck;:182M7002wei84?:0yK52><ugo=6=4>{I34<>{im>0;6<uG16:8yx{zHIIp==>58`cg7012uIJIw=sO@Qy~DE
/zx_ula/branches/xilinx/spectrum_16k_with_rom_game_for_ols/sp16k_for_spartan3e_OLS.ucf
0,0 → 1,38
NET "clk50" LOC = "P41" | IOSTANDARD = LVCMOS33;
# Define clock period for 50 MHz oscillator (40%/60% duty-cycle)
NET "clk50" PERIOD = 20.0ns HIGH 40%;
 
#reset
NET "reset" LOC = "P26" | IOSTANDARD = LVCMOS33;
 
#video
NET "i" LOC = "P68" | IOSTANDARD = LVCMOS33;
NET "b" LOC = "P70" | IOSTANDARD = LVCMOS33;
NET "g" LOC = "P71" | IOSTANDARD = LVCMOS33;
NET "r" LOC = "P78" | IOSTANDARD = LVCMOS33;
NET "csync" LOC = "P79" | IOSTANDARD = LVCMOS33;
 
#audio
NET "audio_out" LOC = "P32" | IOSTANDARD = LVCMOS33;
NET "ear" LOC = "P33" | IOSTANDARD = LVCMOS33;
 
#kbd rows
NET "kbd_rows<0>" LOC = "P53" | IOSTANDARD = LVCMOS33;
NET "kbd_rows<1>" LOC = "P54" | IOSTANDARD = LVCMOS33;
NET "kbd_rows<2>" LOC = "P57" | IOSTANDARD = LVCMOS33;
NET "kbd_rows<3>" LOC = "P58" | IOSTANDARD = LVCMOS33;
NET "kbd_rows<4>" LOC = "P60" | IOSTANDARD = LVCMOS33;
NET "kbd_rows<5>" LOC = "P61" | IOSTANDARD = LVCMOS33;
NET "kbd_rows<6>" LOC = "P62" | IOSTANDARD = LVCMOS33;
NET "kbd_rows<7>" LOC = "P63" | IOSTANDARD = LVCMOS33;
 
#kbd columns
NET "kbd_columns<0>" LOC = "P83" | IOSTANDARD = LVCMOS33 | PULLUP;
NET "kbd_columns<1>" LOC = "P84" | IOSTANDARD = LVCMOS33 | PULLUP;
NET "kbd_columns<2>" LOC = "P85" | IOSTANDARD = LVCMOS33 | PULLUP;
NET "kbd_columns<3>" LOC = "P86" | IOSTANDARD = LVCMOS33 | PULLUP;
NET "kbd_columns<4>" LOC = "P88" | IOSTANDARD = LVCMOS33 | PULLUP;
 
# Debug LED's
#NET "leds<1>" LOC = "P9" | IOSTANDARD = LVCMOS33;
#NET "leds<0>" LOC = "P10" | IOSTANDARD = LVCMOS33;
/zx_ula/branches/xilinx/spectrum_16k_with_rom_game_for_ols/tv80n.v
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
 
/zx_ula/branches/xilinx/spectrum_16k_with_rom_game_for_ols/ula.v
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
/zx_ula/branches/xilinx/spectrum_16k_with_rom_game_for_ols/tv80_alu.v
0,0 → 1,442
//
// 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_alu (/*AUTOARG*/
// Outputs
Q, F_Out,
// Inputs
Arith16, Z16, ALU_Op, IR, ISet, BusA, BusB, F_In
);
 
parameter Mode = 0;
parameter Flag_C = 0;
parameter Flag_N = 1;
parameter Flag_P = 2;
parameter Flag_X = 3;
parameter Flag_H = 4;
parameter Flag_Y = 5;
parameter Flag_Z = 6;
parameter Flag_S = 7;
 
input Arith16;
input Z16;
input [3:0] ALU_Op ;
input [5:0] IR;
input [1:0] ISet;
input [7:0] BusA;
input [7:0] BusB;
input [7:0] F_In;
output [7:0] Q;
output [7:0] F_Out;
reg [7:0] Q;
reg [7:0] F_Out;
 
function [4:0] AddSub4;
input [3:0] A;
input [3:0] B;
input Sub;
input Carry_In;
begin
AddSub4 = { 1'b0, A } + { 1'b0, (Sub)?~B:B } + {4'h0,Carry_In};
end
endfunction // AddSub4
function [3:0] AddSub3;
input [2:0] A;
input [2:0] B;
input Sub;
input Carry_In;
begin
AddSub3 = { 1'b0, A } + { 1'b0, (Sub)?~B:B } + {3'h0,Carry_In};
end
endfunction // AddSub4
 
function [1:0] AddSub1;
input A;
input B;
input Sub;
input Carry_In;
begin
AddSub1 = { 1'b0, A } + { 1'b0, (Sub)?~B:B } + {1'h0,Carry_In};
end
endfunction // AddSub4
 
// AddSub variables (temporary signals)
reg UseCarry;
reg Carry7_v;
reg OverFlow_v;
reg HalfCarry_v;
reg Carry_v;
reg [7:0] Q_v;
 
reg [7:0] BitMask;
 
 
always @(/*AUTOSENSE*/ALU_Op or BusA or BusB or F_In or IR)
begin
case (IR[5:3])
3'b000 : BitMask = 8'b00000001;
3'b001 : BitMask = 8'b00000010;
3'b010 : BitMask = 8'b00000100;
3'b011 : BitMask = 8'b00001000;
3'b100 : BitMask = 8'b00010000;
3'b101 : BitMask = 8'b00100000;
3'b110 : BitMask = 8'b01000000;
default: BitMask = 8'b10000000;
endcase // case(IR[5:3])
UseCarry = ~ ALU_Op[2] && ALU_Op[0];
{ HalfCarry_v, Q_v[3:0] } = AddSub4(BusA[3:0], BusB[3:0], ALU_Op[1], ALU_Op[1] ^ (UseCarry && F_In[Flag_C]) );
{ Carry7_v, Q_v[6:4] } = AddSub3(BusA[6:4], BusB[6:4], ALU_Op[1], HalfCarry_v);
{ Carry_v, Q_v[7] } = AddSub1(BusA[7], BusB[7], ALU_Op[1], Carry7_v);
OverFlow_v = Carry_v ^ Carry7_v;
end // always @ *
reg [7:0] Q_t;
reg [8:0] DAA_Q;
always @ (/*AUTOSENSE*/ALU_Op or Arith16 or BitMask or BusA or BusB
or Carry_v or F_In or HalfCarry_v or IR or ISet
or OverFlow_v or Q_v or Z16)
begin
Q_t = 8'hxx;
DAA_Q = {9{1'bx}};
F_Out = F_In;
case (ALU_Op)
4'b0000, 4'b0001, 4'b0010, 4'b0011, 4'b0100, 4'b0101, 4'b0110, 4'b0111 :
begin
F_Out[Flag_N] = 1'b0;
F_Out[Flag_C] = 1'b0;
case (ALU_Op[2:0])
3'b000, 3'b001 : // ADD, ADC
begin
Q_t = Q_v;
F_Out[Flag_C] = Carry_v;
F_Out[Flag_H] = HalfCarry_v;
F_Out[Flag_P] = OverFlow_v;
end
3'b010, 3'b011, 3'b111 : // SUB, SBC, CP
begin
Q_t = Q_v;
F_Out[Flag_N] = 1'b1;
F_Out[Flag_C] = ~ Carry_v;
F_Out[Flag_H] = ~ HalfCarry_v;
F_Out[Flag_P] = OverFlow_v;
end
3'b100 : // AND
begin
Q_t[7:0] = BusA & BusB;
F_Out[Flag_H] = 1'b1;
end
3'b101 : // XOR
begin
Q_t[7:0] = BusA ^ BusB;
F_Out[Flag_H] = 1'b0;
end
default : // OR 3'b110
begin
Q_t[7:0] = BusA | BusB;
F_Out[Flag_H] = 1'b0;
end
endcase // case(ALU_OP[2:0])
if (ALU_Op[2:0] == 3'b111 )
begin // CP
F_Out[Flag_X] = BusB[3];
F_Out[Flag_Y] = BusB[5];
end
else
begin
F_Out[Flag_X] = Q_t[3];
F_Out[Flag_Y] = Q_t[5];
end
if (Q_t[7:0] == 8'b00000000 )
begin
F_Out[Flag_Z] = 1'b1;
if (Z16 == 1'b1 )
begin
F_Out[Flag_Z] = F_In[Flag_Z]; // 16 bit ADC,SBC
end
end
else
begin
F_Out[Flag_Z] = 1'b0;
end // else: !if(Q_t[7:0] == 8'b00000000 )
F_Out[Flag_S] = Q_t[7];
case (ALU_Op[2:0])
3'b000, 3'b001, 3'b010, 3'b011, 3'b111 : // ADD, ADC, SUB, SBC, CP
;
default :
F_Out[Flag_P] = ~(^Q_t);
endcase // case(ALU_Op[2:0])
if (Arith16 == 1'b1 )
begin
F_Out[Flag_S] = F_In[Flag_S];
F_Out[Flag_Z] = F_In[Flag_Z];
F_Out[Flag_P] = F_In[Flag_P];
end
end // case: 4'b0000, 4'b0001, 4'b0010, 4'b0011, 4'b0100, 4'b0101, 4'b0110, 4'b0111
4'b1100 :
begin
// DAA
F_Out[Flag_H] = F_In[Flag_H];
F_Out[Flag_C] = F_In[Flag_C];
DAA_Q[7:0] = BusA;
DAA_Q[8] = 1'b0;
if (F_In[Flag_N] == 1'b0 )
begin
// After addition
// Alow > 9 || H == 1
if (DAA_Q[3:0] > 9 || F_In[Flag_H] == 1'b1 )
begin
if ((DAA_Q[3:0] > 9) )
begin
F_Out[Flag_H] = 1'b1;
end
else
begin
F_Out[Flag_H] = 1'b0;
end
DAA_Q = DAA_Q + 6;
end // if (DAA_Q[3:0] > 9 || F_In[Flag_H] == 1'b1 )
// new Ahigh > 9 || C == 1
if (DAA_Q[8:4] > 9 || F_In[Flag_C] == 1'b1 )
begin
DAA_Q = DAA_Q + 96; // 0x60
end
end
else
begin
// After subtraction
if (DAA_Q[3:0] > 9 || F_In[Flag_H] == 1'b1 )
begin
if (DAA_Q[3:0] > 5 )
begin
F_Out[Flag_H] = 1'b0;
end
DAA_Q[7:0] = DAA_Q[7:0] - 6;
end
if (BusA > 153 || F_In[Flag_C] == 1'b1 )
begin
DAA_Q = DAA_Q - 352; // 0x160
end
end // else: !if(F_In[Flag_N] == 1'b0 )
F_Out[Flag_X] = DAA_Q[3];
F_Out[Flag_Y] = DAA_Q[5];
F_Out[Flag_C] = F_In[Flag_C] || DAA_Q[8];
Q_t = DAA_Q[7:0];
if (DAA_Q[7:0] == 8'b00000000 )
begin
F_Out[Flag_Z] = 1'b1;
end
else
begin
F_Out[Flag_Z] = 1'b0;
end
F_Out[Flag_S] = DAA_Q[7];
F_Out[Flag_P] = ~ (^DAA_Q);
end // case: 4'b1100
4'b1101, 4'b1110 :
begin
// RLD, RRD
Q_t[7:4] = BusA[7:4];
if (ALU_Op[0] == 1'b1 )
begin
Q_t[3:0] = BusB[7:4];
end
else
begin
Q_t[3:0] = BusB[3:0];
end
F_Out[Flag_H] = 1'b0;
F_Out[Flag_N] = 1'b0;
F_Out[Flag_X] = Q_t[3];
F_Out[Flag_Y] = Q_t[5];
if (Q_t[7:0] == 8'b00000000 )
begin
F_Out[Flag_Z] = 1'b1;
end
else
begin
F_Out[Flag_Z] = 1'b0;
end
F_Out[Flag_S] = Q_t[7];
F_Out[Flag_P] = ~(^Q_t);
end // case: when 4'b1101, 4'b1110
4'b1001 :
begin
// BIT
Q_t[7:0] = BusB & BitMask;
F_Out[Flag_S] = Q_t[7];
if (Q_t[7:0] == 8'b00000000 )
begin
F_Out[Flag_Z] = 1'b1;
F_Out[Flag_P] = 1'b1;
end
else
begin
F_Out[Flag_Z] = 1'b0;
F_Out[Flag_P] = 1'b0;
end
F_Out[Flag_H] = 1'b1;
F_Out[Flag_N] = 1'b0;
F_Out[Flag_X] = 1'b0;
F_Out[Flag_Y] = 1'b0;
if (IR[2:0] != 3'b110 )
begin
F_Out[Flag_X] = BusB[3];
F_Out[Flag_Y] = BusB[5];
end
end // case: when 4'b1001
4'b1010 :
// SET
Q_t[7:0] = BusB | BitMask;
4'b1011 :
// RES
Q_t[7:0] = BusB & ~ BitMask;
4'b1000 :
begin
// ROT
case (IR[5:3])
3'b000 : // RLC
begin
Q_t[7:1] = BusA[6:0];
Q_t[0] = BusA[7];
F_Out[Flag_C] = BusA[7];
end
3'b010 : // RL
begin
Q_t[7:1] = BusA[6:0];
Q_t[0] = F_In[Flag_C];
F_Out[Flag_C] = BusA[7];
end
3'b001 : // RRC
begin
Q_t[6:0] = BusA[7:1];
Q_t[7] = BusA[0];
F_Out[Flag_C] = BusA[0];
end
3'b011 : // RR
begin
Q_t[6:0] = BusA[7:1];
Q_t[7] = F_In[Flag_C];
F_Out[Flag_C] = BusA[0];
end
3'b100 : // SLA
begin
Q_t[7:1] = BusA[6:0];
Q_t[0] = 1'b0;
F_Out[Flag_C] = BusA[7];
end
3'b110 : // SLL (Undocumented) / SWAP
begin
if (Mode == 3 )
begin
Q_t[7:4] = BusA[3:0];
Q_t[3:0] = BusA[7:4];
F_Out[Flag_C] = 1'b0;
end
else
begin
Q_t[7:1] = BusA[6:0];
Q_t[0] = 1'b1;
F_Out[Flag_C] = BusA[7];
end // else: !if(Mode == 3 )
end // case: 3'b110
3'b101 : // SRA
begin
Q_t[6:0] = BusA[7:1];
Q_t[7] = BusA[7];
F_Out[Flag_C] = BusA[0];
end
default : // SRL
begin
Q_t[6:0] = BusA[7:1];
Q_t[7] = 1'b0;
F_Out[Flag_C] = BusA[0];
end
endcase // case(IR[5:3])
F_Out[Flag_H] = 1'b0;
F_Out[Flag_N] = 1'b0;
F_Out[Flag_X] = Q_t[3];
F_Out[Flag_Y] = Q_t[5];
F_Out[Flag_S] = Q_t[7];
if (Q_t[7:0] == 8'b00000000 )
begin
F_Out[Flag_Z] = 1'b1;
end
else
begin
F_Out[Flag_Z] = 1'b0;
end
F_Out[Flag_P] = ~(^Q_t);
 
if (ISet == 2'b00 )
begin
F_Out[Flag_P] = F_In[Flag_P];
F_Out[Flag_S] = F_In[Flag_S];
F_Out[Flag_Z] = F_In[Flag_Z];
end
end // case: 4'b1000
default :
;
endcase // case(ALU_Op)
Q = Q_t;
end // always @ (Arith16, ALU_OP, F_In, BusA, BusB, IR, Q_v, Carry_v, HalfCarry_v, OverFlow_v, BitMask, ISet, Z16)
endmodule // T80_ALU
/zx_ula/branches/xilinx/spectrum_16k_with_rom_game_for_ols/master_clock.v
0,0 → 1,75
////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 1995-2010 Xilinx, Inc. All rights reserved.
////////////////////////////////////////////////////////////////////////////////
// ____ ____
// / /\/ /
// /___/ \ / Vendor: Xilinx
// \ \ \/ Version : 12.4
// \ \ Application : xaw2verilog
// / / Filename : master_clock.v
// /___/ /\ Timestamp : 04/21/2012 19:26:35
// \ \ / \
// \___\/\___\
//
//Command: xaw2verilog -st C:\\proyectos_xilinx\ulaplus\ipcore_dir\.\master_clock.xaw C:\\proyectos_xilinx\ulaplus\ipcore_dir\.\master_clock
//Design Name: master_clock
//Device: xc3s1000-ft256-4
//
// Module master_clock
// Generated by Xilinx Architecture Wizard
// Written for synthesis tool: XST
// Period Jitter (unit interval) for block DCM_INST = 0.05 UI
// Period Jitter (Peak-to-Peak) for block DCM_INST = 1.92 ns
`timescale 1ns / 1ps
 
module master_clock(CLKIN_IN,
CLKFX_OUT,
CLKIN_IBUFG_OUT,
CLK0_OUT);
 
input CLKIN_IN;
output CLKFX_OUT;
output CLKIN_IBUFG_OUT;
output CLK0_OUT;
wire CLKFB_IN;
wire CLKFX_BUF;
wire CLKIN_IBUFG;
wire CLK0_BUF;
wire GND_BIT;
assign GND_BIT = 0;
assign CLKIN_IBUFG_OUT = CLKIN_IBUFG;
assign CLK0_OUT = CLKFB_IN;
BUFG CLKFX_BUFG_INST (.I(CLKFX_BUF),
.O(CLKFX_OUT));
IBUFG CLKIN_IBUFG_INST (.I(CLKIN_IN),
.O(CLKIN_IBUFG));
BUFG CLK0_BUFG_INST (.I(CLK0_BUF),
.O(CLKFB_IN));
DCM #( .CLK_FEEDBACK("1X"), .CLKDV_DIVIDE(2.0), .CLKFX_DIVIDE(25),
.CLKFX_MULTIPLY(14), .CLKIN_DIVIDE_BY_2("FALSE"),
.CLKIN_PERIOD(20.000), .CLKOUT_PHASE_SHIFT("NONE"),
.DESKEW_ADJUST("SYSTEM_SYNCHRONOUS"), .DFS_FREQUENCY_MODE("LOW"),
.DLL_FREQUENCY_MODE("LOW"), .DUTY_CYCLE_CORRECTION("TRUE"),
.FACTORY_JF(16'h8080), .PHASE_SHIFT(0), .STARTUP_WAIT("FALSE") )
DCM_INST (.CLKFB(CLKFB_IN),
.CLKIN(CLKIN_IBUFG),
.DSSEN(GND_BIT),
.PSCLK(GND_BIT),
.PSEN(GND_BIT),
.PSINCDEC(GND_BIT),
.RST(GND_BIT),
.CLKDV(),
.CLKFX(CLKFX_BUF),
.CLKFX180(),
.CLK0(CLK0_BUF),
.CLK2X(),
.CLK2X180(),
.CLK90(),
.CLK180(),
.CLK270(),
.LOCKED(),
.PSDONE(),
.STATUS());
endmodule
/zx_ula/branches/xilinx/spectrum_16k_with_rom_game_for_ols/spectrum16k_TOP.v
0,0 → 1,190
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: Dept. Architecture and Computing Technology. University of Seville
// Engineer: Miguel Angel Rodriguez Jodar. rodriguj@atc.us.es
// Revision: Joseba Epalza Ramos (Company: INGEPAL) <jepalza@gmail.com>
//
// Create Date: 20-December-2012
// Design Name: ZX Spectrum
// Module Name: tld_spartan3_sp16k
// Project Name:
// Target Devices:
// Tool versions:
// Description: Spectrum 16k OLS (Open Logic Sniffer) Dangerous Prototypes, "http://dangerousprototypes.com"
//
// Dependencies:
//
// Revision:
// Revision 2.00 - File Created
// Additional Comments: GPL License policies apply to the contents of this file.
//
//////////////////////////////////////////////////////////////////////////////////
module tld_spartan3_sp16k (
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
);
 
// 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: only for compatibility issue
wire [7:0] sramdout;
// ROM data bus
wire [7:0] romdout;
 
// Chip Select
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)
);
 
//////////////////////////////////////////////
// Lower 16k VRAM (not upper RAM in 16k model)
//////////////////////////////////////////////
ram_controller vram_and_upper_ram (
.clk(clkmem),
.a1({2'b00,va}),
.cs1_n(!vramcs),
.oe1_n(!vramoe),
.we1_n(!vramwe),
.din1 (vramdin),
.dout1(vramdout)
);
 
/////////////////////////////////////
// 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)
);
 
/////////////////////////////////////
// Connecting all togther
/////////////////////////////////////
assign sramdin = cpudout;
assign uladin = cpudout;
assign cpudin = (rom_cs)? romdout :
(ula_cs | vram_cs | port255_cs)? uladout :
(sram_cs)? sramdout : // dont' has any Upper 32kb SRAM, but it's neccesary in order to void garbage.
8'hFF;
 
endmodule
/zx_ula/branches/xilinx/spectrum_16k_with_rom_game_for_ols/zx_spectrum_16k.gise
0,0 → 1,30
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<generated_project xmlns="http://www.xilinx.com/XMLSchema" xmlns:xil_pn="http://www.xilinx.com/XMLSchema">
 
<!-- -->
 
<!-- For tool use only. Do not edit. -->
 
<!-- -->
 
<!-- ProjectNavigator created generated project file. -->
 
<!-- For use in tracking generated file and other information -->
 
<!-- allowing preservation of process status. -->
 
<!-- -->
 
<!-- Copyright (c) 1995-2012 Xilinx, Inc. All rights reserved. -->
 
<version xmlns="http://www.xilinx.com/XMLSchema">11.1</version>
 
<sourceproject xmlns="http://www.xilinx.com/XMLSchema" xil_pn:fileType="FILE_XISE" xil_pn:name="zx_spectrum_16k.xise"/>
 
<files xmlns="http://www.xilinx.com/XMLSchema">
<file xil_pn:fileType="FILE_NCD" xil_pn:name="tld_spartan3_sp16k_guide.ncd" xil_pn:origination="imported"/>
</files>
 
<transforms xmlns="http://www.xilinx.com/XMLSchema"/>
 
</generated_project>
/zx_ula/branches/xilinx/spectrum_16k_with_rom_game_for_ols/zx_spectrum_16k.xise
0,0 → 1,377
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<project xmlns="http://www.xilinx.com/XMLSchema" xmlns:xil_pn="http://www.xilinx.com/XMLSchema">
 
<header>
<!-- ISE source project file created by Project Navigator. -->
<!-- -->
<!-- This file contains project source information including a list of -->
<!-- project source files, project and process properties. This file, -->
<!-- along with the project source files, is sufficient to open and -->
<!-- implement in ISE Project Navigator. -->
<!-- -->
<!-- Copyright (c) 1995-2012 Xilinx, Inc. All rights reserved. -->
</header>
 
<version xil_pn:ise_version="14.3" xil_pn:schema_version="2"/>
 
<files>
<file xil_pn:name="master_clock.v" xil_pn:type="FILE_VERILOG">
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="10"/>
<association xil_pn:name="Implementation" xil_pn:seqID="9"/>
</file>
<file xil_pn:name="ram.v" xil_pn:type="FILE_VERILOG">
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="9"/>
<association xil_pn:name="Implementation" xil_pn:seqID="8"/>
</file>
<file xil_pn:name="rom.v" xil_pn:type="FILE_VERILOG">
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="8"/>
<association xil_pn:name="Implementation" xil_pn:seqID="7"/>
</file>
<file xil_pn:name="spectrum16k_TOP.v" xil_pn:type="FILE_VERILOG">
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="11"/>
<association xil_pn:name="Implementation" xil_pn:seqID="10"/>
</file>
<file xil_pn:name="tv80_alu.v" xil_pn:type="FILE_VERILOG">
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="3"/>
<association xil_pn:name="Implementation" xil_pn:seqID="3"/>
</file>
<file xil_pn:name="tv80_core.v" xil_pn:type="FILE_VERILOG">
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="4"/>
<association xil_pn:name="Implementation" xil_pn:seqID="4"/>
</file>
<file xil_pn:name="tv80_mcode.v" xil_pn:type="FILE_VERILOG">
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="2"/>
<association xil_pn:name="Implementation" xil_pn:seqID="2"/>
</file>
<file xil_pn:name="tv80_reg.v" xil_pn:type="FILE_VERILOG">
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="1"/>
<association xil_pn:name="Implementation" xil_pn:seqID="1"/>
</file>
<file xil_pn:name="tv80n.v" xil_pn:type="FILE_VERILOG">
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="7"/>
<association xil_pn:name="Implementation" xil_pn:seqID="6"/>
</file>
<file xil_pn:name="ula.v" xil_pn:type="FILE_VERILOG">
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="6"/>
<association xil_pn:name="Implementation" xil_pn:seqID="5"/>
</file>
<file xil_pn:name="sp16k_for_spartan3e_OLS.ucf" xil_pn:type="FILE_UCF">
<association xil_pn:name="Implementation" xil_pn:seqID="0"/>
</file>
</files>
 
<properties>
<property xil_pn:name="Add I/O Buffers" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="Allow Logic Optimization Across Hierarchy" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Allow SelectMAP Pins to Persist" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Allow Unexpanded Blocks" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Allow Unmatched LOC Constraints" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Allow Unmatched Timing Group Constraints" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Asynchronous To Synchronous" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Auto Implementation Compile Order" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="Auto Implementation Top" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="Automatic BRAM Packing" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Automatically Insert glbl Module in the Netlist" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="Automatically Run Generate Target PROM/ACE File" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="BRAM Utilization Ratio" xil_pn:value="100" xil_pn:valueState="default"/>
<property xil_pn:name="Bring Out Global Set/Reset Net as a Port" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Bring Out Global Tristate Net as a Port" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Bus Delimiter" xil_pn:value="&lt;>" xil_pn:valueState="default"/>
<property xil_pn:name="CLB Pack Factor Percentage" xil_pn:value="100" xil_pn:valueState="default"/>
<property xil_pn:name="Case" xil_pn:value="Maintain" xil_pn:valueState="default"/>
<property xil_pn:name="Case Implementation Style" xil_pn:value="None" xil_pn:valueState="default"/>
<property xil_pn:name="Change Device Speed To" xil_pn:value="-4" xil_pn:valueState="default"/>
<property xil_pn:name="Change Device Speed To Post Trace" xil_pn:value="-4" xil_pn:valueState="default"/>
<property xil_pn:name="Combinatorial Logic Optimization" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Compile EDK Simulation Library" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="Compile SIMPRIM (Timing) Simulation Library" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="Compile UNISIM (Functional) Simulation Library" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="Compile XilinxCoreLib (CORE Generator) Simulation Library" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="Compile for HDL Debugging" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="Configuration Clk (Configuration Pins)" xil_pn:value="Pull Up" xil_pn:valueState="default"/>
<property xil_pn:name="Configuration Pin Done" xil_pn:value="Pull Up" xil_pn:valueState="default"/>
<property xil_pn:name="Configuration Pin HSWAPEN" xil_pn:value="Pull Up" xil_pn:valueState="default"/>
<property xil_pn:name="Configuration Pin M0" xil_pn:value="Pull Up" xil_pn:valueState="default"/>
<property xil_pn:name="Configuration Pin M1" xil_pn:value="Pull Up" xil_pn:valueState="default"/>
<property xil_pn:name="Configuration Pin M2" xil_pn:value="Pull Up" xil_pn:valueState="default"/>
<property xil_pn:name="Configuration Pin Program" xil_pn:value="Pull Up" xil_pn:valueState="default"/>
<property xil_pn:name="Configuration Rate" xil_pn:value="Default (1)" xil_pn:valueState="default"/>
<property xil_pn:name="Correlate Output to Input Design" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Create ASCII Configuration File" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Create Binary Configuration File" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Create Bit File" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="Create I/O Pads from Ports" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Create IEEE 1532 Configuration File" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Create Logic Allocation File" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Create Mask File" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Create ReadBack Data Files" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Cross Clock Analysis" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Custom Waveform Configuration File Behav" xil_pn:value="ram_controller_chronogram.wcfg" xil_pn:valueState="non-default"/>
<property xil_pn:name="DCI Update Mode" xil_pn:value="As Required" xil_pn:valueState="default"/>
<property xil_pn:name="Decoder Extraction" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="Delay Values To Be Read from SDF" xil_pn:value="Setup Time" xil_pn:valueState="default"/>
<property xil_pn:name="Device" xil_pn:value="xc3s250e" xil_pn:valueState="non-default"/>
<property xil_pn:name="Device Family" xil_pn:value="Spartan3E" xil_pn:valueState="non-default"/>
<property xil_pn:name="Device Speed Grade/Select ABS Minimum" xil_pn:value="-4" xil_pn:valueState="default"/>
<property xil_pn:name="Do Not Escape Signal and Instance Names in Netlist" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Done (Output Events)" xil_pn:value="Default (4)" xil_pn:valueState="default"/>
<property xil_pn:name="Drive Done Pin High" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Enable BitStream Compression" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Enable Cyclic Redundancy Checking (CRC)" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="Enable Debugging of Serial Mode BitStream" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Enable Hardware Co-Simulation" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Enable Internal Done Pipe" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Enable Message Filtering" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Enable Outputs (Output Events)" xil_pn:value="Default (5)" xil_pn:valueState="default"/>
<property xil_pn:name="Equivalent Register Removal XST" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="Evaluation Development Board" xil_pn:value="None Specified" xil_pn:valueState="default"/>
<property xil_pn:name="Exclude Compilation of Deprecated EDK Cores" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="Exclude Compilation of EDK Sub-Libraries" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Extra Effort" xil_pn:value="None" xil_pn:valueState="default"/>
<property xil_pn:name="Extra Effort (Highest PAR level only)" xil_pn:value="None" xil_pn:valueState="default"/>
<property xil_pn:name="FPGA Start-Up Clock" xil_pn:value="CCLK" xil_pn:valueState="default"/>
<property xil_pn:name="FSM Encoding Algorithm" xil_pn:value="Auto" xil_pn:valueState="default"/>
<property xil_pn:name="FSM Style" xil_pn:value="LUT" xil_pn:valueState="default"/>
<property xil_pn:name="Filter Files From Compile Order" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="Flatten Output Netlist" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Functional Model Target Language ArchWiz" xil_pn:value="Verilog" xil_pn:valueState="default"/>
<property xil_pn:name="Functional Model Target Language Coregen" xil_pn:value="Verilog" xil_pn:valueState="default"/>
<property xil_pn:name="Functional Model Target Language Schematic" xil_pn:value="Verilog" xil_pn:valueState="default"/>
<property xil_pn:name="Generate Architecture Only (No Entity Declaration)" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Generate Asynchronous Delay Report" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Generate Clock Region Report" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Generate Constraints Interaction Report" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Generate Constraints Interaction Report Post Trace" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Generate Datasheet Section" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="Generate Datasheet Section Post Trace" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="Generate Detailed MAP Report" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Generate Multiple Hierarchical Netlist Files" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Generate Post-Place &amp; Route Power Report" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Generate Post-Place &amp; Route Simulation Model" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Generate RTL Schematic" xil_pn:value="Yes" xil_pn:valueState="default"/>
<property xil_pn:name="Generate SAIF File for Power Optimization/Estimation Par" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Generate Testbench File" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Generate Timegroups Section" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Generate Timegroups Section Post Trace" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Generics, Parameters" xil_pn:value="" xil_pn:valueState="default"/>
<property xil_pn:name="Global Optimization Goal" xil_pn:value="AllClockNets" xil_pn:valueState="default"/>
<property xil_pn:name="Global Set/Reset Port Name" xil_pn:value="GSR_PORT" xil_pn:valueState="default"/>
<property xil_pn:name="Global Tristate Port Name" xil_pn:value="GTS_PORT" xil_pn:valueState="default"/>
<property xil_pn:name="Hierarchy Separator" xil_pn:value="/" xil_pn:valueState="default"/>
<property xil_pn:name="ISim UUT Instance Name" xil_pn:value="UUT" xil_pn:valueState="default"/>
<property xil_pn:name="Ignore User Timing Constraints Map" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Ignore User Timing Constraints Par" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Implementation Top" xil_pn:value="Module|tld_spartan3_sp16k" xil_pn:valueState="non-default"/>
<property xil_pn:name="Implementation Top File" xil_pn:value="spectrum16k_TOP.v" xil_pn:valueState="non-default"/>
<property xil_pn:name="Implementation Top Instance Path" xil_pn:value="/tld_spartan3_sp16k" xil_pn:valueState="non-default"/>
<property xil_pn:name="Include 'uselib Directive in Verilog File" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Include SIMPRIM Models in Verilog File" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Include UNISIM Models in Verilog File" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Include sdf_annotate task in Verilog File" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="Incremental Compilation" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="Insert Buffers to Prevent Pulse Swallowing" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="Instantiation Template Target Language Xps" xil_pn:value="Verilog" xil_pn:valueState="default"/>
<property xil_pn:name="JTAG Pin TCK" xil_pn:value="Pull Up" xil_pn:valueState="default"/>
<property xil_pn:name="JTAG Pin TDI" xil_pn:value="Pull Up" xil_pn:valueState="default"/>
<property xil_pn:name="JTAG Pin TDO" xil_pn:value="Pull Up" xil_pn:valueState="default"/>
<property xil_pn:name="JTAG Pin TMS" xil_pn:value="Pull Up" xil_pn:valueState="default"/>
<property xil_pn:name="Keep Hierarchy" xil_pn:value="No" xil_pn:valueState="default"/>
<property xil_pn:name="Language" xil_pn:value="VHDL" xil_pn:valueState="default"/>
<property xil_pn:name="Last Applied Goal" xil_pn:value="Balanced" xil_pn:valueState="default"/>
<property xil_pn:name="Last Applied Strategy" xil_pn:value="Xilinx Default (unlocked)" xil_pn:valueState="default"/>
<property xil_pn:name="Last Unlock Status" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Launch SDK after Export" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="Library for Verilog Sources" xil_pn:value="" xil_pn:valueState="default"/>
<property xil_pn:name="Load glbl" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="Logical Shifter Extraction" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="Manual Implementation Compile Order" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Map Effort Level" xil_pn:value="High" xil_pn:valueState="default"/>
<property xil_pn:name="Map Slice Logic into Unused Block RAMs" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Max Fanout" xil_pn:value="500" xil_pn:valueState="default"/>
<property xil_pn:name="Maximum Number of Lines in Report" xil_pn:value="1000" xil_pn:valueState="default"/>
<property xil_pn:name="Maximum Signal Name Length" xil_pn:value="20" xil_pn:valueState="default"/>
<property xil_pn:name="Move First Flip-Flop Stage" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="Move Last Flip-Flop Stage" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="Multiplier Style" xil_pn:value="Auto" xil_pn:valueState="default"/>
<property xil_pn:name="Mux Extraction" xil_pn:value="Yes" xil_pn:valueState="default"/>
<property xil_pn:name="Mux Style" xil_pn:value="Auto" xil_pn:valueState="default"/>
<property xil_pn:name="Netlist Hierarchy" xil_pn:value="As Optimized" xil_pn:valueState="default"/>
<property xil_pn:name="Netlist Translation Type" xil_pn:value="Timestamp" xil_pn:valueState="default"/>
<property xil_pn:name="Number of Clock Buffers" xil_pn:value="24" xil_pn:valueState="default"/>
<property xil_pn:name="Number of Paths in Error/Verbose Report" xil_pn:value="3" xil_pn:valueState="default"/>
<property xil_pn:name="Number of Paths in Error/Verbose Report Post Trace" xil_pn:value="3" xil_pn:valueState="default"/>
<property xil_pn:name="Optimization Effort" xil_pn:value="Normal" xil_pn:valueState="default"/>
<property xil_pn:name="Optimization Goal" xil_pn:value="Speed" xil_pn:valueState="default"/>
<property xil_pn:name="Optimization Strategy (Cover Mode)" xil_pn:value="Area" xil_pn:valueState="default"/>
<property xil_pn:name="Optimize Instantiated Primitives" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Other Bitgen Command Line Options" xil_pn:value="" xil_pn:valueState="default"/>
<property xil_pn:name="Other Compiler Options" xil_pn:value="" xil_pn:valueState="default"/>
<property xil_pn:name="Other Compiler Options Map" xil_pn:value="" xil_pn:valueState="default"/>
<property xil_pn:name="Other Compiler Options Par" xil_pn:value="" xil_pn:valueState="default"/>
<property xil_pn:name="Other Compiler Options Translate" xil_pn:value="" xil_pn:valueState="default"/>
<property xil_pn:name="Other Compxlib Command Line Options" xil_pn:value="" xil_pn:valueState="default"/>
<property xil_pn:name="Other Map Command Line Options" xil_pn:value="" xil_pn:valueState="default"/>
<property xil_pn:name="Other NETGEN Command Line Options" xil_pn:value="" xil_pn:valueState="default"/>
<property xil_pn:name="Other Ngdbuild Command Line Options" xil_pn:value="" xil_pn:valueState="default"/>
<property xil_pn:name="Other Place &amp; Route Command Line Options" xil_pn:value="" xil_pn:valueState="default"/>
<property xil_pn:name="Other Simulator Commands Behavioral" xil_pn:value="" xil_pn:valueState="default"/>
<property xil_pn:name="Other Simulator Commands Post-Map" xil_pn:value="" xil_pn:valueState="default"/>
<property xil_pn:name="Other Simulator Commands Post-Route" xil_pn:value="" xil_pn:valueState="default"/>
<property xil_pn:name="Other Simulator Commands Post-Translate" xil_pn:value="" xil_pn:valueState="default"/>
<property xil_pn:name="Other XPWR Command Line Options" xil_pn:value="" xil_pn:valueState="default"/>
<property xil_pn:name="Other XST Command Line Options" xil_pn:value="" xil_pn:valueState="default"/>
<property xil_pn:name="Output Extended Identifiers" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Output File Name" xil_pn:value="tld_spartan3_sp16k" xil_pn:valueState="default"/>
<property xil_pn:name="Overwrite Compiled Libraries" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Pack I/O Registers into IOBs" xil_pn:value="Auto" xil_pn:valueState="default"/>
<property xil_pn:name="Pack I/O Registers/Latches into IOBs" xil_pn:value="Off" xil_pn:valueState="default"/>
<property xil_pn:name="Package" xil_pn:value="vq100" xil_pn:valueState="default"/>
<property xil_pn:name="Perform Advanced Analysis" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Perform Advanced Analysis Post Trace" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Perform Timing-Driven Packing and Placement" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Place &amp; Route Effort Level (Overall)" xil_pn:value="High" xil_pn:valueState="default"/>
<property xil_pn:name="Place And Route Mode" xil_pn:value="Normal Place and Route" xil_pn:valueState="default"/>
<property xil_pn:name="Placer Effort Level (Overrides Overall Level)" xil_pn:value="None" xil_pn:valueState="default"/>
<property xil_pn:name="Port to be used" xil_pn:value="Auto - default" xil_pn:valueState="default"/>
<property xil_pn:name="Post Map Simulation Model Name" xil_pn:value="tld_spartan3_sp16k_map.v" xil_pn:valueState="default"/>
<property xil_pn:name="Post Place &amp; Route Simulation Model Name" xil_pn:value="tld_spartan3_sp16k_timesim.v" xil_pn:valueState="default"/>
<property xil_pn:name="Post Synthesis Simulation Model Name" xil_pn:value="tld_spartan3_sp16k_synthesis.v" xil_pn:valueState="default"/>
<property xil_pn:name="Post Translate Simulation Model Name" xil_pn:value="tld_spartan3_sp16k_translate.v" xil_pn:valueState="default"/>
<property xil_pn:name="Power Reduction Map" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Power Reduction Par" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Preferred Language" xil_pn:value="Verilog" xil_pn:valueState="default"/>
<property xil_pn:name="Priority Encoder Extraction" xil_pn:value="Yes" xil_pn:valueState="default"/>
<property xil_pn:name="Produce Verbose Report" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Project Description" xil_pn:value="" xil_pn:valueState="default"/>
<property xil_pn:name="Project Generator" xil_pn:value="ProjNav" xil_pn:valueState="default"/>
<property xil_pn:name="Property Specification in Project File" xil_pn:value="Store all values" xil_pn:valueState="default"/>
<property xil_pn:name="RAM Extraction" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="RAM Style" xil_pn:value="Auto" xil_pn:valueState="default"/>
<property xil_pn:name="ROM Extraction" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="ROM Style" xil_pn:value="Auto" xil_pn:valueState="default"/>
<property xil_pn:name="Read Cores" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="Regenerate Core" xil_pn:value="Under Current Project Setting" xil_pn:valueState="default"/>
<property xil_pn:name="Register Balancing" xil_pn:value="No" xil_pn:valueState="default"/>
<property xil_pn:name="Register Duplication" xil_pn:value="Off" xil_pn:valueState="default"/>
<property xil_pn:name="Register Duplication Xst" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="Release Write Enable (Output Events)" xil_pn:value="Default (6)" xil_pn:valueState="default"/>
<property xil_pn:name="Rename Design Instance in Testbench File to" xil_pn:value="UUT" xil_pn:valueState="default"/>
<property xil_pn:name="Rename Top Level Architecture To" xil_pn:value="Structure" xil_pn:valueState="default"/>
<property xil_pn:name="Rename Top Level Entity to" xil_pn:value="" xil_pn:valueState="default"/>
<property xil_pn:name="Rename Top Level Module To" xil_pn:value="" xil_pn:valueState="default"/>
<property xil_pn:name="Report Fastest Path(s) in Each Constraint" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="Report Fastest Path(s) in Each Constraint Post Trace" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="Report Paths by Endpoint" xil_pn:value="3" xil_pn:valueState="default"/>
<property xil_pn:name="Report Paths by Endpoint Post Trace" xil_pn:value="3" xil_pn:valueState="default"/>
<property xil_pn:name="Report Type" xil_pn:value="Verbose Report" xil_pn:valueState="default"/>
<property xil_pn:name="Report Type Post Trace" xil_pn:value="Verbose Report" xil_pn:valueState="default"/>
<property xil_pn:name="Report Unconstrained Paths" xil_pn:value="" xil_pn:valueState="default"/>
<property xil_pn:name="Report Unconstrained Paths Post Trace" xil_pn:value="" xil_pn:valueState="default"/>
<property xil_pn:name="Reset DCM if SHUTDOWN &amp; AGHIGH performed" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Reset On Configuration Pulse Width" xil_pn:value="100" xil_pn:valueState="default"/>
<property xil_pn:name="Resource Sharing" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="Retain Hierarchy" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="Router Effort Level (Overrides Overall Level)" xil_pn:value="None" xil_pn:valueState="default"/>
<property xil_pn:name="Run Design Rules Checker (DRC)" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="Run for Specified Time" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="Run for Specified Time Map" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="Run for Specified Time Par" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="Run for Specified Time Translate" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="Safe Implementation" xil_pn:value="No" xil_pn:valueState="default"/>
<property xil_pn:name="Security" xil_pn:value="Enable Readback and Reconfiguration" xil_pn:valueState="default"/>
<property xil_pn:name="Selected Module Instance Name" xil_pn:value="/tld_spartan3_sp48k" xil_pn:valueState="non-default"/>
<property xil_pn:name="Selected Simulation Root Source Node Behavioral" xil_pn:value="work.tld_spartan3_sp48k" xil_pn:valueState="non-default"/>
<property xil_pn:name="Selected Simulation Root Source Node Post-Map" xil_pn:value="" xil_pn:valueState="default"/>
<property xil_pn:name="Selected Simulation Root Source Node Post-Route" xil_pn:value="" xil_pn:valueState="default"/>
<property xil_pn:name="Selected Simulation Root Source Node Post-Translate" xil_pn:value="" xil_pn:valueState="default"/>
<property xil_pn:name="Selected Simulation Source Node" xil_pn:value="UUT" xil_pn:valueState="default"/>
<property xil_pn:name="Shift Register Extraction" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="Show All Models" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Simulation Model Target" xil_pn:value="Verilog" xil_pn:valueState="default"/>
<property xil_pn:name="Simulation Run Time ISim" xil_pn:value="6700 ns" xil_pn:valueState="non-default"/>
<property xil_pn:name="Simulation Run Time Map" xil_pn:value="1000 ns" xil_pn:valueState="default"/>
<property xil_pn:name="Simulation Run Time Par" xil_pn:value="1000 ns" xil_pn:valueState="default"/>
<property xil_pn:name="Simulation Run Time Translate" xil_pn:value="1000 ns" xil_pn:valueState="default"/>
<property xil_pn:name="Simulator" xil_pn:value="ISim (VHDL/Verilog)" xil_pn:valueState="default"/>
<property xil_pn:name="Slice Packing" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="Slice Utilization Ratio" xil_pn:value="100" xil_pn:valueState="default"/>
<property xil_pn:name="Specify 'define Macro Name and Value" xil_pn:value="" xil_pn:valueState="default"/>
<property xil_pn:name="Specify Top Level Instance Names Behavioral" xil_pn:value="work.tld_spartan3_sp48k" xil_pn:valueState="default"/>
<property xil_pn:name="Specify Top Level Instance Names Post-Map" xil_pn:value="Default" xil_pn:valueState="default"/>
<property xil_pn:name="Specify Top Level Instance Names Post-Route" xil_pn:value="Default" xil_pn:valueState="default"/>
<property xil_pn:name="Specify Top Level Instance Names Post-Translate" xil_pn:value="Default" xil_pn:valueState="default"/>
<property xil_pn:name="Speed Grade" xil_pn:value="-4" xil_pn:valueState="non-default"/>
<property xil_pn:name="Starting Placer Cost Table (1-100) Map" xil_pn:value="1" xil_pn:valueState="default"/>
<property xil_pn:name="Starting Placer Cost Table (1-100) Par" xil_pn:value="1" xil_pn:valueState="default"/>
<property xil_pn:name="Synthesis Tool" xil_pn:value="XST (VHDL/Verilog)" xil_pn:valueState="default"/>
<property xil_pn:name="Target Simulator" xil_pn:value="Please Specify" xil_pn:valueState="default"/>
<property xil_pn:name="Timing Mode Map" xil_pn:value="Non Timing Driven" xil_pn:valueState="default"/>
<property xil_pn:name="Timing Mode Par" xil_pn:value="Performance Evaluation" xil_pn:valueState="default"/>
<property xil_pn:name="Top-Level Module Name in Output Netlist" xil_pn:value="" xil_pn:valueState="default"/>
<property xil_pn:name="Top-Level Source Type" xil_pn:value="HDL" xil_pn:valueState="default"/>
<property xil_pn:name="Trim Unconnected Signals" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="Tristate On Configuration Pulse Width" xil_pn:value="0" xil_pn:valueState="default"/>
<property xil_pn:name="Unused IOB Pins" xil_pn:value="Pull Down" xil_pn:valueState="default"/>
<property xil_pn:name="Use 64-bit PlanAhead on 64-bit Systems" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="Use Clock Enable" xil_pn:value="Yes" xil_pn:valueState="default"/>
<property xil_pn:name="Use Custom Project File Behavioral" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Use Custom Project File Post-Map" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Use Custom Project File Post-Route" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Use Custom Project File Post-Translate" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Use Custom Simulation Command File Behavioral" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Use Custom Simulation Command File Map" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Use Custom Simulation Command File Par" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Use Custom Simulation Command File Translate" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Use Custom Waveform Configuration File Behav" xil_pn:value="true" xil_pn:valueState="non-default"/>
<property xil_pn:name="Use Custom Waveform Configuration File Map" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Use Custom Waveform Configuration File Par" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Use Custom Waveform Configuration File Translate" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Use LOC Constraints" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="Use RLOC Constraints" xil_pn:value="Yes" xil_pn:valueState="default"/>
<property xil_pn:name="Use Smart Guide" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Use Synchronous Reset" xil_pn:value="Yes" xil_pn:valueState="default"/>
<property xil_pn:name="Use Synchronous Set" xil_pn:value="Yes" xil_pn:valueState="default"/>
<property xil_pn:name="Use Synthesis Constraints File" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="User Browsed Strategy Files" xil_pn:value="" xil_pn:valueState="default"/>
<property xil_pn:name="UserID Code (8 Digit Hexadecimal)" xil_pn:value="0xFFFFFFFF" xil_pn:valueState="default"/>
<property xil_pn:name="VHDL Source Analysis Standard" xil_pn:value="VHDL-200X" xil_pn:valueState="non-default"/>
<property xil_pn:name="Value Range Check" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Verilog 2001 Xst" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="Verilog Macros" xil_pn:value="" xil_pn:valueState="default"/>
<property xil_pn:name="Wait for DCI Match (Output Events) virtex2" xil_pn:value="Auto" xil_pn:valueState="default"/>
<property xil_pn:name="Wait for DLL Lock (Output Events)" xil_pn:value="Default (NoWait)" xil_pn:valueState="default"/>
<property xil_pn:name="Working Directory" xil_pn:value="." xil_pn:valueState="non-default"/>
<property xil_pn:name="Write Timing Constraints" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="XOR Collapsing" xil_pn:value="true" xil_pn:valueState="default"/>
<!-- -->
<!-- The following properties are for internal use only. These should not be modified.-->
<!-- -->
<property xil_pn:name="PROP_BehavioralSimTop" xil_pn:value="Module|tld_spartan3_sp48k" xil_pn:valueState="non-default"/>
<property xil_pn:name="PROP_DesignName" xil_pn:value="zx_spectrum_48k" xil_pn:valueState="non-default"/>
<property xil_pn:name="PROP_DevFamilyPMName" xil_pn:value="spartan3e" xil_pn:valueState="default"/>
<property xil_pn:name="PROP_FPGAConfiguration" xil_pn:value="FPGAConfiguration" xil_pn:valueState="default"/>
<property xil_pn:name="PROP_PostMapSimTop" xil_pn:value="" xil_pn:valueState="default"/>
<property xil_pn:name="PROP_PostParSimTop" xil_pn:value="" xil_pn:valueState="default"/>
<property xil_pn:name="PROP_PostSynthSimTop" xil_pn:value="" xil_pn:valueState="default"/>
<property xil_pn:name="PROP_PostXlateSimTop" xil_pn:value="" xil_pn:valueState="default"/>
<property xil_pn:name="PROP_PreSynthesis" xil_pn:value="PreSynthesis" xil_pn:valueState="default"/>
<property xil_pn:name="PROP_intProjectCreationTimestamp" xil_pn:value="2012-04-24T12:50:54" xil_pn:valueState="non-default"/>
<property xil_pn:name="PROP_intWbtProjectID" xil_pn:value="44419C92BD2D457E847B96D98538FAD4" xil_pn:valueState="non-default"/>
<property xil_pn:name="PROP_intWorkingDirLocWRTProjDir" xil_pn:value="Same" xil_pn:valueState="non-default"/>
<property xil_pn:name="PROP_intWorkingDirUsed" xil_pn:value="No" xil_pn:valueState="non-default"/>
</properties>
 
<bindings/>
 
<libraries/>
 
<autoManagedFiles>
<!-- The following files are identified by `include statements in verilog -->
<!-- source files and are automatically managed by Project Navigator. -->
<!-- -->
<!-- Do not hand-edit this section, as it will be overwritten when the -->
<!-- project is analyzed based on files automatically identified as -->
<!-- include files. -->
</autoManagedFiles>
 
</project>
/zx_ula/branches/xilinx/spectrum_16k_with_rom_game_for_ols/tv80_mcode.v
0,0 → 1,2650
//
// TV80 8-Bit Microprocessor Core
// Based on the VHDL T80 core by Daniel Wallner (jesus@opencores.org)
//
// Copyright (c) 2004,2007 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_mcode
(/*AUTOARG*/
// Outputs
MCycles, TStates, Prefix, Inc_PC, Inc_WZ, IncDec_16, Read_To_Reg,
Read_To_Acc, Set_BusA_To, Set_BusB_To, ALU_Op, Save_ALU, PreserveC,
Arith16, Set_Addr_To, IORQ, Jump, JumpE, JumpXY, Call, RstP, LDZ,
LDW, LDSPHL, Special_LD, ExchangeDH, ExchangeRp, ExchangeAF,
ExchangeRS, I_DJNZ, I_CPL, I_CCF, I_SCF, I_RETN, I_BT, I_BC, I_BTR,
I_RLD, I_RRD, I_INRC, SetDI, SetEI, IMode, Halt, NoRead, Write,
// Inputs
IR, ISet, MCycle, F, NMICycle, IntCycle
);
parameter Mode = 0;
parameter Flag_C = 0;
parameter Flag_N = 1;
parameter Flag_P = 2;
parameter Flag_X = 3;
parameter Flag_H = 4;
parameter Flag_Y = 5;
parameter Flag_Z = 6;
parameter Flag_S = 7;
 
input [7:0] IR;
input [1:0] ISet ;
input [6:0] MCycle ;
input [7:0] F ;
input NMICycle ;
input IntCycle ;
output [2:0] MCycles ;
output [2:0] TStates ;
output [1:0] Prefix ; // None,BC,ED,DD/FD
output Inc_PC ;
output Inc_WZ ;
output [3:0] IncDec_16 ; // BC,DE,HL,SP 0 is inc
output Read_To_Reg ;
output Read_To_Acc ;
output [3:0] Set_BusA_To ; // B,C,D,E,H,L,DI/DB,A,SP(L),SP(M),0,F
output [3:0] Set_BusB_To ; // B,C,D,E,H,L,DI,A,SP(L),SP(M),1,F,PC(L),PC(M),0
output [3:0] ALU_Op ;
output Save_ALU ;
output PreserveC ;
output Arith16 ;
output [2:0] Set_Addr_To ; // aNone,aXY,aIOA,aSP,aBC,aDE,aZI
output IORQ ;
output Jump ;
output JumpE ;
output JumpXY ;
output Call ;
output RstP ;
output LDZ ;
output LDW ;
output LDSPHL ;
output [2:0] Special_LD ; // A,I;A,R;I,A;R,A;None
output ExchangeDH ;
output ExchangeRp ;
output ExchangeAF ;
output ExchangeRS ;
output I_DJNZ ;
output I_CPL ;
output I_CCF ;
output I_SCF ;
output I_RETN ;
output I_BT ;
output I_BC ;
output I_BTR ;
output I_RLD ;
output I_RRD ;
output I_INRC ;
output SetDI ;
output SetEI ;
output [1:0] IMode ;
output Halt ;
output NoRead ;
output Write ;
 
// regs
reg [2:0] MCycles ;
reg [2:0] TStates ;
reg [1:0] Prefix ; // None,BC,ED,DD/FD
reg Inc_PC ;
reg Inc_WZ ;
reg [3:0] IncDec_16 ; // BC,DE,HL,SP 0 is inc
reg Read_To_Reg ;
reg Read_To_Acc ;
reg [3:0] Set_BusA_To ; // B,C,D,E,H,L,DI/DB,A,SP(L),SP(M),0,F
reg [3:0] Set_BusB_To ; // B,C,D,E,H,L,DI,A,SP(L),SP(M),1,F,PC(L),PC(M),0
reg [3:0] ALU_Op ;
reg Save_ALU ;
reg PreserveC ;
reg Arith16 ;
reg [2:0] Set_Addr_To ; // aNone,aXY,aIOA,aSP,aBC,aDE,aZI
reg IORQ ;
reg Jump ;
reg JumpE ;
reg JumpXY ;
reg Call ;
reg RstP ;
reg LDZ ;
reg LDW ;
reg LDSPHL ;
reg [2:0] Special_LD ; // A,I;A,R;I,A;R,A;None
reg ExchangeDH ;
reg ExchangeRp ;
reg ExchangeAF ;
reg ExchangeRS ;
reg I_DJNZ ;
reg I_CPL ;
reg I_CCF ;
reg I_SCF ;
reg I_RETN ;
reg I_BT ;
reg I_BC ;
reg I_BTR ;
reg I_RLD ;
reg I_RRD ;
reg I_INRC ;
reg SetDI ;
reg SetEI ;
reg [1:0] IMode ;
reg Halt ;
reg NoRead ;
reg Write ;
 
parameter aNone = 3'b111;
parameter aBC = 3'b000;
parameter aDE = 3'b001;
parameter aXY = 3'b010;
parameter aIOA = 3'b100;
parameter aSP = 3'b101;
parameter aZI = 3'b110;
// constant aNone : std_logic_vector[2:0] = 3'b000;
// constant aXY : std_logic_vector[2:0] = 3'b001;
// constant aIOA : std_logic_vector[2:0] = 3'b010;
// constant aSP : std_logic_vector[2:0] = 3'b011;
// constant aBC : std_logic_vector[2:0] = 3'b100;
// constant aDE : std_logic_vector[2:0] = 3'b101;
// constant aZI : std_logic_vector[2:0] = 3'b110;
 
function is_cc_true;
input [7:0] FF;
input [2:0] cc;
begin
if (Mode == 3 )
begin
case (cc)
3'b000 : is_cc_true = FF[7] == 1'b0; // NZ
3'b001 : is_cc_true = FF[7] == 1'b1; // Z
3'b010 : is_cc_true = FF[4] == 1'b0; // NC
3'b011 : is_cc_true = FF[4] == 1'b1; // C
3'b100 : is_cc_true = 0;
3'b101 : is_cc_true = 0;
3'b110 : is_cc_true = 0;
3'b111 : is_cc_true = 0;
endcase
end
else
begin
case (cc)
3'b000 : is_cc_true = FF[6] == 1'b0; // NZ
3'b001 : is_cc_true = FF[6] == 1'b1; // Z
3'b010 : is_cc_true = FF[0] == 1'b0; // NC
3'b011 : is_cc_true = FF[0] == 1'b1; // C
3'b100 : is_cc_true = FF[2] == 1'b0; // PO
3'b101 : is_cc_true = FF[2] == 1'b1; // PE
3'b110 : is_cc_true = FF[7] == 1'b0; // P
3'b111 : is_cc_true = FF[7] == 1'b1; // M
endcase
end
end
endfunction // is_cc_true
 
reg [2:0] DDD;
reg [2:0] SSS;
reg [1:0] DPAIR;
always @ (/*AUTOSENSE*/F or IR or ISet or IntCycle or MCycle
or NMICycle)
begin
DDD = IR[5:3];
SSS = IR[2:0];
DPAIR = IR[5:4];
 
MCycles = 3'b001;
if (MCycle[0] )
begin
TStates = 3'b100;
end
else
begin
TStates = 3'b011;
end
Prefix = 2'b00;
Inc_PC = 1'b0;
Inc_WZ = 1'b0;
IncDec_16 = 4'b0000;
Read_To_Acc = 1'b0;
Read_To_Reg = 1'b0;
Set_BusB_To = 4'b0000;
Set_BusA_To = 4'b0000;
ALU_Op = { 1'b0, IR[5:3] };
Save_ALU = 1'b0;
PreserveC = 1'b0;
Arith16 = 1'b0;
IORQ = 1'b0;
Set_Addr_To = aNone;
Jump = 1'b0;
JumpE = 1'b0;
JumpXY = 1'b0;
Call = 1'b0;
RstP = 1'b0;
LDZ = 1'b0;
LDW = 1'b0;
LDSPHL = 1'b0;
Special_LD = 3'b000;
ExchangeDH = 1'b0;
ExchangeRp = 1'b0;
ExchangeAF = 1'b0;
ExchangeRS = 1'b0;
I_DJNZ = 1'b0;
I_CPL = 1'b0;
I_CCF = 1'b0;
I_SCF = 1'b0;
I_RETN = 1'b0;
I_BT = 1'b0;
I_BC = 1'b0;
I_BTR = 1'b0;
I_RLD = 1'b0;
I_RRD = 1'b0;
I_INRC = 1'b0;
SetDI = 1'b0;
SetEI = 1'b0;
IMode = 2'b11;
Halt = 1'b0;
NoRead = 1'b0;
Write = 1'b0;
case (ISet)
2'b00 :
begin
 
//----------------------------------------------------------------------------
//
// Unprefixed instructions
//
//----------------------------------------------------------------------------
 
casez (IR)
// 8 BIT LOAD GROUP
8'b01zzzzzz :
begin
if (IR[5:0] == 6'b110110)
Halt = 1'b1;
else if (IR[2:0] == 3'b110)
begin
// LD r,(HL)
MCycles = 3'b010;
if (MCycle[0])
Set_Addr_To = aXY;
if (MCycle[1])
begin
Set_BusA_To[2:0] = DDD;
Read_To_Reg = 1'b1;
end
end // if (IR[2:0] == 3'b110)
else if (IR[5:3] == 3'b110)
begin
// LD (HL),r
MCycles = 3'b010;
if (MCycle[0])
begin
Set_Addr_To = aXY;
Set_BusB_To[2:0] = SSS;
Set_BusB_To[3] = 1'b0;
end
if (MCycle[1])
Write = 1'b1;
end // if (IR[5:3] == 3'b110)
else
begin
Set_BusB_To[2:0] = SSS;
ExchangeRp = 1'b1;
Set_BusA_To[2:0] = DDD;
Read_To_Reg = 1'b1;
end // else: !if(IR[5:3] == 3'b110)
end // case: 8'b01zzzzzz
 
8'b00zzz110 :
begin
if (IR[5:3] == 3'b110)
begin
// LD (HL),n
MCycles = 3'b011;
if (MCycle[1])
begin
Inc_PC = 1'b1;
Set_Addr_To = aXY;
Set_BusB_To[2:0] = SSS;
Set_BusB_To[3] = 1'b0;
end
if (MCycle[2])
Write = 1'b1;
end // if (IR[5:3] == 3'b110)
else
begin
// LD r,n
MCycles = 3'b010;
if (MCycle[1])
begin
Inc_PC = 1'b1;
Set_BusA_To[2:0] = DDD;
Read_To_Reg = 1'b1;
end
end
end
8'b00001010 :
begin
// LD A,(BC)
MCycles = 3'b010;
if (MCycle[0])
Set_Addr_To = aBC;
if (MCycle[1])
Read_To_Acc = 1'b1;
end // case: 8'b00001010
8'b00011010 :
begin
// LD A,(DE)
MCycles = 3'b010;
if (MCycle[0])
Set_Addr_To = aDE;
if (MCycle[1])
Read_To_Acc = 1'b1;
end // case: 8'b00011010
8'b00111010 :
begin
if (Mode == 3 )
begin
// LDD A,(HL)
MCycles = 3'b010;
if (MCycle[0])
Set_Addr_To = aXY;
if (MCycle[1])
begin
Read_To_Acc = 1'b1;
IncDec_16 = 4'b1110;
end
end
else
begin
// LD A,(nn)
MCycles = 3'b100;
if (MCycle[1])
begin
Inc_PC = 1'b1;
LDZ = 1'b1;
end
if (MCycle[2])
begin
Set_Addr_To = aZI;
Inc_PC = 1'b1;
end
if (MCycle[3])
begin
Read_To_Acc = 1'b1;
end
end // else: !if(Mode == 3 )
end // case: 8'b00111010
8'b00000010 :
begin
// LD (BC),A
MCycles = 3'b010;
if (MCycle[0])
begin
Set_Addr_To = aBC;
Set_BusB_To = 4'b0111;
end
if (MCycle[1])
begin
Write = 1'b1;
end
end // case: 8'b00000010
8'b00010010 :
begin
// LD (DE),A
MCycles = 3'b010;
case (1'b1) // MCycle
MCycle[0] :
begin
Set_Addr_To = aDE;
Set_BusB_To = 4'b0111;
end
MCycle[1] :
Write = 1'b1;
default :;
endcase // case(MCycle)
end // case: 8'b00010010
8'b00110010 :
begin
if (Mode == 3 )
begin
// LDD (HL),A
MCycles = 3'b010;
case (1'b1) // MCycle
MCycle[0] :
begin
Set_Addr_To = aXY;
Set_BusB_To = 4'b0111;
end
MCycle[1] :
begin
Write = 1'b1;
IncDec_16 = 4'b1110;
end
default :;
endcase // case(MCycle)
end
else
begin
// LD (nn),A
MCycles = 3'b100;
case (1'b1) // MCycle
MCycle[1] :
begin
Inc_PC = 1'b1;
LDZ = 1'b1;
end
MCycle[2] :
begin
Set_Addr_To = aZI;
Inc_PC = 1'b1;
Set_BusB_To = 4'b0111;
end
MCycle[3] :
begin
Write = 1'b1;
end
default :;
endcase
end // else: !if(Mode == 3 )
end // case: 8'b00110010
 
// 16 BIT LOAD GROUP
8'b00000001,8'b00010001,8'b00100001,8'b00110001 :
begin
// LD dd,nn
MCycles = 3'b011;
case (1'b1) // MCycle
MCycle[1] :
begin
Inc_PC = 1'b1;
Read_To_Reg = 1'b1;
if (DPAIR == 2'b11 )
begin
Set_BusA_To[3:0] = 4'b1000;
end
else
begin
Set_BusA_To[2:1] = DPAIR;
Set_BusA_To[0] = 1'b1;
end
end // case: 2
MCycle[2] :
begin
Inc_PC = 1'b1;
Read_To_Reg = 1'b1;
if (DPAIR == 2'b11 )
begin
Set_BusA_To[3:0] = 4'b1001;
end
else
begin
Set_BusA_To[2:1] = DPAIR;
Set_BusA_To[0] = 1'b0;
end
end // case: 3
default :;
endcase // case(MCycle)
end // case: 8'b00000001,8'b00010001,8'b00100001,8'b00110001
8'b00101010 :
begin
if (Mode == 3 )
begin
// LDI A,(HL)
MCycles = 3'b010;
case (1'b1) // MCycle
MCycle[0] :
Set_Addr_To = aXY;
MCycle[1] :
begin
Read_To_Acc = 1'b1;
IncDec_16 = 4'b0110;
end
default :;
endcase
end
else
begin
// LD HL,(nn)
MCycles = 3'b101;
case (1'b1) // MCycle
MCycle[1] :
begin
Inc_PC = 1'b1;
LDZ = 1'b1;
end
MCycle[2] :
begin
Set_Addr_To = aZI;
Inc_PC = 1'b1;
LDW = 1'b1;
end
MCycle[3] :
begin
Set_BusA_To[2:0] = 3'b101; // L
Read_To_Reg = 1'b1;
Inc_WZ = 1'b1;
Set_Addr_To = aZI;
end
MCycle[4] :
begin
Set_BusA_To[2:0] = 3'b100; // H
Read_To_Reg = 1'b1;
end
default :;
endcase
end // else: !if(Mode == 3 )
end // case: 8'b00101010
8'b00100010 :
begin
if (Mode == 3 )
begin
// LDI (HL),A
MCycles = 3'b010;
case (1'b1) // MCycle
MCycle[0] :
begin
Set_Addr_To = aXY;
Set_BusB_To = 4'b0111;
end
MCycle[1] :
begin
Write = 1'b1;
IncDec_16 = 4'b0110;
end
default :;
endcase
end
else
begin
// LD (nn),HL
MCycles = 3'b101;
case (1'b1) // MCycle
MCycle[1] :
begin
Inc_PC = 1'b1;
LDZ = 1'b1;
end
MCycle[2] :
begin
Set_Addr_To = aZI;
Inc_PC = 1'b1;
LDW = 1'b1;
Set_BusB_To = 4'b0101; // L
end
MCycle[3] :
begin
Inc_WZ = 1'b1;
Set_Addr_To = aZI;
Write = 1'b1;
Set_BusB_To = 4'b0100; // H
end
MCycle[4] :
Write = 1'b1;
default :;
endcase
end // else: !if(Mode == 3 )
end // case: 8'b00100010
8'b11111001 :
begin
// LD SP,HL
TStates = 3'b110;
LDSPHL = 1'b1;
end
8'b11zz0101 :
begin
// PUSH qq
MCycles = 3'b011;
case (1'b1) // MCycle
MCycle[0] :
begin
TStates = 3'b101;
IncDec_16 = 4'b1111;
Set_Addr_To = aSP;
if (DPAIR == 2'b11 )
begin
Set_BusB_To = 4'b0111;
end
else
begin
Set_BusB_To[2:1] = DPAIR;
Set_BusB_To[0] = 1'b0;
Set_BusB_To[3] = 1'b0;
end
end // case: 1
MCycle[1] :
begin
IncDec_16 = 4'b1111;
Set_Addr_To = aSP;
if (DPAIR == 2'b11 )
begin
Set_BusB_To = 4'b1011;
end
else
begin
Set_BusB_To[2:1] = DPAIR;
Set_BusB_To[0] = 1'b1;
Set_BusB_To[3] = 1'b0;
end
Write = 1'b1;
end // case: 2
MCycle[2] :
Write = 1'b1;
default :;
endcase // case(MCycle)
end // case: 8'b11000101,8'b11010101,8'b11100101,8'b11110101
8'b11zz0001 :
begin
// POP qq
MCycles = 3'b011;
case (1'b1) // MCycle
MCycle[0] :
Set_Addr_To = aSP;
MCycle[1] :
begin
IncDec_16 = 4'b0111;
Set_Addr_To = aSP;
Read_To_Reg = 1'b1;
if (DPAIR == 2'b11 )
begin
Set_BusA_To[3:0] = 4'b1011;
end
else
begin
Set_BusA_To[2:1] = DPAIR;
Set_BusA_To[0] = 1'b1;
end
end // case: 2
MCycle[2] :
begin
IncDec_16 = 4'b0111;
Read_To_Reg = 1'b1;
if (DPAIR == 2'b11 )
begin
Set_BusA_To[3:0] = 4'b0111;
end
else
begin
Set_BusA_To[2:1] = DPAIR;
Set_BusA_To[0] = 1'b0;
end
end // case: 3
default :;
endcase // case(MCycle)
end // case: 8'b11000001,8'b11010001,8'b11100001,8'b11110001
 
// EXCHANGE, BLOCK TRANSFER AND SEARCH GROUP
8'b11101011 :
begin
if (Mode != 3 )
begin
// EX DE,HL
ExchangeDH = 1'b1;
end
end
8'b00001000 :
begin
if (Mode == 3 )
begin
// LD (nn),SP
MCycles = 3'b101;
case (1'b1) // MCycle
MCycle[1] :
begin
Inc_PC = 1'b1;
LDZ = 1'b1;
end
MCycle[2] :
begin
Set_Addr_To = aZI;
Inc_PC = 1'b1;
LDW = 1'b1;
Set_BusB_To = 4'b1000;
end
MCycle[3] :
begin
Inc_WZ = 1'b1;
Set_Addr_To = aZI;
Write = 1'b1;
Set_BusB_To = 4'b1001;
end
MCycle[4] :
Write = 1'b1;
default :;
endcase
end
else if (Mode < 2 )
begin
// EX AF,AF'
ExchangeAF = 1'b1;
end
end // case: 8'b00001000
8'b11011001 :
begin
if (Mode == 3 )
begin
// RETI
MCycles = 3'b011;
case (1'b1) // MCycle
MCycle[0] :
Set_Addr_To = aSP;
MCycle[1] :
begin
IncDec_16 = 4'b0111;
Set_Addr_To = aSP;
LDZ = 1'b1;
end
MCycle[2] :
begin
Jump = 1'b1;
IncDec_16 = 4'b0111;
I_RETN = 1'b1;
SetEI = 1'b1;
end
default :;
endcase
end
else if (Mode < 2 )
begin
// EXX
ExchangeRS = 1'b1;
end
end // case: 8'b11011001
8'b11100011 :
begin
if (Mode != 3 )
begin
// EX (SP),HL
MCycles = 3'b101;
case (1'b1) // MCycle
MCycle[0] :
Set_Addr_To = aSP;
MCycle[1] :
begin
Read_To_Reg = 1'b1;
Set_BusA_To = 4'b0101;
Set_BusB_To = 4'b0101;
Set_Addr_To = aSP;
end
MCycle[2] :
begin
IncDec_16 = 4'b0111;
Set_Addr_To = aSP;
TStates = 3'b100;
Write = 1'b1;
end
MCycle[3] :
begin
Read_To_Reg = 1'b1;
Set_BusA_To = 4'b0100;
Set_BusB_To = 4'b0100;
Set_Addr_To = aSP;
end
MCycle[4] :
begin
IncDec_16 = 4'b1111;
TStates = 3'b101;
Write = 1'b1;
end
default :;
endcase
end // if (Mode != 3 )
end // case: 8'b11100011
 
// 8 BIT ARITHMETIC AND LOGICAL GROUP
8'b10zzzzzz :
begin
if (IR[2:0] == 3'b110)
begin
// ADD A,(HL)
// ADC A,(HL)
// SUB A,(HL)
// SBC A,(HL)
// AND A,(HL)
// OR A,(HL)
// XOR A,(HL)
// CP A,(HL)
MCycles = 3'b010;
case (1'b1) // MCycle
MCycle[0] :
Set_Addr_To = aXY;
MCycle[1] :
begin
Read_To_Reg = 1'b1;
Save_ALU = 1'b1;
Set_BusB_To[2:0] = SSS;
Set_BusA_To[2:0] = 3'b111;
end
default :;
endcase // case(MCycle)
end // if (IR[2:0] == 3'b110)
else
begin
// ADD A,r
// ADC A,r
// SUB A,r
// SBC A,r
// AND A,r
// OR A,r
// XOR A,r
// CP A,r
Set_BusB_To[2:0] = SSS;
Set_BusA_To[2:0] = 3'b111;
Read_To_Reg = 1'b1;
Save_ALU = 1'b1;
end // else: !if(IR[2:0] == 3'b110)
end // case: 8'b10000000,8'b10000001,8'b10000010,8'b10000011,8'b10000100,8'b10000101,8'b10000111,...
8'b11zzz110 :
begin
// ADD A,n
// ADC A,n
// SUB A,n
// SBC A,n
// AND A,n
// OR A,n
// XOR A,n
// CP A,n
MCycles = 3'b010;
if (MCycle[1] )
begin
Inc_PC = 1'b1;
Read_To_Reg = 1'b1;
Save_ALU = 1'b1;
Set_BusB_To[2:0] = SSS;
Set_BusA_To[2:0] = 3'b111;
end
end
8'b00zzz100 :
begin
if (IR[5:3] == 3'b110)
begin
// INC (HL)
MCycles = 3'b011;
case (1'b1) // MCycle
MCycle[0] :
Set_Addr_To = aXY;
MCycle[1] :
begin
TStates = 3'b100;
Set_Addr_To = aXY;
Read_To_Reg = 1'b1;
Save_ALU = 1'b1;
PreserveC = 1'b1;
ALU_Op = 4'b0000;
Set_BusB_To = 4'b1010;
Set_BusA_To[2:0] = DDD;
end // case: 2
MCycle[2] :
Write = 1'b1;
default :;
endcase // case(MCycle)
end // case: 8'b00110100
else
begin
// INC r
Set_BusB_To = 4'b1010;
Set_BusA_To[2:0] = DDD;
Read_To_Reg = 1'b1;
Save_ALU = 1'b1;
PreserveC = 1'b1;
ALU_Op = 4'b0000;
end
end
8'b00zzz101 :
begin
if (IR[5:3] == 3'b110)
begin
// DEC (HL)
MCycles = 3'b011;
case (1'b1) // MCycle
MCycle[0] :
Set_Addr_To = aXY;
MCycle[1] :
begin
TStates = 3'b100;
Set_Addr_To = aXY;
ALU_Op = 4'b0010;
Read_To_Reg = 1'b1;
Save_ALU = 1'b1;
PreserveC = 1'b1;
Set_BusB_To = 4'b1010;
Set_BusA_To[2:0] = DDD;
end // case: 2
MCycle[2] :
Write = 1'b1;
default :;
endcase // case(MCycle)
end
else
begin
// DEC r
Set_BusB_To = 4'b1010;
Set_BusA_To[2:0] = DDD;
Read_To_Reg = 1'b1;
Save_ALU = 1'b1;
PreserveC = 1'b1;
ALU_Op = 4'b0010;
end
end
// GENERAL PURPOSE ARITHMETIC AND CPU CONTROL GROUPS
8'b00100111 :
begin
// DAA
Set_BusA_To[2:0] = 3'b111;
Read_To_Reg = 1'b1;
ALU_Op = 4'b1100;
Save_ALU = 1'b1;
end
8'b00101111 :
// CPL
I_CPL = 1'b1;
8'b00111111 :
// CCF
I_CCF = 1'b1;
8'b00110111 :
// SCF
I_SCF = 1'b1;
8'b00000000 :
begin
if (NMICycle == 1'b1 )
begin
// NMI
MCycles = 3'b011;
case (1'b1) // MCycle
MCycle[0] :
begin
TStates = 3'b101;
IncDec_16 = 4'b1111;
Set_Addr_To = aSP;
Set_BusB_To = 4'b1101;
end
MCycle[1] :
begin
TStates = 3'b100;
Write = 1'b1;
IncDec_16 = 4'b1111;
Set_Addr_To = aSP;
Set_BusB_To = 4'b1100;
end
MCycle[2] :
begin
TStates = 3'b100;
Write = 1'b1;
end
default :;
endcase // case(MCycle)
end
else if (IntCycle == 1'b1 )
begin
// INT (IM 2)
MCycles = 3'b101;
case (1'b1) // MCycle
MCycle[0] :
begin
LDZ = 1'b1;
TStates = 3'b101;
IncDec_16 = 4'b1111;
Set_Addr_To = aSP;
Set_BusB_To = 4'b1101;
end
MCycle[1] :
begin
TStates = 3'b100;
Write = 1'b1;
IncDec_16 = 4'b1111;
Set_Addr_To = aSP;
Set_BusB_To = 4'b1100;
end
MCycle[2] :
begin
TStates = 3'b100;
Write = 1'b1;
end
MCycle[3] :
begin
Inc_PC = 1'b1;
LDZ = 1'b1;
end
MCycle[4] :
Jump = 1'b1;
default :;
endcase
end
end // case: 8'b00000000
8'b11110011 :
// DI
SetDI = 1'b1;
8'b11111011 :
// EI
SetEI = 1'b1;
 
// 16 BIT ARITHMETIC GROUP
8'b00zz1001 :
begin
// ADD HL,ss
MCycles = 3'b011;
case (1'b1) // MCycle
MCycle[1] :
begin
NoRead = 1'b1;
ALU_Op = 4'b0000;
Read_To_Reg = 1'b1;
Save_ALU = 1'b1;
Set_BusA_To[2:0] = 3'b101;
case (IR[5:4])
0,1,2 :
begin
Set_BusB_To[2:1] = IR[5:4];
Set_BusB_To[0] = 1'b1;
end
default :
Set_BusB_To = 4'b1000;
endcase // case(IR[5:4])
TStates = 3'b100;
Arith16 = 1'b1;
end // case: 2
MCycle[2] :
begin
NoRead = 1'b1;
Read_To_Reg = 1'b1;
Save_ALU = 1'b1;
ALU_Op = 4'b0001;
Set_BusA_To[2:0] = 3'b100;
case (IR[5:4])
0,1,2 :
Set_BusB_To[2:1] = IR[5:4];
default :
Set_BusB_To = 4'b1001;
endcase
Arith16 = 1'b1;
end // case: 3
default :;
endcase // case(MCycle)
end // case: 8'b00001001,8'b00011001,8'b00101001,8'b00111001
8'b00zz0011 :
begin
// INC ss
TStates = 3'b110;
IncDec_16[3:2] = 2'b01;
IncDec_16[1:0] = DPAIR;
end
8'b00zz1011 :
begin
// DEC ss
TStates = 3'b110;
IncDec_16[3:2] = 2'b11;
IncDec_16[1:0] = DPAIR;
end
 
// ROTATE AND SHIFT GROUP
8'b00000111,
// RLCA
8'b00010111,
// RLA
8'b00001111,
// RRCA
8'b00011111 :
// RRA
begin
Set_BusA_To[2:0] = 3'b111;
ALU_Op = 4'b1000;
Read_To_Reg = 1'b1;
Save_ALU = 1'b1;
end // case: 8'b00000111,...
 
// JUMP GROUP
8'b11000011 :
begin
// JP nn
MCycles = 3'b011;
if (MCycle[1])
begin
Inc_PC = 1'b1;
LDZ = 1'b1;
end
if (MCycle[2])
begin
Inc_PC = 1'b1;
Jump = 1'b1;
end
end // case: 8'b11000011
8'b11zzz010 :
begin
if (IR[5] == 1'b1 && Mode == 3 )
begin
case (IR[4:3])
2'b00 :
begin
// LD ($FF00+C),A
MCycles = 3'b010;
case (1'b1) // MCycle
MCycle[0] :
begin
Set_Addr_To = aBC;
Set_BusB_To = 4'b0111;
end
MCycle[1] :
begin
Write = 1'b1;
IORQ = 1'b1;
end
default :;
endcase // case(MCycle)
end // case: 2'b00
2'b01 :
begin
// LD (nn),A
MCycles = 3'b100;
case (1'b1) // MCycle
MCycle[1] :
begin
Inc_PC = 1'b1;
LDZ = 1'b1;
end
MCycle[2] :
begin
Set_Addr_To = aZI;
Inc_PC = 1'b1;
Set_BusB_To = 4'b0111;
end
MCycle[3] :
Write = 1'b1;
default :;
endcase // case(MCycle)
end // case: default :...
2'b10 :
begin
// LD A,($FF00+C)
MCycles = 3'b010;
case (1'b1) // MCycle
MCycle[0] :
Set_Addr_To = aBC;
MCycle[1] :
begin
Read_To_Acc = 1'b1;
IORQ = 1'b1;
end
default :;
endcase // case(MCycle)
end // case: 2'b10
2'b11 :
begin
// LD A,(nn)
MCycles = 3'b100;
case (1'b1) // MCycle
MCycle[1] :
begin
Inc_PC = 1'b1;
LDZ = 1'b1;
end
MCycle[2] :
begin
Set_Addr_To = aZI;
Inc_PC = 1'b1;
end
MCycle[3] :
Read_To_Acc = 1'b1;
default :;
endcase // case(MCycle)
end
endcase
end
else
begin
// JP cc,nn
MCycles = 3'b011;
case (1'b1) // MCycle
MCycle[1] :
begin
Inc_PC = 1'b1;
LDZ = 1'b1;
end
MCycle[2] :
begin
Inc_PC = 1'b1;
if (is_cc_true(F, IR[5:3]) )
begin
Jump = 1'b1;
end
end
default :;
endcase
end // else: !if(DPAIR == 2'b11 )
end // case: 8'b11000010,8'b11001010,8'b11010010,8'b11011010,8'b11100010,8'b11101010,8'b11110010,8'b11111010
8'b00011000 :
begin
if (Mode != 2 )
begin
// JR e
MCycles = 3'b011;
case (1'b1) // MCycle
MCycle[1] :
Inc_PC = 1'b1;
MCycle[2] :
begin
NoRead = 1'b1;
JumpE = 1'b1;
TStates = 3'b101;
end
default :;
endcase
end // if (Mode != 2 )
end // case: 8'b00011000
 
// Conditional relative jumps (JR [C/NC/Z/NZ], e)
8'b001zz000 :
begin
if (Mode != 2 )
begin
MCycles = 3'd3;
case (1'b1) // MCycle
MCycle[1] :
begin
Inc_PC = 1'b1;
 
case (IR[4:3])
0 : MCycles = (F[Flag_Z]) ? 3'd2 : 3'd3;
1 : MCycles = (!F[Flag_Z]) ? 3'd2 : 3'd3;
2 : MCycles = (F[Flag_C]) ? 3'd2 : 3'd3;
3 : MCycles = (!F[Flag_C]) ? 3'd2 : 3'd3;
endcase
end
MCycle[2] :
begin
NoRead = 1'b1;
JumpE = 1'b1;
TStates = 3'd5;
end
default :;
endcase
end // if (Mode != 2 )
end // case: 8'b00111000
8'b11101001 :
// JP (HL)
JumpXY = 1'b1;
8'b00010000 :
begin
if (Mode == 3 )
begin
I_DJNZ = 1'b1;
end
else if (Mode < 2 )
begin
// DJNZ,e
MCycles = 3'b011;
case (1'b1) // MCycle
MCycle[0] :
begin
TStates = 3'b101;
I_DJNZ = 1'b1;
Set_BusB_To = 4'b1010;
Set_BusA_To[2:0] = 3'b000;
Read_To_Reg = 1'b1;
Save_ALU = 1'b1;
ALU_Op = 4'b0010;
end
MCycle[1] :
begin
I_DJNZ = 1'b1;
Inc_PC = 1'b1;
end
MCycle[2] :
begin
NoRead = 1'b1;
JumpE = 1'b1;
TStates = 3'b101;
end
default :;
endcase
end // if (Mode < 2 )
end // case: 8'b00010000
 
// CALL AND RETURN GROUP
8'b11001101 :
begin
// CALL nn
MCycles = 3'b101;
case (1'b1) // MCycle
MCycle[1] :
begin
Inc_PC = 1'b1;
LDZ = 1'b1;
end
MCycle[2] :
begin
IncDec_16 = 4'b1111;
Inc_PC = 1'b1;
TStates = 3'b100;
Set_Addr_To = aSP;
LDW = 1'b1;
Set_BusB_To = 4'b1101;
end
MCycle[3] :
begin
Write = 1'b1;
IncDec_16 = 4'b1111;
Set_Addr_To = aSP;
Set_BusB_To = 4'b1100;
end
MCycle[4] :
begin
Write = 1'b1;
Call = 1'b1;
end
default :;
endcase // case(MCycle)
end // case: 8'b11001101
8'b11zzz100 :
begin
if (IR[5] == 1'b0 || Mode != 3 )
begin
// CALL cc,nn
MCycles = 3'b101;
case (1'b1) // MCycle
MCycle[1] :
begin
Inc_PC = 1'b1;
LDZ = 1'b1;
end
MCycle[2] :
begin
Inc_PC = 1'b1;
LDW = 1'b1;
if (is_cc_true(F, IR[5:3]) )
begin
IncDec_16 = 4'b1111;
Set_Addr_To = aSP;
TStates = 3'b100;
Set_BusB_To = 4'b1101;
end
else
begin
MCycles = 3'b011;
end // else: !if(is_cc_true(F, IR[5:3]) )
end // case: 3
MCycle[3] :
begin
Write = 1'b1;
IncDec_16 = 4'b1111;
Set_Addr_To = aSP;
Set_BusB_To = 4'b1100;
end
MCycle[4] :
begin
Write = 1'b1;
Call = 1'b1;
end
default :;
endcase
end // if (IR[5] == 1'b0 || Mode != 3 )
end // case: 8'b11000100,8'b11001100,8'b11010100,8'b11011100,8'b11100100,8'b11101100,8'b11110100,8'b11111100
8'b11001001 :
begin
// RET
MCycles = 3'b011;
case (1'b1) // MCycle
MCycle[0] :
begin
TStates = 3'b101;
Set_Addr_To = aSP;
end
MCycle[1] :
begin
IncDec_16 = 4'b0111;
Set_Addr_To = aSP;
LDZ = 1'b1;
end
MCycle[2] :
begin
Jump = 1'b1;
IncDec_16 = 4'b0111;
end
default :;
endcase // case(MCycle)
end // case: 8'b11001001
8'b11000000,8'b11001000,8'b11010000,8'b11011000,8'b11100000,8'b11101000,8'b11110000,8'b11111000 :
begin
if (IR[5] == 1'b1 && Mode == 3 )
begin
case (IR[4:3])
2'b00 :
begin
// LD ($FF00+nn),A
MCycles = 3'b011;
case (1'b1) // MCycle
MCycle[1] :
begin
Inc_PC = 1'b1;
Set_Addr_To = aIOA;
Set_BusB_To = 4'b0111;
end
MCycle[2] :
Write = 1'b1;
default :;
endcase // case(MCycle)
end // case: 2'b00
2'b01 :
begin
// ADD SP,n
MCycles = 3'b011;
case (1'b1) // MCycle
MCycle[1] :
begin
ALU_Op = 4'b0000;
Inc_PC = 1'b1;
Read_To_Reg = 1'b1;
Save_ALU = 1'b1;
Set_BusA_To = 4'b1000;
Set_BusB_To = 4'b0110;
end
MCycle[2] :
begin
NoRead = 1'b1;
Read_To_Reg = 1'b1;
Save_ALU = 1'b1;
ALU_Op = 4'b0001;
Set_BusA_To = 4'b1001;
Set_BusB_To = 4'b1110; // Incorrect unsigned !!!!!!!!!!!!!!!!!!!!!
end
default :;
endcase // case(MCycle)
end // case: 2'b01
2'b10 :
begin
// LD A,($FF00+nn)
MCycles = 3'b011;
case (1'b1) // MCycle
MCycle[1] :
begin
Inc_PC = 1'b1;
Set_Addr_To = aIOA;
end
MCycle[2] :
Read_To_Acc = 1'b1;
default :;
endcase // case(MCycle)
end // case: 2'b10
2'b11 :
begin
// LD HL,SP+n -- Not correct !!!!!!!!!!!!!!!!!!!
MCycles = 3'b101;
case (1'b1) // MCycle
MCycle[1] :
begin
Inc_PC = 1'b1;
LDZ = 1'b1;
end
MCycle[2] :
begin
Set_Addr_To = aZI;
Inc_PC = 1'b1;
LDW = 1'b1;
end
MCycle[3] :
begin
Set_BusA_To[2:0] = 3'b101; // L
Read_To_Reg = 1'b1;
Inc_WZ = 1'b1;
Set_Addr_To = aZI;
end
MCycle[4] :
begin
Set_BusA_To[2:0] = 3'b100; // H
Read_To_Reg = 1'b1;
end
default :;
endcase // case(MCycle)
end // case: 2'b11
endcase // case(IR[4:3])
end
else
begin
// RET cc
MCycles = 3'b011;
case (1'b1) // MCycle
MCycle[0] :
begin
if (is_cc_true(F, IR[5:3]) )
begin
Set_Addr_To = aSP;
end
else
begin
MCycles = 3'b001;
end
TStates = 3'b101;
end // case: 1
MCycle[1] :
begin
IncDec_16 = 4'b0111;
Set_Addr_To = aSP;
LDZ = 1'b1;
end
MCycle[2] :
begin
Jump = 1'b1;
IncDec_16 = 4'b0111;
end
default :;
endcase
end // else: !if(IR[5] == 1'b1 && Mode == 3 )
end // case: 8'b11000000,8'b11001000,8'b11010000,8'b11011000,8'b11100000,8'b11101000,8'b11110000,8'b11111000
8'b11000111,8'b11001111,8'b11010111,8'b11011111,8'b11100111,8'b11101111,8'b11110111,8'b11111111 :
begin
// RST p
MCycles = 3'b011;
case (1'b1) // MCycle
MCycle[0] :
begin
TStates = 3'b101;
IncDec_16 = 4'b1111;
Set_Addr_To = aSP;
Set_BusB_To = 4'b1101;
end
MCycle[1] :
begin
Write = 1'b1;
IncDec_16 = 4'b1111;
Set_Addr_To = aSP;
Set_BusB_To = 4'b1100;
end
MCycle[2] :
begin
Write = 1'b1;
RstP = 1'b1;
end
default :;
endcase // case(MCycle)
end // case: 8'b11000111,8'b11001111,8'b11010111,8'b11011111,8'b11100111,8'b11101111,8'b11110111,8'b11111111
// INPUT AND OUTPUT GROUP
8'b11011011 :
begin
if (Mode != 3 )
begin
// IN A,(n)
MCycles = 3'b011;
case (1'b1) // MCycle
MCycle[1] :
begin
Inc_PC = 1'b1;
Set_Addr_To = aIOA;
end
MCycle[2] :
begin
Read_To_Acc = 1'b1;
IORQ = 1'b1;
end
default :;
endcase
end // if (Mode != 3 )
end // case: 8'b11011011
8'b11010011 :
begin
if (Mode != 3 )
begin
// OUT (n),A
MCycles = 3'b011;
case (1'b1) // MCycle
MCycle[1] :
begin
Inc_PC = 1'b1;
Set_Addr_To = aIOA;
Set_BusB_To = 4'b0111;
end
MCycle[2] :
begin
Write = 1'b1;
IORQ = 1'b1;
end
default :;
endcase
end // if (Mode != 3 )
end // case: 8'b11010011
 
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
// MULTIBYTE INSTRUCTIONS
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
 
8'b11001011 :
begin
if (Mode != 2 )
begin
Prefix = 2'b01;
end
end
 
8'b11101101 :
begin
if (Mode < 2 )
begin
Prefix = 2'b10;
end
end
 
8'b11011101,8'b11111101 :
begin
if (Mode < 2 )
begin
Prefix = 2'b11;
end
end
endcase // case(IR)
end // case: 2'b00
 
2'b01 :
begin
 
//----------------------------------------------------------------------------
//
// CB prefixed instructions
//
//----------------------------------------------------------------------------
Set_BusA_To[2:0] = IR[2:0];
Set_BusB_To[2:0] = IR[2:0];
casez (IR)
8'b00000000,8'b00000001,8'b00000010,8'b00000011,8'b00000100,8'b00000101,8'b00000111,
8'b00010000,8'b00010001,8'b00010010,8'b00010011,8'b00010100,8'b00010101,8'b00010111,
8'b00001000,8'b00001001,8'b00001010,8'b00001011,8'b00001100,8'b00001101,8'b00001111,
8'b00011000,8'b00011001,8'b00011010,8'b00011011,8'b00011100,8'b00011101,8'b00011111,
8'b00100000,8'b00100001,8'b00100010,8'b00100011,8'b00100100,8'b00100101,8'b00100111,
8'b00101000,8'b00101001,8'b00101010,8'b00101011,8'b00101100,8'b00101101,8'b00101111,
8'b00110000,8'b00110001,8'b00110010,8'b00110011,8'b00110100,8'b00110101,8'b00110111,
8'b00111000,8'b00111001,8'b00111010,8'b00111011,8'b00111100,8'b00111101,8'b00111111 :
begin
// RLC r
// RL r
// RRC r
// RR r
// SLA r
// SRA r
// SRL r
// SLL r (Undocumented) / SWAP r
if (MCycle[0] ) begin
ALU_Op = 4'b1000;
Read_To_Reg = 1'b1;
Save_ALU = 1'b1;
end
end // case: 8'b00000000,8'b00000001,8'b00000010,8'b00000011,8'b00000100,8'b00000101,8'b00000111,...
8'b00zzz110 :
begin
// RLC (HL)
// RL (HL)
// RRC (HL)
// RR (HL)
// SRA (HL)
// SRL (HL)
// SLA (HL)
// SLL (HL) (Undocumented) / SWAP (HL)
MCycles = 3'b011;
case (1'b1) // MCycle
MCycle[0], MCycle[6] :
Set_Addr_To = aXY;
MCycle[1] :
begin
ALU_Op = 4'b1000;
Read_To_Reg = 1'b1;
Save_ALU = 1'b1;
Set_Addr_To = aXY;
TStates = 3'b100;
end
MCycle[2] :
Write = 1'b1;
default :;
endcase // case(MCycle)
end // case: 8'b00000110,8'b00010110,8'b00001110,8'b00011110,8'b00101110,8'b00111110,8'b00100110,8'b00110110
8'b01000000,8'b01000001,8'b01000010,8'b01000011,8'b01000100,8'b01000101,8'b01000111,
8'b01001000,8'b01001001,8'b01001010,8'b01001011,8'b01001100,8'b01001101,8'b01001111,
8'b01010000,8'b01010001,8'b01010010,8'b01010011,8'b01010100,8'b01010101,8'b01010111,
8'b01011000,8'b01011001,8'b01011010,8'b01011011,8'b01011100,8'b01011101,8'b01011111,
8'b01100000,8'b01100001,8'b01100010,8'b01100011,8'b01100100,8'b01100101,8'b01100111,
8'b01101000,8'b01101001,8'b01101010,8'b01101011,8'b01101100,8'b01101101,8'b01101111,
8'b01110000,8'b01110001,8'b01110010,8'b01110011,8'b01110100,8'b01110101,8'b01110111,
8'b01111000,8'b01111001,8'b01111010,8'b01111011,8'b01111100,8'b01111101,8'b01111111 :
begin
// BIT b,r
if (MCycle[0] )
begin
Set_BusB_To[2:0] = IR[2:0];
ALU_Op = 4'b1001;
end
end // case: 8'b01000000,8'b01000001,8'b01000010,8'b01000011,8'b01000100,8'b01000101,8'b01000111,...
8'b01000110,8'b01001110,8'b01010110,8'b01011110,8'b01100110,8'b01101110,8'b01110110,8'b01111110 :
begin
// BIT b,(HL)
MCycles = 3'b010;
case (1'b1) // MCycle
MCycle[0], MCycle[6] :
Set_Addr_To = aXY;
MCycle[1] :
begin
ALU_Op = 4'b1001;
TStates = 3'b100;
end
default :;
endcase // case(MCycle)
end // case: 8'b01000110,8'b01001110,8'b01010110,8'b01011110,8'b01100110,8'b01101110,8'b01110110,8'b01111110
8'b11000000,8'b11000001,8'b11000010,8'b11000011,8'b11000100,8'b11000101,8'b11000111,
8'b11001000,8'b11001001,8'b11001010,8'b11001011,8'b11001100,8'b11001101,8'b11001111,
8'b11010000,8'b11010001,8'b11010010,8'b11010011,8'b11010100,8'b11010101,8'b11010111,
8'b11011000,8'b11011001,8'b11011010,8'b11011011,8'b11011100,8'b11011101,8'b11011111,
8'b11100000,8'b11100001,8'b11100010,8'b11100011,8'b11100100,8'b11100101,8'b11100111,
8'b11101000,8'b11101001,8'b11101010,8'b11101011,8'b11101100,8'b11101101,8'b11101111,
8'b11110000,8'b11110001,8'b11110010,8'b11110011,8'b11110100,8'b11110101,8'b11110111,
8'b11111000,8'b11111001,8'b11111010,8'b11111011,8'b11111100,8'b11111101,8'b11111111 :
begin
// SET b,r
if (MCycle[0] )
begin
ALU_Op = 4'b1010;
Read_To_Reg = 1'b1;
Save_ALU = 1'b1;
end
end // case: 8'b11000000,8'b11000001,8'b11000010,8'b11000011,8'b11000100,8'b11000101,8'b11000111,...
8'b11000110,8'b11001110,8'b11010110,8'b11011110,8'b11100110,8'b11101110,8'b11110110,8'b11111110 :
begin
// SET b,(HL)
MCycles = 3'b011;
case (1'b1) // MCycle
MCycle[0], MCycle[6] :
Set_Addr_To = aXY;
MCycle[1] :
begin
ALU_Op = 4'b1010;
Read_To_Reg = 1'b1;
Save_ALU = 1'b1;
Set_Addr_To = aXY;
TStates = 3'b100;
end
MCycle[2] :
Write = 1'b1;
default :;
endcase // case(MCycle)
end // case: 8'b11000110,8'b11001110,8'b11010110,8'b11011110,8'b11100110,8'b11101110,8'b11110110,8'b11111110
8'b10000000,8'b10000001,8'b10000010,8'b10000011,8'b10000100,8'b10000101,8'b10000111,
8'b10001000,8'b10001001,8'b10001010,8'b10001011,8'b10001100,8'b10001101,8'b10001111,
8'b10010000,8'b10010001,8'b10010010,8'b10010011,8'b10010100,8'b10010101,8'b10010111,
8'b10011000,8'b10011001,8'b10011010,8'b10011011,8'b10011100,8'b10011101,8'b10011111,
8'b10100000,8'b10100001,8'b10100010,8'b10100011,8'b10100100,8'b10100101,8'b10100111,
8'b10101000,8'b10101001,8'b10101010,8'b10101011,8'b10101100,8'b10101101,8'b10101111,
8'b10110000,8'b10110001,8'b10110010,8'b10110011,8'b10110100,8'b10110101,8'b10110111,
8'b10111000,8'b10111001,8'b10111010,8'b10111011,8'b10111100,8'b10111101,8'b10111111 :
begin
// RES b,r
if (MCycle[0] )
begin
ALU_Op = 4'b1011;
Read_To_Reg = 1'b1;
Save_ALU = 1'b1;
end
end // case: 8'b10000000,8'b10000001,8'b10000010,8'b10000011,8'b10000100,8'b10000101,8'b10000111,...
8'b10000110,8'b10001110,8'b10010110,8'b10011110,8'b10100110,8'b10101110,8'b10110110,8'b10111110 :
begin
// RES b,(HL)
MCycles = 3'b011;
case (1'b1) // MCycle
MCycle[0], MCycle[6] :
Set_Addr_To = aXY;
MCycle[1] :
begin
ALU_Op = 4'b1011;
Read_To_Reg = 1'b1;
Save_ALU = 1'b1;
Set_Addr_To = aXY;
TStates = 3'b100;
end
MCycle[2] :
Write = 1'b1;
default :;
endcase // case(MCycle)
end // case: 8'b10000110,8'b10001110,8'b10010110,8'b10011110,8'b10100110,8'b10101110,8'b10110110,8'b10111110
endcase // case(IR)
end // case: 2'b01
default :
begin : default_ed_block
//----------------------------------------------------------------------------
//
// ED prefixed instructions
//
//----------------------------------------------------------------------------
 
casez (IR)
/*
* Undocumented NOP instructions commented out to reduce size of mcode
*
8'b00000000,8'b00000001,8'b00000010,8'b00000011,8'b00000100,8'b00000101,8'b00000110,8'b00000111
,8'b00001000,8'b00001001,8'b00001010,8'b00001011,8'b00001100,8'b00001101,8'b00001110,8'b00001111
,8'b00010000,8'b00010001,8'b00010010,8'b00010011,8'b00010100,8'b00010101,8'b00010110,8'b00010111
,8'b00011000,8'b00011001,8'b00011010,8'b00011011,8'b00011100,8'b00011101,8'b00011110,8'b00011111
,8'b00100000,8'b00100001,8'b00100010,8'b00100011,8'b00100100,8'b00100101,8'b00100110,8'b00100111
,8'b00101000,8'b00101001,8'b00101010,8'b00101011,8'b00101100,8'b00101101,8'b00101110,8'b00101111
,8'b00110000,8'b00110001,8'b00110010,8'b00110011,8'b00110100,8'b00110101,8'b00110110,8'b00110111
,8'b00111000,8'b00111001,8'b00111010,8'b00111011,8'b00111100,8'b00111101,8'b00111110,8'b00111111
 
,8'b10000000,8'b10000001,8'b10000010,8'b10000011,8'b10000100,8'b10000101,8'b10000110,8'b10000111
,8'b10001000,8'b10001001,8'b10001010,8'b10001011,8'b10001100,8'b10001101,8'b10001110,8'b10001111
,8'b10010000,8'b10010001,8'b10010010,8'b10010011,8'b10010100,8'b10010101,8'b10010110,8'b10010111
,8'b10011000,8'b10011001,8'b10011010,8'b10011011,8'b10011100,8'b10011101,8'b10011110,8'b10011111
, 8'b10100100,8'b10100101,8'b10100110,8'b10100111
, 8'b10101100,8'b10101101,8'b10101110,8'b10101111
, 8'b10110100,8'b10110101,8'b10110110,8'b10110111
, 8'b10111100,8'b10111101,8'b10111110,8'b10111111
,8'b11000000,8'b11000001,8'b11000010,8'b11000011,8'b11000100,8'b11000101,8'b11000110,8'b11000111
,8'b11001000,8'b11001001,8'b11001010,8'b11001011,8'b11001100,8'b11001101,8'b11001110,8'b11001111
,8'b11010000,8'b11010001,8'b11010010,8'b11010011,8'b11010100,8'b11010101,8'b11010110,8'b11010111
,8'b11011000,8'b11011001,8'b11011010,8'b11011011,8'b11011100,8'b11011101,8'b11011110,8'b11011111
,8'b11100000,8'b11100001,8'b11100010,8'b11100011,8'b11100100,8'b11100101,8'b11100110,8'b11100111
,8'b11101000,8'b11101001,8'b11101010,8'b11101011,8'b11101100,8'b11101101,8'b11101110,8'b11101111
,8'b11110000,8'b11110001,8'b11110010,8'b11110011,8'b11110100,8'b11110101,8'b11110110,8'b11110111
,8'b11111000,8'b11111001,8'b11111010,8'b11111011,8'b11111100,8'b11111101,8'b11111110,8'b11111111 :
; // NOP, undocumented
8'b01111110,8'b01111111 :
// NOP, undocumented
;
*/
// 8 BIT LOAD GROUP
8'b01010111 :
begin
// LD A,I
Special_LD = 3'b100;
TStates = 3'b101;
end
8'b01011111 :
begin
// LD A,R
Special_LD = 3'b101;
TStates = 3'b101;
end
8'b01000111 :
begin
// LD I,A
Special_LD = 3'b110;
TStates = 3'b101;
end
8'b01001111 :
begin
// LD R,A
Special_LD = 3'b111;
TStates = 3'b101;
end
// 16 BIT LOAD GROUP
8'b01001011,8'b01011011,8'b01101011,8'b01111011 :
begin
// LD dd,(nn)
MCycles = 3'b101;
case (1'b1) // MCycle
MCycle[1] :
begin
Inc_PC = 1'b1;
LDZ = 1'b1;
end
MCycle[2] :
begin
Set_Addr_To = aZI;
Inc_PC = 1'b1;
LDW = 1'b1;
end
MCycle[3] :
begin
Read_To_Reg = 1'b1;
if (IR[5:4] == 2'b11 )
begin
Set_BusA_To = 4'b1000;
end
else
begin
Set_BusA_To[2:1] = IR[5:4];
Set_BusA_To[0] = 1'b1;
end
Inc_WZ = 1'b1;
Set_Addr_To = aZI;
end // case: 4
MCycle[4] :
begin
Read_To_Reg = 1'b1;
if (IR[5:4] == 2'b11 )
begin
Set_BusA_To = 4'b1001;
end
else
begin
Set_BusA_To[2:1] = IR[5:4];
Set_BusA_To[0] = 1'b0;
end
end // case: 5
default :;
endcase // case(MCycle)
end // case: 8'b01001011,8'b01011011,8'b01101011,8'b01111011
8'b01000011,8'b01010011,8'b01100011,8'b01110011 :
begin
// LD (nn),dd
MCycles = 3'b101;
case (1'b1) // MCycle
MCycle[1] :
begin
Inc_PC = 1'b1;
LDZ = 1'b1;
end
MCycle[2] :
begin
Set_Addr_To = aZI;
Inc_PC = 1'b1;
LDW = 1'b1;
if (IR[5:4] == 2'b11 )
begin
Set_BusB_To = 4'b1000;
end
else
begin
Set_BusB_To[2:1] = IR[5:4];
Set_BusB_To[0] = 1'b1;
Set_BusB_To[3] = 1'b0;
end
end // case: 3
MCycle[3] :
begin
Inc_WZ = 1'b1;
Set_Addr_To = aZI;
Write = 1'b1;
if (IR[5:4] == 2'b11 )
begin
Set_BusB_To = 4'b1001;
end
else
begin
Set_BusB_To[2:1] = IR[5:4];
Set_BusB_To[0] = 1'b0;
Set_BusB_To[3] = 1'b0;
end
end // case: 4
MCycle[4] :
begin
Write = 1'b1;
end
default :;
endcase // case(MCycle)
end // case: 8'b01000011,8'b01010011,8'b01100011,8'b01110011
8'b10100000 , 8'b10101000 , 8'b10110000 , 8'b10111000 :
begin
// LDI, LDD, LDIR, LDDR
MCycles = 3'b100;
case (1'b1) // MCycle
MCycle[0] :
begin
Set_Addr_To = aXY;
IncDec_16 = 4'b1100; // BC
end
MCycle[1] :
begin
Set_BusB_To = 4'b0110;
Set_BusA_To[2:0] = 3'b111;
ALU_Op = 4'b0000;
Set_Addr_To = aDE;
if (IR[3] == 1'b0 )
begin
IncDec_16 = 4'b0110; // IX
end
else
begin
IncDec_16 = 4'b1110;
end
end // case: 2
MCycle[2] :
begin
I_BT = 1'b1;
TStates = 3'b101;
Write = 1'b1;
if (IR[3] == 1'b0 )
begin
IncDec_16 = 4'b0101; // DE
end
else
begin
IncDec_16 = 4'b1101;
end
end // case: 3
MCycle[3] :
begin
NoRead = 1'b1;
TStates = 3'b101;
end
default :;
endcase // case(MCycle)
end // case: 8'b10100000 , 8'b10101000 , 8'b10110000 , 8'b10111000
8'b10100001 , 8'b10101001 , 8'b10110001 , 8'b10111001 :
begin
// CPI, CPD, CPIR, CPDR
MCycles = 3'b100;
case (1'b1) // MCycle
MCycle[0] :
begin
Set_Addr_To = aXY;
IncDec_16 = 4'b1100; // BC
end
MCycle[1] :
begin
Set_BusB_To = 4'b0110;
Set_BusA_To[2:0] = 3'b111;
ALU_Op = 4'b0111;
Save_ALU = 1'b1;
PreserveC = 1'b1;
if (IR[3] == 1'b0 )
begin
IncDec_16 = 4'b0110;
end
else
begin
IncDec_16 = 4'b1110;
end
end // case: 2
MCycle[2] :
begin
NoRead = 1'b1;
I_BC = 1'b1;
TStates = 3'b101;
end
MCycle[3] :
begin
NoRead = 1'b1;
TStates = 3'b101;
end
default :;
endcase // case(MCycle)
end // case: 8'b10100001 , 8'b10101001 , 8'b10110001 , 8'b10111001
8'b01000100,8'b01001100,8'b01010100,8'b01011100,8'b01100100,8'b01101100,8'b01110100,8'b01111100 :
begin
// NEG
ALU_Op = 4'b0010;
Set_BusB_To = 4'b0111;
Set_BusA_To = 4'b1010;
Read_To_Acc = 1'b1;
Save_ALU = 1'b1;
end
8'b01000110,8'b01001110,8'b01100110,8'b01101110 :
begin
// IM 0
IMode = 2'b00;
end
8'b01010110,8'b01110110 :
// IM 1
IMode = 2'b01;
8'b01011110,8'b01110111 :
// IM 2
IMode = 2'b10;
// 16 bit arithmetic
8'b01001010,8'b01011010,8'b01101010,8'b01111010 :
begin
// ADC HL,ss
MCycles = 3'b011;
case (1'b1) // MCycle
MCycle[1] :
begin
NoRead = 1'b1;
ALU_Op = 4'b0001;
Read_To_Reg = 1'b1;
Save_ALU = 1'b1;
Set_BusA_To[2:0] = 3'b101;
case (IR[5:4])
0,1,2 :
begin
Set_BusB_To[2:1] = IR[5:4];
Set_BusB_To[0] = 1'b1;
end
default :
Set_BusB_To = 4'b1000;
endcase
TStates = 3'b100;
end // case: 2
MCycle[2] :
begin
NoRead = 1'b1;
Read_To_Reg = 1'b1;
Save_ALU = 1'b1;
ALU_Op = 4'b0001;
Set_BusA_To[2:0] = 3'b100;
case (IR[5:4])
0,1,2 :
begin
Set_BusB_To[2:1] = IR[5:4];
Set_BusB_To[0] = 1'b0;
end
default :
Set_BusB_To = 4'b1001;
endcase // case(IR[5:4])
end // case: 3
default :;
endcase // case(MCycle)
end // case: 8'b01001010,8'b01011010,8'b01101010,8'b01111010
8'b01000010,8'b01010010,8'b01100010,8'b01110010 :
begin
// SBC HL,ss
MCycles = 3'b011;
case (1'b1) // MCycle
MCycle[1] :
begin
NoRead = 1'b1;
ALU_Op = 4'b0011;
Read_To_Reg = 1'b1;
Save_ALU = 1'b1;
Set_BusA_To[2:0] = 3'b101;
case (IR[5:4])
0,1,2 :
begin
Set_BusB_To[2:1] = IR[5:4];
Set_BusB_To[0] = 1'b1;
end
default :
Set_BusB_To = 4'b1000;
endcase
TStates = 3'b100;
end // case: 2
MCycle[2] :
begin
NoRead = 1'b1;
ALU_Op = 4'b0011;
Read_To_Reg = 1'b1;
Save_ALU = 1'b1;
Set_BusA_To[2:0] = 3'b100;
case (IR[5:4])
0,1,2 :
Set_BusB_To[2:1] = IR[5:4];
default :
Set_BusB_To = 4'b1001;
endcase
end // case: 3
default :;
endcase // case(MCycle)
end // case: 8'b01000010,8'b01010010,8'b01100010,8'b01110010
8'b01101111 :
begin
// RLD
MCycles = 3'b100;
case (1'b1) // MCycle
MCycle[1] :
begin
NoRead = 1'b1;
Set_Addr_To = aXY;
end
MCycle[2] :
begin
Read_To_Reg = 1'b1;
Set_BusB_To[2:0] = 3'b110;
Set_BusA_To[2:0] = 3'b111;
ALU_Op = 4'b1101;
TStates = 3'b100;
Set_Addr_To = aXY;
Save_ALU = 1'b1;
end
MCycle[3] :
begin
I_RLD = 1'b1;
Write = 1'b1;
end
default :;
endcase // case(MCycle)
end // case: 8'b01101111
8'b01100111 :
begin
// RRD
MCycles = 3'b100;
case (1'b1) // MCycle
MCycle[1] :
Set_Addr_To = aXY;
MCycle[2] :
begin
Read_To_Reg = 1'b1;
Set_BusB_To[2:0] = 3'b110;
Set_BusA_To[2:0] = 3'b111;
ALU_Op = 4'b1110;
TStates = 3'b100;
Set_Addr_To = aXY;
Save_ALU = 1'b1;
end
MCycle[3] :
begin
I_RRD = 1'b1;
Write = 1'b1;
end
default :;
endcase // case(MCycle)
end // case: 8'b01100111
8'b01000101,8'b01001101,8'b01010101,8'b01011101,8'b01100101,8'b01101101,8'b01110101,8'b01111101 :
begin
// RETI, RETN
MCycles = 3'b011;
case (1'b1) // MCycle
MCycle[0] :
Set_Addr_To = aSP;
MCycle[1] :
begin
IncDec_16 = 4'b0111;
Set_Addr_To = aSP;
LDZ = 1'b1;
end
MCycle[2] :
begin
Jump = 1'b1;
IncDec_16 = 4'b0111;
I_RETN = 1'b1;
end
default :;
endcase // case(MCycle)
end // case: 8'b01000101,8'b01001101,8'b01010101,8'b01011101,8'b01100101,8'b01101101,8'b01110101,8'b01111101
8'b01000000,8'b01001000,8'b01010000,8'b01011000,8'b01100000,8'b01101000,8'b01110000,8'b01111000 :
begin
// IN r,(C)
MCycles = 3'b010;
case (1'b1) // MCycle
MCycle[0] :
Set_Addr_To = aBC;
MCycle[1] :
begin
IORQ = 1'b1;
if (IR[5:3] != 3'b110 )
begin
Read_To_Reg = 1'b1;
Set_BusA_To[2:0] = IR[5:3];
end
I_INRC = 1'b1;
end
default :;
endcase // case(MCycle)
end // case: 8'b01000000,8'b01001000,8'b01010000,8'b01011000,8'b01100000,8'b01101000,8'b01110000,8'b01111000
8'b01000001,8'b01001001,8'b01010001,8'b01011001,8'b01100001,8'b01101001,8'b01110001,8'b01111001 :
begin
// OUT (C),r
// OUT (C),0
MCycles = 3'b010;
case (1'b1) // MCycle
MCycle[0] :
begin
Set_Addr_To = aBC;
Set_BusB_To[2:0] = IR[5:3];
if (IR[5:3] == 3'b110 )
begin
Set_BusB_To[3] = 1'b1;
end
end
MCycle[1] :
begin
Write = 1'b1;
IORQ = 1'b1;
end
default :;
endcase // case(MCycle)
end // case: 8'b01000001,8'b01001001,8'b01010001,8'b01011001,8'b01100001,8'b01101001,8'b01110001,8'b01111001
8'b10100010 , 8'b10101010 , 8'b10110010 , 8'b10111010 :
begin
// INI, IND, INIR, INDR
MCycles = 3'b100;
case (1'b1) // MCycle
MCycle[0] :
begin
Set_Addr_To = aBC;
Set_BusB_To = 4'b1010;
Set_BusA_To = 4'b0000;
Read_To_Reg = 1'b1;
Save_ALU = 1'b1;
ALU_Op = 4'b0010;
end
MCycle[1] :
begin
IORQ = 1'b1;
Set_BusB_To = 4'b0110;
Set_Addr_To = aXY;
end
MCycle[2] :
begin
if (IR[3] == 1'b0 )
begin
IncDec_16 = 4'b0110;
end
else
begin
IncDec_16 = 4'b1110;
end
TStates = 3'b100;
Write = 1'b1;
I_BTR = 1'b1;
end // case: 3
MCycle[3] :
begin
NoRead = 1'b1;
TStates = 3'b101;
end
default :;
endcase // case(MCycle)
end // case: 8'b10100010 , 8'b10101010 , 8'b10110010 , 8'b10111010
8'b10100011 , 8'b10101011 , 8'b10110011 , 8'b10111011 :
begin
// OUTI, OUTD, OTIR, OTDR
MCycles = 3'b100;
case (1'b1) // MCycle
MCycle[0] :
begin
TStates = 3'b101;
Set_Addr_To = aXY;
Set_BusB_To = 4'b1010;
Set_BusA_To = 4'b0000;
Read_To_Reg = 1'b1;
Save_ALU = 1'b1;
ALU_Op = 4'b0010;
end
MCycle[1] :
begin
Set_BusB_To = 4'b0110;
Set_Addr_To = aBC;
if (IR[3] == 1'b0 )
begin
IncDec_16 = 4'b0110;
end
else
begin
IncDec_16 = 4'b1110;
end
end
MCycle[2] :
begin
if (IR[3] == 1'b0 )
begin
IncDec_16 = 4'b0010;
end
else
begin
IncDec_16 = 4'b1010;
end
IORQ = 1'b1;
Write = 1'b1;
I_BTR = 1'b1;
end // case: 3
MCycle[3] :
begin
NoRead = 1'b1;
TStates = 3'b101;
end
default :;
endcase // case(MCycle)
end // case: 8'b10100011 , 8'b10101011 , 8'b10110011 , 8'b10111011
 
default : ;
endcase // case(IR)
end // block: default_ed_block
endcase // case(ISet)
if (Mode == 1 )
begin
if (MCycle[0] )
begin
//TStates = 3'b100;
end
else
begin
TStates = 3'b011;
end
end
 
if (Mode == 3 )
begin
if (MCycle[0] )
begin
//TStates = 3'b100;
end
else
begin
TStates = 3'b100;
end
end
 
if (Mode < 2 )
begin
if (MCycle[5] )
begin
Inc_PC = 1'b1;
if (Mode == 1 )
begin
Set_Addr_To = aXY;
TStates = 3'b100;
Set_BusB_To[2:0] = SSS;
Set_BusB_To[3] = 1'b0;
end
if (IR == 8'b00110110 || IR == 8'b11001011 )
begin
Set_Addr_To = aNone;
end
end
if (MCycle[6] )
begin
if (Mode == 0 )
begin
TStates = 3'b101;
end
if (ISet != 2'b01 )
begin
Set_Addr_To = aXY;
end
Set_BusB_To[2:0] = SSS;
Set_BusB_To[3] = 1'b0;
if (IR == 8'b00110110 || ISet == 2'b01 )
begin
// LD (HL),n
Inc_PC = 1'b1;
end
else
begin
NoRead = 1'b1;
end
end
end // if (Mode < 2 )
end // always @ (IR, ISet, MCycle, F, NMICycle, IntCycle)
endmodule // T80_MCode
/zx_ula/branches/xilinx/spectrum_16k_with_rom_game_for_ols/bitstreams/OLS_spartan3e-250_sp16k.bit Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream
zx_ula/branches/xilinx/spectrum_16k_with_rom_game_for_ols/bitstreams/OLS_spartan3e-250_sp16k.bit Property changes : Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: zx_ula/branches/xilinx/spectrum_16k_with_rom_game_for_ols/tv80_core.v =================================================================== --- zx_ula/branches/xilinx/spectrum_16k_with_rom_game_for_ols/tv80_core.v (nonexistent) +++ zx_ula/branches/xilinx/spectrum_16k_with_rom_game_for_ols/tv80_core.v (revision 27) @@ -0,0 +1,1389 @@ +// +// 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_core (/*AUTOARG*/ + // Outputs + m1_n, iorq, no_read, write, rfsh_n, halt_n, busak_n, A, dout, mc, + ts, intcycle_n, IntE, stop, + // Inputs + reset_n, clk, cen, wait_n, int_n, nmi_n, busrq_n, dinst, di + ); + // Beginning of automatic inputs (from unused autoinst inputs) + // End of automatics + + parameter Mode = 1; // 0 => Z80, 1 => Fast Z80, 2 => 8080, 3 => GB + parameter IOWait = 1; // 0 => Single cycle I/O, 1 => Std I/O cycle + parameter Flag_C = 0; + parameter Flag_N = 1; + parameter Flag_P = 2; + parameter Flag_X = 3; + parameter Flag_H = 4; + parameter Flag_Y = 5; + parameter Flag_Z = 6; + parameter Flag_S = 7; + + input reset_n; + input clk; + input cen; + input wait_n; + input int_n; + input nmi_n; + input busrq_n; + output m1_n; + output iorq; + output no_read; + output write; + output rfsh_n; + output halt_n; + output busak_n; + output [15:0] A; + input [7:0] dinst; + input [7:0] di; + output [7:0] dout; + output [6:0] mc; + output [6:0] ts; + output intcycle_n; + output IntE; + output stop; + + reg m1_n; + reg iorq; +`ifdef TV80_REFRESH + reg rfsh_n; +`endif + reg halt_n; + reg busak_n; + reg [15:0] A; + reg [7:0] dout; + reg [6:0] mc; + reg [6:0] ts; + reg intcycle_n; + reg IntE; + reg stop; + + parameter aNone = 3'b111; + parameter aBC = 3'b000; + parameter aDE = 3'b001; + parameter aXY = 3'b010; + parameter aIOA = 3'b100; + parameter aSP = 3'b101; + parameter aZI = 3'b110; + + // Registers + reg [7:0] ACC, F; + reg [7:0] Ap, Fp; + reg [7:0] I; +`ifdef TV80_REFRESH + reg [7:0] R; +`endif + reg [15:0] SP, PC; + reg [7:0] RegDIH; + reg [7:0] RegDIL; + wire [15:0] RegBusA; + wire [15:0] RegBusB; + wire [15:0] RegBusC; + reg [2:0] RegAddrA_r; + reg [2:0] RegAddrA; + reg [2:0] RegAddrB_r; + reg [2:0] RegAddrB; + reg [2:0] RegAddrC; + reg RegWEH; + reg RegWEL; + reg Alternate; + + // Help Registers + reg [15:0] TmpAddr; // Temporary address register + reg [7:0] IR; // Instruction register + reg [1:0] ISet; // Instruction set selector + reg [15:0] RegBusA_r; + + reg [15:0] ID16; + reg [7:0] Save_Mux; + + reg [6:0] tstate; + reg [6:0] mcycle; + reg last_mcycle, last_tstate; + reg IntE_FF1; + reg IntE_FF2; + reg Halt_FF; + reg BusReq_s; + reg BusAck; + reg ClkEn; + reg NMI_s; + reg INT_s; + reg [1:0] IStatus; + + reg [7:0] DI_Reg; + reg T_Res; + reg [1:0] XY_State; + reg [2:0] Pre_XY_F_M; + reg NextIs_XY_Fetch; + reg XY_Ind; + reg No_BTR; + reg BTR_r; + reg Auto_Wait; + reg Auto_Wait_t1; + reg Auto_Wait_t2; + reg IncDecZ; + + // ALU signals + reg [7:0] BusB; + reg [7:0] BusA; + wire [7:0] ALU_Q; + wire [7:0] F_Out; + + // Registered micro code outputs + reg [4:0] Read_To_Reg_r; + reg Arith16_r; + reg Z16_r; + reg [3:0] ALU_Op_r; + reg Save_ALU_r; + reg PreserveC_r; + reg [2:0] mcycles; + + // Micro code outputs + wire [2:0] mcycles_d; + wire [2:0] tstates; + reg IntCycle; + reg NMICycle; + wire Inc_PC; + wire Inc_WZ; + wire [3:0] IncDec_16; + wire [1:0] Prefix; + wire Read_To_Acc; + wire Read_To_Reg; + wire [3:0] Set_BusB_To; + wire [3:0] Set_BusA_To; + wire [3:0] ALU_Op; + wire Save_ALU; + wire PreserveC; + wire Arith16; + wire [2:0] Set_Addr_To; + wire Jump; + wire JumpE; + wire JumpXY; + wire Call; + wire RstP; + wire LDZ; + wire LDW; + wire LDSPHL; + wire iorq_i; + wire [2:0] Special_LD; + wire ExchangeDH; + wire ExchangeRp; + wire ExchangeAF; + wire ExchangeRS; + wire I_DJNZ; + wire I_CPL; + wire I_CCF; + wire I_SCF; + wire I_RETN; + wire I_BT; + wire I_BC; + wire I_BTR; + wire I_RLD; + wire I_RRD; + wire I_INRC; + wire SetDI; + wire SetEI; + wire [1:0] IMode; + wire Halt; + + reg [15:0] PC16; + reg [15:0] PC16_B; + reg [15:0] SP16, SP16_A, SP16_B; + reg [15:0] ID16_B; + reg Oldnmi_n; + + tv80_mcode #(Mode, Flag_C, Flag_N, Flag_P, Flag_X, Flag_H, Flag_Y, Flag_Z, Flag_S) i_mcode + ( + .IR (IR), + .ISet (ISet), + .MCycle (mcycle), + .F (F), + .NMICycle (NMICycle), + .IntCycle (IntCycle), + .MCycles (mcycles_d), + .TStates (tstates), + .Prefix (Prefix), + .Inc_PC (Inc_PC), + .Inc_WZ (Inc_WZ), + .IncDec_16 (IncDec_16), + .Read_To_Acc (Read_To_Acc), + .Read_To_Reg (Read_To_Reg), + .Set_BusB_To (Set_BusB_To), + .Set_BusA_To (Set_BusA_To), + .ALU_Op (ALU_Op), + .Save_ALU (Save_ALU), + .PreserveC (PreserveC), + .Arith16 (Arith16), + .Set_Addr_To (Set_Addr_To), + .IORQ (iorq_i), + .Jump (Jump), + .JumpE (JumpE), + .JumpXY (JumpXY), + .Call (Call), + .RstP (RstP), + .LDZ (LDZ), + .LDW (LDW), + .LDSPHL (LDSPHL), + .Special_LD (Special_LD), + .ExchangeDH (ExchangeDH), + .ExchangeRp (ExchangeRp), + .ExchangeAF (ExchangeAF), + .ExchangeRS (ExchangeRS), + .I_DJNZ (I_DJNZ), + .I_CPL (I_CPL), + .I_CCF (I_CCF), + .I_SCF (I_SCF), + .I_RETN (I_RETN), + .I_BT (I_BT), + .I_BC (I_BC), + .I_BTR (I_BTR), + .I_RLD (I_RLD), + .I_RRD (I_RRD), + .I_INRC (I_INRC), + .SetDI (SetDI), + .SetEI (SetEI), + .IMode (IMode), + .Halt (Halt), + .NoRead (no_read), + .Write (write) + ); + + tv80_alu #(Mode, Flag_C, Flag_N, Flag_P, Flag_X, Flag_H, Flag_Y, Flag_Z, Flag_S) i_alu + ( + .Arith16 (Arith16_r), + .Z16 (Z16_r), + .ALU_Op (ALU_Op_r), + .IR (IR[5:0]), + .ISet (ISet), + .BusA (BusA), + .BusB (BusB), + .F_In (F), + .Q (ALU_Q), + .F_Out (F_Out) + ); + + function [6:0] number_to_bitvec; + input [2:0] num; + begin + case (num) + 1 : number_to_bitvec = 7'b0000001; + 2 : number_to_bitvec = 7'b0000010; + 3 : number_to_bitvec = 7'b0000100; + 4 : number_to_bitvec = 7'b0001000; + 5 : number_to_bitvec = 7'b0010000; + 6 : number_to_bitvec = 7'b0100000; + 7 : number_to_bitvec = 7'b1000000; + default : number_to_bitvec = 7'bx; + endcase // case(num) + end + endfunction // number_to_bitvec + + function [2:0] mcyc_to_number; + input [6:0] mcyc; + begin + casez (mcyc) + 7'b1zzzzzz : mcyc_to_number = 3'h7; + 7'b01zzzzz : mcyc_to_number = 3'h6; + 7'b001zzzz : mcyc_to_number = 3'h5; + 7'b0001zzz : mcyc_to_number = 3'h4; + 7'b00001zz : mcyc_to_number = 3'h3; + 7'b000001z : mcyc_to_number = 3'h2; + 7'b0000001 : mcyc_to_number = 3'h1; + default : mcyc_to_number = 3'h1; + endcase + end + endfunction + + always @(/*AUTOSENSE*/mcycle or mcycles or tstate or tstates) + begin + case (mcycles) + 1 : last_mcycle = mcycle[0]; + 2 : last_mcycle = mcycle[1]; + 3 : last_mcycle = mcycle[2]; + 4 : last_mcycle = mcycle[3]; + 5 : last_mcycle = mcycle[4]; + 6 : last_mcycle = mcycle[5]; + 7 : last_mcycle = mcycle[6]; + default : last_mcycle = 1'bx; + endcase // case(mcycles) + + case (tstates) + 0 : last_tstate = tstate[0]; + 1 : last_tstate = tstate[1]; + 2 : last_tstate = tstate[2]; + 3 : last_tstate = tstate[3]; + 4 : last_tstate = tstate[4]; + 5 : last_tstate = tstate[5]; + 6 : last_tstate = tstate[6]; + default : last_tstate = 1'bx; + endcase + end // always @ (... + + + always @(/*AUTOSENSE*/ALU_Q or BusAck or BusB or DI_Reg + or ExchangeRp or IR or Save_ALU_r or Set_Addr_To or XY_Ind + or XY_State or cen or last_tstate or mcycle) + begin + ClkEn = cen && ~ BusAck; + + if (last_tstate) + T_Res = 1'b1; + else T_Res = 1'b0; + + if (XY_State != 2'b00 && XY_Ind == 1'b0 && + ((Set_Addr_To == aXY) || + (mcycle[0] && IR == 8'b11001011) || + (mcycle[0] && IR == 8'b00110110))) + NextIs_XY_Fetch = 1'b1; + else + NextIs_XY_Fetch = 1'b0; + + if (ExchangeRp) + Save_Mux = BusB; + else if (!Save_ALU_r) + Save_Mux = DI_Reg; + else + Save_Mux = ALU_Q; + end // always @ * + + always @ (posedge clk or negedge reset_n) + begin + if (reset_n == 1'b0 ) + begin + PC <= #1 0; // Program Counter + A <= #1 0; + TmpAddr <= #1 0; + IR <= #1 8'b00000000; + ISet <= #1 2'b00; + XY_State <= #1 2'b00; + IStatus <= #1 2'b00; + mcycles <= #1 3'b000; + dout <= #1 8'b00000000; + + ACC <= #1 8'hFF; + F <= #1 8'hFF; + Ap <= #1 8'hFF; + Fp <= #1 8'hFF; + I <= #1 0; + `ifdef TV80_REFRESH + R <= #1 0; + `endif + SP <= #1 16'hFFFF; + Alternate <= #1 1'b0; + + Read_To_Reg_r <= #1 5'b00000; + Arith16_r <= #1 1'b0; + BTR_r <= #1 1'b0; + Z16_r <= #1 1'b0; + ALU_Op_r <= #1 4'b0000; + Save_ALU_r <= #1 1'b0; + PreserveC_r <= #1 1'b0; + XY_Ind <= #1 1'b0; + end + else + begin + + if (ClkEn == 1'b1 ) + begin + + ALU_Op_r <= #1 4'b0000; + Save_ALU_r <= #1 1'b0; + Read_To_Reg_r <= #1 5'b00000; + + mcycles <= #1 mcycles_d; + + if (IMode != 2'b11 ) + begin + IStatus <= #1 IMode; + end + + Arith16_r <= #1 Arith16; + PreserveC_r <= #1 PreserveC; + if (ISet == 2'b10 && ALU_Op[2] == 1'b0 && ALU_Op[0] == 1'b1 && mcycle[2] ) + begin + Z16_r <= #1 1'b1; + end + else + begin + Z16_r <= #1 1'b0; + end + + if (mcycle[0] && (tstate[1] | tstate[2] | tstate[3] )) + begin + // mcycle == 1 && tstate == 1, 2, || 3 + if (tstate[2] && wait_n == 1'b1 ) + begin + `ifdef TV80_REFRESH + if (Mode < 2 ) + begin + A[7:0] <= #1 R; + A[15:8] <= #1 I; + R[6:0] <= #1 R[6:0] + 1; + end + `endif + if (Jump == 1'b0 && Call == 1'b0 && NMICycle == 1'b0 && IntCycle == 1'b0 && ~ (Halt_FF == 1'b1 || Halt == 1'b1) ) + begin + PC <= #1 PC16; + end + + if (IntCycle == 1'b1 && IStatus == 2'b01 ) + begin + IR <= #1 8'b11111111; + end + else if (Halt_FF == 1'b1 || (IntCycle == 1'b1 && IStatus == 2'b10) || NMICycle == 1'b1 ) + begin + IR <= #1 8'b00000000; + TmpAddr[7:0] <= #1 dinst; // Special M1 vector fetch + end + else + begin + IR <= #1 dinst; + end + + ISet <= #1 2'b00; + if (Prefix != 2'b00 ) + begin + if (Prefix == 2'b11 ) + begin + if (IR[5] == 1'b1 ) + begin + XY_State <= #1 2'b10; + end + else + begin + XY_State <= #1 2'b01; + end + end + else + begin + if (Prefix == 2'b10 ) + begin + XY_State <= #1 2'b00; + XY_Ind <= #1 1'b0; + end + ISet <= #1 Prefix; + end + end + else + begin + XY_State <= #1 2'b00; + XY_Ind <= #1 1'b0; + end + end // if (tstate == 2 && wait_n == 1'b1 ) + + + end + else + begin + // either (mcycle > 1) OR (mcycle == 1 AND tstate > 3) + + if (mcycle[5] ) + begin + XY_Ind <= #1 1'b1; + if (Prefix == 2'b01 ) + begin + ISet <= #1 2'b01; + end + end + + if (T_Res == 1'b1 ) + begin + BTR_r <= #1 (I_BT || I_BC || I_BTR) && ~ No_BTR; + if (Jump == 1'b1 ) + begin + A[15:8] <= #1 DI_Reg; + A[7:0] <= #1 TmpAddr[7:0]; + PC[15:8] <= #1 DI_Reg; + PC[7:0] <= #1 TmpAddr[7:0]; + end + else if (JumpXY == 1'b1 ) + begin + A <= #1 RegBusC; + PC <= #1 RegBusC; + end else if (Call == 1'b1 || RstP == 1'b1 ) + begin + A <= #1 TmpAddr; + PC <= #1 TmpAddr; + end + else if (last_mcycle && NMICycle == 1'b1 ) + begin + A <= #1 16'b0000000001100110; + PC <= #1 16'b0000000001100110; + end + else if (mcycle[2] && IntCycle == 1'b1 && IStatus == 2'b10 ) + begin + A[15:8] <= #1 I; + A[7:0] <= #1 TmpAddr[7:0]; + PC[15:8] <= #1 I; + PC[7:0] <= #1 TmpAddr[7:0]; + end + else + begin + case (Set_Addr_To) + aXY : + begin + if (XY_State == 2'b00 ) + begin + A <= #1 RegBusC; + end + else + begin + if (NextIs_XY_Fetch == 1'b1 ) + begin + A <= #1 PC; + end + else + begin + A <= #1 TmpAddr; + end + end // else: !if(XY_State == 2'b00 ) + end // case: aXY + + aIOA : + begin + if (Mode == 3 ) + begin + // Memory map I/O on GBZ80 + A[15:8] <= #1 8'hFF; + end + else if (Mode == 2 ) + begin + // Duplicate I/O address on 8080 + A[15:8] <= #1 DI_Reg; + end + else + begin + A[15:8] <= #1 ACC; + end + A[7:0] <= #1 DI_Reg; + end // case: aIOA + + + aSP : + begin + A <= #1 SP; + end + + aBC : + begin + if (Mode == 3 && iorq_i == 1'b1 ) + begin + // Memory map I/O on GBZ80 + A[15:8] <= #1 8'hFF; + A[7:0] <= #1 RegBusC[7:0]; + end + else + begin + A <= #1 RegBusC; + end + end // case: aBC + + aDE : + begin + A <= #1 RegBusC; + end + + aZI : + begin + if (Inc_WZ == 1'b1 ) + begin + A <= #1 TmpAddr + 1; + end + else + begin + A[15:8] <= #1 DI_Reg; + A[7:0] <= #1 TmpAddr[7:0]; + end + end // case: aZI + + default : + begin + A <= #1 PC; + end + endcase // case(Set_Addr_To) + + end // else: !if(mcycle[2] && IntCycle == 1'b1 && IStatus == 2'b10 ) + + + Save_ALU_r <= #1 Save_ALU; + ALU_Op_r <= #1 ALU_Op; + + if (I_CPL == 1'b1 ) + begin + // CPL + ACC <= #1 ~ ACC; + F[Flag_Y] <= #1 ~ ACC[5]; + F[Flag_H] <= #1 1'b1; + F[Flag_X] <= #1 ~ ACC[3]; + F[Flag_N] <= #1 1'b1; + end + if (I_CCF == 1'b1 ) + begin + // CCF + F[Flag_C] <= #1 ~ F[Flag_C]; + F[Flag_Y] <= #1 ACC[5]; + F[Flag_H] <= #1 F[Flag_C]; + F[Flag_X] <= #1 ACC[3]; + F[Flag_N] <= #1 1'b0; + end + if (I_SCF == 1'b1 ) + begin + // SCF + F[Flag_C] <= #1 1'b1; + F[Flag_Y] <= #1 ACC[5]; + F[Flag_H] <= #1 1'b0; + F[Flag_X] <= #1 ACC[3]; + F[Flag_N] <= #1 1'b0; + end + end // if (T_Res == 1'b1 ) + + + if (tstate[2] && wait_n == 1'b1 ) + begin + if (ISet == 2'b01 && mcycle[6] ) + begin + IR <= #1 dinst; + end + if (JumpE == 1'b1 ) + begin + PC <= #1 PC16; + end + else if (Inc_PC == 1'b1 ) + begin + //PC <= #1 PC + 1; + PC <= #1 PC16; + end + if (BTR_r == 1'b1 ) + begin + //PC <= #1 PC - 2; + PC <= #1 PC16; + end + if (RstP == 1'b1 ) + begin + TmpAddr <= #1 { 10'h0, IR[5:3], 3'h0 }; + //TmpAddr <= #1 (others =>1'b0); + //TmpAddr[5:3] <= #1 IR[5:3]; + end + end + if (tstate[3] && mcycle[5] ) + begin + TmpAddr <= #1 SP16; + end + + if ((tstate[2] && wait_n == 1'b1) || (tstate[4] && mcycle[0]) ) + begin + if (IncDec_16[2:0] == 3'b111 ) + begin + SP <= #1 SP16; + end + end + + if (LDSPHL == 1'b1 ) + begin + SP <= #1 RegBusC; + end + if (ExchangeAF == 1'b1 ) + begin + Ap <= #1 ACC; + ACC <= #1 Ap; + Fp <= #1 F; + F <= #1 Fp; + end + if (ExchangeRS == 1'b1 ) + begin + Alternate <= #1 ~ Alternate; + end + end // else: !if(mcycle == 3'b001 && tstate(2) == 1'b0 ) + + + if (tstate[3] ) + begin + if (LDZ == 1'b1 ) + begin + TmpAddr[7:0] <= #1 DI_Reg; + end + if (LDW == 1'b1 ) + begin + TmpAddr[15:8] <= #1 DI_Reg; + end + + if (Special_LD[2] == 1'b1 ) + begin + case (Special_LD[1:0]) + 2'b00 : + begin + ACC <= #1 I; + F[Flag_P] <= #1 IntE_FF2; + F[Flag_Z] <= (I == 0); + F[Flag_S] <= I[7]; + F[Flag_H] <= 0; + F[Flag_N] <= 0; + end + + 2'b01 : + begin + `ifdef TV80_REFRESH + ACC <= #1 R; + `else + ACC <= #1 0; + `endif + F[Flag_P] <= #1 IntE_FF2; + F[Flag_Z] <= (I == 0); + F[Flag_S] <= I[7]; + F[Flag_H] <= 0; + F[Flag_N] <= 0; + end + + 2'b10 : + I <= #1 ACC; + + `ifdef TV80_REFRESH + default : + R <= #1 ACC; + `else + default : ; + `endif + endcase + end + end // if (tstate == 3 ) + + + if ((I_DJNZ == 1'b0 && Save_ALU_r == 1'b1) || ALU_Op_r == 4'b1001 ) + begin + if (Mode == 3 ) + begin + F[6] <= #1 F_Out[6]; + F[5] <= #1 F_Out[5]; + F[7] <= #1 F_Out[7]; + if (PreserveC_r == 1'b0 ) + begin + F[4] <= #1 F_Out[4]; + end + end + else + begin + F[7:1] <= #1 F_Out[7:1]; + if (PreserveC_r == 1'b0 ) + begin + F[Flag_C] <= #1 F_Out[0]; + end + end + end // if ((I_DJNZ == 1'b0 && Save_ALU_r == 1'b1) || ALU_Op_r == 4'b1001 ) + + if (T_Res == 1'b1 && I_INRC == 1'b1 ) + begin + F[Flag_H] <= #1 1'b0; + F[Flag_N] <= #1 1'b0; + if (DI_Reg[7:0] == 8'b00000000 ) + begin + F[Flag_Z] <= #1 1'b1; + end + else + begin + F[Flag_Z] <= #1 1'b0; + end + F[Flag_S] <= #1 DI_Reg[7]; + F[Flag_P] <= #1 ~ (^DI_Reg[7:0]); + end // if (T_Res == 1'b1 && I_INRC == 1'b1 ) + + + if (tstate[1] && Auto_Wait_t1 == 1'b0 ) + begin + dout <= #1 BusB; + if (I_RLD == 1'b1 ) + begin + dout[3:0] <= #1 BusA[3:0]; + dout[7:4] <= #1 BusB[3:0]; + end + if (I_RRD == 1'b1 ) + begin + dout[3:0] <= #1 BusB[7:4]; + dout[7:4] <= #1 BusA[3:0]; + end + end + + if (T_Res == 1'b1 ) + begin + Read_To_Reg_r[3:0] <= #1 Set_BusA_To; + Read_To_Reg_r[4] <= #1 Read_To_Reg; + if (Read_To_Acc == 1'b1 ) + begin + Read_To_Reg_r[3:0] <= #1 4'b0111; + Read_To_Reg_r[4] <= #1 1'b1; + end + end + + if (tstate[1] && I_BT == 1'b1 ) + begin + F[Flag_X] <= #1 ALU_Q[3]; + F[Flag_Y] <= #1 ALU_Q[1]; + F[Flag_H] <= #1 1'b0; + F[Flag_N] <= #1 1'b0; + end + if (I_BC == 1'b1 || I_BT == 1'b1 ) + begin + F[Flag_P] <= #1 IncDecZ; + end + + if ((tstate[1] && Save_ALU_r == 1'b0 && Auto_Wait_t1 == 1'b0) || + (Save_ALU_r == 1'b1 && ALU_Op_r != 4'b0111) ) + begin + case (Read_To_Reg_r) + 5'b10111 : + ACC <= #1 Save_Mux; + 5'b10110 : + dout <= #1 Save_Mux; + 5'b11000 : + SP[7:0] <= #1 Save_Mux; + 5'b11001 : + SP[15:8] <= #1 Save_Mux; + 5'b11011 : + F <= #1 Save_Mux; + default : ; + endcase + end // if ((tstate == 1 && Save_ALU_r == 1'b0 && Auto_Wait_t1 == 1'b0) ||... + end // if (ClkEn == 1'b1 ) + end // else: !if(reset_n == 1'b0 ) + end + + + //------------------------------------------------------------------------- + // + // BC('), DE('), HL('), IX && IY + // + //------------------------------------------------------------------------- + always @ (posedge clk) + begin + if (ClkEn == 1'b1 ) + begin + // Bus A / Write + RegAddrA_r <= #1 { Alternate, Set_BusA_To[2:1] }; + if (XY_Ind == 1'b0 && XY_State != 2'b00 && Set_BusA_To[2:1] == 2'b10 ) + begin + RegAddrA_r <= #1 { XY_State[1], 2'b11 }; + end + + // Bus B + RegAddrB_r <= #1 { Alternate, Set_BusB_To[2:1] }; + if (XY_Ind == 1'b0 && XY_State != 2'b00 && Set_BusB_To[2:1] == 2'b10 ) + begin + RegAddrB_r <= #1 { XY_State[1], 2'b11 }; + end + + // Address from register + RegAddrC <= #1 { Alternate, Set_Addr_To[1:0] }; + // Jump (HL), LD SP,HL + if ((JumpXY == 1'b1 || LDSPHL == 1'b1) ) + begin + RegAddrC <= #1 { Alternate, 2'b10 }; + end + if (((JumpXY == 1'b1 || LDSPHL == 1'b1) && XY_State != 2'b00) || (mcycle[5]) ) + begin + RegAddrC <= #1 { XY_State[1], 2'b11 }; + end + + if (I_DJNZ == 1'b1 && Save_ALU_r == 1'b1 && Mode < 2 ) + begin + IncDecZ <= #1 F_Out[Flag_Z]; + end + if ((tstate[2] || (tstate[3] && mcycle[0])) && IncDec_16[2:0] == 3'b100 ) + begin + if (ID16 == 0 ) + begin + IncDecZ <= #1 1'b0; + end + else + begin + IncDecZ <= #1 1'b1; + end + end + + RegBusA_r <= #1 RegBusA; + end + + end // always @ (posedge clk) + + + always @(/*AUTOSENSE*/Alternate or ExchangeDH or IncDec_16 + or RegAddrA_r or RegAddrB_r or XY_State or mcycle or tstate) + begin + if ((tstate[2] || (tstate[3] && mcycle[0] && IncDec_16[2] == 1'b1)) && XY_State == 2'b00) + RegAddrA = { Alternate, IncDec_16[1:0] }; + else if ((tstate[2] || (tstate[3] && mcycle[0] && IncDec_16[2] == 1'b1)) && IncDec_16[1:0] == 2'b10) + RegAddrA = { XY_State[1], 2'b11 }; + else if (ExchangeDH == 1'b1 && tstate[3]) + RegAddrA = { Alternate, 2'b10 }; + else if (ExchangeDH == 1'b1 && tstate[4]) + RegAddrA = { Alternate, 2'b01 }; + else + RegAddrA = RegAddrA_r; + + if (ExchangeDH == 1'b1 && tstate[3]) + RegAddrB = { Alternate, 2'b01 }; + else + RegAddrB = RegAddrB_r; + end // always @ * + + + always @(/*AUTOSENSE*/ALU_Op_r or Auto_Wait_t1 or ExchangeDH + or IncDec_16 or Read_To_Reg_r or Save_ALU_r or mcycle + or tstate or wait_n) + begin + RegWEH = 1'b0; + RegWEL = 1'b0; + if ((tstate[1] && ~Save_ALU_r && ~Auto_Wait_t1) || + (Save_ALU_r && (ALU_Op_r != 4'b0111)) ) + begin + case (Read_To_Reg_r) + 5'b10000 , 5'b10001 , 5'b10010 , 5'b10011 , 5'b10100 , 5'b10101 : + begin + RegWEH = ~ Read_To_Reg_r[0]; + RegWEL = Read_To_Reg_r[0]; + end // UNMATCHED !! + default : ; + endcase // case(Read_To_Reg_r) + + end // if ((tstate == 1 && Save_ALU_r == 1'b0 && Auto_Wait_t1 == 1'b0) ||... + + + if (ExchangeDH && (tstate[3] || tstate[4]) ) + begin + RegWEH = 1'b1; + RegWEL = 1'b1; + end + + if (IncDec_16[2] && ((tstate[2] && wait_n && ~mcycle[0]) || (tstate[3] && mcycle[0])) ) + begin + case (IncDec_16[1:0]) + 2'b00 , 2'b01 , 2'b10 : + begin + RegWEH = 1'b1; + RegWEL = 1'b1; + end // UNMATCHED !! + default : ; + endcase + end + end // always @ * + + + always @(/*AUTOSENSE*/ExchangeDH or ID16 or IncDec_16 or RegBusA_r + or RegBusB or Save_Mux or mcycle or tstate) + begin + RegDIH = Save_Mux; + RegDIL = Save_Mux; + + if (ExchangeDH == 1'b1 && tstate[3] ) + begin + RegDIH = RegBusB[15:8]; + RegDIL = RegBusB[7:0]; + end + else if (ExchangeDH == 1'b1 && tstate[4] ) + begin + RegDIH = RegBusA_r[15:8]; + RegDIL = RegBusA_r[7:0]; + end + else if (IncDec_16[2] == 1'b1 && ((tstate[2] && ~mcycle[0]) || (tstate[3] && mcycle[0])) ) + begin + RegDIH = ID16[15:8]; + RegDIL = ID16[7:0]; + end + end + + tv80_reg i_reg + ( + .clk (clk), + .CEN (ClkEn), + .WEH (RegWEH), + .WEL (RegWEL), + .AddrA (RegAddrA), + .AddrB (RegAddrB), + .AddrC (RegAddrC), + .DIH (RegDIH), + .DIL (RegDIL), + .DOAH (RegBusA[15:8]), + .DOAL (RegBusA[7:0]), + .DOBH (RegBusB[15:8]), + .DOBL (RegBusB[7:0]), + .DOCH (RegBusC[15:8]), + .DOCL (RegBusC[7:0]) + ); + + //------------------------------------------------------------------------- + // + // Buses + // + //------------------------------------------------------------------------- + + always @ (posedge clk) + begin + if (ClkEn == 1'b1 ) + begin + case (Set_BusB_To) + 4'b0111 : + BusB <= #1 ACC; + 4'b0000 , 4'b0001 , 4'b0010 , 4'b0011 , 4'b0100 , 4'b0101 : + begin + if (Set_BusB_To[0] == 1'b1 ) + begin + BusB <= #1 RegBusB[7:0]; + end + else + begin + BusB <= #1 RegBusB[15:8]; + end + end + 4'b0110 : + BusB <= #1 DI_Reg; + 4'b1000 : + BusB <= #1 SP[7:0]; + 4'b1001 : + BusB <= #1 SP[15:8]; + 4'b1010 : + BusB <= #1 8'b00000001; + 4'b1011 : + BusB <= #1 F; + 4'b1100 : + BusB <= #1 PC[7:0]; + 4'b1101 : + BusB <= #1 PC[15:8]; + 4'b1110 : + BusB <= #1 8'b00000000; + default : + BusB <= #1 8'h0; + endcase + + case (Set_BusA_To) + 4'b0111 : + BusA <= #1 ACC; + 4'b0000 , 4'b0001 , 4'b0010 , 4'b0011 , 4'b0100 , 4'b0101 : + begin + if (Set_BusA_To[0] == 1'b1 ) + begin + BusA <= #1 RegBusA[7:0]; + end + else + begin + BusA <= #1 RegBusA[15:8]; + end + end + 4'b0110 : + BusA <= #1 DI_Reg; + 4'b1000 : + BusA <= #1 SP[7:0]; + 4'b1001 : + BusA <= #1 SP[15:8]; + 4'b1010 : + BusA <= #1 8'b00000000; + default : + BusA <= #1 8'h0; + endcase + end + end + + //------------------------------------------------------------------------- + // + // Generate external control signals + // + //------------------------------------------------------------------------- +`ifdef TV80_REFRESH + always @ (posedge clk or negedge reset_n) + begin + if (reset_n == 1'b0 ) + begin + rfsh_n <= #1 1'b1; + end + else + begin + if (cen == 1'b1 ) + begin + if (mcycle[0] && ((tstate[2] && wait_n == 1'b1) || tstate[3]) ) + begin + rfsh_n <= #1 1'b0; + end + else + begin + rfsh_n <= #1 1'b1; + end + end + end + end // always @ (posedge clk or negedge reset_n) +`else // !`ifdef TV80_REFRESH + assign rfsh_n = 1'b1; +`endif + + always @(/*AUTOSENSE*/BusAck or Halt_FF or I_DJNZ or IntCycle + or IntE_FF1 or di or iorq_i or mcycle or tstate) + begin + mc = mcycle; + ts = tstate; + DI_Reg = di; + halt_n = ~ Halt_FF; + busak_n = ~ BusAck; + intcycle_n = ~ IntCycle; + IntE = IntE_FF1; + iorq = iorq_i; + stop = I_DJNZ; + end + + //----------------------------------------------------------------------- + // + // Syncronise inputs + // + //----------------------------------------------------------------------- + + always @ (posedge clk or negedge reset_n) + begin : sync_inputs + if (~reset_n) + begin + BusReq_s <= #1 1'b0; + INT_s <= #1 1'b0; + NMI_s <= #1 1'b0; + Oldnmi_n <= #1 1'b0; + end + else + begin + if (cen == 1'b1 ) + begin + BusReq_s <= #1 ~ busrq_n; + INT_s <= #1 ~ int_n; + if (NMICycle == 1'b1 ) + begin + NMI_s <= #1 1'b0; + end + else if (nmi_n == 1'b0 && Oldnmi_n == 1'b1 ) + begin + NMI_s <= #1 1'b1; + end + Oldnmi_n <= #1 nmi_n; + end + end + end + + //----------------------------------------------------------------------- + // + // Main state machine + // + //----------------------------------------------------------------------- + + always @ (posedge clk or negedge reset_n) + begin + if (reset_n == 1'b0 ) + begin + mcycle <= #1 7'b0000001; + tstate <= #1 7'b0000001; + Pre_XY_F_M <= #1 3'b000; + Halt_FF <= #1 1'b0; + BusAck <= #1 1'b0; + NMICycle <= #1 1'b0; + IntCycle <= #1 1'b0; + IntE_FF1 <= #1 1'b0; + IntE_FF2 <= #1 1'b0; + No_BTR <= #1 1'b0; + Auto_Wait_t1 <= #1 1'b0; + Auto_Wait_t2 <= #1 1'b0; + m1_n <= #1 1'b1; + end + else + begin + if (cen == 1'b1 ) + begin + if (T_Res == 1'b1 ) + begin + Auto_Wait_t1 <= #1 1'b0; + end + else + begin + Auto_Wait_t1 <= #1 Auto_Wait || (iorq_i & ~Auto_Wait_t2); + end + Auto_Wait_t2 <= #1 Auto_Wait_t1 & !T_Res; + No_BTR <= #1 (I_BT && (~ IR[4] || ~ F[Flag_P])) || + (I_BC && (~ IR[4] || F[Flag_Z] || ~ F[Flag_P])) || + (I_BTR && (~ IR[4] || F[Flag_Z])); + if (tstate[2] ) + begin + if (SetEI == 1'b1 ) + begin + if (!NMICycle) + IntE_FF1 <= #1 1'b1; + IntE_FF2 <= #1 1'b1; + end + if (I_RETN == 1'b1 ) + begin + IntE_FF1 <= #1 IntE_FF2; + end + end + if (tstate[3] ) + begin + if (SetDI == 1'b1 ) + begin + IntE_FF1 <= #1 1'b0; + IntE_FF2 <= #1 1'b0; + end + end + if (IntCycle == 1'b1 || NMICycle == 1'b1 ) + begin + Halt_FF <= #1 1'b0; + end + if (mcycle[0] && tstate[2] && wait_n == 1'b1 ) + begin + m1_n <= #1 1'b1; + end + if (BusReq_s == 1'b1 && BusAck == 1'b1 ) + begin + end + else + begin + BusAck <= #1 1'b0; + if (tstate[2] && wait_n == 1'b0 ) + begin + end + else if (T_Res == 1'b1 ) + begin + if (Halt == 1'b1 ) + begin + Halt_FF <= #1 1'b1; + end + if (BusReq_s == 1'b1 ) + begin + BusAck <= #1 1'b1; + end + else + begin + tstate <= #1 7'b0000010; + if (NextIs_XY_Fetch == 1'b1 ) + begin + mcycle <= #1 7'b0100000; + Pre_XY_F_M <= #1 mcyc_to_number(mcycle); + if (IR == 8'b00110110 && Mode == 0 ) + begin + Pre_XY_F_M <= #1 3'b010; + end + end + else if ((mcycle[6]) || (mcycle[5] && Mode == 1 && ISet != 2'b01) ) + begin + mcycle <= #1 number_to_bitvec(Pre_XY_F_M + 1); + end + else if ((last_mcycle) || + No_BTR == 1'b1 || + (mcycle[1] && I_DJNZ == 1'b1 && IncDecZ == 1'b1) ) + begin + m1_n <= #1 1'b0; + mcycle <= #1 7'b0000001; + IntCycle <= #1 1'b0; + NMICycle <= #1 1'b0; + if (NMI_s == 1'b1 && Prefix == 2'b00 ) + begin + NMICycle <= #1 1'b1; + IntE_FF1 <= #1 1'b0; + end + else if ((IntE_FF1 == 1'b1 && INT_s == 1'b1) && Prefix == 2'b00 && SetEI == 1'b0 ) + begin + IntCycle <= #1 1'b1; + IntE_FF1 <= #1 1'b0; + IntE_FF2 <= #1 1'b0; + end + end + else + begin + mcycle <= #1 { mcycle[5:0], mcycle[6] }; + end + end + end + else + begin // verilog has no "nor" operator + if ( ~(Auto_Wait == 1'b1 && Auto_Wait_t2 == 1'b0) && + ~(IOWait == 1 && iorq_i == 1'b1 && Auto_Wait_t1 == 1'b0) ) + begin + tstate <= #1 { tstate[5:0], tstate[6] }; + end + end + end + if (tstate[0]) + begin + m1_n <= #1 1'b0; + end + end + end + end + + always @(/*AUTOSENSE*/BTR_r or DI_Reg or IncDec_16 or JumpE or PC + or RegBusA or RegBusC or SP or tstate) + begin + if (JumpE == 1'b1 ) + begin + PC16_B = { {8{DI_Reg[7]}}, DI_Reg }; + end + else if (BTR_r == 1'b1 ) + begin + PC16_B = -2; + end + else + begin + PC16_B = 1; + end + + if (tstate[3]) + begin + SP16_A = RegBusC; + SP16_B = { {8{DI_Reg[7]}}, DI_Reg }; + end + else + begin + // suspect that ID16 and SP16 could be shared + SP16_A = SP; + + if (IncDec_16[3] == 1'b1) + SP16_B = -1; + else + SP16_B = 1; + end + + if (IncDec_16[3]) + ID16_B = -1; + else + ID16_B = 1; + + ID16 = RegBusA + ID16_B; + PC16 = PC + PC16_B; + SP16 = SP16_A + SP16_B; + end // always @ * + + + always @(/*AUTOSENSE*/IntCycle or NMICycle or mcycle) + begin + Auto_Wait = 1'b0; + if (IntCycle == 1'b1 || NMICycle == 1'b1 ) + begin + if (mcycle[0] ) + begin + Auto_Wait = 1'b1; + end + end + end // always @ * + +endmodule // T80 +

powered by: WebSVN 2.1.0

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