From 5fe242df64811a955aab476bd33e83221e3b0730 Mon Sep 17 00:00:00 2001 From: Polprzewodnikowy Date: Fri, 20 Aug 2021 19:51:55 +0200 Subject: [PATCH] update --- fw/SummerCart64.qsf | 120 +- fw/SummerCart64.sdc | 60 +- fw/btldr/btldr.h | 4 +- fw/btldr/btldr.sv | 54 + fw/btldr/btldr_template.sv | 7 +- fw/rtl/SummerCart64.sv | 137 +- fw/rtl/cpu/cpu_bus.sv | 19 +- fw/rtl/cpu/cpu_gpio.sv | 39 +- fw/rtl/cpu/cpu_i2c.sv | 17 +- fw/rtl/cpu/cpu_ram.sv | 51 +- fw/rtl/cpu/cpu_soc.sv | 52 +- fw/rtl/cpu/cpu_uart.sv | 136 +- fw/rtl/cpu/cpu_usb.sv | 14 +- fw/rtl/cpu/cpu_wrapper.sv | 25 +- fw/rtl/intel/gpio/intel_gpio_ddro.qip | 77 ++ fw/rtl/intel/gpio/intel_gpio_ddro.v | 123 ++ .../gpio/intel_gpio_ddro/altera_gpio_lite.sv | 1200 +++++++++++++++++ fw/rtl/memory/memory_flash.sv | 55 + fw/rtl/memory/memory_sdram.sv | 66 + fw/rtl/memory/sdram.vhd | 445 ++++++ fw/rtl/n64/n64_bus.sv | 56 + fw/rtl/n64/n64_pi.sv | 89 +- fw/rtl/n64/n64_soc.sv | 57 + fw/rtl/system/config.sv | 34 + fw/rtl/system/sc64.sv | 24 + fw/stp.stp | 976 ++++++-------- sw/bootloader/Makefile | 2 +- 27 files changed, 2998 insertions(+), 941 deletions(-) create mode 100644 fw/btldr/btldr.sv create mode 100644 fw/rtl/intel/gpio/intel_gpio_ddro.qip create mode 100644 fw/rtl/intel/gpio/intel_gpio_ddro.v create mode 100644 fw/rtl/intel/gpio/intel_gpio_ddro/altera_gpio_lite.sv create mode 100644 fw/rtl/memory/memory_flash.sv create mode 100644 fw/rtl/memory/sdram.vhd create mode 100644 fw/rtl/n64/n64_bus.sv create mode 100644 fw/rtl/n64/n64_soc.sv create mode 100644 fw/rtl/system/config.sv create mode 100644 fw/rtl/system/sc64.sv diff --git a/fw/SummerCart64.qsf b/fw/SummerCart64.qsf index 3b7cea8..1c34dc2 100644 --- a/fw/SummerCart64.qsf +++ b/fw/SummerCart64.qsf @@ -19,7 +19,7 @@ # # Quartus Prime # Version 20.1.1 Build 720 11/11/2020 SJ Lite Edition -# Date created = 00:18:46 August 16, 2021 +# Date created = 16:40:13 August 18, 2021 # # -------------------------------------------------------------------------- # # @@ -46,6 +46,32 @@ set_global_assignment -name LAST_QUARTUS_VERSION "20.1.1 Lite Edition" set_global_assignment -name PROJECT_OUTPUT_DIRECTORY output_files set_global_assignment -name NUM_PARALLEL_PROCESSORS ALL set_global_assignment -name FLOW_ENABLE_POWER_ANALYZER ON +set_global_assignment -name QSYS_FILE rtl/intel/flash/intel_flash.qsys +set_global_assignment -name QSYS_FILE rtl/intel/snp/intel_snp.qsys +set_global_assignment -name QIP_FILE rtl/intel/fifo/fifo8.qip +set_global_assignment -name QIP_FILE rtl/intel/pll/intel_pll.qip +set_global_assignment -name SDC_FILE SummerCart64.sdc +set_global_assignment -name SIGNALTAP_FILE stp.stp +set_global_assignment -name SYSTEMVERILOG_FILE btldr/btldr.sv +set_global_assignment -name SYSTEMVERILOG_FILE picorv32/picorv32.v +set_global_assignment -name SYSTEMVERILOG_FILE rtl/cpu/cpu_bus.sv +set_global_assignment -name SYSTEMVERILOG_FILE rtl/cpu/cpu_gpio.sv +set_global_assignment -name SYSTEMVERILOG_FILE rtl/cpu/cpu_i2c.sv +set_global_assignment -name SYSTEMVERILOG_FILE rtl/cpu/cpu_ram.sv +set_global_assignment -name SYSTEMVERILOG_FILE rtl/cpu/cpu_soc.sv +set_global_assignment -name SYSTEMVERILOG_FILE rtl/cpu/cpu_uart.sv +set_global_assignment -name SYSTEMVERILOG_FILE rtl/cpu/cpu_usb.sv +set_global_assignment -name SYSTEMVERILOG_FILE rtl/cpu/cpu_wrapper.sv +set_global_assignment -name SYSTEMVERILOG_FILE rtl/memory/memory_flash.sv +set_global_assignment -name SYSTEMVERILOG_FILE rtl/memory/memory_sdram.sv +set_global_assignment -name SYSTEMVERILOG_FILE rtl/n64/n64_bus.sv +set_global_assignment -name SYSTEMVERILOG_FILE rtl/n64/n64_pi.sv +set_global_assignment -name SYSTEMVERILOG_FILE rtl/n64/n64_soc.sv +set_global_assignment -name SYSTEMVERILOG_FILE rtl/SummerCart64.sv +set_global_assignment -name SYSTEMVERILOG_FILE rtl/system/config.sv +set_global_assignment -name SYSTEMVERILOG_FILE rtl/system/sc64.sv +set_global_assignment -name SYSTEMVERILOG_FILE rtl/system/system.sv +set_global_assignment -name SYSTEMVERILOG_FILE rtl/usb/usb_ft1248.sv # Pin & Location Assignments # ========================== @@ -59,7 +85,7 @@ set_location_assignment PIN_13 -to o_uart_txd set_location_assignment PIN_14 -to i_uart_cts set_location_assignment PIN_15 -to o_uart_rts set_location_assignment PIN_17 -to o_led -set_location_assignment PIN_21 -to io_rtc_scl +set_location_assignment PIN_21 -to o_rtc_scl set_location_assignment PIN_22 -to io_rtc_sda set_location_assignment PIN_24 -to io_n64_si_dq set_location_assignment PIN_25 -to i_n64_nmi @@ -204,48 +230,57 @@ set_global_assignment -name OUTPUT_IO_TIMING_FAR_END_VMEAS "HALF SIGNAL SWING" - # Pin & Location Assignments # ========================== -set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to o_usb_clk -set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to o_usb_cs -set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to io_usb_miosi[0] -set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to io_usb_miosi[1] -set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to io_usb_miosi[2] -set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to io_usb_miosi[3] -set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to io_n64_pi_ad[*] -set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to io_usb_miosi[0] -set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to io_usb_miosi[1] -set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to io_usb_miosi[2] -set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to io_usb_miosi[3] -set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to io_n64_pi_ad[*] -set_instance_assignment -name FAST_INPUT_REGISTER ON -to io_usb_miosi[0] -set_instance_assignment -name FAST_INPUT_REGISTER ON -to io_usb_miosi[1] -set_instance_assignment -name FAST_INPUT_REGISTER ON -to io_usb_miosi[2] -set_instance_assignment -name FAST_INPUT_REGISTER ON -to io_usb_miosi[3] -set_instance_assignment -name FAST_INPUT_REGISTER ON -to i_usb_miso +set_instance_assignment -name FAST_INPUT_REGISTER ON -to io_usb_miosi[*] +set_instance_assignment -name FAST_INPUT_REGISTER ON -to i_uart_rxd +set_instance_assignment -name FAST_INPUT_REGISTER ON -to i_uart_cts +set_instance_assignment -name FAST_INPUT_REGISTER ON -to io_rtc_sda +set_instance_assignment -name FAST_INPUT_REGISTER ON -to io_n64_si_dq +set_instance_assignment -name FAST_INPUT_REGISTER ON -to i_n64_nmi +set_instance_assignment -name FAST_INPUT_REGISTER ON -to i_n64_reset +set_instance_assignment -name FAST_INPUT_REGISTER ON -to i_n64_si_clk set_instance_assignment -name FAST_INPUT_REGISTER ON -to io_n64_pi_ad[*] set_instance_assignment -name FAST_INPUT_REGISTER ON -to i_n64_pi_aleh -set_instance_assignment -name FAST_INPUT_REGISTER ON -to i_n64_pi_alel set_instance_assignment -name FAST_INPUT_REGISTER ON -to i_n64_pi_read set_instance_assignment -name FAST_INPUT_REGISTER ON -to i_n64_pi_write -set_instance_assignment -name FAST_INPUT_REGISTER ON -to i_n64_reset -set_instance_assignment -name FAST_INPUT_REGISTER ON -to i_n64_nmi +set_instance_assignment -name FAST_INPUT_REGISTER ON -to i_n64_pi_alel +set_instance_assignment -name FAST_INPUT_REGISTER ON -to io_sdram_dq[*] +set_instance_assignment -name FAST_INPUT_REGISTER ON -to io_sd_* +set_instance_assignment -name FAST_INPUT_REGISTER ON -to i_usb_pwren +set_instance_assignment -name FAST_INPUT_REGISTER ON -to i_usb_miso +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to o_usb_clk +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to io_usb_miosi[*] +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to o_uart_txd +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to o_uart_rts +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to o_rtc_scl +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to io_rtc_sda +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to io_n64_pi_ad[*] +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to o_sdram_* +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to io_sdram_dq[*] +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to o_sd_clk +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to io_sd_* +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to o_usb_cs +set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to io_usb_miosi[*] +set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to io_n64_pi_ad[*] +set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to io_sdram_dq[*] +set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to io_sd_* +set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to io_rtc_sda # Fitter Assignments # ================== +set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to io_usb_miosi[*] set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to i_n64_nmi -set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to i_n64_pi_aleh -set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to i_n64_pi_alel -set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to i_n64_pi_read -set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to i_n64_pi_write +set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to i_uart_rxd +set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to i_uart_cts +set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to io_n64_si_dq set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to i_n64_reset set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to i_n64_si_clk -set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to io_n64_si_dq +set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to i_n64_pi_aleh +set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to i_n64_pi_read +set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to i_n64_pi_write +set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to i_n64_pi_alel set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to o_n64_irq -set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to io_usb_miosi[0] -set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to io_usb_miosi[1] -set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to io_usb_miosi[2] -set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to io_usb_miosi[3] -set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to i_usb_miso set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to i_usb_pwren +set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to i_usb_miso # start DESIGN_PARTITION(Top) # --------------------------- @@ -261,25 +296,6 @@ set_global_assignment -name PARTITION_COLOR 16764057 -section_id Top # end ENTITY(SummerCart64) # ------------------------ -set_global_assignment -name QSYS_FILE rtl/intel/flash/intel_flash.qsys -set_global_assignment -name VERILOG_FILE picorv32/picorv32.v -set_global_assignment -name QSYS_FILE rtl/intel/snp/intel_snp.qsys -set_global_assignment -name QIP_FILE rtl/intel/fifo/fifo8.qip -set_global_assignment -name QIP_FILE rtl/intel/pll/intel_pll.qip -set_global_assignment -name SDC_FILE SummerCart64.sdc -set_global_assignment -name SIGNALTAP_FILE stp.stp -set_global_assignment -name SYSTEMVERILOG_FILE btldr/btldr.sv -set_global_assignment -name SYSTEMVERILOG_FILE rtl/cpu/cpu_bus.sv -set_global_assignment -name SYSTEMVERILOG_FILE rtl/cpu/cpu_gpio.sv -set_global_assignment -name SYSTEMVERILOG_FILE rtl/cpu/cpu_i2c.sv -set_global_assignment -name SYSTEMVERILOG_FILE rtl/cpu/cpu_ram.sv -set_global_assignment -name SYSTEMVERILOG_FILE rtl/cpu/cpu_soc.sv -set_global_assignment -name SYSTEMVERILOG_FILE rtl/cpu/cpu_uart.sv -set_global_assignment -name SYSTEMVERILOG_FILE rtl/cpu/cpu_usb.sv -set_global_assignment -name SYSTEMVERILOG_FILE rtl/cpu/cpu_wrapper.sv -set_global_assignment -name SYSTEMVERILOG_FILE rtl/SummerCart64.sv -set_global_assignment -name SYSTEMVERILOG_FILE rtl/system/system.sv -set_global_assignment -name SYSTEMVERILOG_FILE rtl/n64/n64_pi.sv -set_global_assignment -name SYSTEMVERILOG_FILE rtl/usb/usb_ft1248.sv +set_global_assignment -name QIP_FILE rtl/intel/gpio/intel_gpio_ddro.qip set_global_assignment -name SLD_FILE db/stp_auto_stripped.stp set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top \ No newline at end of file diff --git a/fw/SummerCart64.sdc b/fw/SummerCart64.sdc index a6d4eba..a118471 100644 --- a/fw/SummerCart64.sdc +++ b/fw/SummerCart64.sdc @@ -6,30 +6,30 @@ derive_pll_clocks -create_base_clocks # set sdram_pll_clk {sys_pll|altpll_component|auto_generated|pll1|clk[1]} # set sd_reg_clk {sd_interface_inst|sd_clk_inst|o_sd_clk|q} -# create_generated_clock -name sdram_clk -source [get_pins $sdram_pll_clk] [get_ports {o_sdram_clk}] +create_generated_clock -name sdram_clk -source [get_pins {system_inst|intel_pll_inst|altpll_component|auto_generated|pll1|clk[1]}] [get_ports {o_sdram_clk}] # create_generated_clock -name sd_reg_clk -source [get_pins {sd_interface_inst|sd_clk_inst|o_sd_clk|clk}] -divide_by 2 [get_pins $sd_reg_clk] # create_generated_clock -name sd_clk -source [get_pins $sd_reg_clk] [get_ports {o_sd_clk}] -# create_generated_clock -name flash_se_neg_reg \ -# -source [get_pins -compatibility_mode {*altera_onchip_flash:*onchip_flash_0|altera_onchip_flash_avmm_data_controller:avmm_data_controller|flash_se_neg_reg|clk}] \ -# -divide_by 2 \ -# [get_pins -compatibility_mode {*altera_onchip_flash:*onchip_flash_0|altera_onchip_flash_avmm_data_controller:avmm_data_controller|flash_se_neg_reg|q}] +create_generated_clock -name flash_se_neg_reg \ + -source [get_pins -compatibility_mode {*altera_onchip_flash:*onchip_flash_0|altera_onchip_flash_avmm_data_controller:avmm_data_controller|flash_se_neg_reg|clk}] \ + -divide_by 2 \ + [get_pins -compatibility_mode {*altera_onchip_flash:*onchip_flash_0|altera_onchip_flash_avmm_data_controller:avmm_data_controller|flash_se_neg_reg|q}] derive_clock_uncertainty # # SDRAM timings -# set sdram_outputs {o_sdram_cs o_sdram_ras o_sdram_cas o_sdram_we o_sdram_a[*] o_sdram_ba[*] io_sdram_dq[*]} -# set sdram_inputs {io_sdram_dq[*]} +set sdram_outputs {o_sdram_cs o_sdram_ras o_sdram_cas o_sdram_we o_sdram_a[*] o_sdram_ba[*] io_sdram_dq[*]} +set sdram_inputs {io_sdram_dq[*]} -# set_output_delay -clock [get_clocks {sdram_clk}] -max 1.5 [get_ports $sdram_outputs] -# set_output_delay -clock [get_clocks {sdram_clk}] -min -0.8 [get_ports $sdram_outputs] +set_output_delay -clock [get_clocks {sdram_clk}] -max 1.5 [get_ports $sdram_outputs] +set_output_delay -clock [get_clocks {sdram_clk}] -min -0.8 [get_ports $sdram_outputs] -# set_input_delay -clock [get_clocks {sdram_clk}] -max 5.4 [get_ports $sdram_inputs] -# set_input_delay -clock [get_clocks {sdram_clk}] -min 2.5 [get_ports $sdram_inputs] +set_input_delay -clock [get_clocks {sdram_clk}] -max 5.4 [get_ports $sdram_inputs] +set_input_delay -clock [get_clocks {sdram_clk}] -min 2.5 [get_ports $sdram_inputs] -# set_multicycle_path -setup -end 2 -from [get_clocks {sdram_clk}] -to [get_clocks $sys_clk] +set_multicycle_path -setup -end 2 -from [get_clocks {sdram_clk}] -to [get_clocks {system_inst|intel_pll_inst|altpll_component|auto_generated|pll1|clk[0]}] # # FTDI timings @@ -52,15 +52,21 @@ derive_clock_uncertainty # set_multicycle_path -hold -end 1 -from [get_clocks {sd_clk}] -to [get_clocks $sys_clk] -# # N64, PI and SI timings +# FT1248 timings -# set_false_path -from [get_ports {i_n64_reset i_n64_nmi}] +set_false_path -to [get_ports {o_usb_clk io_usb_miosi[*] o_usb_cs}] +set_false_path -from [get_ports {io_usb_miosi[*] i_usb_miso}] -# set_false_path -to [get_ports {io_n64_pi_ad[*]}] -# set_false_path -from [get_ports {i_n64_pi_* io_n64_pi_ad[*]}] +# N64, PI and SI timings -# set_false_path -to [get_ports {io_n64_si_dq}] -# set_false_path -from [get_ports {i_n64_si_clk io_n64_si_dq}] +set_false_path -to [get_ports {o_n64_irq}] +set_false_path -from [get_ports {i_n64_reset i_n64_nmi}] + +set_false_path -to [get_ports {io_n64_pi_ad[*]}] +set_false_path -from [get_ports {i_n64_pi_* io_n64_pi_ad[*]}] + +set_false_path -to [get_ports {io_n64_si_dq}] +set_false_path -from [get_ports {i_n64_si_clk io_n64_si_dq}] # LED timings @@ -68,7 +74,19 @@ derive_clock_uncertainty set_false_path -to [get_ports {o_led}] -# # PMOD timings +# UART timings -# set_false_path -to [get_ports {io_pmod[*]}] -# set_false_path -from [get_ports {io_pmod[*]}] +set_false_path -to [get_ports {o_uart_txd o_uart_rts}] +set_false_path -from [get_ports {i_uart_rxd i_uart_cts}] + + +# I2C timings + +set_false_path -to [get_ports {o_rtc_scl io_rtc_sda}] +set_false_path -from [get_ports {io_rtc_sda}] + + +# JTAG timings + +set_false_path -to [get_ports {altera_reserved_tdo}] +set_false_path -from [get_ports {altera_reserved_tdi altera_reserved_tms}] diff --git a/fw/btldr/btldr.h b/fw/btldr/btldr.h index 0d77bde..ced6df6 100644 --- a/fw/btldr/btldr.h +++ b/fw/btldr/btldr.h @@ -9,8 +9,8 @@ typedef volatile uint8_t * io8_t; typedef volatile uint32_t * io32_t; #define RAM (*((io8_t) 0x00000000)) -#define USB_SR (*((io8_t) 0x40000000)) -#define USB_DR (*((io8_t) 0x40000004)) +#define USB_SR (*((io8_t) 0x50000000)) +#define USB_DR (*((io8_t) 0x50000004)) #define USB_SR_RXNE (1 << 0) #define USB_SR_TXE (1 << 1) diff --git a/fw/btldr/btldr.sv b/fw/btldr/btldr.sv new file mode 100644 index 0000000..7a1716d --- /dev/null +++ b/fw/btldr/btldr.sv @@ -0,0 +1,54 @@ +module cpu_bootloader ( + if_system.sys sys, + if_cpu_bus bus +); + + always_ff @(posedge sys.clk) begin + bus.ack <= 1'b0; + if (bus.request) begin + bus.ack <= 1'b1; + end + end + + always_comb begin + bus.rdata = 32'd0; + if (bus.ack) begin + case (bus.address[6:2]) + 0: bus.rdata = 32'h50000737; + 1: bus.rdata = 32'h00074783; + 2: bus.rdata = 32'h0027f793; + 3: bus.rdata = 32'hfe078ce3; + 4: bus.rdata = 32'h03e00793; + 5: bus.rdata = 32'h00f70223; + 6: bus.rdata = 32'h50000637; + 7: bus.rdata = 32'h00000793; + 8: bus.rdata = 32'h00000713; + 9: bus.rdata = 32'h02000593; + 10: bus.rdata = 32'h00064683; + 11: bus.rdata = 32'h0016f693; + 12: bus.rdata = 32'hfe068ce3; + 13: bus.rdata = 32'h00464683; + 14: bus.rdata = 32'h00f696b3; + 15: bus.rdata = 32'h00878793; + 16: bus.rdata = 32'h00d76733; + 17: bus.rdata = 32'hfeb792e3; + 18: bus.rdata = 32'h00000793; + 19: bus.rdata = 32'h500005b7; + 20: bus.rdata = 32'h0005c683; + 21: bus.rdata = 32'h0016f693; + 22: bus.rdata = 32'hfe068ce3; + 23: bus.rdata = 32'h0045c683; + 24: bus.rdata = 32'h00178613; + 25: bus.rdata = 32'h0ff6f693; + 26: bus.rdata = 32'h00d78023; + 27: bus.rdata = 32'h00e61663; + 28: bus.rdata = 32'hf0000097; + 29: bus.rdata = 32'hf90080e7; + 30: bus.rdata = 32'h00060793; + 31: bus.rdata = 32'hfd5ff06f; + default: bus.rdata = 32'd0; + endcase + end + end + +endmodule diff --git a/fw/btldr/btldr_template.sv b/fw/btldr/btldr_template.sv index 9ab26aa..b5fe4b9 100644 --- a/fw/btldr/btldr_template.sv +++ b/fw/btldr/btldr_template.sv @@ -1,7 +1,10 @@ bus.rdata -module cpu_bootloader (if_cpu_bus bus); +module cpu_bootloader ( + if_system.sys sys, + if_cpu_bus bus +); - always_ff @(posedge bus.clk) begin + always_ff @(posedge sys.clk) begin bus.ack <= 1'b0; if (bus.request) begin bus.ack <= 1'b1; diff --git a/fw/rtl/SummerCart64.sv b/fw/rtl/SummerCart64.sv index 74fe7b0..c7f6b00 100644 --- a/fw/rtl/SummerCart64.sv +++ b/fw/rtl/SummerCart64.sv @@ -1,17 +1,6 @@ module SummerCart64 ( input i_clk, - output o_usb_clk, - output o_usb_cs, - input i_usb_miso, - inout [3:0] io_usb_miosi, - input i_usb_pwren, - - input i_uart_rxd, - output o_uart_txd, - input i_uart_cts, - output o_uart_rts, - input i_n64_reset, input i_n64_nmi, output o_n64_irq, @@ -34,13 +23,24 @@ module SummerCart64 ( output [12:0] o_sdram_a, inout [15:0] io_sdram_dq, + output o_rtc_scl, + inout io_rtc_sda, + + output o_usb_clk, + output o_usb_cs, + input i_usb_miso, + inout [3:0] io_usb_miosi, + input i_usb_pwren, + + input i_uart_rxd, + output o_uart_txd, + input i_uart_cts, + output o_uart_rts, + output o_sd_clk, inout io_sd_cmd, inout [3:0] io_sd_dat, - inout io_rtc_scl, - inout io_rtc_sda, - output o_led ); @@ -60,18 +60,44 @@ module SummerCart64 ( .n64_nmi(i_n64_nmi) ); + if_config cfg (); + system system_inst ( .sys(sys) ); + n64_soc n64_soc_inst ( + .sys(sys), + .cfg(cfg), + + .n64_pi_alel(i_n64_pi_alel), + .n64_pi_aleh(i_n64_pi_aleh), + .n64_pi_read(i_n64_pi_read), + .n64_pi_write(i_n64_pi_write), + .n64_pi_ad(io_n64_pi_ad), + + .n64_si_clk(i_n64_si_clk), + .n64_si_dq(io_n64_si_dq), + + .sdram_clk(o_sdram_clk), + .sdram_cs(o_sdram_cs), + .sdram_ras(o_sdram_ras), + .sdram_cas(o_sdram_cas), + .sdram_we(o_sdram_we), + .sdram_ba(o_sdram_ba), + .sdram_a(o_sdram_a), + .sdram_dq(io_sdram_dq) + ); + cpu_soc cpu_soc_inst ( .sys(sys), + .cfg(cfg), .gpio_o(gpio_o), .gpio_i(gpio_i), .gpio_oe(gpio_oe), - .i2c_scl(io_rtc_scl), + .i2c_scl(o_rtc_scl), .i2c_sda(io_rtc_sda), .usb_clk(o_usb_clk), @@ -83,82 +109,11 @@ module SummerCart64 ( .uart_rxd(i_uart_rxd), .uart_txd(o_uart_txd), .uart_cts(i_uart_cts), - .uart_rts(o_uart_rts) + .uart_rts(o_uart_rts), + + .sd_clk(o_sd_clk), + .sd_cmd(io_sd_cmd), + .sd_dat(io_sd_dat) ); - logic n64_request; - logic n64_ack; - logic n64_write; - logic [31:0] n64_address; - logic [15:0] n64_wdata; - logic [15:0] n64_rdata; - - n64_pi n64_pi_inst ( - .sys(sys), - - .n64_pi_alel(i_n64_pi_alel), - .n64_pi_aleh(i_n64_pi_aleh), - .n64_pi_read(i_n64_pi_read), - .n64_pi_write(i_n64_pi_write), - .n64_pi_ad(io_n64_pi_ad), - - .request(n64_request), - .ack(n64_ack), - .write(n64_write), - .address(n64_address), - .wdata(n64_wdata), - .rdata(n64_rdata) - ); - - logic flash_request; - logic [31:0] flash_rdata; - logic flash_busy; - logic flash_ack; - - logic in_address; - logic dummy_ack; - - intel_flash intel_flash_inst ( - .clock(sys.clk), - .reset_n(~sys.reset), - .avmm_data_addr(n64_address[31:2]), - .avmm_data_read((n64_ack && in_address) || flash_request), - .avmm_data_readdata(flash_rdata), - .avmm_data_waitrequest(flash_busy), - .avmm_data_readdatavalid(flash_ack), - .avmm_data_burstcount(2'd1) - ); - - - always_ff @(posedge sys.clk) begin - dummy_ack <= 1'b0; - if (sys.reset) begin - flash_request <= 1'b0; - end else begin - if (!flash_busy) begin - flash_request <= 1'b0; - end - if (n64_request && in_address) begin - flash_request <= 1'b1; - end - - if (!in_address && n64_request) begin - dummy_ack <= 1'b1; - end - end - end - - always_comb begin - in_address = n64_address < 32'h10008000; - n64_rdata = n64_address[1] ? {flash_rdata[23:16], flash_rdata[31:24]} : {flash_rdata[7:0], flash_rdata[15:8]}; - if (!in_address) n64_rdata = 32'd0; - - n64_ack = 1'b0; - if (in_address) begin - n64_ack = flash_ack; - end else begin - n64_ack = dummy_ack; - end - end - endmodule diff --git a/fw/rtl/cpu/cpu_bus.sv b/fw/rtl/cpu/cpu_bus.sv index c2901df..13579af 100644 --- a/fw/rtl/cpu/cpu_bus.sv +++ b/fw/rtl/cpu/cpu_bus.sv @@ -1,9 +1,6 @@ -interface if_cpu_bus #( - parameter NUM_DEVICES = 1 -) ( - input clk, - input reset -); +interface if_cpu_bus (); + + localparam [3:0] NUM_DEVICES = sc64::__ID_CPU_END; logic request; logic ack; @@ -26,8 +23,6 @@ interface if_cpu_bus #( end modport cpu ( - input clk, - input reset, output request, input ack, output wmask, @@ -39,11 +34,13 @@ interface if_cpu_bus #( genvar n; generate for (n = 0; n < NUM_DEVICES; n++) begin : at - wire device_request = request && address[31:28] == n[3:0]; + logic device_request; + + always_comb begin + device_request = request && address[31:28] == n[3:0]; + end modport device ( - input .clk(clk), - input .reset(reset), input .request(device_request), output .ack(device_ack[n]), input .wmask(wmask), diff --git a/fw/rtl/cpu/cpu_gpio.sv b/fw/rtl/cpu/cpu_gpio.sv index 86e90e9..4877713 100644 --- a/fw/rtl/cpu/cpu_gpio.sv +++ b/fw/rtl/cpu/cpu_gpio.sv @@ -1,33 +1,36 @@ module cpu_gpio ( + if_system.sys sys, if_cpu_bus bus, input [7:0] gpio_i, - output reg [7:0] gpio_o, - output reg [7:0] gpio_oe + output [7:0] gpio_o, + output [7:0] gpio_oe ); - reg [7:0] gpio_i_ff1, gpio_i_ff2; - reg [7:0] gpio_o_value; - reg [7:0] gpio_oe_value; - - always_comb begin - bus.rdata = 32'd0; - if (bus.ack) begin - bus.rdata = {8'd0, gpio_oe_value, gpio_i_ff2, gpio_o_value}; - end - end - - always_ff @(posedge bus.clk) begin - {gpio_i_ff2, gpio_i_ff1} <= {gpio_i_ff1, gpio_i}; - gpio_o <= gpio_o_value; - gpio_oe <= gpio_oe_value; + logic [1:0][7:0] gpio_i_ff; + logic [7:0] gpio_o_value; + logic [7:0] gpio_oe_value; + always_ff @(posedge sys.clk) begin bus.ack <= 1'b0; if (bus.request) begin bus.ack <= 1'b1; end + end - if (bus.reset) begin + always_comb begin + bus.rdata = 32'd0; + if (bus.ack) begin + bus.rdata = {8'd0, gpio_oe_value, gpio_i_ff[1], gpio_o_value}; + end + end + + always_ff @(posedge sys.clk) begin + gpio_i_ff <= {gpio_i_ff[0], gpio_i}; + gpio_o <= gpio_o_value; + gpio_oe <= gpio_oe_value; + + if (sys.reset) begin gpio_o_value <= 8'd0; gpio_oe_value <= 8'd0; end else if (bus.request) begin diff --git a/fw/rtl/cpu/cpu_i2c.sv b/fw/rtl/cpu/cpu_i2c.sv index 155294f..ab2c7e2 100644 --- a/fw/rtl/cpu/cpu_i2c.sv +++ b/fw/rtl/cpu/cpu_i2c.sv @@ -1,7 +1,8 @@ module cpu_i2c ( + if_system.sys sys, if_cpu_bus bus, - inout i2c_scl, + output i2c_scl, inout i2c_sda ); @@ -20,13 +21,13 @@ module cpu_i2c ( end end - always_ff @(posedge bus.clk) begin + always_ff @(posedge sys.clk) begin bus.ack <= 1'b0; if (bus.request) begin bus.ack <= 1'b1; end - if (bus.reset) begin + if (sys.reset) begin mack <= 1'b0; end else if (bus.request && bus.wmask[0] && !bus.address[2]) begin mack <= bus.wdata[2]; @@ -39,14 +40,14 @@ module cpu_i2c ( wire clock_tick = &clock_div; wire [3:0] clock_phase = {4{clock_tick}} & clock_phase_gen; - always_ff @(posedge bus.clk) begin - if (bus.reset) begin + always_ff @(posedge sys.clk) begin + if (sys.reset) begin clock_div <= 6'd0; end else begin clock_div <= clock_div + 1'd1; end - if (bus.reset || state == 2'd0) begin + if (sys.reset || state == 2'd0) begin clock_phase_gen <= 4'b0001; end else if (clock_tick) begin clock_phase_gen <= {clock_phase_gen[2:0], clock_phase_gen[3]}; @@ -62,10 +63,10 @@ module cpu_i2c ( assign i2c_scl = scl_o ? 1'bZ : 1'b0; assign i2c_sda = sda_o ? 1'bZ : 1'b0; - always_ff @(posedge bus.clk) begin + always_ff @(posedge sys.clk) begin {sda_i_ff2, sda_i_ff1} <= {sda_i_ff1, i2c_sda}; - if (bus.reset) begin + if (sys.reset) begin state <= 2'd0; scl_o <= 1'b1; sda_o <= 1'b1; diff --git a/fw/rtl/cpu/cpu_ram.sv b/fw/rtl/cpu/cpu_ram.sv index 36d2cce..fae5dd9 100644 --- a/fw/rtl/cpu/cpu_ram.sv +++ b/fw/rtl/cpu/cpu_ram.sv @@ -1,44 +1,33 @@ -module cpu_ram(if_cpu_bus bus); +module cpu_ram ( + if_system.sys sys, + if_cpu_bus bus +); - logic bank; - logic [3:0][7:0] ram_1 [0:4095]; - // logic [3:0][7:0] ram_2 [0:2047]; - logic [31:0] q_1;//, q_2; - // logic [31:0] q; + logic [3:0][7:0] ram [0:4095]; + logic [31:0] q; - assign bank = bus.address[14]; - - always_comb begin - bus.rdata = 32'd0; - if (bus.ack) begin - bus.rdata = q_1; - // if (bank) bus.rdata = q_2; - end - end - - always_ff @(posedge bus.clk) begin + always_ff @(posedge sys.clk) begin bus.ack <= 1'b0; if (bus.request) begin bus.ack <= 1'b1; end end - always_ff @(posedge bus.clk) begin - q_1 <= ram_1[bus.address[13:2]]; - if (bus.request & !bank) begin - if (bus.wmask[0]) ram_1[bus.address[13:2]][0] <= bus.wdata[7:0]; - if (bus.wmask[1]) ram_1[bus.address[13:2]][1] <= bus.wdata[15:8]; - if (bus.wmask[2]) ram_1[bus.address[13:2]][2] <= bus.wdata[23:16]; - if (bus.wmask[3]) ram_1[bus.address[13:2]][3] <= bus.wdata[31:24]; + always_comb begin + bus.rdata = 32'd0; + if (bus.ack) begin + bus.rdata = q; end + end - // q_2 <= ram_2[bus.address[12:2]]; - // if (bus.request & bank) begin - // if (bus.wmask[0]) ram_2[bus.address[12:2]][0] <= bus.wdata[7:0]; - // if (bus.wmask[1]) ram_2[bus.address[12:2]][1] <= bus.wdata[15:8]; - // if (bus.wmask[2]) ram_2[bus.address[12:2]][2] <= bus.wdata[23:16]; - // if (bus.wmask[3]) ram_2[bus.address[12:2]][3] <= bus.wdata[31:24]; - // end + always_ff @(posedge sys.clk) begin + q <= ram[bus.address[13:2]]; + if (bus.request) begin + if (bus.wmask[0]) ram[bus.address[13:2]][0] <= bus.wdata[7:0]; + if (bus.wmask[1]) ram[bus.address[13:2]][1] <= bus.wdata[15:8]; + if (bus.wmask[2]) ram[bus.address[13:2]][2] <= bus.wdata[23:16]; + if (bus.wmask[3]) ram[bus.address[13:2]][3] <= bus.wdata[31:24]; + end end endmodule diff --git a/fw/rtl/cpu/cpu_soc.sv b/fw/rtl/cpu/cpu_soc.sv index d5cc2ab..caa38f4 100644 --- a/fw/rtl/cpu/cpu_soc.sv +++ b/fw/rtl/cpu/cpu_soc.sv @@ -1,11 +1,12 @@ module cpu_soc ( if_system.sys sys, + if_config cfg, input [7:0] gpio_i, output [7:0] gpio_o, output [7:0] gpio_oe, - inout i2c_scl, + output i2c_scl, inout i2c_sda, output usb_clk, @@ -17,56 +18,48 @@ module cpu_soc ( input uart_rxd, output uart_txd, input uart_cts, - output uart_rts + output uart_rts, + + output sd_clk, + inout sd_cmd, + inout [3:0] sd_dat ); - enum bit [3:0] { - RAM, - BOOTLOADER, - GPIO, - I2C, - USB, - UART, - __NUM_DEVICES - } e_address_map; + if_cpu_bus bus (); - if_cpu_bus #( - .NUM_DEVICES(__NUM_DEVICES) - ) bus ( - .clk(sys.clk), - .reset(sys.reset) - ); - - cpu_wrapper # ( - .ENTRY_DEVICE(BOOTLOADER) - ) cpu_wrapper_inst ( + cpu_wrapper cpu_wrapper_inst ( + .sys(sys), .bus(bus) ); cpu_ram cpu_ram_inst ( - .bus(bus.at[RAM].device) + .sys(sys), + .bus(bus.at[sc64::ID_CPU_RAM].device) ); cpu_bootloader cpu_bootloader_inst ( - .bus(bus.at[BOOTLOADER].device) + .sys(sys), + .bus(bus.at[sc64::ID_CPU_BOOTLOADER].device) ); cpu_gpio cpu_gpio_inst ( - .bus(bus.at[GPIO].device), + .sys(sys), + .bus(bus.at[sc64::ID_CPU_GPIO].device), .gpio_i(gpio_i), .gpio_o(gpio_o), .gpio_oe(gpio_oe) ); cpu_i2c cpu_i2c_inst ( - .bus(bus.at[I2C].device), + .sys(sys), + .bus(bus.at[sc64::ID_CPU_I2C].device), .i2c_scl(i2c_scl), .i2c_sda(i2c_sda) ); cpu_usb cpu_usb_inst ( .sys(sys), - .bus(bus.at[USB].device), + .bus(bus.at[sc64::ID_CPU_USB].device), .usb_clk(usb_clk), .usb_cs(usb_cs), .usb_miso(usb_miso), @@ -74,10 +67,9 @@ module cpu_soc ( .usb_pwren(usb_pwren) ); - cpu_uart #( - .BAUD_RATE(1_000_000) - ) cpu_uart_inst ( - .bus(bus.at[UART].device), + cpu_uart cpu_uart_inst ( + .sys(sys), + .bus(bus.at[sc64::ID_CPU_UART].device), .uart_rxd(uart_rxd), .uart_txd(uart_txd), .uart_cts(uart_cts), diff --git a/fw/rtl/cpu/cpu_uart.sv b/fw/rtl/cpu/cpu_uart.sv index ff28bb7..dd1d21a 100644 --- a/fw/rtl/cpu/cpu_uart.sv +++ b/fw/rtl/cpu/cpu_uart.sv @@ -1,6 +1,5 @@ -module cpu_uart # ( - parameter BAUD_RATE = 1_000_000 -) ( +module cpu_uart ( + if_system.sys sys, if_cpu_bus bus, input uart_rxd, @@ -9,78 +8,145 @@ module cpu_uart # ( output uart_rts ); - localparam BAUD_GEN_VALUE = int'(100_000_000 / BAUD_RATE) - 1'd1; + localparam BAUD_GEN_VALUE = int'(100_000_000 / sc64::UART_BAUD_RATE) - 1'd1; typedef enum bit [1:0] { - S_TX_IDLE, - S_TX_DATA - } e_tx_state; + S_TRX_IDLE, + S_TRX_DATA, + S_TRX_SAMPLING_OFFSET + } e_trx_state; - e_tx_state tx_state; - logic [7:0] tx_data; - logic tx_start; + + // CPU bus controller + + e_trx_state tx_state; + e_trx_state rx_state; + logic [7:0] rx_data; + logic rx_available; + logic rx_overrun; + + always_ff @(posedge sys.clk) begin + bus.ack <= 1'b0; + if (bus.request) begin + bus.ack <= 1'b1; + end + end always_comb begin bus.rdata = 32'd0; if (bus.ack) begin case (bus.address[2:2]) - 0: bus.rdata = {30'd0, tx_state == S_TX_IDLE, 1'b0}; + 0: bus.rdata = {29'd0, rx_overrun, tx_state == S_TRX_IDLE, rx_available}; + 1: bus.rdata = {24'd0, rx_data}; default: bus.rdata = 32'd0; endcase end end - always_ff @(posedge bus.clk) begin - bus.ack <= 1'b0; - tx_start <= 1'b0; - if (bus.request) begin - bus.ack <= 1'b1; - - case (bus.address[2:2]) - 2'd1: if (bus.wmask[0]) begin - tx_data <= bus.wdata[7:0]; - tx_start <= 1'b1; - end - endcase - end - end + // TX path logic [6:0] tx_baud_counter; logic [3:0] tx_bit_counter; logic [9:0] tx_shifter; - always_ff @(posedge bus.clk) begin + always_ff @(posedge sys.clk) begin tx_baud_counter <= tx_baud_counter + 1'd1; uart_txd <= tx_shifter[0]; - if (bus.reset) begin - tx_state <= S_TX_IDLE; + if (sys.reset) begin + tx_state <= S_TRX_IDLE; tx_shifter <= 10'h3FF; end else begin case (tx_state) - S_TX_IDLE: begin - if (tx_start) begin - tx_state <= S_TX_DATA; + S_TRX_IDLE: begin + if (bus.request && bus.wmask[0] && bus.address[2]) begin + tx_state <= S_TRX_DATA; tx_baud_counter <= 7'd0; tx_bit_counter <= 4'd0; - tx_shifter <= {1'b1, tx_data, 1'b0}; + tx_shifter <= {1'b1, bus.wdata[7:0], 1'b0}; end end - S_TX_DATA: begin + S_TRX_DATA: begin if (tx_baud_counter == BAUD_GEN_VALUE) begin tx_baud_counter <= 7'd0; tx_bit_counter <= tx_bit_counter + 1'd1; tx_shifter <= {1'b1, tx_shifter[9:1]}; if (tx_bit_counter == 4'd9) begin - tx_state <= S_TX_IDLE; + tx_state <= S_TRX_IDLE; end end end default: begin - tx_state <= S_TX_IDLE; + tx_state <= S_TRX_IDLE; + tx_shifter <= 10'h3FF; + end + endcase + end + end + + + // RX path + + logic [6:0] rx_baud_counter; + logic [3:0] rx_bit_counter; + logic [7:0] rx_shifter; + logic [1:0] rxd_ff; + + always_ff @(posedge sys.clk) begin + rx_baud_counter <= rx_baud_counter + 1'd1; + rxd_ff <= {rxd_ff[0], uart_rxd}; + + if (bus.request && bus.wmask[0] && !bus.address[2]) begin + rx_overrun <= bus.wdata[2]; + end + if (bus.request && !bus.wmask[0] && bus.address[2]) begin + rx_available <= 1'b0; + end + + if (sys.reset) begin + rx_state <= S_TRX_IDLE; + rx_available <= 1'b0; + rx_overrun <= 1'b0; + end else begin + case (rx_state) + S_TRX_IDLE: begin + if (!rxd_ff[1]) begin + rx_state <= S_TRX_SAMPLING_OFFSET; + rx_baud_counter <= 7'd0; + rx_bit_counter <= 4'd0; + end + end + + S_TRX_SAMPLING_OFFSET: begin + if (rx_baud_counter == (BAUD_GEN_VALUE / 2)) begin + rx_state <= S_TRX_DATA; + rx_baud_counter <= 7'd0; + end + end + + S_TRX_DATA: begin + if (rx_baud_counter == BAUD_GEN_VALUE) begin + rx_baud_counter <= 7'd0; + rx_bit_counter <= rx_bit_counter + 1'd1; + rx_shifter <= {rxd_ff[1], rx_shifter[7:1]}; + if (rx_bit_counter == 4'd8) begin + rx_state <= S_TRX_IDLE; + if (rxd_ff[1]) begin + rx_data <= rx_shifter[7:0]; + rx_available <= 1'b1; + rx_overrun <= rx_available; + end + end + end + end + + default: begin + rx_state <= S_TRX_IDLE; + rx_available <= 1'b0; + rx_overrun <= 1'b0; end endcase end diff --git a/fw/rtl/cpu/cpu_usb.sv b/fw/rtl/cpu/cpu_usb.sv index 9eeb0e3..04ef581 100644 --- a/fw/rtl/cpu/cpu_usb.sv +++ b/fw/rtl/cpu/cpu_usb.sv @@ -19,6 +19,13 @@ module cpu_usb ( logic tx_write; logic [7:0] tx_wdata; + always_ff @(posedge sys.clk) begin + bus.ack <= 1'b0; + if (bus.request) begin + bus.ack <= 1'b1; + end + end + always_comb begin bus.rdata = 32'd0; if (bus.ack) begin @@ -30,18 +37,13 @@ module cpu_usb ( end end - always_ff @(posedge bus.clk) begin + always_ff @(posedge sys.clk) begin rx_flush <= 1'b0; rx_read <= 1'b0; tx_flush <= 1'b0; tx_write <= 1'b0; - bus.ack <= 1'b0; - if (bus.request) begin - bus.ack <= 1'b1; - end - if (bus.request) begin case (bus.address[2:2]) 2'd0: if (bus.wmask[0]) begin diff --git a/fw/rtl/cpu/cpu_wrapper.sv b/fw/rtl/cpu/cpu_wrapper.sv index 973abda..ed37687 100644 --- a/fw/rtl/cpu/cpu_wrapper.sv +++ b/fw/rtl/cpu/cpu_wrapper.sv @@ -1,20 +1,21 @@ -module cpu_wrapper #( - parameter [3:0] ENTRY_DEVICE = 4'h0 -) ( +module cpu_wrapper ( + if_system.sys sys, if_cpu_bus.cpu bus ); - typedef enum bit {S_IDLE, S_WAITING} e_bus_state; + typedef enum bit [0:0] { + S_IDLE, + S_WAITING + } e_bus_state; e_bus_state state; - wire mem_la_read; - wire mem_la_write; + logic mem_la_read; + logic mem_la_write; - always_ff @(posedge bus.clk) begin + always_ff @(posedge sys.clk) begin bus.request <= 1'b0; - - if (bus.reset) begin + if (sys.reset) begin state <= S_IDLE; end else begin if (state == S_IDLE && (mem_la_read || mem_la_write)) begin @@ -33,10 +34,10 @@ module cpu_wrapper #( .TWO_STAGE_SHIFT(0), .CATCH_MISALIGN(0), .CATCH_ILLINSN(0), - .PROGADDR_RESET({ENTRY_DEVICE, 28'h000_0000}) + .PROGADDR_RESET({4'(sc64::ID_CPU_BOOTLOADER), 28'h000_0000}) ) cpu_inst ( - .clk(bus.clk), - .resetn(~bus.reset), + .clk(sys.clk), + .resetn(~sys.reset), .mem_addr(bus.address), .mem_wdata(bus.wdata), .mem_wstrb(bus.wmask), diff --git a/fw/rtl/intel/gpio/intel_gpio_ddro.qip b/fw/rtl/intel/gpio/intel_gpio_ddro.qip new file mode 100644 index 0000000..6a307ed --- /dev/null +++ b/fw/rtl/intel/gpio/intel_gpio_ddro.qip @@ -0,0 +1,77 @@ +set_global_assignment -entity "intel_gpio_ddro" -library "intel_gpio_ddro" -name IP_TOOL_NAME "altera_gpio_lite" +set_global_assignment -entity "intel_gpio_ddro" -library "intel_gpio_ddro" -name IP_TOOL_VERSION "20.1" +set_global_assignment -entity "intel_gpio_ddro" -library "intel_gpio_ddro" -name IP_TOOL_ENV "mwpim" +set_global_assignment -library "intel_gpio_ddro" -name MISC_FILE [file join $::quartus(qip_path) "intel_gpio_ddro.cmp"] +set_global_assignment -entity "intel_gpio_ddro" -library "intel_gpio_ddro" -name IP_TARGETED_DEVICE_FAMILY "MAX 10" +set_global_assignment -entity "intel_gpio_ddro" -library "intel_gpio_ddro" -name IP_GENERATED_DEVICE_FAMILY "{MAX 10}" +set_global_assignment -entity "intel_gpio_ddro" -library "intel_gpio_ddro" -name IP_QSYS_MODE "UNKNOWN" +set_global_assignment -name SYNTHESIS_ONLY_QIP ON +set_global_assignment -entity "intel_gpio_ddro" -library "intel_gpio_ddro" -name IP_COMPONENT_NAME "aW50ZWxfZ3Bpb19kZHJv" +set_global_assignment -entity "intel_gpio_ddro" -library "intel_gpio_ddro" -name IP_COMPONENT_DISPLAY_NAME "R1BJTyBMaXRlIEludGVsIEZQR0EgSVA=" +set_global_assignment -entity "intel_gpio_ddro" -library "intel_gpio_ddro" -name IP_COMPONENT_REPORT_HIERARCHY "Off" +set_global_assignment -entity "intel_gpio_ddro" -library "intel_gpio_ddro" -name IP_COMPONENT_INTERNAL "Off" +set_global_assignment -entity "intel_gpio_ddro" -library "intel_gpio_ddro" -name IP_COMPONENT_AUTHOR "SW50ZWwgQ29ycG9yYXRpb24=" +set_global_assignment -entity "intel_gpio_ddro" -library "intel_gpio_ddro" -name IP_COMPONENT_VERSION "MjAuMQ==" +set_global_assignment -entity "intel_gpio_ddro" -library "intel_gpio_ddro" -name IP_COMPONENT_DESCRIPTION "R1BJTyBMaXRlIEludGVsIEZQR0EgSVA=" +set_global_assignment -entity "altera_gpio_lite" -library "intel_gpio_ddro" -name IP_COMPONENT_NAME "YWx0ZXJhX2dwaW9fbGl0ZQ==" +set_global_assignment -entity "altera_gpio_lite" -library "intel_gpio_ddro" -name IP_COMPONENT_DISPLAY_NAME "R1BJTyBMaXRlIEludGVsIEZQR0EgSVA=" +set_global_assignment -entity "altera_gpio_lite" -library "intel_gpio_ddro" -name IP_COMPONENT_REPORT_HIERARCHY "Off" +set_global_assignment -entity "altera_gpio_lite" -library "intel_gpio_ddro" -name IP_COMPONENT_INTERNAL "Off" +set_global_assignment -entity "altera_gpio_lite" -library "intel_gpio_ddro" -name IP_COMPONENT_AUTHOR "SW50ZWwgQ29ycG9yYXRpb24=" +set_global_assignment -entity "altera_gpio_lite" -library "intel_gpio_ddro" -name IP_COMPONENT_VERSION "MjAuMQ==" +set_global_assignment -entity "altera_gpio_lite" -library "intel_gpio_ddro" -name IP_COMPONENT_DESCRIPTION "R1BJTyBMaXRlIEludGVsIEZQR0EgSVA=" +set_global_assignment -entity "altera_gpio_lite" -library "intel_gpio_ddro" -name IP_COMPONENT_PARAMETER "REVWSUNFX0ZBTUlMWQ==::TUFYIDEw::RGV2aWNlIGZhbWlseQ==" +set_global_assignment -entity "altera_gpio_lite" -library "intel_gpio_ddro" -name IP_COMPONENT_PARAMETER "UElOX1RZUEU=::b3V0cHV0::RGF0YSBkaXJlY3Rpb24=" +set_global_assignment -entity "altera_gpio_lite" -library "intel_gpio_ddro" -name IP_COMPONENT_PARAMETER "U0laRQ==::MQ==::RGF0YSB3aWR0aA==" +set_global_assignment -entity "altera_gpio_lite" -library "intel_gpio_ddro" -name IP_COMPONENT_PARAMETER "Z3VpX3RydWVfZGlmZl9idWY=::ZmFsc2U=::VXNlIHRydWUgZGlmZmVyZW50aWFsIGJ1ZmZlcg==" +set_global_assignment -entity "altera_gpio_lite" -library "intel_gpio_ddro" -name IP_COMPONENT_PARAMETER "Z3VpX3BzZXVkb19kaWZmX2J1Zg==::ZmFsc2U=::VXNlIHBzZXVkbyBkaWZmZXJlbnRpYWwgYnVmZmVy" +set_global_assignment -entity "altera_gpio_lite" -library "intel_gpio_ddro" -name IP_COMPONENT_PARAMETER "Z3VpX2J1c19ob2xk::ZmFsc2U=::VXNlIGJ1cy1ob2xkIGNpcmN1aXRyeQ==" +set_global_assignment -entity "altera_gpio_lite" -library "intel_gpio_ddro" -name IP_COMPONENT_PARAMETER "Z3VpX29wZW5fZHJhaW4=::ZmFsc2U=::VXNlIG9wZW4gZHJhaW4gb3V0cHV0" +set_global_assignment -entity "altera_gpio_lite" -library "intel_gpio_ddro" -name IP_COMPONENT_PARAMETER "Z3VpX2VuYWJsZV9vZV9wb3J0::ZmFsc2U=::RW5hYmxlIG9lIHBvcnQ=" +set_global_assignment -entity "altera_gpio_lite" -library "intel_gpio_ddro" -name IP_COMPONENT_PARAMETER "Z3VpX2lvX3JlZ19tb2Rl::ZGRy::UmVnaXN0ZXIgbW9kZQ==" +set_global_assignment -entity "altera_gpio_lite" -library "intel_gpio_ddro" -name IP_COMPONENT_PARAMETER "Z3VpX2VuYWJsZV9hY2xyX3BvcnQ=::ZmFsc2U=::RW5hYmxlIGFjbHIgcG9ydA==" +set_global_assignment -entity "altera_gpio_lite" -library "intel_gpio_ddro" -name IP_COMPONENT_PARAMETER "Z3VpX2VuYWJsZV9hc2V0X3BvcnQ=::ZmFsc2U=::RW5hYmxlIGFzZXQgcG9ydA==" +set_global_assignment -entity "altera_gpio_lite" -library "intel_gpio_ddro" -name IP_COMPONENT_PARAMETER "Z3VpX2VuYWJsZV9zY2xyX3BvcnQ=::ZmFsc2U=::RW5hYmxlIHNjbHIgcG9ydA==" +set_global_assignment -entity "altera_gpio_lite" -library "intel_gpio_ddro" -name IP_COMPONENT_PARAMETER "Z3VpX3NldF9yZWdpc3RlcnNfdG9fcG93ZXJfdXBfaGlnaA==::ZmFsc2U=::U2V0IHJlZ2lzdGVycyB0byBwb3dlciB1cCBoaWdoICh3aGVuIGFjbHIsIHNjbHIgYW5kIGFzZXQgcG9ydHMgYXJlIG5vdCB1c2VkKQ==" +set_global_assignment -entity "altera_gpio_lite" -library "intel_gpio_ddro" -name IP_COMPONENT_PARAMETER "Z3VpX2Nsb2NrX2VuYWJsZQ==::ZmFsc2U=::RW5hYmxlIGluY2xvY2tlbi9vdXRjbG9ja2VuIHBvcnRz" +set_global_assignment -entity "altera_gpio_lite" -library "intel_gpio_ddro" -name IP_COMPONENT_PARAMETER "Z3VpX2ludmVydF9vdXRwdXQ=::ZmFsc2U=::SW52ZXJ0IGRpbg==" +set_global_assignment -entity "altera_gpio_lite" -library "intel_gpio_ddro" -name IP_COMPONENT_PARAMETER "Z3VpX3VzZV9yZWdpc3Rlcl90b19kcml2ZV9vYnVmX29l::ZmFsc2U=::VXNlIGEgc2luZ2xlIHJlZ2lzdGVyIHRvIGRyaXZlIHRoZSBvdXRwdXQgZW5hYmxlIChvZSkgc2lnbmFsIGF0IHRoZSBJL08gYnVmZmVy" +set_global_assignment -entity "altera_gpio_lite" -library "intel_gpio_ddro" -name IP_COMPONENT_PARAMETER "Z3VpX3VzZV9kZGlvX3JlZ190b19kcml2ZV9vZQ==::ZmFsc2U=::VXNlIERESU8gcmVnaXN0ZXJzIHRvIGRyaXZlIHRoZSBvdXRwdXQgZW5hYmxlIChvZSkgc2lnbmFsIGF0IHRoZSBJL08gYnVmZmVy" +set_global_assignment -entity "altera_gpio_lite" -library "intel_gpio_ddro" -name IP_COMPONENT_PARAMETER "Z3VpX3VzZV9hZHZhbmNlZF9kZHJfZmVhdHVyZXM=::ZmFsc2U=::RW5hYmxlIGFkdmFuY2VkIEREUiBmZWF0dXJlcw==" +set_global_assignment -entity "altera_gpio_lite" -library "intel_gpio_ddro" -name IP_COMPONENT_PARAMETER "Z3VpX2VuYWJsZV9waGFzZV9kZXRlY3Rvcl9mb3JfY2s=::ZmFsc2U=::RW5hYmxlIFBoYXNlIERldGVjdG9yIGZyb20gQ0sgbG9vcGJhY2sgc2lnbmFs" +set_global_assignment -entity "altera_gpio_lite" -library "intel_gpio_ddro" -name IP_COMPONENT_PARAMETER "Z3VpX2VuYWJsZV9vZV9oYWxmX2N5Y2xlX2RlbGF5::dHJ1ZQ==::QWRkIGhhbGYtY3ljbGUgZGVsYXkgdG8gT0Ugc2lnbmFs" +set_global_assignment -entity "altera_gpio_lite" -library "intel_gpio_ddro" -name IP_COMPONENT_PARAMETER "Z3VpX2VuYWJsZV9ocl9jbG9jaw==::ZmFsc2U=::RW5hYmxlIGhhbGYtcmF0ZSBjbG9jayBwb3J0" +set_global_assignment -entity "altera_gpio_lite" -library "intel_gpio_ddro" -name IP_COMPONENT_PARAMETER "Z3VpX2VuYWJsZV9pbnZlcnRfaHJfY2xvY2tfcG9ydA==::ZmFsc2U=::RW5hYmxlIGludmVydF9ocl9jbG9jayBwb3J0" +set_global_assignment -entity "altera_gpio_lite" -library "intel_gpio_ddro" -name IP_COMPONENT_PARAMETER "Z3VpX2ludmVydF9jbGtkaXZfaW5wdXRfY2xvY2s=::ZmFsc2U=::SW52ZXJ0IGNsb2NrIGRpdmlkZXIgaW5wdXQgY2xvY2s=" +set_global_assignment -entity "altera_gpio_lite" -library "intel_gpio_ddro" -name IP_COMPONENT_PARAMETER "Z3VpX2ludmVydF9vdXRwdXRfY2xvY2s=::ZmFsc2U=::SW52ZXJ0IERESU8gb3V0Y2xvY2s=" +set_global_assignment -entity "altera_gpio_lite" -library "intel_gpio_ddro" -name IP_COMPONENT_PARAMETER "Z3VpX2ludmVydF9vZV9pbmNsb2Nr::ZmFsc2U=::SW52ZXJ0IG91dHB1dCBlbmFibGUgKG9lKSByZWdpc3RlciBpbmNsb2Nr" +set_global_assignment -entity "altera_gpio_lite" -library "intel_gpio_ddro" -name IP_COMPONENT_PARAMETER "UkVHSVNURVJfTU9ERQ==::ZGRy::UkVHSVNURVJfTU9ERQ==" +set_global_assignment -entity "altera_gpio_lite" -library "intel_gpio_ddro" -name IP_COMPONENT_PARAMETER "QlVGRkVSX1RZUEU=::c2luZ2xlLWVuZGVk::QlVGRkVSX1RZUEU=" +set_global_assignment -entity "altera_gpio_lite" -library "intel_gpio_ddro" -name IP_COMPONENT_PARAMETER "QVNZTkNfTU9ERQ==::bm9uZQ==::QVNZTkNfTU9ERQ==" +set_global_assignment -entity "altera_gpio_lite" -library "intel_gpio_ddro" -name IP_COMPONENT_PARAMETER "U1lOQ19NT0RF::bm9uZQ==::U1lOQ19NT0RF" +set_global_assignment -entity "altera_gpio_lite" -library "intel_gpio_ddro" -name IP_COMPONENT_PARAMETER "QlVTX0hPTEQ=::ZmFsc2U=::QlVTX0hPTEQ=" +set_global_assignment -entity "altera_gpio_lite" -library "intel_gpio_ddro" -name IP_COMPONENT_PARAMETER "T1BFTl9EUkFJTl9PVVRQVVQ=::ZmFsc2U=::T1BFTl9EUkFJTl9PVVRQVVQ=" +set_global_assignment -entity "altera_gpio_lite" -library "intel_gpio_ddro" -name IP_COMPONENT_PARAMETER "RU5BQkxFX09FX1BPUlQ=::ZmFsc2U=::RU5BQkxFX09FX1BPUlQ=" +set_global_assignment -entity "altera_gpio_lite" -library "intel_gpio_ddro" -name IP_COMPONENT_PARAMETER "RU5BQkxFX05TTEVFUF9QT1JU::ZmFsc2U=::RU5BQkxFX05TTEVFUF9QT1JU" +set_global_assignment -entity "altera_gpio_lite" -library "intel_gpio_ddro" -name IP_COMPONENT_PARAMETER "RU5BQkxFX0NMT0NLX0VOQV9QT1JU::ZmFsc2U=::RU5BQkxFX0NMT0NLX0VOQV9QT1JU" +set_global_assignment -entity "altera_gpio_lite" -library "intel_gpio_ddro" -name IP_COMPONENT_PARAMETER "U0VUX1JFR0lTVEVSX09VVFBVVFNfSElHSA==::ZmFsc2U=::U0VUX1JFR0lTVEVSX09VVFBVVFNfSElHSA==" +set_global_assignment -entity "altera_gpio_lite" -library "intel_gpio_ddro" -name IP_COMPONENT_PARAMETER "SU5WRVJUX09VVFBVVA==::ZmFsc2U=::SU5WRVJUX09VVFBVVA==" +set_global_assignment -entity "altera_gpio_lite" -library "intel_gpio_ddro" -name IP_COMPONENT_PARAMETER "SU5WRVJUX0lOUFVUX0NMT0NL::ZmFsc2U=::SU5WRVJUX0lOUFVUX0NMT0NL" +set_global_assignment -entity "altera_gpio_lite" -library "intel_gpio_ddro" -name IP_COMPONENT_PARAMETER "VVNFX09ORV9SRUdfVE9fRFJJVkVfT0U=::ZmFsc2U=::VVNFX09ORV9SRUdfVE9fRFJJVkVfT0U=" +set_global_assignment -entity "altera_gpio_lite" -library "intel_gpio_ddro" -name IP_COMPONENT_PARAMETER "VVNFX0RESU9fUkVHX1RPX0RSSVZFX09F::ZmFsc2U=::VVNFX0RESU9fUkVHX1RPX0RSSVZFX09F" +set_global_assignment -entity "altera_gpio_lite" -library "intel_gpio_ddro" -name IP_COMPONENT_PARAMETER "VVNFX0FEVkFOQ0VEX0REUl9GRUFUVVJFUw==::ZmFsc2U=::VVNFX0FEVkFOQ0VEX0REUl9GRUFUVVJFUw==" +set_global_assignment -entity "altera_gpio_lite" -library "intel_gpio_ddro" -name IP_COMPONENT_PARAMETER "VVNFX0FEVkFOQ0VEX0REUl9GRUFUVVJFU19GT1JfSU5QVVRfT05MWQ==::ZmFsc2U=::VVNFX0FEVkFOQ0VEX0REUl9GRUFUVVJFU19GT1JfSU5QVVRfT05MWQ==" +set_global_assignment -entity "altera_gpio_lite" -library "intel_gpio_ddro" -name IP_COMPONENT_PARAMETER "RU5BQkxFX09FX0hBTEZfQ1lDTEVfREVMQVk=::dHJ1ZQ==::RU5BQkxFX09FX0hBTEZfQ1lDTEVfREVMQVk=" +set_global_assignment -entity "altera_gpio_lite" -library "intel_gpio_ddro" -name IP_COMPONENT_PARAMETER "SU5WRVJUX0NMS0RJVl9JTlBVVF9DTE9DSw==::ZmFsc2U=::SU5WRVJUX0NMS0RJVl9JTlBVVF9DTE9DSw==" +set_global_assignment -entity "altera_gpio_lite" -library "intel_gpio_ddro" -name IP_COMPONENT_PARAMETER "RU5BQkxFX1BIQVNFX0lOVkVSVF9DVFJMX1BPUlQ=::ZmFsc2U=::RU5BQkxFX1BIQVNFX0lOVkVSVF9DVFJMX1BPUlQ=" +set_global_assignment -entity "altera_gpio_lite" -library "intel_gpio_ddro" -name IP_COMPONENT_PARAMETER "RU5BQkxFX0hSX0NMT0NL::ZmFsc2U=::RU5BQkxFX0hSX0NMT0NL" +set_global_assignment -entity "altera_gpio_lite" -library "intel_gpio_ddro" -name IP_COMPONENT_PARAMETER "SU5WRVJUX09VVFBVVF9DTE9DSw==::ZmFsc2U=::SU5WRVJUX09VVFBVVF9DTE9DSw==" +set_global_assignment -entity "altera_gpio_lite" -library "intel_gpio_ddro" -name IP_COMPONENT_PARAMETER "SU5WRVJUX09FX0lOQ0xPQ0s=::ZmFsc2U=::SU5WRVJUX09FX0lOQ0xPQ0s=" +set_global_assignment -entity "altera_gpio_lite" -library "intel_gpio_ddro" -name IP_COMPONENT_PARAMETER "RU5BQkxFX1BIQVNFX0RFVEVDVE9SX0ZPUl9DSw==::ZmFsc2U=::RU5BQkxFX1BIQVNFX0RFVEVDVE9SX0ZPUl9DSw==" + +set_global_assignment -library "intel_gpio_ddro" -name VERILOG_FILE [file join $::quartus(qip_path) "intel_gpio_ddro.v"] +set_global_assignment -library "intel_gpio_ddro" -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) "intel_gpio_ddro/altera_gpio_lite.sv"] + +set_global_assignment -entity "altera_gpio_lite" -library "intel_gpio_ddro" -name IP_TOOL_NAME "altera_gpio_lite" +set_global_assignment -entity "altera_gpio_lite" -library "intel_gpio_ddro" -name IP_TOOL_VERSION "20.1" +set_global_assignment -entity "altera_gpio_lite" -library "intel_gpio_ddro" -name IP_TOOL_ENV "mwpim" diff --git a/fw/rtl/intel/gpio/intel_gpio_ddro.v b/fw/rtl/intel/gpio/intel_gpio_ddro.v new file mode 100644 index 0000000..9d07b1a --- /dev/null +++ b/fw/rtl/intel/gpio/intel_gpio_ddro.v @@ -0,0 +1,123 @@ +// megafunction wizard: %GPIO Lite Intel FPGA IP v20.1% +// GENERATION: XML +// intel_gpio_ddro.v + +// Generated using ACDS version 20.1 720 + +`timescale 1 ps / 1 ps +module intel_gpio_ddro ( + input wire outclock, // outclock.export + input wire [1:0] din, // din.export + output wire [0:0] pad_out // pad_out.export + ); + + altera_gpio_lite #( + .PIN_TYPE ("output"), + .SIZE (1), + .REGISTER_MODE ("ddr"), + .BUFFER_TYPE ("single-ended"), + .ASYNC_MODE ("none"), + .SYNC_MODE ("none"), + .BUS_HOLD ("false"), + .OPEN_DRAIN_OUTPUT ("false"), + .ENABLE_OE_PORT ("false"), + .ENABLE_NSLEEP_PORT ("false"), + .ENABLE_CLOCK_ENA_PORT ("false"), + .SET_REGISTER_OUTPUTS_HIGH ("false"), + .INVERT_OUTPUT ("false"), + .INVERT_INPUT_CLOCK ("false"), + .USE_ONE_REG_TO_DRIVE_OE ("false"), + .USE_DDIO_REG_TO_DRIVE_OE ("false"), + .USE_ADVANCED_DDR_FEATURES ("false"), + .USE_ADVANCED_DDR_FEATURES_FOR_INPUT_ONLY ("false"), + .ENABLE_OE_HALF_CYCLE_DELAY ("true"), + .INVERT_CLKDIV_INPUT_CLOCK ("false"), + .ENABLE_PHASE_INVERT_CTRL_PORT ("false"), + .ENABLE_HR_CLOCK ("false"), + .INVERT_OUTPUT_CLOCK ("false"), + .INVERT_OE_INCLOCK ("false"), + .ENABLE_PHASE_DETECTOR_FOR_CK ("false") + ) intel_gpio_ddro_inst ( + .outclock (outclock), // outclock.export + .din (din), // din.export + .pad_out (pad_out), // pad_out.export + .outclocken (1'b1), // (terminated) + .inclock (1'b0), // (terminated) + .inclocken (1'b0), // (terminated) + .fr_clock (), // (terminated) + .hr_clock (), // (terminated) + .invert_hr_clock (1'b0), // (terminated) + .phy_mem_clock (1'b0), // (terminated) + .mimic_clock (), // (terminated) + .dout (), // (terminated) + .pad_io (), // (terminated) + .pad_io_b (), // (terminated) + .pad_in (1'b0), // (terminated) + .pad_in_b (1'b0), // (terminated) + .pad_out_b (), // (terminated) + .aset (1'b0), // (terminated) + .aclr (1'b0), // (terminated) + .sclr (1'b0), // (terminated) + .nsleep (1'b0), // (terminated) + .oe (1'b0) // (terminated) + ); + +endmodule +// Retrieval info: +// +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// IPFS_FILES : intel_gpio_ddro.vo +// RELATED_FILES: intel_gpio_ddro.v, altera_gpio_lite.sv diff --git a/fw/rtl/intel/gpio/intel_gpio_ddro/altera_gpio_lite.sv b/fw/rtl/intel/gpio/intel_gpio_ddro/altera_gpio_lite.sv new file mode 100644 index 0000000..6d395bb --- /dev/null +++ b/fw/rtl/intel/gpio/intel_gpio_ddro/altera_gpio_lite.sv @@ -0,0 +1,1200 @@ +// (C) 2001-2020 Intel Corporation. All rights reserved. +// Your use of Intel Corporation's design tools, logic functions and other +// software and tools, and its AMPP partner logic functions, and any output +// files from any of the foregoing (including device programming or simulation +// files), and any associated documentation or information are expressly subject +// to the terms and conditions of the Intel Program License Subscription +// Agreement, Intel FPGA IP License Agreement, or other applicable +// license agreement, including, without limitation, that your use is for the +// sole purpose of programming logic devices manufactured by Intel and sold by +// Intel or its authorized distributors. Please refer to the applicable +// agreement for further details. + + +`timescale 1 ps / 1 ps + +module altgpio_one_bit( + inclock, + outclock, + phy_mem_clock, + inclocken, + outclocken, + oe, + din, + dout, + pad, + pad_b, + aset, + sclr, + hr_clock, + fr_clock, + mimic_clock, + nsleep +); + + parameter PIN_TYPE = "output"; + parameter BUFFER_TYPE = "single-ended"; + parameter REGISTER_MODE = "bypass"; + parameter ASYNC_MODE = "none"; + parameter SYNC_MODE = "none"; + parameter BUS_HOLD = "false"; + parameter SET_REGISTER_OUTPUTS_HIGH = "false"; + parameter USE_ENHANCED_DDR_HIO_REGISTER = "false"; + parameter BYPASS_THREE_QUARTER_REGISTER = "true"; + parameter INVERT_OUTPUT = "false"; + parameter INVERT_INPUT_CLOCK = "false"; + parameter INVERT_OUTPUT_CLOCK = "false"; + parameter INVERT_OE_INCLOCK = "false"; + parameter USE_ONE_REG_TO_DRIVE_OE = "false"; + parameter USE_DDIO_REG_TO_DRIVE_OE = "false"; + parameter OPEN_DRAIN_OUTPUT = "false"; + parameter ENABLE_OE_HALF_CYCLE_DELAY = "true"; + parameter USE_ADVANCED_DDR_FEATURES_FOR_INPUT_ONLY = "false"; + parameter ENABLE_CLOCK_ENA_PORT = "false"; + parameter ENABLE_HR_CLOCK = "false"; + parameter ENABLE_PHASE_DETECTOR_FOR_CK = "false"; + parameter ENABLE_NSLEEP_PORT = "false"; + + localparam DATA_SIZE = (REGISTER_MODE == "ddr") ? 2:1; + localparam DDIO_REG_POWER_UP = (ASYNC_MODE == "preset" || SET_REGISTER_OUTPUTS_HIGH == "true") ? "high" : "low"; + + input inclock; + input outclock; + input inclocken; + input outclocken; + input oe; + input nsleep; + input [DATA_SIZE - 1:0] din; + output [DATA_SIZE - 1:0] dout; + inout pad; + inout pad_b; + input aset; + input sclr; + input phy_mem_clock; + input hr_clock; + (* altera_attribute = "-name GLOBAL_SIGNAL\"OFF\"" *) output fr_clock; + output mimic_clock; + + wire din_ddr; + wire buf_in; + + wire oe_out; + wire nsleep_in; + + generate + if (PIN_TYPE == "output" || PIN_TYPE == "bidir") + begin + wire [1:0] din_fr; + if (INVERT_OUTPUT == "false") + begin + assign din_fr = din; + end + else + begin + assign din_fr = ~din; + end + + wire outclock_wire; + if (REGISTER_MODE != "bypass") + begin + if (INVERT_OUTPUT_CLOCK == "false") + begin: normal_input_clock + assign outclock_wire = outclock; + end + else + begin: inverted_output_clock + assign outclock_wire = ~outclock; + end + end + + wire outclocken_wire; + assign outclocken_wire = (ENABLE_CLOCK_ENA_PORT == "true") ? outclocken : 1'b1; + + if (REGISTER_MODE == "ddr" && USE_ENHANCED_DDR_HIO_REGISTER == "true") + begin + if (ASYNC_MODE != "none") + begin: async_mode_out_path_enhanced_ddr + fiftyfivenm_ddio_out + #( + .async_mode(ASYNC_MODE), + .sync_mode(SYNC_MODE), + .use_enhanced_ddr_hio(USE_ENHANCED_DDR_HIO_REGISTER), + .bypass_three_quarter_register(BYPASS_THREE_QUARTER_REGISTER), + .power_up(DDIO_REG_POWER_UP), + .use_new_clocking_model("true") + ) fr_out_data_ddio ( + .datainhi(din_fr[0]), + .datainlo(din_fr[1]), + .dataout(din_ddr), + .clkhi(outclock_wire), + .clklo(outclock_wire), + .muxsel(outclock_wire), + .areset(aset), + .ena(outclocken_wire), + .phymemclock(phy_mem_clock) + `ifndef ALTERA_RESERVED_QIS + , + .clk (outclock_wire), + .sreset(1'b0), + .dfflo(), + .dffhi(), + .devpor(1'b1), + .devclrn(1'b1) + `endif + ); + end + else if (SYNC_MODE != "none") + begin: sync_mode_out_path_enhanced_ddr + fiftyfivenm_ddio_out + #( + .async_mode(ASYNC_MODE), + .sync_mode(SYNC_MODE), + .use_enhanced_ddr_hio(USE_ENHANCED_DDR_HIO_REGISTER), + .bypass_three_quarter_register(BYPASS_THREE_QUARTER_REGISTER), + .power_up(DDIO_REG_POWER_UP), + .use_new_clocking_model("true") + ) fr_out_data_ddio ( + .datainhi(din_fr[0]), + .datainlo(din_fr[1]), + .dataout(din_ddr), + .clkhi(outclock_wire), + .clklo(outclock_wire), + .muxsel(outclock_wire), + .sreset(sclr), + .ena(outclocken_wire), + .phymemclock(phy_mem_clock) + `ifndef ALTERA_RESERVED_QIS + , + .clk (outclock_wire), + .areset(1'b0), + .dfflo(), + .dffhi(), + .devpor(1'b1), + .devclrn(1'b1) + `endif + ); + end + else + begin: out_path_enhanced_ddr + fiftyfivenm_ddio_out + #( + .async_mode(ASYNC_MODE), + .sync_mode(SYNC_MODE), + .use_enhanced_ddr_hio(USE_ENHANCED_DDR_HIO_REGISTER), + .bypass_three_quarter_register(BYPASS_THREE_QUARTER_REGISTER), + .power_up(DDIO_REG_POWER_UP), + .use_new_clocking_model("true") + ) fr_out_data_ddio ( + .datainhi(din_fr[0]), + .datainlo(din_fr[1]), + .dataout(din_ddr), + .clkhi(outclock_wire), + .clklo(outclock_wire), + .muxsel(outclock_wire), + .ena(outclocken_wire), + .phymemclock(phy_mem_clock) + `ifndef ALTERA_RESERVED_QIS + , + .areset(1'b0), + .clk(1'b0), + .sreset(1'b0), + .dfflo(), + .dffhi(), + .devpor(1'b1), + .devclrn(1'b1) + `endif + ); + end + end + else if (REGISTER_MODE == "ddr" && USE_ENHANCED_DDR_HIO_REGISTER == "false") + begin + if (ASYNC_MODE != "none") + begin: async_mode_out_path_ddr + fiftyfivenm_ddio_out + #( + .async_mode(ASYNC_MODE), + .sync_mode(SYNC_MODE), + .power_up(DDIO_REG_POWER_UP), + .use_new_clocking_model("true"), + .bypass_three_quarter_register(BYPASS_THREE_QUARTER_REGISTER) + ) fr_out_data_ddio ( + .datainhi(din_fr[0]), + .datainlo(din_fr[1]), + .dataout(din_ddr), + .clkhi(outclock_wire), + .clklo(outclock_wire), + .muxsel(outclock_wire), + .areset(aset), + .ena(outclocken_wire) + `ifndef ALTERA_RESERVED_QIS + , + .clk(1'b0), + .phymemclock(1'b0), + .sreset(1'b0), + .dfflo(), + .dffhi(), + .devpor(1'b1), + .devclrn(1'b1) + `endif + ); + end + else if (SYNC_MODE != "none") + begin: sync_mode_out_path_ddr + fiftyfivenm_ddio_out + #( + .async_mode(ASYNC_MODE), + .sync_mode(SYNC_MODE), + .power_up(DDIO_REG_POWER_UP), + .use_new_clocking_model("true"), + .bypass_three_quarter_register(BYPASS_THREE_QUARTER_REGISTER) + ) fr_out_data_ddio ( + .datainhi(din_fr[0]), + .datainlo(din_fr[1]), + .dataout(din_ddr), + .clkhi(outclock_wire), + .clklo(outclock_wire), + .muxsel(outclock_wire), + .sreset(sclr), + .ena(outclocken_wire) + `ifndef ALTERA_RESERVED_QIS + , + .areset(1'b0), + .clk(1'b0), + .phymemclock(1'b0), + .dfflo(), + .dffhi(), + .devpor(1'b1), + .devclrn(1'b1) + `endif + ); + end + else + begin: out_path_ddr + fiftyfivenm_ddio_out + #( + .async_mode(ASYNC_MODE), + .sync_mode(SYNC_MODE), + .power_up(DDIO_REG_POWER_UP), + .use_new_clocking_model("true"), + .bypass_three_quarter_register(BYPASS_THREE_QUARTER_REGISTER) + ) fr_out_data_ddio ( + .datainhi(din_fr[0]), + .datainlo(din_fr[1]), + .dataout(din_ddr), + .clkhi(outclock_wire), + .clklo(outclock_wire), + .muxsel(outclock_wire), + .ena(outclocken_wire) + `ifndef ALTERA_RESERVED_QIS + , + .areset(1'b0), + .clk(1'b0), + .phymemclock(1'b0), + .sreset(1'b0), + .dfflo(), + .dffhi(), + .devpor(1'b1), + .devclrn(1'b1) + `endif + ); + end + end + else if (REGISTER_MODE == "single-register") + begin: out_path_sdr + reg reg_data_out /* synthesis altera_attribute="FAST_OUTPUT_REGISTER=on" */; + always @(posedge outclock_wire) + reg_data_out <= din_fr[0]; + + assign din_ddr = reg_data_out; + end + else + begin: out_path_reg_none + assign din_ddr = din_fr[0]; + end + end + endgenerate + + generate + + if (PIN_TYPE == "bidir" || PIN_TYPE == "output") + begin + wire oe_inclk_wire; + if (USE_ONE_REG_TO_DRIVE_OE == "true" || USE_DDIO_REG_TO_DRIVE_OE == "true") + begin + if (INVERT_OE_INCLOCK == "false") + begin: normal_oe_inclock + assign oe_inclk_wire = outclock; + end + else + begin: inverted_oe_inclock + assign oe_inclk_wire = ~outclock; + end + end + + wire oe_outclocken_wire; + assign oe_outclocken_wire = (ENABLE_CLOCK_ENA_PORT == "true") ? outclocken : 1'b1; + + if (USE_DDIO_REG_TO_DRIVE_OE == "true") + begin + if (REGISTER_MODE == "ddr" && USE_ENHANCED_DDR_HIO_REGISTER == "true") + begin + if (ASYNC_MODE != "none") + begin: async_mode_oe_path_enhanced_ddr + fiftyfivenm_ddio_oe + #( + .async_mode(ASYNC_MODE), + .sync_mode(SYNC_MODE), + .use_enhanced_ddr_hio(USE_ENHANCED_DDR_HIO_REGISTER), + .bypass_three_quarter_register(BYPASS_THREE_QUARTER_REGISTER), + .enable_half_cycle_delay(ENABLE_OE_HALF_CYCLE_DELAY), + .power_up(DDIO_REG_POWER_UP) + ) fr_oe_data_ddio ( + .oe(~oe), + .dataout(oe_out), + .clk(oe_inclk_wire), + .areset(aset), + .ena(oe_outclocken_wire), + .phymemclock(phy_mem_clock) + `ifndef ALTERA_RESERVED_QIS + , + .sreset(1'b0), + .dfflo(), + .dffhi(), + .devpor(1'b1), + .devclrn(1'b1) + `endif + ); + end + else if (SYNC_MODE != "none") + begin: sync_mode_oe_path_enhanced_ddr + fiftyfivenm_ddio_oe + #( + .async_mode(ASYNC_MODE), + .sync_mode(SYNC_MODE), + .use_enhanced_ddr_hio(USE_ENHANCED_DDR_HIO_REGISTER), + .bypass_three_quarter_register(BYPASS_THREE_QUARTER_REGISTER), + .enable_half_cycle_delay(ENABLE_OE_HALF_CYCLE_DELAY), + .power_up(DDIO_REG_POWER_UP) + ) fr_oe_data_ddio ( + .oe(~oe), + .dataout(oe_out), + .clk(oe_inclk_wire), + .sreset(sclr), + .ena(oe_outclocken_wire), + .phymemclock(phy_mem_clock) + `ifndef ALTERA_RESERVED_QIS + , + .areset(1'b0), + .dfflo(), + .dffhi(), + .devpor(1'b1), + .devclrn(1'b1) + `endif + ); + end + else + begin: oe_path_enhanced_ddr + fiftyfivenm_ddio_oe + #( + .async_mode(ASYNC_MODE), + .sync_mode(SYNC_MODE), + .use_enhanced_ddr_hio(USE_ENHANCED_DDR_HIO_REGISTER), + .bypass_three_quarter_register(BYPASS_THREE_QUARTER_REGISTER), + .enable_half_cycle_delay(ENABLE_OE_HALF_CYCLE_DELAY), + .power_up(DDIO_REG_POWER_UP) + ) fr_oe_data_ddio ( + .oe(~oe), + .dataout(oe_out), + .clk(oe_inclk_wire), + .ena(oe_outclocken_wire), + .phymemclock(phy_mem_clock) + `ifndef ALTERA_RESERVED_QIS + , + .areset(1'b0), + .sreset(1'b0), + .dfflo(), + .dffhi(), + .devpor(1'b1), + .devclrn(1'b1) + `endif + ); + end + end + else if (REGISTER_MODE == "ddr" && USE_ENHANCED_DDR_HIO_REGISTER == "false") + begin + if (ASYNC_MODE != "none") + begin: async_mode_oe_path_ddr + fiftyfivenm_ddio_oe + #( + .async_mode(ASYNC_MODE), + .sync_mode(SYNC_MODE), + .enable_half_cycle_delay(ENABLE_OE_HALF_CYCLE_DELAY), + .power_up(DDIO_REG_POWER_UP), + .bypass_three_quarter_register(BYPASS_THREE_QUARTER_REGISTER) + ) fr_oe_data_ddio ( + .oe(~oe), + .dataout(oe_out), + .clk(oe_inclk_wire), + .areset(aset), + .ena(oe_outclocken_wire) + `ifndef ALTERA_RESERVED_QIS + , + .phymemclock(1'b0), + .sreset(1'b0), + .dfflo(), + .dffhi(), + .devpor(1'b1), + .devclrn(1'b1) + `endif + ); + end + else if (SYNC_MODE != "none") + begin: sync_mode_oe_path_ddr + fiftyfivenm_ddio_oe + #( + .async_mode(ASYNC_MODE), + .sync_mode(SYNC_MODE), + .enable_half_cycle_delay(ENABLE_OE_HALF_CYCLE_DELAY), + .power_up(DDIO_REG_POWER_UP), + .bypass_three_quarter_register(BYPASS_THREE_QUARTER_REGISTER) + ) fr_oe_data_ddio ( + .oe(~oe), + .dataout(oe_out), + .clk(oe_inclk_wire), + .sreset(sclr), + .ena(oe_outclocken_wire) + `ifndef ALTERA_RESERVED_QIS + , + .areset(1'b0), + .phymemclock(1'b0), + .dfflo(), + .dffhi(), + .devpor(1'b1), + .devclrn(1'b1) + `endif + ); + end + else + begin: oe_path_ddr + fiftyfivenm_ddio_oe + #( + .async_mode(ASYNC_MODE), + .sync_mode(SYNC_MODE), + .enable_half_cycle_delay(ENABLE_OE_HALF_CYCLE_DELAY), + .power_up(DDIO_REG_POWER_UP), + .bypass_three_quarter_register(BYPASS_THREE_QUARTER_REGISTER) + ) fr_oe_data_ddio ( + .oe(~oe), + .dataout(oe_out), + .clk(oe_inclk_wire), + .ena(oe_outclocken_wire) + `ifndef ALTERA_RESERVED_QIS + , + .areset(1'b0), + .phymemclock(1'b0), + .sreset(1'b0), + .dfflo(), + .dffhi(), + .devpor(1'b1), + .devclrn(1'b1) + `endif + ); + end + end + end + else if (USE_ONE_REG_TO_DRIVE_OE == "true") + begin: oe_path_sdr + fiftyfivenm_ff oe_reg ( + .clk(oe_inclk_wire), + .d(~oe), + .clrn(1'b1), + .ena(1'b1), + .q(oe_out) + ); + end + else if (USE_ONE_REG_TO_DRIVE_OE == "false" && USE_DDIO_REG_TO_DRIVE_OE == "false") + begin: oe_path_reg_none + assign oe_out = ~oe; + end + end + endgenerate + + generate + if (PIN_TYPE == "input" || PIN_TYPE == "bidir") + begin + wire [1:0] ddr_input; + wire inclock_wire; + + if (REGISTER_MODE != "bypass") + begin + if (INVERT_INPUT_CLOCK == "false") + begin: normal_input_clock + assign inclock_wire = inclock; + end + else + begin: inverted_input_clock + assign inclock_wire = ~inclock; + end + end + + wire inclocken_wire; + assign inclocken_wire = (ENABLE_CLOCK_ENA_PORT == "true") ? inclocken : 1'b1; + + if (REGISTER_MODE == "ddr") + begin + if (USE_ENHANCED_DDR_HIO_REGISTER == "true" || USE_ADVANCED_DDR_FEATURES_FOR_INPUT_ONLY == "true") + begin + if (ENABLE_HR_CLOCK == "true") + begin + if (ASYNC_MODE != "none") + begin: async_mode_in_path_enhanced_ddr_with_halfrateresyncclk + fiftyfivenm_ddio_in + #( + .async_mode(ASYNC_MODE), + .sync_mode(SYNC_MODE), + .power_up(DDIO_REG_POWER_UP), + .invert_input_clock(INVERT_INPUT_CLOCK) + ) fr_in_ddio ( + .datain(buf_in), + .clk(inclock_wire), + .ena(inclocken_wire), + .halfrateresyncclk(hr_clock), + .regouthi(ddr_input[1]), + .regoutlo(ddr_input[0]), + .clkout(fr_clock), + .areset(aset) + `ifndef ALTERA_RESERVED_QIS + , + .sreset(1'b0), + .dfflo(), + .devpor(1'b1), + .devclrn(1'b1) + `endif + ); + end + else if (SYNC_MODE != "none") + begin:sync_mode_in_path_enhanced_ddr_with_halfrateresyncclk + fiftyfivenm_ddio_in + #( + .async_mode(ASYNC_MODE), + .sync_mode(SYNC_MODE), + .power_up(DDIO_REG_POWER_UP), + .invert_input_clock(INVERT_INPUT_CLOCK) + ) fr_in_ddio ( + .datain(buf_in), + .clk (inclock_wire), + .ena(inclocken_wire), + .sreset(sclr), + .halfrateresyncclk(hr_clock), + .regouthi(ddr_input[1]), + .regoutlo(ddr_input[0]), + .clkout(fr_clock) + `ifndef ALTERA_RESERVED_QIS + , + .areset(1'b0), + .dfflo(), + .devpor(1'b1), + .devclrn(1'b1) + `endif + ); + end + else + begin:in_path_enhanced_ddr_with_halfrateresyncclk + fiftyfivenm_ddio_in + #( + .async_mode(ASYNC_MODE), + .sync_mode(SYNC_MODE), + .power_up(DDIO_REG_POWER_UP), + .invert_input_clock(INVERT_INPUT_CLOCK) + ) fr_in_ddio ( + .datain(buf_in), + .clk (inclock_wire), + .ena(inclocken_wire), + .halfrateresyncclk(hr_clock), + .regouthi(ddr_input[1]), + .regoutlo(ddr_input[0]), + .clkout(fr_clock) + `ifndef ALTERA_RESERVED_QIS + , + .sreset(1'b0), + .areset(1'b0), + .dfflo(), + .devpor(1'b1), + .devclrn(1'b1) + `endif + ); + end + end + else + begin + if (ASYNC_MODE != "none") + begin: async_mode_in_path_enhanced_ddr + fiftyfivenm_ddio_in + #( + .async_mode(ASYNC_MODE), + .sync_mode(SYNC_MODE), + .power_up(DDIO_REG_POWER_UP), + .invert_input_clock(INVERT_INPUT_CLOCK) + ) fr_in_ddio ( + .datain(buf_in), + .clk(inclock_wire), + .ena(inclocken_wire), + .regouthi(ddr_input[1]), + .regoutlo(ddr_input[0]), + .clkout(fr_clock), + .areset(aset) + `ifndef ALTERA_RESERVED_QIS + , + .sreset(1'b0), + .dfflo(), + .devpor(1'b1), + .devclrn(1'b1), + .halfrateresyncclk(1'b0) + `endif + ); + end + else if (SYNC_MODE != "none") + begin:sync_mode_in_path_enhanced_ddr + fiftyfivenm_ddio_in + #( + .async_mode(ASYNC_MODE), + .sync_mode(SYNC_MODE), + .power_up(DDIO_REG_POWER_UP), + .invert_input_clock(INVERT_INPUT_CLOCK) + ) fr_in_ddio ( + .datain(buf_in), + .clk (inclock_wire), + .ena(inclocken_wire), + .sreset(sclr), + .regouthi(ddr_input[1]), + .regoutlo(ddr_input[0]), + .clkout(fr_clock) + `ifndef ALTERA_RESERVED_QIS + , + .areset(1'b0), + .dfflo(), + .devpor(1'b1), + .devclrn(1'b1), + .halfrateresyncclk(1'b0) + `endif + ); + end + else + begin:in_path_enhanced_ddr + fiftyfivenm_ddio_in + #( + .async_mode(ASYNC_MODE), + .sync_mode(SYNC_MODE), + .power_up(DDIO_REG_POWER_UP), + .invert_input_clock(INVERT_INPUT_CLOCK) + ) fr_in_ddio ( + .datain(buf_in), + .clk (inclock_wire), + .ena(inclocken_wire), + .regouthi(ddr_input[1]), + .regoutlo(ddr_input[0]), + .clkout(fr_clock) + `ifndef ALTERA_RESERVED_QIS + , + .sreset(1'b0), + .areset(1'b0), + .dfflo(), + .devpor(1'b1), + .devclrn(1'b1), + .halfrateresyncclk(1'b0) + `endif + ); + end + end + end + else if (ENABLE_PHASE_DETECTOR_FOR_CK == "true") + begin + assign mimic_clock = buf_in; + end + else + begin: in_path_ddr + wire input_cell_l_q; + wire input_aset; + + assign input_aset = ( ASYNC_MODE == "clear") ? !aset : aset; + + fiftyfivenm_ff input_cell_l ( + .clk(inclock_wire), + .d(buf_in), + .clrn(input_aset), + .ena(inclocken_wire), + .q(input_cell_l_q) + ); + + fiftyfivenm_ff input_latch_l ( + .clk(~inclock_wire), + .d(input_cell_l_q), + .clrn(input_aset), + .ena(inclocken_wire), + .q(ddr_input[0]) + ); + + fiftyfivenm_ff input_cell_h ( + .clk(~inclock_wire), + .d(buf_in), + .clrn(input_aset), + .ena(inclocken_wire), + .q(ddr_input[1]) + ); + + end + end + else if (REGISTER_MODE == "single-register") + begin: in_path_sdr + reg reg_data_in /* synthesis altera_attribute="FAST_INPUT_REGISTER=on" */; + always @(posedge inclock_wire) begin + reg_data_in <= buf_in; + end + assign ddr_input[0] = reg_data_in; + end + else + begin: in_path_reg_none + assign ddr_input[0] = buf_in; + end + + assign dout[DATA_SIZE - 1:0] = ddr_input[DATA_SIZE - 1:0]; + + end + endgenerate + + generate + if (PIN_TYPE == "output" || PIN_TYPE == "bidir") + begin + if(BUFFER_TYPE == "pseudo_differential") + begin: pseudo_diff_output_buf + + wire wire_pseudo_diff_o; + wire wire_pseudo_diff_o_bar; + + fiftyfivenm_io_obuf + #( + .bus_hold(BUS_HOLD), + .open_drain_output(OPEN_DRAIN_OUTPUT) + ) obuf_a ( + .i(wire_pseudo_diff_o), + .oe(~oe_out), + .o(pad), + .obar() + `ifndef ALTERA_RESERVED_QIS + , + .seriesterminationcontrol(16'b0), + .devoe(1'b1) + `endif + ); + + fiftyfivenm_io_obuf + #( + .bus_hold(BUS_HOLD), + .open_drain_output(OPEN_DRAIN_OUTPUT) + ) obuf_a_bar ( + .i(wire_pseudo_diff_o_bar), + .oe(~oe_out), + .o(pad_b), + .obar() + `ifndef ALTERA_RESERVED_QIS + , + .seriesterminationcontrol(16'b0), + .devoe(1'b1) + `endif + ); + + fiftyfivenm_pseudo_diff_out pseudo_diff_a + ( + .i(din_ddr), + .o(wire_pseudo_diff_o), + .obar(wire_pseudo_diff_o_bar) + ); + + + + end + else if (BUFFER_TYPE == "true_differential") + begin: true_diff_output_buf + fiftyfivenm_io_obuf + #( + .bus_hold(BUS_HOLD), + .open_drain_output(OPEN_DRAIN_OUTPUT) + ) obuf ( + .i(din_ddr), + .oe(~oe_out), + .o(pad), + .obar(pad_b) + `ifndef ALTERA_RESERVED_QIS + , + .seriesterminationcontrol(16'b0), + .devoe(1'b1) + `endif + ); + end + else + begin: output_buf + fiftyfivenm_io_obuf + #( + .bus_hold(BUS_HOLD), + .open_drain_output(OPEN_DRAIN_OUTPUT) + ) obuf ( + .i(din_ddr), + .oe(~oe_out), + .o(pad), + .obar() + `ifndef ALTERA_RESERVED_QIS + , + .seriesterminationcontrol(16'b0), + .devoe(1'b1) + `endif + ); + end + end + endgenerate + + assign nsleep_in = (ENABLE_NSLEEP_PORT == "true") ? nsleep : 1'b1; + + generate + if (PIN_TYPE == "input" || PIN_TYPE == "bidir") + begin + if(BUFFER_TYPE == "true_differential" || BUFFER_TYPE == "pseudo_differential") + begin: diff_input_buf + if (ENABLE_NSLEEP_PORT == "true") + begin: diff_input_buf_with_nsleep + fiftyfivenm_io_ibuf + #( + .bus_hold(BUS_HOLD) + ) ibuf ( + .i(pad), + .ibar(pad_b), + .o(buf_in), + .nsleep(nsleep_in) + ); + end + else + begin: diff_input_buf_without_nsleep + fiftyfivenm_io_ibuf + #( + .bus_hold(BUS_HOLD) + ) ibuf ( + .i(pad), + .ibar(pad_b), + .o(buf_in) + ); + end + end + else + begin:input_buf + if (ENABLE_NSLEEP_PORT == "true") + begin: input_buf_with_nsleep + fiftyfivenm_io_ibuf + #( + .bus_hold(BUS_HOLD) + ) ibuf ( + .i(pad), + .o(buf_in), + .nsleep(nsleep_in) + `ifndef ALTERA_RESERVED_QIS + , + .ibar(1'b0) + `endif + ); + end + else + begin: input_buf_without_nsleep + fiftyfivenm_io_ibuf + #( + .bus_hold(BUS_HOLD) + ) ibuf ( + .i(pad), + .o(buf_in) + `ifndef ALTERA_RESERVED_QIS + , + .ibar(1'b0) + `endif + ); + end + end + end + endgenerate + + generate + if (PIN_TYPE == "output") + begin + assign dout = {DATA_SIZE{1'b0}}; + end + + if (PIN_TYPE == "output" || REGISTER_MODE != "ddr" || USE_ENHANCED_DDR_HIO_REGISTER == "false") + begin + assign fr_clock = 1'b0; + end + + if (PIN_TYPE == "input" || PIN_TYPE == "output" || REGISTER_MODE != "ddr" || ENABLE_PHASE_DETECTOR_FOR_CK == "false") + begin + assign mimic_clock = 1'b0; + end + endgenerate + +endmodule + +module altera_gpio_lite( + inclock, + outclock, + inclocken, + outclocken, + oe, + din, + dout, + pad_io, + pad_io_b, + pad_in, + pad_in_b, + pad_out, + pad_out_b, + aset, + aclr, + phy_mem_clock, + sclr, + hr_clock, + fr_clock, + invert_hr_clock, + mimic_clock, + nsleep +); + + parameter PIN_TYPE = "output"; + parameter BUFFER_TYPE = "single-ended"; + parameter REGISTER_MODE = "bypass"; + parameter SIZE = 4; + parameter ASYNC_MODE = "none"; + parameter SYNC_MODE = "none"; + parameter BUS_HOLD = "false"; + parameter SET_REGISTER_OUTPUTS_HIGH = "false"; + parameter INVERT_OUTPUT = "false"; + parameter INVERT_INPUT_CLOCK = "false"; + parameter INVERT_OUTPUT_CLOCK = "false"; + parameter INVERT_OE_INCLOCK = "false"; + parameter USE_ONE_REG_TO_DRIVE_OE = "false"; + parameter USE_DDIO_REG_TO_DRIVE_OE = "false"; + parameter OPEN_DRAIN_OUTPUT = "false"; + parameter USE_ADVANCED_DDR_FEATURES = "false"; + parameter USE_ADVANCED_DDR_FEATURES_FOR_INPUT_ONLY = "false"; + parameter INVERT_CLKDIV_INPUT_CLOCK = "false"; + parameter ENABLE_HR_CLOCK = "false"; + parameter ENABLE_OE_HALF_CYCLE_DELAY = "true"; + parameter ENABLE_OE_PORT = "false"; + parameter ENABLE_CLOCK_ENA_PORT = "false"; + parameter ENABLE_PHASE_INVERT_CTRL_PORT = "false"; + parameter ENABLE_PHASE_DETECTOR_FOR_CK = "false"; + parameter ENABLE_NSLEEP_PORT = "false"; + + localparam USE_ENHANCED_DDR_HIO_REGISTER = USE_ADVANCED_DDR_FEATURES; + localparam BYPASS_THREE_QUARTER_REGISTER = (USE_ADVANCED_DDR_FEATURES == "true") ? "false" : "true"; + localparam DATA_SIZE = (REGISTER_MODE == "ddr") ? 2 : 1; + + input inclock; + input outclock; + input inclocken; + input outclocken; + input [SIZE - 1:0] oe; + input [SIZE - 1:0] nsleep; + input [SIZE * DATA_SIZE - 1:0] din; + output [SIZE * DATA_SIZE - 1:0] dout; + inout [SIZE - 1:0] pad_io; + inout [SIZE - 1:0] pad_io_b; + input [SIZE - 1:0] pad_in; + input [SIZE - 1:0] pad_in_b; + output [SIZE - 1:0] pad_out; + output [SIZE - 1:0] pad_out_b; + input aset; + input aclr; + input sclr; + input phy_mem_clock; + input invert_hr_clock; + output [SIZE - 1:0] fr_clock; + output wire hr_clock; + output [SIZE - 1:0] mimic_clock; + + wire [SIZE * DATA_SIZE - 1:0] din_reordered; + wire [SIZE * DATA_SIZE - 1:0] dout_reordered; + wire aclr_aset_wire; + wire sclr_wire; + wire [SIZE - 1:0] pad_io; + wire [SIZE - 1:0] pad_io_b; + + + assign aclr_aset_wire = (ASYNC_MODE == "clear") ? aclr : (ASYNC_MODE == "preset") ? aset : 1'b1; + assign sclr_wire = (SYNC_MODE == "clear") ? sclr : 1'b0; + + generate + if (PIN_TYPE == "input") + begin + assign pad_io = pad_in; + assign pad_io_b = pad_in_b; + assign pad_out = {SIZE{1'b0}}; + assign pad_out_b = {SIZE{1'b0}}; + end + else if (PIN_TYPE == "output") + begin + assign pad_out = pad_io; + assign pad_out_b = pad_io_b; + end + else begin + assign pad_out = {SIZE{1'b0}}; + assign pad_out_b = {SIZE{1'b0}}; + end + endgenerate + + genvar j, k; + generate + begin : reorder + for(j = 0; j < SIZE ; j = j + 1) begin : j_loop + for(k = 0; k < DATA_SIZE; k = k + 1) begin : k_d_loop + assign din_reordered[j * DATA_SIZE + k] = din[j + k * SIZE]; + assign dout[j + k * SIZE] = dout_reordered[j * DATA_SIZE + k]; + end + end + end + endgenerate + + genvar i; + generate + begin : gpio_one_bit + for(i = 0 ; i < SIZE ; i = i + 1) begin : i_loop + wire oe_wire; + wire nsleep_wire; + + + assign oe_wire = (PIN_TYPE == "output" && ENABLE_OE_PORT == "false") ? 1'b1 : + (PIN_TYPE == "input") ? 1'b0 : oe[i]; + + + assign nsleep_wire = (PIN_TYPE == "input" && ENABLE_NSLEEP_PORT == "false") ? 1'b1 : + (PIN_TYPE == "output") ? 1'b0 : nsleep[i]; + + altgpio_one_bit #( + .PIN_TYPE(PIN_TYPE), + .BUFFER_TYPE(BUFFER_TYPE), + .REGISTER_MODE(REGISTER_MODE), + .ASYNC_MODE(ASYNC_MODE), + .SYNC_MODE(SYNC_MODE), + .BUS_HOLD(BUS_HOLD), + .SET_REGISTER_OUTPUTS_HIGH(SET_REGISTER_OUTPUTS_HIGH), + .USE_ENHANCED_DDR_HIO_REGISTER(USE_ENHANCED_DDR_HIO_REGISTER), + .USE_ADVANCED_DDR_FEATURES_FOR_INPUT_ONLY(USE_ADVANCED_DDR_FEATURES_FOR_INPUT_ONLY), + .BYPASS_THREE_QUARTER_REGISTER(BYPASS_THREE_QUARTER_REGISTER), + .INVERT_OUTPUT(INVERT_OUTPUT), + .INVERT_INPUT_CLOCK(INVERT_INPUT_CLOCK), + .INVERT_OUTPUT_CLOCK(INVERT_OUTPUT_CLOCK), + .INVERT_OE_INCLOCK(INVERT_OE_INCLOCK), + .USE_ONE_REG_TO_DRIVE_OE(USE_ONE_REG_TO_DRIVE_OE), + .USE_DDIO_REG_TO_DRIVE_OE(USE_DDIO_REG_TO_DRIVE_OE), + .OPEN_DRAIN_OUTPUT(OPEN_DRAIN_OUTPUT), + .ENABLE_OE_HALF_CYCLE_DELAY(ENABLE_OE_HALF_CYCLE_DELAY), + .ENABLE_CLOCK_ENA_PORT(ENABLE_CLOCK_ENA_PORT), + .ENABLE_HR_CLOCK(ENABLE_HR_CLOCK), + .ENABLE_PHASE_DETECTOR_FOR_CK(ENABLE_PHASE_DETECTOR_FOR_CK), + .ENABLE_NSLEEP_PORT(ENABLE_NSLEEP_PORT) + ) altgpio_bit_i ( + .inclock(inclock), + .outclock(outclock), + .phy_mem_clock(phy_mem_clock), + .inclocken(inclocken), + .outclocken(outclocken), + .oe(oe_wire), + .din(din_reordered[(i + 1) * DATA_SIZE - 1 : i * DATA_SIZE]), + .dout(dout_reordered[(i + 1) * DATA_SIZE - 1 : i * DATA_SIZE]), + .pad(pad_io[i]), + .pad_b(pad_io_b[i]), + .aset(aclr_aset_wire), + .sclr(sclr_wire), + .fr_clock(fr_clock[i]), + .hr_clock(hr_clock), + .mimic_clock(mimic_clock[i]), + .nsleep(nsleep_wire) + ); + end + end + endgenerate + + generate + if ((PIN_TYPE == "input" || PIN_TYPE == "bidir") && (ENABLE_HR_CLOCK == "true")) + begin + if (ENABLE_PHASE_INVERT_CTRL_PORT == "true") + begin + if (SYNC_MODE == "clear") + begin : clock_divider_sync_mode_invert_hr_clock + fiftyfivenm_io_clock_divider + #( + .invert_input_clock_phase(INVERT_CLKDIV_INPUT_CLOCK), + .use_phasectrlin(ENABLE_PHASE_INVERT_CTRL_PORT), + .sync_mode(SYNC_MODE) + ) io_clkdiv ( + .clk(inclock), + .phaseinvertctrl(invert_hr_clock), + .sreset(sclr_wire), + .clkout(hr_clock) + ); + end + else + begin : clock_divider_invert_hr_clock + fiftyfivenm_io_clock_divider + #( + .invert_input_clock_phase(INVERT_CLKDIV_INPUT_CLOCK), + .use_phasectrlin(ENABLE_PHASE_INVERT_CTRL_PORT), + .sync_mode(SYNC_MODE) + ) io_clkdiv ( + .clk(inclock), + .phaseinvertctrl(invert_hr_clock), + .clkout(hr_clock) + `ifndef ALTERA_RESERVED_QIS + , + .sreset(1'b0) + `endif + ); + end + end + else + begin + if (SYNC_MODE == "clear") + begin : clock_divider_sync_mode + fiftyfivenm_io_clock_divider + #( + .invert_input_clock_phase(INVERT_CLKDIV_INPUT_CLOCK), + .use_phasectrlin(ENABLE_PHASE_INVERT_CTRL_PORT), + .sync_mode(SYNC_MODE) + ) io_clkdiv ( + .clk(inclock), + .sreset(sclr_wire), + .clkout(hr_clock) + `ifndef ALTERA_RESERVED_QIS + , + .phaseinvertctrl(1'b0) + `endif + ); + end + else + begin : clock_divider + fiftyfivenm_io_clock_divider + #( + .invert_input_clock_phase(INVERT_CLKDIV_INPUT_CLOCK), + .use_phasectrlin(ENABLE_PHASE_INVERT_CTRL_PORT), + .sync_mode(SYNC_MODE) + ) io_clkdiv ( + .clk(inclock), + .clkout(hr_clock) + `ifndef ALTERA_RESERVED_QIS + , + .sreset(1'b0), + .phaseinvertctrl(1'b0) + `endif + ); + end + end + end + else begin + assign hr_clock = 1'b0; + end + endgenerate + +endmodule diff --git a/fw/rtl/memory/memory_flash.sv b/fw/rtl/memory/memory_flash.sv new file mode 100644 index 0000000..5c1d398 --- /dev/null +++ b/fw/rtl/memory/memory_flash.sv @@ -0,0 +1,55 @@ +module memory_flash ( + if_system.sys sys, + if_n64_bus bus +); + + logic flash_enable; + logic flash_request; + logic flash_busy; + logic flash_ack; + logic [31:0] flash_rdata; + + logic dummy_ack; + + always_comb begin + flash_enable = bus.address < 32'h10016800; + + bus.ack = flash_ack | dummy_ack; + + bus.rdata = 16'd0; + if (bus.ack && flash_enable) begin + if (bus.address[1]) bus.rdata = {flash_rdata[23:16], flash_rdata[31:24]}; + else bus.rdata = {flash_rdata[7:0], flash_rdata[15:8]}; + end + end + + always_ff @(posedge sys.clk) begin + dummy_ack <= 1'b0; + if (sys.reset) begin + flash_request <= 1'b0; + end else begin + if (!flash_busy) begin + flash_request <= 1'b0; + end + if (bus.request) begin + if (flash_enable) begin + flash_request <= 1'b1; + end else begin + dummy_ack <= 1'b1; + end + end + end + end + + intel_flash intel_flash_inst ( + .clock(sys.clk), + .reset_n(~sys.reset), + .avmm_data_addr(bus.address[31:2]), + .avmm_data_read(flash_request || (bus.request && flash_enable)), + .avmm_data_readdata(flash_rdata), + .avmm_data_waitrequest(flash_busy), + .avmm_data_readdatavalid(flash_ack), + .avmm_data_burstcount(2'd1) + ); + +endmodule diff --git a/fw/rtl/memory/memory_sdram.sv b/fw/rtl/memory/memory_sdram.sv index e69de29..787d58a 100644 --- a/fw/rtl/memory/memory_sdram.sv +++ b/fw/rtl/memory/memory_sdram.sv @@ -0,0 +1,66 @@ +module memory_sdram ( + if_system sys, + if_n64_bus bus, + + output sdram_clk, + output sdram_cs, + output sdram_ras, + output sdram_cas, + output sdram_we, + output [1:0] sdram_ba, + output [12:0] sdram_a, + inout [15:0] sdram_dq +); + + intel_gpio_ddro sdram_clk_ddro ( + .outclock(sys.sdram.sdram_clk), + .din({1'b0, 1'b1}), + .pad_out(sdram_clk) + ); + + parameter bit [2:0] CAS_LATENCY = 3'd2; + + localparam bit [12:0] MODE_REGISTER = {2'b00, 1'b0, 1'b0, 2'b00, CAS_LATENCY, 1'b0, 3'b000}; + + typedef enum bit [3:0] { + CMD_DESL = 4'b1111; + CMD_NOP = 4'b0111; + CMD_READ = 4'b0101; + CMD_WRITE = 4'b0100; + CMD_ACT = 4'b0011; + CMD_PRE = 4'b0010; + CMD_REF = 4'b0001; + CMD_MRS = 4'b0000; + } e_sdram_cmd; + + e_sdram_cmd sdram_next_cmd; + logic [15:0] sdram_dq_input; + logic [15:0] sdram_dq_output; + logic sdram_dq_output_enable; + + always_ff @(posedge sys.clk) begin + {o_sdram_cs, o_sdram_ras, o_sdram_cas, o_sdram_we} <= 4'(sdram_next_cmd); + + {sdram_ba, sdram_a} <= 15'd0; + + sdram_dq_input <= sdram_dq; + sdram_dq_output <= bus.wdata; + + sdram_dq_output_enable <= 1'b0; + + case (sdram_next_cmd) + CMD_READ, CMD_WRITE: begin + {sdram_ba, sdram_a} <= {bus.address[25:24], 3'b000, bus.address[10:1]}; + sdram_dq_output_enable <= sdram_next_cmd == CMD_WRITE; + end + CMD_ACT: {sdram_ba, sdram_a} <= bus.address[25:11]; + CMD_PRE: {sdram_ba, sdram_a} <= {2'b00, 2'b00, 1'b1, 10'd0}; + CMD_MRS: {sdram_ba, sdram_a} <= MODE_REGISTER; + endcase + end + + always_comb begin + sdram_dq = sdram_dq_output_enable ? sdram_dq_output : 16'hZZZZ; + end + +endmodule diff --git a/fw/rtl/memory/sdram.vhd b/fw/rtl/memory/sdram.vhd new file mode 100644 index 0000000..921f49d --- /dev/null +++ b/fw/rtl/memory/sdram.vhd @@ -0,0 +1,445 @@ +-- __ __ __ __ __ __ +-- /\ "-.\ \ /\ \/\ \ /\ \ /\ \ +-- \ \ \-. \ \ \ \_\ \ \ \ \____ \ \ \____ +-- \ \_\\"\_\ \ \_____\ \ \_____\ \ \_____\ +-- \/_/ \/_/ \/_____/ \/_____/ \/_____/ +-- ______ ______ __ ______ ______ ______ +-- /\ __ \ /\ == \ /\ \ /\ ___\ /\ ___\ /\__ _\ +-- \ \ \/\ \ \ \ __< _\_\ \ \ \ __\ \ \ \____ \/_/\ \/ +-- \ \_____\ \ \_____\ /\_____\ \ \_____\ \ \_____\ \ \_\ +-- \/_____/ \/_____/ \/_____/ \/_____/ \/_____/ \/_/ +-- +-- https://joshbassett.info +-- https://twitter.com/nullobject +-- https://github.com/nullobject +-- +-- Copyright (c) 2020 Josh Bassett +-- +-- Permission is hereby granted, free of charge, to any person obtaining a copy +-- of this software and associated documentation files (the "Software"), to deal +-- in the Software without restriction, including without limitation the rights +-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +-- copies of the Software, and to permit persons to whom the Software is +-- furnished to do so, subject to the following conditions: +-- +-- The above copyright notice and this permission notice shall be included in all +-- copies or substantial portions of the Software. +-- +-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +-- SOFTWARE. + +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; +use ieee.math_real.all; + +-- This SDRAM controller provides a symmetric 32-bit synchronous read/write +-- interface for a 16Mx16-bit SDRAM chip (e.g. AS4C16M16SA-6TCN, IS42S16400F, +-- etc.). +entity sdram is + generic ( + -- clock frequency (in MHz) + -- + -- This value must be provided, as it is used to calculate the number of + -- clock cycles required for the other timing values. + CLK_FREQ : real := 100.0; + + -- 32-bit controller interface + ADDR_WIDTH : natural := 25; + DATA_WIDTH : natural := 32; + + -- SDRAM interface + SDRAM_ADDR_WIDTH : natural := 13; + SDRAM_DATA_WIDTH : natural := 16; + SDRAM_COL_WIDTH : natural := 10; + SDRAM_ROW_WIDTH : natural := 13; + SDRAM_BANK_WIDTH : natural := 2; + + -- The delay in clock cycles, between the start of a read command and the + -- availability of the output data. + CAS_LATENCY : natural := 2; -- 2=below 133MHz, 3=above 133MHz + + -- The number of 16-bit words to be bursted during a read/write. + BURST_LENGTH : natural := 2; + + -- timing values (in nanoseconds) + -- + -- These values can be adjusted to match the exact timing of your SDRAM + -- chip (refer to the datasheet). + T_DESL : real := 100000.0; -- startup delay + T_MRD : real := 14.0; -- mode register cycle time + T_RC : real := 60.0; -- row cycle time + T_RCD : real := 15.0; -- RAS to CAS delay + T_RP : real := 15.0; -- precharge to activate delay + T_WR : real := 22.0; -- write recovery time + T_REFI : real := 7800.0 -- average refresh interval + ); + port ( + -- reset + reset : in std_logic := '0'; + + -- clock + clk : in std_logic; + + -- address bus + addr : in unsigned(ADDR_WIDTH-1 downto 0); + + -- input data bus + data : in std_logic_vector(DATA_WIDTH-1 downto 0); + + -- When the write enable signal is asserted, a write operation will be performed. + we : in std_logic; + + -- When the request signal is asserted, an operation will be performed. + req : in std_logic; + + -- The acknowledge signal is asserted by the SDRAM controller when + -- a request has been accepted. + ack : out std_logic; + + -- The valid signal is asserted when there is a valid word on the output + -- data bus. + valid : out std_logic; + + -- output data bus + q : out std_logic_vector(DATA_WIDTH-1 downto 0); + + -- SDRAM interface (e.g. AS4C16M16SA-6TCN, IS42S16400F, etc.) + sdram_a : out unsigned(SDRAM_ADDR_WIDTH-1 downto 0); + sdram_ba : out unsigned(SDRAM_BANK_WIDTH-1 downto 0); + sdram_dq : inout std_logic_vector(SDRAM_DATA_WIDTH-1 downto 0); + sdram_cke : out std_logic; + sdram_cs_n : out std_logic; + sdram_ras_n : out std_logic; + sdram_cas_n : out std_logic; + sdram_we_n : out std_logic; + sdram_dqml : out std_logic; + sdram_dqmh : out std_logic + ); +end sdram; + +architecture arch of sdram is + function ilog2(n : natural) return natural is + begin + return natural(ceil(log2(real(n)))); + end ilog2; + + subtype command_t is std_logic_vector(3 downto 0); + + -- commands + constant CMD_DESELECT : command_t := "1---"; + constant CMD_LOAD_MODE : command_t := "0000"; + constant CMD_AUTO_REFRESH : command_t := "0001"; + constant CMD_PRECHARGE : command_t := "0010"; + constant CMD_ACTIVE : command_t := "0011"; + constant CMD_WRITE : command_t := "0100"; + constant CMD_READ : command_t := "0101"; + constant CMD_STOP : command_t := "0110"; + constant CMD_NOP : command_t := "0111"; + + -- the ordering of the accesses within a burst + constant BURST_TYPE : std_logic := '0'; -- 0=sequential, 1=interleaved + + -- the write burst mode enables bursting for write operations + constant WRITE_BURST_MODE : std_logic := '0'; -- 0=burst, 1=single + + -- the value written to the mode register to configure the memory + constant MODE_REG : unsigned(SDRAM_ADDR_WIDTH-1 downto 0) := ( + "000" & + WRITE_BURST_MODE & + "00" & + to_unsigned(CAS_LATENCY, 3) & + BURST_TYPE & + to_unsigned(ilog2(BURST_LENGTH), 3) + ); + + -- calculate the clock period (in nanoseconds) + constant CLK_PERIOD : real := 1.0/CLK_FREQ*1000.0; + + -- the number of clock cycles to wait before initialising the device + constant INIT_WAIT : natural := natural(ceil(T_DESL/CLK_PERIOD)); + + -- the number of clock cycles to wait while a LOAD MODE command is being + -- executed + constant LOAD_MODE_WAIT : natural := natural(ceil(T_MRD/CLK_PERIOD)); + + -- the number of clock cycles to wait while an ACTIVE command is being + -- executed + constant ACTIVE_WAIT : natural := natural(ceil(T_RCD/CLK_PERIOD)); + + -- the number of clock cycles to wait while a REFRESH command is being + -- executed + constant REFRESH_WAIT : natural := natural(ceil(T_RC/CLK_PERIOD)); + + -- the number of clock cycles to wait while a PRECHARGE command is being + -- executed + constant PRECHARGE_WAIT : natural := natural(ceil(T_RP/CLK_PERIOD)); + + -- the number of clock cycles to wait while a READ command is being executed + constant READ_WAIT : natural := CAS_LATENCY+BURST_LENGTH; + + -- the number of clock cycles to wait while a WRITE command is being executed + constant WRITE_WAIT : natural := BURST_LENGTH+natural(ceil((T_WR+T_RP)/CLK_PERIOD)); + + -- the number of clock cycles before the memory controller needs to refresh + -- the SDRAM + constant REFRESH_INTERVAL : natural := natural(floor(T_REFI/CLK_PERIOD))-10; + + type state_t is (INIT, MODE, IDLE, ACTIVE, READ, WRITE, REFRESH); + + -- state signals + signal state, next_state : state_t; + + -- command signals + signal cmd, next_cmd : command_t := CMD_NOP; + + -- control signals + signal start : std_logic; + signal load_mode_done : std_logic; + signal active_done : std_logic; + signal refresh_done : std_logic; + signal first_word : std_logic; + signal read_done : std_logic; + signal write_done : std_logic; + signal should_refresh : std_logic; + + -- counters + signal wait_counter : natural range 0 to 16383; + signal refresh_counter : natural range 0 to 1023; + + -- registers + signal addr_reg : unsigned(SDRAM_COL_WIDTH+SDRAM_ROW_WIDTH+SDRAM_BANK_WIDTH-1 downto 0); + signal data_reg : std_logic_vector(DATA_WIDTH-1 downto 0); + signal we_reg : std_logic; + signal q_reg : std_logic_vector(DATA_WIDTH-1 downto 0); + + -- aliases to decode the address register + alias col : unsigned(SDRAM_COL_WIDTH-1 downto 0) is addr_reg(SDRAM_COL_WIDTH-1 downto 0); + alias row : unsigned(SDRAM_ROW_WIDTH-1 downto 0) is addr_reg(SDRAM_COL_WIDTH+SDRAM_ROW_WIDTH-1 downto SDRAM_COL_WIDTH); + alias bank : unsigned(SDRAM_BANK_WIDTH-1 downto 0) is addr_reg(SDRAM_COL_WIDTH+SDRAM_ROW_WIDTH+SDRAM_BANK_WIDTH-1 downto SDRAM_COL_WIDTH+SDRAM_ROW_WIDTH); +begin + -- state machine + fsm : process (state, wait_counter, req, we_reg, load_mode_done, active_done, refresh_done, read_done, write_done, should_refresh) + begin + next_state <= state; + + -- default to a NOP command + next_cmd <= CMD_NOP; + + case state is + -- execute the initialisation sequence + when INIT => + if wait_counter = 0 then + next_cmd <= CMD_DESELECT; + elsif wait_counter = INIT_WAIT-1 then + next_cmd <= CMD_PRECHARGE; + elsif wait_counter = INIT_WAIT+PRECHARGE_WAIT-1 then + next_cmd <= CMD_AUTO_REFRESH; + elsif wait_counter = INIT_WAIT+PRECHARGE_WAIT+REFRESH_WAIT-1 then + next_cmd <= CMD_AUTO_REFRESH; + elsif wait_counter = INIT_WAIT+PRECHARGE_WAIT+REFRESH_WAIT+REFRESH_WAIT-1 then + next_state <= MODE; + next_cmd <= CMD_LOAD_MODE; + end if; + + -- load the mode register + when MODE => + if load_mode_done = '1' then + next_state <= IDLE; + end if; + + -- wait for a read/write request + when IDLE => + if should_refresh = '1' then + next_state <= REFRESH; + next_cmd <= CMD_AUTO_REFRESH; + elsif req = '1' then + next_state <= ACTIVE; + next_cmd <= CMD_ACTIVE; + end if; + + -- activate the row + when ACTIVE => + if active_done = '1' then + if we_reg = '1' then + next_state <= WRITE; + next_cmd <= CMD_WRITE; + else + next_state <= READ; + next_cmd <= CMD_READ; + end if; + end if; + + -- execute a read command + when READ => + if read_done = '1' then + if should_refresh = '1' then + next_state <= REFRESH; + next_cmd <= CMD_AUTO_REFRESH; + elsif req = '1' then + next_state <= ACTIVE; + next_cmd <= CMD_ACTIVE; + else + next_state <= IDLE; + end if; + end if; + + -- execute a write command + when WRITE => + if write_done = '1' then + if should_refresh = '1' then + next_state <= REFRESH; + next_cmd <= CMD_AUTO_REFRESH; + elsif req = '1' then + next_state <= ACTIVE; + next_cmd <= CMD_ACTIVE; + else + next_state <= IDLE; + end if; + end if; + + -- execute an auto refresh + when REFRESH => + if refresh_done = '1' then + if req = '1' then + next_state <= ACTIVE; + next_cmd <= CMD_ACTIVE; + else + next_state <= IDLE; + end if; + end if; + end case; + end process; + + -- latch the next state + latch_next_state : process (clk, reset) + begin + if reset = '1' then + state <= INIT; + cmd <= CMD_NOP; + elsif rising_edge(clk) then + state <= next_state; + cmd <= next_cmd; + end if; + end process; + + -- the wait counter is used to hold the current state for a number of clock + -- cycles + update_wait_counter : process (clk, reset) + begin + if reset = '1' then + wait_counter <= 0; + elsif rising_edge(clk) then + if state /= next_state then -- state changing + wait_counter <= 0; + else + wait_counter <= wait_counter + 1; + end if; + end if; + end process; + + -- the refresh counter is used to periodically trigger a refresh operation + update_refresh_counter : process (clk, reset) + begin + if reset = '1' then + refresh_counter <= 0; + elsif rising_edge(clk) then + if state = REFRESH and wait_counter = 0 then + refresh_counter <= 0; + else + refresh_counter <= refresh_counter + 1; + end if; + end if; + end process; + + -- latch the rquest + latch_request : process (clk) + begin + if rising_edge(clk) then + if start = '1' then + -- we need to multiply the address by two, because we are converting + -- from a 32-bit controller address to a 16-bit SDRAM address + addr_reg <= shift_left(resize(addr, addr_reg'length), 1); + data_reg <= data; + we_reg <= we; + end if; + end if; + end process; + + -- latch the output data as it's bursted from the SDRAM + latch_sdram_data : process (clk) + begin + if rising_edge(clk) then + valid <= '0'; + + if state = READ then + if first_word = '1' then + q_reg(31 downto 16) <= sdram_dq; + elsif read_done = '1' then + q_reg(15 downto 0) <= sdram_dq; + valid <= '1'; + end if; + end if; + end if; + end process; + + -- set wait signals + load_mode_done <= '1' when wait_counter = LOAD_MODE_WAIT-1 else '0'; + active_done <= '1' when wait_counter = ACTIVE_WAIT-1 else '0'; + refresh_done <= '1' when wait_counter = REFRESH_WAIT-1 else '0'; + first_word <= '1' when wait_counter = CAS_LATENCY else '0'; + read_done <= '1' when wait_counter = READ_WAIT-1 else '0'; + write_done <= '1' when wait_counter = WRITE_WAIT-1 else '0'; + + -- the SDRAM should be refreshed when the refresh interval has elapsed + should_refresh <= '1' when refresh_counter >= REFRESH_INTERVAL-1 else '0'; + + -- a new request is only allowed at the end of the IDLE, READ, WRITE, and + -- REFRESH states + start <= '1' when (state = IDLE) or + (state = READ and read_done = '1') or + (state = WRITE and write_done = '1') or + (state = REFRESH and refresh_done = '1') else '0'; + + -- assert the acknowledge signal at the beginning of the ACTIVE state + ack <= '1' when state = ACTIVE and wait_counter = 0 else '0'; + + -- set output data + q <= q_reg; + + -- deassert the clock enable at the beginning of the INIT state + sdram_cke <= '0' when state = INIT and wait_counter = 0 else '1'; + + -- set SDRAM control signals + (sdram_cs_n, sdram_ras_n, sdram_cas_n, sdram_we_n) <= cmd; + + -- set SDRAM bank + with state select + sdram_ba <= + bank when ACTIVE, + bank when READ, + bank when WRITE, + (others => '0') when others; + + -- set SDRAM address + with state select + sdram_a <= + "0010000000000" when INIT, + MODE_REG when MODE, + row when ACTIVE, + "0010" & col when READ, -- auto precharge + "0010" & col when WRITE, -- auto precharge + (others => '0') when others; + + -- decode the next 16-bit word from the write buffer + sdram_dq <= data_reg((BURST_LENGTH-wait_counter)*SDRAM_DATA_WIDTH-1 downto (BURST_LENGTH-wait_counter-1)*SDRAM_DATA_WIDTH) when state = WRITE else (others => 'Z'); + + -- set SDRAM data mask + sdram_dqmh <= '0'; + sdram_dqml <= '0'; +end architecture arch; diff --git a/fw/rtl/n64/n64_bus.sv b/fw/rtl/n64/n64_bus.sv new file mode 100644 index 0000000..c4080f8 --- /dev/null +++ b/fw/rtl/n64/n64_bus.sv @@ -0,0 +1,56 @@ +interface if_n64_bus (); + + localparam sc64::e_n64_id NUM_DEVICES = sc64::__ID_N64_END; + + sc64::e_n64_id id; + logic request; + logic ack; + logic write; + logic [31:0] address; + logic [15:0] wdata; + logic [15:0] rdata; + + logic device_ack [(NUM_DEVICES - 1):0]; + logic [15:0] device_rdata [(NUM_DEVICES - 1):0]; + + always_comb begin + ack = 1'b0; + rdata = 16'd0; + + for (integer i = 0; i < NUM_DEVICES; i++) begin + ack = ack | device_ack[i]; + rdata = rdata | device_rdata[i]; + end + end + + modport n64 ( + output id, + output request, + input ack, + output write, + output address, + output wdata, + input rdata + ); + + genvar n; + generate + for (n = 0; n < NUM_DEVICES; n++) begin : at + logic device_request; + + always_comb begin + device_request = request && id == sc64::e_n64_id'(n); + end + + modport device ( + input .request(device_request), + output .ack(device_ack[n]), + input .write(write), + input .address(address), + input .wdata(wdata), + output .rdata(device_rdata[n]) + ); + end + endgenerate + +endinterface diff --git a/fw/rtl/n64/n64_pi.sv b/fw/rtl/n64/n64_pi.sv index 0a85970..b053e60 100644 --- a/fw/rtl/n64/n64_pi.sv +++ b/fw/rtl/n64/n64_pi.sv @@ -1,18 +1,13 @@ module n64_pi ( if_system.sys sys, + if_config.pi cfg, + if_n64_bus.n64 bus, input n64_pi_alel, input n64_pi_aleh, input n64_pi_read, input n64_pi_write, - inout [15:0] n64_pi_ad, - - output request, - input ack, - output write, - output [31:0] address, - output [15:0] wdata, - input [15:0] rdata + inout [15:0] n64_pi_ad ); // Control signals input synchronization @@ -35,7 +30,6 @@ module n64_pi ( logic pi_read; logic pi_read_delayed; logic pi_write; - logic pi_write_delayed; always_comb begin pi_reset = sys.n64_hard_reset; @@ -43,8 +37,7 @@ module n64_pi ( pi_alel = n64_pi_alel_ff[2]; pi_read = n64_pi_read_ff[1]; pi_read_delayed = n64_pi_read_ff[2]; - pi_write = n64_pi_write_ff[1]; - pi_write_delayed = n64_pi_write_ff[2]; + pi_write = n64_pi_write_ff[2]; end // PI bus state and event generator @@ -91,10 +84,12 @@ module n64_pi ( logic [15:0] n64_pi_ad_output_data_buffer; logic n64_pi_ad_output_enable; logic n64_pi_ad_output_enable_data; + + logic n64_pi_address_valid; always_comb begin n64_pi_ad = n64_pi_ad_output_enable ? n64_pi_ad_output : 16'hZZZZ; - n64_pi_ad_output_enable_data = !pi_reset && pi_mode == PI_MODE_VALID && !pi_read_delayed; + n64_pi_ad_output_enable_data = !pi_reset && pi_mode == PI_MODE_VALID && n64_pi_address_valid && !pi_read_delayed; end always_ff @(posedge sys.clk) begin @@ -118,34 +113,81 @@ module n64_pi ( logic pending_operation; logic pending_write; + sc64::e_n64_id next_id; + logic [25:0] next_offset; + always_ff @(posedge sys.clk) begin - request <= 1'b0; + if (aleh_op) begin + n64_pi_address_valid <= 1'b0; + next_offset <= 32'd0; + if (cfg.dd_enabled) begin + if (n64_pi_ad_input == 16'h0500) begin + n64_pi_address_valid <= 1'b1; + next_id <= sc64::ID_N64_DDREGS; + end + if (n64_pi_ad_input >= 16'h0600 && n64_pi_ad_input < 16'h0640) begin + n64_pi_address_valid <= 1'b1; + next_id <= sc64::ID_N64_SDRAM; + next_offset <= cfg.dd_offset; + end + end + if (n64_pi_ad_input >= 16'h0800 && n64_pi_ad_input < 16'h0802) begin + if (cfg.sram_enabled) begin + n64_pi_address_valid <= 1'b1; + next_id <= sc64::ID_N64_SDRAM; + next_offset <= cfg.save_offset; + end else if (cfg.flashram_enabled) begin + n64_pi_address_valid <= 1'b1; + next_id <= sc64::ID_N64_FLASHRAM; + if (cfg.flashram_read_mode) begin + next_id <= sc64::ID_N64_SDRAM; + next_offset <= cfg.save_offset; + end + end + end + if (n64_pi_ad_input >= 16'h1000 && n64_pi_ad_input < 16'h1400) begin + n64_pi_address_valid <= 1'b1; + next_id <= cfg.sdram_switch ? sc64::ID_N64_SDRAM : sc64::ID_N64_BOOTLOADER; + end + if (n64_pi_ad_input == 16'h1FB0) begin + n64_pi_address_valid <= 1'b1; + next_id <= sc64::ID_N64_CPU; + end + end + end + + always_ff @(posedge sys.clk) begin + bus.request <= 1'b0; if (sys.reset || sys.n64_hard_reset || sys.n64_soft_reset) begin state <= S_IDLE; - first_operation <= 1'b0; pending_operation <= 1'b0; end else begin case (state) S_IDLE: begin - if (aleh_op) address[31:16] <= n64_pi_ad_input; - if (alel_op) address[15:0] <= {n64_pi_ad_input[15:1], 1'b0}; - if (alel_op || read_op || write_op || pending_operation) begin + if (aleh_op) begin + bus.address[31:16] <= n64_pi_ad_input; + end + if (alel_op) begin + bus.address <= {bus.address[31:16], n64_pi_ad_input[15:1], 1'b0} + next_offset; + end + if (n64_pi_address_valid && (alel_op || read_op || write_op || pending_operation)) begin state <= S_WAIT; - request <= 1'b1; - write <= write_op || (pending_operation && pending_write); + bus.id <= next_id; + bus.request <= 1'b1; + bus.write <= write_op || (pending_operation && pending_write); if (!alel_op && !(first_operation && write_op)) begin - address[31:1] <= address[31:1] + 1'd1; + bus.address[31:1] <= bus.address[31:1] + 1'd1; end - wdata <= n64_pi_ad_input; + bus.wdata <= n64_pi_ad_input; first_operation <= alel_op; end end S_WAIT: begin - if (ack) begin + if (bus.ack) begin state <= S_IDLE; - n64_pi_ad_output_data_buffer <= rdata; + n64_pi_ad_output_data_buffer <= bus.rdata; end if (read_op || write_op) begin pending_operation <= 1'b1; @@ -155,7 +197,6 @@ module n64_pi ( default: begin state <= S_IDLE; - first_operation <= 1'b0; pending_operation <= 1'b0; end endcase diff --git a/fw/rtl/n64/n64_soc.sv b/fw/rtl/n64/n64_soc.sv new file mode 100644 index 0000000..580b7d7 --- /dev/null +++ b/fw/rtl/n64/n64_soc.sv @@ -0,0 +1,57 @@ +module n64_soc ( + if_system sys, + if_config cfg, + + input n64_pi_alel, + input n64_pi_aleh, + input n64_pi_read, + input n64_pi_write, + inout [15:0] n64_pi_ad, + + input n64_si_clk, + inout n64_si_dq, + + output sdram_clk, + output sdram_cs, + output sdram_ras, + output sdram_cas, + output sdram_we, + output [1:0] sdram_ba, + output [12:0] sdram_a, + inout [15:0] sdram_dq +); + + if_n64_bus bus (); + + n64_pi n64_pi_inst ( + .sys(sys), + .cfg(cfg), + .bus(bus), + + .n64_pi_alel(n64_pi_alel), + .n64_pi_aleh(n64_pi_aleh), + .n64_pi_read(n64_pi_read), + .n64_pi_write(n64_pi_write), + .n64_pi_ad(n64_pi_ad) + ); + + memory_sdram memory_sdram_inst ( + .sys(sys), + .bus(bus.at[sc64::ID_N64_SDRAM].device), + + .sdram_clk(sdram_clk), + .sdram_cs(sdram_cs), + .sdram_ras(sdram_ras), + .sdram_cas(sdram_cas), + .sdram_we(sdram_we), + .sdram_ba(sdram_ba), + .sdram_a(sdram_a), + .sdram_dq(sdram_dq) + ); + + memory_flash memory_flash_inst ( + .sys(sys), + .bus(bus.at[sc64::ID_N64_BOOTLOADER].device) + ); + +endmodule diff --git a/fw/rtl/system/config.sv b/fw/rtl/system/config.sv new file mode 100644 index 0000000..d905205 --- /dev/null +++ b/fw/rtl/system/config.sv @@ -0,0 +1,34 @@ +interface if_config (); + + logic sdram_switch; + logic sdram_writable; + logic dd_enabled; + logic sram_enabled; + logic flashram_enabled; + logic flashram_read_mode; + logic [25:0] dd_offset; + logic [25:0] save_offset; + + always_comb begin + sdram_switch = 1'b0; + sdram_writable = 1'b0; + dd_enabled = 1'b1; + sram_enabled = 1'b1; + flashram_enabled = 1'b1; + flashram_read_mode = 1'b1; + dd_offset = 26'h3BE_0000; + save_offset = 26'h3FE_0000; + end + + modport pi ( + input sdram_switch, + input sdram_writable, + input dd_enabled, + input sram_enabled, + input flashram_enabled, + input flashram_read_mode, + input dd_offset, + input save_offset + ); + +endinterface diff --git a/fw/rtl/system/sc64.sv b/fw/rtl/system/sc64.sv new file mode 100644 index 0000000..e88cc01 --- /dev/null +++ b/fw/rtl/system/sc64.sv @@ -0,0 +1,24 @@ +package sc64; + + typedef enum bit [2:0] { + ID_N64_SDRAM, + ID_N64_BOOTLOADER, + ID_N64_FLASHRAM, + ID_N64_DDREGS, + ID_N64_CPU, + __ID_N64_END + } e_n64_id; + + typedef enum bit [3:0] { + ID_CPU_RAM, + ID_CPU_BOOTLOADER, + ID_CPU_GPIO, + ID_CPU_I2C, + ID_CPU_USB, + ID_CPU_UART, + __ID_CPU_END + } e_cpu_id; + + parameter UART_BAUD_RATE = 1_000_000; + +endpackage diff --git a/fw/stp.stp b/fw/stp.stp index 7f2b030..0d06440 100644 --- a/fw/stp.stp +++ b/fw/stp.stp @@ -6,635 +6,417 @@ - + - + - + - + - + - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + - - - - - - - + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + - + - 'if_system:sys|if_system.n64_hard_reset' == low && 'if_system:sys|if_system.n64_soft_reset' == low && 'n64_pi:n64_pi_inst|ack' == rising edge + 'n64_soc:n64_soc_inst|n64_pi:n64_pi_inst|bus.request' == rising edge @@ -650,10 +432,10 @@ trigger;]]> - 1 - 1 + 11 + 11 - 'n64_pi:n64_pi_inst|ack' == high + 'n64_soc:n64_soc_inst|n64_pi:n64_pi_inst|bus.ack' == high @@ -670,7 +452,7 @@ trigger;]]> - 000000000000000000001000000000001000001110110000000000000001000000001000000000000001000000001001000000000000000000001010000000000000000000000000000000000000000000001000000010000000010000000100000000000001000000001000000010000010110000000000000000000000000000001010000010000000010000000100000000000000000000001010000010000000010000000100000000000001000000001010000010000010010000000000000000000000000000001000010010000000010000000100000000000000000000001000010010000000010000000100000000000001000000001000010010000011010000000000000000000000000000001010010010000111100001000000000000000000000000001010010010000111100001000000000000000001000000001010010010000100101000111000000000000000000000001000001010000100100001000010000000000000000000001000001010000100100001000010000000000001000000001000001010000000000000000000000000000000000000001010001010001110001001000010000000000000000000001010001010001110001001000010000000000001000000001010001010000000000011000000000000000000000000001000011010000101000000010010000000000000000000001000011010000101000000010010000000000001000000001000011010001000000011011100000000000000000000001010011010000000000000000000000000000000000000001010011010000000000000000000000000000001000000001010011010000000000000000000000000000000000000001000000110001100100011110111000000000000000000001000000110001100100011110111000000000001000000001000000110000111111001011111000000000000000000001010000110001110101100110111000000000000000000001010000110001110101100110111000000000001000000001010000110000000000000000000000000000000000000001000010110000110101010110111000000000000000000001000010110000110101010110111000000000001000000001000010110000000000010000000000000000000000000001010010110001110101010110111000000000000000000001010010110001110101010110111000000000001000000001010010110000000000001000000000000000000000000001000001110000110101110110111000000000000000000001000001110000110101110110111000000000001000000001000001110000000000011000000000000000000000000001010001110001110101110110111000000000000000000001010001110001110101110110111000000000001000000001010001110000000000000100000000000000000000000001000011110000111100001000000000000000000000000001000011110000111100001000000000000000001000000001000011110000100101000111000000000000000000000001010011110000100100001000010000000000000000000001010011110000100100001000010000000000001000000001010011110000000000000000000000000000000000000001000000001000111100101000000000000000000000000001000000001000111100101000000000000000001000000001000000001000000101001111111000000000000000000001010000001001111100101000000000000000000000000001010000001001111100101000000000000000001000000001010000001000000101000111111000000000000000000001000010001000111100011000000000000000000000000001000010001000111100011000000000000000001000000001000010001000100101000110000000000000000000000001010010001000100100011000110000000000000000000001010010001000100100011000110000000000001000000001010010001000000000000000000000000000000000000001000001001001101100001000000000000000000000000001000001001001101100001000000000000000001000000001000001001000000000000001000000000000000000000001010001001001110101001000010000000000000000000001010001001001110101001000010000000000001000000001010001001000000000010000000000000000000000000001000011001001100100000100000000000000000000000001000011001001100100000100000000000000001000000001000011001000111000000001011000000000000000000001010011001000000000000000000000000000000000000001010011001000000000000000000000000000001000000001010011001000000000000000000000000000000000000001000000101001000100000110001000000000000000000001000000101001000100000110001000000000001000000001000000101001111111111111111000000000000000000001010000101000101000000010001000000000000000000001010000101000101000000010001000000000001000000001010000101001111111011111111000000000000000000001000010101000000000000000000000000000000000000001000010101000000000000000000000000000001000000001000010101000000000000000000000000000000000000001010010101000110101000000010000000000000000000001010010101000110101000000010000000000001000000001010010101000000000001000000000000000000000000001000001101001101100001000000000000000000000000001000001101001101100001000000000000000001000000001000001101000000000010100000000000000000000000001010001101001110101001000010000000000000000000001010001101001110101001000010000000000001000000001010001101000000000011000000000000000000000000001000011101000110101000000010000000000000000000001000011101000110101000000010000000000001000000001000011101000000000000000000000000000000000000001010011101001100100000100000000000000000000000001010011101001100100000100000000000000001000000001010011101000000000010000000000000000000000000001000000011000000000000000000000000000000000000001000000011000000000000000000000000000001000000001000000011000000000000000000000000000000000000001010000011001000100000110001000000000000000000001010000011001000100000110001000000000001000000001010000011001111111111111111000000000000000000001000010011000101000000010001000000000000000000001000010011000101000000010001000000000001000000001000010011001111111011111111000000000000000000001010010011000000000000000000000000000000000000001010010011000000000000000000000000000001000000001010010011000000000000000000000000000000000000001000001011001101100001000000000000000000000000001000001011001101100001000000000000000001000000001000001011000000000111000000000000000000000000001010001011001110101001000010000000000000000000001010001011001110101001000010000000000001000000001010001011000000000000000000000000000000000000001000011011001100100000100000000000000000000000001000011011001100100000100000000000000001000000001000011011000000000000010000000000000000000000001010011011001000100000110001000000000000000000001010011011001000100000110001000000000001000000001010011011001111111111111111000000000000000000001000000111000101000000010001000000000000000000001000000111000101000000010001000000000001000000001000000111000111111111111111000000000000000000001010000111001101100001000000000000000000000000001010000111001101100001000000000000000001000000001010000111001000000111000010000000000000000000001000010111001110101001000110000000000000000000001000010111001110101001000110000000000001000000001000010111000000000000000000000000000000000000001010010111001111100001000000000000000000000000001010010111001111100001000000000000000001000000001010010111000011000001000000000000000000000000001000001111001101100001010010000000000000000000001000001111001101100001010010000000000001000000001000001111000010100001110000000000000000000000001010001111001110101001001010000000000000000000001010001111001110101001001010000000000001000000001010001111000000000001000000000000000000000000001000011111000110101000001010000000000000000000001000011111000110101000001010000000000001000000001000011111000000000010100000000000000000000000001010011111001111100001000000000000000000000000001010011111001111100001000000000000000001000000001010011111000000001000000000000000000000000000001000000000101110101001001010000000000000000000001000000000101110101001001010000000000001000000001000000000100000000010000000000000000000000000001010000000100000000000000000000000000000000000001010000000100000000000000000000000000001000000001010000000101010110010010000000000000000000000001000010000100000000000000000000000000000000000001000010000100000000000000000000000000001000000001000010000101001110010010000000000000000000000001010010000101111100111000000000000000000000000001010010000101111100111000000000000000001000000001010010000100000101000111111000000000000000000001000001000100000000000000000000000000000000000001000001000100000000000000000000000000001000000001000001000101000011010010000000000000000000000001010001000101111100001100000000000000000000000001010001000101111100001100000000000000001000000001010001000100000101000111111000000000000000000001000011000100111100110100000000000000000000000001000011000100111100110100000000000000001000000001000011000100000101000000000000000000000000000001010011000100000000000000000000000000000000000001010011000100000000000000000000000000001000000001010011000101011101010010000000000000000000000001000000100100111100110000000000000000000000000001000000100100111100110000000000000000001000000001000000100100000101000111111000000000000000000001010000100101111100110000000000000000000000000001010000100101111100110000000000000000001000000001010000100100000101000000000000000000000000000001000010100100000000000000000000000000000000000001000010100100000000000000000000000000001000000001000010100101001001010010000000000000000000000001010010100100111100010100000000000000000000000001010010100100111100010100000000000000001000000001010010100100000101000000000000000000000000000001000001100101100100011110111000000000000000000001000001100101100100011110111000000000001000000001000001100100111111001110111000000000000000000001010001100100000000000010111000000000000000000001010001100100000000000010111000000000001000000001010001100101001111010010000000000000000000000001000011100100111100000100000000000000000000000001000011100100111100000100000000000000001000000001000011100100100101000110000000000000000000000001010011100100110001000100001000000000000000000001010011100100110001000100001000000000001000000001010011100100000000010000000000000000000000000001000000010101111100000100000000000000000000000001000000010101111100000100000000000000001000000001000000010101000000000000010000000000000000000001010000010101100100000110001000000000000000000001010000010101100100000110001000000000001000000001010000010101000000000000010000000000000000000001000010010101101000000100001000000000000000000001000010010101101000000100001000000000001000000001000010010101000000010000000000000000000000000001010010010100000000000000000000000000000000000001010010010100000000000000000000000000001000000001010010010100000000000000000000000000000000000001000001010100100100000100000000000000000000000001000001010100100100000100000000000000001000000001000001010100000000000000001000000000000000000001010001010101101100000111010000000000000000000001010001010101101100000111010000000000001000000001010001010100000010000000000000000000000000000001000011010100001000000000000000000000000000000001000011010100001000000000000000000000001000000001000011010101000000100000000000000000000000000001010011010100000000000000000000000000000000000001010011010100000000000000000000000000001000000001010011010100000000000000000000000000000000000001000000110100100100000100000000000000000000000001000000110100100100000100000000000000001000000001000000110100100000000000000000000000000000000001010000110101101100000111010000000000000000000001010000110101101100000111010000000000001000000001010000110100000001000000000000000000000000000001000010110100110101111010001000000000000000000001000010110100110101111010001000000000001000000001000010110100000000010000000000000000000000000001010010110101100100010111110000000000000000000001010010110101100100010111110000000000001000000001010010110100000000011000000000000000000000000001000001110100110000000000010000000000000000000001000001110100110000000000010000000000001000000001000001110100000000111101110000000000000000000001010001110100000000000000000000000000000000000001010001110100000000000000000000000000001000000001010001110100000000000000000000000000000000000001000011110100001000000001000000000000000000000001000011110100001000000001000000000000001000000001000011110100000000001110000000000000000000000001010011110100000000000000000000000000000000000001010011110100000000000000000000000000001000000001010011110100000000000000000000000000000000000001000000001100110101100010111000000000000000000001000000001100110101100010111000000000001000000001000000001100000000000000000000000000000000000001010000001101100100001000000000000000000000000001010000001101100100001000000000000000001000000001010000001100000100000000000000000000000000000001000010001101110101001000110000000000000000000001000010001101110101001000110000000000001000000001000010001100000000000000000000000000000000000001010010001101110001101011110000000000000000000001010010001101110001101011110000000000001000000001010010001100000000000000000000000000000000000001000001001100111100001000000000000000000000000001000001001100111100001000000000000000001000000001000001001101001111111111100000000000000000000001010001001100000000001011010000000000000000000001010001001100000000001011010000000000001000000001010001001100011010010010000000000000000000000001000011001101110101101010111000000000000000000001000011001101110101101010111000000000001000000001000011001100000000010000000000000000000000000001010011001101000100011110111000000000000000000001010011001101000100011110111000000000001000000001010011001100000000001000000000000000000000000001000000101101100100001000000000000000000000000001000000101101100100001000000000000000001000000001000000101100001000000000000000000000000000000001010000101101110101001000110000000000000000000001010000101101110101001000110000000000001000000001010000101100000000000000000000000000000000000001000010101100111100001000000000000000000000000001000010101100111100001000000000000000001000000001000010101101001101001100000000000000000000000001010010101100101000001011010000000000000000000001010010101100101000001011010000000000001000000001010010101100000000011000000000000000000000000001000001101100000000000000000000000000000000000001000001101100000000000000000000000000001000000001000001101100000000000000000000000000000000000001010001101100111100001000000000000000000000000001010001101100111100001000000000000000001000000001010001101100010000000000000000000000000000000001000011101100000000001000011000000000000000000001000011101100000000001000011000000000001000000001000011101100000011000010000000000000000000000001010011101100000000000110011000000000000000000001010011101100000000000110011000000000001000000001010011101100010011000010000000000000000000000001000000011100000000000110011000000000000000000001000000011100000000000110011000000000001000000001000000011100010011000010000000000000000000000001010000011100111100001000000000000000000000000001010000011100111100001000000000000000001000000001010000011100000000000010000000000000000000000001000010011100000000001001101000000000000000000001000010011100000000001001101000000000001000000001000010011100001101000010000000000000000000000001010010011100000000001000101000000000000000000001010010011100000000001000101000000000001000000001010010011100000101000010000000000000000000000001000001011100000000100100000000000000000000000001000001011100000000100100000000000000001000000001000001011100001001000001000000000000000000000001010001011100000100100101001000000000000000000001010001011100000100100101001000000000001000000001010001011101000000000000000000000000000000000001000011011100001000000000000000000000000000000001000011011100001000000000000000000000001000000001000011011101000000100000000000000000000000000001010011011100000000000000000000000000000000000001010011011100000000000000000000000000001000000001010011011100000000000000000000000000000000000001000000111100111100001000000000000000000000000001000000111100111100001000000000000000001000000001000000111100000000000100000000000000000000000001010000111100000000001000101000000000000000000001010000111100000000001000101000000000001000000001010000111100000101000010000000000000000000000001000010111100100100001000000000000000000000000001000010111100100100001000000000000000001000000001000010111100000100000000000000000000000000000001010010111100110101001000110000000000000000000001010010111100110101001000110000000000001000000001010010111100000000000000000000000000000000000001000001111101110001001011110000000000000000000001000001111101110001001011110000000000001000000001000001111100000000010010000000000000000000000001010001111100110001101111110000000000000000000001010001111100110001101111110000000000001000000001010001111100000000000000000000000000000000000001000011111100100100001000000000000000000000000001000011111100100100001000000000000000001000000001000011111100001000000000000000000000000000000001010011111100110101001000110000000000000000000001010011111100110101001000110000000000001000000001010011111100000000000000000000000000000000000001000000000011001100001010010000000000000000000001000000000011001100001010010000000000001000000001000000000011111111111111111000000000000000000001010000000010100100001000000000000000000000000001010000000010100100001000000000000000001000000001010000000010100000000000010000000000000000000001000010000010101000001010010000000000000000000001000010000010101000001010010000000000001000000001000010000011000000001000000000000000000000000001010010000010000000000000000000000000000000000001010010000010000000000000000000000000001000000001010010000010000000000000000000000000000000000001000001000011111100101100000000000000000000000001000001000011111100101100000000000000001000000001000001000010000000000000010000000000000000000001010001000011000000101101011000000000000000000001010001000011000000101101011000000000001000000001010001000010001011010010000000000000000000000001000011000010101000000001011000000000000000000001000011000010101000000001011000000000001000000001000011000011000000010000000000000000000000000001010011000010000000000000000000000000000000000001010011000010000000000000000000000000001000000001010011000010000000000000000000000000000000000001000000100010111100001000000000000000000000000001000000100010111100001000000000000000001000000001000000100010001000011100000000000000000000000001010000100010101100001000010000000000000000000001010000100010101100001000010000000000001000000001010000100010010000010000001000000000000000000001000010100010110101001011110000000000000000000001000010100010110101001011110000000000001000000001000010100010000000001100000000000000000000000001010010100010001000000000000000000000000000000001010010100010001000000000000000000000001000000001010010100011000000100000000000000000000000000001000001100010111100001000000000000000000000000001000001100010111100001000000000000000001000000001000001100010010000011000000000000000000000000001010001100010101100001000010000000000000000000001010001100010101100001000010000000000001000000001010001100010001000010000001000000000000000000001000011100010110101001011110000000000000000000001000011100010110101001011110000000000001000000001000011100010000000001100000000000000000000000001010011100010111100001000000000000000000000000001010011100010111100001000000000000000001000000001010011100010010000000000000000000000000000000001000000010010000000001001110000000000000000000001000000010010000000001001110000000000001000000001000000010010001110000010000000000000000000000001010000010010000000000111110000000000000000000001010000010010000000000111110000000000001000000001010000010010011110000010000000000000000000000001000010010010000000000111110000000000000000000001000010010010000000000111110000000000001000000001000010010010011110000010000000000000000000000001010010010011100100011010110000000000000000000001010010010011100100011010110000000000001000000001010010010011000000000000000000000000000000000001000001010010110100001010110000000000000000000001000001010010110100001010110000000000001000000001000001010010000000001000000000000000000000000001010001010010101000000000010000000000000000000001010001010010101000000000010000000000001000000001010001010010111111010001111000000000000000000001000011010010000000000000000000000000000000000001000011010010000000000000000000000000001000000001000011010010000000000000000000000000000000000001010011010010111100001000000000000000000000000001010011010010111100001000000000000000001000000001010011010010100011000000000000000000000000000001000000110010110101001001010000000000000000000001000000110010110101001001010000000000001000000001000000110010000000011000000000000000000000000001010000110010111100001000000000000000000000000001010000110010111100001000000000000000001000000001010000110010000001000000000000000000000000000001000010110010110101001001010000000000000000000001000010110010110101001001010000000000001000000001000010110010000000010000000000000000000000000001010010110010000000000001111000000000000000000001010010110010000000000001111000000000001000000001010010110011010111010010000000000000000000000001000001110010000000000000000000000000000000000001000001110010000000000000000000000000001000000001000001110011011000010010000000000000000000000001010001110011110001001010111000000000000000000001010001110011110001001010111000000000001000000001010001110010000000010000000000000000000000000001000011110010111100001000000000000000000000000001000011110010111100001000000000000000001000000001000011110011001101001000000000000000000000000001010011110010101000001010010000000000000000000001010011110010101000001010010000000000001000000001010011110010000000110100000000000000000000000001000000001010000000000000000000000000000000000001000000001010000000000000000000000000001000000001000000001010000000000000000000000000000000000001010000001010110101001110001000000000000000000001010000001010110101001110001000000000001000000001010000001010000000010000000000000000000000000001000010001011100100010110011000000000000000000001000010001011100100010110011000000000001000000001000010001010000000011000000000000000000000000001010010001010110001010010111000000000000000000001010010001010110001010010111000000000001000000001010010001010000000000000000000000000000000000001000001001011000100011110111000000000000000000001000001001011000100011110111000000000001000000001000001001010000000001000000000000000000000000001010001001011100100010000000000000000000000000001010001001011100100010000000000000000001000000001010001001011000000000000000000000000000000000001000011001010110000000000010000000000000000000001000011001010110000000000010000000000001000000001000011001010000000000100101000000000000000000001010011001010000000000000000000000000000000000001010011001010000000000000000000000000001000000001010011001010000000000000000000000000000000000001000000101010110001001001101000000000000000000001000000101010110001001001101000000000001000000001000000101010000000000000000000000000000000000001010000101010111100001000000000000000000000000001010000101010111100001000000000000000001000000001010000101010000000001000000000000000000000000001000010101010000000110100010000000000000000000001000010101010000000110100010000000000001000000001000010101010000010000010000000000000000000000001010010101011110001001000010000000000000000000001010010101011110001001000010000000000001000000001010010101010000000000000000000000000000000000001000001101010110001001001101000000000000000000001000001101010110001001001101000000000001000000001000001101010000000000000000000000000000000000001010001101010111100001000000000000000000000000001010001101010111100001000000000000000001000000001010001101010000000001000000000000000000000000001000011101010000000110100010000000000000000000001000011101010000000110100010000000000001000000001000011101010000010000010000000000000000000000001010011101011110001001000010000000000000000000001010011101011110001001000010000000000001000000001010011101010000000000000000000000000000000000001000000011010111100001000000000000000000000000001000000011010111100001000000000000000001000000001000000011010100000000000000000000000000000000001010000011010000000001001110000000000000000000001010000011010000000001001110000000000001000000001010000011010001110000010000000000000000000000001000010011010000000000110011000000000000000000001000010011010000000000110011000000000001000000001000010011010010011000010000000000000000000000001010010011010111100001000000000000000000000000001010010011010111100001000000000000000001000000001010010011010000000000100000000000000000000000001000001011010000000001001101000000000000000000001000001011010000000001001101000000000001000000001000001011010001101000010000000000000000000000001010001011010001000000000000000000000000000000001010001011010001000000000000000000000001000000001010001011011000000000010000000000000000000000001000011011011110101110110001000000000000000000001000011011011110101110110001000000000001000000001000011011010000000010000000000000000000000000001010011011011100100010101100000000000000000000001010011011011100100010101100000000000001000000001010011011010000000011000000000000000000000000001000000111010110001010010111000000000000000000001000000111010110001010010111000000000001000000001000000111010000000000000000000000000000000000001010000111011000100011110111000000000000000000001010000111011000100011110111000000000001000000001010000111010000000001000000000000000000000000001000010111011100100010000000000000000000000000001000010111011100100010000000000000000001000000001000010111011000000000000000000000000000000000001010010111010110000000000010000000000000000000001010010111010110000000000010000000000001000000001010010111010000000000100101000000000000000000001000001111010000000000000000000000000000000000001000001111010000000000000000000000000001000000001000001111010000000000000000000000000000000000001010001111010110001001011100000000000000000000001010001111010110001001011100000000000001000000001010001111010000000000000000000000000000000000001000011111010111100001000000000000000000000000001000011111010111100001000000000000000001000000001000011111010000000001000000000000000000000000001010011111011000000110000010000000000000000000001010011111011000000110000010000000000001000000001010011111010000010000010000000000000000000000001000000000111110001001000010000000000000000000001000000000111110001001000010000000000001000000001000000000110000000000000000000000000000000000001010000000110111100001000000000000000000000000001010000000110111100001000000000000000001000000001010000000110000000000100000000000000000000000001000010000111000000110000010000000000000000000001000010000111000000110000010000000000001000000001000010000110000010000010000000000000000000000001010010000111110001001000010000000000000000000001010010000111110001001000010000000000001000000001010010000110000000000000000000000000000000000001000001000110111100001000000000000000000000000001000001000110111100001000000000000000001000000001000001000110000000001100000000000000000000000001010001000111000000110000010000000000000000000001010001000111000000110000010000000000001000000001010001000110000010000010000000000000000000000001000011000111110001001000010000000000000000000001000011000111110001001000010000000000001000000001000011000110000000000000000000000000000000000001010011000110110001001011100000000000000000000001010011000110110001001011100000000000001000000001010011000110000000000000000000000000000000000001000000100110111100001000000000000000000000000001000000100110111100001000000000000000001000000001000000100110000000001000000000000000000000000001010000100111000000110000010000000000000000000001010000100111000000110000010000000000001000000001010000100110000010000010000000000000000000000001000010100111110001001000010000000000000000000001000010100111110001001000010000000000001000000001000010100110000000000000000000000000000000000001010010100110111100001000000000000000000000000001010010100110111100001000000000000000001000000001010010100110000000000100000000000000000000000001000001100111000000110000010000000000000000000001000001100111000000110000010000000000001000000001000001100110000010000010000000000000000000000001010001100111110001001000010000000000000000000001010001100111110001001000010000000000001000000001010001100110000000000000000000000000000000000001000011100110111100001000000000000000000000000001000011100110111100001000000000000000001000000001000011100110000000001100000000000000000000000001010011100111000000110000010000000000000000000001010011100111000000110000010000000000001000000001010011100110000010000010000000000000000000000001000000010111110001001000010000000000000000000001000000010111110001001000010000000000001000000001000000010110000000000000000000000000000000000001010000010110111100001000000000000000000000000001010000010110111100001000000000000000001000000001010000010110010000000000000000000000000000000001000010010110000000001011101000000000000000000001000010010110000000001011101000000000001000000001000010010110011101000010000000000000000000000001010010010110000000000101100000000000000000000001010010010110000000000101100000000000001000000001010010010110001100000010000000000000000000000001000001010110000000000101100000000000000000000001000001010110000000000101100000000000001000000001000001010110001100000010000000000000000000000001010001010110111100001000000000000000000000000001010001010110111100001000000000000000001000000001010001010110000000000010000000000000000000000001000011010110000000001011100000000000000000000001000011010110000000001011100000000000001000000001000011010110011100000010000000000000000000000001010011010111100100100011000000000000000000000001010011010111100100100011000000000000001000000001010011010111000000000000000000000000000000000001000000110111000000011011000000000000000000000001000000110111000000011011000000000000001000000001000000110110000010101010000000000000000000000001010000110110101000000000010000000000000000000001010000110110101000000000010000000000001000000001010000110111111111100001111000000000000000000001000010110110000000000000000000000000000000000001000010110110000000000000000000000000001000000001000010110110000000000000000000000000000000000001010010110110111100101000000000000000000000000001010010110110111100101000000000000000001000000001010010110110100101000111000000000000000000000001000001110110000000100100000000000000000000000001000001110110000000100100000000000000001000000001000001110110101001000001100000000000000000000001010001110111111100001000000000000000000000000001010001110111111100001000000000000000001000000001010001110110000000110000000000000000000000000001000011110111101100001010010000000000000000000001000011110111101100001010010000000000001000000001000011110110101100010110001000000000000000000001010011110110000000100110010000000000000000000001010011110110000000100110010000000000001000000001010011110111010010010010000000000000000000000001000000001111110101001001010000000000000000000001000000001111110101001001010000000000001000000001000000001110000000000100000000000000000000000001010000001111110001001001010000000000000000000001010000001111110001001001010000000000001000000001010000001110000000000100000000000000000000000001000010001110111100001000000000000000000000000001000010001110111100001000000000000000001000000001000010001110000101000000000000000000000000000001010010001110101100001000010000000000000000000001010010001110101100001000010000000000001000000001010010001110000000000000011000000000000000000001000001001111111100001000000000000000000000000001000001001111111100001000000000000000001000000001000001001111110000111111111000000000000000000001010001001111101100001010010000000000000000000001010001001111101100001010010000000000001000000001010001001111111111111111111000000000000000000001000011001111000000001001101000000000000000000001000011001111000000001001101000000000001000000001000011001110001101010010000000000000000000000001010011001110110101110100010000000000000000000001010011001110110101110100010000000000001000000001010011001110000000001100000000000000000000000001000000101110000000000001111000000000000000000001000000101110000000000001111000000000001000000001000000101111010111010010000000000000000000000001010000101111100100011110111000000000000000000001010000101111100100011110111000000000001000000001010000101110000000001001000000000000000000000001000010101111110001100110111000000000000000000001000010101111110001100110111000000000001000000001000010101110000000000000000000000000000000000001010010101110110001010110111000000000000000000001010010101110110001010110111000000000001000000001010010101110000000010000000000000000000000000001000001101111110001010110111000000000000000000001000001101111110001010110111000000000001000000001000001101110000000001000000000000000000000000001010001101110110001110110111000000000000000000001010001101110110001110110111000000000001000000001010001101110000000011000000000000000000000000001000011101111110001110110111000000000000000000001000011101111110001110110111000000000001000000001000011101110000000000100000000000000000000000001010011101111100100011110111000000000000000000001010011101111100100011110111000000000001000000001010011101110000000001100000000000000000000000001000000011110111100001000000000000000000000000001000000011110111100001000000000000000001000000001000000011110000001000000000000000000000000000001010000011110100100001000010000000000000000000001010000011110100100001000010000000000001000000001010000011110000000000000000000000000000000000001000010011111100100001000010000000000000000000001000010011111100100001000010000000000001000000001000010011110000010000000000000000000000000000001010010011111100100001010010000000000000000000001010010011111100100001010010000000000001000000001010010011110111111000011111000000000000000000001000001011110000010000000100000000000000000000001000001011110000010000000100000000000001000000001000001011110000111000000000000000000000000000001010001011110000010000000100000000000000000000001010001011110000010000000100000000000001000000001010001011110010111000000000000000000000000000001000011011110111101001000010000000000000000000001000011011110111101001000010000000000001000000001000011011110000000000000000000000000000000000001010011011111000000001000010000000000000000000001010011011111000000001000010000000000001000000001010011011111010000101010000000000000000000000001000000111110101000000010000000000000000000000001000000111110101000000010000000000000001000000001000000111111111111011111111000000000000000000001010000111110100100001000010000000000000000000001010000111110100100001000010000000000001000000001010000111110000000000010000000000000000000000001000010111110111100001000000000000000000000000001000010111110111100001000000000000000001000000001000010111110000001000000000000000000000000000001010010111110100100001000010000000000000000000001010010111110100100001000010000000000001000000001010010111110000000000000000000000000000000000001000001111111100100001000010000000000000000000001000001111111100100001000010000000000001000000001000001111110000100000000000000000000000000000001010001111111100100001010010000000000000000000001010001111111100100001010010000000000001000000001010001111110111111000111111000000000000000000001000011111111111101001000010000000000000000000001000011111111111101001000010000000000001000000001000011111110000000000000000000000000000000000001010011111111000000001000010000000000000000000001010011111111000000001000010000000000001000000001010011111111010000101010000010000000000000000001000000000000101000000010000010000000000000000001000000000000101000000010000010000000001000000001000000000001111111011111111010000000000000000001010000000000100100001000010010000000000000000001010000000000100100001000010010000000001000000001010000000000000000000100000010000000000000000001000010000000001000000000000010000000000000000001000010000000001000000000000010000000001000000001000010000001000000100100000010000000000000000001010010000000000000000000000010000000000000000001010010000000000000000000000010000000001000000001010010000000000000000000000010000000000000000001000001000000111100001000000010000000000000000001000001000000111100001000000010000000001000000001000001000000000001000000000010000000000000000001010001000000100100001000010010000000000000000001010001000000100100001000010010000000001000000001010001000000000000000000000010000000000000000001000011000001100100001000010010000000000000000001000011000001100100001000010010000000001000000001000011000000000010000000000010000000000000000001010011000001100100001010010010000000000000000001010011000001100100001010010010000000001000000001010011000000111111000011111010000000000000000001000000100000000010000000100010000000000000000001000000100000000010000000100010000000001000000001000000100000000111000000000010000000000000000001010000100000000010000000100010000000000000000001010000100000000010000000100010000000001000000001010000100000010111000000000010000000000000000001000010100000111101001000010010000000000000000001000010100000111101001000010010000000001000000001000010100000000000000000000010000000000000000001010010100001000000001000010010000000000000000001010010100001000000001000010010000000001000000001010010100001010000101010000010000000000000000001000001100000101000000010000010000000000000000001000001100000101000000010000010000000001000000001000001100001111111011111111010000000000000000001010001100000100100001000010010000000000000000001010001100000100100001000010010000000001000000001010001100000000000000010000010000000000000000001000011100000111100001000000010000000000000000001000011100000111100001000000010000000001000000001000011100000000001000000000010000000000000000001010011100000100100001000010010000000000000000001010011100000100100001000010010000000001000000001010011100000000000000000000010000000000000000001000000010001100100001000010010000000000000000001000000010001100100001000010010000000001000000001000000010000000100000000000010000000000000000001010000010001100100001010010010000000000000000001010000010001100100001010010010000000001000000001010000010000111111000111111010000000000000000001000010010001111101000000010010000000000000000001000010010001111101000000010010000000001000000001000010010000000000000000000010000000000000000001010010010001000000001000010010000000000000000001010010010001000000001000010010000000001000000001010010010001010000101010000010000000000000000001000001010000101000000010000010000000000000000001000001010000101000000010000010000000001000000001000001010001111111011111111010000000000000000001010001010000100100001000010010000000000000000001010001010000100100001000010010000000001000000001010001010000000000000100000010000000000000000001000011010000111100101000000010000000000000000001000011010000111100101000000010000000001000000001000011010000100101000000000010000000000000000001010011010000100100101001010010000000000000000001010011010000100100101001010010000000001000000001010011010000000000000000000010000000000000000001000000110001111100101000000010000000000000000001000000110001111100101000000010000000001000000001000000110000111111000111111010000000000000000001010000110001111100001000000010000000000000000001010000110001111100001000000010000000001000000001010000110000000000000100000010000000000000000001000010110001000000101001010010000000000000000001000010110001000000101001010010000000001000000001000010110000001010010010000010000000000000000001010010110000111100001000000010000000000000000001010010110000111100001000000010000000001000000001010010110000100101000000000010000000000000000001000001110001100100001010010010000000000000000001000001110001100100001010010010000000001000000001000001110001111111111111111010000000000000000001010001110001111100101000000010000000000000000001010001110001111100101000000010000000001000000001010001110000100101000000000010000000000000000001000011110000100100001000010010000000000000000001000011110000100100001000010010000000001000000001000011110000100000000001100010000000000000000001010011110001100100101011010010000000000000000001010011110001100100101011010010000000001000000001010011110000100000010111011010000000000000000001000000001001000000001000010010000000000000000001000000001001000000001000010010000000001000000001000000001000000010010010000010000000000000000001010000001001000000001011010010000000000000000001010000001001000000001011010010000000001000000001010000001000011010010010000010000000000000000001000010001001111100001000000010000000000000000001000010001001111100001000000010000000001000000001000010001000000101000000000010000000000000000001010010001000000000101000010010000000000000000001010010001000000000101000010010000000001000000001010010001001000010010010000010000000000000000001000001001000000000101011010010000000000000000001000001001000000000101011010010000000001000000001000001001001011010010010000010000000000000000001010001001001100100001010010010000000000000000001010001001001100100001010010010000000001000000001010001001000000000000000000010000000000000000001000011001001110001011000010010000000000000000001000011001001110001011000010010000000001000000001000011001000000000000000000010000000000000000001010011001000100100001000010010000000000000000001010011001000100100001000010010000000001000000001010011001000000000010000000010000000000000000001000000101001000000101000010010000000000000000001000000101001000000101000010010000000001000000001000000101001010000101010000010000000000000000001010000101001100100001010010010000000000000000001010000101001100100001010010010000000001000000001010000101000000000010000000010000000000000000001000010101000101000000010000010000000000000000001000010101000101000000010000010000000001000000001000010101001111111101111111010000000000000000001010010101001110101011010010010000000000000000001010010101001110101011010010010000000001000000001010010101000111111011111111010000000000000000001000001101000111100011000000010000000000000000001000001101000111100011000000010000000001000000001000001101000000001000000000010000000000000000001010001101000100100011000110010000000000000000001010001101000100100011000110010000000001000000001010001101000000000000000000010000000000000000001000011101000000000000000110010000000000000000001000011101000000000000000110010000000001000000001000011101000000000001000000010000000000000000001010011101000000000000000000010000000000000000001010011101000000000000000000010000000001000000001010011101000000000000000000010000000000000000001000000011001111100101000000010000000000000000001000000011001111100101000000010000000001000000001000000011000001101000000000010000000000000000001010000011001110001001011010010000000000000000001010000011001110001001011010010000000001000000001010000011000000000001000000010000000000000000001000010011000111100101000000010000000000000000001000010011000111100101000000010000000001000000001000010011001111000111111111010000000000000000001010010011000101100101001010010000000000000000001010010011000101100101001010010000000001000000001010010011001111111111111111010000000000000000001000001011001111100000000000010000000000000000001000001011001111100000000000010000000001000000001000001011000100101000011000010000000000000000001010001011000000000101010010010000000000000000001010001011000000000101010010010000000001000000001010001011000010010010010000010000000000000000001000011011001110101001010000010000000000000000001000011011001110101001010000010000000001000000001000011011000000000000000000010000000000000000001010011011000111100001000000010000000000000000001010011011000111100001000000010000000001000000001010011011000100101000011000010000000000000000001000000111000110001001000010010000000000000000001000000111000110001001000010010000000001000000001000000111000000000000100000010000000000000000001010000111000001100001000010010000000000000000001010000111000001100001000010010000000001000000001010000111000000000100000000010000000000000000001000010111000101010000000010010000000000000000001000010111000101010000000010010000000001000000001000010111001111111011111111010000000000000000001010010111000111100001000000010000000000000000001010010111000111100001000000010000000001000000001010010111000100101000011000010000000000000000001000001111000100100001000000010000000000000000001000001111000100100001000000010000000001000000001000001111000001000000000000010000000000000000001010001111001000000101000010010000000000000000001010001111001000000101000010010000000001000000001010001111000000010000010000010000000000000000001000011111000000000101000010010000000000000000001000011111000000000101000010010000000001000000001000011111000000010010010000010000000000000000001010011111001111100000000000010000000000000000001010011111001111100000000000010000000001000000001010011111000100101000011000010000000000000000001000000000100110101001010000010000000000000000001000000000100110101001010000010000000001000000001000000000100000000010000000010000000000000000001010000000100111100101000000010000000000000000001010000000100111100101000000010000000001000000001010000000100000000000100000010000000000000000001000010000100100100101001010010000000000000000001000010000100100100101001010010000000001000000001000010000101111111111111111010000000000000000001010010000101111100000000000010000000000000000001010010000101111100000000000010000000001000000001010010000100100101000011000010000000000000000001000001000100110101101010000010000000000000000001000001000100110101101010000010000000001000000001000001000100000000011000000010000000000000000001010001000100000000000000000010000000000000000001010001000100000000000000000010000000001000000001010001000100000000000000000010000000000000000001000011000100000000000000000010000000000000000001000011000100000000000000000010000000001000000001000011000100000000000000000010000000000000000001010011000100000000000000000010000000000000000001010011000100000000000000000010000000001000000001010011000100000000000000000010000000000000000001000000100100000000000000000010000000000000000001000000100100000000000000000010000000001000000001000000100100000000000000000010000000000000000001010000100100000000000000000010000000000000000001010000100100000000000000000010000000001000000001010000100100000000000000000010000000000000000001000010100100000000000000000010000000000000000001000010100100000000000000000010000000001000000001000010100100000000000000000010000000000000000001010010100100000000000000000010000000000000000001010010100100000000000000000010000000001000000001010010100100000000000000000010000000000000000001000001100100000000000000000010000000000000000001000001100100000000000000000010000000001000000001000001100100000000000000000010000000000000000001010001100100000000000000000010000000000000000001010001100100000000000000000010000000001000000001010001100100000000000000000010000000000000000001000011100100000000000000000010000000000000000001000011100100000000000000000010000000001000000001000011100100000000000000000010000000000000000001010011100100000000000000000010000000000000000001010011100100000000000000000010000000001000000001010011100100000000000000000010000000000000000001000000010100000000000000000010000000000000000001000000010100000000000000000010000000001000000001000000010100000000000000000010000000000000000001010000010100000000000000000010000000000000000001010000010100000000000000000010000000001000000001010000010100000000000000000010000000000000000001000010010100000000000000000010000000000000000001000010010100000000000000000010000000001000000001000010010100000000000000000010000000000000000001010010010100000000000000000010000000000000000001010010010100000000000000000010000000001000000001010010010100000000000000000010000000000000000001000001010100000000000000000010000000000000000001000001010100000000000000000010000000001000000001000001010100000000000000000010000000000000000001010001010100000000000000000010000000000000000001010001010100000000000000000010000000001000000001010001010100000000000000000010000000000000000001000011010100000000000000000010000000000000000001000011010100000000000000000010000000001000000001000011010100000000000000000010000000000000000001010011010100000000000000000010000000000000000001010011010100000000000000000010000000001000000001010011010100000000000000000010000000000000000001000000110100000000000000000010000000000000000001000000110100000000000000000010000000001000000001000000110100000000000000000010000000000000000001010000110100000000000000000010000000000000000001010000110100000000000000000010000000001000000001010000110100000000000000000010000000000000000001000010110100000000000000000010000000000000000001000010110100000000000000000010000000001000000001000010110100000000000000000010000000000000000001010010110100000000000000000010000000000000000001010010110100000000000000000010000000001000000001010010110100000000000000000010000000000000000001000001110100000000000000000010000000000000000001000001110100000000000000000010000000001000000001000001110100000000000000000010000000000000000001010001110100000000000000000010000000000000000001010001110100000000000000000010000000001000000001010001110100000000000000000010000000000000000001000011110100000000000000000010000000000000000001000011110100000000000000000010000000001000000001000011110100000000000000000010000000000000000001010011110100000000000000000010000000000000000001010011110100000000000000000010000000001000000001010011110100000000000000000010000000000000000001000000001100000000000000000010000000000000000001000000001100000000000000000010000000001000000001000000001100000000000000000010000000000000000001010000001101111100101000000010000000000000000001010000001101111100101000000010000000001000000001010000001100100101000011000010000000000000000001000010001101110001101011010010000000000000000001000010001101110001101011010010000000001000000001000010001100000000000100000010000000000000000001010010001101001100101011010010000000000000000001010010001101001100101011010010000000001000000001010010001101000000000000000010000000000000000001000001001100101000000011010010000000000000000001000001001100101000000011010010000000001000000001000001001100111111000011111010000000000000000001010001001100000000000000000010000000000000000001010001001100000000000000000010000000001000000001010001001100000000000000000010000000000000000001000011001101111100101000000010000000000000000001000011001101111100101000000010000000001000000001000011001100001101000000000010000000000000000001010011001100110001010011010010000000000000000001010011001100110001010011010010000000001000000001010011001100000000001000000010000000000000000001000000101100000000000001101010000000000000000001000000101100000000000001101010000000001000000001000000101101010100010010000010000000000000000001010000101101111100000000000010000000000000000001010000101101111100000000000010000000001000000001010000101100111010001101010010000000000000000001000010101101101100000010000010000000000000000001000010101101101100000010000010000000001000000001000010101101010001010011011010000000000000000001010010101101000000000010100010000000000000000001010010101101000000000010100010000000001000000001010010101101000000001100000010000000000000000001000001101101100100011110111010000000000000000001000001101101100100011110111010000000001000000001000001101100111111000011111010000000000000000001010001101101110101111110111010000000000000000001010001101101110101111110111010000000001000000001010001101100000000011100000010000000000000000001000011101100110101000110111010000000000000000001000011101100110101000110111010000000001000000001000011101100000000010100000010000000000000000001010011101101111100111100000010000000000000000001010011101101111100111100000010000000001000000001010011101100000000000100000010000000000000000001000000011100000000000000000010000000000000000001000000011100000000000000000010000000001000000001000000011101011000010010000010000000000000000001010000011100000000000000000010000000000000000001010000011100000000000000000010000000001000000001010000011101000010010010000010000000000000000001000010011100000000000000100010000000000000000001000010011100000000000000100010000000001000000001000010011101010010010010000010000000000000000001010010011101100100011000000010000000000000000001010010011101100100011000000010000000001000000001010010011100000000000010000010000000000000000001000001011100000000000000000010000000000000000001000001011100000000000000000010000000001000000001000001011100001000100100000010000000000000000001010001011100100100100001000010000000000000000001010001011100100100100001000010000000001000000001010001011101000000000000000010000000000000000001000011011100000000000001000010000000000000000001000011011100000000000001000010000000001000000001000011011101011100010010000010000000000000000001010011011100000000000001000010000000000000000001010011011100000000000001000010000000001000000001010011011101001010010010000010000000000000000001000000111100000000000001000010000000000000000001000000111100000000000001000010000000001000000001000000111101011010010010000010000000000000000001010000111100000000000001000010000000000000000001010000111100000000000001000010000000001000000001010000111101000001010010000010000000000000000001000010111100000000000001000010000000000000000001000010111100000000000001000010000000001000000001000010111101001100010010000010000000000000000001010010111100000000000001000010000000000000000001010010111100000000000001000010000000001000000001010010111101000110010010000010000000000000000001000001111100110001100010010010000000000000000001000001111100110001100010010010000000001000000001000001111100000000000000000010000000000000000001010001111100000000100011100010000000000000000001010001111100000000100011100010000000001000000001010001111101011000000010000010000000000000000001000011111101000000110011000010000000000000000001000011111101000000110011000010000000001000000001000011111101010000101010000010000000000000000001010011111100001000000010000010000000000000000001010011111100001000000010000010000000001000000001010011111100000000100000000010000000000000000001000000000010000000000011000010000000000000000001000000000010000000000011000010000000001000000001000000000011010100010010000010000000000000000001010000000010100100101001010010000000000000000001010000000010100100101001010010000000001000000001010000000011000000000000000010000000000000000001000010000011001100100001000010000000000000000001000010000011001100100001000010000000001000000001000010000011000000111100000010000000000000000001010010000011000000100010110010000000000000000001010010000011000000100010110010000000001000000001010010000011011110100010000010000000000000000001000001000010000000100011110010000000000000000001000001000010000000100011110010000000001000000001000001000010000011110000000010000000000000000001010001000010000000100011000010000000000000000001010001000010000000100011000010000000001000000001010001000010001110010000000010000000000000000001000011000010000000001101110010000000000000000001000011000010000000001101110010000000001000000001000011000011000100010010000010000000000000000001010011000010000000100001100010000000000000000001010011000010000000100001100010000000001000000001010011000011010000101010000010000000000000000001000000100010000000000010100010000000000000000001000000100010000000000010100010000000001000000001000000100011011100010010000010000000000000000001010000100010000000100011010010000000000000000001010000100010000000100011010010000000001000000001010000100010011010110010000010000000000000000001000010100010001000000010000010000000000000000001000010100010001000000010000010000000001000000001000010100010000000010000000010000000000000000001010010100010000000010000001010000000000000000001010010100010000000010000001010000000001000000001010010100011000001000010000010000000000000000001000001100010000000100011100010000000000000000001000001100010000000100011100010000000001000000001000001100010010011110010000010000000000000000001010001100010001000000000000010000000000000000001010001100010001000000000000010000000001000000001010001100010000000100000000010000000000000000001000011100010000000110010011010000000000000000001000011100010000000110010011010000000001000000001000011100010001100110010000010000000000000000001010011100010000000010001100010000000000000000001010011100010000000010001100010000000001000000001010011100010001100110010000010000000000000000001000000010010100100001000010010000000000000000001000000010010100100001000010010000000001000000001000000010010000000010000000010000000000000000001010000010010000000000101000010000000000000000001010000010010000000000101000010000000001000000001010000010010011110110010000010000000000000000001000010010011100100001010010010000000000000000001000010010011100100001010010010000000001000000001000010010010000000010000000010000000000000000001010010010011101000111100010010000000000000000001010010010011101000111100010010000000001000000001010010010010111111001011111010000000000000000001000001010010000000011011110010000000000000000001000001010010000000011011110010000000001000000001000001010011000110000010000010000000000000000001010001010010000000101011100010000000000000000001010001010010000000101011100010000000001000000001010001010010001110110010000010000000000000000001000011010011000000101001110010000000000000000001000011010011000000101001110010000000001000000001000011010010011100110010000010000000000000000001010011010010000000110000001010000000000000000001010011010010000000110000001010000000001000000001010011010010000011110010000010000000000000000001000000110010000000011000011010000000000000000001000000110010000000011000011010000000001000000001000000110010000001110010000010000000000000000001010000110011111100101000000010000000000000000001010000110011111100101000000010000000001000000001010000110010001101000000000010000000000000000001000010110010110001001011010010000000000000000001000010110010110001001011010010000000001000000001000010110010000000000100000010000000000000000001010010110010101000001011100010000000000000000001010010110010101000001011100010000000001000000001010010110010000000110000000010000000000000000001000001110010000000000000000010000000000000000001000001110010000000000000000010000000001000000001000001110010000000000000000010000000000000000001010001110010110001001011010010000000000000000001010001110010110001001011010010000000001000000001010001110010000000010100000010000000000000000001000011110010101000001000001010000000000000000001000011110010101000001000001010000000001000000001000011110011000000100000000010000000000000000001010011110010000000000000000010000000000000000001010011110010000000000000000010000000001000000001010011110010000000000000000010000000000000000001000000001011100000000100000010000000000000000001000000001011100000000100000010000000001000000001000000001011000000100000000010000000000000000001010000001010000000000000000010000000000000000001010000001010000000000000000010000000001000000001010000001010000000000000000010000000000000000001000010001011100000000100000010000000000000000001000010001011100000000100000010000000001000000001000010001011111111111111111010000000000000000001010010001010000000000000000010000000000000000001010010001010000000000000000010000000001000000001010010001010000000000000000010000000000000000001000001001011111100001000000010000000000000000001000001001011111100001000000010000000001000000001000001001010100101001000000010000000000000000001010001001011110001001010010010000000000000000001010001001011110001001010010010000000001000000001010001001010000000000000000010000000000000000001000011001010110001000110111010000000000000000001000011001010110001000110111010000000001000000001000011001010000000010100000010000000000000000001010011001011110001111110111010000000000000000001010011001011110001111110111010000000001000000001010011001010000000011100000010000000000000000001000000101010001000000010010010000000000000000001000000101010001000000010010010000000001000000001000000101010000000110000000010000000000000000001010000101011100100011110111010000000000000000001010000101011100100011110111010000000001000000001010000101010000000000010000010000000000000000001000010101010100100101000000010000000000000000001000010101010100100101000000010000000001000000001000010101011000000000001000010000000000000000001010010101011111100000000000010000000000000000001010010101011111100000000000010000000001000000001010010101010100101010000000010000000000000000001000001101010110101101010000010000000000000000001000001101010110101101010000010000000001000000001000001101010000000000100000010000000000000000001010001101011111100000000000010000000000000000001010001101011111100000000000010000000001000000001010001101010100101001000000010000000000000000001000011101010110101000010000010000000000000000001000011101010110101000010000010000000001000000001000011101010000000000000000010000000000000000001010011101011111100101000000010000000000000000001010011101011111100101000000010000000001000000001010011101010000000101010100010000000000000000001000000011011101100101011010010000000000000000001000000011011101100101011010010000000001000000001000000011010010101111010101010000000000000000001010000011011111100000000000010000000000000000001010000011011111100000000000010000000001000000001010000011010100101010000000010000000000000000001000010011011110101101010000010000000000000000001000010011011110101101010000010000000001000000001000010011010000000000100000010000000000000000001010010011011111100000000000010000000000000000001010010011011111100000000000010000000001000000001010010011010100101000110000010000000000000000001000001011010100100001000000010000000000000000001000001011010100100001000000010000000001000000001000001011011100000010101010010000000000000000001010001011010110101001010000010000000000000000001010001011010110101001010000010000000001000000001010001011010000000011000000010000000000000000001000011011011111100000000000010000000000000000001000011011011111100000000000010000000001000000001000011011010100101000000100010000000000000000001010011011010110101000010000010000000000000000001010011011010110101000010000010000000001000000001010011011010000000001100000010000000000000000001000000111011111100000000000010000000000000000001000000111011111100000000000010000000001000000001000000111010100101000101000010000000000000000001010000111010110101000010000010000000000000000001010000111010110101000010000010000000001000000001010000111010000000011000000010000000000000000001000010111011111100000000000010000000000000000001000010111011111100000000000010000000001000000001000010111010100101000110000010000000000000000001010010111011100100001000000010000000000000000001010010111011100100001000000010000000001000000001010010111010010000000000000010000000000000000001000001111011110101001010000010000000000000000001000001111011110101001010000010000000001000000001000001111010000000000000000010000000000000000001010001111011100100001000000010000000000000000001010001111011100100001000000010000000001000000001010001111010000000100000000010000000000000000001000011111011111100000000000010000000000000000001000011111011111100000000000010000000001000000001000011111010100101000011000010000000000000000001010011111010111100001000000010000000000000000001010011111010111100001000000010000000001000000001010011111010000101000000000010000000000000000001000000000110101100001000010010000000000000000001000000000110101100001000010010000000001000000001000000000110000000000000011010000000000000000001010000000111110101001010000010000000000000000001010000000111110101001010000010000000001000000001010000000110000000000100000010000000000000000001000010000111110101110100010010000000000000000001000010000111110101110100010010000000001000000001000010000110000000010100000010000000000000000001010010000111110101010100010010000000000000000001010010000111110101010100010010000000001000000001010010000110000000011000000010000000000000000001000001000111110101100100010010000000000000000001000001000111110101100100010010000000001000000001000001000110000000010000000010000000000000000001010001000110001000000011001010000000000000000001010001000110001000000011001010000000001000000001010001000110000000010000000010000000000000000001000011000110110101010100010010000000000000000001000011000110110101010100010010000000001000000001000011000110000000000000000010000000000000000001010011000111111100001000000010000000000000000001010011000111111100001000000010000000001000000001010011000110100101000000001010000000000000000001000000100110001000000000000010000000000000000001000000100110001000000000000010000000001000000001000000100111000000100000000010000000000000000001010000100111100100001010010010000000000000000001010000100111100100001010010010000000001000000001010000100110000000000000000010000000000000000001000010100111111100001000000010000000000000000001000010100111111100001000000010000000001000000001000010100110001101000000000010000000000000000001010010100111100100001010010010000000000000000001010010100111100100001010010010000000001000000001010010100110000000000000000010000000000000000001000001100111110101001000010010000000000000000001000001100111110101001000010010000000001000000001000001100110000000001000000010000000000000000001010001100110111100001000000010000000000000000001010001100110111100001000000010000000001000000001010001100110100101000000000010000000000000000001000011100110100100001000010010000000000000000001000011100110100100001000010010000000001000000001000011100110000000000000000010000000000000000001010011100111000100001000010010000000000000000001010011100111000100001000010010000000001000000001010011100110001000000000000010000000000000000001000000010110100100001000010010000000000000000001000000010110100100001000010010000000001000000001000000010110000000010000000010000000000000000001010000010111101000001000010010000000000000000001010000010111101000001000010010000000001000000001010000010110111111111111111010000000000000000001000010010110110101000000010010000000000000000001000010010110110101000000010010000000001000000001000010010110111111011111111010000000000000000001010010010110111100001000000010000000000000000001010010010110111100001000000010000000001000000001010010010110100101000000000010000000000000000001000001010110100100001000010010000000000000000001000001010110100100001000010010000000001000000001000001010110001000000000000010000000000000000001010001010111000100001000010010000000000000000001010001010111000100001000010010000000001000000001010001010110001000000000000010000000000000000001000011010110100100001000010010000000000000000001000011010110100100001000010010000000001000000001000011010110000000010000000010000000000000000001010011010111101000001000010010000000000000000001010011010111101000001000010010000000001000000001010011010110111111111111111010000000000000000001000000110110110101000000010010000000000000000001000000110110110101000000010010000000001000000001000000110110111111011111111010000000000000000001010000110111111100101000000010000000000000000001010000110111111100101000000010000000001000000001010000110110001101000000000010000000000000000001000010110111110001001011010010000000000000000001000010110111110001001011010010000000001000000001000010110110000000001000000010000000000000000001010010110110000000000010010010000000000000000001010010110110000000000010010010000000001000000001010010110110000000001000000010000000000000000001000001110110000000000000000010000000000000000001000001110110000000000000000010000000001000000001000001110110000000000000000010000000000000000001010001110110000000000000000010000000000000000001010001110110000000000000000010000000001000000001010001110110000000000000000010000000000000000001000011110111100100011110111010000000000000000001000011110111100100011110111010000000001000000001000011110110111111000011011010000000000000000001010011110110110101000110111010000000000000000001010011110110110101000110111010000000001000000001010011110110000000000001000010000000000000000001000000001111110101000110111010000000000000000001000000001111110101000110111010000000001000000001000000001110000000010001000010000000000000000001010000001110000000000000000010000000000000000001010000001110000000000000000010000000001000000001010000001111010001010010000010000000000000000001000010001110000000000000000010000000000000000001000010001110000000000000000010000000001000000001000010001111000001010010000010000000000000000001010010001110110101100010111010000000000000000001010010001110110101100010111010000000001000000001010010001110000000000000000010000000000000000001000001001111110101100010111010000000000000000001000001001111110101100010111010000000001000000001000001001110000000010000000010000000000000000001010001001110110101010010111010000000000000000001010001001110110101010010111010000000001000000001010001001110000000001000000010000000000000000001000011001111110101010010111010000000000000000001000011001111110101010010111010000000001000000001000011001110000000011000000010000000000000000001010011001110110101110010111010000000000000000001010011001110110101110010111010000000001000000001010011001110000000000100000010000000000000000001000000101111110101110010111010000000000000000001000000101111110101110010111010000000001000000001000000101110000000010100000010000000000000000001010000101110110101001010111010000000000000000001010000101110110101001010111010000000001000000001010000101110000000001100000010000000000000000001000010101111110101001010111010000000000000000001000010101111110101001010111010000000001000000001000010101110000000011100000010000000000000000001010010101110110101101010111010000000000000000001010010101110110101101010111010000000001000000001010010101110000000000010000010000000000000000001000001101111110101101010111010000000000000000001000001101111110101101010111010000000001000000001000001101110000000010010000010000000000000000001010001101110110101011010111010000000000000000001010001101110110101011010111010000000001000000001010001101110000000001010000010000000000000000001000011101111110101011010111010000000000000000001000011101111110101011010111010000000001000000001000011101110000000011010000010000000000000000001010011101110110101111010111010000000000000000001010011101110110101111010111010000000001000000001010011101110000000000110000010000000000000000001000000011111110101111010111010000000000000000001000000011111110101111010111010000000001000000001000000011110000000010110000010000000000000000001010000011110110101001110111010000000000000000001010000011110110101001110111010000000001000000001010000011110000000001110000010000000000000000001000010011111110101001110111010000000000000000001000010011111110101001110111010000000001000000001000010011110000000011110000010000000000000000001010010011110110101100110111010000000000000000001010010011110110101100110111010000000001000000001010010011110000000001001000010000000000000000001000001011111110101100110111010000000000000000001000001011111110101100110111010000000001000000001000001011110000000011001000010000000000000000001010001011110110101010110111010000000000000000001010001011110110101010110111010000000001000000001010001011110000000000101000010000000000000000001000011011111110101010110111010000000000000000001000011011111110101010110111010000000001000000001000011011110000000010101000010000000000000000001010011011110110101110110111010000000000000000001010011011110110101110110111010000000001000000001010011011110000000001101000010000000000000000001000000111111110101110110111010000000000000000001000000111111110101110110111010000000001000000001000000111110000000011101000010000000000000000001010000111110110101111110111010000000000000000001010000111110110101111110111010000000001000000001010000111110000000000011000010000000000000000001000010111111110101111110111010000000000000000001000010111111110101111110111010000000001000000001000010111110000000010011000010000000000000000001010010111110110000000000010010000000000000000001010010111110110000000000010010000000001000000001010010111110000000000010001010000000000000000001000001111110000000000000000010000000000000000001000001111110000000000000000010000000001000000001000001111110000000000000000010000000000000000001010001111110100100000100001010000000000000000001010001111110100100000100001010000000001000000001010001111111000000000000000010000000000000000001000011111111010100001000001010000000000000000001000011111111010100001000001010000000001000000001000011111110000000010000000010000000000000000001010011111110101000000010010010000000000000000001010011111110101000000010010010000000001000000001010011111111111111101111111001000000000000000001000000000000000000100010001001000000000000000001000000000000000000100010001001000000001000000001000000000001010001000010000001000000000000000001010000000001000000000100000001000000000000000001010000000001000000000100000001000000001000000001010000000000000100100000100001000000000000000001000010000000110000000000010001000000000000000001000010000000110000000000010001000000001000000001000010000000000000000100101001000000000000000001010010000001100100010000000001000000000000000001010010000001100100010000000001000000001000000001010010000001000000000000000001000000000000000001000001000001110001111110111001000000000000000001000001000001110001111110111001000000001000000001000001000000000000010011000001000000000000000001010001000001000000000100000001000000000000000001010001000001000000000100000001000000001000000001010001000000001000100000100001000000000000000001000011000001110001000110111001000000000000000001000011000001110001000110111001000000001000000001000011000000000000010001000001000000000000000001010011000001110001100010111001000000000000000001010011000001110001100010111001000000001000000001010011000000000000010000000001000000000000000001000000100000110001010010111001000000000000000001000000100000110001010010111001000000001000000001000000100000000000001000000001000000000000000001010000100001110001010010111001000000000000000001010000100001110001010010111001000000001000000001010000100000000000011000000001000000000000000001000010100000110001110010111001000000000000000001000010100000110001110010111001000000001000000001000010100000000000000100000001000000000000000001010010100001110001110010111001000000000000000001010010100001110001110010111001000000001000000001010010100000000000010100000001000000000000000001000001100000110001001010111001000000000000000001000001100000110001001010111001000000001000000001000001100000000000001100000001000000000000000001010001100001110001001010111001000000000000000001010001100001110001001010111001000000001000000001010001100000000000011100000001000000000000000001000011100000110001101010111001000000000000000001000011100000110001101010111001000000001000000001000011100000000000000010000001000000000000000001010011100001110001101010111001000000000000000001010011100001110001101010111001000000001000000001010011100000000000010010000001000000000000000001000000010000110001011010111001000000000000000001000000010000110001011010111001000000001000000001000000010000000000001010000001000000000000000001010000010001110001011010111001000000000000000001010000010001110001011010111001000000001000000001010000010000000000011010000001000000000000000001000010010000110001111010111001000000000000000001000010010000110001111010111001000000001000000001000010010000000000000110000001000000000000000001010010010001110001111010111001000000000000000001010010010001110001111010111001000000001000000001010010010000000000010110000001000000000000000001000001010000110001001110111001000000000000000001000001010000110001001110111001000000001000000001000001010000000000001110000001000000000000000001010001010001110001001110111001000000000000000001010001010001110001001110111001000000001000000001010001010000000000011110000001000000000000000001000011010000110001000110111001000000000000000001000011010000110001000110111001000000001000000001000011010000000000000001000001000000000000000001010011010000110001100110111001000000000000000001010011010000110001100110111001000000001000000001010011010000000000001001000001000000000000000001000000110001110001100110111001000000000000000001000000110001110001100110111001000000001000000001000000110000000000011001000001000000000000000001010000110000110001010110111001000000000000000001010000110000110001010110111001000000001000000001010000110000000000000101000001000000000000000001000010110001110001010110111001000000000000000001000010110001110001010110111001000000001000000001000010110000000000010101000001000000000000000001010010110000110001110110111001000000000000000001010010110000110001110110111001000000001000000001010010110000000000001101000001000000000000000001000001110001110001110110111001000000000000000001000001110001110001110110111001000000001000000001000001110000000000011101000001000000000000000001010001110000110001111110111001000000000000000001010001110000110001111110111001000000001000000001010001110000000000000011000001000000000000000001000011110000000000000011111001000000000000000001000011110000000000000011111001000000001000000001000011110000000000001000000001000000000000000001010011110001100100011110111001000000000000000001010011110001100100011110111001000000001000000001010011110000000000000010100001000000000000000001000000001001100100011110111001000000000000000001000000001001100100011110111001000000001000000001000000001000111111000011111001000000000000000001010000001001110101111110111001000000000000000001010000001001110101111110111001000000001000000001010000001000000000011100000001000000000000000001000010001000000000000000000001000000000000000001000010001000000000000000000001000000001000000001000010001001010010010010000001000000000000000001010010001000000000000000000001000000000000000001010010001000000000000000000001000000001000000001010010001001011010010010000001000000000000000001000001001000000000000000000001000000000000000001000001001000000000000000000001000000001000000001000001001001000110010010000001000000000000000001010001001000010100101100110001000000000000000001010001001000010100101100110001000000001000000001010001001000000000000001000001000000000000000001000011001000001010000001011001000000000000000001000011001000001010000001011001000000001000000001000011001000000000001100000001000000000000000001010011001000000000000000000001000000000000000001010011001000000000000000000001000000001000000001010011001001001000010010000001000000000000000001000000101000110000000000010001000000000000000001000000101000110000000000010001000000001000000001000000101001000000100001001001000000000000000001010000101000000000000000110001000000000000000001010000101000000000000000110001000000001000000001010000101001000100010010000001000000000000000001000010101000011010000001000001000000000000000001000010101000011010000001000001000000001000000001000010101000000000001000000001000000000000000001010010101000010100101110010001000000000000000001010010101000010100101110010001000000001000000001010010101000000000000101000001000000000000000001000001101001000000001001000001000000000000000001000001101001000000001001000001000000001000000001000001101001001011100010000001000000000000000001010001101000000000011001011001000000000000000001010001101000000000011001011001000000001000000001010001101001000000001100000001000000000000000001000011101000000000000001000001000000000000000001000011101000000000000001000001000000001000000001000011101001010010010010000001000000000000000001010011101000000000000000000001000000000000000001010011101000000000000000000001000000001000000001010011101000001011100100000001000000000000000001000000011000000000101111010001000000000000000001000000011000000000101111010001000000001000000001000000011001011010000010000001000000000000000001010000011000000000000000000001000000000000000001010000011000000000000000000001000000001000000001010000011000000000000000000001000000000000000001000010011000010100101110010001000000000000000001000010011000010100101110010001000000001000000001000010011000000000000101000001000000000000000001010010011000101000000001011001000000000000000001010010011000101000000001011001000000001000000001010010011001111111000111111001000000000000000001000001011000100100011000110001000000000000000001000001011000100100011000110001000000001000000001000001011001000000000000000001000000000000000001010001011001000000101000000001000000000000000001010001011001000000101000000001000000001000000001010001011000000100000000100001000000000000000001000011011001000000101000100001000000000000000001000011011001000000101000100001000000001000000001000011011001000100100010000001000000000000000001010011011000000000010000000001000000000000000001010011011000000000010000000001000000001000000001010011011000000100000000100001000000000000000001000000111001000000101000100001000000000000000001000000111001000000101000100001000000001000000001000000111001000100100010000001000000000000000001010000111000000000010000000001000000000000000001010000111000000000010000000001000000001000000001010000111000000100000001000001000000000000000001000010111000110000000000010001000000000000000001000010111000110000000000010001000000001000000001000010111000000000000011001001000000000000000001010010111000100100010000100001000000000000000001010010111000100100010000100001000000001000000001010010111000111111000100100001000000000000000001000001111000001000000000000001000000000000000001000001111000001000000000000001000000001000000001000001111001000000100000000001000000000000000001010001111001110001111110111001000000000000000001010001111001110001111110111001000000001000000001010001111000000000011100000001000000000000000001000011111000000000000000000001000000000000000001000011111000000000000000000001000000001000000001000011111001001000010010000001000000000000000001010011111001110001111110111001000000000000000001010011111001110001111110111001000000001000000001010011111000000000011100000001000000000000000001000000000101100100011110111001000000000000000001000000000101100100011110111001000000001000000001000000000100000000000010000001000000000000000001010000000100000000000011111001000000000000000001010000000100000000000011111001000000001000000001010000000100000000001000000001000000000000000001000010000100000000000000000001000000000000000001000010000100000000000000000001000000001000000001000010000100000000000000000001000000000000000001010010000101100100011110111001000000000000000001010010000101100100011110111001000000001000000001010010000100111111001101111001000000000000000001000001000101110101111110111001000000000000000001000001000101110101111110111001000000001000000001000001000100000000011100000001000000000000000001010001000100000000000000000001000000000000000001010001000100000000000000000001000000001000000001010001000101001000010010000001000000000000000001000011000100110000000000010001000000000000000001000011000100110000000000010001000000001000000001000011000100000000000100101001000000000000000001010011000101100100010000000001000000000000000001010011000101100100010000000001000000001000000001010011000100000000100000000001000000000000000001000000100100000000000000000001000000000000000001000000100100000000000000000001000000001000000001000000100101001111010010000001000000000000000001010000100100100100101100000001000000000000000001010000100100100100101100000001000000001000000001010000100101111111111111111001000000000000000001000010100100110101101100101001000000000000000001000010100100110101101100101001000000001000000001000010100100000000010000000001000000000000000001010010100101110001100000101001000000000000000001010010100101110001100000101001000000001000000001010010100100000000010000000001000000000000000001000001100100110101101100101001000000000000000001000001100100110101101100101001000000001000000001000001100100000000000000000001000000000000000001010001100100110101101100101001000000000000000001010001100100110101101100101001000000001000000001010001100100000000000000000001000000000000000001000011100100000000000000000001000000000000000001000011100100000000000000000001000000001000000001000011100101000111010010000001000000000000000001010011100101000000100000000001000000000000000001010011100101000000100000000001000000001000000001010011100100111000100000000001000000000000000001000000010100001100101111000001000000000000000001000000010100001100101111000001000000001000000001000000010101000000000000000001000000000000000001010000010100001010000001011001000000000000000001010000010100001010000001011001000000001000000001010000010101000000100000000001000000000000000001000010010100100100011100111001000000000000000001000010010100100100011100111001000000001000000001000010010101000000000000000001000000000000000001010010010100100100100001000001000000000000000001010010010100100100100001000001000000001000000001010010010101000000000000000001000000000000000001000001010100100100011100111001000000000000000001000001010100100100011100111001000000001000000001000001010101000000000000000001000000000000000001010001010100010100101100111001000000000000000001010001010100010100101100111001000000001000000001010001010100000000001000000001000000000000000001000011010100101000000001011001000000000000000001000011010100101000000001011001000000001000000001000011010101111111001111111001000000000000000001010011010101000000100000000001000000000000000001010011010101000000100000000001000000001000000001010011010100011000100001000001000000000000000001000000110100100100111101111001000000000000000001000000110100100100111101111001000000001000000001000000110101000000000000000001000000000000000001010000110100010100101101111001000000000000000001010000110100010100101101111001000000001000000001010000110100000000101000000001000000000000000001000010110100101010000001011001000000000000000001000010110100101010000001011001000000001000000001000010110101111111111011111001000000000000000001010010110100100100101100000001000000000000000001010010110100100100101100000001000000001000000001010010110101111111111111111001000000000000000001000001110101110001111110111001000000000000000001000001110101110001111110111001000000001000000001000001110100000000011100000001000000000000000001010001110101100100011110111001000000000000000001010001110101100100011110111001000000001000000001010001110100000000001010000001000000000000000001000011110100000000000011111001000000000000000001000011110100000000000011111001000000001000000001000011110100000000001000000001000000000000000001010011110100000000000000000001000000000000000001010011110100000000000000000001000000001000000001010011110100000000000000000001000000000000000001000000001101100100011110111001000000000000000001000000001101100100011110111001000000001000000001000000001100111111001101111001000000000000000001010000001101110101111110111001000000000000000001010000001101110101111110111001000000001000000001010000001100000000011100000001000000000000000001000010001100110101010010111001000000000000000001000010001100110101010010111001000000001000000001000010001100000000000010000001000000000000000001010010001100000101000010111001000000000000000001010010001100000101000010111001000000001000000001010010001101000000110010000001000000000000000001000001001100000000000000000001000000000000000001000001001100000000000000000 + 1000000000000000000001000000000001001000001110110000000000000000000000100000000000100000000100000000000100000100000000100100000000000000000010000000000000000000010100000000010000000000000000000100000111011000001000000000000000000001000000010001000000010000000100000000000000010000100000000000100000000100000001000100001011000000000000000000000001000010000000000000000000010100000100010000000100000001000000001000000010001000000000000000000001010000010001000000010000000100000000000100010000100000000000100000000101000001000100001001000000000000000000010001000010000000000000000000010000100100010000000100000001000000001000000010001000000000000000000001000010010001000000010000000100000000000010010000100000000000100000000100001001000100001101000000000000000000001001000010000000000000000000010100100100010001111000010000000000001000000010001000000000000000000001010010010001000111100001000000000000000110010000100000000000100000000101001001000100010010100011100000000000011001000010000000000000000000010000010100010001001000010000100011110000100000001000000000000000000001000001010001000100100001000010000000000001010000100000000000100000000100000101000100000000000000000000000000000101000010000000000000000000010100010100010011100010010000100010010000100001001000000000000000000001010001010001001110001001000010000000000101010000100000000000100000000101000101000100000000001100000000000000010101000010000000000000000000010000110100010001010000000100100111000100100001001000000000000000000001000011010001000101000000010010000000000011010000100000000000100000000100001101000100100000001101110000000000001101000010000000000000000000010100110100010000000000000000000010100000001001001000000000000000000001010011010001000000000000000000000000000111010000100000000000100000000101001101000100000000000000000000000000011101000010000000000000000000010000001100010011001000111101110000000000000000001000000000000000000001000000110001001100100011110111000000000000110000100000000000100000000100000011000100011111100101111100000000000011000010000000000000000000010100001100010011101011001101110110010001111011101000000000000000000001010000110001001110101100110111000000000100110000100000000000100000000101000011000100000000000000000000000000010011000010000000000000000000010000101100010001101010101101110111010110011011101000000000000000000001000010110001000110101010110111000000000010110000100000000000100000000100001011000100000000001000000000000000001011000010000000000000000000010100101100010011101010101101110011010101011011101000000000000000000001010010110001001110101010110111000000000110110000100000000000100000000101001011000100000000000100000000000000011011000010000000000000000000010000011100010001101011101101110111010101011011101000000000000000000001000001110001000110101110110111000000000001110000100000000000100000000100000111000100000000001100000000000000000111000010000000000000000000010100011100010011101011101101110011010111011011101000000000000000000001010001110001001110101110110111000000000101110000100000000000100000000101000111000100000000000010000000000000010111000010000000000000000000010000111100010001111000010000000111010111011011101000000000000000000001000011110001000111100001000000000000000011110000100000000000100000000100001111000100010010100011100000000000001111000010000000000000000000010100111100010001001000010000100011110000100000001000000000000000000001010011110001000100100001000010000000000111110000100000000000100000000101001111000100000000000000000000000000011111000010000000000000000000010000000010010001111001010000000010010000100001001000000000000000000001000000001001000111100101000000000000000000001000100000000000100000000100000000100100000010100111111100000000000000100010000000000000000000010100000010010011111001010000000011110010100000001000000000000000000001010000001001001111100101000000000000000100001000100000000000100000000101000000100100000010100011111100000000010000100010000000000000000000010000100010010001111000110000000111110010100000001000000000000000000001000010001001000111100011000000000000000010001000100000000000100000000100001000100100010010100011000000000000001000100010000000000000000000010100100010010001001000110001100011110001100000001000000000000000000001010010001001000100100011000110000000000110001000100000000000100000000101001000100100000000000000000000000000011000100010000000000000000000010000010010010011011000010000000010010001100011001000000000000000000001000001001001001101100001000000000000000001001000100000000000100000000100000100100100000000000000100000000000000100100010000000000000000000010100010010010011101010010000100110110000100000001000000000000000000001010001001001001110101001000010000000000101001000100000000000100000000101000100100100000000001000000000000000010100100010000000000000000000010000110010010011001000001000000111010100100001001000000000000000000001000011001001001100100000100000000000000011001000100000000000100000000100001100100100011100000000101100000000001100100010000000000000000000010100110010010000000000000000000110010000010000001000000000000000000001010011001001000000000000000000000000000111001000100000000000100000000101001100100100000000000000000000000000011100100010000000000000000000010000001010010010001000001100010000000000000000001000000000000000000001000000101001001000100000110001000000000000101000100000000000100000000100000010100100111111111111111100000000000010100010000000000000000000010100001010010001010000000100010100010000011000101000000000000000000001010000101001000101000000010001000000000100101000100000000000100000000101000010100100111111101111111100000000010010100010000000000000000000010000101010010000000000000000000010100000001000101000000000000000000001000010101001000000000000000000000000000010101000100000000000100000000100001010100100000000000000000000000000001010100010000000000000000000010100101010010001101010000000100000000000000000001000000000000000000001010010101001000110101000000010000000000110101000100000000000100000000101001010100100000000000100000000000000011010100010000000000000000000010000011010010011011000010000000011010100000001001000000000000000000001000001101001001101100001000000000000000001101000100000000000100000000100000110100100000000001010000000000000000110100010000000000000000000010100011010010011101010010000100110110000100000001000000000000000000001010001101001001110101001000010000000000101101000100000000000100000000101000110100100000000001100000000000000010110100010000000000000000000010000111010010001101010000000100111010100100001001000000000000000000001000011101001000110101000000010000000000011101000100000000000100000000100001110100100000000000000000000000000001110100010000000000000000000010100111010010011001000001000000011010100000001001000000000000000000001010011101001001100100000100000000000000111101000100000000000100000000101001110100100000000001000000000000000011110100010000000000000000000010000000110010000000000000000000110010000010000001000000000000000000001000000011001000000000000000000000000000000011000100000000000100000000100000001100100000000000000000000000000000001100010000000000000000000010100000110010010001000001100010000000000000000001000000000000000000001010000011001001000100000110001000000000100011000100000000000100000000101000001100100111111111111111100000000010001100010000000000000000000010000100110010001010000000100010100010000011000101000000000000000000001000010011001000101000000010001000000000010011000100000000000100000000100001001100100111111101111111100000000001001100010000000000000000000010100100110010000000000000000000010100000001000101000000000000000000001010010011001000000000000000000000000000110011000100000000000100000000101001001100100000000000000000000000000011001100010000000000000000000010000010110010011011000010000000000000000000000001000000000000000000001000001011001001101100001000000000000000001011000100000000000100000000100000101100100000000011100000000000000000101100010000000000000000000010100010110010011101010010000100110110000100000001000000000000000000001010001011001001110101001000010000000000101011000100000000000100000000101000101100100000000000000000000000000010101100010000000000000000000010000110110010011001000001000000111010100100001001000000000000000000001000011011001001100100000100000000000000011011000100000000000100000000100001101100100000000000001000000000000001101100010000000000000000000010100110110010010001000001100010110010000010000001000000000000000000001010011011001001000100000110001000000000111011000100000000000100000000101001101100100111111111111111100000000011101100010000000000000000000010000001110010001010000000100010100010000011000101000000000000000000001000000111001000101000000010001000000000000111000100000000000100000000100000011100100011111111111111100000000000011100010000000000000000000010100001110010011011000010000000010100000001000101000000000000000000001010000111001001101100001000000000000000100111000100000000000100000000101000011100100100000011100001000000000010011100010000000000000000000010000101110010011101010010001100110110000100000001000000000000000000001000010111001001110101001000110000000000010111000100000000000100000000100001011100100000000000000000000000000001011100010000000000000000000010100101110010011111000010000000111010100100011001000000000000000000001010010111001001111100001000000000000000110111000100000000000100000000101001011100100001100000100000000000000011011100010000000000000000000010000011110010011011000010100100111110000100000001000000000000000000001000001111001001101100001010010000000000001111000100000000000100000000100000111100100001010000111000000000000000111100010000000000000000000010100011110010011101010010010100110110000101001001000000000000000000001010001111001001110101001001010000000000101111000100000000000100000000101000111100100000000000100000000000000010111100010000000000000000000010000111110010001101010000010100111010100100101001000000000000000000001000011111001000110101000001010000000000011111000100000000000100000000100001111100100000000001010000000000000001111100010000000000000000000010100111110010011111000010000000011010100000101001000000000000000000001010011111001001111100001000000000000000111111000100000000000100000000101001111100100000000100000000000000000011111100010000000000000000000010000000001010011101010010010100111110000100000001000000000000000000001000000000101001110101001001010000000000000000100100000000000100000000100000000010100000000001000000000000000000000010010000000000000000000010100000001010000000000000000000111010100100101001000000000000000000001010000000101000000000000000000000000000100000100100000000000100000000101000000010100101011001001000000000000010000010010000000000000000000010000100001010000000000000000000000000000000000001000000000000000000001000010000101000000000000000000000000000010000100100000000000100000000100001000010100100111001001000000000000001000010010000000000000000000010100100001010011111001110000000000000000000000001000000000000000000001010010000101001111100111000000000000000110000100100000000000100000000101001000010100000010100011111100000000011000010010000000000000000000010000010001010000000000000000000111110011100000001000000000000000000001000001000101000000000000000000000000000001000100100000000000100000000100000100010100100001101001000000000000000100010010000000000000000000010100010001010011111000011000000000000000000000001000000000000000000001010001000101001111100001100000000000000101000100100000000000100000000101000100010100000010100011111100000000010100010010000000000000000000010000110001010001111001101000000111110000110000001000000000000000000001000011000101000111100110100000000000000011000100100000000000100000000100001100010100000010100000000000000000001100010010000000000000000000010100110001010000000000000000000011110011010000001000000000000000000001010011000101000000000000000000000000000111000100100000000000100000000101001100010100101110101001000000000000011100010010000000000000000000010000001001010001111001100000000000000000000000001000000000000000000001000000100101000111100110000000000000000000100100100000000000100000000100000010010100000010100011111100000000000010010010000000000000000000010100001001010011111001100000000011110011000000001000000000000000000001010000100101001111100110000000000000000100100100100000000000100000000101000010010100000010100000000000000000010010010010000000000000000000010000101001010000000000000000000111110011000000001000000000000000000001000010100101000000000000000000000000000010100100100000000000100000000100001010010100100100101001000000000000001010010010000000000000000000010100101001010001111000101000000000000000000000001000000000000000000001010010100101000111100010100000000000000110100100100000000000100000000101001010010100000010100000000000000000011010010010000000000000000000010000011001010011001000111101110011110001010000001000000000000000000001000001100101001100100011110111000000000001100100100000000000100000000100000110010100011111100111011100000000000110010010000000000000000000010100011001010000000000000101110110010001111011101000000000000000000001010001100101000000000000010111000000000101100100100000000000100000000101000110010100100111101001000000000000010110010010000000000000000000010000111001010001111000001000000000000000001011101000000000000000000001000011100101000111100000100000000000000011100100100000000000100000000100001110010100010010100011000000000000001110010010000000000000000000010100111001010001100010001000010011110000010000001000000000000000000001010011100101000110001000100001000000000111100100100000000000100000000101001110010100000000001000000000000000011110010010000000000000000000010000000101010011111000001000000011000100010000101000000000000000000001000000010101001111100000100000000000000000010100100000000000100000000100000001010100100000000000001000000000000001010010000000000000000000010100000101010011001000001100010111110000010000001000000000000000000001010000010101001100100000110001000000000100010100100000000000100000000101000001010100100000000000001000000000010001010010000000000000000000010000100101010011010000001000010110010000011000101000000000000000000001000010010101001101000000100001000000000010010100100000000000100000000100001001010100100000001000000000000000001001010010000000000000000000010100100101010000000000000000000110100000010000101000000000000000000001010010010101000000000000000000000000000110010100100000000000100000000101001001010100000000000000000000000000011001010010000000000000000000010000010101010001001000001000000000000000000000001000000000000000000001000001010101000100100000100000000000000001010100100000000000100000000100000101010100000000000000000100000000000101010010000000000000000000010100010101010011011000001110100010010000010000001000000000000000000001010001010101001101100000111010000000000101010100100000000000100000000101000101010100000001000000000000000000010101010010000000000000000000010000110101010000010000000000000110110000011101001000000000000000000001000011010101000001000000000000000000000011010100100000000000100000000100001101010100100000010000000000000000001101010010000000000000000000010100110101010000000000000000000000100000000000001000000000000000000001010011010101000000000000000000000000000111010100100000000000100000000101001101010100000000000000000000000000011101010010000000000000000000010000001101010001001000001000000000000000000000001000000000000000000001000000110101000100100000100000000000000000110100100000000000100000000100000011010100010000000000000000000000000011010010000000000000000000010100001101010011011000001110100010010000010000001000000000000000000001010000110101001101100000111010000000000100110100100000000000100000000101000011010100000000100000000000000000010011010010000000000000000000010000101101010001101011110100010110110000011101001000000000000000000001000010110101000110101111010001000000000010110100100000000000100000000100001011010100000000001000000000000000001011010010000000000000000000010100101101010011001000101111100011010111101000101000000000000000000001010010110101001100100010111110000000000110110100100000000000100000000101001011010100000000001100000000000000011011010010000000000000000000010000011101010001100000000000100110010001011111001000000000000000000001000001110101000110000000000010000000000001110100100000000000100000000100000111010100000000011110111000000000000111010010000000000000000000010100011101010000000000000000000011000000000001001000000000000000000001010001110101000000000000000000000000000101110100100000000000100000000101000111010100000000000000000000000000010111010010000000000000000000010000111101010000010000000010000000000000000000001000000000000000000001000011110101000001000000001000000000000011110100100000000000100000000100001111010100000000000111000000000000001111010010000000000000000000010100111101010000000000000000000000100000000100001000000000000000000001010011110101000000000000000000000000000111110100100000000000100000000101001111010100000000000000000000000000011111010010000000000000000000010000000011010001101011000101110000000000000000001000000000000000000001000000001101000110101100010111000000000000001100100000000000100000000100000000110100000000000000000000000000000000110010000000000000000000010100000011010011001000010000000011010110001011101000000000000000000001010000001101001100100001000000000000000100001100100000000000100000000101000000110100000010000000000000000000010000110010000000000000000000010000100011010011101010010001100110010000100000001000000000000000000001000010001101001110101001000110000000000010001100100000000000100000000100001000110100000000000000000000000000001000110010000000000000000000010100100011010011100011010111100111010100100011001000000000000000000001010010001101001110001101011110000000000110001100100000000000100000000101001000110100000000000000000000000000011000110010000000000000000000010000010011010001111000010000000111000110101111001000000000000000000001000001001101000111100001000000000000000001001100100000000000100000000100000100110100100111111111110000000000000100110010000000000000000000010100010011010000000000010110100011110000100000001000000000000000000001010001001101000000000001011010000000000101001100100000000000100000000101000100110100001101001001000000000000010100110010000000000000000000010000110011010011101011010101110000000000101101001000000000000000000001000011001101001110101101010111000000000011001100100000000000100000000100001100110100000000001000000000000000001100110010000000000000000000010100110011010010001000111101110111010110101011101000000000000000000001010011001101001000100011110111000000000111001100100000000000100000000101001100110100000000000100000000000000011100110010000000000000000000010000001011010011001000010000000100010001111011101000000000000000000001000000101101001100100001000000000000000000101100100000000000100000000100000010110100000100000000000000000000000010110010000000000000000000010100001011010011101010010001100110010000100000001000000000000000000001010000101101001110101001000110000000000100101100100000000000100000000101000010110100000000000000000000000000010010110010000000000000000000010000101011010001111000010000000111010100100011001000000000000000000001000010101101000111100001000000000000000010101100100000000000100000000100001010110100100110100110000000000000001010110010000000000000000000010100101011010001010000010110100011110000100000001000000000000000000001010010101101000101000001011010000000000110101100100000000000100000000101001010110100000000001100000000000000011010110010000000000000000000010000011011010000000000000000000010100000101101001000000000000000000001000001101101000000000000000000000000000001101100100000000000100000000100000110110100000000000000000000000000000110110010000000000000000000010100011011010001111000010000000000000000000000001000000000000000000001010001101101000111100001000000000000000101101100100000000000100000000101000110110100001000000000000000000000010110110010000000000000000000010000111011010000000000010000110011110000100000001000000000000000000001000011101101000000000001000011000000000011101100100000000000100000000100001110110100000001100001000000000000001110110010000000000000000000010100111011010000000000001100110000000000100001101000000000000000000001010011101101000000000000110011000000000111101100100000000000100000000101001110110100001001100001000000000000011110110010000000000000000000010000000111010000000000001100110000000000011001101000000000000000000001000000011101000000000000110011000000000000011100100000000000100000000100000001110100001001100001000000000000000001110010000000000000000000010100000111010001111000010000000000000000011001101000000000000000000001010000011101000111100001000000000000000100011100100000000000100000000101000001110100000000000001000000000000010001110010000000000000000000010000100111010000000000010011010011110000100000001000000000000000000001000010011101000000000001001101000000000010011100100000000000100000000100001001110100000110100001000000000000001001110010000000000000000000010100100111010000000000010001010000000000100110101000000000000000000001010010011101000000000001000101000000000110011100100000000000100000000101001001110100000010100001000000000000011001110010000000000000000000010000010111010000000001001000000000000000100010101000000000000000000001000001011101000000000100100000000000000001011100100000000000100000000100000101110100000100100000100000000000000101110010000000000000000000010100010111010000001001001010010000000010010000001000000000000000000001010001011101000000100100101001000000000101011100100000000000100000000101000101110100100000000000000000000000010101110010000000000000000000010000110111010000010000000000000000010010010100101000000000000000000001000011011101000001000000000000000000000011011100100000000000100000000100001101110100100000010000000000000000001101110010000000000000000000010100110111010000000000000000000000100000000000001000000000000000000001010011011101000000000000000000000000000111011100100000000000100000000101001101110100000000000000000000000000011101110010000000000000000000010000001111010001111000010000000000000000000000001000000000000000000001000000111101000111100001000000000000000000111100100000000000100000000100000011110100000000000010000000000000000011110010000000000000000000010100001111010000000000010001010011110000100000001000000000000000000001010000111101000000000001000101000000000100111100100000000000100000000101000011110100000010100001000000000000010011110010000000000000000000010000101111010001001000010000000000000000100010101000000000000000000001000010111101000100100001000000000000000010111100100000000000100000000100001011110100000010000000000000000000001011110010000000000000000000010100101111010001101010010001100010010000100000001000000000000000000001010010111101000110101001000110000000000110111100100000000000100000000101001011110100000000000000000000000000011011110010000000000000000000010000011111010011100010010111100011010100100011001000000000000000000001000001111101001110001001011110000000000001111100100000000000100000000100000111110100000000001001000000000000000111110010000000000000000000010100011111010001100011011111100111000100101111001000000000000000000001010001111101000110001101111110000000000101111100100000000000100000000101000111110100000000000000000000000000010111110010000000000000000000010000111111010001001000010000000011000110111111001000000000000000000001000011111101000100100001000000000000000011111100100000000000100000000100001111110100000100000000000000000000001111110010000000000000000000010100111111010001101010010001100010010000100000001000000000000000000001010011111101000110101001000110000000000111111100100000000000100000000101001111110100000000000000000000000000011111110010000000000000000000010000000000110010011000010100100011010100100011001000000000000000000001000000000011001001100001010010000000000000000010100000000000100000000100000000001100111111111111111100000000000000001010000000000000000000010100000000110001001000010000000100110000101001001000000000000000000001010000000011000100100001000000000000000100000010100000000000100000000101000000001100010000000000001000000000010000001010000000000000000000010000100000110001010000010100100010010000100000001000000000000000000001000010000011000101000001010010000000000010000010100000000000100000000100001000001100100000000100000000000000001000001010000000000000000000010100100000110000000000000000000010100000101001001000000000000000000001010010000011000000000000000000000000000110000010100000000000100000000101001000001100000000000000000000000000011000001010000000000000000000010000010000110011111001011000000000000000000000001000000000000000000001000001000011001111100101100000000000000001000010100000000000100000000100000100001100000000000000001000000000000100001010000000000000000000010100010000110010000001011010110111110010110000001000000000000000000001010001000011001000000101101011000000000101000010100000000000100000000101000100001100000101101001000000000000010100001010000000000000000000010000110000110001010000000010110100000010110101101000000000000000000001000011000011000101000000001011000000000011000010100000000000100000000100001100001100100000001000000000000000001100001010000000000000000000010100110000110000000000000000000010100000000101101000000000000000000001010011000011000000000000000000000000000111000010100000000000100000000101001100001100000000000000000000000000011100001010000000000000000000010000001000110001111000010000000000000000000000001000000000000000000001000000100011000111100001000000000000000000100010100000000000100000000100000010001100000100001110000000000000000010001010000000000000000000010100001000110001011000010000100011110000100000001000000000000000000001010000100011000101100001000010000000000100100010100000000000100000000101000010001100001000001000000100000000010010001010000000000000000000010000101000110001101010010111100010110000100001001000000000000000000001000010100011000110101001011110000000000010100010100000000000100000000100001010001100000000000110000000000000001010001010000000000000000000010100101000110000010000000000000011010100101111001000000000000000000001010010100011000001000000000000000000000110100010100000000000100000000101001010001100100000010000000000000000011010001010000000000000000000010000011000110001111000010000000000100000000000001000000000000000000001000001100011000111100001000000000000000001100010100000000000100000000100000110001100001000001100000000000000000110001010000000000000000000010100011000110001011000010000100011110000100000001000000000000000000001010001100011000101100001000010000000000101100010100000000000100000000101000110001100000100001000000100000000010110001010000000000000000000010000111000110001101010010111100010110000100001001000000000000000000001000011100011000110101001011110000000000011100010100000000000100000000100001110001100000000000110000000000000001110001010000000000000000000010100111000110001111000010000000011010100101111001000000000000000000001010011100011000111100001000000000000000111100010100000000000100000000101001110001100001000000000000000000000011110001010000000000000000000010000000100110000000000010011100011110000100000001000000000000000000001000000010011000000000001001110000000000000010010100000000000100000000100000001001100000111000001000000000000000001001010000000000000000000010100000100110000000000001111100000000000100111001000000000000000000001010000010011000000000000111110000000000100010010100000000000100000000101000001001100001111000001000000000000010001001010000000000000000000010000100100110000000000001111100000000000011111001000000000000000000001000010010011000000000000111110000000000010010010100000000000100000000100001001001100001111000001000000000000001001001010000000000000000000010100100100110011001000110101100000000000011111001000000000000000000001010010010011001100100011010110000000000110010010100000000000100000000101001001001100100000000000000000000000011001001010000000000000000000010000010100110001101000010101100110010001101011001000000000000000000001000001010011000110100001010110000000000001010010100000000000100000000100000101001100000000000100000000000000000101001010000000000000000000010100010100110001010000000000100011010000101011001000000000000000000001010001010011000101000000000010000000000101010010100000000000100000000101000101001100011111101000111100000000010101001010000000000000000000010000110100110000000000000000000010100000000001001000000000000000000001000011010011000000000000000000000000000011010010100000000000100000000100001101001100000000000000000000000000001101001010000000000000000000010100110100110001111000010000000000000000000000001000000000000000000001010011010011000111100001000000000000000111010010100000000000100000000101001101001100010001100000000000000000011101001010000000000000000000010000001100110001101010010010100011110000100000001000000000000000000001000000110011000110101001001010000000000000110010100000000000100000000100000011001100000000001100000000000000000011001010000000000000000000010100001100110001111000010000000011010100100101001000000000000000000001010000110011000111100001000000000000000100110010100000000000100000000101000011001100000000100000000000000000010011001010000000000000000000010000101100110001101010010010100011110000100000001000000000000000000001000010110011000110101001001010000000000010110010100000000000100000000100001011001100000000001000000000000000001011001010000000000000000000010100101100110000000000000011110011010100100101001000000000000000000001010010110011000000000000001111000000000110110010100000000000100000000101001011001100101011101001000000000000011011001010000000000000000000010000011100110000000000000000000000000000000111101000000000000000000001000001110011000000000000000000000000000001110010100000000000100000000100000111001100101100001001000000000000000111001010000000000000000000010100011100110011100010010101110000000000000000001000000000000000000001010001110011001110001001010111000000000101110010100000000000100000000101000111001100000000001000000000000000010111001010000000000000000000010000111100110001111000010000000111000100101011101000000000000000000001000011110011000111100001000000000000000011110010100000000000100000000100001111001100100110100100000000000000001111001010000000000000000000010100111100110001010000010100100011110000100000001000000000000000000001010011110011000101000001010010000000000111110010100000000000100000000101001111001100000000011010000000000000011111001010000000000000000000010000000010110000000000000000000010100000101001001000000000000000000001000000001011000000000000000000000000000000001010100000000000100000000100000000101100000000000000000000000000000000101010000000000000000000010100000010110001101010011100010000000000000000001000000000000000000001010000001011000110101001110001000000000100001010100000000000100000000101000000101100000000001000000000000000010000101010000000000000000000010000100010110011001000101100110011010100111000101000000000000000000001000010001011001100100010110011000000000010001010100000000000100000000100001000101100000000001100000000000000001000101010000000000000000000010100100010110001100010100101110110010001011001101000000000000000000001010010001011000110001010010111000000000110001010100000000000100000000101001000101100000000000000000000000000011000101010000000000000000000010000010010110010001000111101110011000101001011101000000000000000000001000001001011001000100011110111000000000001001010100000000000100000000100000100101100000000000100000000000000000100101010000000000000000000010100010010110011001000100000000100010001111011101000000000000000000001010001001011001100100010000000000000000101001010100000000000100000000101000100101100100000000000000000000000010100101010000000000000000000010000110010110001100000000000100110010001000000001000000000000000000001000011001011000110000000000010000000000011001010100000000000100000000100001100101100000000000010010100000000001100101010000000000000000000010100110010110000000000000000000011000000000001001000000000000000000001010011001011000000000000000000000000000111001010100000000000100000000101001100101100000000000000000000000000011100101010000000000000000000010000001010110001100010010011010000000000000000001000000000000000000001000000101011000110001001001101000000000000101010100000000000100000000100000010101100000000000000000000000000000010101010000000000000000000010100001010110001111000010000000011000100100110101000000000000000000001010000101011000111100001000000000000000100101010100000000000100000000101000010101100000000000100000000000000010010101010000000000000000000010000101010110000000001101000100011110000100000001000000000000000000001000010101011000000000110100010000000000010101010100000000000100000000100001010101100000001000001000000000000001010101010000000000000000000010100101010110011100010010000100000000011010001001000000000000000000001010010101011001110001001000010000000000110101010100000000000100000000101001010101100000000000000000000000000011010101010000000000000000000010000011010110001100010010011010111000100100001001000000000000000000001000001101011000110001001001101000000000001101010100000000000100000000100000110101100000000000000000000000000000110101010000000000000000000010100011010110001111000010000000011000100100110101000000000000000000001010001101011000111100001000000000000000101101010100000000000100000000101000110101100000000000100000000000000010110101010000000000000000000010000111010110000000001101000100011110000100000001000000000000000000001000011101011000000000110100010000000000011101010100000000000100000000100001110101100000001000001000000000000001110101010000000000000000000010100111010110011100010010000100000000011010001001000000000000000000001010011101011001110001001000010000000000111101010100000000000100000000101001110101100000000000000000000000000011110101010000000000000000000010000000110110001111000010000000111000100100001001000000000000000000001000000011011000111100001000000000000000000011010100000000000100000000100000001101100010000000000000000000000000001101010000000000000000000010100000110110000000000010011100011110000100000001000000000000000000001010000011011000000000001001110000000000100011010100000000000100000000101000001101100000111000001000000000000010001101010000000000000000000010000100110110000000000001100110000000000100111001000000000000000000001000010011011000000000000110011000000000010011010100000000000100000000100001001101100001001100001000000000000001001101010000000000000000000010100100110110001111000010000000000000000011001101000000000000000000001010010011011000111100001000000000000000110011010100000000000100000000101001001101100000000000010000000000000011001101010000000000000000000010000010110110000000000010011010011110000100000001000000000000000000001000001011011000000000001001101000000000001011010100000000000100000000100000101101100000110100001000000000000000101101010000000000000000000010100010110110000010000000000000000000000100110101000000000000000000001010001011011000001000000000000000000000101011010100000000000100000000101000101101100100000000001000000000000010101101010000000000000000000010000110110110011101011101100010000100000000000001000000000000000000001000011011011001110101110110001000000000011011010100000000000100000000100001101101100000000001000000000000000001101101010000000000000000000010100110110110011001000101011000111010111011000101000000000000000000001010011011011001100100010101100000000000111011010100000000000100000000101001101101100000000001100000000000000011101101010000000000000000000010000001110110001100010100101110110010001010110001000000000000000000001000000111011000110001010010111000000000000111010100000000000100000000100000011101100000000000000000000000000000011101010000000000000000000010100001110110010001000111101110011000101001011101000000000000000000001010000111011001000100011110111000000000100111010100000000000100000000101000011101100000000000100000000000000010011101010000000000000000000010000101110110011001000100000000100010001111011101000000000000000000001000010111011001100100010000000000000000010111010100000000000100000000100001011101100100000000000000000000000001011101010000000000000000000010100101110110001100000000000100110010001000000001000000000000000000001010010111011000110000000000010000000000110111010100000000000100000000101001011101100000000000010010100000000011011101010000000000000000000010000011110110000000000000000000011000000000001001000000000000000000001000001111011000000000000000000000000000001111010100000000000100000000100000111101100000000000000000000000000000111101010000000000000000000010100011110110001100010010111000000000000000000001000000000000000000001010001111011000110001001011100000000000101111010100000000000100000000101000111101100000000000000000000000000010111101010000000000000000000010000111110110001111000010000000011000100101110001000000000000000000001000011111011000111100001000000000000000011111010100000000000100000000100001111101100000000000100000000000000001111101010000000000000000000010100111110110010000001100000100011110000100000001000000000000000000001010011111011001000000110000010000000000111111010100000000000100000000101001111101100000001000001000000000000011111101010000000000000000000010000000001110011100010010000100100000011000001001000000000000000000001000000000111001110001001000010000000000000000110100000000000100000000100000000011100000000000000000000000000000000011010000000000000000000010100000001110001111000010000000111000100100001001000000000000000000001010000000111000111100001000000000000000100000110100000000000100000000101000000011100000000000010000000000000010000011010000000000000000000010000100001110010000001100000100011110000100000001000000000000000000001000010000111001000000110000010000000000010000110100000000000100000000100001000011100000001000001000000000000001000011010000000000000000000010100100001110011100010010000100100000011000001001000000000000000000001010010000111001110001001000010000000000110000110100000000000100000000101001000011100000000000000000000000000011000011010000000000000000000010000010001110001111000010000000111000100100001001000000000000000000001000001000111000111100001000000000000000001000110100000000000100000000100000100011100000000000110000000000000000100011010000000000000000000010100010001110010000001100000100011110000100000001000000000000000000001010001000111001000000110000010000000000101000110100000000000100000000101000100011100000001000001000000000000010100011010000000000000000000010000110001110011100010010000100100000011000001001000000000000000000001000011000111001110001001000010000000000011000110100000000000100000000100001100011100000000000000000000000000001100011010000000000000000000010100110001110001100010010111000111000100100001001000000000000000000001010011000111000110001001011100000000000111000110100000000000100000000101001100011100000000000000000000000000011100011010000000000000000000010000001001110001111000010000000011000100101110001000000000000000000001000000100111000111100001000000000000000000100110100000000000100000000100000010011100000000000100000000000000000010011010000000000000000000010100001001110010000001100000100011110000100000001000000000000000000001010000100111001000000110000010000000000100100110100000000000100000000101000010011100000001000001000000000000010010011010000000000000000000010000101001110011100010010000100100000011000001001000000000000000000001000010100111001110001001000010000000000010100110100000000000100000000100001010011100000000000000000000000000001010011010000000000000000000010100101001110001111000010000000111000100100001001000000000000000000001010010100111000111100001000000000000000110100110100000000000100000000101001010011100000000000010000000000000011010011010000000000000000000010000011001110010000001100000100011110000100000001000000000000000000001000001100111001000000110000010000000000001100110100000000000100000000100000110011100000001000001000000000000000110011010000000000000000000010100011001110011100010010000100100000011000001001000000000000000000001010001100111001110001001000010000000000101100110100000000000100000000101000110011100000000000000000000000000010110011010000000000000000000010000111001110001111000010000000111000100100001001000000000000000000001000011100111000111100001000000000000000011100110100000000000100000000100001110011100000000000110000000000000001110011010000000000000000000010100111001110010000001100000100011110000100000001000000000000000000001010011100111001000000110000010000000000111100110100000000000100000000101001110011100000001000001000000000000011110011010000000000000000000010000000101110011100010010000100100000011000001001000000000000000000001000000010111001110001001000010000000000000010110100000000000100000000100000001011100000000000000000000000000000001011010000000000000000000010100000101110001111000010000000111000100100001001000000000000000000001010000010111000111100001000000000000000100010110100000000000100000000101000001011100001000000000000000000000010001011010000000000000000000010000100101110000000000010111010011110000100000001000000000000000000001000010010111000000000001011101000000000010010110100000000000100000000100001001011100001110100001000000000000001001011010000000000000000000010100100101110000000000001011000000000000101110101000000000000000000001010010010111000000000000101100000000000110010110100000000000100000000101001001011100000110000001000000000000011001011010000000000000000000010000010101110000000000001011000000000000010110001000000000000000000001000001010111000000000000101100000000000001010110100000000000100000000100000101011100000110000001000000000000000101011010000000000000000000010100010101110001111000010000000000000000010110001000000000000000000001010001010111000111100001000000000000000101010110100000000000100000000101000101011100000000000001000000000000010101011010000000000000000000010000110101110000000000010111000011110000100000001000000000000000000001000011010111000000000001011100000000000011010110100000000000100000000100001101011100001110000001000000000000001101011010000000000000000000010100110101110011001001000110000000000000101110001000000000000000000001010011010111001100100100011000000000000111010110100000000000100000000101001101011100100000000000000000000000011101011010000000000000000000010000001101110010000000110110000110010010001100001000000000000000000001000000110111001000000011011000000000000000110110100000000000100000000100000011011100000001010101000000000000000011011010000000000000000000010100001101110001010000000000100100000001101100001000000000000000000001010000110111000101000000000010000000000100110110100000000000100000000101000011011100111111110000111100000000010011011010000000000000000000010000101101110000000000000000000010100000000001001000000000000000000001000010110111000000000000000000000000000010110110100000000000100000000100001011011100000000000000000000000000001011011010000000000000000000010100101101110001111001010000000000000000000000001000000000000000000001010010110111000111100101000000000000000110110110100000000000100000000101001011011100010010100011100000000000011011011010000000000000000000010000011101110000000001001000000011110010100000001000000000000000000001000001110111000000000100100000000000000001110110100000000000100000000100000111011100010100100000110000000000000111011010000000000000000000010100011101110011111000010000000000000010010000001000000000000000000001010001110111001111100001000000000000000101110110100000000000100000000101000111011100000000011000000000000000010111011010000000000000000000010000111101110011011000010100100111110000100000001000000000000000000001000011110111001101100001010010000000000011110110100000000000100000000100001111011100010110001011000100000000001111011010000000000000000000010100111101110000000001001100100110110000101001001000000000000000000001010011110111000000000100110010000000000111110110100000000000100000000101001111011100101001001001000000000000011111011010000000000000000000010000000011110011101010010010100000000010011001001000000000000000000001000000001111001110101001001010000000000000001110100000000000100000000100000000111100000000000010000000000000000000111010000000000000000000010100000011110011100010010010100111010100100101001000000000000000000001010000001111001110001001001010000000000100001110100000000000100000000101000000111100000000000010000000000000010000111010000000000000000000010000100011110001111000010000000111000100100101001000000000000000000001000010001111000111100001000000000000000010001110100000000000100000000100001000111100000010100000000000000000001000111010000000000000000000010100100011110001011000010000100011110000100000001000000000000000000001010010001111000101100001000010000000000110001110100000000000100000000101001000111100000000000000001100000000011000111010000000000000000000010000010011110011111000010000000010110000100001001000000000000000000001000001001111001111100001000000000000000001001110100000000000100000000100000100111100111000011111111100000000000100111010000000000000000000010100010011110011011000010100100111110000100000001000000000000000000001010001001111001101100001010010000000000101001110100000000000100000000101000100111100111111111111111100000000010100111010000000000000000000010000110011110010000000010011010110110000101001001000000000000000000001000011001111001000000001001101000000000011001110100000000000100000000100001100111100000110101001000000000000001100111010000000000000000000010100110011110001101011101000100100000000100110101000000000000000000001010011001111000110101110100010000000000111001110100000000000100000000101001100111100000000000110000000000000011100111010000000000000000000010000001011110000000000000011110011010111010001001000000000000000000001000000101111000000000000001111000000000000101110100000000000100000000100000010111100101011101001000000000000000010111010000000000000000000010100001011110011001000111101110000000000000111101000000000000000000001010000101111001100100011110111000000000100101110100000000000100000000101000010111100000000000100100000000000010010111010000000000000000000010000101011110011100011001101110110010001111011101000000000000000000001000010101111001110001100110111000000000010101110100000000000100000000100001010111100000000000000000000000000001010111010000000000000000000010100101011110001100010101101110111000110011011101000000000000000000001010010101111000110001010110111000000000110101110100000000000100000000101001010111100000000001000000000000000011010111010000000000000000000010000011011110011100010101101110011000101011011101000000000000000000001000001101111001110001010110111000000000001101110100000000000100000000100000110111100000000000100000000000000000110111010000000000000000000010100011011110001100011101101110111000101011011101000000000000000000001010001101111000110001110110111000000000101101110100000000000100000000101000110111100000000001100000000000000010110111010000000000000000000010000111011110011100011101101110011000111011011101000000000000000000001000011101111001110001110110111000000000011101110100000000000100000000100001110111100000000000010000000000000001110111010000000000000000000010100111011110011001000111101110111000111011011101000000000000000000001010011101111001100100011110111000000000111101110100000000000100000000101001110111100000000000110000000000000011110111010000000000000000000010000000111110001111000010000000110010001111011101000000000000000000001000000011111000111100001000000000000000000011110100000000000100000000100000001111100000000100000000000000000000001111010000000000000000000010100000111110001001000010000100011110000100000001000000000000000000001010000011111000100100001000010000000000100011110100000000000100000000101000001111100000000000000000000000000010001111010000000000000000000010000100111110011001000010000100010010000100001001000000000000000000001000010011111001100100001000010000000000010011110100000000000100000000100001001111100000001000000000000000000001001111010000000000000000000010100100111110011001000010100100110010000100001001000000000000000000001010010011111001100100001010010000000000110011110100000000000100000000101001001111100011111100001111100000000011001111010000000000000000000010000010111110000000100000001000110010000101001001000000000000000000001000001011111000000010000000100000000000001011110100000000000100000000100000101111100000011100000000000000000000101111010000000000000000000010100010111110000000100000001000000001000000010001000000000000000000001010001011111000000010000000100000000000101011110100000000000100000000101000101111100001011100000000000000000010101111010000000000000000000010000110111110001111010010000100000001000000010001000000000000000000001000011011111000111101001000010000000000011011110100000000000100000000100001101111100000000000000000000000000001101111010000000000000000000010100110111110010000000010000100011110100100001001000000000000000000001010011011111001000000001000010000000000111011110100000000000100000000101001101111100101000010101000000000000011101111010000000000000000000010000001111110001010000000100000100000000100001001000000000000000000001000000111111000101000000010000000000000000111110100000000000100000000100000011111100111111101111111100000000000011111010000000000000000000010100001111110001001000010000100010100000001000001000000000000000000001010000111111000100100001000010000000000100111110100000000000100000000101000011111100000000000001000000000000010011111010000000000000000000010000101111110001111000010000000010010000100001001000000000000000000001000010111111000111100001000000000000000010111110100000000000100000000100001011111100000000100000000000000000001011111010000000000000000000010100101111110001001000010000100011110000100000001000000000000000000001010010111111000100100001000010000000000110111110100000000000100000000101001011111100000000000000000000000000011011111010000000000000000000010000011111110011001000010000100010010000100001001000000000000000000001000001111111001100100001000010000000000001111110100000000000100000000100000111111100000010000000000000000000000111111010000000000000000000010100011111110011001000010100100110010000100001001000000000000000000001010001111111001100100001010010000000000101111110100000000000100000000101000111111100011111100011111100000000010111111010000000000000000000010000111111110011111010010000100110010000101001001000000000000000000001000011111111001111101001000010000000000011111110100000000000100000000100001111111100000000000000000000000000001111111010000000000000000000010100111111110010000000010000100111110100100001001000000000000000000001010011111111001000000001000010000000000111111110100000000000100000000101001111111100101000010101000000000000011111111010100000000000000000010000000000010001010000000100000100000000100001001010000000000000000001000000000001000101000000010000001000000000000000101000000000100000000100000000000100111111101111111100100000000000000010100000000000000000010100000000010001001000010000100010100000001000001010000000000000000001010000000001000100100001000010001000000100000000101000000000100000000101000000000100000000000010000000100000010000000010100000000000000000010000100000010000010000000000000010010000100001001010000000000000000001000010000001000001000000000000001000000010000000101000000000100000000100001000000100100000010010000000100000001000000010100000000000000000010100100000010000000000000000000000100000000000001010000000000000000001010010000001000000000000000000001000000110000000101000000000100000000101001000000100000000000000000000100000011000000010100000000000000000010000010000010001111000010000000000000000000000001010000000000000000001000001000001000111100001000000001000000001000000101000000000100000000100000100000100000000100000000000100000000100000010100000000000000000010100010000010001001000010000100011110000100000001010000000000000000001010001000001000100100001000010001000000101000000101000000000100000000101000100000100000000000000000000100000010100000010100000000000000000010000110000010011001000010000100010010000100001001010000000000000000001000011000001001100100001000010001000000011000000101000000000100000000100001100000100000001000000000000100000001100000010100000000000000000010100110000010011001000010100100110010000100001001010000000000000000001010011000001001100100001010010001000000111000000101000000000100000000101001100000100011111100001111100100000011100000010100000000000000000010000001000010000000100000001000110010000101001001010000000000000000001000000100001000000010000000100001000000000100000101000000000100000000100000010000100000011100000000000100000000010000010100000000000000000010100001000010000000100000001000000001000000010001010000000000000000001010000100001000000010000000100001000000100100000101000000000100000000101000010000100001011100000000000100000010010000010100000000000000000010000101000010001111010010000100000001000000010001010000000000000000001000010100001000111101001000010001000000010100000101000000000100000000100001010000100000000000000000000100000001010000010100000000000000000010100101000010010000000010000100011110100100001001010000000000000000001010010100001001000000001000010001000000110100000101000000000100000000101001010000100101000010101000000100000011010000010100000000000000000010000011000010001010000000100000100000000100001001010000000000000000001000001100001000101000000010000001000000001100000101000000000100000000100000110000100111111101111111100100000000110000010100000000000000000010100011000010001001000010000100010100000001000001010000000000000000001010001100001000100100001000010001000000101100000101000000000100000000101000110000100000000000001000000100000010110000010100000000000000000010000111000010001111000010000000010010000100001001010000000000000000001000011100001000111100001000000001000000011100000101000000000100000000100001110000100000000100000000000100000001110000010100000000000000000010100111000010001001000010000100011110000100000001010000000000000000001010011100001000100100001000010001000000111100000101000000000100000000101001110000100000000000000000000100000011110000010100000000000000000010000000100010011001000010000100010010000100001001010000000000000000001000000010001001100100001000010001000000000010000101000000000100000000100000001000100000010000000000000100000000001000010100000000000000000010100000100010011001000010100100110010000100001001010000000000000000001010000010001001100100001010010001000000100010000101000000000100000000101000001000100011111100011111100100000010001000010100000000000000000010000100100010011111010000000100110010000101001001010000000000000000001000010010001001111101000000010001000000010010000101000000000100000000100001001000100000000000000000000100000001001000010100000000000000000010100100100010010000000010000100111110100000001001010000000000000000001010010010001001000000001000010001000000110010000101000000000100000000101001001000100101000010101000000100000011001000010100000000000000000010000010100010001010000000100000100000000100001001010000000000000000001000001010001000101000000010000001000000001010000101000000000100000000100000101000100111111101111111100100000000101000010100000000000000000010100010100010001001000010000100010100000001000001010000000000000000001010001010001000100100001000010001000000101010000101000000000100000000101000101000100000000000010000000100000010101000010100000000000000000010000110100010001111001010000000010010000100001001010000000000000000001000011010001000111100101000000001000000011010000101000000000100000000100001101000100010010100000000000100000001101000010100000000000000000010100110100010001001001010010100011110010100000001010000000000000000001010011010001000100100101001010001000000111010000101000000000100000000101001101000100000000000000000000100000011101000010100000000000000000010000001100010011111001010000000010010010100101001010000000000000000001000000110001001111100101000000001000000000110000101000000000100000000100000011000100011111100011111100100000000011000010100000000000000000010100001100010011111000010000000111110010100000001010000000000000000001010000110001001111100001000000001000000100110000101000000000100000000101000011000100000000000010000000100000010011000010100000000000000000010000101100010010000001010010100111110000100000001010000000000000000001000010110001001000000101001010001000000010110000101000000000100000000100001011000100000101001001000000100000001011000010100000000000000000010100101100010001111000010000000100000010100101001010000000000000000001010010110001000111100001000000001000000110110000101000000000100000000101001011000100010010100000000000100000011011000010100000000000000000010000011100010011001000010100100011110000100000001010000000000000000001000001110001001100100001010010001000000001110000101000000000100000000100000111000100111111111111111100100000000111000010100000000000000000010100011100010011111001010000000110010000101001001010000000000000000001010001110001001111100101000000001000000101110000101000000000100000000101000111000100010010100000000000100000010111000010100000000000000000010000111100010001001000010000100111110010100000001010000000000000000001000011110001000100100001000010001000000011110000101000000000100000000100001111000100010000000000110000100000001111000010100000000000000000010100111100010011001001010110100010010000100001001010000000000000000001010011110001001100100101011010001000000111110000101000000000100000000101001111000100010000001011101100100000011111000010100000000000000000010000000010010010000000010000100110010010101101001010000000000000000001000000001001001000000001000010001000000000001000101000000000100000000100000000100100000001001001000000100000000000100010100000000000000000010100000010010010000000010110100100000000100001001010000000000000000001010000001001001000000001011010001000000100001000101000000000100000000101000000100100001101001001000000100000010000100010100000000000000000010000100010010011111000010000000100000000101101001010000000000000000001000010001001001111100001000000001000000010001000101000000000100000000100001000100100000010100000000000100000001000100010100000000000000000010100100010010000000001010000100111110000100000001010000000000000000001010010001001000000000101000010001000000110001000101000000000100000000101001000100100100001001001000000100000011000100010100000000000000000010000010010010000000001010110100000000010100001001010000000000000000001000001001001000000000101011010001000000001001000101000000000100000000100000100100100101101001001000000100000000100100010100000000000000000010100010010010011001000010100100000000010101101001010000000000000000001010001001001001100100001010010001000000101001000101000000000100000000101000100100100000000000000000000100000010100100010100000000000000000010000110010010011100010110000100110010000101001001010000000000000000001000011001001001110001011000010001000000011001000101000000000100000000100001100100100000000000000000000100000001100100010100000000000000000010100110010010001001000010000100111000101100001001010000000000000000001010011001001000100100001000010001000000111001000101000000000100000000101001100100100000000001000000000100000011100100010100000000000000000010000001010010010000001010000100010010000100001001010000000000000000001000000101001001000000101000010001000000000101000101000000000100000000100000010100100101000010101000000100000000010100010100000000000000000010100001010010011001000010100100100000010100001001010000000000000000001010000101001001100100001010010001000000100101000101000000000100000000101000010100100000000001000000000100000010010100010100000000000000000010000101010010001010000000100000110010000101001001010000000000000000001000010101001000101000000010000001000000010101000101000000000100000000100001010100100111111110111111100100000001010100010100000000000000000010100101010010011101010110100100010100000001000001010000000000000000001010010101001001110101011010010001000000110101000101000000000100000000101001010100100011111101111111100100000011010100010100000000000000000010000011010010001111000110000000111010101101001001010000000000000000001000001101001000111100011000000001000000001101000101000000000100000000100000110100100000000100000000000100000000110100010100000000000000000010100011010010001001000110001100011110001100000001010000000000000000001010001101001000100100011000110001000000101101000101000000000100000000101000110100100000000000000000000100000010110100010100000000000000000010000111010010000000000000001100010010001100011001010000000000000000001000011101001000000000000000110001000000011101000101000000000100000000100001110100100000000000100000000100000001110100010100000000000000000010100111010010000000000000000000000000000000011001010000000000000000001010011101001000000000000000000001000000111101000101000000000100000000101001110100100000000000000000000100000011110100010100000000000000000010000000110010011111001010000000000000000000000001010000000000000000001000000011001001111100101000000001000000000011000101000000000100000000100000001100100000110100000000000100000000001100010100000000000000000010100000110010011100010010110100111110010100000001010000000000000000001010000011001001110001001011010001000000100011000101000000000100000000101000001100100000000000100000000100000010001100010100000000000000000010000100110010001111001010000000111000100101101001010000000000000000001000010011001000111100101000000001000000010011000101000000000100000000100001001100100111100011111111100100000001001100010100000000000000000010100100110010001011001010010100011110010100000001010000000000000000001010010011001000101100101001010001000000110011000101000000000100000000101001001100100111111111111111100100000011001100010100000000000000000010000010110010011111000000000000010110010100101001010000000000000000001000001011001001111100000000000001000000001011000101000000000100000000100000101100100010010100001100000100000000101100010100000000000000000010100010110010000000001010100100111110000000000001010000000000000000001010001011001000000000101010010001000000101011000101000000000100000000101000101100100001001001001000000100000010101100010100000000000000000010000110110010011101010010100000000000010101001001010000000000000000001000011011001001110101001010000001000000011011000101000000000100000000100001101100100000000000000000000100000001101100010100000000000000000010100110110010001111000010000000111010100101000001010000000000000000001010011011001000111100001000000001000000111011000101000000000100000000101001101100100010010100001100000100000011101100010100000000000000000010000001110010001100010010000100011110000100000001010000000000000000001000000111001000110001001000010001000000000111000101000000000100000000100000011100100000000000010000000100000000011100010100000000000000000010100001110010000011000010000100011000100100001001010000000000000000001010000111001000001100001000010001000000100111000101000000000100000000101000011100100000000010000000000100000010011100010100000000000000000010000101110010001010100000000100000110000100001001010000000000000000001000010111001000101010000000010001000000010111000101000000000100000000100001011100100111111101111111100100000001011100010100000000000000000010100101110010001111000010000000010101000000001001010000000000000000001010010111001000111100001000000001000000110111000101000000000100000000101001011100100010010100001100000100000011011100010100000000000000000010000011110010001001000010000000011110000100000001010000000000000000001000001111001000100100001000000001000000001111000101000000000100000000100000111100100000100000000000000100000000111100010100000000000000000010100011110010010000001010000100010010000100000001010000000000000000001010001111001001000000101000010001000000101111000101000000000100000000101000111100100000001000001000000100000010111100010100000000000000000010000111110010000000001010000100100000010100001001010000000000000000001000011111001000000000101000010001000000011111000101000000000100000000100001111100100000001001001000000100000001111100010100000000000000000010100111110010011111000000000000000000010100001001010000000000000000001010011111001001111100000000000001000000111111000101000000000100000000101001111100100010010100001100000100000011111100010100000000000000000010000000001010001101010010100000111110000000000001010000000000000000001000000000101000110101001010000001000000000000100101000000000100000000100000000010100000000001000000000100000000000010010100000000000000000010100000001010001111001010000000011010100101000001010000000000000000001010000000101000111100101000000001000000100000100101000000000100000000101000000010100000000000010000000100000010000010010100000000000000000010000100001010001001001010010100011110010100000001010000000000000000001000010000101000100100101001010001000000010000100101000000000100000000100001000010100111111111111111100100000001000010010100000000000000000010100100001010011111000000000000010010010100101001010000000000000000001010010000101001111100000000000001000000110000100101000000000100000000101001000010100010010100001100000100000011000010010100000000000000000010000010001010001101011010100000111110000000000001010000000000000000001000001000101000110101101010000001000000001000100101000000000100000000100000100010100000000001100000000100000000100010010100000000000000000010100010001010000000000000000000011010110101000001010000000000000000001010001000101000000000000000000001000000101000100101000000000100000000101000100010100000000000000000000100000010100010010100000000000000000010000110001010000000000000000000000000000000000001010000000000000000001000011000101000000000000000000001000000011000100101000000000100000000100001100010100000000000000000000100000001100010010100000000000000000010100110001010000000000000000000000000000000000001010000000000000000001010011000101000000000000000000001000000111000100101000000000100000000101001100010100000000000000000000100000011100010010100000000000000000010000001001010000000000000000000000000000000000001010000000000000000001000000100101000000000000000000001000000000100100101000000000100000000100000010010100000000000000000000100000000010010010100000000000000000010100001001010000000000000000000000000000000000001010000000000000000001010000100101000000000000000000001000000100100100101000000000100000000101000010010100000000000000000000100000010010010010100000000000000000010000101001010000000000000000000000000000000000001010000000000000000001000010100101000000000000000000001000000010100100101000000000100000000100001010010100000000000000000000100000001010010010100000000000000000010100101001010000000000000000000000000000000000001010000000000000000001010010100101000000000000000000001000000110100100101000000000100000000101001010010100000000000000000000100000011010010010100000000000000000010000011001010000000000000000000000000000000000001010000000000000000001000001100101000000000000000000001000000001100100101000000000100000000100000110010100000000000000000000100000000110010010100000000000000000010100011001010000000000000000000000000000000000001010000000000000000001010001100101000000000000000000001000000101100100101000000000100000000101000110010100000000000000000000100000010110010010100000000000000000010000111001010000000000000000000000000000000000001010000000000000000001000011100101000000000000000000001000000011100100101000000000100000000100001110010100000000000000000000100000001110010010100000000000000000010100111001010000000000000000000000000000000000001010000000000000000001010011100101000000000000000000001000000111100100101000000000100000000101001110010100000000000000000000100000011110010010100000000000000000010000000101010000000000000000000000000000000000001010000000000000000001000000010101000000000000000000001000000000010100101000000000100000000100000001010100000000000000000000100000000001010010100000000000000000010100000101010000000000000000000000000000000000001010000000000000000001010000010101000000000000000000001000000100010100101000000000100000000101000001010100000000000000000000100000010001010010100000000000000000010000100101010000000000000000000000000000000000001010000000000000000001000010010101000000000000000000001000000010010100101000000000100000000100001001010100000000000000000000100000001001010010100000000000000000010100100101010000000000000000000000000000000000001010000000000000000001010010010101000000000000000000001000000110010100101000000000100000000101001001010100000000000000000000100000011001010010100000000000000000010000010101010000000000000000000000000000000000001010000000000000000001000001010101000000000000000000001000000001010100101000000000100000000100000101010100000000000000000000100000000101010010100000000000000000010100010101010000000000000000000000000000000000001010000000000000000001010001010101000000000000000000001000000101010100101000000000100000000101000101010100000000000000000000100000010101010010100000000000000000010000110101010000000000000000000000000000000000001010000000000000000001000011010101000000000000000000001000000011010100101000000000100000000100001101010100000000000000000000100000001101010010100000000000000000010100110101010000000000000000000000000000000000001010000000000000000001010011010101000000000000000000001000000111010100101000000000100000000101001101010100000000000000000000100000011101010010100000000000000000010000001101010000000000000000000000000000000000001010000000000000000001000000110101000000000000000000001000000000110100101000000000100000000100000011010100000000000000000000100000000011010010100000000000000000010100001101010000000000000000000000000000000000001010000000000000000001010000110101000000000000000000001000000100110100101000000000100000000101000011010100000000000000000000100000010011010010100000000000000000010000101101010000000000000000000000000000000000001010000000000000000001000010110101000000000000000000001000000010110100101000000000100000000100001011010100000000000000000000100000001011010010100000000000000000010100101101010000000000000000000000000000000000001010000000000000000001010010110101000000000000000000001000000110110100101000000000100000000101001011010100000000000000000000100000011011010010100000000000000000010000011101010000000000000000000000000000000000001010000000000000000001000001110101000000000000000000001000000001110100101000000000100000000100000111010100000000000000000000100000000111010010100000000000000000010100011101010000000000000000000000000000000000001010000000000000000001010001110101000000000000000000001000000101110100101000000000100000000101000111010100000000000000000000100000010111010010100000000000000000010000111101010000000000000000000000000000000000001010000000000000000001000011110101000000000000000000001000000011110100101000000000100000000100001111010100000000000000000000100000001111010010100000000000000000010100111101010000000000000000000000000000000000001010000000000000000001010011110101000000000000000000001000000111110100101000000000100000000101001111010100000000000000000000100000011111010010100000000000000000010000000011010000000000000000000000000000000000001010000000000000000001000000001101000000000000000000001000000000001100101000000000100000000100000000110100000000000000000000100000000000110010100000000000000000010100000011010011111001010000000000000000000000001010000000000000000001010000001101001111100101000000001000000100001100101000000000100000000101000000110100010010100001100000100000010000110010100000000000000000010000100011010011100011010110100111110010100000001010000000000000000001000010001101001110001101011010001000000010001100101000000000100000000100001000110100000000000010000000100000001000110010100000000000000000010100100011010010011001010110100111000110101101001010000000000000000001010010001101001001100101011010001000000110001100101000000000100000000101001000110100100000000000000000100000011000110010100000000000000000010000010011010001010000000110100100110010101101001010000000000000000001000001001101000101000000011010001000000001001100101000000000100000000100000100110100011111100001111100100000000100110010100000000000000000010100010011010000000000000000000010100000001101001010000000000000000001010001001101000000000000000000001000000101001100101000000000100000000101000100110100000000000000000000100000010100110010100000000000000000010000110011010011111001010000000000000000000000001010000000000000000001000011001101001111100101000000001000000011001100101000000000100000000100001100110100000110100000000000100000001100110010100000000000000000010100110011010001100010100110100111110010100000001010000000000000000001010011001101000110001010011010001000000111001100101000000000100000000101001100110100000000000100000000100000011100110010100000000000000000010000001011010000000000000011010011000101001101001010000000000000000001000000101101000000000000001101001000000000101100101000000000100000000100000010110100101010001001000000100000000010110010100000000000000000010100001011010011111000000000000000000000000110101010000000000000000001010000101101001111100000000000001000000100101100101000000000100000000101000010110100011101000110101000100000010010110010100000000000000000010000101011010011011000000100000111110000000000001010000000000000000001000010101101001101100000010000001000000010101100101000000000100000000100001010110100101000101001101100100000001010110010100000000000000000010100101011010010000000000101000110110000001000001010000000000000000001010010101101001000000000010100001000000110101100101000000000100000000101001010110100100000000110000000100000011010110010100000000000000000010000011011010011001000111101110100000000001010001010000000000000000001000001101101001100100011110111001000000001101100101000000000100000000100000110110100011111100001111100100000000110110010100000000000000000010100011011010011101011111101110110010001111011101010000000000000000001010001101101001110101111110111001000000101101100101000000000100000000101000110110100000000001110000000100000010110110010100000000000000000010000111011010001101010001101110111010111111011101010000000000000000001000011101101000110101000110111001000000011101100101000000000100000000100001110110100000000001010000000100000001110110010100000000000000000010100111011010011111001111000000011010100011011101010000000000000000001010011101101001111100111100000001000000111101100101000000000100000000101001110110100000000000010000000100000011110110010100000000000000000010000000111010000000000000000000111110011110000001010000000000000000001000000011101000000000000000000001000000000011100101000000000100000000100000001110100101100001001000000100000000001110010100000000000000000010100000111010000000000000000000000000000000000001010000000000000000001010000011101000000000000000000001000000100011100101000000000100000000101000001110100100001001001000000100000010001110010100000000000000000010000100111010000000000000001000000000000000000001010000000000000000001000010011101000000000000000100001000000010011100101000000000100000000100001001110100101001001001000000100000001001110010100000000000000000010100100111010011001000110000000000000000000010001010000000000000000001010010011101001100100011000000001000000110011100101000000000100000000101001001110100000000000001000000100000011001110010100000000000000000010000010111010000000000000000000110010001100000001010000000000000000001000001011101000000000000000000001000000001011100101000000000100000000100000101110100000100010010000000100000000101110010100000000000000000010100010111010001001001000010000000000000000000001010000000000000000001010001011101000100100100001000001000000101011100101000000000100000000101000101110100100000000000000000100000010101110010100000000000000000010000110111010000000000000010000010010010000100001010000000000000000001000011011101000000000000001000001000000011011100101000000000100000000100001101110100101110001001000000100000001101110010100000000000000000010100110111010000000000000010000000000000000100001010000000000000000001010011011101000000000000001000001000000111011100101000000000100000000101001101110100100101001001000000100000011101110010100000000000000000010000001111010000000000000010000000000000000100001010000000000000000001000000111101000000000000001000001000000000111100101000000000100000000100000011110100101101001001000000100000000011110010100000000000000000010100001111010000000000000010000000000000000100001010000000000000000001010000111101000000000000001000001000000100111100101000000000100000000101000011110100100000101001000000100000010011110010100000000000000000010000101111010000000000000010000000000000000100001010000000000000000001000010111101000000000000001000001000000010111100101000000000100000000100001011110100100110001001000000100000001011110010100000000000000000010100101111010000000000000010000000000000000100001010000000000000000001010010111101000000000000001000001000000110111100101000000000100000000101001011110100100011001001000000100000011011110010100000000000000000010000011111010001100011000100100000000000000100001010000000000000000001000001111101000110001100010010001000000001111100101000000000100000000100000111110100000000000000000000100000000111110010100000000000000000010100011111010000000001000111000011000110001001001010000000000000000001010001111101000000000100011100001000000101111100101000000000100000000101000111110100101100000001000000100000010111110010100000000000000000010000111111010010000001100110000000000010001110001010000000000000000001000011111101001000000110011000001000000011111100101000000000100000000100001111110100101000010101000000100000001111110010100000000000000000010100111111010000010000000100000100000011001100001010000000000000000001010011111101000001000000010000001000000111111100101000000000100000000101001111110100000000010000000000100000011111110010100000000000000000010000000000110000000000000110000000100000001000001010000000000000000001000000000011000000000000011000001000000000000010101000000000100000000100000000001100101010001001000000100000000000001010100000000000000000010100000000110001001001010010100000000000001100001010000000000000000001010000000011000100100101001010001000000100000010101000000000100000000101000000001100100000000000000000100000010000001010100000000000000000010000100000110010011001000010000010010010100101001010000000000000000001000010000011001001100100001000001000000010000010101000000000100000000100001000001100100000011110000000100000001000001010100000000000000000010100100000110010000001000101100100110010000100001010000000000000000001010010000011001000000100010110001000000110000010101000000000100000000101001000001100101111010001000000100000011000001010100000000000000000010000010000110000000001000111100100000010001011001010000000000000000001000001000011000000000100011110001000000001000010101000000000100000000100000100001100000001111000000000100000000100001010100000000000000000010100010000110000000001000110000000000010001111001010000000000000000001010001000011000000000100011000001000000101000010101000000000100000000101000100001100000111001000000000100000010100001010100000000000000000010000110000110000000000011011100000000010001100001010000000000000000001000011000011000000000001101110001000000011000010101000000000100000000100001100001100100010001001000000100000001100001010100000000000000000010100110000110000000001000011000000000000110111001010000000000000000001010011000011000000000100001100001000000111000010101000000000100000000101001100001100101000010101000000100000011100001010100000000000000000010000001000110000000000000101000000000010000110001010000000000000000001000000100011000000000000010100001000000000100010101000000000100000000100000010001100101110001001000000100000000010001010100000000000000000010100001000110000000001000110100000000000001010001010000000000000000001010000100011000000000100011010001000000100100010101000000000100000000101000010001100001101011001000000100000010010001010100000000000000000010000101000110000010000000100000000000010001101001010000000000000000001000010100011000001000000010000001000000010100010101000000000100000000100001010001100000000001000000000100000001010001010100000000000000000010100101000110000000000100000010000100000001000001010000000000000000001010010100011000000000010000001001000000110100010101000000000100000000101001010001100100000100001000000100000011010001010100000000000000000010000011000110000000001000111000000000001000000101010000000000000000001000001100011000000000100011100001000000001100010101000000000100000000100000110001100001001111001000000100000000110001010100000000000000000010100011000110000010000000000000000000010001110001010000000000000000001010001100011000001000000000000001000000101100010101000000000100000000101000110001100000000010000000000100000010110001010100000000000000000010000111000110000000001100100110000100000000000001010000000000000000001000011100011000000000110010011001000000011100010101000000000100000000100001110001100000110011001000000100000001110001010100000000000000000010100111000110000000000100011000000000011001001101010000000000000000001010011100011000000000010001100001000000111100010101000000000100000000101001110001100000110011001000000100000011110001010100000000000000000010000000100110001001000010000100000000001000110001010000000000000000001000000010011000100100001000010001000000000010010101000000000100000000100000001001100000000001000000000100000000001001010100000000000000000010100000100110000000000001010000010010000100001001010000000000000000001010000010011000000000000101000001000000100010010101000000000100000000101000001001100001111011001000000100000010001001010100000000000000000010000100100110011001000010100100000000000010100001010000000000000000001000010010011001100100001010010001000000010010010101000000000100000000100001001001100000000001000000000100000001001001010100000000000000000010100100100110011010001111000100110010000101001001010000000000000000001010010010011001101000111100010001000000110010010101000000000100000000101001001001100011111100101111100100000011001001010100000000000000000010000010100110000000000110111100110100011110001001010000000000000000001000001010011000000000011011110001000000001010010101000000000100000000100000101001100100011000001000000100000000101001010100000000000000000010100010100110000000001010111000000000001101111001010000000000000000001010001010011000000000101011100001000000101010010101000000000100000000101000101001100000111011001000000100000010101001010100000000000000000010000110100110010000001010011100000000010101110001010000000000000000001000011010011001000000101001110001000000011010010101000000000100000000100001101001100001110011001000000100000001101001010100000000000000000010100110100110000000001100000010100000010100111001010000000000000000001010011010011000000000110000001001000000111010010101000000000100000000101001101001100000001111001000000100000011101001010100000000000000000010000001100110000000000110000110000000011000000101010000000000000000001000000110011000000000011000011001000000000110010101000000000100000000100000011001100000000111001000000100000000011001010100000000000000000010100001100110011111001010000000000000001100001101010000000000000000001010000110011001111100101000000001000000100110010101000000000100000000101000011001100000110100000000000100000010011001010100000000000000000010000101100110001100010010110100111110010100000001010000000000000000001000010110011000110001001011010001000000010110010101000000000100000000100001011001100000000000010000000100000001011001010100000000000000000010100101100110001010000010111000011000100101101001010000000000000000001010010110011000101000001011100001000000110110010101000000000100000000101001011001100000000011000000000100000011011001010100000000000000000010000011100110000000000000000000010100000101110001010000000000000000001000001110011000000000000000000001000000001110010101000000000100000000100000111001100000000000000000000100000000111001010100000000000000000010100011100110001100010010110100000000000000000001010000000000000000001010001110011000110001001011010001000000101110010101000000000100000000101000111001100000000001010000000100000010111001010100000000000000000010000111100110001010000010000010011000100101101001010000000000000000001000011110011000101000001000001001000000011110010101000000000100000000100001111001100100000010000000000100000001111001010100000000000000000010100111100110000000000000000000010100000100000101010000000000000000001010011110011000000000000000000001000000111110010101000000000100000000101001111001100000000000000000000100000011111001010100000000000000000010000000010110011000000001000000000000000000000001010000000000000000001000000001011001100000000100000001000000000001010101000000000100000000100000000101100100000010000000000100000000000101010100000000000000000010100000010110000000000000000000110000000010000001010000000000000000001010000001011000000000000000000001000000100001010101000000000100000000101000000101100000000000000000000100000010000101010100000000000000000010000100010110011000000001000000000000000000000001010000000000000000001000010001011001100000000100000001000000010001010101000000000100000000100001000101100111111111111111100100000001000101010100000000000000000010100100010110000000000000000000110000000010000001010000000000000000001010010001011000000000000000000001000000110001010101000000000100000000101001000101100000000000000000000100000011000101010100000000000000000010000010010110011111000010000000000000000000000001010000000000000000001000001001011001111100001000000001000000001001010101000000000100000000100000100101100010010100100000000100000000100101010100000000000000000010100010010110011100010010100100111110000100000001010000000000000000001010001001011001110001001010010001000000101001010101000000000100000000101000100101100000000000000000000100000010100101010100000000000000000010000110010110001100010001101110111000100101001001010000000000000000001000011001011000110001000110111001000000011001010101000000000100000000100001100101100000000001010000000100000001100101010100000000000000000010100110010110011100011111101110011000100011011101010000000000000000001010011001011001110001111110111001000000111001010101000000000100000000101001100101100000000001110000000100000011100101010100000000000000000010000001010110000010000000100100111000111111011101010000000000000000001000000101011000001000000010010001000000000101010101000000000100000000100000010101100000000011000000000100000000010101010100000000000000000010100001010110011001000111101110000100000001001001010000000000000000001010000101011001100100011110111001000000100101010101000000000100000000101000010101100000000000001000000100000010010101010100000000000000000010000101010110001001001010000000110010001111011101010000000000000000001000010101011000100100101000000001000000010101010101000000000100000000100001010101100100000000000100000100000001010101010100000000000000000010100101010110011111000000000000010010010100000001010000000000000000001010010101011001111100000000000001000000110101010101000000000100000000101001010101100010010101000000000100000011010101010100000000000000000010000011010110001101011010100000111110000000000001010000000000000000001000001101011000110101101010000001000000001101010101000000000100000000100000110101100000000000010000000100000000110101010100000000000000000010100011010110011111000000000000011010110101000001010000000000000000001010001101011001111100000000000001000000101101010101000000000100000000101000110101100010010100100000000100000010110101010100000000000000000010000111010110001101010000100000111110000000000001010000000000000000001000011101011000110101000010000001000000011101010101000000000100000000100001110101100000000000000000000100000001110101010100000000000000000010100111010110011111001010000000011010100001000001010000000000000000001010011101011001111100101000000001000000111101010101000000000100000000101001110101100000000010101010000100000011110101010100000000000000000010000000110110011011001010110100111110010100000001010000000000000000001000000011011001101100101011010001000000000011010101000000000100000000100000001101100001010111101010100100000000001101010100000000000000000010100000110110011111000000000000110110010101101001010000000000000000001010000011011001111100000000000001000000100011010101000000000100000000101000001101100010010101000000000100000010001101010100000000000000000010000100110110011101011010100000111110000000000001010000000000000000001000010011011001110101101010000001000000010011010101000000000100000000100001001101100000000000010000000100000001001101010100000000000000000010100100110110011111000000000000111010110101000001010000000000000000001010010011011001111100000000000001000000110011010101000000000100000000101001001101100010010100011000000100000011001101010100000000000000000010000010110110001001000010000000111110000000000001010000000000000000001000001011011000100100001000000001000000001011010101000000000100000000100000101101100110000001010101000100000000101101010100000000000000000010100010110110001101010010100000010010000100000001010000000000000000001010001011011000110101001010000001000000101011010101000000000100000000101000101101100000000001100000000100000010101101010100000000000000000010000110110110011111000000000000011010100101000001010000000000000000001000011011011001111100000000000001000000011011010101000000000100000000100001101101100010010100000010000100000001101101010100000000000000000010100110110110001101010000100000111110000000000001010000000000000000001010011011011000110101000010000001000000111011010101000000000100000000101001101101100000000000110000000100000011101101010100000000000000000010000001110110011111000000000000011010100001000001010000000000000000001000000111011001111100000000000001000000000111010101000000000100000000100000011101100010010100010100000100000000011101010100000000000000000010100001110110001101010000100000111110000000000001010000000000000000001010000111011000110101000010000001000000100111010101000000000100000000101000011101100000000001100000000100000010011101010100000000000000000010000101110110011111000000000000011010100001000001010000000000000000001000010111011001111100000000000001000000010111010101000000000100000000100001011101100010010100011000000100000001011101010100000000000000000010100101110110011001000010000000111110000000000001010000000000000000001010010111011001100100001000000001000000110111010101000000000100000000101001011101100001000000000000000100000011011101010100000000000000000010000011110110011101010010100000110010000100000001010000000000000000001000001111011001110101001010000001000000001111010101000000000100000000100000111101100000000000000000000100000000111101010100000000000000000010100011110110011001000010000000111010100101000001010000000000000000001010001111011001100100001000000001000000101111010101000000000100000000101000111101100000000010000000000100000010111101010100000000000000000010000111110110011111000000000000110010000100000001010000000000000000001000011111011001111100000000000001000000011111010101000000000100000000100001111101100010010100001100000100000001111101010100000000000000000010100111110110001111000010000000111110000000000001010000000000000000001010011111011000111100001000000001000000111111010101000000000100000000101001111101100000010100000000000100000011111101010100000000000000000010000000001110001011000010000100011110000100000001010000000000000000001000000000111000101100001000010001000000000000110101000000000100000000100000000011100000000000000001100100000000000011010100000000000000000010100000001110011101010010100000010110000100001001010000000000000000001010000000111001110101001010000001000000100000110101000000000100000000101000000011100000000000010000000100000010000011010100000000000000000010000100001110011101011101000100111010100101000001010000000000000000001000010000111001110101110100010001000000010000110101000000000100000000100001000011100000000001010000000100000001000011010100000000000000000010100100001110011101010101000100111010111010001001010000000000000000001010010000111001110101010100010001000000110000110101000000000100000000101001000011100000000001100000000100000011000011010100000000000000000010000010001110011101011001000100111010101010001001010000000000000000001000001000111001110101100100010001000000001000110101000000000100000000100000100011100000000001000000000100000000100011010100000000000000000010100010001110000010000000110010111010110010001001010000000000000000001010001000111000001000000011001001000000101000110101000000000100000000101000100011100000000001000000000100000010100011010100000000000000000010000110001110001101010101000100000100000001100101010000000000000000001000011000111000110101010100010001000000011000110101000000000100000000100001100011100000000000000000000100000001100011010100000000000000000010100110001110011111000010000000011010101010001001010000000000000000001010011000111001111100001000000001000000111000110101000000000100000000101001100011100010010100000000100100000011100011010100000000000000000010000001001110000010000000000000111110000100000001010000000000000000001000000100111000001000000000000001000000000100110101000000000100000000100000010011100100000010000000000100000000010011010100000000000000000010100001001110011001000010100100000100000000000001010000000000000000001010000100111001100100001010010001000000100100110101000000000100000000101000010011100000000000000000000100000010010011010100000000000000000010000101001110011111000010000000110010000101001001010000000000000000001000010100111001111100001000000001000000010100110101000000000100000000100001010011100000110100000000000100000001010011010100000000000000000010100101001110011001000010100100111110000100000001010000000000000000001010010100111001100100001010010001000000110100110101000000000100000000101001010011100000000000000000000100000011010011010100000000000000000010000011001110011101010010000100110010000101001001010000000000000000001000001100111001110101001000010001000000001100110101000000000100000000100000110011100000000000100000000100000000110011010100000000000000000010100011001110001111000010000000111010100100001001010000000000000000001010001100111000111100001000000001000000101100110101000000000100000000101000110011100010010100000000000100000010110011010100000000000000000010000111001110001001000010000100011110000100000001010000000000000000001000011100111000100100001000010001000000011100110101000000000100000000100001110011100000000000000000000100000001110011010100000000000000000010100111001110010001000010000100010010000100001001010000000000000000001010011100111001000100001000010001000000111100110101000000000100000000101001110011100000100000000000000100000011110011010100000000000000000010000000101110001001000010000100100010000100001001010000000000000000001000000010111000100100001000010001000000000010110101000000000100000000100000001011100000000001000000000100000000001011010100000000000000000010100000101110011010000010000100010010000100001001010000000000000000001010000010111001101000001000010001000000100010110101000000000100000000101000001011100011111111111111100100000010001011010100000000000000000010000100101110001101010000000100110100000100001001010000000000000000001000010010111000110101000000010001000000010010110101000000000100000000100001001011100011111101111111100100000001001011010100000000000000000010100100101110001111000010000000011010100000001001010000000000000000001010010010111000111100001000000001000000110010110101000000000100000000101001001011100010010100000000000100000011001011010100000000000000000010000010101110001001000010000100011110000100000001010000000000000000001000001010111000100100001000010001000000001010110101000000000100000000100000101011100000100000000000000100000000101011010100000000000000000010100010101110010001000010000100010010000100001001010000000000000000001010001010111001000100001000010001000000101010110101000000000100000000101000101011100000100000000000000100000010101011010100000000000000000010000110101110001001000010000100100010000100001001010000000000000000001000011010111000100100001000010001000000011010110101000000000100000000100001101011100000000001000000000100000001101011010100000000000000000010100110101110011010000010000100010010000100001001010000000000000000001010011010111001101000001000010001000000111010110101000000000100000000101001101011100011111111111111100100000011101011010100000000000000000010000001101110001101010000000100110100000100001001010000000000000000001000000110111000110101000000010001000000000110110101000000000100000000100000011011100011111101111111100100000000011011010100000000000000000010100001101110011111001010000000011010100000001001010000000000000000001010000110111001111100101000000001000000100110110101000000000100000000101000011011100000110100000000000100000010011011010100000000000000000010000101101110011100010010110100111110010100000001010000000000000000001000010110111001110001001011010001000000010110110101000000000100000000100001011011100000000000100000000100000001011011010100000000000000000010100101101110000000000000100100111000100101101001010000000000000000001010010110111000000000000010010001000000110110110101000000000100000000101001011011100000000000100000000100000011011011010100000000000000000010000011101110000000000000000000000000000001001001010000000000000000001000001110111000000000000000000001000000001110110101000000000100000000100000111011100000000000000000000100000000111011010100000000000000000010100011101110000000000000000000000000000000000001010000000000000000001010001110111000000000000000000001000000101110110101000000000100000000101000111011100000000000000000000100000010111011010100000000000000000010000111101110011001000111101110000000000000000001010000000000000000001000011110111001100100011110111001000000011110110101000000000100000000100001111011100011111100001101100100000001111011010100000000000000000010100111101110001101010001101110110010001111011101010000000000000000001010011110111000110101000110111001000000111110110101000000000100000000101001111011100000000000000100000100000011111011010100000000000000000010000000011110011101010001101110011010100011011101010000000000000000001000000001111001110101000110111001000000000001110101000000000100000000100000000111100000000001000100000100000000000111010100000000000000000010100000011110000000000000000000111010100011011101010000000000000000001010000001111000000000000000000001000000100001110101000000000100000000101000000111100101000101001000000100000010000111010100000000000000000010000100011110000000000000000000000000000000000001010000000000000000001000010001111000000000000000000001000000010001110101000000000100000000100001000111100100000101001000000100000001000111010100000000000000000010100100011110001101011000101110000000000000000001010000000000000000001010010001111000110101100010111001000000110001110101000000000100000000101001000111100000000000000000000100000011000111010100000000000000000010000010011110011101011000101110011010110001011101010000000000000000001000001001111001110101100010111001000000001001110101000000000100000000100000100111100000000001000000000100000000100111010100000000000000000010100010011110001101010100101110111010110001011101010000000000000000001010001001111000110101010010111001000000101001110101000000000100000000101000100111100000000000100000000100000010100111010100000000000000000010000110011110011101010100101110011010101001011101010000000000000000001000011001111001110101010010111001000000011001110101000000000100000000100001100111100000000001100000000100000001100111010100000000000000000010100110011110001101011100101110111010101001011101010000000000000000001010011001111000110101110010111001000000111001110101000000000100000000101001100111100000000000010000000100000011100111010100000000000000000010000001011110011101011100101110011010111001011101010000000000000000001000000101111001110101110010111001000000000101110101000000000100000000100000010111100000000001010000000100000000010111010100000000000000000010100001011110001101010010101110111010111001011101010000000000000000001010000101111000110101001010111001000000100101110101000000000100000000101000010111100000000000110000000100000010010111010100000000000000000010000101011110011101010010101110011010100101011101010000000000000000001000010101111001110101001010111001000000010101110101000000000100000000100001010111100000000001110000000100000001010111010100000000000000000010100101011110001101011010101110111010100101011101010000000000000000001010010101111000110101101010111001000000110101110101000000000100000000101001010111100000000000001000000100000011010111010100000000000000000010000011011110011101011010101110011010110101011101010000000000000000001000001101111001110101101010111001000000001101110101000000000100000000100000110111100000000001001000000100000000110111010100000000000000000010100011011110001101010110101110111010110101011101010000000000000000001010001101111000110101011010111001000000101101110101000000000100000000101000110111100000000000101000000100000010110111010100000000000000000010000111011110011101010110101110011010101101011101010000000000000000001000011101111001110101011010111001000000011101110101000000000100000000100001110111100000000001101000000100000001110111010100000000000000000010100111011110001101011110101110111010101101011101010000000000000000001010011101111000110101111010111001000000111101110101000000000100000000101001110111100000000000011000000100000011110111010100000000000000000010000000111110011101011110101110011010111101011101010000000000000000001000000011111001110101111010111001000000000011110101000000000100000000100000001111100000000001011000000100000000001111010100000000000000000010100000111110001101010011101110111010111101011101010000000000000000001010000011111000110101001110111001000000100011110101000000000100000000101000001111100000000000111000000100000010001111010100000000000000000010000100111110011101010011101110011010100111011101010000000000000000001000010011111001110101001110111001000000010011110101000000000100000000100001001111100000000001111000000100000001001111010100000000000000000010100100111110001101011001101110111010100111011101010000000000000000001010010011111000110101100110111001000000110011110101000000000100000000101001001111100000000000100100000100000011001111010100000000000000000010000010111110011101011001101110011010110011011101010000000000000000001000001011111001110101100110111001000000001011110101000000000100000000100000101111100000000001100100000100000000101111010100000000000000000010100010111110001101010101101110111010110011011101010000000000000000001010001011111000110101010110111001000000101011110101000000000100000000101000101111100000000000010100000100000010101111010100000000000000000010000110111110011101010101101110011010101011011101010000000000000000001000011011111001110101010110111001000000011011110101000000000100000000100001101111100000000001010100000100000001101111010100000000000000000010100110111110001101011101101110111010101011011101010000000000000000001010011011111000110101110110111001000000111011110101000000000100000000101001101111100000000000110100000100000011101111010100000000000000000010000001111110011101011101101110011010111011011101010000000000000000001000000111111001110101110110111001000000000111110101000000000100000000100000011111100000000001110100000100000000011111010100000000000000000010100001111110001101011111101110111010111011011101010000000000000000001010000111111000110101111110111001000000100111110101000000000100000000101000011111100000000000001100000100000010011111010100000000000000000010000101111110011101011111101110011010111111011101010000000000000000001000010111111001110101111110111001000000010111110101000000000100000000100001011111100000000001001100000100000001011111010100000000000000000010100101111110001100000000000100111010111111011101010000000000000000001010010111111000110000000000010001000000110111110101000000000100000000101001011111100000000000001000100100000011011111010100000000000000000010000011111110000000000000000000011000000000001001010000000000000000001000001111111000000000000000000001000000001111110101000000000100000000100000111111100000000000000000000100000000111111010100000000000000000010100011111110001001000001000010000000000000000001010000000000000000001010001111111000100100000100001001000000101111110101000000000100000000101000111111100100000000000000000100000010111111010100000000000000000010000111111110010101000010000010010010000010000101010000000000000000001000011111111001010100001000001001000000011111110101000000000100000000100001111111100000000001000000000100000001111111010100000000000000000010100111111110001010000000100100101010000100000101010000000000000000001010011111111000101000000010010001000000111111110101000000000100000000101001111111100111111110111111100100000011111111010010000000000000000010000000000010000000001000100010010100000001001001001000000000000000001000000000001000000000100010001000100000000000000100100000000100000000100000000000100101000100001000000010000000000000010010000000000000000010100000000010010000000001000000000000010001000101001000000000000000001010000000001001000000000100000000100000100000000100100000000100000000101000000000100000010010000010000010000010000000010010000000000000000010000100000010001100000000000100100000000010000001001000000000000000001000010000001000110000000000010000100000010000000100100000000100000000100001000000100000000000010010100010000001000000010010000000000000000010100100000010011001000100000000011000000000001001001000000000000000001010010000001001100100010000000000100000110000000100100000000100000000101001000000100100000000000000000010000011000000010010000000000000000010000010000010011100011111101110110010001000000001001000000000000000001000001000001001110001111110111000100000001000000100100000000100000000100000100000100000000001001100000010000000100000010010000000000000000010100010000010010000000001000000111000111111011101001000000000000000001010001000001001000000000100000000100000101000000100100000000100000000101000100000100000100010000010000010000010100000010010000000000000000010000110000010011100010001101110100000000010000001001000000000000000001000011000001001110001000110111000100000011000000100100000000100000000100001100000100000000001000100000010000001100000010010000000000000000010100110000010011100011000101110111000100011011101001000000000000000001010011000001001110001100010111000100000111000000100100000000100000000101001100000100000000001000000000010000011100000010010000000000000000010000001000010001100010100101110111000110001011101001000000000000000001000000100001000110001010010111000100000000100000100100000000100000000100000010000100000000000100000000010000000010000010010000000000000000010100001000010011100010100101110011000101001011101001000000000000000001010000100001001110001010010111000100000100100000100100000000100000000101000010000100000000001100000000010000010010000010010000000000000000010000101000010001100011100101110111000101001011101001000000000000000001000010100001000110001110010111000100000010100000100100000000100000000100001010000100000000000010000000010000001010000010010000000000000000010100101000010011100011100101110011000111001011101001000000000000000001010010100001001110001110010111000100000110100000100100000000100000000101001010000100000000001010000000010000011010000010010000000000000000010000011000010001100010010101110111000111001011101001000000000000000001000001100001000110001001010111000100000001100000100100000000100000000100000110000100000000000110000000010000000110000010010000000000000000010100011000010011100010010101110011000100101011101001000000000000000001010001100001001110001001010111000100000101100000100100000000100000000101000110000100000000001110000000010000010110000010010000000000000000010000111000010001100011010101110111000100101011101001000000000000000001000011100001000110001101010111000100000011100000100100000000100000000100001110000100000000000001000000010000001110000010010000000000000000010100111000010011100011010101110011000110101011101001000000000000000001010011100001001110001101010111000100000111100000100100000000100000000101001110000100000000001001000000010000011110000010010000000000000000010000000100010001100010110101110111000110101011101001000000000000000001000000010001000110001011010111000100000000010000100100000000100000000100000001000100000000000101000000010000000001000010010000000000000000010100000100010011100010110101110011000101101011101001000000000000000001010000010001001110001011010111000100000100010000100100000000100000000101000001000100000000001101000000010000010001000010010000000000000000010000100100010001100011110101110111000101101011101001000000000000000001000010010001000110001111010111000100000010010000100100000000100000000100001001000100000000000011000000010000001001000010010000000000000000010100100100010011100011110101110011000111101011101001000000000000000001010010010001001110001111010111000100000110010000100100000000100000000101001001000100000000001011000000010000011001000010010000000000000000010000010100010001100010011101110111000111101011101001000000000000000001000001010001000110001001110111000100000001010000100100000000100000000100000101000100000000000111000000010000000101000010010000000000000000010100010100010011100010011101110011000100111011101001000000000000000001010001010001001110001001110111000100000101010000100100000000100000000101000101000100000000001111000000010000010101000010010000000000000000010000110100010001100010001101110111000100111011101001000000000000000001000011010001000110001000110111000100000011010000100100000000100000000100001101000100000000000000100000010000001101000010010000000000000000010100110100010001100011001101110011000100011011101001000000000000000001010011010001000110001100110111000100000111010000100100000000100000000101001101000100000000000100100000010000011101000010010000000000000000010000001100010011100011001101110011000110011011101001000000000000000001000000110001001110001100110111000100000000110000100100000000100000000100000011000100000000001100100000010000000011000010010000000000000000010100001100010001100010101101110111000110011011101001000000000000000001010000110001000110001010110111000100000100110000100100000000100000000101000011000100000000000010100000010000010011000010010000000000000000010000101100010011100010101101110011000101011011101001000000000000000001000010110001001110001010110111000100000010110000100100000000100000000100001011000100000000001010100000010000001011000010010000000000000000010100101100010001100011101101110111000101011011101001000000000000000001010010110001000110001110110111000100000110110000100100000000100000000101001011000100000000000110100000010000011011000010010000000000000000010000011100010011100011101101110011000111011011101001000000000000000001000001110001001110001110110111000100000001110000100100000000100000000100000111000100000000001110100000010000000111000010010000000000000000010100011100010001100011111101110111000111011011101001000000000000000001010001110001000110001111110111000100000101110000100100000000100000000101000111000100000000000001100000010000010111000010010000000000000000010000111100010000000000000111110011000111111011101001000000000000000001000011110001000000000000011111000100000011110000100100000000100000000100001111000100000000000100000000010000001111000010010000000000000000010100111100010011001000111101110000000000001111101001000000000000000001010011110001001100100011110111000100000111110000100100000000100000000101001111000100000000000001010000010000011111000010010000000000000000010000000010010011001000111101110110010001111011101001000000000000000001000000001001001100100011110111000100000000001000100100000000100000000100000000100100011111100001111100010000000000100010010000000000000000010100000010010011101011111101110110010001111011101001000000000000000001010000001001001110101111110111000100000100001000100100000000100000000101000000100100000000001110000000010000010000100010010000000000000000010000100010010000000000000000000111010111111011101001000000000000000001000010001001000000000000000000000100000010001000100100000000100000000100001000100100101001001001000000010000001000100010010000000000000000010100100010010000000000000000000000000000000000001001000000000000000001010010001001000000000000000000000100000110001000100100000000100000000101001000100100101101001001000000010000011000100010010000000000000000010000010010010000000000000000000000000000000000001001000000000000000001000001001001000000000000000000000100000001001000100100000000100000000100000100100100100011001001000000010000000100100010010000000000000000010100010010010000101001011001100000000000000000001001000000000000000001010001001001000010100101100110000100000101001000100100000000100000000101000100100100000000000000100000010000010100100010010000000000000000010000110010010000010100000010110001010010110011001001000000000000000001000011001001000001010000001011000100000011001000100100000000100000000100001100100100000000000110000000010000001100100010010000000000000000010100110010010000000000000000000000101000000101101001000000000000000001010011001001000000000000000000000100000111001000100100000000100000000101001100100100100100001001000000010000011100100010010000000000000000010000001010010001100000000000100000000000000000001001000000000000000001000000101001000110000000000010000100000000101000100100000000100000000100000010100100100000010000100100010000000010100010010000000000000000010100001010010000000000000001100011000000000001001001000000000000000001010000101001000000000000000110000100000100101000100100000000100000000101000010100100100010001001000000010000010010100010010000000000000000010000101010010000110100000010000000000000000011001001000000000000000001000010101001000011010000001000000100000010101000100100000000100000000100001010100100000000000100000000010000001010100010010000000000000000010100101010010000101001011100100001101000000100001001000000000000000001010010101001000010100101110010000100000110101000100100000000100000000101001010100100000000000010100000010000011010100010010000000000000000010000011010010010000000010010000001010010111001001001000000000000000001000001101001001000000001001000000100000001101000100100000000100000000100000110100100100101110001000000010000000110100010010000000000000000010100011010010000000000110010110100000000100100001001000000000000000001010001101001000000000011001011000100000101101000100100000000100000000101000110100100100000000110000000010000010110100010010000000000000000010000111010010000000000000010000000000001100101101001000000000000000001000011101001000000000000001000000100000011101000100100000000100000000100001110100100101001001001000000010000001110100010010000000000000000010100111010010000000000000000000000000000000100001001000000000000000001010011101001000000000000000000000100000111101000100100000000100000000101001110100100000101110010000000010000011110100010010000000000000000010000000110010000000001011110100000000000000000001001000000000000000001000000011001000000000101111010000100000000011000100100000000100000000100000001100100101101000001000000010000000001100010010000000000000000010100000110010000000000000000000000000010111101001001000000000000000001010000011001000000000000000000000100000100011000100100000000100000000101000001100100000000000000000000010000010001100010010000000000000000010000100110010000101001011100100000000000000000001001000000000000000001000010011001000010100101110010000100000010011000100100000000100000000100001001100100000000000010100000010000001001100010010000000000000000010100100110010001010000000010110001010010111001001001000000000000000001010010011001000101000000001011000100000110011000100100000000100000000101001001100100111111100011111100010000011001100010010000000000000000010000010110010001001000110001100010100000000101101001000000000000000001000001011001000100100011000110000100000001011000100100000000100000000100000101100100100000000000000000010000000101100010010000000000000000010100010110010010000001010000000010010001100011001001000000000000000001010001011001001000000101000000000100000101011000100100000000100000000101000101100100000010000000010000010000010101100010010000000000000000010000110110010010000001010001000100000010100000001001000000000000000001000011011001001000000101000100000100000011011000100100000000100000000100001101100100100010010001000000010000001101100010010000000000000000010100110110010000000000100000000100000010100010001001000000000000000001010011011001000000000010000000000100000111011000100100000000100000000101001101100100000010000000010000010000011101100010010000000000000000010000001110010010000001010001000000000001000000001001000000000000000001000000111001001000000101000100000100000000111000100100000000100000000100000011100100100010010001000000010000000011100010010000000000000000010100001110010000000000100000000100000010100010001001000000000000000001010000111001000000000010000000000100000100111000100100000000100000000101000011100100000010000000100000010000010011100010010000000000000000010000101110010001100000000000100000000001000000001001000000000000000001000010111001000110000000000010000100000010111000100100000000100000000100001011100100000000000001100100010000001011100010010000000000000000010100101110010001001000100001000011000000000001001001000000000000000001010010111001000100100010000100000100000110111000100100000000100000000101001011100100011111100010010000010000011011100010010000000000000000010000011110010000010000000000000010010001000010001001000000000000000001000001111001000001000000000000000100000001111000100100000000100000000100000111100100100000010000000000010000000111100010010000000000000000010100011110010011100011111101110000100000000000001001000000000000000001010001111001001110001111110111000100000101111000100100000000100000000101000111100100000000001110000000010000010111100010010000000000000000010000111110010000000000000000000111000111111011101001000000000000000001000011111001000000000000000000000100000011111000100100000000100000000100001111100100100100001001000000010000001111100010010000000000000000010100111110010011100011111101110000000000000000001001000000000000000001010011111001001110001111110111000100000111111000100100000000100000000101001111100100000000001110000000010000011111100010010000000000000000010000000001010011001000111101110111000111111011101001000000000000000001000000000101001100100011110111000100000000000100100100000000100000000100000000010100000000000001000000010000000000010010010000000000000000010100000001010000000000000111110110010001111011101001000000000000000001010000000101000000000000011111000100000100000100100100000000100000000101000000010100000000000100000000010000010000010010010000000000000000010000100001010000000000000000000000000000001111101001000000000000000001000010000101000000000000000000000100000010000100100100000000100000000100001000010100000000000000000000010000001000010010010000000000000000010100100001010011001000111101110000000000000000001001000000000000000001010010000101001100100011110111000100000110000100100100000000100000000101001000010100011111100110111100010000011000010010010000000000000000010000010001010011101011111101110110010001111011101001000000000000000001000001000101001110101111110111000100000001000100100100000000100000000100000100010100000000001110000000010000000100010010010000000000000000010100010001010000000000000000000111010111111011101001000000000000000001010001000101000000000000000000000100000101000100100100000000100000000101000100010100100100001001000000010000010100010010010000000000000000010000110001010001100000000000100000000000000000001001000000000000000001000011000101000110000000000010000100000011000100100100000000100000000100001100010100000000000010010100010000001100010010010000000000000000010100110001010011001000100000000011000000000001001001000000000000000001010011000101001100100010000000000100000111000100100100000000100000000101001100010100000000010000000000010000011100010010010000000000000000010000001001010000000000000000000110010001000000001001000000000000000001000000100101000000000000000000000100000000100100100100000000100000000100000010010100100111101001000000010000000010010010010000000000000000010100001001010001001001011000000000000000000000001001000000000000000001010000100101000100100101100000000100000100100100100100000000100000000101000010010100111111111111111100010000010010010010010000000000000000010000101001010001101011011001010010010010110000001001000000000000000001000010100101000110101101100101000100000010100100100100000000100000000100001010010100000000001000000000010000001010010010010000000000000000010100101001010011100011000001010011010110110010101001000000000000000001010010100101001110001100000101000100000110100100100100000000100000000101001010010100000000001000000000010000011010010010010000000000000000010000011001010001101011011001010111000110000010101001000000000000000001000001100101000110101101100101000100000001100100100100000000100000000100000110010100000000000000000000010000000110010010010000000000000000010100011001010001101011011001010011010110110010101001000000000000000001010001100101000110101101100101000100000101100100100100000000100000000101000110010100000000000000000000010000010110010010010000000000000000010000111001010000000000000000000011010110110010101001000000000000000001000011100101000000000000000000000100000011100100100100000000100000000100001110010100100011101001000000010000001110010010010000000000000000010100111001010010000001000000000000000000000000001001000000000000000001010011100101001000000100000000000100000111100100100100000000100000000101001110010100011100010000000000010000011110010010010000000000000000010000000101010000011001011110000100000010000000001001000000000000000001000000010101000001100101111000000100000000010100100100000000100000000100000001010100100000000000000000010000000001010010010000000000000000010100000101010000010100000010110000110010111100001001000000000000000001010000010101000001010000001011000100000100010100100100000000100000000101000001010100100000010000000000010000010001010010010000000000000000010000100101010001001000111001110000101000000101101001000000000000000001000010010101000100100011100111000100000010010100100100000000100000000100001001010100100000000000000000010000001001010010010000000000000000010100100101010001001001000010000010010001110011101001000000000000000001010010010101000100100100001000000100000110010100100100000000100000000101001001010100100000000000000000010000011001010010010000000000000000010000010101010001001000111001110010010010000100001001000000000000000001000001010101000100100011100111000100000001010100100100000000100000000100000101010100100000000000000000010000000101010010010000000000000000010100010101010000101001011001110010010001110011101001000000000000000001010001010101000010100101100111000100000101010100100100000000100000000101000101010100000000000100000000010000010101010010010000000000000000010000110101010001010000000010110001010010110011101001000000000000000001000011010101000101000000001011000100000011010100100100000000100000000100001101010100111111100111111100010000001101010010010000000000000000010100110101010010000001000000000010100000000101101001000000000000000001010011010101001000000100000000000100000111010100100100000000100000000101001101010100001100010000100000010000011101010010010000000000000000010000001101010001001001111011110100000010000000001001000000000000000001000000110101000100100111101111000100000000110100100100000000100000000100000011010100100000000000000000010000000011010010010000000000000000010100001101010000101001011011110010010011110111101001000000000000000001010000110101000010100101101111000100000100110100100100000000100000000101000011010100000000010100000000010000010011010010010000000000000000010000101101010001010100000010110001010010110111101001000000000000000001000010110101000101010000001011000100000010110100100100000000100000000100001011010100111111111101111100010000001011010010010000000000000000010100101101010001001001011000000010101000000101101001000000000000000001010010110101000100100101100000000100000110110100100100000000100000000101001011010100111111111111111100010000011011010010010000000000000000010000011101010011100011111101110010010010110000001001000000000000000001000001110101001110001111110111000100000001110100100100000000100000000100000111010100000000001110000000010000000111010010010000000000000000010100011101010011001000111101110111000111111011101001000000000000000001010001110101001100100011110111000100000101110100100100000000100000000101000111010100000000000101000000010000010111010010010000000000000000010000111101010000000000000111110110010001111011101001000000000000000001000011110101000000000000011111000100000011110100100100000000100000000100001111010100000000000100000000010000001111010010010000000000000000010100111101010000000000000000000000000000001111101001000000000000000001010011110101000000000000000000000100000111110100100100000000100000000101001111010100000000000000000000010000011111010010010000000000000000010000000011010011001000111101110000000000000000001001000000000000000001000000001101001100100011110111000100000000001100100100000000100000000100000000110100011111100110111100010000000000110010010000000000000000010100000011010011101011111101110110010001111011101001000000000000000001010000001101001110101111110111000100000100001100100100000000100000000101000000110100000000001110000000010000010000110010010000000000000000010000100011010001101010100101110111010111111011101001000000000000000001000010001101000110101010010111000100000010001100100100000000100000000100001000110100000000000001000000010000001000110010010000000000000000010100100011010000001010000101110011010101001011101001000000000000000001010010001101000000101000010111000100000110001100100100000000100000000101001000110100100000011001000000010000011000110010010000000000000000010000010011010000000000000000000000010100001011101001000000000000000001000001001101000000000000000000000100000001001100 T111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111 @@ -687,7 +469,7 @@ trigger;]]> - + diff --git a/sw/bootloader/Makefile b/sw/bootloader/Makefile index 698432b..9a9295c 100644 --- a/sw/bootloader/Makefile +++ b/sw/bootloader/Makefile @@ -16,7 +16,7 @@ HEADER_NAME = header PROG_NAME = SummerLoader64 -ROM_SIZE = 32k +ROM_SIZE = 90k SOURCE_DIR = src BUILD_DIR = build