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