diff --git a/verilog/sd2snes_test/address.v b/verilog/sd2snes_test/address.v new file mode 100644 index 0000000..6dae255 --- /dev/null +++ b/verilog/sd2snes_test/address.v @@ -0,0 +1,72 @@ +`timescale 1 ns / 1 ns +////////////////////////////////////////////////////////////////////////////////// +// Company: Rehkopf +// Engineer: Rehkopf +// +// Create Date: 01:13:46 05/09/2009 +// Design Name: +// Module Name: address +// Project Name: +// Target Devices: +// Tool versions: +// Description: Address logic w/ SaveRAM masking +// +// Dependencies: +// +// Revision: +// Additional Comments: +// +////////////////////////////////////////////////////////////////////////////////// +module address( + input CLK, + input [23:0] SNES_ADDR, // requested address from SNES + output [23:0] ram0_addr, + output [18:0] ram1_addr, + output [7:0] PA_addr, + output [12:0] bram_addr, + input [7:0] ram0_bank, + input ram0_linear, + output ram0_enable, + output ram1_enable, + output PA_enable, + output bram_enable, + output irq_enable, + output bank_enable, + output linear_enable +); + +wire [23:0] SRAM_SNES_ADDR; + +assign ram0bank0_enable = (SNES_ADDR[23:15] == 9'h001) | (SNES_ADDR[23:16] == 8'hC0); +assign ram0bankx_enable = (SNES_ADDR[23:16] == 8'hC8); +assign ram0linear_enable = ram0_linear & (SNES_ADDR[22] | SNES_ADDR[15]); +assign ram0_enable = ram0linear_enable | ram0bank0_enable | ram0bankx_enable; +assign ram1_enable = ~ram0_enable & (SNES_ADDR[23:20] == 4'hD); +assign PA_enable = ~ram0_enable & (SNES_ADDR[23:20] == 4'hE); +assign bram_enable = ~ram0_enable & (SNES_ADDR[23:20] == 4'hF); +wire bank_enable_ = (SNES_ADDR == 24'h0055AA); +wire irq_enable_ = (SNES_ADDR == 24'h002222); +wire linear_enable_ = (SNES_ADDR == 24'h003333); + +reg [2:0] bank_enable_r; +reg [2:0] irq_enable_r; +reg [2:0] linear_enable_r; +always @(posedge CLK) begin + bank_enable_r <= {bank_enable_r[1:0], bank_enable_}; + irq_enable_r <= {irq_enable_r[1:0], irq_enable_}; + linear_enable_r <= {linear_enable_r[1:0], linear_enable_}; +end +assign bank_enable = bank_enable_r[2]; +assign irq_enable = irq_enable_r[2]; +assign linear_enable = linear_enable_r[2]; + +assign ram0_addr = ram0_linear ? SNES_ADDR + : {2'b00,SNES_ADDR[21:0]}; + +assign ram1_addr = SNES_ADDR[18:0]; + +assign PA_addr = SNES_ADDR[7:0]; + +assign bram_addr = SNES_ADDR[12:0]; + +endmodule diff --git a/verilog/sd2snes_test/clk_test.v b/verilog/sd2snes_test/clk_test.v new file mode 100644 index 0000000..d00601d --- /dev/null +++ b/verilog/sd2snes_test/clk_test.v @@ -0,0 +1,120 @@ +`timescale 1ns / 1ps +////////////////////////////////////////////////////////////////////////////////// +// Company: +// Engineer: +// +// Create Date: 22:40:46 12/20/2010 +// Design Name: +// Module Name: clk_test +// Project Name: +// Target Devices: +// Tool versions: +// Description: +// +// Dependencies: +// +// Revision: +// Revision 0.01 - File Created +// Additional Comments: +// +////////////////////////////////////////////////////////////////////////////////// +module clk_test( + input clk, + input sysclk, + input read, + input write, + input pawr, + input pard, + input refresh, + input cpuclk, + input romsel, + output reg [31:0] snes_sysclk_freq, + output reg [31:0] snes_read_freq, + output reg [31:0] snes_write_freq, + output reg [31:0] snes_pawr_freq, + output reg [31:0] snes_pard_freq, + output reg [31:0] snes_refresh_freq, + output reg [31:0] snes_cpuclk_freq, + output reg [31:0] snes_romsel_freq +); + +reg [31:0] sysclk_counter; +reg [31:0] sysclk_value; +reg [31:0] read_value; +reg [31:0] write_value; +reg [31:0] pard_value; +reg [31:0] pawr_value; +reg [31:0] refresh_value; +reg [31:0] cpuclk_value; +reg [31:0] romsel_value; + +initial snes_sysclk_freq = 32'hFFFFFFFF; +initial sysclk_counter = 0; +initial sysclk_value = 0; +initial read_value = 0; +initial write_value = 0; +initial pard_value = 0; +initial pawr_value = 0; +initial refresh_value = 0; +initial cpuclk_value = 0; +initial romsel_value = 0; + +reg [1:0] sysclk_sreg; +reg [1:0] read_sreg; +reg [1:0] write_sreg; +reg [1:0] pard_sreg; +reg [1:0] pawr_sreg; +reg [1:0] refresh_sreg; +reg [1:0] cpuclk_sreg; +reg [1:0] romsel_sreg; + +always @(posedge clk) romsel_sreg <= {romsel_sreg[0], romsel}; +wire romsel_rising = (romsel_sreg == 2'b01); +always @(posedge clk) cpuclk_sreg <= {cpuclk_sreg[0], cpuclk}; +wire cpuclk_rising = (cpuclk_sreg == 2'b01); +always @(posedge clk) sysclk_sreg <= {sysclk_sreg[0], sysclk}; +wire sysclk_rising = (sysclk_sreg == 2'b01); +always @(posedge clk) read_sreg <= {read_sreg[0], read}; +wire read_rising = (read_sreg == 2'b01); +always @(posedge clk) write_sreg <= {write_sreg[0], write}; +wire write_rising = (write_sreg == 2'b01); +always @(posedge clk) pard_sreg <= {pard_sreg[0], pard}; +wire pard_rising = (pard_sreg == 2'b01); +always @(posedge clk) pawr_sreg <= {pawr_sreg[0], pawr}; +wire pawr_rising = (pawr_sreg == 2'b01); +always @(posedge clk) refresh_sreg <= {refresh_sreg[0], refresh}; +wire refresh_rising = (refresh_sreg == 2'b01); + +always @(posedge clk) begin + if(sysclk_counter < 96000000) begin + sysclk_counter <= sysclk_counter + 1; + if(sysclk_rising) sysclk_value <= sysclk_value + 1; + if(read_rising) read_value <= read_value + 1; + if(write_rising) write_value <= write_value + 1; + if(pard_rising) pard_value <= pard_value + 1; + if(pawr_rising) pawr_value <= pawr_value + 1; + if(refresh_rising) refresh_value <= refresh_value + 1; + if(cpuclk_rising) cpuclk_value <= cpuclk_value + 1; + if(romsel_rising) romsel_value <= romsel_value + 1; + end else begin + snes_sysclk_freq <= sysclk_value; + snes_read_freq <= read_value; + snes_write_freq <= write_value; + snes_pard_freq <= pard_value; + snes_pawr_freq <= pawr_value; + snes_refresh_freq <= refresh_value; + snes_cpuclk_freq <= cpuclk_value; + snes_romsel_freq <= romsel_value; + sysclk_counter <= 0; + sysclk_value <= 0; + read_value <= 0; + write_value <= 0; + pard_value <= 0; + pawr_value <= 0; + refresh_value <= 0; + cpuclk_value <= 0; + romsel_value <= 0; + end +end + +endmodule diff --git a/verilog/sd2snes_test/dac.v b/verilog/sd2snes_test/dac.v new file mode 100644 index 0000000..db6d059 --- /dev/null +++ b/verilog/sd2snes_test/dac.v @@ -0,0 +1,146 @@ +`timescale 1ns / 1ps +////////////////////////////////////////////////////////////////////////////////// +// Company: +// Engineer: +// +// Create Date: 19:26:11 07/23/2010 +// Design Name: +// Module Name: dac_test +// Project Name: +// Target Devices: +// Tool versions: +// Description: +// +// Dependencies: +// +// Revision: +// Revision 0.01 - File Created +// Additional Comments: +// +////////////////////////////////////////////////////////////////////////////////// +module dac( + input clkin, + input sysclk, + input we, + input[10:0] pgm_address, + input[7:0] pgm_data, + input play, + input reset, + output sdout, + output lrck, + output mclk, + output DAC_STATUS +); + +reg[8:0] dac_address_r; +wire[8:0] dac_address = dac_address_r; + +wire[31:0] dac_data; +assign DAC_STATUS = dac_address_r[8]; +reg[7:0] vol_reg; +reg[7:0] vol_target_reg; +reg[1:0] vol_latch_reg; +reg vol_valid; +reg[2:0] sysclk_sreg; +wire sysclk_rising = (sysclk_sreg[2:1] == 2'b01); + +reg [25:0] interpol_count; + +always @(posedge clkin) begin + sysclk_sreg <= {sysclk_sreg[1:0], sysclk}; +end + +dac_buf snes_dac_buf ( + .clka(clkin), + .wea(~we), // Bus [0 : 0] + .addra(pgm_address), // Bus [10 : 0] + .dina(pgm_data), // Bus [7 : 0] + .clkb(clkin), + .addrb(dac_address), // Bus [8 : 0] + .doutb(dac_data)); // Bus [31 : 0] + +reg [8:0] cnt; +reg [15:0] smpcnt; +reg [1:0] samples; +reg [15:0] smpshift; + +assign mclk = cnt[2]; // mclk = clk/8 +assign lrck = cnt[8]; // lrck = mclk/128 +wire sclk = cnt[3]; // sclk = lrck*32 + +reg [2:0] lrck_sreg; +reg [2:0] sclk_sreg; +wire lrck_rising = ({lrck_sreg[2:1]} == 2'b01); +wire lrck_falling = ({lrck_sreg[2:1]} == 2'b10); + +wire sclk_rising = ({sclk_sreg[2:1]} == 2'b01); + +reg sdout_reg; +assign sdout = sdout_reg; + +reg [1:0] reset_sreg; +wire reset_rising = (reset_sreg[1:0] == 2'b01); + +reg play_r; + +initial begin + cnt = 9'h100; + smpcnt = 16'b0; + lrck_sreg = 2'b11; + sclk_sreg = 1'b0; + dac_address_r = 10'b0; + vol_valid = 1'b0; + vol_latch_reg = 1'b0; + vol_reg = 8'h0; + vol_target_reg = 8'hff; + samples <= 2'b00; +end + +always @(posedge clkin) begin + if(reset_rising) begin + dac_address_r <= 0; + interpol_count <= 0; + end else if(sysclk_rising) begin + if(interpol_count > 59378938) begin + interpol_count <= interpol_count + 122500 - 59501439; + dac_address_r <= dac_address_r + play_r; + end else begin + interpol_count <= interpol_count + 122500; + end + end +end + +always @(posedge clkin) begin + cnt <= cnt + 1; + lrck_sreg <= {lrck_sreg[1:0], lrck}; + sclk_sreg <= {sclk_sreg[1:0], sclk}; + play_r <= play; + reset_sreg <= {reset_sreg[0], reset}; +end + +// ramp volume only every 4 samples +always @(posedge clkin) begin + if (lrck_rising && &samples[1:0]) begin + if(vol_reg > vol_target_reg) + vol_reg <= vol_reg - 1; + else if(vol_reg < vol_target_reg) + vol_reg <= vol_reg + 1; + end +end + +always @(posedge clkin) begin + if (lrck_rising) begin // right channel + smpshift <= (({16'h0, dac_data[31:16]^16'h8000} * vol_reg) >> 8) ^ 16'h8000; + samples <= samples + 1; + end else if (lrck_falling) begin // left channel + smpshift <= (({16'h0, dac_data[15:0]^16'h8000} * vol_reg) >> 8) ^ 16'h8000; + end else begin + if (sclk_rising) begin + smpcnt <= smpcnt + 1; + sdout_reg <= smpshift[15]; + smpshift <= {smpshift[14:0], 1'b0}; + end + end +end + +endmodule diff --git a/verilog/sd2snes_test/dcm.v b/verilog/sd2snes_test/dcm.v new file mode 100644 index 0000000..90b516e --- /dev/null +++ b/verilog/sd2snes_test/dcm.v @@ -0,0 +1,72 @@ +`timescale 1ns / 1ps +////////////////////////////////////////////////////////////////////////////////// +// Company: +// Engineer: +// +// Create Date: 13:06:52 06/28/2009 +// Design Name: +// Module Name: dcm +// Project Name: +// Target Devices: +// Tool versions: +// Description: +// +// Dependencies: +// +// Revision: +// Revision 0.01 - File Created +// Additional Comments: +// +////////////////////////////////////////////////////////////////////////////////// +module my_dcm ( + input CLKIN, + output CLKFX, + output LOCKED, + input RST, + output[7:0] STATUS + ); + + // DCM: Digital Clock Manager Circuit + // Spartan-3 + // Xilinx HDL Language Template, version 11.1 + + DCM #( + .SIM_MODE("SAFE"), // Simulation: "SAFE" vs. "FAST", see "Synthesis and Simulation Design Guide" for details + .CLKDV_DIVIDE(2.0), // Divide by: 1.5,2.0,2.5,3.0,3.5,4.0,4.5,5.0,5.5,6.0,6.5 + // 7.0,7.5,8.0,9.0,10.0,11.0,12.0,13.0,14.0,15.0 or 16.0 + .CLKFX_DIVIDE(1), // Can be any integer from 1 to 32 + .CLKFX_MULTIPLY(4), // Can be any integer from 2 to 32 + .CLKIN_DIVIDE_BY_2("FALSE"), // TRUE/FALSE to enable CLKIN divide by two feature + .CLKIN_PERIOD(41.667), // Specify period of input clock + .CLKOUT_PHASE_SHIFT("NONE"), // Specify phase shift of NONE, FIXED or VARIABLE + .CLK_FEEDBACK("NONE"), // Specify clock feedback of NONE, 1X or 2X + .DESKEW_ADJUST("SYSTEM_SYNCHRONOUS"), // SOURCE_SYNCHRONOUS, SYSTEM_SYNCHRONOUS or + // an integer from 0 to 15 + .DFS_FREQUENCY_MODE("LOW"), // HIGH or LOW frequency mode for frequency synthesis + .DLL_FREQUENCY_MODE("LOW"), // HIGH or LOW frequency mode for DLL + .DUTY_CYCLE_CORRECTION("TRUE"), // Duty cycle correction, TRUE or FALSE + .FACTORY_JF(16'hFFFF), // FACTORY JF values +// .LOC("DCM_X0Y0"), + .PHASE_SHIFT(0), // Amount of fixed phase shift from -255 to 255 + .STARTUP_WAIT("TRUE") // Delay configuration DONE until DCM LOCK, TRUE/FALSE + ) DCM_inst ( + .CLK0(CLK0), // 0 degree DCM CLK output + .CLK180(CLK180), // 180 degree DCM CLK output + .CLK270(CLK270), // 270 degree DCM CLK output + .CLK2X(CLK2X), // 2X DCM CLK output + .CLK2X180(CLK2X180), // 2X, 180 degree DCM CLK out + .CLK90(CLK90), // 90 degree DCM CLK output + .CLKDV(CLKDV), // Divided DCM CLK out (CLKDV_DIVIDE) + .CLKFX(CLKFX), // DCM CLK synthesis out (M/D) + .CLKFX180(CLKFX180), // 180 degree CLK synthesis out + .LOCKED(LOCKED), // DCM LOCK status output + .PSDONE(PSDONE), // Dynamic phase adjust done output + .STATUS(STATUS), // 8-bit DCM status bits output + .CLKFB(CLKFB), // DCM clock feedback + .CLKIN(CLKIN), // Clock input (from IBUFG, BUFG or DCM) + .PSCLK(PSCLK), // Dynamic phase adjust clock input + .PSEN(PSEN), // Dynamic phase adjust enable input + .PSINCDEC(PSINCDEC), // Dynamic phase adjust increment/decrement + .RST(RST) // DCM asynchronous reset input + ); +endmodule diff --git a/verilog/sd2snes_test/ipcore_dir/PA.xco b/verilog/sd2snes_test/ipcore_dir/PA.xco new file mode 100644 index 0000000..e25d689 --- /dev/null +++ b/verilog/sd2snes_test/ipcore_dir/PA.xco @@ -0,0 +1,105 @@ +############################################################## +# +# Xilinx Core Generator version 13.2 +# Date: Fri Dec 9 20:36:25 2011 +# +############################################################## +# +# This file contains the customisation parameters for a +# Xilinx CORE Generator IP GUI. It is strongly recommended +# that you do not manually alter this file as it may cause +# unexpected and unsupported behavior. +# +############################################################## +# +# Generated from component: xilinx.com:ip:blk_mem_gen:6.2 +# +############################################################## +# +# BEGIN Project Options +SET addpads = false +SET asysymbol = true +SET busformat = BusFormatAngleBracketNotRipped +SET createndf = false +SET designentry = Verilog +SET device = xa3s400 +SET devicefamily = aspartan3 +SET flowvendor = Other +SET formalverification = false +SET foundationsym = false +SET implementationfiletype = Ngc +SET package = pqg208 +SET removerpms = false +SET simulationfiles = Behavioral +SET speedgrade = -4q +SET verilogsim = true +SET vhdlsim = false +# END Project Options +# BEGIN Select +SELECT Block_Memory_Generator xilinx.com:ip:blk_mem_gen:6.2 +# END Select +# BEGIN Parameters +CSET additional_inputs_for_power_estimation=false +CSET algorithm=Minimum_Area +CSET assume_synchronous_clk=true +CSET axi_id_width=4 +CSET axi_slave_type=Memory_Slave +CSET axi_type=AXI4_Full +CSET byte_size=9 +CSET coe_file=no_coe_file_loaded +CSET collision_warnings=ALL +CSET component_name=PA +CSET disable_collision_warnings=false +CSET disable_out_of_range_warnings=false +CSET ecc=false +CSET ecctype=No_ECC +CSET enable_a=Always_Enabled +CSET enable_b=Always_Enabled +CSET error_injection_type=Single_Bit_Error_Injection +CSET fill_remaining_memory_locations=false +CSET interface_type=Native +CSET load_init_file=false +CSET memory_type=Simple_Dual_Port_RAM +CSET operating_mode_a=WRITE_FIRST +CSET operating_mode_b=WRITE_FIRST +CSET output_reset_value_a=0 +CSET output_reset_value_b=0 +CSET pipeline_stages=0 +CSET port_a_clock=100 +CSET port_a_enable_rate=100 +CSET port_a_write_rate=50 +CSET port_b_clock=100 +CSET port_b_enable_rate=100 +CSET port_b_write_rate=0 +CSET primitive=8kx2 +CSET read_width_a=8 +CSET read_width_b=8 +CSET register_porta_input_of_softecc=false +CSET register_porta_output_of_memory_core=false +CSET register_porta_output_of_memory_primitives=false +CSET register_portb_output_of_memory_core=false +CSET register_portb_output_of_memory_primitives=false +CSET register_portb_output_of_softecc=false +CSET remaining_memory_locations=0 +CSET reset_memory_latch_a=false +CSET reset_memory_latch_b=false +CSET reset_priority_a=CE +CSET reset_priority_b=CE +CSET reset_type=SYNC +CSET softecc=false +CSET use_axi_id=false +CSET use_byte_write_enable=false +CSET use_error_injection_pins=false +CSET use_regcea_pin=false +CSET use_regceb_pin=false +CSET use_rsta_pin=false +CSET use_rstb_pin=false +CSET write_depth_a=256 +CSET write_width_a=8 +CSET write_width_b=8 +# END Parameters +# BEGIN Extra information +MISC pkg_timestamp=2011-03-11T08:24:14.000Z +# END Extra information +GENERATE +# CRC: 213d12c4 diff --git a/verilog/sd2snes_test/ipcore_dir/PA.xise b/verilog/sd2snes_test/ipcore_dir/PA.xise new file mode 100644 index 0000000..33142d2 --- /dev/null +++ b/verilog/sd2snes_test/ipcore_dir/PA.xise @@ -0,0 +1,378 @@ + + + +
+ + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/verilog/sd2snes_test/ipcore_dir/bram.xco b/verilog/sd2snes_test/ipcore_dir/bram.xco new file mode 100644 index 0000000..4312d26 --- /dev/null +++ b/verilog/sd2snes_test/ipcore_dir/bram.xco @@ -0,0 +1,105 @@ +############################################################## +# +# Xilinx Core Generator version 13.2 +# Date: Fri Dec 9 20:35:22 2011 +# +############################################################## +# +# This file contains the customisation parameters for a +# Xilinx CORE Generator IP GUI. It is strongly recommended +# that you do not manually alter this file as it may cause +# unexpected and unsupported behavior. +# +############################################################## +# +# Generated from component: xilinx.com:ip:blk_mem_gen:6.2 +# +############################################################## +# +# BEGIN Project Options +SET addpads = false +SET asysymbol = true +SET busformat = BusFormatAngleBracketNotRipped +SET createndf = false +SET designentry = Verilog +SET device = xa3s400 +SET devicefamily = aspartan3 +SET flowvendor = Other +SET formalverification = false +SET foundationsym = false +SET implementationfiletype = Ngc +SET package = pqg208 +SET removerpms = false +SET simulationfiles = Behavioral +SET speedgrade = -4q +SET verilogsim = true +SET vhdlsim = false +# END Project Options +# BEGIN Select +SELECT Block_Memory_Generator xilinx.com:ip:blk_mem_gen:6.2 +# END Select +# BEGIN Parameters +CSET additional_inputs_for_power_estimation=false +CSET algorithm=Minimum_Area +CSET assume_synchronous_clk=true +CSET axi_id_width=4 +CSET axi_slave_type=Memory_Slave +CSET axi_type=AXI4_Full +CSET byte_size=9 +CSET coe_file=no_coe_file_loaded +CSET collision_warnings=ALL +CSET component_name=bram +CSET disable_collision_warnings=false +CSET disable_out_of_range_warnings=false +CSET ecc=false +CSET ecctype=No_ECC +CSET enable_a=Always_Enabled +CSET enable_b=Always_Enabled +CSET error_injection_type=Single_Bit_Error_Injection +CSET fill_remaining_memory_locations=false +CSET interface_type=Native +CSET load_init_file=false +CSET memory_type=True_Dual_Port_RAM +CSET operating_mode_a=WRITE_FIRST +CSET operating_mode_b=WRITE_FIRST +CSET output_reset_value_a=0 +CSET output_reset_value_b=0 +CSET pipeline_stages=0 +CSET port_a_clock=100 +CSET port_a_enable_rate=100 +CSET port_a_write_rate=50 +CSET port_b_clock=100 +CSET port_b_enable_rate=100 +CSET port_b_write_rate=50 +CSET primitive=8kx2 +CSET read_width_a=8 +CSET read_width_b=8 +CSET register_porta_input_of_softecc=false +CSET register_porta_output_of_memory_core=false +CSET register_porta_output_of_memory_primitives=false +CSET register_portb_output_of_memory_core=false +CSET register_portb_output_of_memory_primitives=false +CSET register_portb_output_of_softecc=false +CSET remaining_memory_locations=0 +CSET reset_memory_latch_a=false +CSET reset_memory_latch_b=false +CSET reset_priority_a=CE +CSET reset_priority_b=CE +CSET reset_type=SYNC +CSET softecc=false +CSET use_axi_id=false +CSET use_byte_write_enable=false +CSET use_error_injection_pins=false +CSET use_regcea_pin=false +CSET use_regceb_pin=false +CSET use_rsta_pin=false +CSET use_rstb_pin=false +CSET write_depth_a=8192 +CSET write_width_a=8 +CSET write_width_b=8 +# END Parameters +# BEGIN Extra information +MISC pkg_timestamp=2011-03-11T08:24:14.000Z +# END Extra information +GENERATE +# CRC: cb4729a5 diff --git a/verilog/sd2snes_test/ipcore_dir/bram.xise b/verilog/sd2snes_test/ipcore_dir/bram.xise new file mode 100644 index 0000000..8bf0faa --- /dev/null +++ b/verilog/sd2snes_test/ipcore_dir/bram.xise @@ -0,0 +1,378 @@ + + + +
+ + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/verilog/sd2snes_test/ipcore_dir/dac_buf.xco b/verilog/sd2snes_test/ipcore_dir/dac_buf.xco new file mode 100644 index 0000000..316029b --- /dev/null +++ b/verilog/sd2snes_test/ipcore_dir/dac_buf.xco @@ -0,0 +1,105 @@ +############################################################## +# +# Xilinx Core Generator version 13.2 +# Date: Fri Dec 9 20:37:13 2011 +# +############################################################## +# +# This file contains the customisation parameters for a +# Xilinx CORE Generator IP GUI. It is strongly recommended +# that you do not manually alter this file as it may cause +# unexpected and unsupported behavior. +# +############################################################## +# +# Generated from component: xilinx.com:ip:blk_mem_gen:6.1 +# +############################################################## +# +# BEGIN Project Options +SET addpads = false +SET asysymbol = true +SET busformat = BusFormatAngleBracketNotRipped +SET createndf = false +SET designentry = Verilog +SET device = xa3s400 +SET devicefamily = aspartan3 +SET flowvendor = Foundation_ISE +SET formalverification = false +SET foundationsym = false +SET implementationfiletype = Ngc +SET package = pqg208 +SET removerpms = false +SET simulationfiles = Behavioral +SET speedgrade = -4q +SET verilogsim = true +SET vhdlsim = false +# END Project Options +# BEGIN Select +SELECT Block_Memory_Generator xilinx.com:ip:blk_mem_gen:6.1 +# END Select +# BEGIN Parameters +CSET additional_inputs_for_power_estimation=false +CSET algorithm=Minimum_Area +CSET assume_synchronous_clk=true +CSET axi_id_width=4 +CSET axi_slave_type=Memory_Slave +CSET axi_type=AXI4_Full +CSET byte_size=9 +CSET coe_file=no_coe_file_loaded +CSET collision_warnings=ALL +CSET component_name=dac_buf +CSET disable_collision_warnings=false +CSET disable_out_of_range_warnings=false +CSET ecc=false +CSET ecctype=No_ECC +CSET enable_a=Always_Enabled +CSET enable_b=Always_Enabled +CSET error_injection_type=Single_Bit_Error_Injection +CSET fill_remaining_memory_locations=false +CSET interface_type=Native +CSET load_init_file=false +CSET memory_type=Simple_Dual_Port_RAM +CSET operating_mode_a=WRITE_FIRST +CSET operating_mode_b=WRITE_FIRST +CSET output_reset_value_a=0 +CSET output_reset_value_b=0 +CSET pipeline_stages=0 +CSET port_a_clock=100 +CSET port_a_enable_rate=100 +CSET port_a_write_rate=50 +CSET port_b_clock=100 +CSET port_b_enable_rate=100 +CSET port_b_write_rate=0 +CSET primitive=8kx2 +CSET read_width_a=8 +CSET read_width_b=32 +CSET register_porta_input_of_softecc=false +CSET register_porta_output_of_memory_core=false +CSET register_porta_output_of_memory_primitives=false +CSET register_portb_output_of_memory_core=false +CSET register_portb_output_of_memory_primitives=false +CSET register_portb_output_of_softecc=false +CSET remaining_memory_locations=0 +CSET reset_memory_latch_a=false +CSET reset_memory_latch_b=false +CSET reset_priority_a=CE +CSET reset_priority_b=CE +CSET reset_type=SYNC +CSET softecc=false +CSET use_axi_id=false +CSET use_byte_write_enable=false +CSET use_error_injection_pins=false +CSET use_regcea_pin=false +CSET use_regceb_pin=false +CSET use_rsta_pin=false +CSET use_rstb_pin=false +CSET write_depth_a=2048 +CSET write_width_a=8 +CSET write_width_b=32 +# END Parameters +# BEGIN Extra information +MISC pkg_timestamp=2011-06-21T06:43:52.000Z +# END Extra information +GENERATE +# CRC: 360f80d1 diff --git a/verilog/sd2snes_test/ipcore_dir/dac_buf.xise b/verilog/sd2snes_test/ipcore_dir/dac_buf.xise new file mode 100644 index 0000000..81e803a --- /dev/null +++ b/verilog/sd2snes_test/ipcore_dir/dac_buf.xise @@ -0,0 +1,378 @@ + + + +
+ + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/verilog/sd2snes_test/main.ucf b/verilog/sd2snes_test/main.ucf new file mode 100644 index 0000000..e2457cb --- /dev/null +++ b/verilog/sd2snes_test/main.ucf @@ -0,0 +1,635 @@ +NET "CLKIN" TNM_NET = "CLKIN"; +TIMESPEC TS_CLKIN = PERIOD "CLKIN" 24 MHz HIGH 50 %; +//TIMESPEC TS_CLKIN = PERIOD "CLKIN" 21.5 MHz HIGH 50 %; + +NET "p113_out" IOSTANDARD = LVCMOS33; +NET "p113_out" LOC = P113; + +NET "SPI_SCK" LOC = P71; +NET "SPI_SCK" CLOCK_DEDICATED_ROUTE = FALSE; +NET "SPI_SCK" TNM_NET = "SPI_SCK"; +TIMESPEC TS_SPI_SCK = PERIOD "SPI_SCK" 48MHz HIGH 50 %; + +NET "SPI_SCK" IOSTANDARD = LVCMOS33; +NET "SPI_SCK" DRIVE = 8; +NET "SPI_SCK" PULLUP; + +NET "SNES_CS" IOSTANDARD = LVCMOS33; +NET "SNES_READ" IOSTANDARD = LVCMOS33; +NET "SNES_WRITE" IOSTANDARD = LVCMOS33; +NET "SNES_CPU_CLK" IOSTANDARD = LVCMOS33; +NET "SNES_REFRESH" IOSTANDARD = LVCMOS33; + +NET "CLKIN" IOSTANDARD = LVCMOS33; +//NET "CLKIN" PULLUP; +NET "SPI_SS" PULLUP; +//NET "DCM_RST" LOC = P46; +//NET "DCM_RST" IOSTANDARD = LVCMOS33; +NET "SNES_DATABUS_DIR" IOSTANDARD = LVCMOS33; +NET "SNES_DATABUS_OE" IOSTANDARD = LVCMOS33; +NET "SNES_IRQ" IOSTANDARD = LVCMOS33; + +NET "ROM_CE" LOC = P172; +NET "ROM_CE" IOSTANDARD = LVCMOS33; +NET "ROM_CE" DRIVE = 8; + +NET "SNES_ADDR[0]" LOC = P119; +NET "SNES_ADDR[10]" LOC = P146; +NET "SNES_ADDR[11]" LOC = P148; +NET "SNES_ADDR[12]" LOC = P147; +NET "SNES_ADDR[13]" LOC = P144; +NET "SNES_ADDR[14]" LOC = P141; +NET "SNES_ADDR[15]" LOC = P139; +NET "SNES_ADDR[16]" LOC = P137; +NET "SNES_ADDR[17]" LOC = P133; +NET "SNES_ADDR[18]" LOC = P131; +NET "SNES_ADDR[19]" LOC = P128; +NET "SNES_ADDR[1]" LOC = P122; +NET "SNES_ADDR[20]" LOC = P125; +NET "SNES_ADDR[21]" LOC = P123; +NET "SNES_ADDR[22]" LOC = P120; +NET "SNES_ADDR[23]" LOC = P117; +NET "SNES_ADDR[2]" LOC = P124; +NET "SNES_ADDR[3]" LOC = P126; +NET "SNES_ADDR[4]" LOC = P130; +NET "SNES_ADDR[5]" LOC = P132; +NET "SNES_ADDR[6]" LOC = P135; +NET "SNES_ADDR[7]" LOC = P138; +NET "SNES_ADDR[8]" LOC = P140; +NET "SNES_ADDR[9]" LOC = P143; +NET "SNES_DATA[0]" LOC = P107; +NET "SNES_DATA[1]" LOC = P102; +NET "SNES_DATA[2]" LOC = P100; +NET "SNES_DATA[3]" LOC = P96; +NET "SNES_DATA[4]" LOC = P108; +NET "SNES_DATA[5]" LOC = P106; +NET "SNES_DATA[6]" LOC = P101; +NET "SNES_DATA[7]" LOC = P97; + + +NET "CLKIN" LOC = P80; +// NET "RST" LOC = P113; +NET "MCU_OVR" LOC = P92; + + +NET "MCU_OVR" IOSTANDARD = LVCMOS33; +NET "MCU_OVR" DRIVE = 8; + +NET "MCU_RDY" LOC = P83; +NET "MCU_RDY" IOSTANDARD = LVCMOS33; +NET "MCU_RDY" DRIVE = 8; + + +NET "ROM_ADDR[0]" LOC = P166; + + +NET "ROM_ADDR[0]" IOSTANDARD = LVCMOS33; +NET "ROM_ADDR[0]" DRIVE = 8; + + +NET "ROM_ADDR[10]" LOC = P197; + + +NET "ROM_ADDR[10]" IOSTANDARD = LVCMOS33; +NET "ROM_ADDR[10]" DRIVE = 8; + + +NET "ROM_ADDR[11]" LOC = P196; + + +NET "ROM_ADDR[11]" IOSTANDARD = LVCMOS33; +NET "ROM_ADDR[11]" DRIVE = 8; + + +NET "ROM_ADDR[12]" LOC = P2; + + +NET "ROM_ADDR[12]" IOSTANDARD = LVCMOS33; +NET "ROM_ADDR[12]" DRIVE = 8; + + +NET "ROM_ADDR[13]" LOC = P194; + + +NET "ROM_ADDR[13]" IOSTANDARD = LVCMOS33; +NET "ROM_ADDR[13]" DRIVE = 8; + + +NET "ROM_ADDR[14]" LOC = P200; + + +NET "ROM_ADDR[14]" IOSTANDARD = LVCMOS33; +NET "ROM_ADDR[14]" DRIVE = 8; + + +NET "ROM_ADDR[15]" LOC = P184; + + +NET "ROM_ADDR[15]" IOSTANDARD = LVCMOS33; +NET "ROM_ADDR[15]" DRIVE = 8; + + +NET "ROM_ADDR[16]" LOC = P199; + + +NET "ROM_ADDR[16]" IOSTANDARD = LVCMOS33; +NET "ROM_ADDR[16]" DRIVE = 8; + + +NET "ROM_ADDR[17]" LOC = P11; + + +NET "ROM_ADDR[17]" IOSTANDARD = LVCMOS33; +NET "ROM_ADDR[17]" DRIVE = 8; + + +NET "ROM_ADDR[18]" LOC = P3; + + +NET "ROM_ADDR[18]" IOSTANDARD = LVCMOS33; +NET "ROM_ADDR[18]" DRIVE = 8; + + +NET "ROM_ADDR[19]" LOC = P4; + + +NET "ROM_ADDR[19]" IOSTANDARD = LVCMOS33; +NET "ROM_ADDR[19]" DRIVE = 8; + + +NET "ROM_ADDR[1]" LOC = P168; + + +NET "ROM_ADDR[1]" IOSTANDARD = LVCMOS33; +NET "ROM_ADDR[1]" DRIVE = 8; + + +NET "ROM_ADDR[20]" LOC = P191; + + +NET "ROM_ADDR[20]" IOSTANDARD = LVCMOS33; +NET "ROM_ADDR[20]" DRIVE = 8; + + +NET "ROM_ADDR[21]" LOC = P203; + + +NET "ROM_ADDR[21]" IOSTANDARD = LVCMOS33; +NET "ROM_ADDR[21]" DRIVE = 8; + + +NET "ROM_ADDR[22]" LOC = P198; + + +NET "ROM_ADDR[22]" IOSTANDARD = LVCMOS33; +NET "ROM_ADDR[22]" DRIVE = 8; + + +NET "ROM_ADDR[2]" LOC = P171; + + +NET "ROM_ADDR[2]" IOSTANDARD = LVCMOS33; +NET "ROM_ADDR[2]" DRIVE = 8; + + +NET "ROM_ADDR[3]" LOC = P165; + + +NET "ROM_ADDR[3]" IOSTANDARD = LVCMOS33; +NET "ROM_ADDR[3]" DRIVE = 8; + + +NET "ROM_ADDR[4]" LOC = P169; + + +NET "ROM_ADDR[4]" IOSTANDARD = LVCMOS33; +NET "ROM_ADDR[4]" DRIVE = 8; + + +NET "ROM_ADDR[5]" LOC = P18; + + +NET "ROM_ADDR[5]" IOSTANDARD = LVCMOS33; +NET "ROM_ADDR[5]" DRIVE = 8; + + +NET "ROM_ADDR[6]" LOC = P175; + + +NET "ROM_ADDR[6]" IOSTANDARD = LVCMOS33; +NET "ROM_ADDR[6]" DRIVE = 8; + + +NET "ROM_ADDR[7]" LOC = P167; + + +NET "ROM_ADDR[7]" IOSTANDARD = LVCMOS33; +NET "ROM_ADDR[7]" DRIVE = 8; + + +NET "ROM_ADDR[8]" LOC = P205; + + +NET "ROM_ADDR[8]" IOSTANDARD = LVCMOS33; +NET "ROM_ADDR[8]" DRIVE = 8; + + +NET "ROM_ADDR[9]" LOC = P204; + + +NET "ROM_ADDR[9]" IOSTANDARD = LVCMOS33; +NET "ROM_ADDR[9]" DRIVE = 8; + + +NET "ROM_BHE" LOC = P161; + + +NET "ROM_BHE" IOSTANDARD = LVCMOS33; +NET "ROM_BHE" DRIVE = 8; + + +NET "ROM_BLE" LOC = P156; + + +NET "ROM_BLE" IOSTANDARD = LVCMOS33; +NET "ROM_BLE" DRIVE = 8; + + +NET "ROM_DATA[0]" LOC = P176; + + +NET "ROM_DATA[0]" IOSTANDARD = LVCMOS33; +NET "ROM_DATA[0]" DRIVE = 8; + + +NET "ROM_DATA[10]" LOC = P15; + + +NET "ROM_DATA[10]" IOSTANDARD = LVCMOS33; +NET "ROM_DATA[10]" DRIVE = 8; + + +NET "ROM_DATA[11]" LOC = P12; + + +NET "ROM_DATA[11]" IOSTANDARD = LVCMOS33; +NET "ROM_DATA[11]" DRIVE = 8; + + +NET "ROM_DATA[12]" LOC = P10; + + +NET "ROM_DATA[12]" IOSTANDARD = LVCMOS33; +NET "ROM_DATA[12]" DRIVE = 8; + + +NET "ROM_DATA[13]" LOC = P7; + + +NET "ROM_DATA[13]" IOSTANDARD = LVCMOS33; +NET "ROM_DATA[13]" DRIVE = 8; + + +NET "ROM_DATA[14]" LOC = P9; + + +NET "ROM_DATA[14]" IOSTANDARD = LVCMOS33; +NET "ROM_DATA[14]" DRIVE = 8; + + +NET "ROM_DATA[15]" LOC = P5; + + +NET "ROM_DATA[15]" IOSTANDARD = LVCMOS33; +NET "ROM_DATA[15]" DRIVE = 8; + + +NET "ROM_DATA[1]" LOC = P178; + + +NET "ROM_DATA[1]" IOSTANDARD = LVCMOS33; +NET "ROM_DATA[1]" DRIVE = 8; + + +NET "ROM_DATA[2]" LOC = P181; + + +NET "ROM_DATA[2]" IOSTANDARD = LVCMOS33; +NET "ROM_DATA[2]" DRIVE = 8; + + +NET "ROM_DATA[3]" LOC = P182; + + +NET "ROM_DATA[3]" IOSTANDARD = LVCMOS33; +NET "ROM_DATA[3]" DRIVE = 8; + + +NET "ROM_DATA[4]" LOC = P183; + + +NET "ROM_DATA[4]" IOSTANDARD = LVCMOS33; +NET "ROM_DATA[4]" DRIVE = 8; + + +NET "ROM_DATA[5]" LOC = P187; + + +NET "ROM_DATA[5]" IOSTANDARD = LVCMOS33; +NET "ROM_DATA[5]" DRIVE = 8; + + +NET "ROM_DATA[6]" LOC = P185; + + +NET "ROM_DATA[6]" IOSTANDARD = LVCMOS33; +NET "ROM_DATA[6]" DRIVE = 8; + + +NET "ROM_DATA[7]" LOC = P189; + + +NET "ROM_DATA[7]" IOSTANDARD = LVCMOS33; +NET "ROM_DATA[7]" DRIVE = 8; + + +NET "ROM_DATA[8]" LOC = P16; + + +NET "ROM_DATA[8]" IOSTANDARD = LVCMOS33; +NET "ROM_DATA[8]" DRIVE = 8; + + +NET "ROM_DATA[9]" LOC = P13; + + +NET "ROM_DATA[9]" IOSTANDARD = LVCMOS33; +NET "ROM_DATA[9]" DRIVE = 8; + + +NET "ROM_OE" LOC = P162; + + +NET "ROM_OE" IOSTANDARD = LVCMOS33; +NET "ROM_OE" DRIVE = 8; + + +NET "ROM_WE" LOC = P190; + + +NET "ROM_WE" IOSTANDARD = LVCMOS33; +NET "ROM_WE" DRIVE = 8; +NET "SNES_ADDR[0]" IOSTANDARD = LVCMOS33; +NET "SNES_ADDR[0]" DRIVE = 8; +NET "SNES_ADDR[10]" IOSTANDARD = LVCMOS33; +NET "SNES_ADDR[10]" DRIVE = 8; +NET "SNES_ADDR[11]" IOSTANDARD = LVCMOS33; +NET "SNES_ADDR[11]" DRIVE = 8; +NET "SNES_ADDR[12]" IOSTANDARD = LVCMOS33; +NET "SNES_ADDR[12]" DRIVE = 8; +NET "SNES_ADDR[13]" IOSTANDARD = LVCMOS33; +NET "SNES_ADDR[13]" DRIVE = 8; +NET "SNES_ADDR[14]" IOSTANDARD = LVCMOS33; +NET "SNES_ADDR[14]" DRIVE = 8; +NET "SNES_ADDR[15]" IOSTANDARD = LVCMOS33; +NET "SNES_ADDR[15]" DRIVE = 8; +NET "SNES_ADDR[16]" IOSTANDARD = LVCMOS33; +NET "SNES_ADDR[16]" DRIVE = 8; +NET "SNES_ADDR[17]" IOSTANDARD = LVCMOS33; +NET "SNES_ADDR[17]" DRIVE = 8; +NET "SNES_ADDR[18]" IOSTANDARD = LVCMOS33; +NET "SNES_ADDR[18]" DRIVE = 8; +NET "SNES_ADDR[19]" IOSTANDARD = LVCMOS33; +NET "SNES_ADDR[19]" DRIVE = 8; +NET "SNES_ADDR[1]" IOSTANDARD = LVCMOS33; +NET "SNES_ADDR[1]" DRIVE = 8; +NET "SNES_ADDR[20]" IOSTANDARD = LVCMOS33; +NET "SNES_ADDR[20]" DRIVE = 8; +NET "SNES_ADDR[21]" IOSTANDARD = LVCMOS33; +NET "SNES_ADDR[21]" DRIVE = 8; +NET "SNES_ADDR[22]" IOSTANDARD = LVCMOS33; +NET "SNES_ADDR[22]" DRIVE = 8; +NET "SNES_ADDR[23]" IOSTANDARD = LVCMOS33; +NET "SNES_ADDR[23]" DRIVE = 8; +NET "SNES_ADDR[2]" IOSTANDARD = LVCMOS33; +NET "SNES_ADDR[2]" DRIVE = 8; +NET "SNES_ADDR[3]" IOSTANDARD = LVCMOS33; +NET "SNES_ADDR[3]" DRIVE = 8; +NET "SNES_ADDR[4]" IOSTANDARD = LVCMOS33; +NET "SNES_ADDR[4]" DRIVE = 8; +NET "SNES_ADDR[5]" IOSTANDARD = LVCMOS33; +NET "SNES_ADDR[5]" DRIVE = 8; +NET "SNES_ADDR[6]" IOSTANDARD = LVCMOS33; +NET "SNES_ADDR[6]" DRIVE = 8; +NET "SNES_ADDR[7]" IOSTANDARD = LVCMOS33; +NET "SNES_ADDR[7]" DRIVE = 8; +NET "SNES_ADDR[8]" IOSTANDARD = LVCMOS33; +NET "SNES_ADDR[8]" DRIVE = 8; +NET "SNES_ADDR[9]" IOSTANDARD = LVCMOS33; +NET "SNES_ADDR[9]" DRIVE = 8; + + +NET "SNES_CPU_CLK" LOC = P95; +NET "SNES_CS" LOC = P116; +NET "SNES_DATABUS_DIR" LOC = P111; +NET "SNES_DATABUS_OE" LOC = P109; +NET "SNES_DATABUS_DIR" DRIVE = 8; +NET "SNES_DATABUS_OE" DRIVE = 8; + + +NET "SNES_DATA[0]" IOSTANDARD = LVCMOS33; +NET "SNES_DATA[0]" DRIVE = 8; +NET "SNES_DATA[1]" IOSTANDARD = LVCMOS33; +NET "SNES_DATA[1]" DRIVE = 8; +NET "SNES_DATA[2]" IOSTANDARD = LVCMOS33; +NET "SNES_DATA[2]" DRIVE = 8; +NET "SNES_DATA[3]" IOSTANDARD = LVCMOS33; +NET "SNES_DATA[3]" DRIVE = 8; +NET "SNES_DATA[4]" IOSTANDARD = LVCMOS33; +NET "SNES_DATA[4]" DRIVE = 8; +NET "SNES_DATA[5]" IOSTANDARD = LVCMOS33; +NET "SNES_DATA[5]" DRIVE = 8; +NET "SNES_DATA[6]" IOSTANDARD = LVCMOS33; +NET "SNES_DATA[6]" DRIVE = 8; +NET "SNES_DATA[7]" IOSTANDARD = LVCMOS33; +NET "SNES_DATA[7]" DRIVE = 8; + + +NET "SNES_IRQ" LOC = P114; +NET "SNES_READ" LOC = P115; +NET "SNES_REFRESH" LOC = P155; +NET "SNES_WRITE" LOC = P94; + +NET "SNES_PA[0]" IOSTANDARD = LVCMOS33; +NET "SNES_PA[0]" LOC = P90; +NET "SNES_PA[1]" IOSTANDARD = LVCMOS33; +NET "SNES_PA[1]" LOC = P93; +NET "SNES_PA[2]" IOSTANDARD = LVCMOS33; +NET "SNES_PA[2]" LOC = P86; +NET "SNES_PA[3]" IOSTANDARD = LVCMOS33; +NET "SNES_PA[3]" LOC = P87; +NET "SNES_PA[4]" IOSTANDARD = LVCMOS33; +NET "SNES_PA[4]" LOC = P81; +NET "SNES_PA[5]" IOSTANDARD = LVCMOS33; +NET "SNES_PA[5]" LOC = P85; +NET "SNES_PA[6]" IOSTANDARD = LVCMOS33; +NET "SNES_PA[6]" LOC = P152; +NET "SNES_PA[7]" IOSTANDARD = LVCMOS33; +NET "SNES_PA[7]" LOC = P154; + +NET "SNES_PARD" IOSTANDARD = LVCMOS33; +NET "SNES_PARD" LOC = P149; +NET "SNES_PAWR" IOSTANDARD = LVCMOS33; +NET "SNES_PAWR" LOC = P150; + +NET "SPI_MISO" LOC = P72; + + +NET "SPI_MISO" IOSTANDARD = LVCMOS33; +NET "SPI_MISO" DRIVE = 8; + + +NET "SPI_MOSI" LOC = P74; + + +NET "SPI_MOSI" IOSTANDARD = LVCMOS33; +NET "SPI_MOSI" DRIVE = 8; + + +NET "SPI_SS" LOC = P68; + + +NET "SPI_SS" IOSTANDARD = LVCMOS33; +NET "SPI_SS" DRIVE = 8; + + +NET "DAC_LRCK" LOC = P77; + + +NET "DAC_LRCK" IOSTANDARD = LVCMOS33; +NET "DAC_LRCK" DRIVE = 8; + + +NET "DAC_MCLK" LOC = P76; + + +NET "DAC_MCLK" IOSTANDARD = LVCMOS33; +NET "DAC_MCLK" DRIVE = 8; + + +NET "DAC_SDOUT" LOC = P78; + + +NET "DAC_SDOUT" IOSTANDARD = LVCMOS33; +NET "DAC_SDOUT" DRIVE = 8; + +# PlanAhead Generated physical constraints + +NET "SD_CLK" LOC = P64; +NET "SD_CMD" LOC = P67; +NET "SD_DAT[0]" LOC = P65; +NET "SD_DAT[1]" LOC = P79; +NET "SD_DAT[2]" LOC = P62; +NET "SD_DAT[3]" LOC = P63; + +# PlanAhead Generated IO constraints + +NET "SD_CLK" IOSTANDARD = LVCMOS33; +NET "SD_CMD" IOSTANDARD = LVCMOS33; +NET "SD_DAT[0]" IOSTANDARD = LVCMOS33; +NET "SD_DAT[1]" IOSTANDARD = LVCMOS33; +NET "SD_DAT[2]" IOSTANDARD = LVCMOS33; +NET "SD_DAT[3]" IOSTANDARD = LVCMOS33; + +NET "SNES_SYSCLK" LOC = P180; +NET "SNES_SYSCLK" IOSTANDARD = LVCMOS33; + +NET "RAM_DATA[0]" IOSTANDARD = LVCMOS33; +NET "RAM_DATA[0]" DRIVE = 8; +NET "RAM_DATA[0]" LOC = P26; +NET "RAM_DATA[1]" IOSTANDARD = LVCMOS33; +NET "RAM_DATA[1]" DRIVE = 8; +NET "RAM_DATA[1]" LOC = P22; +NET "RAM_DATA[2]" IOSTANDARD = LVCMOS33; +NET "RAM_DATA[2]" DRIVE = 8; +NET "RAM_DATA[2]" LOC = P20; +NET "RAM_DATA[3]" IOSTANDARD = LVCMOS33; +NET "RAM_DATA[3]" DRIVE = 8; +NET "RAM_DATA[3]" LOC = P19; +NET "RAM_DATA[4]" IOSTANDARD = LVCMOS33; +NET "RAM_DATA[4]" DRIVE = 8; +NET "RAM_DATA[4]" LOC = P21; +NET "RAM_DATA[5]" IOSTANDARD = LVCMOS33; +NET "RAM_DATA[5]" DRIVE = 8; +NET "RAM_DATA[5]" LOC = P24; +NET "RAM_DATA[6]" IOSTANDARD = LVCMOS33; +NET "RAM_DATA[6]" DRIVE = 8; +NET "RAM_DATA[6]" LOC = P27; +NET "RAM_DATA[7]" IOSTANDARD = LVCMOS33; +NET "RAM_DATA[7]" DRIVE = 8; +NET "RAM_DATA[7]" LOC = P29; + +NET "RAM_OE" IOSTANDARD = LVCMOS33; +NET "RAM_OE" DRIVE = 8; +NET "RAM_OE" LOC = P36; +NET "RAM_WE" IOSTANDARD = LVCMOS33; +NET "RAM_WE" DRIVE = 8; +NET "RAM_WE" LOC = P50; + +NET "RAM_ADDR[0]" IOSTANDARD = LVCMOS33; +NET "RAM_ADDR[0]" DRIVE = 8; +NET "RAM_ADDR[0]" LOC = P28; +NET "RAM_ADDR[1]" IOSTANDARD = LVCMOS33; +NET "RAM_ADDR[1]" DRIVE = 8; +NET "RAM_ADDR[1]" LOC = P31; +NET "RAM_ADDR[2]" IOSTANDARD = LVCMOS33; +NET "RAM_ADDR[2]" DRIVE = 8; +NET "RAM_ADDR[2]" LOC = P33; +NET "RAM_ADDR[3]" IOSTANDARD = LVCMOS33; +NET "RAM_ADDR[3]" DRIVE = 8; +NET "RAM_ADDR[3]" LOC = P35; +NET "RAM_ADDR[4]" IOSTANDARD = LVCMOS33; +NET "RAM_ADDR[4]" DRIVE = 8; +NET "RAM_ADDR[4]" LOC = P37; +NET "RAM_ADDR[5]" IOSTANDARD = LVCMOS33; +NET "RAM_ADDR[5]" DRIVE = 8; +NET "RAM_ADDR[5]" LOC = P40; +NET "RAM_ADDR[6]" IOSTANDARD = LVCMOS33; +NET "RAM_ADDR[6]" DRIVE = 8; +NET "RAM_ADDR[6]" LOC = P43; +NET "RAM_ADDR[7]" IOSTANDARD = LVCMOS33; +NET "RAM_ADDR[7]" DRIVE = 8; +NET "RAM_ADDR[7]" LOC = P45; +NET "RAM_ADDR[8]" IOSTANDARD = LVCMOS33; +NET "RAM_ADDR[8]" DRIVE = 8; +NET "RAM_ADDR[8]" LOC = P44; +NET "RAM_ADDR[9]" IOSTANDARD = LVCMOS33; +NET "RAM_ADDR[9]" DRIVE = 8; +NET "RAM_ADDR[9]" LOC = P42; +NET "RAM_ADDR[10]" IOSTANDARD = LVCMOS33; +NET "RAM_ADDR[10]" DRIVE = 8; +NET "RAM_ADDR[10]" LOC = P34; +NET "RAM_ADDR[11]" IOSTANDARD = LVCMOS33; +NET "RAM_ADDR[11]" DRIVE = 8; +NET "RAM_ADDR[11]" LOC = P39; +NET "RAM_ADDR[12]" IOSTANDARD = LVCMOS33; +NET "RAM_ADDR[12]" DRIVE = 8; +NET "RAM_ADDR[12]" LOC = P48; +NET "RAM_ADDR[13]" IOSTANDARD = LVCMOS33; +NET "RAM_ADDR[13]" DRIVE = 8; +NET "RAM_ADDR[13]" LOC = P46; +NET "RAM_ADDR[14]" IOSTANDARD = LVCMOS33; +NET "RAM_ADDR[14]" DRIVE = 8; +NET "RAM_ADDR[14]" LOC = P51; +NET "RAM_ADDR[15]" IOSTANDARD = LVCMOS33; +NET "RAM_ADDR[15]" DRIVE = 8; +NET "RAM_ADDR[15]" LOC = P58; +NET "RAM_ADDR[16]" IOSTANDARD = LVCMOS33; +NET "RAM_ADDR[16]" DRIVE = 8; +NET "RAM_ADDR[16]" LOC = P57; +NET "RAM_ADDR[17]" IOSTANDARD = LVCMOS33; +NET "RAM_ADDR[17]" DRIVE = 8; +NET "RAM_ADDR[17]" LOC = P61; +NET "RAM_ADDR[18]" IOSTANDARD = LVCMOS33; +NET "RAM_ADDR[18]" DRIVE = 8; +NET "RAM_ADDR[18]" LOC = P52; diff --git a/verilog/sd2snes_test/main.v b/verilog/sd2snes_test/main.v new file mode 100644 index 0000000..e1adc44 --- /dev/null +++ b/verilog/sd2snes_test/main.v @@ -0,0 +1,596 @@ +`timescale 1 ns / 1 ns +////////////////////////////////////////////////////////////////////////////////// +// Company: Rehkopf +// Engineer: Rehkopf +// +// Create Date: 01:13:46 05/09/2009 +// Design Name: +// Module Name: main +// Project Name: +// Target Devices: +// Tool versions: +// Description: Master Control FSM +// +// Dependencies: address +// +// Revision: +// Revision 0.01 - File Created +// Additional Comments: +// +////////////////////////////////////////////////////////////////////////////////// +module main( + /* input clock */ + input CLKIN, + + /* SNES signals */ + input [23:0] SNES_ADDR, + input SNES_READ, + input SNES_WRITE, + input SNES_CS, + inout [7:0] SNES_DATA, + input SNES_CPU_CLK, + input SNES_REFRESH, + output SNES_IRQ, + output SNES_DATABUS_OE, + output SNES_DATABUS_DIR, + input SNES_SYSCLK, + + input [7:0] SNES_PA, + input SNES_PARD, + input SNES_PAWR, + + /* SRAM signals */ + /* Bus 1: PSRAM, 128Mbit, 16bit, 70ns */ + inout [15:0] ROM_DATA, + output [22:0] ROM_ADDR, + output ROM_CE, + output ROM_OE, + output ROM_WE, + output ROM_BHE, + output ROM_BLE, + + /* Bus 2: SRAM, 4Mbit, 8bit, 45ns */ + inout [7:0] RAM_DATA, + output [18:0] RAM_ADDR, + output RAM_OE, + output RAM_WE, + + /* MCU signals */ + input SPI_MOSI, + inout SPI_MISO, + input SPI_SS, + inout SPI_SCK, + input MCU_OVR, + output MCU_RDY, + + output DAC_MCLK, + output DAC_LRCK, + output DAC_SDOUT, + + /* SD signals */ + input [3:0] SD_DAT, + inout SD_CMD, + inout SD_CLK, + + /* debug */ + output p113_out +); + +wire [31:0] snes_sysclk_freq; +wire [31:0] snes_read_freq; +wire [31:0] snes_write_freq; +wire [31:0] snes_pard_freq; +wire [31:0] snes_pawr_freq; +wire [31:0] snes_refresh_freq; +wire [31:0] snes_cpuclk_freq; +wire [31:0] snes_romsel_freq; + +clk_test snes_clk_test ( + .clk(CLK2), + .sysclk(SNES_SYSCLK), + .read(SNES_READ), + .write(SNES_WRITE), + .pard(SNES_PARD), + .pawr(SNES_PAWR), + .refresh(SNES_REFRESH), + .cpuclk(SNES_CPU_CLK), + .romsel(SNES_CS), + .snes_sysclk_freq(snes_sysclk_freq), + .snes_read_freq(snes_read_freq), + .snes_write_freq(snes_write_freq), + .snes_pard_freq(snes_pard_freq), + .snes_pawr_freq(snes_pawr_freq), + .snes_refresh_freq(snes_refresh_freq), + .snes_cpuclk_freq(snes_cpuclk_freq), + .snes_romsel_freq(snes_romsel_freq) +); + +wire [7:0] spi_cmd_data; +wire [7:0] spi_param_data; +wire [7:0] spi_input_data; +wire [31:0] spi_byte_cnt; +wire [2:0] spi_bit_cnt; +wire [23:0] MCU_ADDR; +wire [2:0] MAPPER; +wire [23:0] SAVERAM_MASK; +wire [23:0] ROM_MASK; +wire [7:0] SD_DMA_SRAM_DATA; +wire [1:0] SD_DMA_TGT; +wire [10:0] SD_DMA_PARTIAL_START; +wire [10:0] SD_DMA_PARTIAL_END; + +wire [10:0] dac_addr; + +wire [23:0] ram0_addr; +wire [18:0] ram1_addr; +wire [7:0] PA_addr; +wire [12:0] bram_addr; +wire ROM_ADDR0; + +sd_dma snes_sd_dma( + .CLK(CLK2), + .SD_DAT(SD_DAT), + .SD_CLK(SD_CLK), + .SD_DMA_EN(SD_DMA_EN), + .SD_DMA_STATUS(SD_DMA_STATUS), + .SD_DMA_SRAM_WE(SD_DMA_SRAM_WE), + .SD_DMA_SRAM_DATA(SD_DMA_SRAM_DATA), + .SD_DMA_NEXTADDR(SD_DMA_NEXTADDR), + .SD_DMA_PARTIAL(SD_DMA_PARTIAL), + .SD_DMA_PARTIAL_START(SD_DMA_PARTIAL_START), + .SD_DMA_PARTIAL_END(SD_DMA_PARTIAL_END) +); + +wire SD_DMA_TO_ROM = (SD_DMA_STATUS && (SD_DMA_TGT == 2'b00)); + +dac snes_dac( + .clkin(CLK2), + .sysclk(SNES_SYSCLK), + .mclk(DAC_MCLK), + .lrck(DAC_LRCK), + .sdout(DAC_SDOUT), + .we(SD_DMA_TGT==2'b01 ? SD_DMA_SRAM_WE : 1'b1), + .pgm_address(dac_addr), + .pgm_data(SD_DMA_SRAM_DATA), + .DAC_STATUS(DAC_STATUS), + .play(dac_play), + .reset(dac_reset) +); + +spi snes_spi( + .clk(CLK2), + .MOSI(SPI_MOSI), + .MISO(SPI_MISO), + .SSEL(SPI_SS), + .SCK(SPI_SCK), + .cmd_ready(spi_cmd_ready), + .param_ready(spi_param_ready), + .cmd_data(spi_cmd_data), + .param_data(spi_param_data), + .endmessage(spi_endmessage), + .startmessage(spi_startmessage), + .input_data(spi_input_data), + .byte_cnt(spi_byte_cnt), + .bit_cnt(spi_bit_cnt) +); + +reg [7:0] MCU_DINr; +wire [7:0] MCU_DOUT; + +wire [7:0] mcu_bram_data_in; +wire [7:0] mcu_bram_data_out; +wire [12:0] mcu_bram_addr; + +mcu_cmd snes_mcu_cmd( + .clk(CLK2), + .cmd_ready(spi_cmd_ready), + .param_ready(spi_param_ready), + .cmd_data(spi_cmd_data), + .param_data(spi_param_data), + .mcu_mapper(MAPPER), + .mcu_write(MCU_WRITE), + .mcu_data_in(MCU_DINr), + .mcu_data_out(MCU_DOUT), + .spi_byte_cnt(spi_byte_cnt), + .spi_bit_cnt(spi_bit_cnt), + .spi_data_out(spi_input_data), + .addr_out(MCU_ADDR), + .saveram_mask_out(SAVERAM_MASK), + .rom_mask_out(ROM_MASK), + .SD_DMA_EN(SD_DMA_EN), + .SD_DMA_STATUS(SD_DMA_STATUS), + .SD_DMA_NEXTADDR(SD_DMA_NEXTADDR), + .SD_DMA_SRAM_DATA(SD_DMA_SRAM_DATA), + .SD_DMA_SRAM_WE(SD_DMA_SRAM_WE), + .SD_DMA_TGT(SD_DMA_TGT), + .SD_DMA_PARTIAL(SD_DMA_PARTIAL), + .SD_DMA_PARTIAL_START(SD_DMA_PARTIAL_START), + .SD_DMA_PARTIAL_END(SD_DMA_PARTIAL_END), + .dac_addr_out(dac_addr), + .DAC_STATUS(DAC_STATUS), +// .dac_volume_out(dac_volume), +// .dac_volume_latch_out(dac_vol_latch), + .dac_play_out(dac_play), + .dac_reset_out(dac_reset), + .featurebits_out(featurebits), + .mcu_rrq(MCU_RRQ), + .mcu_wrq(MCU_WRQ), + .mcu_rq_rdy(MCU_RDY), + .ramsel_out(MCU_RAMSEL), + .snes_sysclk_freq(snes_sysclk_freq), + .snes_read_freq(snes_read_freq), + .snes_write_freq(snes_write_freq), + .snes_pard_freq(snes_pard_freq), + .snes_pawr_freq(snes_pawr_freq), + .snes_refresh_freq(snes_refresh_freq), + .snes_cpuclk_freq(snes_cpuclk_freq), + .snes_romsel_freq(snes_romsel_freq), + .mcu_bram_addr(mcu_bram_addr), + .mcu_bram_data_in(mcu_bram_data_in), + .mcu_bram_data_out(mcu_bram_data_out), + .mcu_bram_we(mcu_bram_we) +); + +wire [7:0] DCM_STATUS; +// dcm1: dfs 4x +my_dcm snes_dcm( + .CLKIN(CLKIN), + .CLKFX(CLK2), + .LOCKED(DCM_LOCKED), + .RST(DCM_RST), + .STATUS(DCM_STATUS) +); + +assign DCM_RST=0; + +reg [5:0] SNES_READr; +reg [5:0] SNES_WRITEr; +reg [5:0] SNES_CPU_CLKr; + +wire SNES_RD_start = (SNES_READr == 6'b111110); +wire SNES_WR_start = (SNES_WRITEr == 6'b111110); +wire SNES_WR_rising = (SNES_WRITEr == 6'b000001); +wire SNES_cycle_start = (SNES_CPU_CLKr[5:0] == 6'b000001); +wire SNES_cycle_end = (SNES_CPU_CLKr[5:0] == 6'b111110); + +always @(posedge CLK2) begin + SNES_READr <= {SNES_READr[4:0], SNES_READ}; + SNES_WRITEr <= {SNES_WRITEr[4:0], SNES_WRITE}; + SNES_CPU_CLKr <= {SNES_CPU_CLKr[4:0], SNES_CPU_CLK}; +end + +reg [7:0] ram0_bank; +initial ram0_bank = 8'h00; +reg ram0_linear; +initial ram0_linear = 1'b0; + +address snes_addr( + .CLK(CLK2), + .SNES_ADDR(SNES_ADDR), // requested address from SNES + .ram0_addr(ram0_addr), // Address to request from SRAM (active low) + .ram1_addr(ram1_addr), + .PA_addr(PA_addr), + .bram_addr(bram_addr), + .ram0_enable(ram0_enable), + .ram1_enable(ram1_enable), + .PA_enable(PA_enable), + .bram_enable(bram_enable), + .ram0_bank(ram0_bank), + .ram0_linear(ram0_linear), + .irq_enable(irq_enable), + .bank_enable(bank_enable), + .linear_enable(linear_enable) +); + +always @(posedge CLK2) begin + if(SNES_WR_rising && bank_enable) ram0_bank <= SNES_DATA; +end + +always @(posedge CLK2) begin + if(SNES_WR_rising && linear_enable) ram0_linear <= SNES_DATA[0]; +end + +reg [7:0] irq_count_r; +initial irq_count_r = 8'b0; +reg SNES_IRQr; +initial SNES_IRQr = 0; + +always @(posedge CLK2) begin + if(SNES_WR_rising & irq_enable) SNES_IRQr <= 1'b1; + else if(irq_count_r == 8'h00) SNES_IRQr <= 1'b0; +end + +always @(posedge CLK2) begin + if(SNES_WR_rising & irq_enable) irq_count_r <= 8'h01; + else irq_count_r <= irq_count_r + 1; +end + + +wire [7:0] bram_data_out; +bram test_bram ( + .clka(CLK2), // input clka + .wea(~SNES_WRITE & bram_enable), // input [0 : 0] wea + .addra(bram_addr), // input [12 : 0] addra + .dina(SNES_DATA), // input [7 : 0] dina + .douta(bram_data_out), // output [7 : 0] douta + .clkb(CLK2), // input clkb + .web(mcu_bram_we), // input [0 : 0] web + .addrb(mcu_bram_addr), // input [12 : 0] addrb + .dinb(mcu_bram_data_out), // input [7 : 0] dinb + .doutb(mcu_bram_data_in) // output [7 : 0] doutb +); +reg [1:0] SNES_PAWR_start_r; +always @(posedge CLK2) SNES_PAWR_start_r <= {SNES_PAWR_start_r[0], SNES_PAWR}; +wire SNES_PAWR_start = (SNES_PAWR_start_r == 2'b01); +wire [7:0] PA_data_out; +PA test_PA ( + .clka(CLK2), // input clka + .wea(SNES_PAWR_start), // input [0 : 0] wea + .addra(SNES_PA), // input [7 : 0] addra + .dina(SNES_DATA), // input [7 : 0] dina + .clkb(CLK2), // input clkb + .addrb(PA_addr), // input [7 : 0] addrb + .doutb(PA_data_out) // output [7 : 0] doutb +); + +parameter MODE_SNES = 1'b0; +parameter MODE_MCU = 1'b1; + +parameter ST_IDLE = 18'b000000000000000001; +parameter ST_SNES_RD_ADDR = 18'b000000000000000010; +parameter ST_SNES_RD_WAIT = 18'b000000000000000100; +parameter ST_SNES_RD_END = 18'b000000000000001000; +parameter ST_SNES_WR_ADDR = 18'b000000000000010000; +parameter ST_SNES_WR_WAIT1= 18'b000000000000100000; +parameter ST_SNES_WR_DATA = 18'b000000000001000000; +parameter ST_SNES_WR_WAIT2= 18'b000000000010000000; +parameter ST_SNES_WR_END = 18'b000000000100000000; +parameter ST_MCU_RD_ADDR = 18'b000000001000000000; +parameter ST_MCU_RD_WAIT = 18'b000000010000000000; +parameter ST_MCU_RD_WAIT2 = 18'b000000100000000000; +parameter ST_MCU_RD_END = 18'b000001000000000000; +parameter ST_MCU_WR_ADDR = 18'b000010000000000000; +parameter ST_MCU_WR_WAIT = 18'b000100000000000000; +parameter ST_MCU_WR_WAIT2 = 18'b001000000000000000; +parameter ST_MCU_WR_END = 18'b010000000000000000; + +parameter ROM_RD_WAIT = 4'h4; +parameter ROM_RD_WAIT_MCU = 4'h6; +parameter ROM_WR_WAIT1 = 4'h2; +parameter ROM_WR_WAIT2 = 4'h3; +parameter ROM_WR_WAIT_MCU = 4'h6; + +reg [17:0] STATE; +initial STATE = ST_IDLE; + +reg [7:0] SNES_DINr; +reg [7:0] ROM_DOUTr; +reg [7:0] RAM_DOUTr; + +assign SNES_DATA = (!SNES_READ) ? (ram0_enable ? SNES_DINr + :ram1_enable ? SNES_DINr + :bram_enable ? bram_data_out + :PA_enable ? PA_data_out + :SNES_DINr /*(ROM_ADDR0 ? ROM_DATA[7:0] : ROM_DATA[15:8])*/) : 8'bZ; + +reg [3:0] ST_MEM_DELAYr; +reg MCU_RD_PENDr; +reg MCU_WR_PENDr; +reg [23:0] ROM_ADDRr; +reg [18:0] RAM_ADDRr; +reg NEED_SNES_ADDRr; +always @(posedge CLK2) begin + if(SNES_cycle_end) NEED_SNES_ADDRr <= 1'b1; + else if(STATE & (ST_SNES_RD_END | ST_SNES_WR_END)) NEED_SNES_ADDRr <= 1'b0; +end + +wire ASSERT_SNES_ADDR = SNES_CPU_CLK & NEED_SNES_ADDRr; + +assign ROM_ADDR = (SD_DMA_TO_ROM) ? MCU_ADDR[23:1] : (ASSERT_SNES_ADDR) ? ram0_addr[23:1] : ROM_ADDRr[23:1]; +assign ROM_ADDR0 = (SD_DMA_TO_ROM) ? MCU_ADDR[0] : (ASSERT_SNES_ADDR) ? ram0_addr[0] : ROM_ADDRr[0]; + +assign RAM_ADDR = ASSERT_SNES_ADDR ? ram1_addr : RAM_ADDRr; + +reg ROM_WEr; +initial ROM_WEr = 1'b1; + +reg RAM_WEr; +initial RAM_WEr = 1'b1; + +reg RQ_MCU_RDYr; +initial RQ_MCU_RDYr = 1'b1; +assign MCU_RDY = RQ_MCU_RDYr; + +always @(posedge CLK2) begin + if(MCU_RRQ) begin + MCU_RD_PENDr <= 1'b1; + RQ_MCU_RDYr <= 1'b0; + end else if(MCU_WRQ) begin + MCU_WR_PENDr <= 1'b1; + RQ_MCU_RDYr <= 1'b0; + end else if(STATE & (ST_MCU_RD_END | ST_MCU_WR_END)) begin + MCU_RD_PENDr <= 1'b0; + MCU_WR_PENDr <= 1'b0; + RQ_MCU_RDYr <= 1'b1; + end +end + +reg snes_wr_cycle; +wire ram_enable = ram0_enable | ram1_enable; +always @(posedge CLK2) begin + if(ram_enable & SNES_cycle_start & ~SNES_WR_start) begin + STATE <= ST_SNES_RD_ADDR; + end else if(ram_enable & SNES_WR_start) begin + snes_wr_cycle <= 1'b1; + STATE <= ST_SNES_WR_ADDR; + end else begin + case(STATE) + ST_IDLE: begin + if(ram0_enable) ROM_ADDRr <= ram0_addr; + if(ram1_enable) RAM_ADDRr <= ram1_addr; + if(MCU_RD_PENDr) STATE <= ST_MCU_RD_ADDR; + else if(MCU_WR_PENDr) STATE <= ST_MCU_WR_ADDR; + else STATE <= ST_IDLE; + end + ST_SNES_RD_ADDR: begin + STATE <= ST_SNES_RD_WAIT; + ST_MEM_DELAYr <= ROM_RD_WAIT; + end + ST_SNES_RD_WAIT: begin + ST_MEM_DELAYr <= ST_MEM_DELAYr - 4'h1; + if(ST_MEM_DELAYr == 4'h0) STATE <= ST_SNES_RD_END; + else STATE <= ST_SNES_RD_WAIT; + if(ram0_enable) begin + if(ROM_ADDR0) SNES_DINr <= ROM_DATA[7:0]; + else SNES_DINr <= ROM_DATA[15:8]; + end else if(ram1_enable) begin + SNES_DINr <= RAM_DATA[7:0]; + end + end + ST_SNES_RD_END: begin + STATE <= ST_IDLE; + if(ram0_enable) begin + if(ROM_ADDR0) SNES_DINr <= ROM_DATA[7:0]; + else SNES_DINr <= ROM_DATA[15:8]; + end else if(ram1_enable) begin + SNES_DINr <= RAM_DATA[7:0]; + end + end + ST_SNES_WR_ADDR: begin + if(ram0_enable) ROM_WEr <= 1'b0; + if(ram1_enable) RAM_WEr <= 1'b0; + STATE <= ST_SNES_WR_WAIT1; + ST_MEM_DELAYr <= ROM_WR_WAIT1; + end + ST_SNES_WR_WAIT1: begin + ST_MEM_DELAYr <= ST_MEM_DELAYr - 4'h1; + if(ST_MEM_DELAYr == 4'h0) STATE <= ST_SNES_WR_DATA; + else STATE <= ST_SNES_WR_WAIT1; + end + ST_SNES_WR_DATA: begin + if(ram0_enable) ROM_DOUTr <= SNES_DATA; + if(ram1_enable) RAM_DOUTr <= SNES_DATA; + ST_MEM_DELAYr <= ROM_WR_WAIT2; + STATE <= ST_SNES_WR_WAIT2; + end + ST_SNES_WR_WAIT2: begin + ST_MEM_DELAYr <= ST_MEM_DELAYr - 4'h1; + if(ST_MEM_DELAYr == 4'h0) STATE <= ST_SNES_WR_END; + else STATE <= ST_SNES_WR_WAIT2; + end + ST_SNES_WR_END: begin + STATE <= ST_IDLE; + ROM_WEr <= 1'b1; + RAM_WEr <= 1'b1; + snes_wr_cycle <= 1'b0; + end + ST_MCU_RD_ADDR: begin + if(MCU_RAMSEL == 1'b0) ROM_ADDRr <= MCU_ADDR; + else RAM_ADDRr <= MCU_ADDR; + STATE <= ST_MCU_RD_WAIT; + ST_MEM_DELAYr <= ROM_RD_WAIT_MCU; + end + ST_MCU_RD_WAIT: begin + ST_MEM_DELAYr <= ST_MEM_DELAYr - 4'h1; + if(ST_MEM_DELAYr == 4'h0) begin + STATE <= ST_MCU_RD_WAIT2; + ST_MEM_DELAYr <= 4'h2; + end + else STATE <= ST_MCU_RD_WAIT; + if(MCU_RAMSEL == 1'b0) begin + if(ROM_ADDR0) MCU_DINr <= ROM_DATA[7:0]; + else MCU_DINr <= ROM_DATA[15:8]; + end else MCU_DINr <= RAM_DATA; + end + ST_MCU_RD_WAIT2: begin + ST_MEM_DELAYr <= ST_MEM_DELAYr - 4'h1; + if(ST_MEM_DELAYr == 4'h0) begin + STATE <= ST_MCU_RD_END; + end else STATE <= ST_MCU_RD_WAIT2; + end + ST_MCU_RD_END: begin + STATE <= ST_IDLE; + end + ST_MCU_WR_ADDR: begin + if(MCU_RAMSEL == 1'b0) ROM_ADDRr <= MCU_ADDR; + else RAM_ADDRr <= MCU_ADDR; + STATE <= ST_MCU_WR_WAIT; + ST_MEM_DELAYr <= ROM_WR_WAIT_MCU; + if(MCU_RAMSEL == 1'b0) ROM_DOUTr <= MCU_DOUT; + else RAM_DOUTr <= MCU_DOUT; + if(MCU_RAMSEL == 1'b0) + ROM_WEr <= 1'b0; + else if(MCU_RAMSEL == 1'b1) + RAM_WEr <= 1'b0; + end + ST_MCU_WR_WAIT: begin + ST_MEM_DELAYr <= ST_MEM_DELAYr - 4'h1; + if(ST_MEM_DELAYr == 4'h0) begin + ROM_WEr <= 1'b1; + RAM_WEr <= 1'b1; + STATE <= ST_MCU_WR_WAIT2; + ST_MEM_DELAYr <= 4'h2; + end + else begin + STATE <= ST_MCU_WR_WAIT; + end + end + ST_MCU_WR_WAIT2: begin + ST_MEM_DELAYr <= ST_MEM_DELAYr - 4'h1; + if(ST_MEM_DELAYr == 4'h0) begin + STATE <= ST_MCU_WR_END; + end else STATE <= ST_MCU_WR_WAIT2; + end + ST_MCU_WR_END: begin + STATE <= ST_IDLE; + end + endcase + end +end + +assign ROM_DATA[7:0] = ROM_ADDR0 + ?(SD_DMA_TO_ROM ? (!MCU_WRITE ? MCU_DOUT : 8'bZ) + : (!ROM_WE ? ROM_DOUTr : 8'bZ) + ) + :8'bZ; + +assign ROM_DATA[15:8] = ROM_ADDR0 ? 8'bZ + :(SD_DMA_TO_ROM ? (!MCU_WRITE ? MCU_DOUT : 8'bZ) + : (!ROM_WE ? ROM_DOUTr : 8'bZ) + ); + +assign RAM_DATA = !RAM_WE ? RAM_DOUTr : 8'bZ; + +assign ROM_WE = SD_DMA_TO_ROM + ?MCU_WRITE + :ROM_WEr | (ASSERT_SNES_ADDR & ~(snes_wr_cycle & ram0_enable)); + +assign RAM_WE = RAM_WEr | (ASSERT_SNES_ADDR & ~(snes_wr_cycle & ram1_enable)); + +assign RAM_OE = 1'b0; + +// OE always active. Overridden by WE when needed. +assign ROM_OE = 1'b0; + +assign ROM_CE = 1'b0; + +assign ROM_BHE = !ROM_WE ? ROM_ADDR0 : 1'b0; +assign ROM_BLE = !ROM_WE ? !ROM_ADDR0 : 1'b0; + +assign SNES_DATABUS_OE = PA_enable ? 1'b0 + : bram_enable ? 1'b0 + : (~SNES_PAWR & SNES_READ) ? 1'b0 + : SNES_CS ? SNES_WRITE + :((SNES_CS) + |(!ram0_enable & !ram1_enable) + |(SNES_READ & SNES_WRITE) + ); + +assign SNES_DATABUS_DIR = ~SNES_READ ? 1'b1 : 1'b0; + +assign IRQ_DIR = 1'b0; +assign SNES_IRQ = SNES_IRQr; + +assign p113_out = 1'b0; + +endmodule diff --git a/verilog/sd2snes_test/mcu_cmd.v b/verilog/sd2snes_test/mcu_cmd.v new file mode 100644 index 0000000..c5e2bb7 --- /dev/null +++ b/verilog/sd2snes_test/mcu_cmd.v @@ -0,0 +1,618 @@ +`timescale 1ns / 1ps +////////////////////////////////////////////////////////////////////////////////// +// Company: +// Engineer: +// +// Create Date: 21:57:50 08/25/2009 +// Design Name: +// Module Name: mcu_cmd +// Project Name: +// Target Devices: +// Tool versions: +// Description: +// +// Dependencies: +// +// Revision: +// Revision 0.01 - File Created +// Additional Comments: +// +////////////////////////////////////////////////////////////////////////////////// +module mcu_cmd( + input clk, + input cmd_ready, + input param_ready, + input [7:0] cmd_data, + input [7:0] param_data, + output [2:0] mcu_mapper, + output mcu_rrq, + output mcu_write, + output mcu_wrq, + input mcu_rq_rdy, + output [7:0] mcu_data_out, + input [7:0] mcu_data_in, + output [7:0] spi_data_out, + input [31:0] spi_byte_cnt, + input [2:0] spi_bit_cnt, + output [23:0] addr_out, + output [23:0] saveram_mask_out, + output [23:0] rom_mask_out, + output reg ramsel_out, + + // SD "DMA" extension + output SD_DMA_EN, + input SD_DMA_STATUS, + input SD_DMA_NEXTADDR, + input [7:0] SD_DMA_SRAM_DATA, + input SD_DMA_SRAM_WE, + output [1:0] SD_DMA_TGT, + output SD_DMA_PARTIAL, + output [10:0] SD_DMA_PARTIAL_START, + output [10:0] SD_DMA_PARTIAL_END, + + // DAC + output [10:0] dac_addr_out, + input DAC_STATUS, + output dac_play_out, + output dac_reset_out, + + // MSU data + output [13:0] msu_addr_out, + input [6:0] MSU_STATUS, + output [5:0] msu_status_reset_out, + output [5:0] msu_status_set_out, + output msu_status_reset_we, + input [31:0] msu_addressrq, + input [15:0] msu_trackrq, + input [7:0] msu_volumerq, + output [13:0] msu_ptr_out, + output msu_reset_out, + + // BS-X + output [7:0] bsx_regs_reset_out, + output [7:0] bsx_regs_set_out, + output bsx_regs_reset_we, + + // generic RTC + output [55:0] rtc_data_out, + output rtc_pgm_we, + + // S-RTC + output srtc_reset, + + // uPD77C25 + output reg [23:0] dspx_pgm_data_out, + output reg [10:0] dspx_pgm_addr_out, + output reg dspx_pgm_we_out, + + output reg [15:0] dspx_dat_data_out, + output reg [10:0] dspx_dat_addr_out, + output reg dspx_dat_we_out, + + output reg dspx_reset_out, + + // feature enable + output reg [3:0] featurebits_out, + + // SNES control signal/clock freqs + + input [31:0] snes_cpuclk_freq, + input [31:0] snes_sysclk_freq, + input [31:0] snes_read_freq, + input [31:0] snes_write_freq, + input [31:0] snes_pard_freq, + input [31:0] snes_pawr_freq, + input [31:0] snes_refresh_freq, + input [31:0] snes_romsel_freq, + + output reg [12:0] mcu_bram_addr, + input [7:0] mcu_bram_data_in, + output reg [7:0] mcu_bram_data_out, + output reg mcu_bram_we + +); + +initial begin + dspx_pgm_addr_out = 11'b00000000000; + dspx_dat_addr_out = 10'b0000000000; + dspx_reset_out = 1'b1; + ramsel_out = 1'b0; +end + +reg [2:0] MAPPER_BUF; +reg [23:0] ADDR_OUT_BUF; +reg [10:0] DAC_ADDR_OUT_BUF; +reg [7:0] DAC_VOL_OUT_BUF; +reg DAC_VOL_LATCH_BUF; +reg DAC_PLAY_OUT_BUF; +reg DAC_RESET_OUT_BUF; +reg [13:0] MSU_ADDR_OUT_BUF; +reg [13:0] MSU_PTR_OUT_BUF; +reg [5:0] msu_status_set_out_buf; +reg [5:0] msu_status_reset_out_buf; +reg msu_status_reset_we_buf; +reg MSU_RESET_OUT_BUF; + +reg [7:0] bsx_regs_set_out_buf; +reg [7:0] bsx_regs_reset_out_buf; +reg bsx_regs_reset_we_buf; + +reg [55:0] rtc_data_out_buf; +reg rtc_pgm_we_buf; + +reg srtc_reset_buf; + +reg [31:0] SNES_SYSCLK_FREQ_BUF; + +reg [7:0] MCU_DATA_OUT_BUF; +reg [7:0] MCU_DATA_IN_BUF; +reg [1:0] mcu_nextaddr_buf; + +wire mcu_nextaddr; + +reg DAC_STATUSr; +reg SD_DMA_STATUSr; +reg [6:0] MSU_STATUSr; +always @(posedge clk) begin + DAC_STATUSr <= DAC_STATUS; + SD_DMA_STATUSr <= SD_DMA_STATUS; + MSU_STATUSr <= MSU_STATUS; +end + +reg SD_DMA_PARTIALr; +assign SD_DMA_PARTIAL = SD_DMA_PARTIALr; + +reg SD_DMA_ENr; +assign SD_DMA_EN = SD_DMA_ENr; + +reg [1:0] SD_DMA_TGTr; +assign SD_DMA_TGT = SD_DMA_TGTr; + +reg [10:0] SD_DMA_PARTIAL_STARTr; +reg [10:0] SD_DMA_PARTIAL_ENDr; +assign SD_DMA_PARTIAL_START = SD_DMA_PARTIAL_STARTr; +assign SD_DMA_PARTIAL_END = SD_DMA_PARTIAL_ENDr; + +reg [23:0] SAVERAM_MASK; +reg [23:0] ROM_MASK; + +assign spi_data_out = MCU_DATA_IN_BUF; + +initial begin + ADDR_OUT_BUF = 0; + DAC_ADDR_OUT_BUF = 0; + MSU_ADDR_OUT_BUF = 0; + SD_DMA_ENr = 0; + MAPPER_BUF = 1; +end + +// command interpretation +always @(posedge clk) begin + if (cmd_ready) begin + case (cmd_data[7:4]) + 4'h3: // select mapper + MAPPER_BUF <= cmd_data[2:0]; + 4'h4: begin// SD DMA + SD_DMA_ENr <= 1; + SD_DMA_TGTr <= cmd_data[1:0]; + SD_DMA_PARTIALr <= cmd_data[2]; + end + 4'h8: SD_DMA_TGTr <= 2'b00; + 4'h9: SD_DMA_TGTr <= cmd_data[1:0]; // not implemented + endcase + end else if (param_ready) begin + casex (cmd_data[7:0]) + 8'h1x: + case (spi_byte_cnt) + 32'h2: + ROM_MASK[23:16] <= param_data; + 32'h3: + ROM_MASK[15:8] <= param_data; + 32'h4: + ROM_MASK[7:0] <= param_data; + endcase + 8'h2x: + case (spi_byte_cnt) + 32'h2: + SAVERAM_MASK[23:16] <= param_data; + 32'h3: + SAVERAM_MASK[15:8] <= param_data; + 32'h4: + SAVERAM_MASK[7:0] <= param_data; + endcase + 8'h4x: + SD_DMA_ENr <= 1'b0; + 8'h6x: + case (spi_byte_cnt) + 32'h2: + SD_DMA_PARTIAL_STARTr[10:9] <= param_data[1:0]; + 32'h3: + SD_DMA_PARTIAL_STARTr[8:0] <= {param_data, 1'b0}; + 32'h4: + SD_DMA_PARTIAL_ENDr[10:9] <= param_data[1:0]; + 32'h5: + SD_DMA_PARTIAL_ENDr[8:0] <= {param_data, 1'b0}; + endcase + 8'h9x: + MCU_DATA_OUT_BUF <= param_data; + 8'he0: + case (spi_byte_cnt) + 32'h2: begin + msu_status_set_out_buf <= param_data[5:0]; + end + 32'h3: begin + msu_status_reset_out_buf <= param_data[5:0]; + msu_status_reset_we_buf <= 1'b1; + end + 32'h4: + msu_status_reset_we_buf <= 1'b0; + endcase + 8'he1: // pause DAC + DAC_PLAY_OUT_BUF <= 1'b0; + 8'he2: // resume DAC + DAC_PLAY_OUT_BUF <= 1'b1; + 8'he3: // reset DAC (set DAC playback address = 0) + case (spi_byte_cnt) + 32'h2: + DAC_RESET_OUT_BUF <= 1'b1; + 32'h3: + DAC_RESET_OUT_BUF <= 1'b0; + endcase + 8'he4: // reset MSU read buffer pointer + case (spi_byte_cnt) + 32'h2: begin + MSU_PTR_OUT_BUF[13:8] <= param_data[5:0]; + MSU_PTR_OUT_BUF[7:0] <= 8'h0; + end + 32'h3: begin + MSU_PTR_OUT_BUF[7:0] <= param_data; + MSU_RESET_OUT_BUF <= 1'b1; + end + 32'h4: + MSU_RESET_OUT_BUF <= 1'b0; + endcase + 8'he5: + case (spi_byte_cnt) + 32'h2: + rtc_data_out_buf[55:48] <= param_data; + 32'h3: + rtc_data_out_buf[47:40] <= param_data; + 32'h4: + rtc_data_out_buf[39:32] <= param_data; + 32'h5: + rtc_data_out_buf[31:24] <= param_data; + 32'h6: + rtc_data_out_buf[23:16] <= param_data; + 32'h7: + rtc_data_out_buf[15:8] <= param_data; + 32'h8: begin + rtc_data_out_buf[7:0] <= param_data; + rtc_pgm_we_buf <= 1'b1; + end + 32'h9: + rtc_pgm_we_buf <= 1'b0; + endcase + 8'he6: + case (spi_byte_cnt) + 32'h2: begin + bsx_regs_set_out_buf <= param_data[7:0]; + end + 32'h3: begin + bsx_regs_reset_out_buf <= param_data[7:0]; + bsx_regs_reset_we_buf <= 1'b1; + end + 32'h4: + bsx_regs_reset_we_buf <= 1'b0; + endcase + 8'he7: + case (spi_byte_cnt) + 32'h2: begin + srtc_reset_buf <= 1'b1; + end + 32'h3: begin + srtc_reset_buf <= 1'b0; + end + endcase + 8'he8: begin // set BRAM address + case (spi_byte_cnt) + 32'h2: mcu_bram_addr[12:8] <= param_data[4:0]; + 32'h3: mcu_bram_addr[7:0] <= param_data[7:0]; + endcase + end + 8'he9: begin // write BRAM + case (spi_byte_cnt) + 32'h2: begin + mcu_bram_data_out <= param_data; + mcu_bram_we <= 1'b1; + end + 32'h3: mcu_bram_we <= 1'b0; + 32'h4: mcu_bram_addr <= mcu_bram_addr + 1; + endcase + end + 8'hee: + ramsel_out <= param_data[0]; + 8'hf5: + if (spi_byte_cnt == 32'h3) mcu_bram_addr <= mcu_bram_addr + 1; + endcase + end +end + +always @(posedge clk) begin + if(param_ready && cmd_data[7:4] == 4'h0) begin + case (cmd_data[1:0]) + 2'b01: begin + case (spi_byte_cnt) + 32'h2: begin + DAC_ADDR_OUT_BUF[10:8] <= param_data[2:0]; + DAC_ADDR_OUT_BUF[7:0] <= 8'b0; + end + 32'h3: + DAC_ADDR_OUT_BUF[7:0] <= param_data; + endcase + end + 2'b10: begin + case (spi_byte_cnt) + 32'h2: begin + MSU_ADDR_OUT_BUF[13:8] <= param_data[5:0]; + MSU_ADDR_OUT_BUF[7:0] <= 8'b0; + end + 32'h3: + MSU_ADDR_OUT_BUF[7:0] <= param_data; + endcase + end + default: + case (spi_byte_cnt) + 32'h2: begin + ADDR_OUT_BUF[23:16] <= param_data; + ADDR_OUT_BUF[15:0] <= 16'b0; + end + 32'h3: + ADDR_OUT_BUF[15:8] <= param_data; + 32'h4: + ADDR_OUT_BUF[7:0] <= param_data; + endcase + endcase + end else if (SD_DMA_NEXTADDR | (mcu_nextaddr & (cmd_data[7:5] == 3'h4) + && (cmd_data[3]) + && (spi_byte_cnt >= (32'h1+cmd_data[4]))) + ) + begin + case (SD_DMA_TGTr) + 2'b00: ADDR_OUT_BUF <= ADDR_OUT_BUF + 1; + 2'b01: DAC_ADDR_OUT_BUF <= DAC_ADDR_OUT_BUF + 1; + 2'b10: MSU_ADDR_OUT_BUF <= MSU_ADDR_OUT_BUF + 1; + endcase + end +end + +// value fetch during last SPI bit +always @(posedge clk) begin + if (cmd_data[7:4] == 4'h8 && mcu_nextaddr_buf == 2'b01) + MCU_DATA_IN_BUF <= mcu_data_in; + else if (spi_bit_cnt == 3'h7) begin + if (cmd_data[7:0] == 8'hF0) + MCU_DATA_IN_BUF <= 8'hA5; + else if (cmd_data[7:0] == 8'hF1) + case (spi_byte_cnt[0]) + 1'b1: // buffer status (1st byte) + MCU_DATA_IN_BUF <= {SD_DMA_STATUSr, DAC_STATUSr, MSU_STATUSr[6], 5'b0}; + 1'b0: // control status (2nd byte) + MCU_DATA_IN_BUF <= {2'b0, MSU_STATUSr[5:0]}; + endcase + else if (cmd_data[7:0] == 8'hF2) + case (spi_byte_cnt) + 32'h1: + MCU_DATA_IN_BUF <= msu_addressrq[31:24]; + 32'h2: + MCU_DATA_IN_BUF <= msu_addressrq[23:16]; + 32'h3: + MCU_DATA_IN_BUF <= msu_addressrq[15:8]; + 32'h4: + MCU_DATA_IN_BUF <= msu_addressrq[7:0]; + endcase + else if (cmd_data[7:0] == 8'hF3) + case (spi_byte_cnt) + 32'h1: + MCU_DATA_IN_BUF <= msu_trackrq[15:8]; + 32'h2: + MCU_DATA_IN_BUF <= msu_trackrq[7:0]; + endcase + else if (cmd_data[7:0] == 8'hF4) + MCU_DATA_IN_BUF <= msu_volumerq; + else if (cmd_data[7:0] == 8'hF5) + MCU_DATA_IN_BUF <= mcu_bram_data_in; + else if (cmd_data[7:0] == 8'hF7) + case (spi_byte_cnt) + 32'h1: + SNES_SYSCLK_FREQ_BUF <= snes_romsel_freq; + 32'h2: + MCU_DATA_IN_BUF <= SNES_SYSCLK_FREQ_BUF[31:24]; + 32'h3: + MCU_DATA_IN_BUF <= SNES_SYSCLK_FREQ_BUF[23:16]; + 32'h4: + MCU_DATA_IN_BUF <= SNES_SYSCLK_FREQ_BUF[15:8]; + 32'h5: + MCU_DATA_IN_BUF <= SNES_SYSCLK_FREQ_BUF[7:0]; + endcase + else if (cmd_data[7:0] == 8'hF8) + case (spi_byte_cnt) + 32'h1: + SNES_SYSCLK_FREQ_BUF <= snes_cpuclk_freq; + 32'h2: + MCU_DATA_IN_BUF <= SNES_SYSCLK_FREQ_BUF[31:24]; + 32'h3: + MCU_DATA_IN_BUF <= SNES_SYSCLK_FREQ_BUF[23:16]; + 32'h4: + MCU_DATA_IN_BUF <= SNES_SYSCLK_FREQ_BUF[15:8]; + 32'h5: + MCU_DATA_IN_BUF <= SNES_SYSCLK_FREQ_BUF[7:0]; + endcase + else if (cmd_data[7:0] == 8'hF9) + case (spi_byte_cnt) + 32'h1: + SNES_SYSCLK_FREQ_BUF <= snes_read_freq; + 32'h2: + MCU_DATA_IN_BUF <= SNES_SYSCLK_FREQ_BUF[31:24]; + 32'h3: + MCU_DATA_IN_BUF <= SNES_SYSCLK_FREQ_BUF[23:16]; + 32'h4: + MCU_DATA_IN_BUF <= SNES_SYSCLK_FREQ_BUF[15:8]; + 32'h5: + MCU_DATA_IN_BUF <= SNES_SYSCLK_FREQ_BUF[7:0]; + endcase + else if (cmd_data[7:0] == 8'hFA) + case (spi_byte_cnt) + 32'h1: + SNES_SYSCLK_FREQ_BUF <= snes_write_freq; + 32'h2: + MCU_DATA_IN_BUF <= SNES_SYSCLK_FREQ_BUF[31:24]; + 32'h3: + MCU_DATA_IN_BUF <= SNES_SYSCLK_FREQ_BUF[23:16]; + 32'h4: + MCU_DATA_IN_BUF <= SNES_SYSCLK_FREQ_BUF[15:8]; + 32'h5: + MCU_DATA_IN_BUF <= SNES_SYSCLK_FREQ_BUF[7:0]; + endcase + else if (cmd_data[7:0] == 8'hFB) + case (spi_byte_cnt) + 32'h1: + SNES_SYSCLK_FREQ_BUF <= snes_pard_freq; + 32'h2: + MCU_DATA_IN_BUF <= SNES_SYSCLK_FREQ_BUF[31:24]; + 32'h3: + MCU_DATA_IN_BUF <= SNES_SYSCLK_FREQ_BUF[23:16]; + 32'h4: + MCU_DATA_IN_BUF <= SNES_SYSCLK_FREQ_BUF[15:8]; + 32'h5: + MCU_DATA_IN_BUF <= SNES_SYSCLK_FREQ_BUF[7:0]; + endcase + else if (cmd_data[7:0] == 8'hFC) + case (spi_byte_cnt) + 32'h1: + SNES_SYSCLK_FREQ_BUF <= snes_pawr_freq; + 32'h2: + MCU_DATA_IN_BUF <= SNES_SYSCLK_FREQ_BUF[31:24]; + 32'h3: + MCU_DATA_IN_BUF <= SNES_SYSCLK_FREQ_BUF[23:16]; + 32'h4: + MCU_DATA_IN_BUF <= SNES_SYSCLK_FREQ_BUF[15:8]; + 32'h5: + MCU_DATA_IN_BUF <= SNES_SYSCLK_FREQ_BUF[7:0]; + endcase + else if (cmd_data[7:0] == 8'hFD) + case (spi_byte_cnt) + 32'h1: + SNES_SYSCLK_FREQ_BUF <= snes_refresh_freq; + 32'h2: + MCU_DATA_IN_BUF <= SNES_SYSCLK_FREQ_BUF[31:24]; + 32'h3: + MCU_DATA_IN_BUF <= SNES_SYSCLK_FREQ_BUF[23:16]; + 32'h4: + MCU_DATA_IN_BUF <= SNES_SYSCLK_FREQ_BUF[15:8]; + 32'h5: + MCU_DATA_IN_BUF <= SNES_SYSCLK_FREQ_BUF[7:0]; + endcase + else if (cmd_data[7:0] == 8'hFE) + case (spi_byte_cnt) + 32'h1: + SNES_SYSCLK_FREQ_BUF <= snes_sysclk_freq; + 32'h2: + MCU_DATA_IN_BUF <= SNES_SYSCLK_FREQ_BUF[31:24]; + 32'h3: + MCU_DATA_IN_BUF <= SNES_SYSCLK_FREQ_BUF[23:16]; + 32'h4: + MCU_DATA_IN_BUF <= SNES_SYSCLK_FREQ_BUF[15:8]; + 32'h5: + MCU_DATA_IN_BUF <= SNES_SYSCLK_FREQ_BUF[7:0]; + endcase + else if (cmd_data[7:0] == 8'hFF) + MCU_DATA_IN_BUF <= param_data; + end +end + +// nextaddr pulse generation +always @(posedge clk) begin + mcu_nextaddr_buf <= {mcu_nextaddr_buf[0], mcu_rq_rdy}; +end + +parameter ST_RQ = 2'b01; +parameter ST_IDLE = 2'b10; + +reg [1:0] rrq_state; +initial rrq_state = ST_IDLE; +reg mcu_rrq_r; + +reg [1:0] wrq_state; +initial wrq_state = ST_IDLE; +reg mcu_wrq_r; + +always @(posedge clk) begin + case(rrq_state) + ST_IDLE: begin + if((param_ready | cmd_ready) && cmd_data[7:4] == 4'h8) begin + mcu_rrq_r <= 1'b1; + rrq_state <= ST_RQ; + end else + rrq_state <= ST_IDLE; + end + ST_RQ: begin + mcu_rrq_r <= 1'b0; + rrq_state <= ST_IDLE; + end + endcase +end + +always @(posedge clk) begin + case(wrq_state) + ST_IDLE: begin + if(param_ready && cmd_data[7:4] == 4'h9) begin + mcu_wrq_r <= 1'b1; + wrq_state <= ST_RQ; + end else + wrq_state <= ST_IDLE; + end + ST_RQ: begin + mcu_wrq_r <= 1'b0; + wrq_state <= ST_IDLE; + end + endcase +end + +// trigger for nextaddr +assign mcu_nextaddr = mcu_nextaddr_buf == 2'b01; + +assign mcu_rrq = mcu_rrq_r; +assign mcu_wrq = mcu_wrq_r; +assign mcu_write = SD_DMA_STATUS + ?(SD_DMA_TGTr == 2'b00 + ?SD_DMA_SRAM_WE + :1'b1 + ) + : 1'b1; + +assign addr_out = ADDR_OUT_BUF; +assign dac_addr_out = DAC_ADDR_OUT_BUF; +assign msu_addr_out = MSU_ADDR_OUT_BUF; +assign dac_play_out = DAC_PLAY_OUT_BUF; +assign dac_reset_out = DAC_RESET_OUT_BUF; +assign msu_status_reset_we = msu_status_reset_we_buf; +assign msu_status_reset_out = msu_status_reset_out_buf; +assign msu_status_set_out = msu_status_set_out_buf; +assign msu_reset_out = MSU_RESET_OUT_BUF; +assign msu_ptr_out = MSU_PTR_OUT_BUF; + +assign bsx_regs_reset_we = bsx_regs_reset_we_buf; +assign bsx_regs_reset_out = bsx_regs_reset_out_buf; +assign bsx_regs_set_out = bsx_regs_set_out_buf; + +assign rtc_data_out = rtc_data_out_buf; +assign rtc_pgm_we = rtc_pgm_we_buf; + +assign srtc_reset = srtc_reset_buf; + +assign mcu_data_out = SD_DMA_STATUS ? SD_DMA_SRAM_DATA : MCU_DATA_OUT_BUF; +assign mcu_mapper = MAPPER_BUF; +assign rom_mask_out = ROM_MASK; +assign saveram_mask_out = SAVERAM_MASK; + +endmodule diff --git a/verilog/sd2snes_test/sd2snes_test.xise b/verilog/sd2snes_test/sd2snes_test.xise new file mode 100644 index 0000000..6c66fb1 --- /dev/null +++ b/verilog/sd2snes_test/sd2snes_test.xise @@ -0,0 +1,432 @@ + + + +
+ + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/verilog/sd2snes_test/sd_dma.v b/verilog/sd2snes_test/sd_dma.v new file mode 100644 index 0000000..2137370 --- /dev/null +++ b/verilog/sd2snes_test/sd_dma.v @@ -0,0 +1,132 @@ +`timescale 1ns / 1ps +////////////////////////////////////////////////////////////////////////////////// +// Company: +// Engineer: +// +// Create Date: 19:19:08 12/01/2010 +// Design Name: +// Module Name: sd_dma +// Project Name: +// Target Devices: +// Tool versions: +// Description: +// +// Dependencies: +// +// Revision: +// Revision 0.01 - File Created +// Additional Comments: +// +////////////////////////////////////////////////////////////////////////////////// +module sd_dma( + input [3:0] SD_DAT, + inout SD_CLK, + input CLK, + input SD_DMA_EN, + output SD_DMA_STATUS, + output SD_DMA_SRAM_WE, + output SD_DMA_NEXTADDR, + output [7:0] SD_DMA_SRAM_DATA, + input SD_DMA_PARTIAL, + input [10:0] SD_DMA_PARTIAL_START, + input [10:0] SD_DMA_PARTIAL_END +); + +reg [10:0] SD_DMA_STARTr; +reg [10:0] SD_DMA_ENDr; +reg SD_DMA_PARTIALr; +always @(posedge CLK) SD_DMA_PARTIALr <= SD_DMA_PARTIAL; + +reg SD_DMA_DONEr; +reg[1:0] SD_DMA_DONEr2; +initial begin + SD_DMA_DONEr2 = 2'b00; + SD_DMA_DONEr = 1'b0; +end +always @(posedge CLK) SD_DMA_DONEr2 <= {SD_DMA_DONEr2[0], SD_DMA_DONEr}; +wire SD_DMA_DONE_rising = (SD_DMA_DONEr2[1:0] == 2'b01); + +reg [1:0] SD_DMA_ENr; +initial SD_DMA_ENr = 2'b00; +always @(posedge CLK) SD_DMA_ENr <= {SD_DMA_ENr[0], SD_DMA_EN}; +wire SD_DMA_EN_rising = (SD_DMA_ENr [1:0] == 2'b01); + +reg SD_DMA_STATUSr; +assign SD_DMA_STATUS = SD_DMA_STATUSr; + +// we need 1042 cycles (startbit + 1024 nibbles + 16 crc + stopbit) +reg [10:0] cyclecnt; +initial cyclecnt = 11'd0; + +reg SD_DMA_SRAM_WEr; +initial SD_DMA_SRAM_WEr = 1'b1; +assign SD_DMA_SRAM_WE = (cyclecnt < 1025 && SD_DMA_STATUSr) ? SD_DMA_SRAM_WEr : 1'b1; + +reg SD_DMA_NEXTADDRr; +assign SD_DMA_NEXTADDR = (cyclecnt < 1025 && SD_DMA_STATUSr) ? SD_DMA_NEXTADDRr : 1'b0; + +reg[7:0] SD_DMA_SRAM_DATAr; +assign SD_DMA_SRAM_DATA = SD_DMA_SRAM_DATAr; + +// we have 4 internal cycles per SD clock, 8 per RAM byte write +reg [2:0] clkcnt; +initial clkcnt = 3'b000; +reg [1:0] SD_CLKr; +always @(posedge CLK) SD_CLKr <= {SD_CLKr[0], clkcnt[1]}; +assign SD_CLK = SD_DMA_STATUSr ? SD_CLKr[1] : 1'bZ; + +always @(posedge CLK) begin + if(SD_DMA_EN_rising) begin + SD_DMA_STATUSr <= 1'b1; + SD_DMA_STARTr <= (SD_DMA_PARTIALr ? SD_DMA_PARTIAL_START : 11'h0); + SD_DMA_ENDr <= (SD_DMA_PARTIALr ? SD_DMA_PARTIAL_END : 11'd1024); + end + else if (SD_DMA_DONE_rising) SD_DMA_STATUSr <= 1'b0; +end + +always @(posedge CLK) begin + if(cyclecnt == 1042) SD_DMA_DONEr <= 1; + else SD_DMA_DONEr <= 0; +end + +always @(posedge CLK) begin + if(SD_DMA_EN_rising || !SD_DMA_STATUSr) begin + clkcnt <= 0; + end else begin + if(SD_DMA_STATUSr) begin + clkcnt <= clkcnt + 1; + end + end +end + +always @(posedge CLK) begin + if(SD_DMA_EN_rising || !SD_DMA_STATUSr) cyclecnt <= 0; + else if(clkcnt[1:0] == 2'b11) cyclecnt <= cyclecnt + 1; +end + +// we have 8 clk cycles to complete one RAM write +// (4 clk cycles per SD_CLK; 2 SD_CLK cycles per byte) +always @(posedge CLK) begin + if(SD_DMA_STATUSr) begin + case(clkcnt[2:0]) + 3'h0: begin + SD_DMA_SRAM_WEr <= 1'b1; + SD_DMA_SRAM_DATAr[7:4] <= SD_DAT; + if(cyclecnt>SD_DMA_STARTr && cyclecnt <= SD_DMA_ENDr) SD_DMA_NEXTADDRr <= 1'b1; + end + 3'h1: + SD_DMA_NEXTADDRr <= 1'b0; +// 3'h2: + 3'h3: + if(cyclecnt>=SD_DMA_STARTr && cyclecnt < SD_DMA_ENDr) SD_DMA_SRAM_WEr <= 1'b0; + 3'h4: + SD_DMA_SRAM_DATAr[3:0] <= SD_DAT; +// 3'h5: +// 3'h6: +// 3'h7: + endcase + end +end + +endmodule + diff --git a/verilog/sd2snes_test/spi.v b/verilog/sd2snes_test/spi.v new file mode 100644 index 0000000..cb6bf79 --- /dev/null +++ b/verilog/sd2snes_test/spi.v @@ -0,0 +1,113 @@ +`timescale 1ns / 1ps +////////////////////////////////////////////////////////////////////////////////// +// Company: +// Engineer: +// +// Create Date: 21:16:09 07/10/2009 +// Design Name: +// Module Name: spi +// Project Name: +// Target Devices: +// Tool versions: +// Description: +// +// Dependencies: +// +// Revision: +// Revision 0.01 - File Created +// Additional Comments: +// + +////////////////////////////////////////////////////////////////////////////////// +module spi( + input clk, + input SCK, + input MOSI, + inout MISO, + input SSEL, + output cmd_ready, + output param_ready, + output [7:0] cmd_data, + output [7:0] param_data, + output endmessage, + output startmessage, + input [7:0] input_data, + output [31:0] byte_cnt, + output [2:0] bit_cnt +); + +reg [7:0] cmd_data_r; +reg [7:0] param_data_r; + +reg [1:0] SSELr; always @(posedge clk) SSELr <= {SSELr[0], SSEL}; +wire SSEL_active = ~SSELr[1]; // SSEL is active low +wire SSEL_startmessage = (SSELr[1:0]==2'b10); // message starts at falling edge +wire SSEL_endmessage = (SSELr[1:0]==2'b01); // message stops at rising edge +assign endmessage = SSEL_endmessage; +assign startmessage = SSEL_startmessage; + +// bit count for one SPI byte + byte count for the message +reg [2:0] bitcnt; +reg [31:0] byte_cnt_r; + +reg byte_received; // high when a byte has been received +reg [7:0] byte_data_received; + +assign bit_cnt = bitcnt; + +always @(posedge SCK) begin + if(SSEL) bitcnt <= 3'b000; + else begin + bitcnt <= bitcnt + 3'b001; + byte_data_received <= {byte_data_received[6:0], MOSI}; + end + if(~SSEL && bitcnt==3'b111) byte_received <= 1'b1; + else byte_received <= 1'b0; +end + +reg [1:0] byte_received_r; +always @(posedge clk) byte_received_r <= {byte_received_r[0], byte_received}; +wire byte_received_sync = (byte_received_r == 2'b01); + +always @(posedge clk) begin + if(~SSEL_active) + byte_cnt_r <= 16'h0000; + else if(byte_received_sync) begin + byte_cnt_r <= byte_cnt_r + 16'h0001; + end +end + +reg [7:0] byte_data_sent; + +assign MISO = ~SSEL ? input_data[7-bitcnt] : 1'bZ; // send MSB first + +reg cmd_ready_r; +reg param_ready_r; +reg cmd_ready_r2; +reg param_ready_r2; +assign cmd_ready = cmd_ready_r; +assign param_ready = param_ready_r; +assign cmd_data = cmd_data_r; +assign param_data = param_data_r; +assign byte_cnt = byte_cnt_r; + +always @(posedge clk) cmd_ready_r2 = byte_received_sync && byte_cnt_r == 32'h0; +always @(posedge clk) param_ready_r2 = byte_received_sync && byte_cnt_r > 32'h0; + +// fill registers +always @(posedge clk) begin + if (SSEL_startmessage) + cmd_data_r <= 8'h00; + else if(cmd_ready_r2) + cmd_data_r <= byte_data_received; + else if(param_ready_r2) + param_data_r <= byte_data_received; +end + +// delay ready signals by one clock +always @(posedge clk) begin + cmd_ready_r <= cmd_ready_r2; + param_ready_r <= param_ready_r2; +end + +endmodule