From 8ed1556594f833dc5cb8e59585fcbe9c43eba308 Mon Sep 17 00:00:00 2001 From: nand2mario Date: Sun, 19 May 2024 15:43:08 +0800 Subject: [PATCH] port snes/nes controller code from snestang --- build.tcl | 93 +++++++-- buildall.bat | 23 ++ nestang_nano20k.gprj | 15 +- nestang_primer25k.gprj | 3 +- src/NESGamepad.v | 177 ---------------- src/controller_ds2.sv | 36 ++++ src/controller_snes.v | 130 ++++++++++++ src/dualshock_controller.v | 2 +- .../config.sv => nano20k/config.v} | 3 + .../gowin_pll_hdmi.v | 0 .../gowin_pll_nes.ipc | 0 .../gowin_pll_nes.mod | 0 .../gowin_pll_nes.v | 0 .../gowin_pll_usb.v | 0 src/{tang_nano_20k => nano20k}/nestang.cst | 74 ++++--- src/{tang_nano_20k => nano20k}/nestang.sdc | 0 src/nestang_top.sv | 180 ++++++++-------- .../config.sv => primer25k/config.v} | 2 + src/primer25k/config_snescontroller.v | 15 ++ .../gowin_pll_27.ipc | 0 .../gowin_pll_27.mod | 0 .../gowin_pll_27.v | 0 .../gowin_pll_hdmi.v | 0 .../gowin_pll_nes.ipc | 0 .../gowin_pll_nes.mod | 0 .../gowin_pll_nes.v | 0 .../gowin_pll_usb.v | 0 .../nestang.cst | 53 ++--- .../nestang.sdc | 0 src/primer25k/nestang_snescontroller.cst | 197 ++++++++++++++++++ 30 files changed, 647 insertions(+), 356 deletions(-) create mode 100644 buildall.bat delete mode 100644 src/NESGamepad.v create mode 100644 src/controller_ds2.sv create mode 100644 src/controller_snes.v rename src/{tang_nano_20k/config.sv => nano20k/config.v} (87%) rename src/{tang_nano_20k => nano20k}/gowin_pll_hdmi.v (100%) rename src/{tang_nano_20k => nano20k}/gowin_pll_nes.ipc (100%) rename src/{tang_nano_20k => nano20k}/gowin_pll_nes.mod (100%) rename src/{tang_nano_20k => nano20k}/gowin_pll_nes.v (100%) rename src/{tang_nano_20k => nano20k}/gowin_pll_usb.v (100%) rename src/{tang_nano_20k => nano20k}/nestang.cst (64%) rename src/{tang_nano_20k => nano20k}/nestang.sdc (100%) rename src/{tang_primer_25k/config.sv => primer25k/config.v} (93%) create mode 100644 src/primer25k/config_snescontroller.v rename src/{tang_primer_25k => primer25k}/gowin_pll_27.ipc (100%) rename src/{tang_primer_25k => primer25k}/gowin_pll_27.mod (100%) rename src/{tang_primer_25k => primer25k}/gowin_pll_27.v (100%) rename src/{tang_primer_25k => primer25k}/gowin_pll_hdmi.v (100%) rename src/{tang_primer_25k => primer25k}/gowin_pll_nes.ipc (100%) rename src/{tang_primer_25k => primer25k}/gowin_pll_nes.mod (100%) rename src/{tang_primer_25k => primer25k}/gowin_pll_nes.v (100%) rename src/{tang_primer_25k => primer25k}/gowin_pll_usb.v (100%) rename src/{tang_primer_25k => primer25k}/nestang.cst (86%) rename src/{tang_primer_25k => primer25k}/nestang.sdc (100%) create mode 100644 src/primer25k/nestang_snescontroller.cst diff --git a/build.tcl b/build.tcl index 1f1e59c..cba6264 100644 --- a/build.tcl +++ b/build.tcl @@ -1,12 +1,56 @@ +if {$argc == 0} { + puts "Usage: $argv0 []" + puts " device: nano20k, primer25k" + puts " controller: snes, ds2" + puts "Note: nano20k supports both controllers simultaneously, so build with just: gw_sh build.tcl nano20k" + exit 1 +} + +set dev [lindex $argv 0] +if {$argc == 2} { + set controller [lindex $argv 1] +} else { + set controller "" +} + +# process $dev and $controller +if {$dev eq "nano20k"} { + set_device GW2AR-LV18QN88C8/I7 -device_version C + add_file src/nano20k/config.v + add_file -type cst "src/nano20k/nestang.cst" + add_file -type verilog "src/nano20k/gowin_pll_hdmi.v" + add_file -type verilog "src/nano20k/gowin_pll_nes.v" + # nano20k supports both controllers simultaneously + set_option -output_base_name nestang_${dev} +} elseif {$dev eq "primer25k"} { + set_device GW5A-LV25MG121NC1/I0 -device_version A + if {$controller eq "snes"} { + add_file src/primer25k/config_snescontroller.v + add_file -type cst "src/primer25k/nestang_snescontroller.cst" + } elseif {$controller eq "ds2"} { + add_file src/primer25k/config.v + add_file -type cst "src/primer25k/nestang.cst" + } else { + error "Unknown controller $controller" + } + add_file -type verilog "src/primer25k/gowin_pll_27.v" + add_file -type verilog "src/primer25k/gowin_pll_hdmi.v" + add_file -type verilog "src/primer25k/gowin_pll_nes.v" + set_option -output_base_name nestang_${dev}_${controller} +} else { + error "Unknown device $dev" +} -add_file -type verilog "src/MicroCode.v" add_file -type verilog "src/apu.v" add_file -type verilog "src/autofire.v" +add_file -type verilog "src/cart.sv" add_file -type verilog "src/compat.v" -add_file -type verilog "src/cpu.v" +add_file -type verilog "src/controller_snes.v" +add_file -type verilog "src/controller_ds2.sv" +add_file -type verilog "src/dpram.v" add_file -type verilog "src/dualshock_controller.v" +add_file -type verilog "src/EEPROM_24C0x.sv" add_file -type verilog "src/game_loader.v" -add_file -type verilog "src/gowin_clkdiv.v" add_file -type verilog "src/hdmi2/audio_clock_regeneration_packet.sv" add_file -type verilog "src/hdmi2/audio_info_frame.sv" add_file -type verilog "src/hdmi2/audio_sample_packet.sv" @@ -17,33 +61,40 @@ add_file -type verilog "src/hdmi2/packet_picker.sv" add_file -type verilog "src/hdmi2/serializer.sv" add_file -type verilog "src/hdmi2/source_product_description_info_frame.sv" add_file -type verilog "src/hdmi2/tmds_channel.sv" -add_file -type verilog "src/hw_sound.v" add_file -type verilog "src/hw_uart.v" -add_file -type verilog "src/memory_controller.v" -add_file -type verilog "src/mmu.v" +add_file -type verilog "src/iosys/gowin_dpb_menu.v" +add_file -type verilog "src/iosys/iosys.v" +add_file -type verilog "src/iosys/picorv32.v" +add_file -type verilog "src/iosys/simplespimaster.v" +add_file -type verilog "src/iosys/simpleuart.v" +add_file -type verilog "src/iosys/spi_master.v" +add_file -type verilog "src/iosys/spiflash.v" +add_file -type verilog "src/iosys/textdisp.v" +add_file -type verilog "src/mappers/generic.sv" +add_file -type verilog "src/mappers/iir_filter.v" +add_file -type verilog "src/mappers/JYCompany.sv" +add_file -type verilog "src/mappers/misc.sv" +add_file -type verilog "src/mappers/MMC1.sv" +add_file -type verilog "src/mappers/MMC2.sv" +add_file -type verilog "src/mappers/MMC3.sv" +add_file -type verilog "src/mappers/MMC5.sv" +add_file -type verilog "src/mappers/Namco.sv" +add_file -type verilog "src/mappers/Sachen.sv" +add_file -type verilog "src/mappers/Sunsoft.sv" add_file -type verilog "src/nes.v" add_file -type verilog "src/nes2hdmi.sv" add_file -type verilog "src/nestang_top.sv" add_file -type verilog "src/ppu.v" -add_file -type verilog "src/sd_file_list_reader.v" -add_file -type verilog "src/sd_loader.v" -add_file -type verilog "src/sd_reader.sv" -add_file -type verilog "src/sdcmd_ctrl.sv" -add_file -type verilog "src/sdram.v" +add_file -type verilog "src/sdram_nes.v" +add_file -type verilog "src/t65/T65.v" +add_file -type verilog "src/t65/T65_ALU.v" +add_file -type verilog "src/t65/T65_MCode.v" +add_file -type verilog "src/t65/T65_Pack.v" add_file -type verilog "src/uart_tx_V2.v" add_file -type verilog "src/usb_hid_host.v" add_file -type verilog "src/usb_hid_host_rom.v" -add_file -type verilog "src/NESGamepad.v" -add_file -type verilog "src/mapLoopy.v" - -if {$dev eq "nano20k"} { - set_device GW2AR-LV18QN88C8/I7 -device_version C -} elseif {$dev eq "primer25k"} { - set_device GW5A-LV25MG121NC1/I0 -device_version A -} set_option -synthesis_tool gowinsynthesis -set_option -output_base_name nestang_$dev set_option -top_module nestang_top set_option -verilog_std sysv2017 set_option -rw_check_on_ram 1 @@ -52,6 +103,8 @@ set_option -use_ready_as_gpio 1 set_option -use_done_as_gpio 1 set_option -use_i2c_as_gpio 1 set_option -use_cpu_as_gpio 1 +set_option -use_sspi_as_gpio 1 + set_option -multi_boot 1 run all diff --git a/buildall.bat b/buildall.bat new file mode 100644 index 0000000..c3177e6 --- /dev/null +++ b/buildall.bat @@ -0,0 +1,23 @@ + +@echo off +set GWSH=c:\Gowin\Gowin_V1.9.9_x64\IDE\bin\gw_sh + +echo. +echo ============ Building nano20k =============== +echo. +%GWSH% build.tcl nano20k + +echo. +echo ============ Building primer25k with snes/nes controller =============== +echo. +%GWSH% build.tcl primer25k snes + +echo. +echo ============ Building primer25k with ds2 controller =============== +echo. +%GWSH% build.tcl primer25k ds2 + +dir impl\pnr\*.fs + +echo "All done." + diff --git a/nestang_nano20k.gprj b/nestang_nano20k.gprj index 9c8bea4..a739025 100644 --- a/nestang_nano20k.gprj +++ b/nestang_nano20k.gprj @@ -6,11 +6,12 @@ gw2ar18c-000 - + + @@ -45,6 +46,9 @@ + + + @@ -54,17 +58,10 @@ - - - - - - - - + diff --git a/nestang_primer25k.gprj b/nestang_primer25k.gprj index 06f2d57..b1dd6dc 100644 --- a/nestang_primer25k.gprj +++ b/nestang_primer25k.gprj @@ -6,11 +6,12 @@ gw5a25a-002 - + + diff --git a/src/NESGamepad.v b/src/NESGamepad.v deleted file mode 100644 index 8f96274..0000000 --- a/src/NESGamepad.v +++ /dev/null @@ -1,177 +0,0 @@ - -// NES classic gamepad based on https://github.com/michael-swan/NES-Controller-SIPO -// fjpolo, 11.2023 - -module NESGamepad( - input i_clk, - input i_rst, - // Device connections - output o_data_clock, - output o_data_latch, - input i_serial_data, - // Data output - output [7:0] o_button_state, - output o_data_available - ); - parameter NUMBER_OF_STATES = 10; // Latch -> 2 * 60uS - // Data -> 8 * 2 * 60uS - // Write -> 2 * 60uS - parameter LAST_STATE = NUMBER_OF_STATES-1; - - // Unit Parameters // - parameter Hz = 1; - parameter KHz = 1000*Hz; - parameter MHz = 1000*KHz; - - // Context-sensitive Parameters // - parameter MASTER_CLOCK_FREQUENCY = 27*MHz; // USER VARIABLE - parameter OUTPUT_UPDATE_FREQUENCY = 120*Hz; // USER VARIABLE - parameter LATCH_CYCLES = (12 / 1000000) * (1 / MASTER_CLOCK_FREQUENCY); - parameter LATCH_120uS_CYCLES = 324; - - // Clock divider register size - // parameter DIVIDER_EXPONENT = log2( (MASTER_CLOCK_FREQUENCY / OUTPUT_UPDATE_FREQUENCY) / 10 ) - 2; - parameter COUNTER_60Hz = 225000; - parameter COUNTER_120uS = 1620; - parameter COUNTER_120uS_HALF = 810; - parameter BUSY_CYCLES = 2 * NUMBER_OF_STATES * COUNTER_120uS; - - // Keep track of the stage of the cycle - reg [(LAST_STATE):0] cycle_stage; // Latch 120uS -> Wait 60uS -> Data 8x120uS -> End - reg [7:0] data; - reg [20:0] clock_counter_60Hz; - reg [20:0] clock_counter_120uS; - reg [7:0] button_state; - wire clock_60Hz; - wire clock_120uS; - - // Generate control signals for the three states - wire latch_state = cycle_stage[0] & (clock_counter_60Hz <= (2 * NUMBER_OF_STATES * COUNTER_120uS + NUMBER_OF_STATES)); - wire data_state = cycle_stage[1] - | cycle_stage[2] - | cycle_stage[3] - | cycle_stage[4] - | cycle_stage[5] - | cycle_stage[6] - | cycle_stage[7] - | cycle_stage[8]; - wire write_state = cycle_stage[9]; - - // Generate a clock for generating the data clock and sampling the controller's output - initial cycle_stage = 1; - initial data = 8'h00; - initial button_state = 8'h00; - initial clock_counter_60Hz = 0; - initial clock_counter_120uS = 0; - - // Handle 60Hz clock counter - always @(posedge i_clk) begin - if(!i_rst) begin - clock_counter_60Hz <= 0; - end else begin - if(clock_counter_60Hz < (2 * COUNTER_60Hz)) begin - clock_counter_60Hz <= clock_counter_60Hz + 1; - end else begin - clock_counter_60Hz <= 0; - end - end - end - - // Handle 60Hz clock - assign clock_60Hz = (clock_counter_60Hz < COUNTER_60Hz); - - // Handle 120uS clock counter - always @(posedge i_clk) begin - if(!i_rst) begin - clock_counter_120uS <= 0; - cycle_stage <= 1; - data <= 8'h00; - button_state <= 8'h00; - end else begin - // Counter - if((clock_counter_60Hz > 0) && (clock_counter_60Hz <= (2 * NUMBER_OF_STATES * COUNTER_120uS + NUMBER_OF_STATES))) begin - if(clock_counter_120uS < (2 * COUNTER_120uS)) begin - clock_counter_120uS <= clock_counter_120uS + 1; - end else begin - clock_counter_120uS <= 0; - if(cycle_stage < (1 << LAST_STATE) && (cycle_stage != 0)) - cycle_stage <= cycle_stage << 1; - else - cycle_stage <= 1; - end - end else begin - clock_counter_120uS <= 0; - end - - // Handle button output - if(!clock_120uS) begin - // data <= 8'h00; - // button_state <= 8'h00; - end else begin - if(latch_state) begin - data <= 8'h00; - end else if(data_state) begin - // data <= {!i_serial_data, data[7:1]}; - // data <= {data[6:0], !i_serial_data}; - case(cycle_stage) - (1 << 1): data[0] <= !i_serial_data; // A - (1 << 2): data[1] <= !i_serial_data; // B - (1 << 3): data[2] <= !i_serial_data; // Select - (1 << 4): data[3] <= !i_serial_data; // Start - (1 << 5): data[4] <= !i_serial_data; // Up - (1 << 6): data[5] <= !i_serial_data; // Down - (1 << 7): data[6] <= !i_serial_data; // Left - (1 << 8): data[7] <= !i_serial_data; // Right - endcase - end else if(write_state) begin - button_state <= data; - end - end - end - end - - // Handle 120uS clock - assign clock_120uS = (clock_counter_120uS > 0) && (clock_counter_120uS <= COUNTER_120uS); - - // Assign outputs - // assign o_data_latch = (clock_counter_60Hz <= (2 * COUNTER_120uS)); - assign o_data_latch = latch_state; - assign o_data_clock = clock_60Hz & clock_120uS & !latch_state; - assign o_data_available = write_state; - assign o_button_state = button_state; - - // - // Formal verification - // - `ifdef FORMAL - - // Clock 60Hz - always @(*) - assert(clock_counter_60Hz <= (2 * COUNTER_60Hz)); - - // Clock 120uS - always @(*) - assert(clock_counter_120uS <= (2 * COUNTER_120uS)); - - // Cycle stage - reg f_valid_state; - always @(*) begin - f_valid_state = 0; - case(cycle_stage) - 9'h01: f_valid_state = 1'b1; - 9'h02: f_valid_state = 1'b1; - 9'h04: f_valid_state = 1'b1; - 9'h08: f_valid_state = 1'b1; - 9'h10: f_valid_state = 1'b1; - 9'h20: f_valid_state = 1'b1; - 9'h40: f_valid_state = 1'b1; - 9'h80: f_valid_state = 1'b1; - 9'h100: f_valid_state = 1'b1; - endcase - assert(f_valid_state); - end - - `endif - - -endmodule \ No newline at end of file diff --git a/src/controller_ds2.sv b/src/controller_ds2.sv new file mode 100644 index 0000000..b77698e --- /dev/null +++ b/src/controller_ds2.sv @@ -0,0 +1,36 @@ + +// convert dualshock to snes controller +module controller_ds2 #(parameter FREQ=21_600_000) ( + input clk, + + output [11:0] snes_buttons, // (R L X A RT LT DN UP START SELECT Y B) + + output ds_clk, + input ds_miso, + output ds_mosi, + output ds_cs +); + +wire [7:0] rx0, rx1; + +// JOYDATA: BYsS UDLR AXlr 0000 +// Up: 0400, Down: 0200, Left: 0100, Right: 0080 + +// dualshock buttons: 0:(L D R U St R3 L3 Se) 1:(□ X O △ R1 L1 R2 L2) +// 12 SNES buttons: (RB LB X A RIGHT LEFT DOWN UP START SELECT Y B) +// A=O, B=X, X=△, Y=□ +assign snes_buttons = {~rx1[3] | ~rx1[1], ~rx1[2] | ~rx1[0], // RB LB + ~rx1[4], ~rx1[5], ~rx0[5], ~rx0[7], // X A RIGHT LEFT + ~rx0[6], ~rx0[4], ~rx0[3], ~rx0[0], // DOWN, UP, ST, SE + ~rx1[7], ~rx1[6]}; // Y B + +// Dualshock controller +dualshock_controller #(.FREQ(FREQ)) ds ( + .clk(clk), .I_RSTn(1'b1), + .O_psCLK(ds_clk), .O_psSEL(ds_cs), .O_psTXD(ds_mosi), + .I_psRXD(ds_miso), + .O_RXD_1(rx0), .O_RXD_2(rx1), .O_RXD_3(), + .O_RXD_4(), .O_RXD_5(), .O_RXD_6() +); + +endmodule \ No newline at end of file diff --git a/src/controller_snes.v b/src/controller_snes.v new file mode 100644 index 0000000..61f4620 --- /dev/null +++ b/src/controller_snes.v @@ -0,0 +1,130 @@ +// A self-scanning SNES/NES controller interface +module controller_snes #( + parameter FREQ = 21_500_000 // frequency of clk +)( + input clk, + input resetn, + + // I/O interface to actual controller + output reg joy_strb, + output joy_clk, + input joy_data, // 0: button pressed, needs to be pulled up + + // Button status, 1=pressed: (R L X A RT LT DN UP START SELECT Y B) + output reg [11:0] buttons +); + +/* + +https://gamefaqs.gamespot.com/snes/916396-super-nintendo/faqs/5395 + + ----------------------------- --------------------- + | | \ + | (1) (2) (3) (4) | (5) (6) (7) | + | | / + ----------------------------- --------------------- + + Pin Description Color of wire in cable + === =========== ====================== + 1 +5v White + 2 Data clock Yellow + 3 Data latch Orange + 4 Serial data Red + 5 ? no wire + 6 ? no wire + 7 Ground Brown + +Every 16.67ms (or about 60Hz), the SNES CPU sends out a 12us wide, positive +going data latch pulse on pin 3. This instructs the ICs in the controller +to latch the state of all buttons internally. Six microsenconds after the +fall of the data latch pulse, the CPU sends out 16 data clock pulses on +pin 2. These are 50% duty cycle with 12us per full cycle. The controllers +serially shift the latched button states out pin 4 on every rising edge +of the clock, and the CPU samples the data on every falling edge. + + Clock Cycle Button Reported + =========== =============== + 1 B + 2 Y + 3 Select + 4 Start + 5 Up on joypad + 6 Down on joypad + 7 Left on joypad + 8 Right on joypad + 9 A + 10 X + 11 L + 12 R + 13 none (always high) + 14 none (always high) + 15 none (always high) + 16 none (always high) +*/ + +localparam TIME_6US = FREQ / 1000000 * 6; + +reg joy_clk_reg = 1; +assign joy_clk = joy_clk_reg; + +reg [2:0] state; +reg [$clog2(FREQ/1000*16)-1:0] cnt; // max 16 ms +reg [3:0] bits; +reg [15:0] buttons_buf; + +localparam [1:0] LATCH = 0; +localparam [1:0] CLK_HIGH = 1; +localparam [1:0] CLK_LOW = 2; +localparam [1:0] WAIT = 3; + +always @(posedge clk) begin + if (~resetn) begin + joy_clk_reg <= 1; + cnt <= 0; + state <= 0; + end else begin + cnt <= cnt + 1; + case (state) + LATCH: begin // send 12us-wide latch + joy_strb <= 1; + if (cnt == TIME_6US * 2 - 1) begin + joy_strb <= 0; + state <= CLK_HIGH; + cnt <= 0; + bits <= 0; + end + end + + CLK_HIGH: begin // wait 6us, then joy_clk falls, sample bit + if (cnt == TIME_6US - 1) begin + joy_clk_reg <= 0; + cnt <= 0; + state <= CLK_LOW; + buttons_buf <= {~joy_data, buttons_buf[15:1]}; // shift right + end + end + + CLK_LOW: begin // wait 6us, then joy_clk rises + if (cnt == TIME_6US - 1) begin + joy_clk_reg <= 1; + cnt <= 0; + bits <= bits + 1; + if (bits == 4'd15) begin // scan complete + state <= 3; + buttons <= buttons_buf[11:0]; + end else + state <= 1; + end + end + + WAIT: // wait 16ms, then start again + if (cnt == FREQ / 1000 * 16 - 1) begin + cnt <= 0; + state <= 0; + end + + endcase + end +end + +endmodule \ No newline at end of file diff --git a/src/dualshock_controller.v b/src/dualshock_controller.v index 0af6dba..4386434 100644 --- a/src/dualshock_controller.v +++ b/src/dualshock_controller.v @@ -44,7 +44,7 @@ `endif module dualshock_controller #( - parameter FREQ = 21_477_000 // frequency of `clk` + parameter FREQ // frequency of `clk` ) ( input clk, // Any main clock faster than 1Mhz input I_RSTn, // MAIN RESET diff --git a/src/tang_nano_20k/config.sv b/src/nano20k/config.v similarity index 87% rename from src/tang_nano_20k/config.sv rename to src/nano20k/config.v index 82dbab1..2db4fff 100644 --- a/src/tang_nano_20k/config.sv +++ b/src/nano20k/config.v @@ -2,6 +2,9 @@ `define GW_IDE `define NANO +`define CONTROLLER_SNES +`define CONTROLLER_DS2 + package configPackage; // total space: 4B * 2K * 256 * 4 = 8MB diff --git a/src/tang_nano_20k/gowin_pll_hdmi.v b/src/nano20k/gowin_pll_hdmi.v similarity index 100% rename from src/tang_nano_20k/gowin_pll_hdmi.v rename to src/nano20k/gowin_pll_hdmi.v diff --git a/src/tang_nano_20k/gowin_pll_nes.ipc b/src/nano20k/gowin_pll_nes.ipc similarity index 100% rename from src/tang_nano_20k/gowin_pll_nes.ipc rename to src/nano20k/gowin_pll_nes.ipc diff --git a/src/tang_nano_20k/gowin_pll_nes.mod b/src/nano20k/gowin_pll_nes.mod similarity index 100% rename from src/tang_nano_20k/gowin_pll_nes.mod rename to src/nano20k/gowin_pll_nes.mod diff --git a/src/tang_nano_20k/gowin_pll_nes.v b/src/nano20k/gowin_pll_nes.v similarity index 100% rename from src/tang_nano_20k/gowin_pll_nes.v rename to src/nano20k/gowin_pll_nes.v diff --git a/src/tang_nano_20k/gowin_pll_usb.v b/src/nano20k/gowin_pll_usb.v similarity index 100% rename from src/tang_nano_20k/gowin_pll_usb.v rename to src/nano20k/gowin_pll_usb.v diff --git a/src/tang_nano_20k/nestang.cst b/src/nano20k/nestang.cst similarity index 64% rename from src/tang_nano_20k/nestang.cst rename to src/nano20k/nestang.cst index bb61659..5ff100b 100644 --- a/src/tang_nano_20k/nestang.cst +++ b/src/nano20k/nestang.cst @@ -56,25 +56,6 @@ IO_PORT "tmds_clk_p" PULL_MODE=NONE DRIVE=8 BANK_VCCIO=3.3; // IO_LOC "NES_gampead_serial_data" 25; // IO_PORT "NES_gampead_serial_data" IO_TYPE=LVCMOS33 PULL_MODE=NONE PCI_CLAMP=OFF BANK_VCCIO=3.3; -// Controllers -IO_LOC "joystick_clk" 17; -IO_PORT "joystick_clk" IO_TYPE=LVCMOS33 PULL_MODE=NONE DRIVE=8 BANK_VCCIO=3.3; -IO_LOC "joystick_cs" 18; -IO_PORT "joystick_cs" IO_TYPE=LVCMOS33 PULL_MODE=NONE DRIVE=8 BANK_VCCIO=3.3; -IO_LOC "joystick_mosi" 20; -IO_PORT "joystick_mosi" IO_TYPE=LVCMOS33 PULL_MODE=NONE DRIVE=8 BANK_VCCIO=3.3; -IO_LOC "joystick_miso" 19; -IO_PORT "joystick_miso" IO_TYPE=LVCMOS33 PULL_MODE=UP BANK_VCCIO=3.3; - -IO_LOC "joystick_clk2" 52; -IO_PORT "joystick_clk2" IO_TYPE=LVCMOS33 PULL_MODE=NONE DRIVE=8 BANK_VCCIO=3.3; -IO_LOC "joystick_cs2" 72; -IO_PORT "joystick_cs2" IO_TYPE=LVCMOS33 PULL_MODE=NONE DRIVE=8 BANK_VCCIO=3.3; -IO_LOC "joystick_mosi2" 53; -IO_PORT "joystick_mosi2" IO_TYPE=LVCMOS33 PULL_MODE=NONE DRIVE=8 BANK_VCCIO=3.3; -IO_LOC "joystick_miso2" 71; -IO_PORT "joystick_miso2" IO_TYPE=LVCMOS33 PULL_MODE=UP BANK_VCCIO=3.3; - // SD Card IO_LOC "sd_clk" 83; IO_PORT "sd_clk" IO_TYPE=LVCMOS33 PULL_MODE=NONE DRIVE=8 BANK_VCCIO=3.3; @@ -95,12 +76,49 @@ IO_PORT "led[1]" IO_TYPE=LVCMOS33 PULL_MODE=UP DRIVE=8 BANK_VCCIO=3.3; IO_LOC "led[0]" 15; IO_PORT "led[0]" IO_TYPE=LVCMOS33 PULL_MODE=UP DRIVE=8 BANK_VCCIO=3.3; -// USB -IO_LOC "usbdp2" 56; -IO_PORT "usbdp2" IO_TYPE=LVCMOS33 PULL_MODE=DOWN DRIVE=8 BANK_VCCIO=3.3; -IO_LOC "usbdm2" 54; -IO_PORT "usbdm2" IO_TYPE=LVCMOS33 PULL_MODE=DOWN DRIVE=8 BANK_VCCIO=3.3; -IO_LOC "usbdp" 42; -IO_PORT "usbdp" IO_TYPE=LVCMOS33 PULL_MODE=DOWN DRIVE=8 BANK_VCCIO=3.3; -IO_LOC "usbdm" 41; -IO_PORT "usbdm" IO_TYPE=LVCMOS33 PULL_MODE=DOWN DRIVE=8 BANK_VCCIO=3.3; +// USB (disabled for now due to lack of PLLs) +// IO_LOC "usbdp2" 56; +// IO_PORT "usbdp2" IO_TYPE=LVCMOS33 PULL_MODE=DOWN DRIVE=8 BANK_VCCIO=3.3; +// IO_LOC "usbdm2" 54; +// IO_PORT "usbdm2" IO_TYPE=LVCMOS33 PULL_MODE=DOWN DRIVE=8 BANK_VCCIO=3.3; +// IO_LOC "usbdp" 42; +// IO_PORT "usbdp" IO_TYPE=LVCMOS33 PULL_MODE=DOWN DRIVE=8 BANK_VCCIO=3.3; +// IO_LOC "usbdm" 41; +// IO_PORT "usbdm" IO_TYPE=LVCMOS33 PULL_MODE=DOWN DRIVE=8 BANK_VCCIO=3.3; + +//------------------------------------------------------------------------------------ +// controllers +IO_LOC "ds_clk" 17; +IO_PORT "ds_clk" IO_TYPE=LVCMOS33 PULL_MODE=NONE DRIVE=8 BANK_VCCIO=3.3; +IO_LOC "ds_miso" 19; +IO_PORT "ds_miso" IO_TYPE=LVCMOS33 PULL_MODE=UP BANK_VCCIO=3.3; +IO_LOC "ds_mosi" 20; +IO_PORT "ds_mosi" IO_TYPE=LVCMOS33 PULL_MODE=NONE DRIVE=8 BANK_VCCIO=3.3; +IO_LOC "ds_cs" 18; +IO_PORT "ds_cs" IO_TYPE=LVCMOS33 PULL_MODE=NONE DRIVE=8 BANK_VCCIO=3.3; + +IO_LOC "ds_clk2" 52; +IO_PORT "ds_clk2" IO_TYPE=LVCMOS33 PULL_MODE=NONE DRIVE=8 BANK_VCCIO=3.3; +IO_LOC "ds_miso2" 71; +IO_PORT "ds_miso2" IO_TYPE=LVCMOS33 PULL_MODE=UP BANK_VCCIO=3.3; +IO_LOC "ds_mosi2" 53; +IO_PORT "ds_mosi2" IO_TYPE=LVCMOS33 PULL_MODE=NONE DRIVE=8 BANK_VCCIO=3.3; +IO_LOC "ds_cs2" 72; +IO_PORT "ds_cs2" IO_TYPE=LVCMOS33 PULL_MODE=NONE DRIVE=8 BANK_VCCIO=3.3; + +// SNES controller 1 +IO_LOC "joy1_strb" 28; +IO_PORT "joy1_strb" PULL_MODE=NONE IO_TYPE=LVCMOS33; +IO_LOC "joy1_clk" 27; +IO_PORT "joy1_clk" PULL_MODE=NONE IO_TYPE=LVCMOS33; +IO_LOC "joy1_data" 25; +IO_PORT "joy1_data" PULL_MODE=UP IO_TYPE=LVCMOS33; + +// SNES controller 2 +IO_LOC "joy2_strb" 29; +IO_PORT "joy2_strb" PULL_MODE=NONE IO_TYPE=LVCMOS33; +IO_LOC "joy2_clk" 26; +IO_PORT "joy2_clk" PULL_MODE=NONE IO_TYPE=LVCMOS33; +IO_LOC "joy2_data" 30; +IO_PORT "joy2_data" PULL_MODE=UP IO_TYPE=LVCMOS33; + diff --git a/src/tang_nano_20k/nestang.sdc b/src/nano20k/nestang.sdc similarity index 100% rename from src/tang_nano_20k/nestang.sdc rename to src/nano20k/nestang.sdc diff --git a/src/nestang_top.sv b/src/nestang_top.sv index 8882e83..698ad3e 100644 --- a/src/nestang_top.sv +++ b/src/nestang_top.sv @@ -49,34 +49,36 @@ module nestang_top ( output flash_spi_wp_n, // write protect output flash_spi_hold_n, // hold operations - // Dualshock game controller - output joystick_clk, - output joystick_mosi, - input joystick_miso, - output reg joystick_cs, - output joystick_clk2, - output joystick_mosi2, - input joystick_miso2, - output reg joystick_cs2, - - // USB - inout usbdm, - inout usbdp, -`ifndef PRIMER - inout usbdm2, - inout usbdp2, +`ifdef CONTROLLER_SNES + // snes controllers + output joy1_strb, + output joy1_clk, + input joy1_data, + output joy2_strb, + output joy2_clk, + input joy2_data, `endif - // NES gamepad -`ifdef NANO - // output NES_gamepad_data_clock, - // output NES_gampepad_data_latch, - // input NES_gampead_serial_data, - // output NES_gamepad_data_clock2, - // output NES_gampepad_data_latch2, - // input NES_gampead_serial_data2, +`ifdef CONTROLLER_DS2 + // dualshock controllers + output ds_clk, + input ds_miso, + output ds_mosi, + output ds_cs, + output ds_clk2, + input ds_miso2, + output ds_mosi2, + output ds_cs2, `endif + // USB +// inout usbdm, +// inout usbdp, +// `ifndef PRIMER +// inout usbdm2, +// inout usbdp2, +// `endif + // HDMI TX output tmds_clk_n, output tmds_clk_p, @@ -149,8 +151,11 @@ wire [7:0] joy_rx[0:1], joy_rx2[0:1]; // 6 RX bytes for all button/axis stat wire [7:0] usb_btn, usb_btn2; wire usb_btn_x, usb_btn_y, usb_btn_x2, usb_btn_y2; wire usb_conerr, usb_conerr2; -wire auto_square, auto_triangle, auto_square2, auto_triangle2; -wire [7:0] nes_btn, nes_btn2; +wire auto_a, auto_b, auto_a2, auto_b2; + +// OR together when both SNES and DS2 controllers are connected (right now only nano20k supports both simultaneously) +wor [11:0] joy1_btns, joy2_btns; // SNES layout (R L X A RT LT DN UP START SELECT Y B) + // Lower 8 bits are NES buttons // NES gamepad wire [7:0]NES_gamepad_button_state; @@ -194,7 +199,7 @@ reg [7:0] reset_cnt = 255; // reset for 255 cycles before start everything always @(posedge clk) begin reset_cnt <= reset_cnt == 0 ? 0 : reset_cnt - 1; if (reset_cnt == 0) - sys_resetn <= ~(nes_btn[5] && nes_btn[2]); // 8BitDo Home button = Select + Down + sys_resetn <= ~(joy1_btns[5] && joy1_btns[2]); // 8BitDo Home button = Select + Down end `ifndef VERILATOR @@ -209,12 +214,6 @@ assign clk27 = sys_clk; // Nano20K: native 27Mhz system clock gowin_pll_nes pll_nes(.clkin(sys_clk), .clkoutd3(clk), .clkout(fclk), .clkoutp(O_sdram_clk)); `endif // PRIMER -// USB clock 12Mhz -// gowin_pll_usb pll_usb( -// .clkin(clk), -// .clkout(clk_usb) // 12Mhz usb clock -// ); - gowin_pll_hdmi pll_hdmi ( .clkin(clk27), .clkout(hclk5) @@ -459,7 +458,7 @@ iosys #(.COLOR_LOGO(15'b01100_00000_01000), .CORE_ID(1) ) // purple nestang .overlay(overlay), .overlay_x(overlay_x), .overlay_y(overlay_y), .overlay_color(overlay_color), - .joy1(nes_btn), .joy2(nes_btn2), + .joy1(joy1_btns), .joy2(joy2_btns), .rom_loading(loading), .rom_do(loader_do), .rom_do_valid(loader_do_valid), .ram_busy(sdram_busy), @@ -477,45 +476,40 @@ iosys #(.COLOR_LOGO(15'b01100_00000_01000), .CORE_ID(1) ) // purple nestang .sd_dat2(sd_dat2), .sd_dat3(sd_dat3) ); -// Dualshock controller -// joy_rx[0:1] dualshock buttons: 0:(L D R U St R3 L3 Se) 1:(□ X O △ R1 L1 R2 L2) -// nes_btn[0:1] NES buttons: (R L D U START SELECT B A) -// O is A, X is B -dualshock_controller controller ( - .clk(clk), .I_RSTn(1'b1), - .O_psCLK(joystick_clk), .O_psSEL(joystick_cs), .O_psTXD(joystick_mosi), - .I_psRXD(joystick_miso), - .O_RXD_1(joy_rx[0]), .O_RXD_2(joy_rx[1]), .O_RXD_3(), - .O_RXD_4(), .O_RXD_5(), .O_RXD_6() +// Controller input +`ifdef CONTROLLER_SNES +controller_snes joy1_snes ( + .clk(clk), .resetn(resetn), .buttons(joy1_btns), + .joy_strb(joy1_strb), .joy_clk(joy1_clk), .joy_data(joy1_data) ); - -dualshock_controller controller2 ( - .clk(clk), .I_RSTn(1'b1), - .O_psCLK(joystick_clk2), .O_psSEL(joystick_cs2), .O_psTXD(joystick_mosi2), - .I_psRXD(joystick_miso2), - .O_RXD_1(joy_rx2[0]), .O_RXD_2(joy_rx2[1]), - .O_RXD_3(), .O_RXD_4(), .O_RXD_5(), .O_RXD_6() +controller_snes joy2_snes ( + .clk(clk), .resetn(resetn), .buttons(joy2_btns), + .joy_strb(joy2_strb), .joy_clk(joy2_clk), .joy_data(joy2_data) ); +`endif -Autofire af_square (.clk(clk), .resetn(sys_resetn), .btn(~joy_rx[1][7] | usb_btn_y), .out(auto_square)); // B -Autofire af_triangle (.clk(clk), .resetn(sys_resetn), .btn(~joy_rx[1][4] | usb_btn_x), .out(auto_triangle)); // A -Autofire af_square2 (.clk(clk), .resetn(sys_resetn), .btn(~joy_rx2[1][7] | usb_btn_y2), .out(auto_square2)); -Autofire af_triangle2 (.clk(clk), .resetn(sys_resetn), .btn(~joy_rx2[1][4] | usb_btn_x2), .out(auto_triangle2)); +`ifdef CONTROLLER_DS2 +controller_ds2 joy1_ds2 ( + .clk(clk), .snes_buttons(joy1_btns), + .ds_clk(ds_clk), .ds_miso(ds_miso), .ds_mosi(ds_mosi), .ds_cs(ds_cs) +); +controller_ds2 joy2_ds2 ( + .clk(clk), .snes_buttons(joy2_btns), + .ds_clk(ds_clk2), .ds_miso(ds_miso2), .ds_mosi(ds_mosi2), .ds_cs(ds_cs2) +); +`endif -assign nes_btn = {~joy_rx[0][5], ~joy_rx[0][7], ~joy_rx[0][6], ~joy_rx[0][4], - ~joy_rx[0][3], ~joy_rx[0][0], ~joy_rx[1][6] | auto_square, ~joy_rx[1][5] | auto_triangle}; - // | usb_btn - // | NES_gamepad_button_state; -assign nes_btn2 = {~joy_rx2[0][5], ~joy_rx2[0][7], ~joy_rx2[0][6], ~joy_rx2[0][4], - ~joy_rx2[0][3], ~joy_rx2[0][0], ~joy_rx2[1][6] | auto_square2, ~joy_rx2[1][5] | auto_triangle2}; - // | usb_btn2 - // | NES_gamepad_button_state2; +// Autofire for NES A (right) and B (left) buttons +Autofire af_a (.clk(clk), .resetn(sys_resetn), .btn(joy1_btns[8]), .out(auto_a)); +Autofire af_b (.clk(clk), .resetn(sys_resetn), .btn(joy1_btns[9]), .out(auto_b)); +Autofire af_a2 (.clk(clk), .resetn(sys_resetn), .btn(joy2_btns[8]), .out(auto_a2)); +Autofire af_b2 (.clk(clk), .resetn(sys_resetn), .btn(joy2_btns[9]), .out(auto_b2)); // Joypad handling always @(posedge clk) begin if (joypad_strobe) begin - joypad_bits <= nes_btn; - joypad_bits2 <= nes_btn2; + joypad_bits <= {joy1_btns[7:2], joy1_btns[1] | auto_b, joy1_btns[0] | auto_a};; + joypad_bits2 <= {joy2_btns[7:2], joy2_btns[1] | auto_b2, joy2_btns[0] | auto_a2}; end if (!joypad_clock[0] && last_joypad_clock[0]) joypad_bits <= {1'b1, joypad_bits[7:1]}; @@ -527,35 +521,33 @@ assign joypad1_data[0] = joypad_bits[0]; assign joypad2_data[0] = joypad_bits2[0]; // usb_btn: (R L D U START SELECT B A) -wire [1:0] usb_type, usb_type2; -wire usb_report, usb_report2; -usb_hid_host usb_controller ( - .usbclk(clk_usb), .usbrst_n(sys_resetn), - .usb_dm(usbdm), .usb_dp(usbdp), .typ(usb_type), .report(usb_report), - .game_l(usb_btn[6]), .game_r(usb_btn[7]), .game_u(usb_btn[4]), .game_d(usb_btn[5]), - .game_a(usb_btn[0]), .game_b(usb_btn[1]), .game_x(usb_btn_x), .game_y(usb_btn_y), - .game_sel(usb_btn[2]), .game_sta(usb_btn[3]), - // ignore keyboard and mouse input - .key_modifiers(), .key1(), .key2(), .key3(), .key4(), - .mouse_btn(), .mouse_dx(), .mouse_dy(), - .dbg_hid_report() -); - -`ifndef PRIMER -usb_hid_host usb_controller2 ( - .usbclk(clk_usb), .usbrst_n(sys_resetn), - .usb_dm(usbdm2), .usb_dp(usbdp2), .typ(usb_type2), .report(usb_report2), - .game_l(usb_btn2[6]), .game_r(usb_btn2[7]), .game_u(usb_btn2[4]), .game_d(usb_btn2[5]), - .game_a(usb_btn2[0]), .game_b(usb_btn2[1]), .game_x(usb_btn_x2), .game_y(usb_btn_y2), - .game_sel(usb_btn2[2]), .game_sta(usb_btn2[3]), - // ignore keyboard and mouse input - .key_modifiers(), .key1(), .key2(), .key3(), .key4(), - .mouse_btn(), .mouse_dx(), .mouse_dy(), - .dbg_hid_report() -); -`endif - -// nand2mario: joypad interface changed. we'll add NESGamepad back later +// wire [1:0] usb_type, usb_type2; +// wire usb_report, usb_report2; +// usb_hid_host usb_controller ( +// .usbclk(clk_usb), .usbrst_n(sys_resetn), +// .usb_dm(usbdm), .usb_dp(usbdp), .typ(usb_type), .report(usb_report), +// .game_l(usb_btn[6]), .game_r(usb_btn[7]), .game_u(usb_btn[4]), .game_d(usb_btn[5]), +// .game_a(usb_btn[0]), .game_b(usb_btn[1]), .game_x(usb_btn_x), .game_y(usb_btn_y), +// .game_sel(usb_btn[2]), .game_sta(usb_btn[3]), +// // ignore keyboard and mouse input +// .key_modifiers(), .key1(), .key2(), .key3(), .key4(), +// .mouse_btn(), .mouse_dx(), .mouse_dy(), +// .dbg_hid_report() +// ); + +// `ifndef PRIMER +// usb_hid_host usb_controller2 ( +// .usbclk(clk_usb), .usbrst_n(sys_resetn), +// .usb_dm(usbdm2), .usb_dp(usbdp2), .typ(usb_type2), .report(usb_report2), +// .game_l(usb_btn2[6]), .game_r(usb_btn2[7]), .game_u(usb_btn2[4]), .game_d(usb_btn2[5]), +// .game_a(usb_btn2[0]), .game_b(usb_btn2[1]), .game_x(usb_btn_x2), .game_y(usb_btn_y2), +// .game_sel(usb_btn2[2]), .game_sta(usb_btn2[3]), +// // ignore keyboard and mouse input +// .key_modifiers(), .key1(), .key2(), .key3(), .key4(), +// .mouse_btn(), .mouse_dx(), .mouse_dy(), +// .dbg_hid_report() +// ); +// `endif `endif diff --git a/src/tang_primer_25k/config.sv b/src/primer25k/config.v similarity index 93% rename from src/tang_primer_25k/config.sv rename to src/primer25k/config.v index bb83057..0a66601 100644 --- a/src/tang_primer_25k/config.sv +++ b/src/primer25k/config.v @@ -2,6 +2,8 @@ `define GW_IDE `define PRIMER +`define CONTROLLER_DS2 + package configPackage; // Tang SDRAM v1.2: 2B * 8K * 512 * 4 = 32MB diff --git a/src/primer25k/config_snescontroller.v b/src/primer25k/config_snescontroller.v new file mode 100644 index 0000000..fbf8e07 --- /dev/null +++ b/src/primer25k/config_snescontroller.v @@ -0,0 +1,15 @@ +`define RES_720P +`define GW_IDE +`define PRIMER + +`define CONTROLLER_SNES + +package configPackage; + + // Tang SDRAM v1.2: 2B * 8K * 512 * 4 = 32MB + localparam SDRAM_DATA_WIDTH = 16; // 2 bytes per word + localparam SDRAM_ROW_WIDTH = 13; // 8K rows + localparam SDRAM_COL_WIDTH = 9; // 512 cols + localparam SDRAM_BANK_WIDTH = 2; // 4 banks + +endpackage \ No newline at end of file diff --git a/src/tang_primer_25k/gowin_pll_27.ipc b/src/primer25k/gowin_pll_27.ipc similarity index 100% rename from src/tang_primer_25k/gowin_pll_27.ipc rename to src/primer25k/gowin_pll_27.ipc diff --git a/src/tang_primer_25k/gowin_pll_27.mod b/src/primer25k/gowin_pll_27.mod similarity index 100% rename from src/tang_primer_25k/gowin_pll_27.mod rename to src/primer25k/gowin_pll_27.mod diff --git a/src/tang_primer_25k/gowin_pll_27.v b/src/primer25k/gowin_pll_27.v similarity index 100% rename from src/tang_primer_25k/gowin_pll_27.v rename to src/primer25k/gowin_pll_27.v diff --git a/src/tang_primer_25k/gowin_pll_hdmi.v b/src/primer25k/gowin_pll_hdmi.v similarity index 100% rename from src/tang_primer_25k/gowin_pll_hdmi.v rename to src/primer25k/gowin_pll_hdmi.v diff --git a/src/tang_primer_25k/gowin_pll_nes.ipc b/src/primer25k/gowin_pll_nes.ipc similarity index 100% rename from src/tang_primer_25k/gowin_pll_nes.ipc rename to src/primer25k/gowin_pll_nes.ipc diff --git a/src/tang_primer_25k/gowin_pll_nes.mod b/src/primer25k/gowin_pll_nes.mod similarity index 100% rename from src/tang_primer_25k/gowin_pll_nes.mod rename to src/primer25k/gowin_pll_nes.mod diff --git a/src/tang_primer_25k/gowin_pll_nes.v b/src/primer25k/gowin_pll_nes.v similarity index 100% rename from src/tang_primer_25k/gowin_pll_nes.v rename to src/primer25k/gowin_pll_nes.v diff --git a/src/tang_primer_25k/gowin_pll_usb.v b/src/primer25k/gowin_pll_usb.v similarity index 100% rename from src/tang_primer_25k/gowin_pll_usb.v rename to src/primer25k/gowin_pll_usb.v diff --git a/src/tang_primer_25k/nestang.cst b/src/primer25k/nestang.cst similarity index 86% rename from src/tang_primer_25k/nestang.cst rename to src/primer25k/nestang.cst index 8ce0f7f..c0f061b 100644 --- a/src/tang_primer_25k/nestang.cst +++ b/src/primer25k/nestang.cst @@ -81,10 +81,10 @@ IO_LOC "flash_spi_clk" E7; IO_PORT "flash_spi_clk" PULL_MODE=NONE IO_TYPE=LVCMOS33; // One on-board USB port - IO_LOC "usbdp" L6; - IO_PORT "usbdp" PULL_MODE=DOWN IO_TYPE=LVCMOS33; - IO_LOC "usbdm" K6; - IO_PORT "usbdm" PULL_MODE=DOWN IO_TYPE=LVCMOS33; +// IO_LOC "usbdp" L6; +// IO_PORT "usbdp" PULL_MODE=DOWN IO_TYPE=LVCMOS33; +// IO_LOC "usbdm" K6; +// IO_PORT "usbdm" PULL_MODE=DOWN IO_TYPE=LVCMOS33; // IO_LOC "usbdp2" 56; // IO_PORT "usbdp2" PULL_MODE=DOWN IO_TYPE=LVCMOS33; // IO_LOC "usbdm2" 54; @@ -172,29 +172,30 @@ IO_PORT "O_sdram_cas_n" IO_TYPE=LVCMOS33; IO_LOC "O_sdram_cs_n" K9; IO_PORT "O_sdram_cs_n" IO_TYPE=LVCMOS33; +// 2 LEDs for debug +IO_LOC "led[1]" E8; // Ready +IO_PORT "led[1]" IO_TYPE=LVCMOS33 PULL_MODE=UP; +IO_LOC "led[0]" D7; // Done +IO_PORT "led[0]" IO_TYPE=LVCMOS33 PULL_MODE=UP; + +//------------------------------------------------------------------------------------ // Joystick 1 on pmod -IO_LOC "joystick_clk" L5; -IO_PORT "joystick_clk" PULL_MODE=NONE IO_TYPE=LVCMOS33; -IO_LOC "joystick_miso" K11; -IO_PORT "joystick_miso" PULL_MODE=UP IO_TYPE=LVCMOS33; -IO_LOC "joystick_mosi" E11; -IO_PORT "joystick_mosi" PULL_MODE=NONE IO_TYPE=LVCMOS33; -IO_LOC "joystick_cs" A11; -IO_PORT "joystick_cs" PULL_MODE=NONE IO_TYPE=LVCMOS33; +IO_LOC "ds_clk" L5; +IO_PORT "ds_clk" PULL_MODE=NONE IO_TYPE=LVCMOS33; +IO_LOC "ds_miso" K11; +IO_PORT "ds_miso" PULL_MODE=UP IO_TYPE=LVCMOS33; +IO_LOC "ds_mosi" E11; +IO_PORT "ds_mosi" PULL_MODE=NONE IO_TYPE=LVCMOS33; +IO_LOC "ds_cs" A11; +IO_PORT "ds_cs" PULL_MODE=NONE IO_TYPE=LVCMOS33; // Joystick 2 on pmod -IO_LOC "joystick_clk2" K5; -IO_PORT "joystick_clk2" PULL_MODE=NONE IO_TYPE=LVCMOS33; -IO_LOC "joystick_miso2" L11; -IO_PORT "joystick_miso2" PULL_MODE=UP IO_TYPE=LVCMOS33; -IO_LOC "joystick_mosi2" E10; -IO_PORT "joystick_mosi2" PULL_MODE=NONE IO_TYPE=LVCMOS33; -IO_LOC "joystick_cs2" A10; -IO_PORT "joystick_cs2" PULL_MODE=NONE IO_TYPE=LVCMOS33; - -// 2 LEDs for debug - IO_LOC "led[1]" E8; // Ready - IO_PORT "led[1]" IO_TYPE=LVCMOS33 PULL_MODE=UP; - IO_LOC "led[0]" D7; // Done - IO_PORT "led[0]" IO_TYPE=LVCMOS33 PULL_MODE=UP; +IO_LOC "ds_clk2" K5; +IO_PORT "ds_clk2" PULL_MODE=NONE IO_TYPE=LVCMOS33; +IO_LOC "ds_miso2" L11; +IO_PORT "ds_miso2" PULL_MODE=UP IO_TYPE=LVCMOS33; +IO_LOC "ds_mosi2" E10; +IO_PORT "ds_mosi2" PULL_MODE=NONE IO_TYPE=LVCMOS33; +IO_LOC "ds_cs2" A10; +IO_PORT "ds_cs2" PULL_MODE=NONE IO_TYPE=LVCMOS33; diff --git a/src/tang_primer_25k/nestang.sdc b/src/primer25k/nestang.sdc similarity index 100% rename from src/tang_primer_25k/nestang.sdc rename to src/primer25k/nestang.sdc diff --git a/src/primer25k/nestang_snescontroller.cst b/src/primer25k/nestang_snescontroller.cst new file mode 100644 index 0000000..e8a232a --- /dev/null +++ b/src/primer25k/nestang_snescontroller.cst @@ -0,0 +1,197 @@ +IO_LOC "sys_clk" E2; // 50Mhz +IO_PORT "sys_clk" IO_TYPE=LVCMOS33 PULL_MODE=NONE DRIVE=OFF BANK_VCCIO=3.3; + +IO_LOC "s1" H11; +IO_PORT "s1" IO_TYPE=LVCMOS33 PULL_MODE=DOWN DRIVE=OFF BANK_VCCIO=3.3; + +IO_LOC "reset2" H10; // S2 +IO_PORT "reset2" IO_TYPE=LVCMOS33 PULL_MODE=DOWN DRIVE=OFF BANK_VCCIO=3.3; + +// HDMI (USB-A side PMOD) +//IO_LOC "tmds_clk_p" H5,J5; +//IO_PORT "tmds_clk_p" IO_TYPE=LVCMOS33D PULL_MODE=NONE DRIVE=8 BANK_VCCIO=3.3; +//IO_LOC "tmds_d_p[0]" H8,H7; +//IO_PORT "tmds_d_p[0]" IO_TYPE=LVCMOS33D PULL_MODE=NONE DRIVE=8 BANK_VCCIO=3.3; +//IO_LOC "tmds_d_p[1]" G7,G8; +//IO_PORT "tmds_d_p[1]" IO_TYPE=LVCMOS33D PULL_MODE=NONE DRIVE=8 BANK_VCCIO=3.3; +//IO_LOC "tmds_d_p[2]" F5,G5; +//IO_PORT "tmds_d_p[2]" IO_TYPE=LVCMOS33D PULL_MODE=NONE DRIVE=8 BANK_VCCIO=3.3; +IO_LOC "tmds_clk_p" H5; +IO_PORT "tmds_clk_p" PULL_MODE=NONE IO_TYPE=LVCMOS33D; +IO_LOC "tmds_clk_n" J5; +IO_PORT "tmds_clk_n" PULL_MODE=NONE IO_TYPE=LVCMOS33D; +IO_LOC "tmds_d_p[0]" H8; +IO_PORT "tmds_d_p[0]" PULL_MODE=NONE IO_TYPE=LVCMOS33D; +IO_LOC "tmds_d_n[0]" H7; +IO_PORT "tmds_d_n[0]" PULL_MODE=NONE IO_TYPE=LVCMOS33D; +IO_LOC "tmds_d_p[1]" G7; +IO_PORT "tmds_d_p[1]" PULL_MODE=NONE IO_TYPE=LVCMOS33D; +IO_LOC "tmds_d_n[1]" G8; +IO_PORT "tmds_d_n[1]" PULL_MODE=NONE IO_TYPE=LVCMOS33D; +IO_LOC "tmds_d_p[2]" F5; +IO_PORT "tmds_d_p[2]" PULL_MODE=NONE IO_TYPE=LVCMOS33D; +IO_LOC "tmds_d_n[2]" G5; +IO_PORT "tmds_d_n[2]" PULL_MODE=NONE IO_TYPE=LVCMOS33D; + +// SDCard +IO_LOC "sd_clk" C11; +IO_PORT "sd_clk" PULL_MODE=NONE IO_TYPE=LVCMOS33; +IO_LOC "sd_cmd" D11; // MOSI +IO_PORT "sd_cmd" PULL_MODE=NONE IO_TYPE=LVCMOS33; +IO_LOC "sd_dat0" B11; // MISO or SD card DO, needs pull-up +IO_PORT "sd_dat0" PULL_MODE=UP IO_TYPE=LVCMOS33; +IO_LOC "sd_dat1" G10; // 1 +IO_PORT "sd_dat1" PULL_MODE=NONE IO_TYPE=LVCMOS33; +IO_LOC "sd_dat2" D10; // 1 +IO_PORT "sd_dat2" PULL_MODE=NONE IO_TYPE=LVCMOS33; +IO_LOC "sd_dat3" G11; // 1 +IO_PORT "sd_dat3" PULL_MODE=NONE IO_TYPE=LVCMOS33; +// old MUSELab SDCARD 1.0 +// IO_LOC "sd_clk" D10; +// IO_PORT "sd_clk" PULL_MODE=NONE IO_TYPE=LVCMOS33; +// IO_LOC "sd_cmd" D11; // MOSI +// IO_PORT "sd_cmd" PULL_MODE=NONE IO_TYPE=LVCMOS33; +// IO_LOC "sd_dat0" B11; // MISO or SD card DO, needs pull-up +// IO_PORT "sd_dat0" PULL_MODE=UP IO_TYPE=LVCMOS33; +// IO_LOC "sd_dat1" B10; // 1 +// IO_PORT "sd_dat1" PULL_MODE=NONE IO_TYPE=LVCMOS33; +// IO_LOC "sd_dat2" G11; // 1 +// IO_PORT "sd_dat2" PULL_MODE=NONE IO_TYPE=LVCMOS33; +// IO_LOC "sd_dat3" G10; // 1 +// IO_PORT "sd_dat3" PULL_MODE=NONE IO_TYPE=LVCMOS33; + +// UART through USB-C port +IO_LOC "UART_RXD" B3; // the primer25k example is reversed +IO_LOC "UART_TXD" C3; +IO_PORT "UART_RXD" IO_TYPE=LVCMOS33; +IO_PORT "UART_TXD" IO_TYPE=LVCMOS33; + +// NOR Flash W25Q64 (MSPI pins) +IO_LOC "flash_spi_cs_n" E6; +IO_PORT "flash_spi_cs_n" PULL_MODE=NONE IO_TYPE=LVCMOS33; +IO_LOC "flash_spi_wp_n" D5; +IO_PORT "flash_spi_wp_n" PULL_MODE=NONE IO_TYPE=LVCMOS33; +IO_LOC "flash_spi_hold_n" E4; +IO_PORT "flash_spi_hold_n" PULL_MODE=NONE IO_TYPE=LVCMOS33; +IO_LOC "flash_spi_miso" E5; +IO_PORT "flash_spi_miso" PULL_MODE=NONE IO_TYPE=LVCMOS33; +IO_LOC "flash_spi_mosi" D6; +IO_PORT "flash_spi_mosi" PULL_MODE=NONE IO_TYPE=LVCMOS33; +IO_LOC "flash_spi_clk" E7; +IO_PORT "flash_spi_clk" PULL_MODE=NONE IO_TYPE=LVCMOS33; + +// One on-board USB port +// IO_LOC "usbdp" L6; +// IO_PORT "usbdp" PULL_MODE=DOWN IO_TYPE=LVCMOS33; +// IO_LOC "usbdm" K6; +// IO_PORT "usbdm" PULL_MODE=DOWN IO_TYPE=LVCMOS33; +// IO_LOC "usbdp2" 56; +// IO_PORT "usbdp2" PULL_MODE=DOWN IO_TYPE=LVCMOS33; +// IO_LOC "usbdm2" 54; +// IO_PORT "usbdm2" PULL_MODE=DOWN IO_TYPE=LVCMOS33; + +// Tang SDRAM v1.2 connected through 40-pin port +IO_LOC "IO_sdram_dq[0]" K2; +IO_PORT "IO_sdram_dq[0]" IO_TYPE=LVCMOS33; +IO_LOC "IO_sdram_dq[1]" K1; +IO_PORT "IO_sdram_dq[1]" IO_TYPE=LVCMOS33; +IO_LOC "IO_sdram_dq[2]" L1; +IO_PORT "IO_sdram_dq[2]" IO_TYPE=LVCMOS33; +IO_LOC "IO_sdram_dq[3]" L2; +IO_PORT "IO_sdram_dq[3]" IO_TYPE=LVCMOS33; +IO_LOC "IO_sdram_dq[4]" K4; +IO_PORT "IO_sdram_dq[4]" IO_TYPE=LVCMOS33; +IO_LOC "IO_sdram_dq[5]" J4; +IO_PORT "IO_sdram_dq[5]" IO_TYPE=LVCMOS33; +IO_LOC "IO_sdram_dq[6]" G1; +IO_PORT "IO_sdram_dq[6]" IO_TYPE=LVCMOS33; +IO_LOC "IO_sdram_dq[7]" G2; +IO_PORT "IO_sdram_dq[7]" IO_TYPE=LVCMOS33; +IO_LOC "IO_sdram_dq[8]" E1; +IO_PORT "IO_sdram_dq[8]" IO_TYPE=LVCMOS33; +IO_LOC "IO_sdram_dq[9]" A1; +IO_PORT "IO_sdram_dq[9]" IO_TYPE=LVCMOS33; +IO_LOC "IO_sdram_dq[10]" F2; +IO_PORT "IO_sdram_dq[10]" IO_TYPE=LVCMOS33; +IO_LOC "IO_sdram_dq[11]" F1; +IO_PORT "IO_sdram_dq[11]" IO_TYPE=LVCMOS33; +IO_LOC "IO_sdram_dq[12]" B2; +IO_PORT "IO_sdram_dq[12]" IO_TYPE=LVCMOS33; +IO_LOC "IO_sdram_dq[13]" C2; +IO_PORT "IO_sdram_dq[13]" IO_TYPE=LVCMOS33; +IO_LOC "IO_sdram_dq[14]" L4; +IO_PORT "IO_sdram_dq[14]" IO_TYPE=LVCMOS33; +IO_LOC "IO_sdram_dq[15]" L3; +IO_PORT "IO_sdram_dq[15]" IO_TYPE=LVCMOS33; + +IO_LOC "O_sdram_addr[0]" F6; +IO_PORT "O_sdram_addr[0]" IO_TYPE=LVCMOS33; +IO_LOC "O_sdram_addr[1]" F7; +IO_PORT "O_sdram_addr[1]" IO_TYPE=LVCMOS33; +IO_LOC "O_sdram_addr[2]" J10; +IO_PORT "O_sdram_addr[2]" IO_TYPE=LVCMOS33; +IO_LOC "O_sdram_addr[3]" J11; +IO_PORT "O_sdram_addr[3]" IO_TYPE=LVCMOS33; +IO_LOC "O_sdram_addr[4]" K7; +IO_PORT "O_sdram_addr[4]" IO_TYPE=LVCMOS33; +IO_LOC "O_sdram_addr[5]" H2; +IO_PORT "O_sdram_addr[5]" IO_TYPE=LVCMOS33; +IO_LOC "O_sdram_addr[6]" H1; +IO_PORT "O_sdram_addr[6]" IO_TYPE=LVCMOS33; +IO_LOC "O_sdram_addr[7]" H4; +IO_PORT "O_sdram_addr[7]" IO_TYPE=LVCMOS33; +IO_LOC "O_sdram_addr[8]" G4; +IO_PORT "O_sdram_addr[8]" IO_TYPE=LVCMOS33; +IO_LOC "O_sdram_addr[9]" J2; +IO_PORT "O_sdram_addr[9]" IO_TYPE=LVCMOS33; +IO_LOC "O_sdram_addr[10]" J8; +IO_PORT "O_sdram_addr[10]" IO_TYPE=LVCMOS33; +IO_LOC "O_sdram_addr[11]" J1; +IO_PORT "O_sdram_addr[11]" IO_TYPE=LVCMOS33; +IO_LOC "O_sdram_addr[12]" D1; +IO_PORT "O_sdram_addr[12]" IO_TYPE=LVCMOS33; + +IO_LOC "O_sdram_ba[0]" L9; +IO_PORT "O_sdram_ba[0]" IO_TYPE=LVCMOS33; +IO_LOC "O_sdram_ba[1]" K8; +IO_PORT "O_sdram_ba[1]" IO_TYPE=LVCMOS33; + +IO_LOC "O_sdram_dqm[0]" L8; +IO_PORT "O_sdram_dqm[0]" IO_TYPE=LVCMOS33; +IO_LOC "O_sdram_dqm[1]" L7; +IO_PORT "O_sdram_dqm[1]" IO_TYPE=LVCMOS33; + +IO_LOC "O_sdram_clk" E3; +IO_PORT "O_sdram_clk" IO_TYPE=LVCMOS33; +IO_LOC "O_sdram_wen_n" J7; +IO_PORT "O_sdram_wen_n" IO_TYPE=LVCMOS33; +IO_LOC "O_sdram_ras_n" L10; +IO_PORT "O_sdram_ras_n" IO_TYPE=LVCMOS33; +IO_LOC "O_sdram_cas_n" K10; +IO_PORT "O_sdram_cas_n" IO_TYPE=LVCMOS33; +IO_LOC "O_sdram_cs_n" K9; +IO_PORT "O_sdram_cs_n" IO_TYPE=LVCMOS33; + +// 2 LEDs for debug +IO_LOC "led[1]" E8; // Ready +IO_PORT "led[1]" IO_TYPE=LVCMOS33 PULL_MODE=UP; +IO_LOC "led[0]" D7; // Done +IO_PORT "led[0]" IO_TYPE=LVCMOS33 PULL_MODE=UP; + +//------------------------------------------------------------------------------------ +// SNES controller 1 +IO_LOC "joy1_strb" A11; +IO_PORT "joy1_strb" PULL_MODE=NONE IO_TYPE=LVCMOS33; +IO_LOC "joy1_clk" K11; +IO_PORT "joy1_clk" PULL_MODE=NONE IO_TYPE=LVCMOS33; +IO_LOC "joy1_data" L5; +IO_PORT "joy1_data" PULL_MODE=UP IO_TYPE=LVCMOS33; + +// SNES controller 2 +IO_LOC "joy2_strb" A10; +IO_PORT "joy2_strb" PULL_MODE=NONE IO_TYPE=LVCMOS33; +IO_LOC "joy2_clk" L11; +IO_PORT "joy2_clk" PULL_MODE=NONE IO_TYPE=LVCMOS33; +IO_LOC "joy2_data" K5; +IO_PORT "joy2_data" PULL_MODE=UP IO_TYPE=LVCMOS33; +