mirror of
https://github.com/Gehstock/Mist_FPGA.git
synced 2026-04-05 04:34:45 +00:00
Defender: multi-core conversion, Colony7, Jin, Mayday
This commit is contained in:
@@ -43,22 +43,8 @@ set_global_assignment -name PROJECT_CREATION_TIME_DATE "21:22:13 JUNE 04, 2019"
|
||||
set_global_assignment -name PROJECT_OUTPUT_DIRECTORY output_files
|
||||
set_global_assignment -name PRE_FLOW_SCRIPT_FILE "quartus_sh:rtl/build_id.tcl"
|
||||
set_global_assignment -name ORIGINAL_QUARTUS_VERSION 13.1
|
||||
set_global_assignment -name LAST_QUARTUS_VERSION 13.1
|
||||
set_global_assignment -name LAST_QUARTUS_VERSION "13.1 SP4.26"
|
||||
set_global_assignment -name SMART_RECOMPILE ON
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE rtl/Defender_MiST.sv
|
||||
set_global_assignment -name VHDL_FILE rtl/defender.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/defender_sound_board.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/defender_sound.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/defender_decoder_3.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/defender_decoder_2.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/defender_cmos_ram.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/pia6821.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/cpu68.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/cpu09l_128.vhd
|
||||
set_global_assignment -name QIP_FILE rtl/pll_mist.qip
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE rtl/sdram.sv
|
||||
set_global_assignment -name VHDL_FILE rtl/gen_ram.vhd
|
||||
set_global_assignment -name QIP_FILE ../../../common/mist/mist.qip
|
||||
|
||||
# Pin & Location Assignments
|
||||
# ==========================
|
||||
@@ -185,36 +171,59 @@ set_global_assignment -name OUTPUT_IO_TIMING_FAR_END_VMEAS "HALF SIGNAL SWING" -
|
||||
|
||||
# Pin & Location Assignments
|
||||
# ==========================
|
||||
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_DQ[*]
|
||||
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_A[*]
|
||||
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_BA[0]
|
||||
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_BA[1]
|
||||
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_DQMH
|
||||
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_DQML
|
||||
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_nRAS
|
||||
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_nCAS
|
||||
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_nWE
|
||||
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_nCS
|
||||
set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to SDRAM_DQ[*]
|
||||
set_instance_assignment -name FAST_INPUT_REGISTER ON -to SDRAM_DQ[*]
|
||||
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_DQ[*]
|
||||
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_A[*]
|
||||
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_BA[0]
|
||||
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_BA[1]
|
||||
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_DQMH
|
||||
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_DQML
|
||||
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_nRAS
|
||||
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_nCAS
|
||||
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_nWE
|
||||
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_nCS
|
||||
set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to SDRAM_DQ[*]
|
||||
set_instance_assignment -name FAST_INPUT_REGISTER ON -to SDRAM_DQ[*]
|
||||
|
||||
# Fitter Assignments
|
||||
# ==================
|
||||
set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_*
|
||||
set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to VGA_*
|
||||
set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_*
|
||||
set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to VGA_*
|
||||
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to AUDIO_L
|
||||
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to AUDIO_R
|
||||
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to SPI_DO
|
||||
|
||||
|
||||
# start DESIGN_PARTITION(Top)
|
||||
# ---------------------------
|
||||
|
||||
# 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(Defender_MiST)
|
||||
# -------------------------
|
||||
set_global_assignment -name ENABLE_SIGNALTAP OFF
|
||||
set_global_assignment -name USE_SIGNALTAP_FILE output_files/snd.stp
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE rtl/Defender_MiST.sv
|
||||
set_global_assignment -name VHDL_FILE rtl/defender.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/defender_sound_board.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/defender_sound.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/defender_decoder_3.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/defender_decoder_2.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/defender_cmos_ram.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/cpu68.vhd
|
||||
set_global_assignment -name QIP_FILE rtl/pll_mist.qip
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE rtl/sdram.sv
|
||||
set_global_assignment -name VHDL_FILE rtl/dpram.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/gen_ram.vhd
|
||||
set_global_assignment -name VHDL_FILE ../../../common/IO/pia6821.vhd
|
||||
set_global_assignment -name VHDL_FILE ../../../common/CPU/MC6809/cpu09l_128a.vhd
|
||||
set_global_assignment -name QIP_FILE ../../../common/mist/mist.qip
|
||||
set_global_assignment -name SIGNALTAP_FILE output_files/snd.stp
|
||||
set_global_assignment -name CDF_FILE output_files/Chain2.cdf
|
||||
set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top
|
||||
@@ -53,6 +53,11 @@ set_time_format -unit ns -decimal_places 3
|
||||
|
||||
create_clock -name {SPI_SCK} -period 41.666 -waveform { 20.8 41.666 } [get_ports {SPI_SCK}]
|
||||
|
||||
set sdram_clk "pll|altpll_component|auto_generated|pll1|clk[0]"
|
||||
set vid_clk "pll|altpll_component|auto_generated|pll1|clk[0]"
|
||||
set game_clk "pll|altpll_component|auto_generated|pll1|clk[1]"
|
||||
set aud_clk "pll|altpll_component|auto_generated|pll1|clk[2]"
|
||||
|
||||
#**************************************************************
|
||||
# Create Generated Clock
|
||||
#**************************************************************
|
||||
@@ -79,29 +84,28 @@ set_input_delay -add_delay -clock_fall -clock [get_clocks {SPI_SCK}] 1.000 [ge
|
||||
set_input_delay -add_delay -clock_fall -clock [get_clocks {SPI_SCK}] 1.000 [get_ports {SPI_SS2}]
|
||||
set_input_delay -add_delay -clock_fall -clock [get_clocks {SPI_SCK}] 1.000 [get_ports {SPI_SS3}]
|
||||
|
||||
set_input_delay -clock [get_clocks {pll|altpll_component|auto_generated|pll1|clk[0]}] -max 6.4 [get_ports SDRAM_DQ[*]]
|
||||
set_input_delay -clock [get_clocks {pll|altpll_component|auto_generated|pll1|clk[0]}] -min 3.2 [get_ports SDRAM_DQ[*]]
|
||||
set_input_delay -clock [get_clocks $sdram_clk] -reference_pin [get_ports {SDRAM_CLK}] -max 6.4 [get_ports SDRAM_DQ[*]]
|
||||
set_input_delay -clock [get_clocks $sdram_clk] -reference_pin [get_ports {SDRAM_CLK}] -min 3.2 [get_ports SDRAM_DQ[*]]
|
||||
|
||||
#**************************************************************
|
||||
# Set Output Delay
|
||||
#**************************************************************
|
||||
|
||||
set_output_delay -add_delay -clock_fall -clock [get_clocks {SPI_SCK}] 1.000 [get_ports {SPI_DO}]
|
||||
set_output_delay -add_delay -clock_fall -clock [get_clocks {pll|altpll_component|auto_generated|pll1|clk[2]}] 1.000 [get_ports {AUDIO_L}]
|
||||
set_output_delay -add_delay -clock_fall -clock [get_clocks {pll|altpll_component|auto_generated|pll1|clk[2]}] 1.000 [get_ports {AUDIO_R}]
|
||||
set_output_delay -add_delay -clock_fall -clock [get_clocks {pll|altpll_component|auto_generated|pll1|clk[0]}] 1.000 [get_ports {LED}]
|
||||
set_output_delay -add_delay -clock_fall -clock [get_clocks {pll|altpll_component|auto_generated|pll1|clk[0]}] 1.000 [get_ports {VGA_*}]
|
||||
set_output_delay -add_delay -clock_fall -clock [get_clocks {SPI_SCK}] 1.000 [get_ports {SPI_DO}]
|
||||
set_output_delay -add_delay -clock_fall -clock [get_clocks $aud_clk] 1.000 [get_ports {AUDIO_L}]
|
||||
set_output_delay -add_delay -clock_fall -clock [get_clocks $aud_clk] 1.000 [get_ports {AUDIO_R}]
|
||||
set_output_delay -add_delay -clock_fall -clock [get_clocks $sdram_clk] 1.000 [get_ports {LED}]
|
||||
set_output_delay -add_delay -clock_fall -clock [get_clocks $vid_clk] 1.000 [get_ports {VGA_*}]
|
||||
|
||||
set_output_delay -clock [get_clocks {pll|altpll_component|auto_generated|pll1|clk[0]}] -max 1.5 [get_ports {SDRAM_D* SDRAM_A* SDRAM_BA* SDRAM_n* SDRAM_CKE}]
|
||||
set_output_delay -clock [get_clocks {pll|altpll_component|auto_generated|pll1|clk[0]}] -min -0.8 [get_ports {SDRAM_D* SDRAM_A* SDRAM_BA* SDRAM_n* SDRAM_CKE}]
|
||||
set_output_delay -clock [get_clocks {pll|altpll_component|auto_generated|pll1|clk[0]}] -max 1.5 [get_ports {SDRAM_CLK}]
|
||||
set_output_delay -clock [get_clocks {pll|altpll_component|auto_generated|pll1|clk[0]}] -min -0.8 [get_ports {SDRAM_CLK}]
|
||||
set_output_delay -clock [get_clocks $sdram_clk] -reference_pin [get_ports {SDRAM_CLK}] -max 1.5 [get_ports {SDRAM_D* SDRAM_A* SDRAM_BA* SDRAM_n* SDRAM_CKE}]
|
||||
set_output_delay -clock [get_clocks $sdram_clk] -reference_pin [get_ports {SDRAM_CLK}] -min -0.8 [get_ports {SDRAM_D* SDRAM_A* SDRAM_BA* SDRAM_n* SDRAM_CKE}]
|
||||
|
||||
#**************************************************************
|
||||
# Set Clock Groups
|
||||
#**************************************************************
|
||||
|
||||
set_clock_groups -asynchronous -group [get_clocks {SPI_SCK}] -group [get_clocks {pll|altpll_component|auto_generated|pll1|clk[*]}]
|
||||
set_clock_groups -asynchronous -group [get_clocks $sdram_clk] -group [get_clocks $aud_clk]
|
||||
|
||||
#**************************************************************
|
||||
# Set False Path
|
||||
@@ -113,6 +117,8 @@ set_clock_groups -asynchronous -group [get_clocks {SPI_SCK}] -group [get_clocks
|
||||
# Set Multicycle Path
|
||||
#**************************************************************
|
||||
|
||||
set_multicycle_path -from [get_clocks $game_clk] -to [get_clocks $sdram_clk] -setup 2
|
||||
set_multicycle_path -from [get_clocks $game_clk] -to [get_clocks $sdram_clk] -hold 1
|
||||
set_multicycle_path -to {VGA_*[*]} -setup 2
|
||||
set_multicycle_path -to {VGA_*[*]} -hold 1
|
||||
|
||||
|
||||
@@ -34,24 +34,96 @@ module Defender_MiST(
|
||||
|
||||
`include "rtl/build_id.v"
|
||||
|
||||
`define CORE_NAME "DEFENDER"
|
||||
//`define CORE_NAME "COLONY7"
|
||||
//`define CORE_NAME "MAYDAY"
|
||||
//`define CORE_NAME "JIN"
|
||||
|
||||
localparam CONF_STR = {
|
||||
"DEFENDER;;",
|
||||
`CORE_NAME,";ROM;",
|
||||
"O2,Rotate Controls,Off,On;",
|
||||
"O34,Scanlines,Off,25%,50%,75%;",
|
||||
"T6,Reset;",
|
||||
"V,v1.1.5.",`BUILD_DATE
|
||||
"O5,Blend,Off,On;",
|
||||
"T0,Reset;",
|
||||
"V,v1.2.",`BUILD_DATE
|
||||
};
|
||||
|
||||
wire rotate = status[2];
|
||||
reg [7:0] input0;
|
||||
reg [7:0] input1;
|
||||
reg [7:0] input2;
|
||||
reg mayday; // protection enable in Mayday
|
||||
reg [1:0] orientation; // [left/right, landscape/portrait]
|
||||
|
||||
always @(*) begin
|
||||
mayday = 0;
|
||||
input0 = 0;
|
||||
input1 = 0;
|
||||
input2 = 0;
|
||||
orientation = 2'b10;
|
||||
if (`CORE_NAME == "DEFENDER") begin
|
||||
/*
|
||||
-- pia rom board port a - input0
|
||||
-- bit 0 Auto Up / manual Down
|
||||
-- bit 1 Advance
|
||||
-- bit 2 Right Coin (nc)
|
||||
-- bit 3 High Score Reset
|
||||
-- bit 4 Left Coin
|
||||
-- bit 5 Center Coin (nc)
|
||||
-- bit 6 led 2 (output)
|
||||
-- bit 7 led 1 (output)
|
||||
*/
|
||||
input0 = { 3'b000, m_coin1, 1'b0/*btn_score_reset*/, 1'b0, m_fireF, m_fireE };
|
||||
/*
|
||||
-- pia io port a - input1
|
||||
-- bit 0 Fire
|
||||
-- bit 1 Thrust
|
||||
-- bit 2 Smart Bomb
|
||||
-- bit 3 HyperSpace
|
||||
-- bit 4 2 Players
|
||||
-- bit 5 1 Player
|
||||
-- bit 6 Reverse
|
||||
-- bit 7 Down
|
||||
*/
|
||||
input1 = { m_down, m_left | m_right, m_one_player, m_two_players, m_fireD, m_fireC, m_fireB, m_fireA };
|
||||
/*
|
||||
-- pia io port b
|
||||
-- bit 0 Up
|
||||
-- bit 7 1 for coktail table, 0 for upright cabinet
|
||||
-- other <= GND
|
||||
*/
|
||||
input2 = { 7'b000000, m_up };
|
||||
end else if (`CORE_NAME == "COLONY7") begin
|
||||
orientation = 2'b01;
|
||||
input0 = { 3'b000, m_coin1, 4'b0001 };
|
||||
input1 = { m_fireB, m_fireA, m_one_player, m_two_players, m_up, m_left, m_right, m_down };
|
||||
input2 = { 7'b000000, m_fireC };
|
||||
end else if (`CORE_NAME == "MAYDAY") begin
|
||||
mayday = 1;
|
||||
input0 = { 2'b00, m_coin2, m_coin1, 1'b0, 1'b0/*service*/, m_fireF, m_fireE };
|
||||
input1 = { m_down, 1'b0, m_one_player, m_two_players, m_fireB, m_fireC, m_right, m_fireA };
|
||||
input2 = { 7'b000000, m_up };
|
||||
end else if (`CORE_NAME == "JIN") begin
|
||||
orientation = 2'b11;
|
||||
input0 = { 3'b000, m_coin2, m_coin1, 3'b000 };
|
||||
input1 = { m_fireB, m_fireA, m_one_player, m_two_players, m_right, m_left, m_down, m_up };
|
||||
//unknown/Level completed/Level completed/unknown/Lives/Coinage/Coinage/Coinage
|
||||
input2 = 0;
|
||||
end
|
||||
end
|
||||
|
||||
assign LED = 1;
|
||||
assign SDRAM_CLK = clk_sys;
|
||||
assign SDRAM_CKE = 1;
|
||||
|
||||
wire clk_sys, clock_6, clock_0p89;
|
||||
wire clk_sys, clk_6, clk_0p89;
|
||||
wire pll_locked;
|
||||
pll_mist pll(
|
||||
.inclk0(CLOCK_27),
|
||||
.areset(0),
|
||||
.c0(clk_sys),//36
|
||||
.c1(clock_6),//6
|
||||
.c2(clock_0p89),//0.89
|
||||
.c0(clk_sys),//54
|
||||
.c1(clk_6),//6
|
||||
.c2(clk_0p89),//0.89
|
||||
.locked(pll_locked)
|
||||
);
|
||||
|
||||
@@ -62,22 +134,27 @@ wire [7:0] joystick_0;
|
||||
wire [7:0] joystick_1;
|
||||
wire scandoublerD;
|
||||
wire ypbpr;
|
||||
wire [10:0] ps2_key;
|
||||
wire [7:0] audio;
|
||||
wire hs, vs;
|
||||
wire blankn;
|
||||
wire [2:0] r,g;
|
||||
wire [1:0] b;
|
||||
wire key_pressed;
|
||||
wire [7:0] key_code;
|
||||
wire key_strobe;
|
||||
|
||||
wire [14:0] rom_addr;
|
||||
wire [15:0] rom_do;
|
||||
wire rom_rd;
|
||||
wire ioctl_downl;
|
||||
wire [7:0] ioctl_index;
|
||||
wire ioctl_wr;
|
||||
wire [24:0] ioctl_addr;
|
||||
wire [7:0] ioctl_dout;
|
||||
|
||||
/*
|
||||
ROM Structure:
|
||||
0000-6FFF main cpu 44k (D000-FFFF + page 1,2,3,7)
|
||||
7000-73FF decoder 1k
|
||||
7400-7BFF snd cpu 2k
|
||||
*/
|
||||
data_io data_io (
|
||||
.clk_sys ( clk_sys ),
|
||||
.SPI_SCK ( SPI_SCK ),
|
||||
@@ -89,21 +166,61 @@ data_io data_io (
|
||||
.ioctl_addr ( ioctl_addr ),
|
||||
.ioctl_dout ( ioctl_dout )
|
||||
);
|
||||
|
||||
sdram cart
|
||||
(
|
||||
|
||||
reg port1_req, port2_req;
|
||||
wire [14:0] rom_addr;
|
||||
wire [15:0] rom_do;
|
||||
wire rom_rd;
|
||||
wire [11:0] snd_addr;
|
||||
wire [11:0] snd_rom_addr;
|
||||
wire snd_vma;
|
||||
wire [15:0] snd_do;
|
||||
|
||||
sdram #(.MHZ(54)) sdram(
|
||||
.*,
|
||||
.init ( ~pll_locked ),
|
||||
.init_n ( pll_locked ),
|
||||
.clk ( clk_sys ),
|
||||
.wtbt ( 2'b00 ),
|
||||
.dout ( rom_do ),
|
||||
.din ( {ioctl_dout, ioctl_dout} ),
|
||||
.addr ( ioctl_downl ? ioctl_addr : rom_addr ),
|
||||
.we ( ioctl_downl & ioctl_wr ),
|
||||
.rd ( !ioctl_downl & rom_rd ),
|
||||
.ready()
|
||||
|
||||
// port1 used for main CPU
|
||||
.port1_req ( port1_req ),
|
||||
.port1_ack ( ),
|
||||
.port1_a ( ioctl_addr[23:1] ),
|
||||
.port1_ds ( {ioctl_addr[0], ~ioctl_addr[0]} ),
|
||||
.port1_we ( ioctl_downl ),
|
||||
.port1_d ( {ioctl_dout, ioctl_dout} ),
|
||||
.port1_q ( ),
|
||||
|
||||
.cpu1_addr ( ioctl_downl ? 15'h7fff : {1'b0, rom_addr[14:1]} ),
|
||||
.cpu1_q ( rom_do ),
|
||||
|
||||
// port2 for sound board
|
||||
.port2_req ( port2_req ),
|
||||
.port2_ack ( ),
|
||||
.port2_a ( ioctl_addr[23:1] - 16'h3A00 ),
|
||||
.port2_ds ( {ioctl_addr[0], ~ioctl_addr[0]} ),
|
||||
.port2_we ( ioctl_downl ),
|
||||
.port2_d ( {ioctl_dout, ioctl_dout} ),
|
||||
.port2_q ( ),
|
||||
|
||||
.snd_addr ( ioctl_downl ? 15'h7fff : {5'h0, snd_addr[10:1]} ),
|
||||
.snd_q ( snd_do )
|
||||
);
|
||||
|
||||
always @(posedge clk_sys) begin
|
||||
reg ioctl_wr_last = 0;
|
||||
reg snd_vma_r, snd_vma_r2;
|
||||
|
||||
ioctl_wr_last <= ioctl_wr;
|
||||
if (ioctl_downl) begin
|
||||
if (~ioctl_wr_last && ioctl_wr) begin
|
||||
port1_req <= ~port1_req;
|
||||
port2_req <= ~port2_req;
|
||||
end
|
||||
end
|
||||
snd_vma_r <= snd_vma; snd_vma_r2 <= snd_vma_r;
|
||||
if (snd_vma_r2) snd_addr <= snd_rom_addr;
|
||||
end
|
||||
|
||||
reg reset = 1;
|
||||
reg rom_loaded = 0;
|
||||
always @(posedge clk_sys) begin
|
||||
@@ -111,40 +228,41 @@ always @(posedge clk_sys) begin
|
||||
ioctl_downlD <= ioctl_downl;
|
||||
|
||||
if (ioctl_downlD & ~ioctl_downl) rom_loaded <= 1;
|
||||
reset <= status[0] | buttons[1] | status[6] | ~rom_loaded;
|
||||
reset <= status[0] | buttons[1] | ioctl_downl | ~rom_loaded;
|
||||
end
|
||||
|
||||
defender defender (
|
||||
.clock_6 (clock_6),
|
||||
.clk_0p89 (clock_0p89),
|
||||
.reset ( reset ),
|
||||
.clock_6 ( clk_6 ),
|
||||
.clk_0p89 ( clk_0p89 ),
|
||||
.reset ( reset ),
|
||||
.video_r ( r ),
|
||||
.video_g ( g ),
|
||||
.video_b ( b ),
|
||||
.video_hs ( hs ),
|
||||
.video_hs ( hs ),
|
||||
.video_vs ( vs ),
|
||||
.video_blankn ( blankn ),
|
||||
.audio_out ( audio ),
|
||||
.roms_addr ( rom_addr ),
|
||||
.roms_do ( rom_do[7:0] ),
|
||||
.vma ( rom_rd ),
|
||||
.btn_two_players ( btn_two_players ),
|
||||
.btn_one_player ( btn_one_player ),
|
||||
.btn_left_coin ( btn_coin ),
|
||||
.btn_auto_up (btn_auto_up),
|
||||
.btn_advance (btn_advance),
|
||||
.btn_high_score_reset(btn_score_reset),
|
||||
.btn_fire (m_fire1),
|
||||
.btn_thrust (m_fire2),
|
||||
.btn_smart_bomb (m_fire3),
|
||||
.btn_hyperSpace (m_fire4),
|
||||
.btn_reverse (m_left | m_right),
|
||||
.btn_down (m_down),
|
||||
.btn_up (m_up),
|
||||
.sw_coktail_table (1)
|
||||
.audio_out ( audio ),
|
||||
|
||||
.mayday ( mayday ),
|
||||
|
||||
.input0 ( input0 ),
|
||||
.input1 ( input1 ),
|
||||
.input2 ( input2 ),
|
||||
|
||||
.roms_addr ( rom_addr ),
|
||||
.roms_do ( rom_addr[0] ? rom_do[15:8] : rom_do[7:0] ),
|
||||
.vma ( rom_rd ),
|
||||
.snd_addr ( snd_rom_addr ),
|
||||
.snd_do ( snd_addr[0] ? snd_do[15:8] : snd_do[7:0] ),
|
||||
.snd_vma ( snd_vma ),
|
||||
|
||||
.dl_clock ( clk_sys ),
|
||||
.dl_addr ( ioctl_addr[15:0] ),
|
||||
.dl_data ( ioctl_dout ),
|
||||
.dl_wr ( ioctl_wr )
|
||||
);
|
||||
|
||||
mist_video #(.COLOR_DEPTH(3), .SD_HCNT_WIDTH(10)) mist_video(
|
||||
mist_video #(.COLOR_DEPTH(3), .SD_HCNT_WIDTH(11)) mist_video(
|
||||
.clk_sys ( clk_sys ),
|
||||
.SPI_SCK ( SPI_SCK ),
|
||||
.SPI_SS3 ( SPI_SS3 ),
|
||||
@@ -159,9 +277,10 @@ mist_video #(.COLOR_DEPTH(3), .SD_HCNT_WIDTH(10)) mist_video(
|
||||
.VGA_B ( VGA_B ),
|
||||
.VGA_VS ( VGA_VS ),
|
||||
.VGA_HS ( VGA_HS ),
|
||||
.rotate ( {1'b1,status[2]} ),
|
||||
.rotate ( {orientation[1],rotate} ),
|
||||
.scandoubler_disable( scandoublerD ),
|
||||
.scanlines ( status[4:3] ),
|
||||
.blend ( status[5] ),
|
||||
.ypbpr ( ypbpr )
|
||||
);
|
||||
|
||||
@@ -191,60 +310,32 @@ assign AUDIO_L = dac_o;
|
||||
assign AUDIO_R = dac_o;
|
||||
|
||||
dac #(
|
||||
.C_bits(15))
|
||||
.C_bits(8))
|
||||
dac(
|
||||
.clk_i(clock_0p89),
|
||||
.clk_i(clk_0p89),
|
||||
.res_n_i(1),
|
||||
.dac_i({audio,audio}),
|
||||
.dac_i(audio),
|
||||
.dac_o(dac_o)
|
||||
);
|
||||
|
||||
wire m_up = btn_up | joystick_0[3] | joystick_1[3];
|
||||
wire m_down = btn_down | joystick_0[2] | joystick_1[2];
|
||||
wire m_left = btn_left | joystick_0[1] | joystick_1[1];
|
||||
wire m_right = btn_right | joystick_0[0] | joystick_1[0];
|
||||
wire m_fire1 = btn_fire1 | joystick_0[4] | joystick_1[4];
|
||||
wire m_fire2 = btn_fire2 | joystick_0[5] | joystick_1[5];
|
||||
wire m_fire3 = btn_fire3 | joystick_0[6] | joystick_1[6];
|
||||
wire m_fire4 = btn_fire4 | joystick_0[7] | joystick_1[7];
|
||||
wire m_up, m_down, m_left, m_right, m_fireA, m_fireB, m_fireC, m_fireD, m_fireE, m_fireF;
|
||||
wire m_up2, m_down2, m_left2, m_right2, m_fire2A, m_fire2B, m_fire2C, m_fire2D, m_fire2E, m_fire2F;
|
||||
wire m_tilt, m_coin1, m_coin2, m_coin3, m_coin4, m_one_player, m_two_players, m_three_players, m_four_players;
|
||||
|
||||
reg btn_one_player = 0;
|
||||
reg btn_two_players = 0;
|
||||
reg btn_left = 0;
|
||||
reg btn_right = 0;
|
||||
reg btn_down = 0;
|
||||
reg btn_up = 0;
|
||||
reg btn_fire1 = 0;
|
||||
reg btn_fire2 = 0;
|
||||
reg btn_fire3 = 0;
|
||||
reg btn_fire4 = 0;
|
||||
reg btn_coin = 0;
|
||||
reg btn_advance = 0;
|
||||
reg btn_auto_up = 0;
|
||||
reg btn_score_reset = 0;
|
||||
wire key_pressed;
|
||||
wire [7:0] key_code;
|
||||
wire key_strobe;
|
||||
|
||||
always @(posedge clk_sys) begin
|
||||
if(key_strobe) begin
|
||||
case(key_code)
|
||||
'h75: btn_up <= key_pressed; // up
|
||||
'h72: btn_down <= key_pressed; // down
|
||||
'h6B: btn_left <= key_pressed; // left
|
||||
'h74: btn_right <= key_pressed; // right
|
||||
'h76: btn_coin <= key_pressed; // ESC
|
||||
'h05: btn_one_player <= key_pressed; // F1
|
||||
'h06: btn_two_players <= key_pressed; // F2
|
||||
'h12: btn_fire4 <= key_pressed; // l shift
|
||||
'h14: btn_fire3 <= key_pressed; // ctrl
|
||||
'h11: btn_fire2 <= key_pressed; // alt
|
||||
'h29: btn_fire1 <= key_pressed; // Space
|
||||
'h1C: btn_advance <= key_pressed; // A
|
||||
'h3C: btn_auto_up <= key_pressed; // U
|
||||
'h33: btn_score_reset <= key_pressed; // H
|
||||
endcase
|
||||
end
|
||||
end
|
||||
arcade_inputs inputs (
|
||||
.clk ( clk_sys ),
|
||||
.key_strobe ( key_strobe ),
|
||||
.key_pressed ( key_pressed ),
|
||||
.key_code ( key_code ),
|
||||
.joystick_0 ( joystick_0 ),
|
||||
.joystick_1 ( joystick_1 ),
|
||||
.rotate ( rotate ),
|
||||
.orientation ( orientation ),
|
||||
.joyswap ( 1'b0 ),
|
||||
.oneplayer ( 1'b1 ),
|
||||
.controls ( {m_tilt, m_coin4, m_coin3, m_coin2, m_coin1, m_four_players, m_three_players, m_two_players, m_one_player} ),
|
||||
.player1 ( {m_fireF, m_fireE, m_fireD, m_fireC, m_fireB, m_fireA, m_up, m_down, m_left, m_right} ),
|
||||
.player2 ( {m_fire2F, m_fire2E, m_fire2D, m_fire2C, m_fire2B, m_fire2A, m_up2, m_down2, m_left2, m_right2} )
|
||||
);
|
||||
|
||||
endmodule
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -123,10 +123,10 @@ use ieee.numeric_std.all;
|
||||
|
||||
entity defender is
|
||||
port(
|
||||
clk_sys : in std_logic;
|
||||
clock_6 : in std_logic;
|
||||
clk_0p89 : in std_logic;
|
||||
reset : in std_logic;
|
||||
clk_sys : in std_logic;
|
||||
clock_6 : in std_logic;
|
||||
clk_0p89 : in std_logic;
|
||||
reset : in std_logic;
|
||||
video_r : out std_logic_vector(2 downto 0);
|
||||
video_g : out std_logic_vector(2 downto 0);
|
||||
video_b : out std_logic_vector(1 downto 0);
|
||||
@@ -134,27 +134,26 @@ port(
|
||||
video_blankn : out std_logic;
|
||||
video_hs : out std_logic;
|
||||
video_vs : out std_logic;
|
||||
audio_out : out std_logic_vector(7 downto 0);
|
||||
audio_out : out std_logic_vector( 7 downto 0);
|
||||
|
||||
mayday : in std_logic; -- Mayday protection
|
||||
input0 : in std_logic_vector( 7 downto 0);
|
||||
input1 : in std_logic_vector( 7 downto 0);
|
||||
input2 : in std_logic_vector( 7 downto 0);
|
||||
|
||||
cmd_select_players_btn : out std_logic;
|
||||
|
||||
roms_addr : out std_logic_vector(14 downto 0);
|
||||
roms_do : in std_logic_vector( 7 downto 0);
|
||||
vma : out std_logic;
|
||||
btn_auto_up : in std_logic;
|
||||
btn_advance : in std_logic;
|
||||
btn_high_score_reset : in std_logic;
|
||||
snd_addr : out std_logic_vector(11 downto 0);
|
||||
snd_do : in std_logic_vector( 7 downto 0);
|
||||
snd_vma : out std_logic;
|
||||
|
||||
btn_left_coin : in std_logic;
|
||||
btn_one_player : in std_logic;
|
||||
btn_two_players: in std_logic;
|
||||
|
||||
btn_fire : in std_logic;
|
||||
btn_thrust : in std_logic;
|
||||
btn_smart_bomb : in std_logic;
|
||||
btn_hyperSpace : in std_logic;
|
||||
btn_reverse : in std_logic;
|
||||
btn_down : in std_logic;
|
||||
btn_up : in std_logic;
|
||||
sw_coktail_table : in std_logic;
|
||||
cmd_select_players_btn : out std_logic
|
||||
dl_clock : in std_logic;
|
||||
dl_addr : in std_logic_vector(15 downto 0);
|
||||
dl_data : in std_logic_vector( 7 downto 0);
|
||||
dl_wr : in std_logic
|
||||
);
|
||||
end defender;
|
||||
|
||||
@@ -164,6 +163,7 @@ architecture struct of defender is
|
||||
signal clock_div : std_logic_vector(1 downto 0);
|
||||
|
||||
signal clock_6n : std_logic;
|
||||
signal cpu_a : std_logic_vector(15 downto 0);
|
||||
signal cpu_addr : std_logic_vector(15 downto 0);
|
||||
signal cpu_di : std_logic_vector( 7 downto 0);
|
||||
signal cpu_do : std_logic_vector( 7 downto 0);
|
||||
@@ -274,7 +274,10 @@ architecture struct of defender is
|
||||
|
||||
signal select_sound : std_logic_vector(5 downto 0);
|
||||
signal cpu_ce : std_logic;
|
||||
|
||||
|
||||
signal cpu_video_addr_decoder_we : std_logic;
|
||||
signal video_scan_addr_decoder_we : std_logic;
|
||||
|
||||
begin
|
||||
|
||||
clock_6n <= not clock_6;
|
||||
@@ -350,7 +353,7 @@ roms_addr <=
|
||||
"110" & cpu_addr(11 downto 0) when cpu_addr(15 downto 12) = X"C" and rom_page = "111" else
|
||||
"000" & cpu_addr(11 downto 0) when cpu_addr(15 downto 12) = X"D" else
|
||||
"001" & cpu_addr(11 downto 0) when cpu_addr(15 downto 12) = X"E" else
|
||||
"010" & cpu_addr(11 downto 0) ;--when cpu_addr(15 downto 12) = X"F";
|
||||
"010" & cpu_addr(11 downto 0) ;--when cpu_addr(15 downto 12) = X"F";
|
||||
|
||||
-- encoded cpu addr (decoder.2) and encoded scan addr (decoder.3)
|
||||
-- and screen control for cocktail table flip
|
||||
@@ -451,53 +454,10 @@ begin
|
||||
end if;
|
||||
end process;
|
||||
|
||||
-- pia rom board port a
|
||||
-- bit 0 Auto Up / manual Down
|
||||
-- bit 1 Advance
|
||||
-- bit 2 Right Coin (nc)
|
||||
-- bit 3 High Score Reset
|
||||
-- bit 4 Left Coin
|
||||
-- bit 5 Center Coin (nc)
|
||||
-- bit 6 led 2 (output)
|
||||
-- bit 7 led 1 (output)
|
||||
|
||||
pias_clock <= clock_6; --not cpu_clock;
|
||||
|
||||
pia_rom_pa_i(0) <= btn_auto_up;
|
||||
pia_rom_pa_i(1) <= btn_advance;
|
||||
pia_rom_pa_i(2) <= '0';
|
||||
pia_rom_pa_i(3) <= btn_high_score_reset;
|
||||
pia_rom_pa_i(4) <= btn_left_coin;
|
||||
pia_rom_pa_i(5) <= '0';
|
||||
pia_rom_pa_i(6) <= '0';
|
||||
pia_rom_pa_i(7) <= '0';
|
||||
|
||||
-- pia io port a
|
||||
-- bit 0 Fire
|
||||
-- bit 1 Thrust
|
||||
-- bit 2 Smart Bomb
|
||||
-- bit 3 HyperSpace
|
||||
-- bit 4 2 Players
|
||||
-- bit 5 1 Player
|
||||
-- bit 6 Reverse
|
||||
-- bit 7 Down
|
||||
|
||||
pia_io_pa_i(0) <= btn_fire;
|
||||
pia_io_pa_i(1) <= btn_thrust;
|
||||
pia_io_pa_i(2) <= btn_smart_bomb;
|
||||
pia_io_pa_i(3) <= btn_hyperSpace;
|
||||
pia_io_pa_i(4) <= btn_two_players;
|
||||
pia_io_pa_i(5) <= btn_one_player;
|
||||
pia_io_pa_i(6) <= btn_reverse;
|
||||
pia_io_pa_i(7) <= btn_down;
|
||||
|
||||
-- pia io port b
|
||||
-- bit 0 Up
|
||||
-- bit 7 1 for coktail table, 0 for upright cabinet
|
||||
-- other <= GND
|
||||
pia_io_pb_i(0) <= btn_up;
|
||||
pia_io_pb_i(6 downto 1) <= "000000";
|
||||
pia_io_pb_i(7) <= sw_coktail_table;
|
||||
pia_rom_pa_i <= input0;
|
||||
pia_io_pa_i <= input1;
|
||||
pia_io_pb_i <= input2;
|
||||
|
||||
-- pia io ca/cb
|
||||
cmd_select_players_btn <= pia_io_cb2_o;
|
||||
@@ -518,24 +478,31 @@ cpu_ce <= '1' when pixel_cnt = "100" or pixel_cnt = "010" else '0';
|
||||
main_cpu : entity work.cpu09
|
||||
port map(
|
||||
clk => clock_6, -- E clock input (falling edge)
|
||||
ce => cpu_ce,
|
||||
rst => reset, -- reset input (active high)
|
||||
vma => vma, -- valid memory address (active high)
|
||||
lic_out => open, -- last instruction cycle (active high)
|
||||
ifetch => open, -- instruction fetch cycle (active high)
|
||||
opfetch => open, -- opcode fetch (active high)
|
||||
ba => open, -- bus available (high on sync wait or DMA grant)
|
||||
bs => open, -- bus status (high on interrupt or reset vector fetch or DMA grant)
|
||||
addr => cpu_addr, -- address bus output
|
||||
lic_out => open, -- last instruction cycle (active high)
|
||||
ifetch => open, -- instruction fetch cycle (active high)
|
||||
opfetch => open, -- opcode fetch (active high)
|
||||
ba => open, -- bus available (high on sync wait or DMA grant)
|
||||
bs => open, -- bus status (high on interrupt or reset vector fetch or DMA grant)
|
||||
addr => cpu_a, -- address bus output
|
||||
rw => cpu_rw, -- read not write output
|
||||
data_out => cpu_do, -- data bus output
|
||||
data_in => cpu_di, -- data bus input
|
||||
irq => cpu_irq, -- interrupt request input (active high)
|
||||
firq => '0', -- fast interrupt request input (active high)
|
||||
nmi => '0', -- non maskable interrupt request input (active high)
|
||||
halt => '0', -- not cpu_ce -- hold input (active high) extend bus cycle
|
||||
hold => not cpu_ce -- hold input (active high) extend bus cycle
|
||||
halt => '0' -- not cpu_ce -- hold input (active high) extend bus cycle
|
||||
-- hold => '0'--not cpu_ce -- hold input (active high) extend bus cycle
|
||||
);
|
||||
|
||||
-- Mayday protection.
|
||||
cpu_addr <= cpu_a when mayday = '0' else
|
||||
x"A193" when cpu_rw = '1' and cpu_a = x"A190" else
|
||||
x"A194" when cpu_rw = '1' and cpu_a = x"A191" else
|
||||
cpu_a;
|
||||
|
||||
-- cpu program rom
|
||||
-- 4k D000-DFFF
|
||||
-- 4k E000-EFFF
|
||||
@@ -611,20 +578,32 @@ port map(
|
||||
);
|
||||
|
||||
-- cpu to video addr decoder
|
||||
cpu_video_addr_decoder : entity work.defender_decoder_2
|
||||
cpu_video_addr_decoder : entity work.dpram
|
||||
generic map( dWidth => 8, aWidth => 9)
|
||||
port map(
|
||||
clk => clock_6,
|
||||
addr => cpu_to_video_addr,
|
||||
data => cpu_to_video_do
|
||||
clk_a => clock_6,
|
||||
addr_a => cpu_to_video_addr,
|
||||
q_a => cpu_to_video_do,
|
||||
clk_b => dl_clock,
|
||||
we_b => cpu_video_addr_decoder_we,
|
||||
addr_b => dl_addr(8 downto 0),
|
||||
d_b => dl_data
|
||||
);
|
||||
cpu_video_addr_decoder_we <= '1' when dl_wr = '1' and dl_addr(15 downto 9) = x"7"&"000" else '0'; -- 7000-71FF
|
||||
|
||||
-- video scan addr decoder
|
||||
video_scan_addr_decoder : entity work.defender_decoder_3
|
||||
video_scan_addr_decoder : entity work.dpram
|
||||
generic map( dWidth => 8, aWidth => 9)
|
||||
port map(
|
||||
clk => clock_6,
|
||||
addr => video_scan_addr,
|
||||
data => video_scan_do
|
||||
clk_a => clock_6,
|
||||
addr_a => video_scan_addr,
|
||||
q_a => video_scan_do,
|
||||
clk_b => dl_clock,
|
||||
we_b => video_scan_addr_decoder_we ,
|
||||
addr_b => dl_addr(8 downto 0),
|
||||
d_b => dl_data
|
||||
);
|
||||
video_scan_addr_decoder_we <= '1' when dl_wr = '1' and dl_addr(15 downto 9) = x"7"&"001" else '0'; -- 7200-73FF
|
||||
|
||||
-- pia i/O board
|
||||
pia_io : entity work.pia6821
|
||||
@@ -756,7 +735,10 @@ port map(
|
||||
clk_0p89 => clk_0p89,
|
||||
reset => reset,
|
||||
select_sound => select_sound,
|
||||
audio_out => audio_out
|
||||
audio_out => audio_out,
|
||||
rom_addr => snd_addr,
|
||||
rom_do => snd_do,
|
||||
rom_vma => snd_vma
|
||||
);
|
||||
|
||||
end struct;
|
||||
@@ -1,54 +0,0 @@
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all,ieee.numeric_std.all;
|
||||
|
||||
entity defender_decoder_2 is
|
||||
port (
|
||||
clk : in std_logic;
|
||||
addr : in std_logic_vector(8 downto 0);
|
||||
data : out std_logic_vector(7 downto 0)
|
||||
);
|
||||
end entity;
|
||||
|
||||
architecture prom of defender_decoder_2 is
|
||||
type rom is array(0 to 511) of std_logic_vector(7 downto 0);
|
||||
signal rom_data: rom := (
|
||||
X"00",X"40",X"80",X"01",X"41",X"81",X"02",X"42",X"82",X"03",X"43",X"83",X"04",X"44",X"84",X"05",
|
||||
X"45",X"85",X"06",X"46",X"86",X"07",X"47",X"87",X"08",X"48",X"88",X"09",X"49",X"89",X"0A",X"4A",
|
||||
X"8A",X"0B",X"4B",X"8B",X"0C",X"4C",X"8C",X"0D",X"4D",X"8D",X"0E",X"4E",X"8E",X"0F",X"4F",X"8F",
|
||||
X"10",X"50",X"90",X"11",X"51",X"91",X"12",X"52",X"92",X"13",X"53",X"93",X"14",X"54",X"94",X"15",
|
||||
X"55",X"95",X"16",X"56",X"96",X"17",X"57",X"97",X"18",X"58",X"98",X"19",X"59",X"99",X"1A",X"5A",
|
||||
X"9A",X"1B",X"5B",X"9B",X"1C",X"5C",X"9C",X"1D",X"5D",X"9D",X"1E",X"5E",X"9E",X"1F",X"5F",X"9F",
|
||||
X"20",X"60",X"A0",X"21",X"61",X"A1",X"22",X"62",X"A2",X"23",X"63",X"A3",X"24",X"64",X"A4",X"25",
|
||||
X"65",X"A5",X"26",X"66",X"A6",X"27",X"67",X"A7",X"28",X"68",X"A8",X"29",X"69",X"A9",X"2A",X"6A",
|
||||
X"AA",X"2B",X"6B",X"AB",X"2C",X"6C",X"AC",X"2D",X"6D",X"AD",X"2E",X"6E",X"AE",X"2F",X"6F",X"AF",
|
||||
X"30",X"70",X"B0",X"31",X"71",X"B1",X"32",X"72",X"B2",X"33",X"73",X"B3",X"34",X"74",X"B4",X"35",
|
||||
X"75",X"B5",X"36",X"76",X"B6",X"37",X"77",X"B7",X"38",X"78",X"B8",X"39",X"79",X"B9",X"3A",X"7A",
|
||||
X"BA",X"3B",X"7B",X"BB",X"3C",X"7C",X"BC",X"3D",X"7D",X"BD",X"3E",X"7E",X"BE",X"3F",X"7F",X"BF",
|
||||
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
|
||||
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
|
||||
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
|
||||
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
|
||||
X"00",X"40",X"80",X"01",X"41",X"72",X"32",X"B1",X"71",X"31",X"B0",X"70",X"30",X"AF",X"6F",X"2F",
|
||||
X"AE",X"6E",X"2E",X"AD",X"6D",X"2D",X"AC",X"6C",X"2C",X"AB",X"6B",X"2B",X"AA",X"6A",X"2A",X"A9",
|
||||
X"69",X"29",X"A8",X"68",X"28",X"A7",X"67",X"27",X"A6",X"66",X"26",X"A5",X"65",X"25",X"A4",X"64",
|
||||
X"24",X"A3",X"63",X"23",X"A2",X"62",X"22",X"A1",X"61",X"21",X"A0",X"60",X"20",X"9F",X"5F",X"1F",
|
||||
X"9E",X"5E",X"1E",X"9D",X"5D",X"1D",X"9C",X"5C",X"1C",X"9B",X"5B",X"1B",X"9A",X"5A",X"1A",X"99",
|
||||
X"59",X"19",X"98",X"58",X"18",X"97",X"57",X"17",X"96",X"56",X"16",X"95",X"55",X"15",X"94",X"54",
|
||||
X"14",X"93",X"53",X"13",X"92",X"52",X"12",X"91",X"51",X"11",X"90",X"50",X"10",X"8F",X"4F",X"0F",
|
||||
X"8E",X"4E",X"0E",X"8D",X"4D",X"0D",X"8C",X"4C",X"0C",X"8B",X"4B",X"0B",X"8A",X"4A",X"0A",X"89",
|
||||
X"49",X"09",X"88",X"48",X"08",X"87",X"47",X"07",X"86",X"46",X"06",X"85",X"45",X"05",X"84",X"44",
|
||||
X"04",X"83",X"43",X"03",X"82",X"42",X"02",X"81",X"B2",X"33",X"73",X"B3",X"34",X"74",X"B4",X"35",
|
||||
X"75",X"B5",X"36",X"76",X"B6",X"37",X"77",X"B7",X"38",X"78",X"B8",X"39",X"79",X"B9",X"3A",X"7A",
|
||||
X"BA",X"3B",X"7B",X"BB",X"3C",X"7C",X"BC",X"3D",X"7D",X"BD",X"3E",X"7E",X"BE",X"3F",X"7F",X"BF",
|
||||
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
|
||||
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
|
||||
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
|
||||
X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00");
|
||||
begin
|
||||
process(clk)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
data <= rom_data(to_integer(unsigned(addr)));
|
||||
end if;
|
||||
end process;
|
||||
end architecture;
|
||||
@@ -1,54 +0,0 @@
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all,ieee.numeric_std.all;
|
||||
|
||||
entity defender_decoder_3 is
|
||||
port (
|
||||
clk : in std_logic;
|
||||
addr : in std_logic_vector(8 downto 0);
|
||||
data : out std_logic_vector(7 downto 0)
|
||||
);
|
||||
end entity;
|
||||
|
||||
architecture prom of defender_decoder_3 is
|
||||
type rom is array(0 to 511) of std_logic_vector(7 downto 0);
|
||||
signal rom_data: rom := (
|
||||
X"00",X"01",X"02",X"03",X"04",X"05",X"06",X"07",X"08",X"09",X"0A",X"0B",X"0C",X"0D",X"0E",X"0F",
|
||||
X"10",X"11",X"12",X"13",X"14",X"15",X"16",X"17",X"18",X"19",X"1A",X"1B",X"1C",X"1D",X"1E",X"1F",
|
||||
X"20",X"21",X"22",X"23",X"24",X"25",X"26",X"27",X"28",X"29",X"2A",X"2B",X"2C",X"2D",X"2E",X"2F",
|
||||
X"30",X"31",X"32",X"33",X"34",X"35",X"36",X"37",X"38",X"39",X"3A",X"3B",X"3C",X"3D",X"3E",X"3F",
|
||||
X"40",X"41",X"42",X"43",X"44",X"45",X"46",X"47",X"48",X"49",X"4A",X"4B",X"4C",X"4D",X"4E",X"4F",
|
||||
X"50",X"51",X"52",X"53",X"54",X"55",X"56",X"57",X"58",X"59",X"5A",X"5B",X"5C",X"5D",X"5E",X"5F",
|
||||
X"60",X"61",X"62",X"63",X"64",X"65",X"66",X"67",X"68",X"69",X"6A",X"6B",X"6C",X"6D",X"6E",X"6F",
|
||||
X"70",X"71",X"72",X"73",X"74",X"75",X"76",X"77",X"78",X"79",X"7A",X"7B",X"7C",X"7D",X"7E",X"7F",
|
||||
X"80",X"81",X"82",X"83",X"84",X"85",X"86",X"87",X"88",X"89",X"8A",X"8B",X"8C",X"8D",X"8E",X"8F",
|
||||
X"90",X"91",X"92",X"93",X"94",X"95",X"96",X"97",X"98",X"99",X"9A",X"9B",X"9C",X"9D",X"9E",X"9F",
|
||||
X"A0",X"A1",X"A2",X"A3",X"A4",X"A5",X"A6",X"A7",X"A8",X"A9",X"AA",X"AB",X"AC",X"AD",X"AE",X"AF",
|
||||
X"B0",X"B1",X"B2",X"B3",X"B4",X"B5",X"B6",X"B7",X"B8",X"B9",X"BA",X"BB",X"BC",X"BD",X"BE",X"BF",
|
||||
X"C0",X"C1",X"C2",X"C3",X"C4",X"C5",X"C6",X"C7",X"C8",X"C9",X"CA",X"CB",X"CC",X"CD",X"CE",X"CF",
|
||||
X"D0",X"D1",X"D2",X"D3",X"D4",X"D5",X"D6",X"D7",X"D8",X"D9",X"DA",X"DB",X"DC",X"DD",X"DE",X"DF",
|
||||
X"E0",X"E1",X"E2",X"E3",X"E4",X"E5",X"E6",X"E7",X"E8",X"E9",X"EA",X"EB",X"EC",X"ED",X"EE",X"EF",
|
||||
X"F0",X"F1",X"F2",X"F3",X"F4",X"F5",X"F6",X"F7",X"F8",X"F9",X"FA",X"FB",X"FC",X"FD",X"FE",X"FF",
|
||||
X"FB",X"FA",X"F9",X"F8",X"F7",X"F6",X"F5",X"F4",X"F3",X"F2",X"F1",X"F0",X"EF",X"EE",X"ED",X"EC",
|
||||
X"EB",X"EA",X"E9",X"E8",X"E7",X"E6",X"E5",X"E4",X"E3",X"E2",X"E1",X"E0",X"DF",X"DE",X"DD",X"DC",
|
||||
X"DB",X"DA",X"D9",X"D8",X"D7",X"D6",X"D5",X"D4",X"D3",X"D2",X"D1",X"D0",X"CF",X"CE",X"CD",X"CC",
|
||||
X"CB",X"CA",X"C9",X"C8",X"C7",X"C6",X"C5",X"C4",X"C3",X"C2",X"C1",X"C0",X"BF",X"BE",X"BD",X"BC",
|
||||
X"BB",X"BA",X"B9",X"B8",X"B7",X"B6",X"B5",X"B4",X"B3",X"B2",X"B1",X"B0",X"AF",X"AE",X"AD",X"AC",
|
||||
X"AB",X"AA",X"A9",X"A8",X"A7",X"A6",X"A5",X"A4",X"A3",X"A2",X"A1",X"A0",X"9F",X"9E",X"9D",X"9C",
|
||||
X"9B",X"9A",X"99",X"98",X"97",X"96",X"95",X"94",X"93",X"92",X"91",X"90",X"8F",X"8E",X"8D",X"8C",
|
||||
X"8B",X"8A",X"89",X"88",X"87",X"86",X"85",X"84",X"83",X"82",X"81",X"80",X"7F",X"7E",X"7D",X"7C",
|
||||
X"7B",X"7A",X"79",X"78",X"77",X"76",X"75",X"74",X"73",X"72",X"71",X"70",X"6F",X"6E",X"6D",X"6C",
|
||||
X"6B",X"6A",X"69",X"68",X"67",X"66",X"65",X"64",X"63",X"62",X"61",X"60",X"5F",X"5E",X"5D",X"5C",
|
||||
X"5B",X"5A",X"59",X"58",X"57",X"56",X"55",X"54",X"53",X"52",X"51",X"50",X"4F",X"4E",X"4D",X"4C",
|
||||
X"4B",X"4A",X"49",X"48",X"47",X"46",X"45",X"44",X"43",X"42",X"41",X"40",X"3F",X"3E",X"3D",X"3C",
|
||||
X"3B",X"3A",X"39",X"38",X"37",X"36",X"35",X"34",X"33",X"32",X"31",X"30",X"2F",X"2E",X"2D",X"2C",
|
||||
X"2B",X"2A",X"29",X"28",X"27",X"26",X"25",X"24",X"23",X"22",X"21",X"20",X"1F",X"1E",X"1D",X"1C",
|
||||
X"1B",X"1A",X"19",X"18",X"17",X"16",X"15",X"14",X"13",X"12",X"11",X"10",X"0F",X"0E",X"0D",X"0C",
|
||||
X"0B",X"0A",X"09",X"08",X"07",X"06",X"05",X"04",X"03",X"02",X"01",X"00",X"FC",X"FD",X"FE",X"FF");
|
||||
begin
|
||||
process(clk)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
data <= rom_data(to_integer(unsigned(addr)));
|
||||
end if;
|
||||
end process;
|
||||
end architecture;
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,150 +0,0 @@
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all,ieee.numeric_std.all;
|
||||
|
||||
entity defender_sound is
|
||||
port (
|
||||
clk : in std_logic;
|
||||
addr : in std_logic_vector(10 downto 0);
|
||||
data : out std_logic_vector(7 downto 0)
|
||||
);
|
||||
end entity;
|
||||
|
||||
architecture prom of defender_sound is
|
||||
type rom is array(0 to 2047) of std_logic_vector(7 downto 0);
|
||||
signal rom_data: rom := (
|
||||
X"FF",X"0F",X"8E",X"00",X"7F",X"CE",X"04",X"00",X"6F",X"01",X"6F",X"03",X"86",X"FF",X"A7",X"00",
|
||||
X"6F",X"02",X"86",X"37",X"A7",X"03",X"86",X"3C",X"A7",X"01",X"97",X"09",X"4F",X"97",X"07",X"97",
|
||||
X"04",X"97",X"05",X"97",X"06",X"97",X"08",X"0E",X"20",X"FE",X"16",X"48",X"48",X"48",X"1B",X"CE",
|
||||
X"00",X"13",X"DF",X"0F",X"CE",X"FD",X"76",X"BD",X"FD",X"21",X"C6",X"09",X"7E",X"FB",X"0A",X"96",
|
||||
X"1B",X"B7",X"04",X"00",X"96",X"13",X"97",X"1C",X"96",X"14",X"97",X"1D",X"DE",X"18",X"96",X"1C",
|
||||
X"73",X"04",X"00",X"09",X"27",X"10",X"4A",X"26",X"FA",X"73",X"04",X"00",X"96",X"1D",X"09",X"27",
|
||||
X"05",X"4A",X"26",X"FA",X"20",X"E8",X"B6",X"04",X"00",X"2B",X"01",X"43",X"8B",X"00",X"B7",X"04",
|
||||
X"00",X"96",X"1C",X"9B",X"15",X"97",X"1C",X"96",X"1D",X"9B",X"16",X"97",X"1D",X"91",X"17",X"26",
|
||||
X"CB",X"96",X"1A",X"27",X"06",X"9B",X"13",X"97",X"13",X"26",X"B9",X"39",X"86",X"01",X"97",X"1A",
|
||||
X"C6",X"03",X"20",X"0A",X"86",X"FE",X"97",X"1A",X"86",X"C0",X"C6",X"10",X"20",X"00",X"97",X"19",
|
||||
X"86",X"FF",X"B7",X"04",X"00",X"D7",X"15",X"D6",X"15",X"96",X"0A",X"44",X"44",X"44",X"98",X"0A",
|
||||
X"44",X"76",X"00",X"09",X"76",X"00",X"0A",X"24",X"03",X"73",X"04",X"00",X"96",X"19",X"4A",X"26",
|
||||
X"FD",X"5A",X"26",X"E5",X"96",X"19",X"9B",X"1A",X"97",X"19",X"26",X"DB",X"39",X"86",X"20",X"97",
|
||||
X"15",X"97",X"18",X"86",X"01",X"CE",X"00",X"01",X"C6",X"FF",X"20",X"00",X"97",X"13",X"DF",X"16",
|
||||
X"D7",X"14",X"D6",X"15",X"96",X"0A",X"44",X"44",X"44",X"98",X"0A",X"44",X"76",X"00",X"09",X"76",
|
||||
X"00",X"0A",X"86",X"00",X"24",X"02",X"96",X"14",X"B7",X"04",X"00",X"DE",X"16",X"09",X"26",X"FD",
|
||||
X"5A",X"26",X"E1",X"D6",X"14",X"D0",X"13",X"27",X"09",X"DE",X"16",X"08",X"96",X"18",X"27",X"D0",
|
||||
X"20",X"CC",X"39",X"C6",X"01",X"D7",X"04",X"4F",X"97",X"19",X"20",X"14",X"4F",X"97",X"19",X"C6",
|
||||
X"03",X"20",X"0D",X"86",X"01",X"97",X"19",X"CE",X"03",X"E8",X"86",X"01",X"C6",X"FF",X"20",X"00",
|
||||
X"97",X"18",X"D7",X"13",X"DF",X"16",X"7F",X"00",X"15",X"DE",X"16",X"B6",X"04",X"00",X"16",X"54",
|
||||
X"54",X"54",X"D8",X"0A",X"54",X"76",X"00",X"09",X"76",X"00",X"0A",X"D6",X"13",X"7D",X"00",X"19",
|
||||
X"27",X"02",X"D4",X"09",X"D7",X"14",X"D6",X"15",X"91",X"0A",X"22",X"12",X"09",X"27",X"26",X"B7",
|
||||
X"04",X"00",X"DB",X"15",X"99",X"14",X"25",X"16",X"91",X"0A",X"23",X"F0",X"20",X"10",X"09",X"27",
|
||||
X"14",X"B7",X"04",X"00",X"D0",X"15",X"92",X"14",X"25",X"04",X"91",X"0A",X"22",X"F0",X"96",X"0A",
|
||||
X"B7",X"04",X"00",X"20",X"B9",X"D6",X"18",X"27",X"B5",X"96",X"13",X"D6",X"15",X"44",X"56",X"44",
|
||||
X"56",X"44",X"56",X"43",X"50",X"82",X"FF",X"DB",X"15",X"99",X"13",X"D7",X"15",X"97",X"13",X"26",
|
||||
X"98",X"C1",X"07",X"26",X"94",X"39",X"86",X"FD",X"97",X"0F",X"CE",X"00",X"64",X"DF",X"0B",X"DB",
|
||||
X"0C",X"96",X"11",X"99",X"0B",X"97",X"11",X"DE",X"0B",X"25",X"04",X"20",X"00",X"20",X"03",X"08",
|
||||
X"27",X"11",X"DF",X"0B",X"84",X"0F",X"8B",X"9A",X"97",X"10",X"DE",X"0F",X"A6",X"00",X"B7",X"04",
|
||||
X"00",X"20",X"DC",X"39",X"4F",X"B7",X"04",X"00",X"97",X"11",X"4F",X"91",X"11",X"26",X"03",X"73",
|
||||
X"04",X"00",X"C6",X"12",X"5A",X"26",X"FD",X"4C",X"2A",X"F1",X"73",X"04",X"00",X"7C",X"00",X"11",
|
||||
X"2A",X"E8",X"39",X"CE",X"00",X"13",X"6F",X"00",X"08",X"8C",X"00",X"1B",X"26",X"F8",X"86",X"40",
|
||||
X"97",X"13",X"CE",X"00",X"13",X"86",X"80",X"97",X"11",X"5F",X"A6",X"01",X"AB",X"00",X"A7",X"01",
|
||||
X"2A",X"02",X"DB",X"11",X"74",X"00",X"11",X"08",X"08",X"8C",X"00",X"1B",X"26",X"EC",X"F7",X"04",
|
||||
X"00",X"7C",X"00",X"12",X"26",X"DC",X"CE",X"00",X"13",X"5F",X"A6",X"00",X"27",X"0B",X"81",X"37",
|
||||
X"26",X"04",X"C6",X"41",X"E7",X"02",X"6A",X"00",X"5C",X"08",X"08",X"8C",X"00",X"1B",X"26",X"EA",
|
||||
X"5D",X"26",X"BF",X"39",X"7A",X"00",X"08",X"39",X"7F",X"00",X"08",X"97",X"11",X"CE",X"FD",X"AA",
|
||||
X"A6",X"00",X"27",X"2D",X"7A",X"00",X"11",X"27",X"06",X"4C",X"BD",X"FD",X"21",X"20",X"F1",X"08",
|
||||
X"DF",X"0F",X"BD",X"FD",X"21",X"DF",X"0D",X"DE",X"0F",X"A6",X"00",X"97",X"15",X"A6",X"01",X"EE",
|
||||
X"02",X"DF",X"13",X"8D",X"3E",X"DE",X"0F",X"08",X"08",X"08",X"08",X"DF",X"0F",X"9C",X"0D",X"26",
|
||||
X"E8",X"7E",X"FD",X"0E",X"86",X"03",X"97",X"08",X"39",X"7A",X"00",X"08",X"27",X"0C",X"D6",X"15",
|
||||
X"58",X"58",X"58",X"58",X"1B",X"97",X"15",X"4F",X"20",X"FE",X"4A",X"81",X"0B",X"23",X"01",X"4F",
|
||||
X"CE",X"FE",X"41",X"BD",X"FD",X"21",X"A6",X"00",X"CE",X"FF",X"FF",X"DF",X"13",X"8D",X"04",X"8D",
|
||||
X"2A",X"20",X"FC",X"CE",X"00",X"16",X"81",X"00",X"27",X"15",X"81",X"03",X"27",X"09",X"C6",X"01",
|
||||
X"E7",X"00",X"08",X"80",X"02",X"20",X"EF",X"C6",X"91",X"E7",X"00",X"6F",X"01",X"08",X"08",X"C6",
|
||||
X"7E",X"E7",X"00",X"C6",X"FA",X"E7",X"01",X"C6",X"DD",X"E7",X"02",X"DE",X"13",X"4F",X"F6",X"00",
|
||||
X"12",X"5C",X"D7",X"12",X"D4",X"15",X"54",X"89",X"00",X"54",X"89",X"00",X"54",X"89",X"00",X"54",
|
||||
X"89",X"00",X"54",X"89",X"00",X"54",X"89",X"00",X"54",X"89",X"00",X"1B",X"48",X"48",X"48",X"48",
|
||||
X"B7",X"04",X"00",X"09",X"27",X"03",X"7E",X"00",X"16",X"39",X"36",X"A6",X"00",X"DF",X"0D",X"DE",
|
||||
X"0F",X"A7",X"00",X"08",X"DF",X"0F",X"DE",X"0D",X"08",X"5A",X"26",X"EF",X"32",X"39",X"4F",X"97",
|
||||
X"04",X"97",X"05",X"39",X"7F",X"00",X"04",X"96",X"05",X"84",X"7F",X"81",X"1D",X"26",X"01",X"4F",
|
||||
X"4C",X"97",X"05",X"39",X"86",X"0E",X"BD",X"FB",X"81",X"96",X"05",X"48",X"48",X"43",X"BD",X"FC",
|
||||
X"39",X"7C",X"00",X"17",X"BD",X"FC",X"3B",X"20",X"F8",X"86",X"03",X"BD",X"F8",X"2A",X"D6",X"06",
|
||||
X"C1",X"1F",X"26",X"01",X"5F",X"5C",X"D7",X"06",X"86",X"20",X"10",X"5F",X"81",X"14",X"23",X"05",
|
||||
X"CB",X"0E",X"4A",X"20",X"F7",X"CB",X"05",X"4A",X"26",X"FB",X"D7",X"13",X"BD",X"F8",X"3F",X"20",
|
||||
X"FB",X"96",X"07",X"26",X"09",X"7C",X"00",X"07",X"86",X"0D",X"8D",X"05",X"20",X"69",X"7E",X"FC",
|
||||
X"2E",X"16",X"58",X"1B",X"1B",X"1B",X"CE",X"FE",X"EC",X"BD",X"FD",X"21",X"A6",X"00",X"16",X"84",
|
||||
X"0F",X"97",X"14",X"54",X"54",X"54",X"54",X"D7",X"13",X"A6",X"01",X"16",X"54",X"54",X"54",X"54",
|
||||
X"D7",X"15",X"84",X"0F",X"97",X"11",X"DF",X"0B",X"CE",X"FE",X"4D",X"7A",X"00",X"11",X"2B",X"08",
|
||||
X"A6",X"00",X"4C",X"BD",X"FD",X"21",X"20",X"F3",X"DF",X"18",X"BD",X"FC",X"75",X"DE",X"0B",X"A6",
|
||||
X"02",X"97",X"1A",X"BD",X"FC",X"87",X"DE",X"0B",X"A6",X"03",X"97",X"16",X"A6",X"04",X"97",X"17",
|
||||
X"A6",X"05",X"16",X"A6",X"06",X"CE",X"FF",X"55",X"BD",X"FD",X"21",X"17",X"DF",X"1B",X"7F",X"00",
|
||||
X"23",X"BD",X"FD",X"21",X"DF",X"1D",X"39",X"96",X"13",X"97",X"22",X"DE",X"1B",X"DF",X"0D",X"DE",
|
||||
X"0D",X"A6",X"00",X"9B",X"23",X"97",X"21",X"9C",X"1D",X"27",X"26",X"D6",X"14",X"08",X"DF",X"0D",
|
||||
X"CE",X"00",X"24",X"96",X"21",X"4A",X"26",X"FD",X"A6",X"00",X"B7",X"04",X"00",X"08",X"9C",X"1F",
|
||||
X"26",X"F1",X"5A",X"27",X"DA",X"08",X"09",X"08",X"09",X"08",X"09",X"08",X"09",X"01",X"01",X"20",
|
||||
X"DF",X"96",X"15",X"8D",X"62",X"7A",X"00",X"22",X"26",X"C1",X"96",X"07",X"26",X"46",X"96",X"16",
|
||||
X"27",X"42",X"7A",X"00",X"17",X"27",X"3D",X"9B",X"23",X"97",X"23",X"DE",X"1B",X"5F",X"96",X"23",
|
||||
X"7D",X"00",X"16",X"2B",X"06",X"AB",X"00",X"25",X"08",X"20",X"0B",X"AB",X"00",X"27",X"02",X"25",
|
||||
X"05",X"5D",X"27",X"08",X"20",X"0F",X"5D",X"26",X"03",X"DF",X"1B",X"5C",X"08",X"9C",X"1D",X"26",
|
||||
X"DD",X"5D",X"26",X"01",X"39",X"DF",X"1D",X"96",X"15",X"27",X"06",X"8D",X"08",X"96",X"1A",X"8D",
|
||||
X"16",X"7E",X"FB",X"E7",X"39",X"CE",X"00",X"24",X"DF",X"0F",X"DE",X"18",X"E6",X"00",X"08",X"BD",
|
||||
X"FB",X"0A",X"DE",X"0F",X"DF",X"1F",X"39",X"4D",X"27",X"2B",X"DE",X"18",X"DF",X"0D",X"CE",X"00",
|
||||
X"24",X"97",X"12",X"DF",X"0F",X"DE",X"0D",X"D6",X"12",X"D7",X"11",X"E6",X"01",X"54",X"54",X"54",
|
||||
X"54",X"08",X"DF",X"0D",X"DE",X"0F",X"A6",X"00",X"10",X"7A",X"00",X"11",X"26",X"FA",X"A7",X"00",
|
||||
X"08",X"9C",X"1F",X"26",X"DE",X"39",X"8E",X"00",X"7F",X"B6",X"04",X"02",X"0E",X"43",X"84",X"1F",
|
||||
X"D6",X"08",X"27",X"09",X"2A",X"03",X"BD",X"FA",X"48",X"4A",X"BD",X"FA",X"89",X"5F",X"81",X"0E",
|
||||
X"27",X"02",X"D7",X"06",X"81",X"12",X"27",X"02",X"D7",X"07",X"F6",X"EF",X"FD",X"C1",X"7E",X"26",
|
||||
X"03",X"BD",X"EF",X"FD",X"4D",X"27",X"27",X"4A",X"81",X"0C",X"22",X"08",X"BD",X"FB",X"81",X"BD",
|
||||
X"FB",X"E7",X"20",X"1A",X"81",X"1B",X"22",X"0E",X"80",X"0D",X"48",X"CE",X"FD",X"58",X"8D",X"21",
|
||||
X"EE",X"00",X"AD",X"00",X"20",X"08",X"80",X"1C",X"BD",X"F8",X"2A",X"BD",X"F8",X"3F",X"96",X"04",
|
||||
X"9A",X"05",X"27",X"FE",X"4F",X"97",X"07",X"96",X"04",X"27",X"03",X"7E",X"F9",X"13",X"7E",X"FB",
|
||||
X"34",X"DF",X"0D",X"9B",X"0E",X"97",X"0E",X"24",X"03",X"7C",X"00",X"0D",X"DE",X"0D",X"39",X"0F",
|
||||
X"8E",X"00",X"7F",X"CE",X"FF",X"FF",X"5F",X"E9",X"00",X"09",X"8C",X"F8",X"00",X"26",X"F8",X"E1",
|
||||
X"00",X"27",X"01",X"3E",X"86",X"01",X"BD",X"F8",X"2A",X"BD",X"F8",X"3F",X"F6",X"EF",X"FA",X"C1",
|
||||
X"7E",X"26",X"DC",X"BD",X"EF",X"FA",X"20",X"D7",X"FB",X"49",X"F9",X"13",X"FB",X"24",X"F8",X"8C",
|
||||
X"FB",X"71",X"FB",X"1E",X"F8",X"CD",X"F8",X"94",X"F9",X"1C",X"F9",X"23",X"F9",X"A6",X"F9",X"D4",
|
||||
X"F9",X"F3",X"FA",X"44",X"FA",X"84",X"40",X"01",X"00",X"10",X"E1",X"00",X"80",X"FF",X"FF",X"28",
|
||||
X"01",X"00",X"08",X"81",X"02",X"00",X"FF",X"FF",X"28",X"81",X"00",X"FC",X"01",X"02",X"00",X"FC",
|
||||
X"FF",X"FF",X"01",X"00",X"18",X"41",X"04",X"80",X"00",X"FF",X"8C",X"5B",X"B6",X"40",X"BF",X"49",
|
||||
X"A4",X"73",X"73",X"A4",X"49",X"BF",X"40",X"B6",X"5B",X"8C",X"0C",X"7F",X"1D",X"0F",X"FB",X"7F",
|
||||
X"23",X"0F",X"15",X"FE",X"08",X"50",X"8B",X"88",X"3E",X"3F",X"02",X"3E",X"7C",X"04",X"03",X"FF",
|
||||
X"3E",X"3F",X"2C",X"E2",X"7C",X"12",X"0D",X"74",X"7C",X"0D",X"0E",X"41",X"7C",X"23",X"0B",X"50",
|
||||
X"7C",X"1D",X"29",X"F2",X"7C",X"3F",X"02",X"3E",X"F8",X"04",X"03",X"FF",X"7C",X"3F",X"2C",X"E2",
|
||||
X"F8",X"12",X"0D",X"74",X"F8",X"0D",X"0E",X"41",X"F8",X"23",X"0B",X"50",X"F8",X"1D",X"2F",X"F2",
|
||||
X"F8",X"23",X"05",X"A8",X"F8",X"12",X"06",X"BA",X"F8",X"04",X"07",X"FF",X"7C",X"37",X"04",X"C1",
|
||||
X"7C",X"23",X"05",X"A8",X"7C",X"12",X"06",X"BA",X"3E",X"04",X"07",X"FF",X"3E",X"37",X"04",X"C1",
|
||||
X"3E",X"23",X"05",X"A8",X"1F",X"12",X"06",X"BA",X"1F",X"04",X"07",X"FF",X"1F",X"37",X"04",X"C1",
|
||||
X"1F",X"23",X"16",X"A0",X"FE",X"1D",X"17",X"F9",X"7F",X"37",X"13",X"06",X"7F",X"3F",X"08",X"FA",
|
||||
X"FE",X"04",X"0F",X"FF",X"FE",X"0D",X"0E",X"41",X"FE",X"23",X"0B",X"50",X"FE",X"1D",X"5F",X"E4",
|
||||
X"00",X"47",X"3F",X"37",X"30",X"29",X"23",X"1D",X"17",X"12",X"0D",X"08",X"04",X"08",X"7F",X"D9",
|
||||
X"FF",X"D9",X"7F",X"24",X"00",X"24",X"08",X"00",X"40",X"80",X"00",X"FF",X"00",X"80",X"40",X"10",
|
||||
X"7F",X"B0",X"D9",X"F5",X"FF",X"F5",X"D9",X"B0",X"7F",X"4E",X"24",X"09",X"00",X"09",X"24",X"4E",
|
||||
X"10",X"7F",X"C5",X"EC",X"E7",X"BF",X"8D",X"6D",X"6A",X"7F",X"94",X"92",X"71",X"40",X"17",X"12",
|
||||
X"39",X"10",X"FF",X"FF",X"FF",X"FF",X"00",X"00",X"00",X"00",X"FF",X"FF",X"FF",X"FF",X"00",X"00",
|
||||
X"00",X"00",X"48",X"8A",X"95",X"A0",X"AB",X"B5",X"BF",X"C8",X"D1",X"DA",X"E1",X"E8",X"EE",X"F3",
|
||||
X"F7",X"FB",X"FD",X"FE",X"FF",X"FE",X"FD",X"FB",X"F7",X"F3",X"EE",X"E8",X"E1",X"DA",X"D1",X"C8",
|
||||
X"BF",X"B5",X"AB",X"A0",X"95",X"8A",X"7F",X"75",X"6A",X"5F",X"54",X"4A",X"40",X"37",X"2E",X"25",
|
||||
X"1E",X"17",X"11",X"0C",X"08",X"04",X"02",X"01",X"00",X"01",X"02",X"04",X"08",X"0C",X"11",X"17",
|
||||
X"1E",X"25",X"2E",X"37",X"40",X"4A",X"54",X"5F",X"6A",X"75",X"7F",X"10",X"59",X"7B",X"98",X"AC",
|
||||
X"B3",X"AC",X"98",X"7B",X"59",X"37",X"19",X"06",X"00",X"06",X"19",X"37",X"81",X"24",X"00",X"00",
|
||||
X"00",X"16",X"31",X"12",X"05",X"1A",X"FF",X"00",X"27",X"6D",X"11",X"05",X"11",X"01",X"0F",X"01",
|
||||
X"47",X"11",X"31",X"00",X"01",X"00",X"0D",X"1B",X"F4",X"12",X"00",X"00",X"00",X"14",X"47",X"41",
|
||||
X"45",X"00",X"00",X"00",X"0F",X"5B",X"21",X"35",X"11",X"FF",X"00",X"0D",X"1B",X"15",X"00",X"00",
|
||||
X"FD",X"00",X"01",X"69",X"31",X"11",X"00",X"01",X"00",X"03",X"6A",X"01",X"15",X"01",X"01",X"01",
|
||||
X"01",X"47",X"F6",X"53",X"03",X"00",X"02",X"06",X"94",X"6A",X"10",X"02",X"00",X"02",X"06",X"9A",
|
||||
X"1F",X"12",X"00",X"FF",X"10",X"04",X"69",X"31",X"11",X"00",X"FF",X"00",X"0D",X"00",X"12",X"06",
|
||||
X"00",X"FF",X"01",X"09",X"28",X"A0",X"98",X"90",X"88",X"80",X"78",X"70",X"68",X"60",X"58",X"50",
|
||||
X"44",X"40",X"01",X"01",X"02",X"02",X"04",X"04",X"08",X"08",X"10",X"10",X"30",X"60",X"C0",X"E0",
|
||||
X"01",X"01",X"02",X"02",X"03",X"04",X"05",X"06",X"07",X"08",X"09",X"0A",X"0C",X"80",X"7C",X"78",
|
||||
X"74",X"70",X"74",X"78",X"7C",X"80",X"01",X"01",X"02",X"02",X"04",X"04",X"08",X"08",X"10",X"20",
|
||||
X"28",X"30",X"38",X"40",X"48",X"50",X"60",X"70",X"80",X"A0",X"B0",X"C0",X"08",X"40",X"08",X"40",
|
||||
X"08",X"40",X"08",X"40",X"08",X"40",X"08",X"40",X"08",X"40",X"08",X"40",X"08",X"40",X"08",X"40",
|
||||
X"01",X"02",X"04",X"08",X"09",X"0A",X"0B",X"0C",X"0E",X"0F",X"10",X"12",X"14",X"16",X"40",X"10",
|
||||
X"08",X"01",X"01",X"01",X"01",X"01",X"02",X"02",X"03",X"03",X"04",X"04",X"05",X"06",X"08",X"0A",
|
||||
X"0C",X"10",X"14",X"18",X"20",X"30",X"40",X"50",X"40",X"30",X"20",X"10",X"0C",X"0A",X"08",X"07",
|
||||
X"06",X"05",X"04",X"03",X"02",X"02",X"01",X"01",X"01",X"07",X"08",X"09",X"0A",X"0C",X"08",X"17",
|
||||
X"18",X"19",X"1A",X"1B",X"1C",X"00",X"00",X"00",X"FC",X"B6",X"F8",X"01",X"FD",X"2F",X"F8",X"01");
|
||||
begin
|
||||
process(clk)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
data <= rom_data(to_integer(unsigned(addr)));
|
||||
end if;
|
||||
end process;
|
||||
end architecture;
|
||||
@@ -30,7 +30,10 @@ port(
|
||||
clk_0p89 : in std_logic;
|
||||
reset : in std_logic;
|
||||
select_sound : in std_logic_vector(5 downto 0);
|
||||
audio_out : out std_logic_vector( 7 downto 0)
|
||||
audio_out : out std_logic_vector( 7 downto 0);
|
||||
rom_addr : out std_logic_vector(11 downto 0);
|
||||
rom_do : in std_logic_vector( 7 downto 0);
|
||||
rom_vma : out std_logic
|
||||
);
|
||||
end defender_sound_board;
|
||||
|
||||
@@ -43,13 +46,14 @@ architecture struct of defender_sound_board is
|
||||
signal cpu_do : std_logic_vector( 7 downto 0);
|
||||
signal cpu_rw : std_logic;
|
||||
signal cpu_irq : std_logic;
|
||||
signal cpu_vma : std_logic;
|
||||
|
||||
signal wram_cs : std_logic;
|
||||
signal wram_we : std_logic;
|
||||
signal wram_do : std_logic_vector( 7 downto 0);
|
||||
|
||||
signal rom_cs : std_logic;
|
||||
signal rom_do : std_logic_vector( 7 downto 0);
|
||||
-- signal rom_do : std_logic_vector( 7 downto 0);
|
||||
|
||||
-- pia port a
|
||||
-- bit 0-7 audio output
|
||||
@@ -78,11 +82,9 @@ begin
|
||||
|
||||
reset_n <= not reset;
|
||||
|
||||
|
||||
|
||||
-- pia cs
|
||||
wram_cs <= '1' when cpu_addr(15 downto 8) = X"00" else '0'; -- 0000-007F
|
||||
pia_cs <= '1' when cpu_addr(15 downto 12) = X"0" and cpu_addr(10) = '1' else '0'; -- 8400-8403 ? => 0400-0403
|
||||
pia_cs <= '1' when cpu_addr(14 downto 12) = "000" and cpu_addr(10) = '1' else '0'; -- 8400-8403 ? => 0400-0403
|
||||
rom_cs <= '1' when cpu_addr(15 downto 12) = X"F" else '0'; -- F800-FFFF
|
||||
|
||||
-- write enables
|
||||
@@ -98,8 +100,10 @@ cpu_di <=
|
||||
-- pia I/O
|
||||
audio_out <= pia_pa_o;
|
||||
|
||||
pia_pb_i(4 downto 0) <= select_sound(4 downto 0);
|
||||
pia_pb_i(6 downto 5) <= "11"; -- assume DS1-1 and DS1-2 open
|
||||
pia_pb_i(5 downto 0) <= select_sound(5 downto 0);
|
||||
--pia_pb_i(4 downto 0) <= select_sound(4 downto 0);
|
||||
--pia_pb_i(6 downto 5) <= "11"; -- assume DS1-1 and DS1-2 open
|
||||
pia_pb_i(6) <= '1';
|
||||
pia_pb_i(7) <= '1'; -- Handshake to ? from rom board (drawings are confusing)
|
||||
|
||||
-- pia Cb1
|
||||
@@ -114,7 +118,7 @@ port map(
|
||||
clk => clk_0p89,-- E clock input (falling edge)
|
||||
rst => reset, -- reset input (active high)
|
||||
rw => cpu_rw, -- read not write output
|
||||
vma => open, -- valid memory address (active high)
|
||||
vma => cpu_vma, -- valid memory address (active high)
|
||||
address => cpu_addr, -- address bus output
|
||||
data_in => cpu_di, -- data bus input
|
||||
data_out => cpu_do, -- data bus output
|
||||
@@ -127,12 +131,14 @@ port map(
|
||||
);
|
||||
|
||||
-- cpu program rom
|
||||
cpu_prog_rom : entity work.defender_sound
|
||||
port map(
|
||||
clk => clk_0p89,
|
||||
addr => cpu_addr(10 downto 0),
|
||||
data => rom_do
|
||||
);
|
||||
--cpu_prog_rom : entity work.defender_sound
|
||||
--port map(
|
||||
-- clk => clk_0p89,
|
||||
-- addr => cpu_addr(10 downto 0),
|
||||
-- data => rom_do
|
||||
--);
|
||||
rom_vma <= rom_cs and cpu_vma;
|
||||
rom_addr <= cpu_addr(11 downto 0);
|
||||
|
||||
-- cpu wram
|
||||
cpu_ram : entity work.gen_ram
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
-- -----------------------------------------------------------------------
|
||||
--
|
||||
-- Syntiac's generic VHDL support files.
|
||||
--
|
||||
-- -----------------------------------------------------------------------
|
||||
-- Copyright 2005-2008 by Peter Wendrich (pwsoft@syntiac.com)
|
||||
-- http://www.syntiac.com/fpga64.html
|
||||
--
|
||||
-- Modified April 2016 by Dar (darfpga@aol.fr)
|
||||
-- http://darfpga.blogspot.fr
|
||||
-- Remove address register when writing
|
||||
--
|
||||
-- -----------------------------------------------------------------------
|
||||
--
|
||||
-- dpram.vhd
|
||||
--
|
||||
-- -----------------------------------------------------------------------
|
||||
--
|
||||
-- generic ram.
|
||||
--
|
||||
-- -----------------------------------------------------------------------
|
||||
|
||||
library IEEE;
|
||||
use IEEE.STD_LOGIC_1164.ALL;
|
||||
use IEEE.numeric_std.ALL;
|
||||
|
||||
-- -----------------------------------------------------------------------
|
||||
|
||||
entity dpram is
|
||||
generic (
|
||||
dWidth : integer := 8;
|
||||
aWidth : integer := 10
|
||||
);
|
||||
port (
|
||||
clk_a : in std_logic;
|
||||
we_a : in std_logic := '0';
|
||||
addr_a : in std_logic_vector((aWidth-1) downto 0);
|
||||
d_a : in std_logic_vector((dWidth-1) downto 0) := (others => '0');
|
||||
q_a : out std_logic_vector((dWidth-1) downto 0);
|
||||
|
||||
clk_b : in std_logic;
|
||||
we_b : in std_logic := '0';
|
||||
addr_b : in std_logic_vector((aWidth-1) downto 0);
|
||||
d_b : in std_logic_vector((dWidth-1) downto 0) := (others => '0');
|
||||
q_b : out std_logic_vector((dWidth-1) downto 0)
|
||||
);
|
||||
end entity;
|
||||
|
||||
-- -----------------------------------------------------------------------
|
||||
|
||||
architecture rtl of dpram is
|
||||
subtype addressRange is integer range 0 to ((2**aWidth)-1);
|
||||
type ramDef is array(addressRange) of std_logic_vector((dWidth-1) downto 0);
|
||||
signal ram: ramDef;
|
||||
signal addr_a_reg: std_logic_vector((aWidth-1) downto 0);
|
||||
signal addr_b_reg: std_logic_vector((aWidth-1) downto 0);
|
||||
begin
|
||||
|
||||
-- -----------------------------------------------------------------------
|
||||
process(clk_a)
|
||||
begin
|
||||
if rising_edge(clk_a) then
|
||||
if we_a = '1' then
|
||||
ram(to_integer(unsigned(addr_a))) <= d_a;
|
||||
end if;
|
||||
q_a <= ram(to_integer(unsigned(addr_a)));
|
||||
end if;
|
||||
end process;
|
||||
|
||||
process(clk_b)
|
||||
begin
|
||||
if rising_edge(clk_b) then
|
||||
if we_b = '1' then
|
||||
ram(to_integer(unsigned(addr_b))) <= d_b;
|
||||
end if;
|
||||
q_b <= ram(to_integer(unsigned(addr_b)));
|
||||
end if;
|
||||
end process;
|
||||
|
||||
end architecture;
|
||||
|
||||
@@ -1,553 +0,0 @@
|
||||
--===========================================================================--
|
||||
--
|
||||
-- S Y N T H E Z I A B L E I/O Port C O R E
|
||||
--
|
||||
-- www.OpenCores.Org - May 2004
|
||||
-- This core adheres to the GNU public license
|
||||
--
|
||||
-- File name : pia6821.vhd
|
||||
--
|
||||
-- Purpose : Implements 2 x 8 bit parallel I/O ports
|
||||
-- with programmable data direction registers
|
||||
--
|
||||
-- Dependencies : ieee.Std_Logic_1164
|
||||
-- ieee.std_logic_unsigned
|
||||
--
|
||||
-- Author : John E. Kent
|
||||
--
|
||||
--===========================================================================----
|
||||
--
|
||||
-- Revision History:
|
||||
--
|
||||
-- Date: Revision Author
|
||||
-- 1 May 2004 0.0 John Kent
|
||||
-- Initial version developed from ioport.vhd
|
||||
--
|
||||
--
|
||||
-- Unkown date 0.0.1 found at Pacedev repository
|
||||
-- remove High Z output and and oe signal
|
||||
--
|
||||
-- 18 October 2017 0.0.2 DarFpga
|
||||
-- Set output to low level when in data is in input mode
|
||||
-- (to avoid infered latch warning)
|
||||
--
|
||||
--===========================================================================----
|
||||
--
|
||||
-- Memory Map
|
||||
--
|
||||
-- IO + $00 - Port A Data & Direction register
|
||||
-- IO + $01 - Port A Control register
|
||||
-- IO + $02 - Port B Data & Direction Direction Register
|
||||
-- IO + $03 - Port B Control Register
|
||||
--
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.std_logic_unsigned.all;
|
||||
|
||||
entity pia6821 is
|
||||
port (
|
||||
clk : in std_logic;
|
||||
rst : in std_logic;
|
||||
cs : in std_logic;
|
||||
rw : in std_logic;
|
||||
addr : in std_logic_vector(1 downto 0);
|
||||
data_in : in std_logic_vector(7 downto 0);
|
||||
data_out : out std_logic_vector(7 downto 0);
|
||||
irqa : out std_logic;
|
||||
irqb : out std_logic;
|
||||
pa_i : in std_logic_vector(7 downto 0);
|
||||
pa_o : out std_logic_vector(7 downto 0);
|
||||
pa_oe : out std_logic_vector(7 downto 0);
|
||||
ca1 : in std_logic;
|
||||
ca2_i : in std_logic;
|
||||
ca2_o : out std_logic;
|
||||
ca2_oe : out std_logic;
|
||||
pb_i : in std_logic_vector(7 downto 0);
|
||||
pb_o : out std_logic_vector(7 downto 0);
|
||||
pb_oe : out std_logic_vector(7 downto 0);
|
||||
cb1 : in std_logic;
|
||||
cb2_i : in std_logic;
|
||||
cb2_o : out std_logic;
|
||||
cb2_oe : out std_logic
|
||||
);
|
||||
end;
|
||||
|
||||
architecture pia_arch of pia6821 is
|
||||
|
||||
signal porta_ddr : std_logic_vector(7 downto 0);
|
||||
signal porta_data : std_logic_vector(7 downto 0);
|
||||
signal porta_ctrl : std_logic_vector(5 downto 0);
|
||||
signal porta_read : std_logic;
|
||||
|
||||
signal portb_ddr : std_logic_vector(7 downto 0);
|
||||
signal portb_data : std_logic_vector(7 downto 0);
|
||||
signal portb_ctrl : std_logic_vector(5 downto 0);
|
||||
signal portb_read : std_logic;
|
||||
signal portb_write : std_logic;
|
||||
|
||||
signal ca1_del : std_logic;
|
||||
signal ca1_rise : std_logic;
|
||||
signal ca1_fall : std_logic;
|
||||
signal ca1_edge : std_logic;
|
||||
signal irqa1 : std_logic;
|
||||
|
||||
signal ca2_del : std_logic;
|
||||
signal ca2_rise : std_logic;
|
||||
signal ca2_fall : std_logic;
|
||||
signal ca2_edge : std_logic;
|
||||
signal irqa2 : std_logic;
|
||||
signal ca2_out : std_logic;
|
||||
|
||||
signal cb1_del : std_logic;
|
||||
signal cb1_rise : std_logic;
|
||||
signal cb1_fall : std_logic;
|
||||
signal cb1_edge : std_logic;
|
||||
signal irqb1 : std_logic;
|
||||
|
||||
signal cb2_del : std_logic;
|
||||
signal cb2_rise : std_logic;
|
||||
signal cb2_fall : std_logic;
|
||||
signal cb2_edge : std_logic;
|
||||
signal irqb2 : std_logic;
|
||||
signal cb2_out : std_logic;
|
||||
|
||||
begin
|
||||
|
||||
--------------------------------
|
||||
--
|
||||
-- read I/O port
|
||||
--
|
||||
--------------------------------
|
||||
|
||||
pia_read : process( addr, cs,
|
||||
irqa1, irqa2, irqb1, irqb2,
|
||||
porta_ddr, portb_ddr,
|
||||
porta_data, portb_data,
|
||||
porta_ctrl, portb_ctrl,
|
||||
pa_i, pb_i )
|
||||
variable count : integer;
|
||||
begin
|
||||
case addr is
|
||||
when "00" =>
|
||||
for count in 0 to 7 loop
|
||||
if porta_ctrl(2) = '0' then
|
||||
data_out(count) <= porta_ddr(count);
|
||||
porta_read <= '0';
|
||||
else
|
||||
if porta_ddr(count) = '1' then
|
||||
data_out(count) <= porta_data(count);
|
||||
else
|
||||
data_out(count) <= pa_i(count);
|
||||
end if;
|
||||
porta_read <= cs;
|
||||
end if;
|
||||
end loop;
|
||||
portb_read <= '0';
|
||||
|
||||
when "01" =>
|
||||
data_out <= irqa1 & irqa2 & porta_ctrl;
|
||||
porta_read <= '0';
|
||||
portb_read <= '0';
|
||||
|
||||
when "10" =>
|
||||
for count in 0 to 7 loop
|
||||
if portb_ctrl(2) = '0' then
|
||||
data_out(count) <= portb_ddr(count);
|
||||
portb_read <= '0';
|
||||
else
|
||||
if portb_ddr(count) = '1' then
|
||||
data_out(count) <= portb_data(count);
|
||||
else
|
||||
data_out(count) <= pb_i(count);
|
||||
end if;
|
||||
portb_read <= cs;
|
||||
end if;
|
||||
end loop;
|
||||
porta_read <= '0';
|
||||
|
||||
when "11" =>
|
||||
data_out <= irqb1 & irqb2 & portb_ctrl;
|
||||
porta_read <= '0';
|
||||
portb_read <= '0';
|
||||
|
||||
when others =>
|
||||
data_out <= "00000000";
|
||||
porta_read <= '0';
|
||||
portb_read <= '0';
|
||||
|
||||
end case;
|
||||
end process;
|
||||
|
||||
---------------------------------
|
||||
--
|
||||
-- Write I/O ports
|
||||
--
|
||||
---------------------------------
|
||||
|
||||
pia_write : process( clk, rst, addr, cs, rw, data_in,
|
||||
porta_ctrl, portb_ctrl,
|
||||
porta_data, portb_data,
|
||||
porta_ddr, portb_ddr )
|
||||
begin
|
||||
if rst = '1' then
|
||||
porta_ddr <= "00000000";
|
||||
porta_data <= "00000000";
|
||||
porta_ctrl <= "000000";
|
||||
portb_ddr <= "00000000";
|
||||
portb_data <= "00000000";
|
||||
portb_ctrl <= "000000";
|
||||
portb_write <= '0';
|
||||
elsif clk'event and clk = '1' then
|
||||
if cs = '1' and rw = '0' then
|
||||
case addr is
|
||||
when "00" =>
|
||||
if porta_ctrl(2) = '0' then
|
||||
porta_ddr <= data_in;
|
||||
porta_data <= porta_data;
|
||||
else
|
||||
porta_ddr <= porta_ddr;
|
||||
porta_data <= data_in;
|
||||
end if;
|
||||
porta_ctrl <= porta_ctrl;
|
||||
portb_ddr <= portb_ddr;
|
||||
portb_data <= portb_data;
|
||||
portb_ctrl <= portb_ctrl;
|
||||
portb_write <= '0';
|
||||
when "01" =>
|
||||
porta_ddr <= porta_ddr;
|
||||
porta_data <= porta_data;
|
||||
porta_ctrl <= data_in(5 downto 0);
|
||||
portb_ddr <= portb_ddr;
|
||||
portb_data <= portb_data;
|
||||
portb_ctrl <= portb_ctrl;
|
||||
portb_write <= '0';
|
||||
when "10" =>
|
||||
porta_ddr <= porta_ddr;
|
||||
porta_data <= porta_data;
|
||||
porta_ctrl <= porta_ctrl;
|
||||
if portb_ctrl(2) = '0' then
|
||||
portb_ddr <= data_in;
|
||||
portb_data <= portb_data;
|
||||
portb_write <= '0';
|
||||
else
|
||||
portb_ddr <= portb_ddr;
|
||||
portb_data <= data_in;
|
||||
portb_write <= '1';
|
||||
end if;
|
||||
portb_ctrl <= portb_ctrl;
|
||||
when "11" =>
|
||||
porta_ddr <= porta_ddr;
|
||||
porta_data <= porta_data;
|
||||
porta_ctrl <= porta_ctrl;
|
||||
portb_ddr <= portb_ddr;
|
||||
portb_data <= portb_data;
|
||||
portb_ctrl <= data_in(5 downto 0);
|
||||
portb_write <= '0';
|
||||
when others =>
|
||||
porta_ddr <= porta_ddr;
|
||||
porta_data <= porta_data;
|
||||
porta_ctrl <= porta_ctrl;
|
||||
portb_ddr <= portb_ddr;
|
||||
portb_data <= portb_data;
|
||||
portb_ctrl <= portb_ctrl;
|
||||
portb_write <= '0';
|
||||
end case;
|
||||
else
|
||||
porta_ddr <= porta_ddr;
|
||||
porta_data <= porta_data;
|
||||
porta_ctrl <= porta_ctrl;
|
||||
portb_data <= portb_data;
|
||||
portb_ddr <= portb_ddr;
|
||||
portb_ctrl <= portb_ctrl;
|
||||
portb_write <= '0';
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
---------------------------------
|
||||
--
|
||||
-- direction control port a
|
||||
--
|
||||
---------------------------------
|
||||
porta_direction : process ( porta_data, porta_ddr )
|
||||
variable count : integer;
|
||||
begin
|
||||
for count in 0 to 7 loop
|
||||
if porta_ddr(count) = '1' then
|
||||
pa_o(count) <= porta_data(count);
|
||||
pa_oe(count) <= '1';
|
||||
else
|
||||
pa_o(count) <= '0';
|
||||
pa_oe(count) <= '0';
|
||||
end if;
|
||||
end loop;
|
||||
end process;
|
||||
|
||||
---------------------------------
|
||||
--
|
||||
-- CA1 Edge detect
|
||||
--
|
||||
---------------------------------
|
||||
ca1_input : process( clk, rst, ca1, ca1_del,
|
||||
ca1_rise, ca1_fall, ca1_edge,
|
||||
irqa1, porta_ctrl, porta_read )
|
||||
begin
|
||||
if rst = '1' then
|
||||
ca1_del <= '0';
|
||||
ca1_rise <= '0';
|
||||
ca1_fall <= '0';
|
||||
ca1_edge <= '0';
|
||||
irqa1 <= '0';
|
||||
elsif clk'event and clk = '0' then
|
||||
ca1_del <= ca1;
|
||||
ca1_rise <= (not ca1_del) and ca1;
|
||||
ca1_fall <= ca1_del and (not ca1);
|
||||
if ca1_edge = '1' then
|
||||
irqa1 <= '1';
|
||||
elsif porta_read = '1' then
|
||||
irqa1 <= '0';
|
||||
else
|
||||
irqa1 <= irqa1;
|
||||
end if;
|
||||
end if;
|
||||
|
||||
if porta_ctrl(1) = '0' then
|
||||
ca1_edge <= ca1_fall;
|
||||
else
|
||||
ca1_edge <= ca1_rise;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
---------------------------------
|
||||
--
|
||||
-- CA2 Edge detect
|
||||
--
|
||||
---------------------------------
|
||||
ca2_input : process( clk, rst, ca2_i, ca2_del,
|
||||
ca2_rise, ca2_fall, ca2_edge,
|
||||
irqa2, porta_ctrl, porta_read )
|
||||
begin
|
||||
if rst = '1' then
|
||||
ca2_del <= '0';
|
||||
ca2_rise <= '0';
|
||||
ca2_fall <= '0';
|
||||
ca2_edge <= '0';
|
||||
irqa2 <= '0';
|
||||
elsif clk'event and clk = '0' then
|
||||
ca2_del <= ca2_i;
|
||||
ca2_rise <= (not ca2_del) and ca2_i;
|
||||
ca2_fall <= ca2_del and (not ca2_i);
|
||||
if porta_ctrl(5) = '0' and ca2_edge = '1' then
|
||||
irqa2 <= '1';
|
||||
elsif porta_read = '1' then
|
||||
irqa2 <= '0';
|
||||
else
|
||||
irqa2 <= irqa2;
|
||||
end if;
|
||||
end if;
|
||||
|
||||
if porta_ctrl(4) = '0' then
|
||||
ca2_edge <= ca2_fall;
|
||||
else
|
||||
ca2_edge <= ca2_rise;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
---------------------------------
|
||||
--
|
||||
-- CA2 output control
|
||||
--
|
||||
---------------------------------
|
||||
ca2_output : process( clk, rst, porta_ctrl, porta_read, ca1_edge, ca2_out )
|
||||
begin
|
||||
if rst='1' then
|
||||
ca2_out <= '0';
|
||||
elsif clk'event and clk='0' then
|
||||
case porta_ctrl(5 downto 3) is
|
||||
when "100" => -- read PA clears, CA1 edge sets
|
||||
if porta_read = '1' then
|
||||
ca2_out <= '0';
|
||||
elsif ca1_edge = '1' then
|
||||
ca2_out <= '1';
|
||||
else
|
||||
ca2_out <= ca2_out;
|
||||
end if;
|
||||
when "101" => -- read PA clears, E sets
|
||||
ca2_out <= not porta_read;
|
||||
when "110" => -- set low
|
||||
ca2_out <= '0';
|
||||
when "111" => -- set high
|
||||
ca2_out <= '1';
|
||||
when others => -- no change
|
||||
ca2_out <= ca2_out;
|
||||
end case;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
---------------------------------
|
||||
--
|
||||
-- CA2 direction control
|
||||
--
|
||||
---------------------------------
|
||||
ca2_direction : process( porta_ctrl, ca2_out )
|
||||
begin
|
||||
if porta_ctrl(5) = '0' then
|
||||
ca2_oe <= '0';
|
||||
ca2_o <= '0';
|
||||
else
|
||||
ca2_o <= ca2_out;
|
||||
ca2_oe <= '1';
|
||||
end if;
|
||||
end process;
|
||||
|
||||
---------------------------------
|
||||
--
|
||||
-- direction control port b
|
||||
--
|
||||
---------------------------------
|
||||
portb_direction : process ( portb_data, portb_ddr )
|
||||
variable count : integer;
|
||||
begin
|
||||
for count in 0 to 7 loop
|
||||
if portb_ddr(count) = '1' then
|
||||
pb_o(count) <= portb_data(count);
|
||||
pb_oe(count) <= '1';
|
||||
else
|
||||
pb_o(count) <= '0';
|
||||
pb_oe(count) <= '0';
|
||||
end if;
|
||||
end loop;
|
||||
end process;
|
||||
|
||||
---------------------------------
|
||||
--
|
||||
-- CB1 Edge detect
|
||||
--
|
||||
---------------------------------
|
||||
cb1_input : process( clk, rst, cb1, cb1_del,
|
||||
cb1_rise, cb1_fall, cb1_edge,
|
||||
irqb1, portb_ctrl, portb_read )
|
||||
begin
|
||||
if rst = '1' then
|
||||
cb1_del <= '0';
|
||||
cb1_rise <= '0';
|
||||
cb1_fall <= '0';
|
||||
cb1_edge <= '0';
|
||||
irqb1 <= '0';
|
||||
elsif clk'event and clk = '0' then
|
||||
cb1_del <= cb1;
|
||||
cb1_rise <= (not cb1_del) and cb1;
|
||||
cb1_fall <= cb1_del and (not cb1);
|
||||
if cb1_edge = '1' then
|
||||
irqb1 <= '1';
|
||||
elsif portb_read = '1' then
|
||||
irqb1 <= '0';
|
||||
else
|
||||
irqb1 <= irqb1;
|
||||
end if;
|
||||
end if;
|
||||
|
||||
if portb_ctrl(1) = '0' then
|
||||
cb1_edge <= cb1_fall;
|
||||
else
|
||||
cb1_edge <= cb1_rise;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
---------------------------------
|
||||
--
|
||||
-- CB2 Edge detect
|
||||
--
|
||||
---------------------------------
|
||||
cb2_input : process( clk, rst, cb2_i, cb2_del,
|
||||
cb2_rise, cb2_fall, cb2_edge,
|
||||
irqb2, portb_ctrl, portb_read )
|
||||
begin
|
||||
if rst = '1' then
|
||||
cb2_del <= '0';
|
||||
cb2_rise <= '0';
|
||||
cb2_fall <= '0';
|
||||
cb2_edge <= '0';
|
||||
irqb2 <= '0';
|
||||
elsif clk'event and clk = '0' then
|
||||
cb2_del <= cb2_i;
|
||||
cb2_rise <= (not cb2_del) and cb2_i;
|
||||
cb2_fall <= cb2_del and (not cb2_i);
|
||||
if portb_ctrl(5) = '0' and cb2_edge = '1' then
|
||||
irqb2 <= '1';
|
||||
elsif portb_read = '1' then
|
||||
irqb2 <= '0';
|
||||
else
|
||||
irqb2 <= irqb2;
|
||||
end if;
|
||||
end if;
|
||||
|
||||
if portb_ctrl(4) = '0' then
|
||||
cb2_edge <= cb2_fall;
|
||||
else
|
||||
cb2_edge <= cb2_rise;
|
||||
end if;
|
||||
|
||||
end process;
|
||||
|
||||
---------------------------------
|
||||
--
|
||||
-- CB2 output control
|
||||
--
|
||||
---------------------------------
|
||||
cb2_output : process( clk, rst, portb_ctrl, portb_write, cb1_edge, cb2_out )
|
||||
begin
|
||||
if rst='1' then
|
||||
cb2_out <= '0';
|
||||
elsif clk'event and clk='0' then
|
||||
case portb_ctrl(5 downto 3) is
|
||||
when "100" => -- write PB clears, CA1 edge sets
|
||||
if portb_write = '1' then
|
||||
cb2_out <= '0';
|
||||
elsif cb1_edge = '1' then
|
||||
cb2_out <= '1';
|
||||
else
|
||||
cb2_out <= cb2_out;
|
||||
end if;
|
||||
when "101" => -- write PB clears, E sets
|
||||
cb2_out <= not portb_write;
|
||||
when "110" => -- set low
|
||||
cb2_out <= '0';
|
||||
when "111" => -- set high
|
||||
cb2_out <= '1';
|
||||
when others => -- no change
|
||||
cb2_out <= cb2_out;
|
||||
end case;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
---------------------------------
|
||||
--
|
||||
-- CB2 direction control
|
||||
--
|
||||
---------------------------------
|
||||
cb2_direction : process( portb_ctrl, cb2_out )
|
||||
begin
|
||||
if portb_ctrl(5) = '0' then
|
||||
cb2_oe <= '0';
|
||||
cb2_o <= '0';
|
||||
else
|
||||
cb2_o <= cb2_out;
|
||||
cb2_oe <= '1';
|
||||
end if;
|
||||
end process;
|
||||
|
||||
---------------------------------
|
||||
--
|
||||
-- IRQ control
|
||||
--
|
||||
---------------------------------
|
||||
pia_irq : process( irqa1, irqa2, irqb1, irqb2, porta_ctrl, portb_ctrl )
|
||||
begin
|
||||
irqa <= (irqa1 and porta_ctrl(0)) or (irqa2 and porta_ctrl(3));
|
||||
irqb <= (irqb1 and portb_ctrl(0)) or (irqb2 and portb_ctrl(3));
|
||||
end process;
|
||||
|
||||
end pia_arch;
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
-- ************************************************************
|
||||
-- THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE!
|
||||
--
|
||||
-- 13.1.4 Build 182 03/12/2014 SJ Web Edition
|
||||
-- 13.1.4 Build 182 03/12/2014 Patches 4.26 SJ Web Edition
|
||||
-- ************************************************************
|
||||
|
||||
|
||||
@@ -156,9 +156,9 @@ BEGIN
|
||||
altpll_component : altpll
|
||||
GENERIC MAP (
|
||||
bandwidth_type => "AUTO",
|
||||
clk0_divide_by => 3,
|
||||
clk0_divide_by => 1,
|
||||
clk0_duty_cycle => 50,
|
||||
clk0_multiply_by => 4,
|
||||
clk0_multiply_by => 2,
|
||||
clk0_phase_shift => "0",
|
||||
clk1_divide_by => 9,
|
||||
clk1_duty_cycle => 50,
|
||||
@@ -255,7 +255,7 @@ END SYN;
|
||||
-- Retrieval info: PRIVATE: DUTY_CYCLE0 STRING "50.00000000"
|
||||
-- Retrieval info: PRIVATE: DUTY_CYCLE1 STRING "50.00000000"
|
||||
-- Retrieval info: PRIVATE: DUTY_CYCLE2 STRING "50.00000000"
|
||||
-- Retrieval info: PRIVATE: EFF_OUTPUT_FREQ_VALUE0 STRING "36.000000"
|
||||
-- Retrieval info: PRIVATE: EFF_OUTPUT_FREQ_VALUE0 STRING "54.000000"
|
||||
-- Retrieval info: PRIVATE: EFF_OUTPUT_FREQ_VALUE1 STRING "6.000000"
|
||||
-- Retrieval info: PRIVATE: EFF_OUTPUT_FREQ_VALUE2 STRING "0.890110"
|
||||
-- Retrieval info: PRIVATE: EXPLICIT_SWITCHOVER_COUNTER STRING "0"
|
||||
@@ -284,7 +284,7 @@ END SYN;
|
||||
-- Retrieval info: PRIVATE: MIRROR_CLK0 STRING "0"
|
||||
-- Retrieval info: PRIVATE: MIRROR_CLK1 STRING "0"
|
||||
-- Retrieval info: PRIVATE: MIRROR_CLK2 STRING "0"
|
||||
-- Retrieval info: PRIVATE: MULT_FACTOR0 NUMERIC "4"
|
||||
-- Retrieval info: PRIVATE: MULT_FACTOR0 NUMERIC "6"
|
||||
-- Retrieval info: PRIVATE: MULT_FACTOR1 NUMERIC "2"
|
||||
-- Retrieval info: PRIVATE: MULT_FACTOR2 NUMERIC "3"
|
||||
-- Retrieval info: PRIVATE: NORMAL_MODE_RADIO STRING "1"
|
||||
@@ -343,9 +343,9 @@ END SYN;
|
||||
-- Retrieval info: PRIVATE: ZERO_DELAY_RADIO STRING "0"
|
||||
-- Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all
|
||||
-- Retrieval info: CONSTANT: BANDWIDTH_TYPE STRING "AUTO"
|
||||
-- Retrieval info: CONSTANT: CLK0_DIVIDE_BY NUMERIC "3"
|
||||
-- Retrieval info: CONSTANT: CLK0_DIVIDE_BY NUMERIC "1"
|
||||
-- Retrieval info: CONSTANT: CLK0_DUTY_CYCLE NUMERIC "50"
|
||||
-- Retrieval info: CONSTANT: CLK0_MULTIPLY_BY NUMERIC "4"
|
||||
-- Retrieval info: CONSTANT: CLK0_MULTIPLY_BY NUMERIC "2"
|
||||
-- Retrieval info: CONSTANT: CLK0_PHASE_SHIFT STRING "0"
|
||||
-- Retrieval info: CONSTANT: CLK1_DIVIDE_BY NUMERIC "9"
|
||||
-- Retrieval info: CONSTANT: CLK1_DUTY_CYCLE NUMERIC "50"
|
||||
|
||||
@@ -1,79 +1,134 @@
|
||||
//
|
||||
// sdram.v
|
||||
//
|
||||
// Static RAM controller implementation using SDRAM MT48LC16M16A2
|
||||
// sdram controller implementation for the MiST board
|
||||
// https://github.com/mist-devel/mist-board
|
||||
//
|
||||
// Copyright (c) 2013 Till Harbaum <till@harbaum.org>
|
||||
// Copyright (c) 2019 Gyorgy Szombathelyi
|
||||
//
|
||||
// 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
|
||||
// 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.
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
|
||||
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.
|
||||
module sdram (
|
||||
|
||||
// interface 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, // two byte masks
|
||||
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
|
||||
|
||||
// cpu/chipset interface
|
||||
input init_n, // init signal after FPGA config to initialize RAM
|
||||
input clk, // sdram clock
|
||||
|
||||
input port1_req,
|
||||
output reg port1_ack,
|
||||
input port1_we,
|
||||
input [23:1] port1_a,
|
||||
input [1:0] port1_ds,
|
||||
input [15:0] port1_d,
|
||||
output [15:0] port1_q,
|
||||
|
||||
input [15:1] cpu1_addr,
|
||||
output reg [15:0] cpu1_q,
|
||||
|
||||
input port2_req,
|
||||
output reg port2_ack,
|
||||
input port2_we,
|
||||
input [23:1] port2_a,
|
||||
input [1:0] port2_ds,
|
||||
input [15:0] port2_d,
|
||||
output [15:0] port2_q,
|
||||
|
||||
input [15:1] snd_addr,
|
||||
output reg [15:0] snd_q
|
||||
);
|
||||
|
||||
assign SDRAM_nCS = command[3];
|
||||
assign SDRAM_nRAS = command[2];
|
||||
assign SDRAM_nCAS = command[1];
|
||||
assign SDRAM_nWE = command[0];
|
||||
assign SDRAM_CKE = cke;
|
||||
parameter MHZ = 80; // 80 MHz default clock, adjust to calculate the refresh rate correctly
|
||||
|
||||
// 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 RASCAS_DELAY = 3'd2; // tRCD=20ns -> 2 cycles@<100MHz
|
||||
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/3 allowed
|
||||
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 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;
|
||||
localparam MODE = { 3'b000, NO_WRITE_BURST, OP_MODE, CAS_LATENCY, ACCESS_TYPE, BURST_LENGTH};
|
||||
|
||||
// SDRAM commands
|
||||
// 64ms/8192 rows = 7.8us -> 842 cycles@108MHz
|
||||
localparam RFRSH_CYCLES = 16'd78*MHZ/10;
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// ------------------------ cycle state machine ------------------------
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
SDRAM state machine for 2 bank interleaved access
|
||||
1 word burst, CL2
|
||||
cmd issued registered
|
||||
0 RAS0 cas1
|
||||
1 ras0
|
||||
2 CAS0 data1 returned
|
||||
3 RAS1 cas0
|
||||
4 ras1
|
||||
5 CAS1 data0 returned
|
||||
*/
|
||||
|
||||
localparam STATE_RAS0 = 3'd0; // first state in cycle
|
||||
localparam STATE_RAS1 = 3'd3; // Second ACTIVE command after RAS0 + tRRD (15ns)
|
||||
localparam STATE_CAS0 = STATE_RAS0 + RASCAS_DELAY; // CAS phase - 3
|
||||
localparam STATE_CAS1 = STATE_RAS1 + RASCAS_DELAY; // CAS phase - 5
|
||||
localparam STATE_READ0 = 3'd0; //STATE_CAS0 + CAS_LATENCY + 1'd1; // 7
|
||||
localparam STATE_READ1 = 3'd3;
|
||||
localparam STATE_LAST = 3'd5;
|
||||
|
||||
reg [2:0] t;
|
||||
|
||||
always @(posedge clk) begin
|
||||
t <= t + 1'd1;
|
||||
if (t == STATE_LAST) t <= STATE_RAS0;
|
||||
end
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// --------------------------- startup/reset ---------------------------
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
// wait 1ms (32 8Mhz cycles) after FPGA config is done before going
|
||||
// into normal operation. Initialize the ram in the last 16 reset cycles (cycles 15-0)
|
||||
reg [4:0] reset;
|
||||
reg init = 1'b1;
|
||||
always @(posedge clk, negedge init_n) begin
|
||||
if(!init_n) begin
|
||||
reset <= 5'h1f;
|
||||
init <= 1'b1;
|
||||
end else begin
|
||||
if((t == STATE_LAST) && (reset != 0)) reset <= reset - 5'd1;
|
||||
init <= !(reset == 0);
|
||||
end
|
||||
end
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// ------------------ generate ram control signals ---------------------
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
// all possible commands
|
||||
localparam CMD_INHIBIT = 4'b1111;
|
||||
localparam CMD_NOP = 4'b0111;
|
||||
localparam CMD_ACTIVE = 4'b0011;
|
||||
@@ -84,171 +139,191 @@ 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;
|
||||
reg [3:0] sd_cmd; // current command sent to sd ram
|
||||
reg [15:0] sd_din;
|
||||
// drive control signals according to current command
|
||||
assign SDRAM_nCS = sd_cmd[3];
|
||||
assign SDRAM_nRAS = sd_cmd[2];
|
||||
assign SDRAM_nCAS = sd_cmd[1];
|
||||
assign SDRAM_nWE = sd_cmd[0];
|
||||
|
||||
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;
|
||||
reg [24:1] addr_latch[2];
|
||||
reg [24:1] addr_latch_next[2];
|
||||
reg [15:1] addr_last[2];
|
||||
reg [15:1] addr_last2[2];
|
||||
reg [15:0] din_latch[2];
|
||||
reg [1:0] oe_latch;
|
||||
reg [1:0] we_latch;
|
||||
reg [1:0] ds[2];
|
||||
|
||||
state_t state = STATE_STARTUP;
|
||||
localparam PORT_NONE = 2'd0;
|
||||
localparam PORT_CPU1 = 2'd1;
|
||||
localparam PORT_REQ = 2'd2;
|
||||
|
||||
localparam PORT_SND = 2'd1;
|
||||
|
||||
reg [2:0] next_port[2];
|
||||
reg [2:0] port[2];
|
||||
reg port1_state;
|
||||
reg port2_state;
|
||||
|
||||
reg refresh;
|
||||
reg [10:0] refresh_cnt;
|
||||
wire need_refresh = (refresh_cnt >= RFRSH_CYCLES);
|
||||
|
||||
// PORT1: bank 0,1
|
||||
always @(*) begin
|
||||
if (refresh) begin
|
||||
next_port[0] = PORT_NONE;
|
||||
addr_latch_next[0] = addr_latch[0];
|
||||
end else if (port1_req ^ port1_state) begin
|
||||
next_port[0] = PORT_REQ;
|
||||
addr_latch_next[0] = { 1'b0, port1_a };
|
||||
end else if (cpu1_addr != addr_last[PORT_CPU1]) begin
|
||||
next_port[0] = PORT_CPU1;
|
||||
addr_latch_next[0] = { 9'd0, cpu1_addr };
|
||||
end else begin
|
||||
next_port[0] = PORT_NONE;
|
||||
addr_latch_next[0] = addr_latch[0];
|
||||
end
|
||||
end
|
||||
|
||||
// PORT2: bank 2,3
|
||||
always @(*) begin
|
||||
if (port2_req ^ port2_state) begin
|
||||
next_port[1] = PORT_REQ;
|
||||
addr_latch_next[1] = { 1'b1, port2_a };
|
||||
end else if (snd_addr != addr_last2[PORT_SND]) begin
|
||||
next_port[1] = PORT_SND;
|
||||
addr_latch_next[1] = { 1'b1, 8'd0, snd_addr };
|
||||
end else begin
|
||||
next_port[1] = PORT_NONE;
|
||||
addr_latch_next[1] = addr_latch[1];
|
||||
end
|
||||
end
|
||||
|
||||
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
|
||||
// permanently latch ram data to reduce delays
|
||||
sd_din <= SDRAM_DQ;
|
||||
SDRAM_DQ <= 16'bZZZZZZZZZZZZZZZZ;
|
||||
{ SDRAM_DQMH, SDRAM_DQML } <= 2'b11;
|
||||
sd_cmd <= CMD_NOP; // default: idle
|
||||
refresh_cnt <= refresh_cnt + 1'd1;
|
||||
|
||||
if(init) begin
|
||||
state <= STATE_STARTUP;
|
||||
refresh_count <= startup_refresh_max - sdram_startup_cycles;
|
||||
// initialization takes place at the end of the reset phase
|
||||
if(t == STATE_RAS0) begin
|
||||
|
||||
if(reset == 15) begin
|
||||
sd_cmd <= CMD_PRECHARGE;
|
||||
SDRAM_A[10] <= 1'b1; // precharge all banks
|
||||
end
|
||||
|
||||
if(reset == 10 || reset == 8) begin
|
||||
sd_cmd <= CMD_AUTO_REFRESH;
|
||||
end
|
||||
|
||||
if(reset == 2) begin
|
||||
sd_cmd <= CMD_LOAD_MODE;
|
||||
SDRAM_A <= MODE;
|
||||
SDRAM_BA <= 2'b00;
|
||||
end
|
||||
end
|
||||
end else begin
|
||||
// RAS phase
|
||||
// bank 0,1
|
||||
if(t == STATE_RAS0) begin
|
||||
addr_latch[0] <= addr_latch_next[0];
|
||||
port[0] <= next_port[0];
|
||||
{ oe_latch[0], we_latch[0] } <= 2'b00;
|
||||
|
||||
if (next_port[0] != PORT_NONE) begin
|
||||
sd_cmd <= CMD_ACTIVE;
|
||||
SDRAM_A <= addr_latch_next[0][22:10];
|
||||
SDRAM_BA <= addr_latch_next[0][24:23];
|
||||
addr_last[next_port[0]] <= addr_latch_next[0][15:1];
|
||||
if (next_port[0] == PORT_REQ) begin
|
||||
{ oe_latch[0], we_latch[0] } <= { ~port1_we, port1_we };
|
||||
ds[0] <= port1_ds;
|
||||
din_latch[0] <= port1_d;
|
||||
port1_state <= port1_req;
|
||||
end else begin
|
||||
{ oe_latch[0], we_latch[0] } <= 2'b10;
|
||||
ds[0] <= 2'b11;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// bank 2,3
|
||||
if(t == STATE_RAS1) begin
|
||||
refresh <= 1'b0;
|
||||
addr_latch[1] <= addr_latch_next[1];
|
||||
{ oe_latch[1], we_latch[1] } <= 2'b00;
|
||||
port[1] <= next_port[1];
|
||||
|
||||
if (next_port[1] != PORT_NONE) begin
|
||||
sd_cmd <= CMD_ACTIVE;
|
||||
SDRAM_A <= addr_latch_next[1][22:10];
|
||||
SDRAM_BA <= addr_latch_next[1][24:23];
|
||||
addr_last2[next_port[1]] <= addr_latch_next[1][15:1];
|
||||
if (next_port[1] == PORT_REQ) begin
|
||||
{ oe_latch[1], we_latch[1] } <= { ~port2_we, port2_we };
|
||||
ds[1] <= port2_ds;
|
||||
din_latch[1] <= port2_d;
|
||||
port2_state <= port2_req;
|
||||
end else begin
|
||||
{ oe_latch[1], we_latch[1] } <= 2'b10;
|
||||
ds[1] <= 2'b11;
|
||||
end
|
||||
end
|
||||
|
||||
if (next_port[1] == PORT_NONE && need_refresh && !we_latch[0] && !oe_latch[0]) begin
|
||||
refresh <= 1'b1;
|
||||
refresh_cnt <= 0;
|
||||
sd_cmd <= CMD_AUTO_REFRESH;
|
||||
end
|
||||
end
|
||||
|
||||
// CAS phase
|
||||
if(t == STATE_CAS0 && (we_latch[0] || oe_latch[0])) begin
|
||||
sd_cmd <= we_latch[0]?CMD_WRITE:CMD_READ;
|
||||
{ SDRAM_DQMH, SDRAM_DQML } <= ~ds[0];
|
||||
if (we_latch[0]) begin
|
||||
SDRAM_DQ <= din_latch[0];
|
||||
port1_ack <= port1_req;
|
||||
end
|
||||
SDRAM_A <= { 4'b0010, addr_latch[0][9:1] }; // auto precharge
|
||||
SDRAM_BA <= addr_latch[0][24:23];
|
||||
end
|
||||
|
||||
if(t == STATE_CAS1 && (we_latch[1] || oe_latch[1])) begin
|
||||
sd_cmd <= we_latch[1]?CMD_WRITE:CMD_READ;
|
||||
{ SDRAM_DQMH, SDRAM_DQML } <= ~ds[1];
|
||||
if (we_latch[1]) begin
|
||||
SDRAM_DQ <= din_latch[1];
|
||||
port2_ack <= port2_req;
|
||||
end
|
||||
SDRAM_A <= { 4'b0010, addr_latch[1][9:1] }; // auto precharge
|
||||
SDRAM_BA <= addr_latch[1][24:23];
|
||||
end
|
||||
|
||||
// Data returned
|
||||
if(t == STATE_READ0 && oe_latch[0]) begin
|
||||
case(port[0])
|
||||
PORT_REQ: begin port1_q <= sd_din; port1_ack <= port1_req; end
|
||||
PORT_CPU1: begin cpu1_q <= sd_din; end
|
||||
default: ;
|
||||
endcase;
|
||||
end
|
||||
if(t == STATE_READ1 && oe_latch[1]) begin
|
||||
case(port[1])
|
||||
PORT_REQ: begin port2_q <= sd_din; port2_ack <= port2_req; end
|
||||
PORT_SND: begin snd_q <= sd_din; end
|
||||
default: ;
|
||||
endcase;
|
||||
end
|
||||
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
|
||||
|
||||
Reference in New Issue
Block a user