mirror of
https://github.com/Gehstock/Mist_FPGA.git
synced 2026-01-13 23:26:43 +00:00
use Common CPU
This commit is contained in:
parent
72bd0a1824
commit
71896a93a8
@ -45,36 +45,6 @@ set_global_assignment -name PROJECT_CREATION_TIME_DATE "01:53:30 APRIL 20, 2017
|
||||
set_global_assignment -name PROJECT_OUTPUT_DIRECTORY output_files
|
||||
set_global_assignment -name NUM_PARALLEL_PROCESSORS ALL
|
||||
set_global_assignment -name PRE_FLOW_SCRIPT_FILE "quartus_sh:rtl/build_id.tcl"
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE rtl/DigDug.sv
|
||||
set_global_assignment -name VERILOG_FILE rtl/FPGA_DIGDUG.v
|
||||
set_global_assignment -name VERILOG_FILE rtl/DIGDUG_CORES.v
|
||||
set_global_assignment -name VERILOG_FILE rtl/cpucore.v
|
||||
set_global_assignment -name VERILOG_FILE rtl/DIGDUG_CUSIO.v
|
||||
set_global_assignment -name VERILOG_FILE rtl/DIGDUG_IODEV.v
|
||||
set_global_assignment -name VERILOG_FILE rtl/DIGDUG_SPRITE.v
|
||||
set_global_assignment -name VERILOG_FILE rtl/DIGDUG_VIDEO.v
|
||||
set_global_assignment -name VERILOG_FILE rtl/hvgen.v
|
||||
set_global_assignment -name VERILOG_FILE rtl/dprams.v
|
||||
set_global_assignment -name VERILOG_FILE rtl/wsg.v
|
||||
set_global_assignment -name VERILOG_FILE rtl/LINEBUF.v
|
||||
set_global_assignment -name VERILOG_FILE rtl/pll.v
|
||||
set_global_assignment -name VERILOG_FILE rtl/TV80/tv80s.v
|
||||
set_global_assignment -name VERILOG_FILE rtl/TV80/tv80_reg.v
|
||||
set_global_assignment -name VERILOG_FILE rtl/TV80/tv80_mcode.v
|
||||
set_global_assignment -name VERILOG_FILE rtl/TV80/tv80_core.v
|
||||
set_global_assignment -name VERILOG_FILE rtl/TV80/tv80_alu.v
|
||||
set_global_assignment -name VHDL_FILE rtl/roms/wave_rom.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/roms/spclut_rom.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/roms/spchip_rom.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/roms/palette_rom.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/roms/fgchip_rom.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/roms/cpu2_rom.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/roms/cpu1_rom.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/roms/bgscrn_rom.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/roms/bgclut_rom.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/roms/bgchip_rom.vhd
|
||||
set_global_assignment -name QIP_FILE ../../../common/mist/mist.qip
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE ../../../common/mist/sdram.sv
|
||||
|
||||
# Pin & Location Assignments
|
||||
# ==========================
|
||||
@ -228,4 +198,30 @@ set_global_assignment -name OUTPUT_IO_TIMING_FAR_END_VMEAS "HALF SIGNAL SWING" -
|
||||
|
||||
# end ENTITY(DigDug)
|
||||
# ------------------
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE rtl/DigDug.sv
|
||||
set_global_assignment -name VERILOG_FILE rtl/FPGA_DIGDUG.v
|
||||
set_global_assignment -name VERILOG_FILE rtl/DIGDUG_CORES.v
|
||||
set_global_assignment -name VERILOG_FILE rtl/cpucore.v
|
||||
set_global_assignment -name VERILOG_FILE rtl/DIGDUG_CUSIO.v
|
||||
set_global_assignment -name VERILOG_FILE rtl/DIGDUG_IODEV.v
|
||||
set_global_assignment -name VERILOG_FILE rtl/DIGDUG_SPRITE.v
|
||||
set_global_assignment -name VERILOG_FILE rtl/DIGDUG_VIDEO.v
|
||||
set_global_assignment -name VHDL_FILE rtl/roms/wave_rom.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/roms/spclut_rom.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/roms/spchip_rom.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/roms/palette_rom.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/roms/fgchip_rom.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/roms/cpu2_rom.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/roms/cpu1_rom.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/roms/bgscrn_rom.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/roms/bgclut_rom.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/roms/bgchip_rom.vhd
|
||||
set_global_assignment -name VERILOG_FILE rtl/hvgen.v
|
||||
set_global_assignment -name VERILOG_FILE rtl/dprams.v
|
||||
set_global_assignment -name VERILOG_FILE rtl/wsg.v
|
||||
set_global_assignment -name VERILOG_FILE rtl/LINEBUF.v
|
||||
set_global_assignment -name VERILOG_FILE rtl/pll.v
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE rtl/sdram.sv
|
||||
set_global_assignment -name QIP_FILE ../../../common/mist/mist.qip
|
||||
set_global_assignment -name QIP_FILE ../../../common/CPU/tv80/TV80.qip
|
||||
set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top
|
||||
@ -1,442 +0,0 @@
|
||||
//
|
||||
// TV80 8-Bit Microprocessor Core
|
||||
// Based on the VHDL T80 core by Daniel Wallner (jesus@opencores.org)
|
||||
//
|
||||
// Copyright (c) 2004 Guy Hutchison (ghutchis@opencores.org)
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included
|
||||
// in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
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 } + 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 } + 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 } + 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
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,71 +0,0 @@
|
||||
//
|
||||
// TV80 8-Bit Microprocessor Core
|
||||
// Based on the VHDL T80 core by Daniel Wallner (jesus@opencores.org)
|
||||
//
|
||||
// Copyright (c) 2004 Guy Hutchison (ghutchis@opencores.org)
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included
|
||||
// in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
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
|
||||
wire [7:0] H = RegsH[2];
|
||||
wire [7:0] L = RegsL[2];
|
||||
|
||||
// synopsys dc_script_begin
|
||||
// set_attribute current_design "revision" "$Id: tv80_reg.v,v 1.1 2004/05/16 17:39:57 ghutchis Exp $" -type string -quiet
|
||||
// synopsys dc_script_end
|
||||
endmodule
|
||||
|
||||
@ -1,164 +0,0 @@
|
||||
//
|
||||
// TV80 8-Bit Microprocessor Core
|
||||
// Based on the VHDL T80 core by Daniel Wallner (jesus@opencores.org)
|
||||
//
|
||||
// Copyright (c) 2004 Guy Hutchison (ghutchis@opencores.org)
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included
|
||||
// in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
//`define TV80_REFRESH
|
||||
|
||||
module tv80s (/*AUTOARG*/
|
||||
// Outputs
|
||||
m1_n, mreq_n, iorq_n, rd_n, wr_n, rfsh_n, halt_n, busak_n, A, do,
|
||||
// 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 = 1; // 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] do;
|
||||
|
||||
reg mreq_n;
|
||||
reg iorq_n;
|
||||
reg rd_n;
|
||||
reg 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),
|
||||
.do (do),
|
||||
.mc (mcycle),
|
||||
.ts (tstate),
|
||||
.intcycle_n (intcycle_n)
|
||||
);
|
||||
|
||||
always @(posedge 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;
|
||||
di_reg <= #1 0;
|
||||
end
|
||||
else
|
||||
begin
|
||||
rd_n <= #1 1'b1;
|
||||
wr_n <= #1 1'b1;
|
||||
iorq_n <= #1 1'b1;
|
||||
mreq_n <= #1 1'b1;
|
||||
if (mcycle[0])
|
||||
begin
|
||||
if (tstate[1] || (tstate[2] && wait_n == 1'b0))
|
||||
begin
|
||||
rd_n <= #1 ~ intcycle_n;
|
||||
mreq_n <= #1 ~ intcycle_n;
|
||||
iorq_n <= #1 intcycle_n;
|
||||
end
|
||||
`ifdef TV80_REFRESH
|
||||
if (tstate[3])
|
||||
mreq_n <= #1 1'b0;
|
||||
`endif
|
||||
end // if (mcycle[0])
|
||||
else
|
||||
begin
|
||||
if ((tstate[1] || (tstate[2] && wait_n == 1'b0)) && no_read == 1'b0 && write == 1'b0)
|
||||
begin
|
||||
rd_n <= #1 1'b0;
|
||||
iorq_n <= #1 ~ iorq;
|
||||
mreq_n <= #1 iorq;
|
||||
end
|
||||
if (T2Write == 0)
|
||||
begin
|
||||
if (tstate[2] && write == 1'b1)
|
||||
begin
|
||||
wr_n <= #1 1'b0;
|
||||
iorq_n <= #1 ~ iorq;
|
||||
mreq_n <= #1 iorq;
|
||||
end
|
||||
end
|
||||
else
|
||||
begin
|
||||
if ((tstate[1] || (tstate[2] && wait_n == 1'b0)) && write == 1'b1)
|
||||
begin
|
||||
wr_n <= #1 1'b0;
|
||||
iorq_n <= #1 ~ iorq;
|
||||
mreq_n <= #1 iorq;
|
||||
end
|
||||
end // else: !if(T2write == 0)
|
||||
|
||||
end // else: !if(mcycle[0])
|
||||
|
||||
if (tstate[2] && wait_n == 1'b1)
|
||||
di_reg <= #1 di;
|
||||
end // else: !if(!reset_n)
|
||||
end // always @ (posedge clk or negedge reset_n)
|
||||
|
||||
endmodule // t80s
|
||||
|
||||
@ -28,14 +28,13 @@ wire [7:0] m_di = cs_mrom ? IR : DV ? DI : 8'hFF;
|
||||
|
||||
assign m_irq = ~IRQ;
|
||||
assign m_nmi = ~NMI;
|
||||
|
||||
tv80s core(
|
||||
.mreq_n(m_me),
|
||||
.iorq_n(m_ie),
|
||||
.rd_n(m_rd),
|
||||
.wr_n(m_wr),
|
||||
.A(m_ad),
|
||||
.do(m_do),
|
||||
.dout(m_do),
|
||||
|
||||
.reset_n(~RESET),
|
||||
.clk(CLK),
|
||||
|
||||
@ -1,119 +0,0 @@
|
||||
LIBRARY ieee;
|
||||
USE ieee.std_logic_1164.all;
|
||||
|
||||
LIBRARY altera_mf;
|
||||
USE altera_mf.all;
|
||||
|
||||
ENTITY dpram IS
|
||||
GENERIC
|
||||
(
|
||||
widthad_a : natural;
|
||||
width_a : natural := 8
|
||||
);
|
||||
PORT
|
||||
(
|
||||
address_a : IN STD_LOGIC_VECTOR (widthad_a-1 DOWNTO 0);
|
||||
address_b : IN STD_LOGIC_VECTOR (widthad_a-1 DOWNTO 0);
|
||||
clock_a : IN STD_LOGIC ;
|
||||
clock_b : IN STD_LOGIC ;
|
||||
data_a : IN STD_LOGIC_VECTOR (width_a-1 DOWNTO 0);
|
||||
data_b : IN STD_LOGIC_VECTOR (width_a-1 DOWNTO 0);
|
||||
wren_a : IN STD_LOGIC := '1';
|
||||
wren_b : IN STD_LOGIC := '1';
|
||||
q_a : OUT STD_LOGIC_VECTOR (width_a-1 DOWNTO 0);
|
||||
q_b : OUT STD_LOGIC_VECTOR (width_a-1 DOWNTO 0)
|
||||
);
|
||||
END dpram;
|
||||
|
||||
|
||||
ARCHITECTURE SYN OF dpram IS
|
||||
|
||||
SIGNAL sub_wire0 : STD_LOGIC_VECTOR (width_a-1 DOWNTO 0);
|
||||
SIGNAL sub_wire1 : STD_LOGIC_VECTOR (width_a-1 DOWNTO 0);
|
||||
|
||||
COMPONENT altsyncram
|
||||
GENERIC (
|
||||
address_reg_b : STRING;
|
||||
clock_enable_input_a : STRING;
|
||||
clock_enable_input_b : STRING;
|
||||
clock_enable_output_a : STRING;
|
||||
clock_enable_output_b : STRING;
|
||||
indata_reg_b : STRING;
|
||||
init_file : STRING;
|
||||
intended_device_family : STRING;
|
||||
lpm_type : STRING;
|
||||
numwords_a : NATURAL;
|
||||
numwords_b : NATURAL;
|
||||
operation_mode : STRING;
|
||||
outdata_aclr_a : STRING;
|
||||
outdata_aclr_b : STRING;
|
||||
outdata_reg_a : STRING;
|
||||
outdata_reg_b : STRING;
|
||||
power_up_uninitialized : STRING;
|
||||
widthad_a : NATURAL;
|
||||
widthad_b : NATURAL;
|
||||
width_a : NATURAL;
|
||||
width_b : NATURAL;
|
||||
width_byteena_a : NATURAL;
|
||||
width_byteena_b : NATURAL;
|
||||
wrcontrol_wraddress_reg_b : STRING
|
||||
);
|
||||
PORT (
|
||||
wren_a : IN STD_LOGIC ;
|
||||
clock0 : IN STD_LOGIC ;
|
||||
wren_b : IN STD_LOGIC ;
|
||||
clock1 : IN STD_LOGIC ;
|
||||
address_a : IN STD_LOGIC_VECTOR (widthad_a-1 DOWNTO 0);
|
||||
address_b : IN STD_LOGIC_VECTOR (widthad_a-1 DOWNTO 0);
|
||||
q_a : OUT STD_LOGIC_VECTOR (width_a-1 DOWNTO 0);
|
||||
q_b : OUT STD_LOGIC_VECTOR (width_a-1 DOWNTO 0);
|
||||
data_a : IN STD_LOGIC_VECTOR (width_a-1 DOWNTO 0);
|
||||
data_b : IN STD_LOGIC_VECTOR (width_a-1 DOWNTO 0)
|
||||
);
|
||||
END COMPONENT;
|
||||
|
||||
BEGIN
|
||||
q_a <= sub_wire0(width_a-1 DOWNTO 0);
|
||||
q_b <= sub_wire1(width_a-1 DOWNTO 0);
|
||||
|
||||
altsyncram_component : altsyncram
|
||||
GENERIC MAP (
|
||||
address_reg_b => "CLOCK1",
|
||||
clock_enable_input_a => "BYPASS",
|
||||
clock_enable_input_b => "BYPASS",
|
||||
clock_enable_output_a => "BYPASS",
|
||||
clock_enable_output_b => "BYPASS",
|
||||
indata_reg_b => "CLOCK1",
|
||||
init_file => "",
|
||||
intended_device_family => "Cyclone III",
|
||||
lpm_type => "altsyncram",
|
||||
numwords_a => 2**widthad_a,
|
||||
numwords_b => 2**widthad_a,
|
||||
operation_mode => "BIDIR_DUAL_PORT",
|
||||
outdata_aclr_a => "NONE",
|
||||
outdata_aclr_b => "NONE",
|
||||
outdata_reg_a => "UNREGISTERED",
|
||||
outdata_reg_b => "UNREGISTERED",
|
||||
power_up_uninitialized => "FALSE",
|
||||
widthad_a => widthad_a,
|
||||
widthad_b => widthad_a,
|
||||
width_a => width_a,
|
||||
width_b => width_a,
|
||||
width_byteena_a => 1,
|
||||
width_byteena_b => 1,
|
||||
wrcontrol_wraddress_reg_b => "CLOCK1"
|
||||
)
|
||||
PORT MAP (
|
||||
wren_a => wren_a,
|
||||
clock0 => clock_a,
|
||||
wren_b => wren_b,
|
||||
clock1 => clock_b,
|
||||
address_a => address_a,
|
||||
address_b => address_b,
|
||||
data_a => data_a,
|
||||
data_b => data_b,
|
||||
q_a => sub_wire0,
|
||||
q_b => sub_wire1
|
||||
);
|
||||
|
||||
END SYN;
|
||||
254
Arcade_MiST/Galaga Hardware/DigDug_MiST/rtl/sdram.sv
Normal file
254
Arcade_MiST/Galaga Hardware/DigDug_MiST/rtl/sdram.sv
Normal file
@ -0,0 +1,254 @@
|
||||
//
|
||||
// sdram.v
|
||||
//
|
||||
// Static RAM controller implementation using SDRAM MT48LC16M16A2
|
||||
//
|
||||
// Copyright (c) 2015,2016 Sorgelig
|
||||
//
|
||||
// Some parts of SDRAM code used from project:
|
||||
// http://hamsterworks.co.nz/mediawiki/index.php/Simple_SDRAM_Controller
|
||||
//
|
||||
// This source file is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published
|
||||
// by the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This source file is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
// ------------------------------------------
|
||||
//
|
||||
// v2.1 - Add universal 8/16 bit mode.
|
||||
//
|
||||
|
||||
module sdram
|
||||
(
|
||||
input init, // reset to initialize RAM
|
||||
input clk, // clock ~100MHz
|
||||
//
|
||||
// SDRAM_* - signals to the MT48LC16M16 chip
|
||||
inout reg [15:0] SDRAM_DQ, // 16 bit bidirectional data bus
|
||||
output reg [12:0] SDRAM_A, // 13 bit multiplexed address bus
|
||||
output reg SDRAM_DQML, // two byte masks
|
||||
output reg SDRAM_DQMH, //
|
||||
output reg [1:0] SDRAM_BA, // two banks
|
||||
output SDRAM_nCS, // a single chip select
|
||||
output SDRAM_nWE, // write enable
|
||||
output SDRAM_nRAS, // row address select
|
||||
output SDRAM_nCAS, // columns address select
|
||||
output SDRAM_CKE, // clock enable
|
||||
//
|
||||
input [1:0] wtbt, // 16bit mode: bit1 - write high byte, bit0 - write low byte,
|
||||
// 8bit mode: 2'b00 - use addr[0] to decide which byte to write
|
||||
// Ignored while reading.
|
||||
//
|
||||
input [24:0] addr, // 25 bit address for 8bit mode. addr[0] = 0 for 16bit mode for correct operations.
|
||||
output [15:0] dout, // data output to cpu
|
||||
input [15:0] din, // data input from cpu
|
||||
input we, // cpu requests write
|
||||
input rd, // cpu requests read
|
||||
output reg ready // dout is valid. Ready to accept new read/write.
|
||||
);
|
||||
|
||||
assign SDRAM_nCS = command[3];
|
||||
assign SDRAM_nRAS = command[2];
|
||||
assign SDRAM_nCAS = command[1];
|
||||
assign SDRAM_nWE = command[0];
|
||||
assign SDRAM_CKE = cke;
|
||||
|
||||
// no burst configured
|
||||
localparam BURST_LENGTH = 3'b000; // 000=1, 001=2, 010=4, 011=8
|
||||
localparam ACCESS_TYPE = 1'b0; // 0=sequential, 1=interleaved
|
||||
localparam CAS_LATENCY = 3'd2; // 2 for < 100MHz, 3 for >100MHz
|
||||
localparam OP_MODE = 2'b00; // only 00 (standard operation) allowed
|
||||
localparam NO_WRITE_BURST = 1'b1; // 0= write burst enabled, 1=only single access write
|
||||
localparam MODE = {3'b000, NO_WRITE_BURST, OP_MODE, CAS_LATENCY, ACCESS_TYPE, BURST_LENGTH};
|
||||
|
||||
localparam sdram_startup_cycles= 14'd12100;// 100us, plus a little more, @ 100MHz
|
||||
localparam cycles_per_refresh = 14'd186; // (64000*36)/8192-1 Calc'd as (64ms @ 36MHz)/8192 rose
|
||||
localparam startup_refresh_max = 14'b11111111111111;
|
||||
|
||||
// SDRAM commands
|
||||
localparam CMD_INHIBIT = 4'b1111;
|
||||
localparam CMD_NOP = 4'b0111;
|
||||
localparam CMD_ACTIVE = 4'b0011;
|
||||
localparam CMD_READ = 4'b0101;
|
||||
localparam CMD_WRITE = 4'b0100;
|
||||
localparam CMD_BURST_TERMINATE = 4'b0110;
|
||||
localparam CMD_PRECHARGE = 4'b0010;
|
||||
localparam CMD_AUTO_REFRESH = 4'b0001;
|
||||
localparam CMD_LOAD_MODE = 4'b0000;
|
||||
|
||||
reg [13:0] refresh_count = startup_refresh_max - sdram_startup_cycles;
|
||||
reg [3:0] command = CMD_INHIBIT;
|
||||
reg cke = 0;
|
||||
reg [24:0] save_addr;
|
||||
reg [15:0] data;
|
||||
|
||||
assign dout = save_addr[0] ? {data[7:0], data[15:8]} : {data[15:8], data[7:0]};
|
||||
typedef enum
|
||||
{
|
||||
STATE_STARTUP,
|
||||
STATE_OPEN_1,
|
||||
STATE_WRITE,
|
||||
STATE_READ,
|
||||
STATE_IDLE, STATE_IDLE_1, STATE_IDLE_2, STATE_IDLE_3,
|
||||
STATE_IDLE_4, STATE_IDLE_5, STATE_IDLE_6, STATE_IDLE_7
|
||||
} state_t;
|
||||
|
||||
state_t state = STATE_STARTUP;
|
||||
|
||||
always @(posedge clk) begin
|
||||
reg old_we, old_rd;
|
||||
reg [CAS_LATENCY:0] data_ready_delay;
|
||||
|
||||
reg [15:0] new_data;
|
||||
reg [1:0] new_wtbt;
|
||||
reg new_we;
|
||||
reg new_rd;
|
||||
reg save_we = 1;
|
||||
|
||||
|
||||
command <= CMD_NOP;
|
||||
refresh_count <= refresh_count+1'b1;
|
||||
|
||||
data_ready_delay <= {1'b0, data_ready_delay[CAS_LATENCY:1]};
|
||||
|
||||
if(data_ready_delay[0]) data <= SDRAM_DQ;
|
||||
|
||||
case(state)
|
||||
STATE_STARTUP: begin
|
||||
//------------------------------------------------------------------------
|
||||
//-- This is the initial startup state, where we wait for at least 100us
|
||||
//-- before starting the start sequence
|
||||
//--
|
||||
//-- The initialisation is sequence is
|
||||
//-- * de-assert SDRAM_CKE
|
||||
//-- * 100us wait,
|
||||
//-- * assert SDRAM_CKE
|
||||
//-- * wait at least one cycle,
|
||||
//-- * PRECHARGE
|
||||
//-- * wait 2 cycles
|
||||
//-- * REFRESH,
|
||||
//-- * tREF wait
|
||||
//-- * REFRESH,
|
||||
//-- * tREF wait
|
||||
//-- * LOAD_MODE_REG
|
||||
//-- * 2 cycles wait
|
||||
//------------------------------------------------------------------------
|
||||
cke <= 1;
|
||||
SDRAM_DQ <= 16'bZZZZZZZZZZZZZZZZ;
|
||||
SDRAM_DQML <= 1;
|
||||
SDRAM_DQMH <= 1;
|
||||
SDRAM_A <= 0;
|
||||
SDRAM_BA <= 0;
|
||||
|
||||
// All the commands during the startup are NOPS, except these
|
||||
if(refresh_count == startup_refresh_max-31) begin
|
||||
// ensure all rows are closed
|
||||
command <= CMD_PRECHARGE;
|
||||
SDRAM_A[10] <= 1; // all banks
|
||||
SDRAM_BA <= 2'b00;
|
||||
end else if (refresh_count == startup_refresh_max-23) begin
|
||||
// these refreshes need to be at least tREF (66ns) apart
|
||||
command <= CMD_AUTO_REFRESH;
|
||||
end else if (refresh_count == startup_refresh_max-15)
|
||||
command <= CMD_AUTO_REFRESH;
|
||||
else if (refresh_count == startup_refresh_max-7) begin
|
||||
// Now load the mode register
|
||||
command <= CMD_LOAD_MODE;
|
||||
SDRAM_A <= MODE;
|
||||
end
|
||||
|
||||
//------------------------------------------------------
|
||||
//-- if startup is complete then go into idle mode,
|
||||
//-- get prepared to accept a new command, and schedule
|
||||
//-- the first refresh cycle
|
||||
//------------------------------------------------------
|
||||
if(!refresh_count) begin
|
||||
state <= STATE_IDLE;
|
||||
ready <= 1;
|
||||
refresh_count <= 0;
|
||||
end
|
||||
end
|
||||
|
||||
STATE_IDLE_7: state <= STATE_IDLE_6;
|
||||
STATE_IDLE_6: state <= STATE_IDLE_5;
|
||||
STATE_IDLE_5: state <= STATE_IDLE_4;
|
||||
STATE_IDLE_4: state <= STATE_IDLE_3;
|
||||
STATE_IDLE_3: state <= STATE_IDLE_2;
|
||||
STATE_IDLE_2: state <= STATE_IDLE_1;
|
||||
STATE_IDLE_1: begin
|
||||
SDRAM_DQ <= 16'bZZZZZZZZZZZZZZZZ;
|
||||
state <= STATE_IDLE;
|
||||
// mask possible refresh to reduce colliding.
|
||||
if(refresh_count > cycles_per_refresh) begin
|
||||
//------------------------------------------------------------------------
|
||||
//-- Start the refresh cycle.
|
||||
//-- This tasks tRFC (66ns), so 2 idle cycles are needed @ 36MHz
|
||||
//------------------------------------------------------------------------
|
||||
state <= STATE_IDLE_2;
|
||||
command <= CMD_AUTO_REFRESH;
|
||||
refresh_count <= refresh_count - cycles_per_refresh + 1'd1;
|
||||
end
|
||||
end
|
||||
|
||||
STATE_IDLE: begin
|
||||
// Priority is to issue a refresh if one is outstanding
|
||||
if(refresh_count > (cycles_per_refresh<<1)) state <= STATE_IDLE_1;
|
||||
else if(new_rd | new_we) begin
|
||||
new_we <= 0;
|
||||
new_rd <= 0;
|
||||
save_addr<= addr;
|
||||
save_we <= new_we;
|
||||
state <= STATE_OPEN_1;
|
||||
command <= CMD_ACTIVE;
|
||||
SDRAM_A <= addr[13:1];
|
||||
SDRAM_BA <= addr[24:23];
|
||||
end
|
||||
end
|
||||
|
||||
// ACTIVE-to-READ or WRITE delay >20ns (1 cycle @ 36 MHz)(-75)
|
||||
STATE_OPEN_1: begin
|
||||
SDRAM_A <= {4'b0010, save_addr[22:14]};
|
||||
SDRAM_DQML <= save_we & (new_wtbt ? ~new_wtbt[0] : save_addr[0]);
|
||||
SDRAM_DQMH <= save_we & (new_wtbt ? ~new_wtbt[1] : ~save_addr[0]);
|
||||
state <= save_we ? STATE_WRITE : STATE_READ;
|
||||
end
|
||||
|
||||
STATE_READ: begin
|
||||
state <= STATE_IDLE_5;
|
||||
command <= CMD_READ;
|
||||
SDRAM_DQ <= 16'bZZZZZZZZZZZZZZZZ;
|
||||
|
||||
// Schedule reading the data values off the bus
|
||||
data_ready_delay[CAS_LATENCY] <= 1;
|
||||
end
|
||||
|
||||
STATE_WRITE: begin
|
||||
state <= STATE_IDLE_5;
|
||||
command <= CMD_WRITE;
|
||||
SDRAM_DQ <= new_wtbt ? new_data : {new_data[7:0], new_data[7:0]};
|
||||
ready <= 1;
|
||||
end
|
||||
endcase
|
||||
|
||||
if(init) begin
|
||||
state <= STATE_STARTUP;
|
||||
refresh_count <= startup_refresh_max - sdram_startup_cycles;
|
||||
end
|
||||
|
||||
old_we <= we;
|
||||
old_rd <= rd;
|
||||
if(we & ~old_we) {ready, new_we, new_data, new_wtbt} <= {1'b0, 1'b1, din, wtbt};
|
||||
else
|
||||
if((rd & ~old_rd) || (rd & old_rd & (save_addr != addr))) {ready, new_rd} <= {1'b0, 1'b1};
|
||||
|
||||
end
|
||||
|
||||
endmodule
|
||||
@ -198,7 +198,6 @@ set_global_assignment -name PARTITION_COLOR 16764057 -section_id Top
|
||||
# end ENTITY(galaga_mist)
|
||||
# -----------------------
|
||||
set_global_assignment -name TIMEQUEST_MULTICORNER_ANALYSIS ON
|
||||
set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE rtl/galaga_mist.sv
|
||||
set_global_assignment -name VHDL_FILE rtl/galaga.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/gen_video.vhd
|
||||
@ -219,11 +218,7 @@ set_global_assignment -name VHDL_FILE rtl/roms/galaga_cpu1.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/roms/bg_palette.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/roms/bg_graphx.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/roms/cs54xx_prog.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/T80/T80se.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/T80/T80_Reg.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/T80/T80_Pack.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/T80/T80_MCode.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/T80/T80_ALU.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/T80/T80.vhd
|
||||
set_global_assignment -name VERILOG_FILE rtl/pll.v
|
||||
set_global_assignment -name QIP_FILE ../../../common/mist/mist.qip
|
||||
set_global_assignment -name QIP_FILE ../../../common/mist/mist.qip
|
||||
set_global_assignment -name QIP_FILE ../../../common/CPU/T80/T80.qip
|
||||
set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,351 +0,0 @@
|
||||
--
|
||||
-- Z80 compatible microprocessor core
|
||||
--
|
||||
-- Version : 0247
|
||||
--
|
||||
-- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org)
|
||||
--
|
||||
-- All rights reserved
|
||||
--
|
||||
-- Redistribution and use in source and synthezised forms, with or without
|
||||
-- modification, are permitted provided that the following conditions are met:
|
||||
--
|
||||
-- Redistributions of source code must retain the above copyright notice,
|
||||
-- this list of conditions and the following disclaimer.
|
||||
--
|
||||
-- Redistributions in synthesized form must reproduce the above copyright
|
||||
-- notice, this list of conditions and the following disclaimer in the
|
||||
-- documentation and/or other materials provided with the distribution.
|
||||
--
|
||||
-- Neither the name of the author nor the names of other contributors may
|
||||
-- be used to endorse or promote products derived from this software without
|
||||
-- specific prior written permission.
|
||||
--
|
||||
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
|
||||
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
-- POSSIBILITY OF SUCH DAMAGE.
|
||||
--
|
||||
-- Please report bugs to the author, but before you do so, please
|
||||
-- make sure that this is not a derivative work and that
|
||||
-- you have the latest version of this file.
|
||||
--
|
||||
-- The latest version of this file can be found at:
|
||||
-- http://www.opencores.org/cvsweb.shtml/t80/
|
||||
--
|
||||
-- Limitations :
|
||||
--
|
||||
-- File history :
|
||||
--
|
||||
-- 0214 : Fixed mostly flags, only the block instructions now fail the zex regression test
|
||||
--
|
||||
-- 0238 : Fixed zero flag for 16 bit SBC and ADC
|
||||
--
|
||||
-- 0240 : Added GB operations
|
||||
--
|
||||
-- 0242 : Cleanup
|
||||
--
|
||||
-- 0247 : Cleanup
|
||||
--
|
||||
|
||||
library IEEE;
|
||||
use IEEE.std_logic_1164.all;
|
||||
use IEEE.numeric_std.all;
|
||||
|
||||
entity T80_ALU is
|
||||
generic(
|
||||
Mode : integer := 0;
|
||||
Flag_C : integer := 0;
|
||||
Flag_N : integer := 1;
|
||||
Flag_P : integer := 2;
|
||||
Flag_X : integer := 3;
|
||||
Flag_H : integer := 4;
|
||||
Flag_Y : integer := 5;
|
||||
Flag_Z : integer := 6;
|
||||
Flag_S : integer := 7
|
||||
);
|
||||
port(
|
||||
Arith16 : in std_logic;
|
||||
Z16 : in std_logic;
|
||||
ALU_Op : in std_logic_vector(3 downto 0);
|
||||
IR : in std_logic_vector(5 downto 0);
|
||||
ISet : in std_logic_vector(1 downto 0);
|
||||
BusA : in std_logic_vector(7 downto 0);
|
||||
BusB : in std_logic_vector(7 downto 0);
|
||||
F_In : in std_logic_vector(7 downto 0);
|
||||
Q : out std_logic_vector(7 downto 0);
|
||||
F_Out : out std_logic_vector(7 downto 0)
|
||||
);
|
||||
end T80_ALU;
|
||||
|
||||
architecture rtl of T80_ALU is
|
||||
|
||||
procedure AddSub(A : std_logic_vector;
|
||||
B : std_logic_vector;
|
||||
Sub : std_logic;
|
||||
Carry_In : std_logic;
|
||||
signal Res : out std_logic_vector;
|
||||
signal Carry : out std_logic) is
|
||||
variable B_i : unsigned(A'length - 1 downto 0);
|
||||
variable Res_i : unsigned(A'length + 1 downto 0);
|
||||
begin
|
||||
if Sub = '1' then
|
||||
B_i := not unsigned(B);
|
||||
else
|
||||
B_i := unsigned(B);
|
||||
end if;
|
||||
Res_i := unsigned("0" & A & Carry_In) + unsigned("0" & B_i & "1");
|
||||
Carry <= Res_i(A'length + 1);
|
||||
Res <= std_logic_vector(Res_i(A'length downto 1));
|
||||
end;
|
||||
|
||||
-- AddSub variables (temporary signals)
|
||||
signal UseCarry : std_logic;
|
||||
signal Carry7_v : std_logic;
|
||||
signal Overflow_v : std_logic;
|
||||
signal HalfCarry_v : std_logic;
|
||||
signal Carry_v : std_logic;
|
||||
signal Q_v : std_logic_vector(7 downto 0);
|
||||
|
||||
signal BitMask : std_logic_vector(7 downto 0);
|
||||
|
||||
begin
|
||||
|
||||
with IR(5 downto 3) select BitMask <= "00000001" when "000",
|
||||
"00000010" when "001",
|
||||
"00000100" when "010",
|
||||
"00001000" when "011",
|
||||
"00010000" when "100",
|
||||
"00100000" when "101",
|
||||
"01000000" when "110",
|
||||
"10000000" when others;
|
||||
|
||||
UseCarry <= not ALU_Op(2) and ALU_Op(0);
|
||||
AddSub(BusA(3 downto 0), BusB(3 downto 0), ALU_Op(1), ALU_Op(1) xor (UseCarry and F_In(Flag_C)), Q_v(3 downto 0), HalfCarry_v);
|
||||
AddSub(BusA(6 downto 4), BusB(6 downto 4), ALU_Op(1), HalfCarry_v, Q_v(6 downto 4), Carry7_v);
|
||||
AddSub(BusA(7 downto 7), BusB(7 downto 7), ALU_Op(1), Carry7_v, Q_v(7 downto 7), Carry_v);
|
||||
OverFlow_v <= Carry_v xor Carry7_v;
|
||||
|
||||
process (Arith16, ALU_OP, F_In, BusA, BusB, IR, Q_v, Carry_v, HalfCarry_v, OverFlow_v, BitMask, ISet, Z16)
|
||||
variable Q_t : std_logic_vector(7 downto 0);
|
||||
variable DAA_Q : unsigned(8 downto 0);
|
||||
begin
|
||||
Q_t := "--------";
|
||||
F_Out <= F_In;
|
||||
DAA_Q := "---------";
|
||||
case ALU_Op is
|
||||
when "0000" | "0001" | "0010" | "0011" | "0100" | "0101" | "0110" | "0111" =>
|
||||
F_Out(Flag_N) <= '0';
|
||||
F_Out(Flag_C) <= '0';
|
||||
case ALU_OP(2 downto 0) is
|
||||
when "000" | "001" => -- ADD, ADC
|
||||
Q_t := Q_v;
|
||||
F_Out(Flag_C) <= Carry_v;
|
||||
F_Out(Flag_H) <= HalfCarry_v;
|
||||
F_Out(Flag_P) <= OverFlow_v;
|
||||
when "010" | "011" | "111" => -- SUB, SBC, CP
|
||||
Q_t := Q_v;
|
||||
F_Out(Flag_N) <= '1';
|
||||
F_Out(Flag_C) <= not Carry_v;
|
||||
F_Out(Flag_H) <= not HalfCarry_v;
|
||||
F_Out(Flag_P) <= OverFlow_v;
|
||||
when "100" => -- AND
|
||||
Q_t(7 downto 0) := BusA and BusB;
|
||||
F_Out(Flag_H) <= '1';
|
||||
when "101" => -- XOR
|
||||
Q_t(7 downto 0) := BusA xor BusB;
|
||||
F_Out(Flag_H) <= '0';
|
||||
when others => -- OR "110"
|
||||
Q_t(7 downto 0) := BusA or BusB;
|
||||
F_Out(Flag_H) <= '0';
|
||||
end case;
|
||||
if ALU_Op(2 downto 0) = "111" then -- CP
|
||||
F_Out(Flag_X) <= BusB(3);
|
||||
F_Out(Flag_Y) <= BusB(5);
|
||||
else
|
||||
F_Out(Flag_X) <= Q_t(3);
|
||||
F_Out(Flag_Y) <= Q_t(5);
|
||||
end if;
|
||||
if Q_t(7 downto 0) = "00000000" then
|
||||
F_Out(Flag_Z) <= '1';
|
||||
if Z16 = '1' then
|
||||
F_Out(Flag_Z) <= F_In(Flag_Z); -- 16 bit ADC,SBC
|
||||
end if;
|
||||
else
|
||||
F_Out(Flag_Z) <= '0';
|
||||
end if;
|
||||
F_Out(Flag_S) <= Q_t(7);
|
||||
case ALU_Op(2 downto 0) is
|
||||
when "000" | "001" | "010" | "011" | "111" => -- ADD, ADC, SUB, SBC, CP
|
||||
when others =>
|
||||
F_Out(Flag_P) <= not (Q_t(0) xor Q_t(1) xor Q_t(2) xor Q_t(3) xor
|
||||
Q_t(4) xor Q_t(5) xor Q_t(6) xor Q_t(7));
|
||||
end case;
|
||||
if Arith16 = '1' then
|
||||
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 if;
|
||||
when "1100" =>
|
||||
-- DAA
|
||||
F_Out(Flag_H) <= F_In(Flag_H);
|
||||
F_Out(Flag_C) <= F_In(Flag_C);
|
||||
DAA_Q(7 downto 0) := unsigned(BusA);
|
||||
DAA_Q(8) := '0';
|
||||
if F_In(Flag_N) = '0' then
|
||||
-- After addition
|
||||
-- Alow > 9 or H = 1
|
||||
if DAA_Q(3 downto 0) > 9 or F_In(Flag_H) = '1' then
|
||||
if (DAA_Q(3 downto 0) > 9) then
|
||||
F_Out(Flag_H) <= '1';
|
||||
else
|
||||
F_Out(Flag_H) <= '0';
|
||||
end if;
|
||||
DAA_Q := DAA_Q + 6;
|
||||
end if;
|
||||
-- new Ahigh > 9 or C = 1
|
||||
if DAA_Q(8 downto 4) > 9 or F_In(Flag_C) = '1' then
|
||||
DAA_Q := DAA_Q + 96; -- 0x60
|
||||
end if;
|
||||
else
|
||||
-- After subtraction
|
||||
if DAA_Q(3 downto 0) > 9 or F_In(Flag_H) = '1' then
|
||||
if DAA_Q(3 downto 0) > 5 then
|
||||
F_Out(Flag_H) <= '0';
|
||||
end if;
|
||||
DAA_Q(7 downto 0) := DAA_Q(7 downto 0) - 6;
|
||||
end if;
|
||||
if unsigned(BusA) > 153 or F_In(Flag_C) = '1' then
|
||||
DAA_Q := DAA_Q - 352; -- 0x160
|
||||
end if;
|
||||
end if;
|
||||
F_Out(Flag_X) <= DAA_Q(3);
|
||||
F_Out(Flag_Y) <= DAA_Q(5);
|
||||
F_Out(Flag_C) <= F_In(Flag_C) or DAA_Q(8);
|
||||
Q_t := std_logic_vector(DAA_Q(7 downto 0));
|
||||
if DAA_Q(7 downto 0) = "00000000" then
|
||||
F_Out(Flag_Z) <= '1';
|
||||
else
|
||||
F_Out(Flag_Z) <= '0';
|
||||
end if;
|
||||
F_Out(Flag_S) <= DAA_Q(7);
|
||||
F_Out(Flag_P) <= not (DAA_Q(0) xor DAA_Q(1) xor DAA_Q(2) xor DAA_Q(3) xor
|
||||
DAA_Q(4) xor DAA_Q(5) xor DAA_Q(6) xor DAA_Q(7));
|
||||
when "1101" | "1110" =>
|
||||
-- RLD, RRD
|
||||
Q_t(7 downto 4) := BusA(7 downto 4);
|
||||
if ALU_Op(0) = '1' then
|
||||
Q_t(3 downto 0) := BusB(7 downto 4);
|
||||
else
|
||||
Q_t(3 downto 0) := BusB(3 downto 0);
|
||||
end if;
|
||||
F_Out(Flag_H) <= '0';
|
||||
F_Out(Flag_N) <= '0';
|
||||
F_Out(Flag_X) <= Q_t(3);
|
||||
F_Out(Flag_Y) <= Q_t(5);
|
||||
if Q_t(7 downto 0) = "00000000" then
|
||||
F_Out(Flag_Z) <= '1';
|
||||
else
|
||||
F_Out(Flag_Z) <= '0';
|
||||
end if;
|
||||
F_Out(Flag_S) <= Q_t(7);
|
||||
F_Out(Flag_P) <= not (Q_t(0) xor Q_t(1) xor Q_t(2) xor Q_t(3) xor
|
||||
Q_t(4) xor Q_t(5) xor Q_t(6) xor Q_t(7));
|
||||
when "1001" =>
|
||||
-- BIT
|
||||
Q_t(7 downto 0) := BusB and BitMask;
|
||||
F_Out(Flag_S) <= Q_t(7);
|
||||
if Q_t(7 downto 0) = "00000000" then
|
||||
F_Out(Flag_Z) <= '1';
|
||||
F_Out(Flag_P) <= '1';
|
||||
else
|
||||
F_Out(Flag_Z) <= '0';
|
||||
F_Out(Flag_P) <= '0';
|
||||
end if;
|
||||
F_Out(Flag_H) <= '1';
|
||||
F_Out(Flag_N) <= '0';
|
||||
F_Out(Flag_X) <= '0';
|
||||
F_Out(Flag_Y) <= '0';
|
||||
if IR(2 downto 0) /= "110" then
|
||||
F_Out(Flag_X) <= BusB(3);
|
||||
F_Out(Flag_Y) <= BusB(5);
|
||||
end if;
|
||||
when "1010" =>
|
||||
-- SET
|
||||
Q_t(7 downto 0) := BusB or BitMask;
|
||||
when "1011" =>
|
||||
-- RES
|
||||
Q_t(7 downto 0) := BusB and not BitMask;
|
||||
when "1000" =>
|
||||
-- ROT
|
||||
case IR(5 downto 3) is
|
||||
when "000" => -- RLC
|
||||
Q_t(7 downto 1) := BusA(6 downto 0);
|
||||
Q_t(0) := BusA(7);
|
||||
F_Out(Flag_C) <= BusA(7);
|
||||
when "010" => -- RL
|
||||
Q_t(7 downto 1) := BusA(6 downto 0);
|
||||
Q_t(0) := F_In(Flag_C);
|
||||
F_Out(Flag_C) <= BusA(7);
|
||||
when "001" => -- RRC
|
||||
Q_t(6 downto 0) := BusA(7 downto 1);
|
||||
Q_t(7) := BusA(0);
|
||||
F_Out(Flag_C) <= BusA(0);
|
||||
when "011" => -- RR
|
||||
Q_t(6 downto 0) := BusA(7 downto 1);
|
||||
Q_t(7) := F_In(Flag_C);
|
||||
F_Out(Flag_C) <= BusA(0);
|
||||
when "100" => -- SLA
|
||||
Q_t(7 downto 1) := BusA(6 downto 0);
|
||||
Q_t(0) := '0';
|
||||
F_Out(Flag_C) <= BusA(7);
|
||||
when "110" => -- SLL (Undocumented) / SWAP
|
||||
if Mode = 3 then
|
||||
Q_t(7 downto 4) := BusA(3 downto 0);
|
||||
Q_t(3 downto 0) := BusA(7 downto 4);
|
||||
F_Out(Flag_C) <= '0';
|
||||
else
|
||||
Q_t(7 downto 1) := BusA(6 downto 0);
|
||||
Q_t(0) := '1';
|
||||
F_Out(Flag_C) <= BusA(7);
|
||||
end if;
|
||||
when "101" => -- SRA
|
||||
Q_t(6 downto 0) := BusA(7 downto 1);
|
||||
Q_t(7) := BusA(7);
|
||||
F_Out(Flag_C) <= BusA(0);
|
||||
when others => -- SRL
|
||||
Q_t(6 downto 0) := BusA(7 downto 1);
|
||||
Q_t(7) := '0';
|
||||
F_Out(Flag_C) <= BusA(0);
|
||||
end case;
|
||||
F_Out(Flag_H) <= '0';
|
||||
F_Out(Flag_N) <= '0';
|
||||
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 downto 0) = "00000000" then
|
||||
F_Out(Flag_Z) <= '1';
|
||||
else
|
||||
F_Out(Flag_Z) <= '0';
|
||||
end if;
|
||||
F_Out(Flag_P) <= not (Q_t(0) xor Q_t(1) xor Q_t(2) xor Q_t(3) xor
|
||||
Q_t(4) xor Q_t(5) xor Q_t(6) xor Q_t(7));
|
||||
if ISet = "00" then
|
||||
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 if;
|
||||
when others =>
|
||||
null;
|
||||
end case;
|
||||
Q <= Q_t;
|
||||
end process;
|
||||
|
||||
end;
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,208 +0,0 @@
|
||||
--
|
||||
-- Z80 compatible microprocessor core
|
||||
--
|
||||
-- Version : 0242
|
||||
--
|
||||
-- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org)
|
||||
--
|
||||
-- All rights reserved
|
||||
--
|
||||
-- Redistribution and use in source and synthezised forms, with or without
|
||||
-- modification, are permitted provided that the following conditions are met:
|
||||
--
|
||||
-- Redistributions of source code must retain the above copyright notice,
|
||||
-- this list of conditions and the following disclaimer.
|
||||
--
|
||||
-- Redistributions in synthesized form must reproduce the above copyright
|
||||
-- notice, this list of conditions and the following disclaimer in the
|
||||
-- documentation and/or other materials provided with the distribution.
|
||||
--
|
||||
-- Neither the name of the author nor the names of other contributors may
|
||||
-- be used to endorse or promote products derived from this software without
|
||||
-- specific prior written permission.
|
||||
--
|
||||
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
|
||||
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
-- POSSIBILITY OF SUCH DAMAGE.
|
||||
--
|
||||
-- Please report bugs to the author, but before you do so, please
|
||||
-- make sure that this is not a derivative work and that
|
||||
-- you have the latest version of this file.
|
||||
--
|
||||
-- The latest version of this file can be found at:
|
||||
-- http://www.opencores.org/cvsweb.shtml/t80/
|
||||
--
|
||||
-- Limitations :
|
||||
--
|
||||
-- File history :
|
||||
--
|
||||
|
||||
library IEEE;
|
||||
use IEEE.std_logic_1164.all;
|
||||
|
||||
package T80_Pack is
|
||||
|
||||
component T80
|
||||
generic(
|
||||
Mode : integer := 0; -- 0 => Z80, 1 => Fast Z80, 2 => 8080, 3 => GB
|
||||
IOWait : integer := 0; -- 1 => Single cycle I/O, 1 => Std I/O cycle
|
||||
Flag_C : integer := 0;
|
||||
Flag_N : integer := 1;
|
||||
Flag_P : integer := 2;
|
||||
Flag_X : integer := 3;
|
||||
Flag_H : integer := 4;
|
||||
Flag_Y : integer := 5;
|
||||
Flag_Z : integer := 6;
|
||||
Flag_S : integer := 7
|
||||
);
|
||||
port(
|
||||
RESET_n : in std_logic;
|
||||
CLK_n : in std_logic;
|
||||
CEN : in std_logic;
|
||||
WAIT_n : in std_logic;
|
||||
INT_n : in std_logic;
|
||||
NMI_n : in std_logic;
|
||||
BUSRQ_n : in std_logic;
|
||||
M1_n : out std_logic;
|
||||
IORQ : out std_logic;
|
||||
NoRead : out std_logic;
|
||||
Write : out std_logic;
|
||||
RFSH_n : out std_logic;
|
||||
HALT_n : out std_logic;
|
||||
BUSAK_n : out std_logic;
|
||||
A : out std_logic_vector(15 downto 0);
|
||||
DInst : in std_logic_vector(7 downto 0);
|
||||
DI : in std_logic_vector(7 downto 0);
|
||||
DO : out std_logic_vector(7 downto 0);
|
||||
MC : out std_logic_vector(2 downto 0);
|
||||
TS : out std_logic_vector(2 downto 0);
|
||||
IntCycle_n : out std_logic;
|
||||
IntE : out std_logic;
|
||||
Stop : out std_logic
|
||||
);
|
||||
end component;
|
||||
|
||||
component T80_Reg
|
||||
port(
|
||||
Clk : in std_logic;
|
||||
CEN : in std_logic;
|
||||
WEH : in std_logic;
|
||||
WEL : in std_logic;
|
||||
AddrA : in std_logic_vector(2 downto 0);
|
||||
AddrB : in std_logic_vector(2 downto 0);
|
||||
AddrC : in std_logic_vector(2 downto 0);
|
||||
DIH : in std_logic_vector(7 downto 0);
|
||||
DIL : in std_logic_vector(7 downto 0);
|
||||
DOAH : out std_logic_vector(7 downto 0);
|
||||
DOAL : out std_logic_vector(7 downto 0);
|
||||
DOBH : out std_logic_vector(7 downto 0);
|
||||
DOBL : out std_logic_vector(7 downto 0);
|
||||
DOCH : out std_logic_vector(7 downto 0);
|
||||
DOCL : out std_logic_vector(7 downto 0)
|
||||
);
|
||||
end component;
|
||||
|
||||
component T80_MCode
|
||||
generic(
|
||||
Mode : integer := 0;
|
||||
Flag_C : integer := 0;
|
||||
Flag_N : integer := 1;
|
||||
Flag_P : integer := 2;
|
||||
Flag_X : integer := 3;
|
||||
Flag_H : integer := 4;
|
||||
Flag_Y : integer := 5;
|
||||
Flag_Z : integer := 6;
|
||||
Flag_S : integer := 7
|
||||
);
|
||||
port(
|
||||
IR : in std_logic_vector(7 downto 0);
|
||||
ISet : in std_logic_vector(1 downto 0);
|
||||
MCycle : in std_logic_vector(2 downto 0);
|
||||
F : in std_logic_vector(7 downto 0);
|
||||
NMICycle : in std_logic;
|
||||
IntCycle : in std_logic;
|
||||
MCycles : out std_logic_vector(2 downto 0);
|
||||
TStates : out std_logic_vector(2 downto 0);
|
||||
Prefix : out std_logic_vector(1 downto 0); -- None,BC,ED,DD/FD
|
||||
Inc_PC : out std_logic;
|
||||
Inc_WZ : out std_logic;
|
||||
IncDec_16 : out std_logic_vector(3 downto 0); -- BC,DE,HL,SP 0 is inc
|
||||
Read_To_Reg : out std_logic;
|
||||
Read_To_Acc : out std_logic;
|
||||
Set_BusA_To : out std_logic_vector(3 downto 0); -- B,C,D,E,H,L,DI/DB,A,SP(L),SP(M),0,F
|
||||
Set_BusB_To : out std_logic_vector(3 downto 0); -- B,C,D,E,H,L,DI,A,SP(L),SP(M),1,F,PC(L),PC(M),0
|
||||
ALU_Op : out std_logic_vector(3 downto 0);
|
||||
-- ADD, ADC, SUB, SBC, AND, XOR, OR, CP, ROT, BIT, SET, RES, DAA, RLD, RRD, None
|
||||
Save_ALU : out std_logic;
|
||||
PreserveC : out std_logic;
|
||||
Arith16 : out std_logic;
|
||||
Set_Addr_To : out std_logic_vector(2 downto 0); -- aNone,aXY,aIOA,aSP,aBC,aDE,aZI
|
||||
IORQ : out std_logic;
|
||||
Jump : out std_logic;
|
||||
JumpE : out std_logic;
|
||||
JumpXY : out std_logic;
|
||||
Call : out std_logic;
|
||||
RstP : out std_logic;
|
||||
LDZ : out std_logic;
|
||||
LDW : out std_logic;
|
||||
LDSPHL : out std_logic;
|
||||
Special_LD : out std_logic_vector(2 downto 0); -- A,I;A,R;I,A;R,A;None
|
||||
ExchangeDH : out std_logic;
|
||||
ExchangeRp : out std_logic;
|
||||
ExchangeAF : out std_logic;
|
||||
ExchangeRS : out std_logic;
|
||||
I_DJNZ : out std_logic;
|
||||
I_CPL : out std_logic;
|
||||
I_CCF : out std_logic;
|
||||
I_SCF : out std_logic;
|
||||
I_RETN : out std_logic;
|
||||
I_BT : out std_logic;
|
||||
I_BC : out std_logic;
|
||||
I_BTR : out std_logic;
|
||||
I_RLD : out std_logic;
|
||||
I_RRD : out std_logic;
|
||||
I_INRC : out std_logic;
|
||||
SetDI : out std_logic;
|
||||
SetEI : out std_logic;
|
||||
IMode : out std_logic_vector(1 downto 0);
|
||||
Halt : out std_logic;
|
||||
NoRead : out std_logic;
|
||||
Write : out std_logic
|
||||
);
|
||||
end component;
|
||||
|
||||
component T80_ALU
|
||||
generic(
|
||||
Mode : integer := 0;
|
||||
Flag_C : integer := 0;
|
||||
Flag_N : integer := 1;
|
||||
Flag_P : integer := 2;
|
||||
Flag_X : integer := 3;
|
||||
Flag_H : integer := 4;
|
||||
Flag_Y : integer := 5;
|
||||
Flag_Z : integer := 6;
|
||||
Flag_S : integer := 7
|
||||
);
|
||||
port(
|
||||
Arith16 : in std_logic;
|
||||
Z16 : in std_logic;
|
||||
ALU_Op : in std_logic_vector(3 downto 0);
|
||||
IR : in std_logic_vector(5 downto 0);
|
||||
ISet : in std_logic_vector(1 downto 0);
|
||||
BusA : in std_logic_vector(7 downto 0);
|
||||
BusB : in std_logic_vector(7 downto 0);
|
||||
F_In : in std_logic_vector(7 downto 0);
|
||||
Q : out std_logic_vector(7 downto 0);
|
||||
F_Out : out std_logic_vector(7 downto 0)
|
||||
);
|
||||
end component;
|
||||
|
||||
end;
|
||||
@ -1,105 +0,0 @@
|
||||
--
|
||||
-- T80 Registers, technology independent
|
||||
--
|
||||
-- Version : 0244
|
||||
--
|
||||
-- Copyright (c) 2002 Daniel Wallner (jesus@opencores.org)
|
||||
--
|
||||
-- All rights reserved
|
||||
--
|
||||
-- Redistribution and use in source and synthezised forms, with or without
|
||||
-- modification, are permitted provided that the following conditions are met:
|
||||
--
|
||||
-- Redistributions of source code must retain the above copyright notice,
|
||||
-- this list of conditions and the following disclaimer.
|
||||
--
|
||||
-- Redistributions in synthesized form must reproduce the above copyright
|
||||
-- notice, this list of conditions and the following disclaimer in the
|
||||
-- documentation and/or other materials provided with the distribution.
|
||||
--
|
||||
-- Neither the name of the author nor the names of other contributors may
|
||||
-- be used to endorse or promote products derived from this software without
|
||||
-- specific prior written permission.
|
||||
--
|
||||
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
|
||||
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
-- POSSIBILITY OF SUCH DAMAGE.
|
||||
--
|
||||
-- Please report bugs to the author, but before you do so, please
|
||||
-- make sure that this is not a derivative work and that
|
||||
-- you have the latest version of this file.
|
||||
--
|
||||
-- The latest version of this file can be found at:
|
||||
-- http://www.opencores.org/cvsweb.shtml/t51/
|
||||
--
|
||||
-- Limitations :
|
||||
--
|
||||
-- File history :
|
||||
--
|
||||
-- 0242 : Initial release
|
||||
--
|
||||
-- 0244 : Changed to single register file
|
||||
--
|
||||
|
||||
library IEEE;
|
||||
use IEEE.std_logic_1164.all;
|
||||
use IEEE.numeric_std.all;
|
||||
|
||||
entity T80_Reg is
|
||||
port(
|
||||
Clk : in std_logic;
|
||||
CEN : in std_logic;
|
||||
WEH : in std_logic;
|
||||
WEL : in std_logic;
|
||||
AddrA : in std_logic_vector(2 downto 0);
|
||||
AddrB : in std_logic_vector(2 downto 0);
|
||||
AddrC : in std_logic_vector(2 downto 0);
|
||||
DIH : in std_logic_vector(7 downto 0);
|
||||
DIL : in std_logic_vector(7 downto 0);
|
||||
DOAH : out std_logic_vector(7 downto 0);
|
||||
DOAL : out std_logic_vector(7 downto 0);
|
||||
DOBH : out std_logic_vector(7 downto 0);
|
||||
DOBL : out std_logic_vector(7 downto 0);
|
||||
DOCH : out std_logic_vector(7 downto 0);
|
||||
DOCL : out std_logic_vector(7 downto 0)
|
||||
);
|
||||
end T80_Reg;
|
||||
|
||||
architecture rtl of T80_Reg is
|
||||
|
||||
type Register_Image is array (natural range <>) of std_logic_vector(7 downto 0);
|
||||
signal RegsH : Register_Image(0 to 7);
|
||||
signal RegsL : Register_Image(0 to 7);
|
||||
|
||||
begin
|
||||
|
||||
process (Clk)
|
||||
begin
|
||||
if Clk'event and Clk = '1' then
|
||||
if CEN = '1' then
|
||||
if WEH = '1' then
|
||||
RegsH(to_integer(unsigned(AddrA))) <= DIH;
|
||||
end if;
|
||||
if WEL = '1' then
|
||||
RegsL(to_integer(unsigned(AddrA))) <= DIL;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
DOAH <= RegsH(to_integer(unsigned(AddrA)));
|
||||
DOAL <= RegsL(to_integer(unsigned(AddrA)));
|
||||
DOBH <= RegsH(to_integer(unsigned(AddrB)));
|
||||
DOBL <= RegsL(to_integer(unsigned(AddrB)));
|
||||
DOCH <= RegsH(to_integer(unsigned(AddrC)));
|
||||
DOCL <= RegsL(to_integer(unsigned(AddrC)));
|
||||
|
||||
end;
|
||||
@ -1,184 +0,0 @@
|
||||
--
|
||||
-- Z80 compatible microprocessor core, synchronous top level with clock enable
|
||||
-- Different timing than the original z80
|
||||
-- Inputs needs to be synchronous and outputs may glitch
|
||||
--
|
||||
-- Version : 0242
|
||||
--
|
||||
-- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org)
|
||||
--
|
||||
-- All rights reserved
|
||||
--
|
||||
-- Redistribution and use in source and synthezised forms, with or without
|
||||
-- modification, are permitted provided that the following conditions are met:
|
||||
--
|
||||
-- Redistributions of source code must retain the above copyright notice,
|
||||
-- this list of conditions and the following disclaimer.
|
||||
--
|
||||
-- Redistributions in synthesized form must reproduce the above copyright
|
||||
-- notice, this list of conditions and the following disclaimer in the
|
||||
-- documentation and/or other materials provided with the distribution.
|
||||
--
|
||||
-- Neither the name of the author nor the names of other contributors may
|
||||
-- be used to endorse or promote products derived from this software without
|
||||
-- specific prior written permission.
|
||||
--
|
||||
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
|
||||
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
-- POSSIBILITY OF SUCH DAMAGE.
|
||||
--
|
||||
-- Please report bugs to the author, but before you do so, please
|
||||
-- make sure that this is not a derivative work and that
|
||||
-- you have the latest version of this file.
|
||||
--
|
||||
-- The latest version of this file can be found at:
|
||||
-- http://www.opencores.org/cvsweb.shtml/t80/
|
||||
--
|
||||
-- Limitations :
|
||||
--
|
||||
-- File history :
|
||||
--
|
||||
-- 0235 : First release
|
||||
--
|
||||
-- 0236 : Added T2Write generic
|
||||
--
|
||||
-- 0237 : Fixed T2Write with wait state
|
||||
--
|
||||
-- 0238 : Updated for T80 interface change
|
||||
--
|
||||
-- 0240 : Updated for T80 interface change
|
||||
--
|
||||
-- 0242 : Updated for T80 interface change
|
||||
--
|
||||
|
||||
library IEEE;
|
||||
use IEEE.std_logic_1164.all;
|
||||
use IEEE.numeric_std.all;
|
||||
use work.T80_Pack.all;
|
||||
|
||||
entity T80se is
|
||||
generic(
|
||||
Mode : integer := 0; -- 0 => Z80, 1 => Fast Z80, 2 => 8080, 3 => GB
|
||||
T2Write : integer := 0; -- 0 => WR_n active in T3, /=0 => WR_n active in T2
|
||||
IOWait : integer := 1 -- 0 => Single cycle I/O, 1 => Std I/O cycle
|
||||
);
|
||||
port(
|
||||
RESET_n : in std_logic;
|
||||
CLK_n : in std_logic;
|
||||
CLKEN : in std_logic;
|
||||
WAIT_n : in std_logic;
|
||||
INT_n : in std_logic;
|
||||
NMI_n : in std_logic;
|
||||
BUSRQ_n : in std_logic;
|
||||
M1_n : out std_logic;
|
||||
MREQ_n : out std_logic;
|
||||
IORQ_n : out std_logic;
|
||||
RD_n : out std_logic;
|
||||
WR_n : out std_logic;
|
||||
RFSH_n : out std_logic;
|
||||
HALT_n : out std_logic;
|
||||
BUSAK_n : out std_logic;
|
||||
A : out std_logic_vector(15 downto 0);
|
||||
DI : in std_logic_vector(7 downto 0);
|
||||
DO : out std_logic_vector(7 downto 0)
|
||||
);
|
||||
end T80se;
|
||||
|
||||
architecture rtl of T80se is
|
||||
|
||||
signal IntCycle_n : std_logic;
|
||||
signal NoRead : std_logic;
|
||||
signal Write : std_logic;
|
||||
signal IORQ : std_logic;
|
||||
signal DI_Reg : std_logic_vector(7 downto 0);
|
||||
signal MCycle : std_logic_vector(2 downto 0);
|
||||
signal TState : std_logic_vector(2 downto 0);
|
||||
|
||||
begin
|
||||
|
||||
u0 : T80
|
||||
generic map(
|
||||
Mode => Mode,
|
||||
IOWait => IOWait)
|
||||
port map(
|
||||
CEN => CLKEN,
|
||||
M1_n => M1_n,
|
||||
IORQ => IORQ,
|
||||
NoRead => NoRead,
|
||||
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_n => CLK_n,
|
||||
A => A,
|
||||
DInst => DI,
|
||||
DI => DI_Reg,
|
||||
DO => DO,
|
||||
MC => MCycle,
|
||||
TS => TState,
|
||||
IntCycle_n => IntCycle_n);
|
||||
|
||||
process (RESET_n, CLK_n)
|
||||
begin
|
||||
if RESET_n = '0' then
|
||||
RD_n <= '1';
|
||||
WR_n <= '1';
|
||||
IORQ_n <= '1';
|
||||
MREQ_n <= '1';
|
||||
DI_Reg <= "00000000";
|
||||
elsif CLK_n'event and CLK_n = '1' then
|
||||
if CLKEN = '1' then
|
||||
RD_n <= '1';
|
||||
WR_n <= '1';
|
||||
IORQ_n <= '1';
|
||||
MREQ_n <= '1';
|
||||
if MCycle = "001" then
|
||||
if TState = "001" or (TState = "010" and Wait_n = '0') then
|
||||
RD_n <= not IntCycle_n;
|
||||
MREQ_n <= not IntCycle_n;
|
||||
IORQ_n <= IntCycle_n;
|
||||
end if;
|
||||
if TState = "011" then
|
||||
MREQ_n <= '0';
|
||||
end if;
|
||||
else
|
||||
if (TState = "001" or (TState = "010" and Wait_n = '0')) and NoRead = '0' and Write = '0' then
|
||||
RD_n <= '0';
|
||||
IORQ_n <= not IORQ;
|
||||
MREQ_n <= IORQ;
|
||||
end if;
|
||||
if T2Write = 0 then
|
||||
if TState = "010" and Write = '1' then
|
||||
WR_n <= '0';
|
||||
IORQ_n <= not IORQ;
|
||||
MREQ_n <= IORQ;
|
||||
end if;
|
||||
else
|
||||
if (TState = "001" or (TState = "010" and Wait_n = '0')) and Write = '1' then
|
||||
WR_n <= '0';
|
||||
IORQ_n <= not IORQ;
|
||||
MREQ_n <= IORQ;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
if TState = "010" and Wait_n = '1' then
|
||||
DI_Reg <= DI;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
end;
|
||||
@ -23,9 +23,9 @@ localparam CONF_STR = {
|
||||
"Galaga;;",
|
||||
"O2,Rotate Controls,Off,On;",
|
||||
"O34,Scanlines,Off,25%,50%,75%;",
|
||||
// "O34,Scandoubler Fx,None,HQ2x,CRT 25%,CRT 50%;",
|
||||
"O5,Blend,Off,On;",
|
||||
"T6,Reset;",
|
||||
"V,v1.20.",`BUILD_DATE
|
||||
"V,v1.21.",`BUILD_DATE
|
||||
};
|
||||
|
||||
assign LED = 1;
|
||||
@ -37,7 +37,6 @@ pll pll(
|
||||
.c0(clk_18)
|
||||
);
|
||||
|
||||
|
||||
wire [31:0] status;
|
||||
wire [1:0] buttons;
|
||||
wire [1:0] switches;
|
||||
@ -83,7 +82,7 @@ mist_video #(.COLOR_DEPTH(3), .SD_HCNT_WIDTH(10)) mist_video(
|
||||
.SPI_DI(SPI_DI),
|
||||
.R(blankn ? r : 0),
|
||||
.G(blankn ? g : 0),
|
||||
.B(blankn ? {b, b[1]} : 0),
|
||||
.B(blankn ? {b[0], b} : 0),
|
||||
.HSync(hs),
|
||||
.VSync(vs),
|
||||
.VGA_R(VGA_R),
|
||||
@ -92,6 +91,7 @@ mist_video #(.COLOR_DEPTH(3), .SD_HCNT_WIDTH(10)) mist_video(
|
||||
.VGA_VS(VGA_VS),
|
||||
.VGA_HS(VGA_HS),
|
||||
.ce_divider(1'b1),
|
||||
.blend(status[5]),
|
||||
.rotate({1'b1,status[2]}),
|
||||
.scanlines(scandoublerD ? 2'b00 : status[4:3]),
|
||||
.scandoubler_disable(scandoublerD),
|
||||
|
||||
@ -1,4 +0,0 @@
|
||||
set_global_assignment -name IP_TOOL_NAME "ALTPLL"
|
||||
set_global_assignment -name IP_TOOL_VERSION "13.1"
|
||||
set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) "pll.v"]
|
||||
set_global_assignment -name MISC_FILE [file join $::quartus(qip_path) "pll.ppf"]
|
||||
@ -144,16 +144,15 @@ set_global_assignment -name OUTPUT_IO_TIMING_FAR_END_VMEAS "HALF SIGNAL SWING" -
|
||||
|
||||
# Incremental Compilation Assignments
|
||||
# ===================================
|
||||
set_global_assignment -name PARTITION_NETLIST_TYPE SOURCE -section_id Top
|
||||
set_global_assignment -name PARTITION_FITTER_PRESERVATION_LEVEL PLACEMENT_AND_ROUTING -section_id Top
|
||||
set_global_assignment -name PARTITION_COLOR 16764057 -section_id Top
|
||||
set_global_assignment -name PARTITION_NETLIST_TYPE SOURCE -section_id Top
|
||||
set_global_assignment -name PARTITION_FITTER_PRESERVATION_LEVEL PLACEMENT_AND_ROUTING -section_id Top
|
||||
set_global_assignment -name PARTITION_COLOR 16764057 -section_id Top
|
||||
|
||||
# end DESIGN_PARTITION(Top)
|
||||
# -------------------------
|
||||
|
||||
# end ENTITY(dkong_MiST)
|
||||
# ----------------------
|
||||
set_global_assignment -name QIP_FILE ../../../common/mist/mist.qip
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE rtl/dkong_MiST.sv
|
||||
set_global_assignment -name VERILOG_FILE rtl/dkong_top.v
|
||||
set_global_assignment -name VERILOG_FILE rtl/i8035ip.v
|
||||
@ -211,4 +210,5 @@ set_global_assignment -name VHDL_FILE "rtl/t48_ip/alu_pack-p.vhd"
|
||||
set_global_assignment -name VHDL_FILE rtl/t48_ip/alu.vhd
|
||||
set_global_assignment -name VERILOG_FILE rtl/pll.v
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE rtl/dkong_soundboard.sv
|
||||
set_global_assignment -name QIP_FILE ../../../common/mist/mist.qip
|
||||
set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top
|
||||
Binary file not shown.
@ -404,7 +404,6 @@ set_global_assignment -name VHDL_FILE rtl/phoenix_effect3.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/phoenix_effect2.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/phoenix_effect1.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/phoenix_video.vhd
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE rtl/ym2149.sv
|
||||
set_global_assignment -name VHDL_FILE rtl/ROM/survival_prog.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/ROM/prom_palette_ic41.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/ROM/prom_palette_ic40.vhd
|
||||
@ -416,4 +415,5 @@ set_global_assignment -name VHDL_FILE rtl/gen_ram.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/pll.vhd
|
||||
set_global_assignment -name QIP_FILE ../../../common/CPU/T80/T80.qip
|
||||
set_global_assignment -name QIP_FILE ../../../common/mist/mist.qip
|
||||
set_global_assignment -name VHDL_FILE rtl/YM2149_linmix_sep.vhd
|
||||
set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top
|
||||
@ -41,14 +41,14 @@ localparam CONF_STR = {
|
||||
assign LED = 1;
|
||||
assign AUDIO_R = AUDIO_L;
|
||||
|
||||
wire clk_sys, clk_28, clk_1p79;
|
||||
wire clk_sys, clk_28, clk_ay;
|
||||
wire pll_locked;
|
||||
pll pll(
|
||||
.inclk0(CLOCK_27),
|
||||
.areset(0),
|
||||
.c0(clk_sys),//11
|
||||
.c1(clk_28),//28
|
||||
.c2(clk_1p79)//1.79
|
||||
.c2(clk_ay)//2.75
|
||||
);
|
||||
|
||||
wire [31:0] status;
|
||||
@ -69,7 +69,7 @@ wire [1:0] r,g,b;
|
||||
phoenix phoenix(
|
||||
.clk(clk_sys),
|
||||
.clk_28(clk_28),
|
||||
.clk_1p79(clk_1p79),
|
||||
.clk_ay(clk_ay),
|
||||
.reset(status[0] | status[6] | buttons[1]),
|
||||
.dip_switch(8'b00001111),
|
||||
.btn_coin(btn_coin),
|
||||
|
||||
@ -0,0 +1,553 @@
|
||||
-- changes for seperate audio outputs and enable now enables cpu access as well
|
||||
--
|
||||
-- A simulation model of YM2149 (AY-3-8910 with bells on)
|
||||
|
||||
-- Copyright (c) MikeJ - Jan 2005
|
||||
--
|
||||
-- All rights reserved
|
||||
--
|
||||
-- Redistribution and use in source and synthezised forms, with or without
|
||||
-- modification, are permitted provided that the following conditions are met:
|
||||
--
|
||||
-- Redistributions of source code must retain the above copyright notice,
|
||||
-- this list of conditions and the following disclaimer.
|
||||
--
|
||||
-- Redistributions in synthesized form must reproduce the above copyright
|
||||
-- notice, this list of conditions and the following disclaimer in the
|
||||
-- documentation and/or other materials provided with the distribution.
|
||||
--
|
||||
-- Neither the name of the author nor the names of other contributors may
|
||||
-- be used to endorse or promote products derived from this software without
|
||||
-- specific prior written permission.
|
||||
--
|
||||
-- THIS CODE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
|
||||
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
-- POSSIBILITY OF SUCH DAMAGE.
|
||||
--
|
||||
-- You are responsible for any legal issues arising from your use of this code.
|
||||
--
|
||||
-- The latest version of this file can be found at: www.fpgaarcade.com
|
||||
--
|
||||
-- Email support@fpgaarcade.com
|
||||
--
|
||||
-- Revision list
|
||||
--
|
||||
-- version 001 initial release
|
||||
--
|
||||
-- Clues from MAME sound driver and Kazuhiro TSUJIKAWA
|
||||
--
|
||||
-- These are the measured outputs from a real chip for a single Isolated channel into a 1K load (V)
|
||||
-- vol 15 .. 0
|
||||
-- 3.27 2.995 2.741 2.588 2.452 2.372 2.301 2.258 2.220 2.198 2.178 2.166 2.155 2.148 2.141 2.132
|
||||
-- As the envelope volume is 5 bit, I have fitted a curve to the not quite log shape in order
|
||||
-- to produced all the required values.
|
||||
-- (The first part of the curve is a bit steeper and the last bit is more linear than expected)
|
||||
--
|
||||
-- NOTE, this component uses LINEAR mixing of the three analogue channels, and is only
|
||||
-- accurate for designs where the outputs are buffered and not simply wired together.
|
||||
-- The ouput level is more complex in that case and requires a larger table.
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.std_logic_arith.all;
|
||||
use ieee.std_logic_unsigned.all;
|
||||
|
||||
entity YM2149 is
|
||||
port (
|
||||
-- data bus
|
||||
I_DA : in std_logic_vector(7 downto 0);
|
||||
O_DA : out std_logic_vector(7 downto 0);
|
||||
O_DA_OE_L : out std_logic;
|
||||
-- control
|
||||
I_A9_L : in std_logic;
|
||||
I_A8 : in std_logic;
|
||||
I_BDIR : in std_logic;
|
||||
I_BC2 : in std_logic;
|
||||
I_BC1 : in std_logic;
|
||||
I_SEL_L : in std_logic;
|
||||
|
||||
O_AUDIO : out std_logic_vector(7 downto 0);
|
||||
O_CHAN : out std_logic_vector(1 downto 0);
|
||||
-- port a
|
||||
I_IOA : in std_logic_vector(7 downto 0);
|
||||
O_IOA : out std_logic_vector(7 downto 0);
|
||||
O_IOA_OE_L : out std_logic;
|
||||
-- port b
|
||||
I_IOB : in std_logic_vector(7 downto 0);
|
||||
O_IOB : out std_logic_vector(7 downto 0);
|
||||
O_IOB_OE_L : out std_logic;
|
||||
|
||||
ENA : in std_logic; -- clock enable for higher speed operation
|
||||
RESET_L : in std_logic;
|
||||
CLK : in std_logic -- note 6 Mhz
|
||||
);
|
||||
end;
|
||||
|
||||
architecture RTL of YM2149 is
|
||||
type array_16x8 is array (0 to 15) of std_logic_vector( 7 downto 0);
|
||||
type array_3x12 is array (1 to 3) of std_logic_vector(11 downto 0);
|
||||
|
||||
signal cnt_div : std_logic_vector(3 downto 0) := (others => '0');
|
||||
signal cnt_div_t1 : std_logic_vector(3 downto 0);
|
||||
signal noise_div : std_logic := '0';
|
||||
signal ena_div : std_logic;
|
||||
signal ena_div_noise : std_logic;
|
||||
signal poly17 : std_logic_vector(16 downto 0) := (others => '0');
|
||||
|
||||
-- registers
|
||||
signal addr : std_logic_vector(7 downto 0);
|
||||
signal busctrl_addr : std_logic;
|
||||
signal busctrl_we : std_logic;
|
||||
signal busctrl_re : std_logic;
|
||||
|
||||
signal reg : array_16x8;
|
||||
signal env_reset : std_logic;
|
||||
signal ioa_inreg : std_logic_vector(7 downto 0);
|
||||
signal iob_inreg : std_logic_vector(7 downto 0);
|
||||
|
||||
signal noise_gen_cnt : std_logic_vector(4 downto 0);
|
||||
signal noise_gen_op : std_logic;
|
||||
signal tone_gen_cnt : array_3x12 := (others => (others => '0'));
|
||||
signal tone_gen_op : std_logic_vector(3 downto 1) := "000";
|
||||
|
||||
signal env_gen_cnt : std_logic_vector(15 downto 0);
|
||||
signal env_ena : std_logic;
|
||||
signal env_hold : std_logic;
|
||||
signal env_inc : std_logic;
|
||||
signal env_vol : std_logic_vector(4 downto 0);
|
||||
|
||||
signal tone_ena_l : std_logic;
|
||||
signal tone_src : std_logic;
|
||||
signal noise_ena_l : std_logic;
|
||||
signal chan_vol : std_logic_vector(4 downto 0);
|
||||
|
||||
signal dac_amp : std_logic_vector(7 downto 0);
|
||||
begin
|
||||
-- cpu i/f
|
||||
p_busdecode : process(I_BDIR, I_BC2, I_BC1, addr, I_A9_L, I_A8)
|
||||
variable cs : std_logic;
|
||||
variable sel : std_logic_vector(2 downto 0);
|
||||
begin
|
||||
-- BDIR BC2 BC1 MODE
|
||||
-- 0 0 0 inactive
|
||||
-- 0 0 1 address
|
||||
-- 0 1 0 inactive
|
||||
-- 0 1 1 read
|
||||
-- 1 0 0 address
|
||||
-- 1 0 1 inactive
|
||||
-- 1 1 0 write
|
||||
-- 1 1 1 read
|
||||
busctrl_addr <= '0';
|
||||
busctrl_we <= '0';
|
||||
busctrl_re <= '0';
|
||||
|
||||
cs := '0';
|
||||
if (I_A9_L = '0') and (I_A8 = '1') and (addr(7 downto 4) = "0000") then
|
||||
cs := '1';
|
||||
end if;
|
||||
|
||||
sel := (I_BDIR & I_BC2 & I_BC1);
|
||||
case sel is
|
||||
when "000" => null;
|
||||
when "001" => busctrl_addr <= '1';
|
||||
when "010" => null;
|
||||
when "011" => busctrl_re <= cs;
|
||||
when "100" => busctrl_addr <= '1';
|
||||
when "101" => null;
|
||||
when "110" => busctrl_we <= cs;
|
||||
when "111" => busctrl_addr <= '1';
|
||||
when others => null;
|
||||
end case;
|
||||
end process;
|
||||
|
||||
p_oe : process(busctrl_re)
|
||||
begin
|
||||
-- if we are emulating a real chip, maybe clock this to fake up the tristate typ delay of 100ns
|
||||
O_DA_OE_L <= not (busctrl_re);
|
||||
end process;
|
||||
|
||||
--
|
||||
-- CLOCKED
|
||||
--
|
||||
p_waddr : process(RESET_L, CLK)
|
||||
begin
|
||||
-- looks like registers are latches in real chip, but the address is caught at the end of the address state.
|
||||
if (RESET_L = '0') then
|
||||
addr <= (others => '0');
|
||||
elsif rising_edge(CLK) then
|
||||
if (ENA = '1') then
|
||||
if (busctrl_addr = '1') then
|
||||
addr <= I_DA;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
p_wdata : process(RESET_L, CLK)
|
||||
begin
|
||||
if (RESET_L = '0') then
|
||||
reg <= (others => (others => '0'));
|
||||
env_reset <= '1';
|
||||
elsif rising_edge(CLK) then
|
||||
if (ENA = '1') then
|
||||
env_reset <= '0';
|
||||
if (busctrl_we = '1') then
|
||||
case addr(3 downto 0) is
|
||||
when x"0" => reg(0) <= I_DA;
|
||||
when x"1" => reg(1) <= I_DA;
|
||||
when x"2" => reg(2) <= I_DA;
|
||||
when x"3" => reg(3) <= I_DA;
|
||||
when x"4" => reg(4) <= I_DA;
|
||||
when x"5" => reg(5) <= I_DA;
|
||||
when x"6" => reg(6) <= I_DA;
|
||||
when x"7" => reg(7) <= I_DA;
|
||||
when x"8" => reg(8) <= I_DA;
|
||||
when x"9" => reg(9) <= I_DA;
|
||||
when x"A" => reg(10) <= I_DA;
|
||||
when x"B" => reg(11) <= I_DA;
|
||||
when x"C" => reg(12) <= I_DA;
|
||||
when x"D" => reg(13) <= I_DA; env_reset <= '1';
|
||||
when x"E" => reg(14) <= I_DA;
|
||||
when x"F" => reg(15) <= I_DA;
|
||||
when others => null;
|
||||
end case;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
p_rdata : process(busctrl_re, addr, reg, ioa_inreg, iob_inreg)
|
||||
begin
|
||||
O_DA <= (others => '0'); -- 'X'
|
||||
if (busctrl_re = '1') then -- not necessary, but useful for putting 'X's in the simulator
|
||||
case addr(3 downto 0) is
|
||||
when x"0" => O_DA <= reg(0) ;
|
||||
when x"1" => O_DA <= "0000" & reg(1)(3 downto 0) ;
|
||||
when x"2" => O_DA <= reg(2) ;
|
||||
when x"3" => O_DA <= "0000" & reg(3)(3 downto 0) ;
|
||||
when x"4" => O_DA <= reg(4) ;
|
||||
when x"5" => O_DA <= "0000" & reg(5)(3 downto 0) ;
|
||||
when x"6" => O_DA <= "000" & reg(6)(4 downto 0) ;
|
||||
when x"7" => O_DA <= reg(7) ;
|
||||
when x"8" => O_DA <= "000" & reg(8)(4 downto 0) ;
|
||||
when x"9" => O_DA <= "000" & reg(9)(4 downto 0) ;
|
||||
when x"A" => O_DA <= "000" & reg(10)(4 downto 0) ;
|
||||
when x"B" => O_DA <= reg(11);
|
||||
when x"C" => O_DA <= reg(12);
|
||||
when x"D" => O_DA <= "0000" & reg(13)(3 downto 0);
|
||||
when x"E" => if (reg(7)(6) = '0') then -- input
|
||||
O_DA <= ioa_inreg;
|
||||
else
|
||||
O_DA <= reg(14); -- read output reg
|
||||
end if;
|
||||
when x"F" => if (Reg(7)(7) = '0') then
|
||||
O_DA <= iob_inreg;
|
||||
else
|
||||
O_DA <= reg(15);
|
||||
end if;
|
||||
when others => null;
|
||||
end case;
|
||||
end if;
|
||||
end process;
|
||||
--
|
||||
p_divider : process
|
||||
begin
|
||||
wait until rising_edge(CLK);
|
||||
-- / 8 when SEL is high and /16 when SEL is low
|
||||
if (ENA = '1') then
|
||||
ena_div <= '0';
|
||||
ena_div_noise <= '0';
|
||||
if (cnt_div = "0000") then
|
||||
cnt_div <= (not I_SEL_L) & "111";
|
||||
ena_div <= '1';
|
||||
|
||||
noise_div <= not noise_div;
|
||||
if (noise_div = '1') then
|
||||
ena_div_noise <= '1';
|
||||
end if;
|
||||
else
|
||||
cnt_div <= cnt_div - "1";
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
p_noise_gen : process
|
||||
variable noise_gen_comp : std_logic_vector(4 downto 0);
|
||||
variable poly17_zero : std_logic;
|
||||
begin
|
||||
wait until rising_edge(CLK);
|
||||
if (reg(6)(4 downto 0) = "00000") then
|
||||
noise_gen_comp := "00000";
|
||||
else
|
||||
noise_gen_comp := (reg(6)(4 downto 0) - "1");
|
||||
end if;
|
||||
|
||||
poly17_zero := '0';
|
||||
if (poly17 = "00000000000000000") then poly17_zero := '1'; end if;
|
||||
|
||||
if (ENA = '1') then
|
||||
if (ena_div_noise = '1') then -- divider ena
|
||||
|
||||
if (noise_gen_cnt >= noise_gen_comp) then
|
||||
noise_gen_cnt <= "00000";
|
||||
poly17 <= (poly17(0) xor poly17(2) xor poly17_zero) & poly17(16 downto 1);
|
||||
else
|
||||
noise_gen_cnt <= (noise_gen_cnt + "1");
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
noise_gen_op <= poly17(0);
|
||||
|
||||
p_tone_gens : process
|
||||
variable tone_gen_freq : array_3x12;
|
||||
variable tone_gen_comp : array_3x12;
|
||||
begin
|
||||
wait until rising_edge(CLK);
|
||||
-- looks like real chips count up - we need to get the Exact behaviour ..
|
||||
tone_gen_freq(1) := reg(1)(3 downto 0) & reg(0);
|
||||
tone_gen_freq(2) := reg(3)(3 downto 0) & reg(2);
|
||||
tone_gen_freq(3) := reg(5)(3 downto 0) & reg(4);
|
||||
-- period 0 = period 1
|
||||
for i in 1 to 3 loop
|
||||
if (tone_gen_freq(i) = x"000") then
|
||||
tone_gen_comp(i) := x"000";
|
||||
else
|
||||
tone_gen_comp(i) := (tone_gen_freq(i) - "1");
|
||||
end if;
|
||||
end loop;
|
||||
|
||||
if (ENA = '1') then
|
||||
for i in 1 to 3 loop
|
||||
if (ena_div = '1') then -- divider ena
|
||||
|
||||
if (tone_gen_cnt(i) >= tone_gen_comp(i)) then
|
||||
tone_gen_cnt(i) <= x"000";
|
||||
tone_gen_op(i) <= not tone_gen_op(i);
|
||||
else
|
||||
tone_gen_cnt(i) <= (tone_gen_cnt(i) + "1");
|
||||
end if;
|
||||
end if;
|
||||
end loop;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
p_envelope_freq : process
|
||||
variable env_gen_freq : std_logic_vector(15 downto 0);
|
||||
variable env_gen_comp : std_logic_vector(15 downto 0);
|
||||
begin
|
||||
wait until rising_edge(CLK);
|
||||
env_gen_freq := reg(12) & reg(11);
|
||||
-- envelope freqs 1 and 0 are the same.
|
||||
if (env_gen_freq = x"0000") then
|
||||
env_gen_comp := x"0000";
|
||||
else
|
||||
env_gen_comp := (env_gen_freq - "1");
|
||||
end if;
|
||||
|
||||
if (ENA = '1') then
|
||||
env_ena <= '0';
|
||||
if (ena_div = '1') then -- divider ena
|
||||
if (env_gen_cnt >= env_gen_comp) then
|
||||
env_gen_cnt <= x"0000";
|
||||
env_ena <= '1';
|
||||
else
|
||||
env_gen_cnt <= (env_gen_cnt + "1");
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
p_envelope_shape : process(env_reset, reg, CLK)
|
||||
variable is_bot : boolean;
|
||||
variable is_bot_p1 : boolean;
|
||||
variable is_top_m1 : boolean;
|
||||
variable is_top : boolean;
|
||||
begin
|
||||
if (env_reset = '1') then
|
||||
-- load initial state
|
||||
if (reg(13)(2) = '0') then -- attack
|
||||
env_vol <= "11111";
|
||||
env_inc <= '0'; -- -1
|
||||
else
|
||||
env_vol <= "00000";
|
||||
env_inc <= '1'; -- +1
|
||||
end if;
|
||||
env_hold <= '0';
|
||||
|
||||
elsif rising_edge(CLK) then
|
||||
is_bot := (env_vol = "00000");
|
||||
is_bot_p1 := (env_vol = "00001");
|
||||
is_top_m1 := (env_vol = "11110");
|
||||
is_top := (env_vol = "11111");
|
||||
|
||||
if (ENA = '1') then
|
||||
if (env_ena = '1') then
|
||||
if (env_hold = '0') then
|
||||
if (env_inc = '1') then
|
||||
env_vol <= (env_vol + "00001");
|
||||
else
|
||||
env_vol <= (env_vol + "11111");
|
||||
end if;
|
||||
end if;
|
||||
|
||||
-- envelope shape control.
|
||||
if (reg(13)(3) = '0') then
|
||||
if (env_inc = '0') then -- down
|
||||
if is_bot_p1 then env_hold <= '1'; end if;
|
||||
else
|
||||
if is_top then env_hold <= '1'; end if;
|
||||
end if;
|
||||
else
|
||||
if (reg(13)(0) = '1') then -- hold = 1
|
||||
if (env_inc = '0') then -- down
|
||||
if (reg(13)(1) = '1') then -- alt
|
||||
if is_bot then env_hold <= '1'; end if;
|
||||
else
|
||||
if is_bot_p1 then env_hold <= '1'; end if;
|
||||
end if;
|
||||
else
|
||||
if (reg(13)(1) = '1') then -- alt
|
||||
if is_top then env_hold <= '1'; end if;
|
||||
else
|
||||
if is_top_m1 then env_hold <= '1'; end if;
|
||||
end if;
|
||||
end if;
|
||||
|
||||
elsif (reg(13)(1) = '1') then -- alternate
|
||||
if (env_inc = '0') then -- down
|
||||
if is_bot_p1 then env_hold <= '1'; end if;
|
||||
if is_bot then env_hold <= '0'; env_inc <= '1'; end if;
|
||||
else
|
||||
if is_top_m1 then env_hold <= '1'; end if;
|
||||
if is_top then env_hold <= '0'; env_inc <= '0'; end if;
|
||||
end if;
|
||||
end if;
|
||||
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
p_chan_mixer : process(cnt_div, reg, tone_gen_op)
|
||||
begin
|
||||
tone_ena_l <= '1'; tone_src <= '1';
|
||||
noise_ena_l <= '1'; chan_vol <= "00000";
|
||||
case cnt_div(1 downto 0) is
|
||||
when "00" =>
|
||||
tone_ena_l <= reg(7)(0); tone_src <= tone_gen_op(1); chan_vol <= reg(8)(4 downto 0);
|
||||
noise_ena_l <= reg(7)(3);
|
||||
when "01" =>
|
||||
tone_ena_l <= reg(7)(1); tone_src <= tone_gen_op(2); chan_vol <= reg(9)(4 downto 0);
|
||||
noise_ena_l <= reg(7)(4);
|
||||
when "10" =>
|
||||
tone_ena_l <= reg(7)(2); tone_src <= tone_gen_op(3); chan_vol <= reg(10)(4 downto 0);
|
||||
noise_ena_l <= reg(7)(5);
|
||||
when "11" => null; -- tone gen outputs become valid on this clock
|
||||
when others => null;
|
||||
end case;
|
||||
end process;
|
||||
|
||||
p_op_mixer : process
|
||||
variable chan_mixed : std_logic;
|
||||
variable chan_amp : std_logic_vector(4 downto 0);
|
||||
begin
|
||||
wait until rising_edge(CLK);
|
||||
if (ENA = '1') then
|
||||
|
||||
chan_mixed := (tone_ena_l or tone_src) and (noise_ena_l or noise_gen_op);
|
||||
|
||||
chan_amp := (others => '0');
|
||||
if (chan_mixed = '1') then
|
||||
if (chan_vol(4) = '0') then
|
||||
if (chan_vol(3 downto 0) = "0000") then -- nothing is easy ! make sure quiet is quiet
|
||||
chan_amp := "00000";
|
||||
else
|
||||
chan_amp := chan_vol(3 downto 0) & '1'; -- make sure level 31 (env) = level 15 (tone)
|
||||
end if;
|
||||
else
|
||||
chan_amp := env_vol(4 downto 0);
|
||||
end if;
|
||||
end if;
|
||||
|
||||
dac_amp <= x"00";
|
||||
case chan_amp is
|
||||
when "11111" => dac_amp <= x"FF";
|
||||
when "11110" => dac_amp <= x"D9";
|
||||
when "11101" => dac_amp <= x"BA";
|
||||
when "11100" => dac_amp <= x"9F";
|
||||
when "11011" => dac_amp <= x"88";
|
||||
when "11010" => dac_amp <= x"74";
|
||||
when "11001" => dac_amp <= x"63";
|
||||
when "11000" => dac_amp <= x"54";
|
||||
when "10111" => dac_amp <= x"48";
|
||||
when "10110" => dac_amp <= x"3D";
|
||||
when "10101" => dac_amp <= x"34";
|
||||
when "10100" => dac_amp <= x"2C";
|
||||
when "10011" => dac_amp <= x"25";
|
||||
when "10010" => dac_amp <= x"1F";
|
||||
when "10001" => dac_amp <= x"1A";
|
||||
when "10000" => dac_amp <= x"16";
|
||||
when "01111" => dac_amp <= x"13";
|
||||
when "01110" => dac_amp <= x"10";
|
||||
when "01101" => dac_amp <= x"0D";
|
||||
when "01100" => dac_amp <= x"0B";
|
||||
when "01011" => dac_amp <= x"09";
|
||||
when "01010" => dac_amp <= x"08";
|
||||
when "01001" => dac_amp <= x"07";
|
||||
when "01000" => dac_amp <= x"06";
|
||||
when "00111" => dac_amp <= x"05";
|
||||
when "00110" => dac_amp <= x"04";
|
||||
when "00101" => dac_amp <= x"03";
|
||||
when "00100" => dac_amp <= x"03";
|
||||
when "00011" => dac_amp <= x"02";
|
||||
when "00010" => dac_amp <= x"02";
|
||||
when "00001" => dac_amp <= x"01";
|
||||
when "00000" => dac_amp <= x"00";
|
||||
when others => null;
|
||||
end case;
|
||||
|
||||
cnt_div_t1 <= cnt_div;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
p_audio_output : process(RESET_L, CLK)
|
||||
begin
|
||||
if (RESET_L = '0') then
|
||||
O_AUDIO <= (others => '0');
|
||||
O_CHAN <= (others => '0');
|
||||
elsif rising_edge(CLK) then
|
||||
|
||||
if (ENA = '1') then
|
||||
O_AUDIO <= dac_amp(7 downto 0);
|
||||
O_CHAN <= cnt_div_t1(1 downto 0);
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
p_io_ports : process(reg)
|
||||
begin
|
||||
O_IOA <= reg(14);
|
||||
O_IOA_OE_L <= not reg(7)(6);
|
||||
O_IOB <= reg(15);
|
||||
O_IOB_OE_L <= not reg(7)(7);
|
||||
end process;
|
||||
|
||||
p_io_ports_inreg : process
|
||||
begin
|
||||
wait until rising_edge(CLK);
|
||||
if (ENA = '1') then -- resync
|
||||
ioa_inreg <= I_IOA;
|
||||
iob_inreg <= I_IOB;
|
||||
end if;
|
||||
end process;
|
||||
end architecture RTL;
|
||||
@ -20,10 +20,9 @@ generic (
|
||||
port(
|
||||
clk : in std_logic; -- 11 MHz for TV, 25 MHz for VGA
|
||||
clk_28 : in std_logic;
|
||||
clk_1p79 : in std_logic;
|
||||
clk_ay : in std_logic;
|
||||
reset : in std_logic;
|
||||
ce_pix : out std_logic;
|
||||
|
||||
dip_switch : in std_logic_vector(7 downto 0);
|
||||
-- game controls, normal logic '1':pressed, '0':released
|
||||
|
||||
@ -125,33 +124,14 @@ architecture struct of phoenix is
|
||||
signal player_start : std_logic_vector(1 downto 0);
|
||||
signal buttons : std_logic_vector(3 downto 0);
|
||||
signal R_autofire : std_logic_vector(21 downto 0);
|
||||
signal ay_do : std_logic_vector( 7 downto 0) := (others =>'0');
|
||||
signal protection : std_logic_vector( 7 downto 0) := (others =>'0');
|
||||
signal chanA : std_logic_vector( 7 downto 0) := (others =>'0');
|
||||
signal chanB : std_logic_vector( 7 downto 0) := (others =>'0');
|
||||
signal chanC : std_logic_vector( 7 downto 0) := (others =>'0');
|
||||
|
||||
COMPONENT ym2149
|
||||
PORT
|
||||
(
|
||||
CLK : IN STD_LOGIC;
|
||||
CE : IN STD_LOGIC;
|
||||
RESET : IN STD_LOGIC;
|
||||
BDIR : IN STD_LOGIC;
|
||||
BC : IN STD_LOGIC;
|
||||
DI : IN STD_LOGIC_VECTOR(7 DOWNTO 0);
|
||||
DO : OUT STD_LOGIC_VECTOR(7 DOWNTO 0);
|
||||
CHANNEL_A : OUT STD_LOGIC_VECTOR(7 DOWNTO 0);
|
||||
CHANNEL_B : OUT STD_LOGIC_VECTOR(7 DOWNTO 0);
|
||||
CHANNEL_C : OUT STD_LOGIC_VECTOR(7 DOWNTO 0);
|
||||
SEL : IN STD_LOGIC;
|
||||
MODE : IN STD_LOGIC;
|
||||
IOA_in : IN STD_LOGIC_VECTOR(7 DOWNTO 0);
|
||||
IOA_out : OUT STD_LOGIC_VECTOR(7 DOWNTO 0);
|
||||
IOB_in : IN STD_LOGIC_VECTOR(7 DOWNTO 0);
|
||||
IOB_out : OUT STD_LOGIC_VECTOR(7 DOWNTO 0)
|
||||
);
|
||||
END COMPONENT;
|
||||
signal psg_cs : std_logic;
|
||||
signal ay_ena : std_logic;
|
||||
signal ay_do : std_logic_vector( 7 downto 0) := (others =>'0');
|
||||
signal ay_iob_do : std_logic_vector(7 downto 0);
|
||||
signal ay_ioa_di : std_logic_vector(7 downto 0);
|
||||
signal ay_bdir : std_logic;
|
||||
signal ay_bc1 : std_logic;
|
||||
|
||||
begin
|
||||
|
||||
@ -401,28 +381,43 @@ port map(
|
||||
q => bkgnd_ram_do
|
||||
);
|
||||
|
||||
-- bdir bc1 (bc2 = 1)
|
||||
-- 0 0 : Inactive
|
||||
-- 0 1 : Read
|
||||
-- 1 0 : Write
|
||||
-- 1 1 : Address
|
||||
--ay_ioa_di <= not sw2(to_integer(unsigned(ay_iob_do(3 downto 1)))) & "000" & not sw1;
|
||||
|
||||
music: YM2149
|
||||
port map(
|
||||
-- data bus
|
||||
DI => cpu_do,
|
||||
DO => open,--?
|
||||
BDIR => cpu_wr_n,--?
|
||||
BC => cpu_adr(0),--?
|
||||
SEL => '0',--?
|
||||
MODE => '1',--AY8910
|
||||
CHANNEL_A => chanA,
|
||||
CHANNEL_B => chanB,
|
||||
CHANNEL_C => chanC,
|
||||
IOA_in => (others => '0'),
|
||||
IOA_out => open,
|
||||
IOB_in => (others => '0'),
|
||||
IOB_out => ay_do,--protection
|
||||
CE => clk_1p79,--2.75
|
||||
RESET => not reset_n,
|
||||
CLK => clk
|
||||
);
|
||||
ay_bdir <= '1' when cpu_wr_n = '0' else '0';
|
||||
ay_bc1 <= '1' when ((cpu_wr_n = '1' and cpu_adr(0) = '0')) else '0';
|
||||
psg_cs <= '1' when cpu_adr(15 downto 10) = "110100" else '0';--110100000000000
|
||||
ym2149 : entity work.ym2149 --110100100000000
|
||||
port map (
|
||||
-- data bus
|
||||
I_DA => cpu_do, --: in std_logic_vector(7 downto 0);
|
||||
O_DA => ay_do, --: out std_logic_vector(7 downto 0);
|
||||
O_DA_OE_L => open, --: out std_logic;
|
||||
-- control
|
||||
I_A9_L => '1', --: in std_logic;
|
||||
I_A8 => '1', --: in std_logic;
|
||||
I_BDIR => ay_bdir, --: in std_logic;
|
||||
I_BC2 => '1', --: in std_logic;
|
||||
I_BC1 => ay_bc1, --: in std_logic;
|
||||
I_SEL_L => '1', --: in std_logic;
|
||||
-- audio
|
||||
O_AUDIO => audio, --: out std_logic_vector(7 downto 0);
|
||||
-- port a
|
||||
I_IOA => ay_ioa_di, --: in std_logic_vector(7 downto 0);
|
||||
O_IOA => open, --: out std_logic_vector(7 downto 0);
|
||||
O_IOA_OE_L => open, --: out std_logic;
|
||||
-- port b
|
||||
I_IOB => "11111111", --: in std_logic_vector(7 downto 0);
|
||||
O_IOB => ay_iob_do, --: out std_logic_vector(7 downto 0);
|
||||
O_IOB_OE_L => open, --: out std_logic;
|
||||
|
||||
audio <= chanA + chanB + chanC;
|
||||
ENA => '1', --: in std_logic; -- clock enable for higher speed operation
|
||||
RESET_L => '1', --: in std_logic;
|
||||
CLK => clk_ay
|
||||
);
|
||||
|
||||
end struct;
|
||||
|
||||
@ -167,7 +167,7 @@ BEGIN
|
||||
clk1_duty_cycle => 50,
|
||||
clk1_multiply_by => 57,
|
||||
clk1_phase_shift => "0",
|
||||
clk2_divide_by => 860,
|
||||
clk2_divide_by => 560,
|
||||
clk2_duty_cycle => 50,
|
||||
clk2_multiply_by => 57,
|
||||
clk2_phase_shift => "0",
|
||||
@ -256,7 +256,7 @@ END SYN;
|
||||
-- Retrieval info: PRIVATE: DEVICE_SPEED_GRADE STRING "8"
|
||||
-- Retrieval info: PRIVATE: DIV_FACTOR0 NUMERIC "140"
|
||||
-- Retrieval info: PRIVATE: DIV_FACTOR1 NUMERIC "55"
|
||||
-- Retrieval info: PRIVATE: DIV_FACTOR2 NUMERIC "860"
|
||||
-- Retrieval info: PRIVATE: DIV_FACTOR2 NUMERIC "560"
|
||||
-- Retrieval info: PRIVATE: DIV_FACTOR3 NUMERIC "35"
|
||||
-- Retrieval info: PRIVATE: DUTY_CYCLE0 STRING "50.00000000"
|
||||
-- Retrieval info: PRIVATE: DUTY_CYCLE1 STRING "50.00000000"
|
||||
@ -264,7 +264,7 @@ END SYN;
|
||||
-- Retrieval info: PRIVATE: DUTY_CYCLE3 STRING "50.00000000"
|
||||
-- Retrieval info: PRIVATE: EFF_OUTPUT_FREQ_VALUE0 STRING "10.992857"
|
||||
-- Retrieval info: PRIVATE: EFF_OUTPUT_FREQ_VALUE1 STRING "27.981817"
|
||||
-- Retrieval info: PRIVATE: EFF_OUTPUT_FREQ_VALUE2 STRING "1.789535"
|
||||
-- Retrieval info: PRIVATE: EFF_OUTPUT_FREQ_VALUE2 STRING "2.748214"
|
||||
-- Retrieval info: PRIVATE: EFF_OUTPUT_FREQ_VALUE3 STRING "43.971428"
|
||||
-- Retrieval info: PRIVATE: EXPLICIT_SWITCHOVER_COUNTER STRING "0"
|
||||
-- Retrieval info: PRIVATE: EXT_FEEDBACK_RADIO STRING "0"
|
||||
@ -301,7 +301,7 @@ END SYN;
|
||||
-- Retrieval info: PRIVATE: NORMAL_MODE_RADIO STRING "1"
|
||||
-- Retrieval info: PRIVATE: OUTPUT_FREQ0 STRING "11.00000000"
|
||||
-- Retrieval info: PRIVATE: OUTPUT_FREQ1 STRING "28.00000000"
|
||||
-- Retrieval info: PRIVATE: OUTPUT_FREQ2 STRING "1.79000000"
|
||||
-- Retrieval info: PRIVATE: OUTPUT_FREQ2 STRING "2.75000000"
|
||||
-- Retrieval info: PRIVATE: OUTPUT_FREQ3 STRING "44.00000000"
|
||||
-- Retrieval info: PRIVATE: OUTPUT_FREQ_MODE0 STRING "0"
|
||||
-- Retrieval info: PRIVATE: OUTPUT_FREQ_MODE1 STRING "0"
|
||||
@ -370,7 +370,7 @@ END SYN;
|
||||
-- Retrieval info: CONSTANT: CLK1_DUTY_CYCLE NUMERIC "50"
|
||||
-- Retrieval info: CONSTANT: CLK1_MULTIPLY_BY NUMERIC "57"
|
||||
-- Retrieval info: CONSTANT: CLK1_PHASE_SHIFT STRING "0"
|
||||
-- Retrieval info: CONSTANT: CLK2_DIVIDE_BY NUMERIC "860"
|
||||
-- Retrieval info: CONSTANT: CLK2_DIVIDE_BY NUMERIC "560"
|
||||
-- Retrieval info: CONSTANT: CLK2_DUTY_CYCLE NUMERIC "50"
|
||||
-- Retrieval info: CONSTANT: CLK2_MULTIPLY_BY NUMERIC "57"
|
||||
-- Retrieval info: CONSTANT: CLK2_PHASE_SHIFT STRING "0"
|
||||
|
||||
@ -1,293 +0,0 @@
|
||||
module ym2149
|
||||
(
|
||||
input CLK, // Global clock
|
||||
input CE, // PSG Clock enable
|
||||
input RESET, // Chip RESET (set all Registers to '0', active hi)
|
||||
input BDIR, // Bus Direction (0 - read , 1 - write)
|
||||
input BC, // Bus control
|
||||
input [7:0] DI, // Data In
|
||||
output [7:0] DO, // Data Out
|
||||
output [7:0] CHANNEL_A, // PSG Output channel A
|
||||
output [7:0] CHANNEL_B, // PSG Output channel B
|
||||
output [7:0] CHANNEL_C, // PSG Output channel C
|
||||
|
||||
input SEL,
|
||||
input MODE,
|
||||
|
||||
input [7:0] IOA_in,
|
||||
output [7:0] IOA_out,
|
||||
|
||||
input [7:0] IOB_in,
|
||||
output [7:0] IOB_out
|
||||
);
|
||||
|
||||
assign IOA_out = ymreg[14];
|
||||
assign IOB_out = ymreg[15];
|
||||
|
||||
reg ena_div;
|
||||
reg ena_div_noise;
|
||||
reg [3:0] addr;
|
||||
reg [7:0] ymreg[16];
|
||||
reg env_ena;
|
||||
reg [4:0] env_vol;
|
||||
|
||||
wire [7:0] volTableAy[16] =
|
||||
'{8'h00, 8'h03, 8'h04, 8'h06,
|
||||
8'h0a, 8'h0f, 8'h15, 8'h22,
|
||||
8'h28, 8'h41, 8'h5b, 8'h72,
|
||||
8'h90, 8'hb5, 8'hd7, 8'hff
|
||||
};
|
||||
|
||||
wire [7:0] volTableYm[32] =
|
||||
'{8'h00, 8'h01, 8'h01, 8'h02,
|
||||
8'h02, 8'h03, 8'h03, 8'h04,
|
||||
8'h06, 8'h07, 8'h09, 8'h0a,
|
||||
8'h0c, 8'h0e, 8'h11, 8'h13,
|
||||
8'h17, 8'h1b, 8'h20, 8'h25,
|
||||
8'h2c, 8'h35, 8'h3e, 8'h47,
|
||||
8'h54, 8'h66, 8'h77, 8'h88,
|
||||
8'ha1, 8'hc0, 8'he0, 8'hff
|
||||
};
|
||||
|
||||
// Read from AY
|
||||
assign DO = dout;
|
||||
reg [7:0] dout;
|
||||
always_comb begin
|
||||
case(addr)
|
||||
0: dout = ymreg[0];
|
||||
1: dout = {4'b0000, ymreg[1][3:0]};
|
||||
2: dout = ymreg[2];
|
||||
3: dout = {4'b0000, ymreg[3][3:0]};
|
||||
4: dout = ymreg[4];
|
||||
5: dout = {4'b0000, ymreg[5][3:0]};
|
||||
6: dout = {3'b000, ymreg[6][4:0]};
|
||||
7: dout = ymreg[7];
|
||||
8: dout = {3'b000, ymreg[8][4:0]};
|
||||
9: dout = {3'b000, ymreg[9][4:0]};
|
||||
10: dout = {3'b000, ymreg[10][4:0]};
|
||||
11: dout = ymreg[11];
|
||||
12: dout = ymreg[12];
|
||||
13: dout = {4'b0000, ymreg[13][3:0]};
|
||||
14: dout = (ymreg[7][6] ? ymreg[14] : IOA_in);
|
||||
15: dout = (ymreg[7][7] ? ymreg[15] : IOB_in);
|
||||
endcase
|
||||
end
|
||||
|
||||
// p_divider
|
||||
always @(posedge CLK) begin
|
||||
reg [3:0] cnt_div;
|
||||
reg noise_div;
|
||||
|
||||
if(CE) begin
|
||||
ena_div <= 0;
|
||||
ena_div_noise <= 0;
|
||||
if(!cnt_div) begin
|
||||
cnt_div <= {SEL, 3'b111};
|
||||
ena_div <= 1;
|
||||
|
||||
noise_div <= (~noise_div);
|
||||
if (noise_div) ena_div_noise <= 1;
|
||||
end else begin
|
||||
cnt_div <= cnt_div - 1'b1;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
reg [16:0] poly17;
|
||||
wire [4:0] noise_gen_comp = ymreg[6][4:0] ? ymreg[6][4:0] - 1'd1 : 5'd0;
|
||||
|
||||
// p_noise_gen
|
||||
always @(posedge CLK) begin
|
||||
reg [4:0] noise_gen_cnt;
|
||||
|
||||
if(CE) begin
|
||||
if (ena_div_noise) begin
|
||||
if (noise_gen_cnt >= noise_gen_comp) begin
|
||||
noise_gen_cnt <= 0;
|
||||
poly17 <= {(poly17[0] ^ poly17[2] ^ !poly17), poly17[16:1]};
|
||||
end else begin
|
||||
noise_gen_cnt <= noise_gen_cnt + 1'd1;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
wire [11:0] tone_gen_freq[1:3];
|
||||
assign tone_gen_freq[1] = {ymreg[1][3:0], ymreg[0]};
|
||||
assign tone_gen_freq[2] = {ymreg[3][3:0], ymreg[2]};
|
||||
assign tone_gen_freq[3] = {ymreg[5][3:0], ymreg[4]};
|
||||
|
||||
wire [11:0] tone_gen_comp[1:3];
|
||||
assign tone_gen_comp[1] = tone_gen_freq[1] ? tone_gen_freq[1] - 1'd1 : 12'd0;
|
||||
assign tone_gen_comp[2] = tone_gen_freq[2] ? tone_gen_freq[2] - 1'd1 : 12'd0;
|
||||
assign tone_gen_comp[3] = tone_gen_freq[3] ? tone_gen_freq[3] - 1'd1 : 12'd0;
|
||||
|
||||
reg [3:1] tone_gen_op;
|
||||
|
||||
//p_tone_gens
|
||||
always @(posedge CLK) begin
|
||||
integer i;
|
||||
reg [11:0] tone_gen_cnt[1:3];
|
||||
|
||||
if(CE) begin
|
||||
// looks like real chips count up - we need to get the Exact behaviour ..
|
||||
|
||||
for (i = 1; i <= 3; i = i + 1) begin
|
||||
if(ena_div) begin
|
||||
if (tone_gen_cnt[i] >= tone_gen_comp[i]) begin
|
||||
tone_gen_cnt[i] <= 0;
|
||||
tone_gen_op[i] <= (~tone_gen_op[i]);
|
||||
end else begin
|
||||
tone_gen_cnt[i] <= tone_gen_cnt[i] + 1'd1;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
wire [15:0] env_gen_comp = {ymreg[12], ymreg[11]} ? {ymreg[12], ymreg[11]} - 1'd1 : 16'd0;
|
||||
|
||||
//p_envelope_freq
|
||||
always @(posedge CLK) begin
|
||||
reg [15:0] env_gen_cnt;
|
||||
|
||||
if(CE) begin
|
||||
env_ena <= 0;
|
||||
if(ena_div) begin
|
||||
if (env_gen_cnt >= env_gen_comp) begin
|
||||
env_gen_cnt <= 0;
|
||||
env_ena <= 1;
|
||||
end else begin
|
||||
env_gen_cnt <= (env_gen_cnt + 1'd1);
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
wire is_bot = (env_vol == 5'b00000);
|
||||
wire is_bot_p1 = (env_vol == 5'b00001);
|
||||
wire is_top_m1 = (env_vol == 5'b11110);
|
||||
wire is_top = (env_vol == 5'b11111);
|
||||
|
||||
always @(posedge CLK) begin
|
||||
reg old_BDIR;
|
||||
reg env_reset;
|
||||
reg env_hold;
|
||||
reg env_inc;
|
||||
|
||||
// envelope shapes
|
||||
// C AtAlH
|
||||
// 0 0 x x \___
|
||||
//
|
||||
// 0 1 x x /___
|
||||
//
|
||||
// 1 0 0 0 \\\\
|
||||
//
|
||||
// 1 0 0 1 \___
|
||||
//
|
||||
// 1 0 1 0 \/\/
|
||||
// ___
|
||||
// 1 0 1 1 \
|
||||
//
|
||||
// 1 1 0 0 ////
|
||||
// ___
|
||||
// 1 1 0 1 /
|
||||
//
|
||||
// 1 1 1 0 /\/\
|
||||
//
|
||||
// 1 1 1 1 /___
|
||||
|
||||
if(RESET) begin
|
||||
ymreg[0] <= 0;
|
||||
ymreg[1] <= 0;
|
||||
ymreg[2] <= 0;
|
||||
ymreg[3] <= 0;
|
||||
ymreg[4] <= 0;
|
||||
ymreg[5] <= 0;
|
||||
ymreg[6] <= 0;
|
||||
ymreg[7] <= 255;
|
||||
ymreg[8] <= 0;
|
||||
ymreg[9] <= 0;
|
||||
ymreg[10] <= 0;
|
||||
ymreg[11] <= 0;
|
||||
ymreg[12] <= 0;
|
||||
ymreg[13] <= 0;
|
||||
ymreg[14] <= 0;
|
||||
ymreg[15] <= 0;
|
||||
addr <= 0;
|
||||
env_vol <= 0;
|
||||
end else begin
|
||||
old_BDIR <= BDIR;
|
||||
if(~old_BDIR & BDIR) begin
|
||||
if(BC) addr <= DI[3:0];
|
||||
else begin
|
||||
ymreg[addr] <= DI;
|
||||
env_reset <= (addr == 13);
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if(CE) begin
|
||||
if(env_reset) begin
|
||||
env_reset <= 0;
|
||||
// load initial state
|
||||
if(!ymreg[13][2]) begin // attack
|
||||
env_vol <= 5'b11111;
|
||||
env_inc <= 0; // -1
|
||||
end else begin
|
||||
env_vol <= 5'b00000;
|
||||
env_inc <= 1; // +1
|
||||
end
|
||||
env_hold <= 0;
|
||||
end else begin
|
||||
|
||||
if (env_ena) begin
|
||||
if (!env_hold) begin
|
||||
if (env_inc) env_vol <= (env_vol + 5'b00001);
|
||||
else env_vol <= (env_vol + 5'b11111);
|
||||
end
|
||||
|
||||
// envelope shape control.
|
||||
if(!ymreg[13][3]) begin
|
||||
if(!env_inc) begin // down
|
||||
if(is_bot_p1) env_hold <= 1;
|
||||
end else if (is_top) env_hold <= 1;
|
||||
end else if(ymreg[13][0]) begin // hold = 1
|
||||
if(!env_inc) begin // down
|
||||
if(ymreg[13][1]) begin // alt
|
||||
if(is_bot) env_hold <= 1;
|
||||
end else if(is_bot_p1) env_hold <= 1;
|
||||
end else if(ymreg[13][1]) begin // alt
|
||||
if(is_top) env_hold <= 1;
|
||||
end else if(is_top_m1) env_hold <= 1;
|
||||
end else if(ymreg[13][1]) begin // alternate
|
||||
if(env_inc == 1'b0) begin // down
|
||||
if(is_bot_p1) env_hold <= 1;
|
||||
if(is_bot) begin
|
||||
env_hold <= 0;
|
||||
env_inc <= 1;
|
||||
end
|
||||
end else begin
|
||||
if(is_top_m1) env_hold <= 1;
|
||||
if(is_top) begin
|
||||
env_hold <= 0;
|
||||
env_inc <= 0;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
wire [4:0] A = ~((ymreg[7][0] | tone_gen_op[1]) & (ymreg[7][3] | poly17[0])) ? 5'd0 : ymreg[8][4] ? env_vol[4:0] : { ymreg[8][3:0], ymreg[8][3]};
|
||||
wire [4:0] B = ~((ymreg[7][1] | tone_gen_op[2]) & (ymreg[7][4] | poly17[0])) ? 5'd0 : ymreg[9][4] ? env_vol[4:0] : { ymreg[9][3:0], ymreg[9][3]};
|
||||
wire [4:0] C = ~((ymreg[7][2] | tone_gen_op[3]) & (ymreg[7][5] | poly17[0])) ? 5'd0 : ymreg[10][4] ? env_vol[4:0] : {ymreg[10][3:0], ymreg[10][3]};
|
||||
|
||||
assign CHANNEL_A = MODE ? volTableAy[A[4:1]] : volTableYm[A];
|
||||
assign CHANNEL_B = MODE ? volTableAy[B[4:1]] : volTableYm[B];
|
||||
assign CHANNEL_C = MODE ? volTableAy[C[4:1]] : volTableYm[C];
|
||||
|
||||
|
||||
endmodule
|
||||
@ -7,4 +7,4 @@ set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) T80_Reg.vh
|
||||
set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) T80_MCode.vhd ]
|
||||
set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) T80_ALU.vhd ]
|
||||
set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) T80.vhd ]
|
||||
set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) T80_Pack.vhd ]
|
||||
set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) T80_Pack.vhd ]
|
||||
6
common/CPU/tv80/TV80.qip
Normal file
6
common/CPU/tv80/TV80.qip
Normal file
@ -0,0 +1,6 @@
|
||||
set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) "tv80_core.v"]
|
||||
set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) "tv80_alu.v"]
|
||||
set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) "tv80_mcode.v"]
|
||||
set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) "tv80_reg.v"]
|
||||
set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) "tv80n.v"]
|
||||
set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) "tv80s.v"]
|
||||
Loading…
x
Reference in New Issue
Block a user