This commit is contained in:
Polprzewodnikowy 2021-08-20 19:51:55 +02:00
parent 0992680dd7
commit 5fe242df64
27 changed files with 2998 additions and 941 deletions

View File

@ -19,7 +19,7 @@
# #
# Quartus Prime # Quartus Prime
# Version 20.1.1 Build 720 11/11/2020 SJ Lite Edition # 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 PROJECT_OUTPUT_DIRECTORY output_files
set_global_assignment -name NUM_PARALLEL_PROCESSORS ALL set_global_assignment -name NUM_PARALLEL_PROCESSORS ALL
set_global_assignment -name FLOW_ENABLE_POWER_ANALYZER ON 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 # 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_14 -to i_uart_cts
set_location_assignment PIN_15 -to o_uart_rts set_location_assignment PIN_15 -to o_uart_rts
set_location_assignment PIN_17 -to o_led 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_22 -to io_rtc_sda
set_location_assignment PIN_24 -to io_n64_si_dq set_location_assignment PIN_24 -to io_n64_si_dq
set_location_assignment PIN_25 -to i_n64_nmi 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 # Pin & Location Assignments
# ========================== # ==========================
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to o_usb_clk set_instance_assignment -name FAST_INPUT_REGISTER ON -to io_usb_miosi[*]
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to o_usb_cs set_instance_assignment -name FAST_INPUT_REGISTER ON -to i_uart_rxd
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to io_usb_miosi[0] set_instance_assignment -name FAST_INPUT_REGISTER ON -to i_uart_cts
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to io_usb_miosi[1] set_instance_assignment -name FAST_INPUT_REGISTER ON -to io_rtc_sda
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to io_usb_miosi[2] set_instance_assignment -name FAST_INPUT_REGISTER ON -to io_n64_si_dq
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to io_usb_miosi[3] set_instance_assignment -name FAST_INPUT_REGISTER ON -to i_n64_nmi
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to io_n64_pi_ad[*] set_instance_assignment -name FAST_INPUT_REGISTER ON -to i_n64_reset
set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to io_usb_miosi[0] set_instance_assignment -name FAST_INPUT_REGISTER ON -to i_n64_si_clk
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_n64_pi_ad[*] 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_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_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_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_pi_alel
set_instance_assignment -name FAST_INPUT_REGISTER ON -to i_n64_nmi 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 # 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_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_uart_rxd
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_uart_cts
set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to i_n64_pi_read 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_write
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_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 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 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_pwren
set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to i_usb_miso
# start DESIGN_PARTITION(Top) # start DESIGN_PARTITION(Top)
# --------------------------- # ---------------------------
@ -261,25 +296,6 @@ set_global_assignment -name PARTITION_COLOR 16764057 -section_id Top
# end ENTITY(SummerCart64) # end ENTITY(SummerCart64)
# ------------------------ # ------------------------
set_global_assignment -name QSYS_FILE rtl/intel/flash/intel_flash.qsys set_global_assignment -name QIP_FILE rtl/intel/gpio/intel_gpio_ddro.qip
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 SLD_FILE db/stp_auto_stripped.stp set_global_assignment -name SLD_FILE db/stp_auto_stripped.stp
set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top

View File

@ -6,30 +6,30 @@ derive_pll_clocks -create_base_clocks
# set sdram_pll_clk {sys_pll|altpll_component|auto_generated|pll1|clk[1]} # 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} # 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_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 sd_clk -source [get_pins $sd_reg_clk] [get_ports {o_sd_clk}]
# create_generated_clock -name flash_se_neg_reg \ 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}] \ -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 \ -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}] [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 derive_clock_uncertainty
# # SDRAM timings # # 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_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_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}] -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}] -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}] -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}] -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 # # 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] # 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[*]}] # N64, PI and SI timings
# 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 -to [get_ports {o_n64_irq}]
# set_false_path -from [get_ports {i_n64_si_clk io_n64_si_dq}] 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 # LED timings
@ -68,7 +74,19 @@ derive_clock_uncertainty
set_false_path -to [get_ports {o_led}] set_false_path -to [get_ports {o_led}]
# # PMOD timings # UART timings
# set_false_path -to [get_ports {io_pmod[*]}] set_false_path -to [get_ports {o_uart_txd o_uart_rts}]
# set_false_path -from [get_ports {io_pmod[*]}] 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}]

View File

@ -9,8 +9,8 @@ typedef volatile uint8_t * io8_t;
typedef volatile uint32_t * io32_t; typedef volatile uint32_t * io32_t;
#define RAM (*((io8_t) 0x00000000)) #define RAM (*((io8_t) 0x00000000))
#define USB_SR (*((io8_t) 0x40000000)) #define USB_SR (*((io8_t) 0x50000000))
#define USB_DR (*((io8_t) 0x40000004)) #define USB_DR (*((io8_t) 0x50000004))
#define USB_SR_RXNE (1 << 0) #define USB_SR_RXNE (1 << 0)
#define USB_SR_TXE (1 << 1) #define USB_SR_TXE (1 << 1)

54
fw/btldr/btldr.sv Normal file
View File

@ -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

View File

@ -1,7 +1,10 @@
bus.rdata 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; bus.ack <= 1'b0;
if (bus.request) begin if (bus.request) begin
bus.ack <= 1'b1; bus.ack <= 1'b1;

View File

@ -1,17 +1,6 @@
module SummerCart64 ( module SummerCart64 (
input i_clk, 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_reset,
input i_n64_nmi, input i_n64_nmi,
output o_n64_irq, output o_n64_irq,
@ -34,13 +23,24 @@ module SummerCart64 (
output [12:0] o_sdram_a, output [12:0] o_sdram_a,
inout [15:0] io_sdram_dq, 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, output o_sd_clk,
inout io_sd_cmd, inout io_sd_cmd,
inout [3:0] io_sd_dat, inout [3:0] io_sd_dat,
inout io_rtc_scl,
inout io_rtc_sda,
output o_led output o_led
); );
@ -60,18 +60,44 @@ module SummerCart64 (
.n64_nmi(i_n64_nmi) .n64_nmi(i_n64_nmi)
); );
if_config cfg ();
system system_inst ( system system_inst (
.sys(sys) .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 ( cpu_soc cpu_soc_inst (
.sys(sys), .sys(sys),
.cfg(cfg),
.gpio_o(gpio_o), .gpio_o(gpio_o),
.gpio_i(gpio_i), .gpio_i(gpio_i),
.gpio_oe(gpio_oe), .gpio_oe(gpio_oe),
.i2c_scl(io_rtc_scl), .i2c_scl(o_rtc_scl),
.i2c_sda(io_rtc_sda), .i2c_sda(io_rtc_sda),
.usb_clk(o_usb_clk), .usb_clk(o_usb_clk),
@ -83,82 +109,11 @@ module SummerCart64 (
.uart_rxd(i_uart_rxd), .uart_rxd(i_uart_rxd),
.uart_txd(o_uart_txd), .uart_txd(o_uart_txd),
.uart_cts(i_uart_cts), .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 endmodule

View File

@ -1,9 +1,6 @@
interface if_cpu_bus #( interface if_cpu_bus ();
parameter NUM_DEVICES = 1
) ( localparam [3:0] NUM_DEVICES = sc64::__ID_CPU_END;
input clk,
input reset
);
logic request; logic request;
logic ack; logic ack;
@ -26,8 +23,6 @@ interface if_cpu_bus #(
end end
modport cpu ( modport cpu (
input clk,
input reset,
output request, output request,
input ack, input ack,
output wmask, output wmask,
@ -39,11 +34,13 @@ interface if_cpu_bus #(
genvar n; genvar n;
generate generate
for (n = 0; n < NUM_DEVICES; n++) begin : at 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 ( modport device (
input .clk(clk),
input .reset(reset),
input .request(device_request), input .request(device_request),
output .ack(device_ack[n]), output .ack(device_ack[n]),
input .wmask(wmask), input .wmask(wmask),

View File

@ -1,33 +1,36 @@
module cpu_gpio ( module cpu_gpio (
if_system.sys sys,
if_cpu_bus bus, if_cpu_bus bus,
input [7:0] gpio_i, input [7:0] gpio_i,
output reg [7:0] gpio_o, output [7:0] gpio_o,
output reg [7:0] gpio_oe output [7:0] gpio_oe
); );
reg [7:0] gpio_i_ff1, gpio_i_ff2; logic [1:0][7:0] gpio_i_ff;
reg [7:0] gpio_o_value; logic [7:0] gpio_o_value;
reg [7:0] gpio_oe_value; logic [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;
always_ff @(posedge sys.clk) begin
bus.ack <= 1'b0; bus.ack <= 1'b0;
if (bus.request) begin if (bus.request) begin
bus.ack <= 1'b1; bus.ack <= 1'b1;
end 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_o_value <= 8'd0;
gpio_oe_value <= 8'd0; gpio_oe_value <= 8'd0;
end else if (bus.request) begin end else if (bus.request) begin

View File

@ -1,7 +1,8 @@
module cpu_i2c ( module cpu_i2c (
if_system.sys sys,
if_cpu_bus bus, if_cpu_bus bus,
inout i2c_scl, output i2c_scl,
inout i2c_sda inout i2c_sda
); );
@ -20,13 +21,13 @@ module cpu_i2c (
end end
end end
always_ff @(posedge bus.clk) begin always_ff @(posedge sys.clk) begin
bus.ack <= 1'b0; bus.ack <= 1'b0;
if (bus.request) begin if (bus.request) begin
bus.ack <= 1'b1; bus.ack <= 1'b1;
end end
if (bus.reset) begin if (sys.reset) begin
mack <= 1'b0; mack <= 1'b0;
end else if (bus.request && bus.wmask[0] && !bus.address[2]) begin end else if (bus.request && bus.wmask[0] && !bus.address[2]) begin
mack <= bus.wdata[2]; mack <= bus.wdata[2];
@ -39,14 +40,14 @@ module cpu_i2c (
wire clock_tick = &clock_div; wire clock_tick = &clock_div;
wire [3:0] clock_phase = {4{clock_tick}} & clock_phase_gen; wire [3:0] clock_phase = {4{clock_tick}} & clock_phase_gen;
always_ff @(posedge bus.clk) begin always_ff @(posedge sys.clk) begin
if (bus.reset) begin if (sys.reset) begin
clock_div <= 6'd0; clock_div <= 6'd0;
end else begin end else begin
clock_div <= clock_div + 1'd1; clock_div <= clock_div + 1'd1;
end end
if (bus.reset || state == 2'd0) begin if (sys.reset || state == 2'd0) begin
clock_phase_gen <= 4'b0001; clock_phase_gen <= 4'b0001;
end else if (clock_tick) begin end else if (clock_tick) begin
clock_phase_gen <= {clock_phase_gen[2:0], clock_phase_gen[3]}; 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_scl = scl_o ? 1'bZ : 1'b0;
assign i2c_sda = sda_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}; {sda_i_ff2, sda_i_ff1} <= {sda_i_ff1, i2c_sda};
if (bus.reset) begin if (sys.reset) begin
state <= 2'd0; state <= 2'd0;
scl_o <= 1'b1; scl_o <= 1'b1;
sda_o <= 1'b1; sda_o <= 1'b1;

View File

@ -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 [0:4095];
logic [3:0][7:0] ram_1 [0:4095]; logic [31:0] q;
// logic [3:0][7:0] ram_2 [0:2047];
logic [31:0] q_1;//, q_2;
// logic [31:0] q;
assign bank = bus.address[14]; always_ff @(posedge sys.clk) begin
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
bus.ack <= 1'b0; bus.ack <= 1'b0;
if (bus.request) begin if (bus.request) begin
bus.ack <= 1'b1; bus.ack <= 1'b1;
end end
end end
always_ff @(posedge bus.clk) begin always_comb begin
q_1 <= ram_1[bus.address[13:2]]; bus.rdata = 32'd0;
if (bus.request & !bank) begin if (bus.ack) begin
if (bus.wmask[0]) ram_1[bus.address[13:2]][0] <= bus.wdata[7:0]; bus.rdata = q;
if (bus.wmask[1]) ram_1[bus.address[13:2]][1] <= bus.wdata[15:8]; end
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];
end end
// q_2 <= ram_2[bus.address[12:2]]; always_ff @(posedge sys.clk) begin
// if (bus.request & bank) begin q <= ram[bus.address[13:2]];
// if (bus.wmask[0]) ram_2[bus.address[12:2]][0] <= bus.wdata[7:0]; if (bus.request) begin
// if (bus.wmask[1]) ram_2[bus.address[12:2]][1] <= bus.wdata[15:8]; if (bus.wmask[0]) ram[bus.address[13:2]][0] <= bus.wdata[7:0];
// if (bus.wmask[2]) ram_2[bus.address[12:2]][2] <= bus.wdata[23:16]; if (bus.wmask[1]) ram[bus.address[13:2]][1] <= bus.wdata[15:8];
// if (bus.wmask[3]) ram_2[bus.address[12:2]][3] <= bus.wdata[31:24]; if (bus.wmask[2]) ram[bus.address[13:2]][2] <= bus.wdata[23:16];
// end if (bus.wmask[3]) ram[bus.address[13:2]][3] <= bus.wdata[31:24];
end
end end
endmodule endmodule

View File

@ -1,11 +1,12 @@
module cpu_soc ( module cpu_soc (
if_system.sys sys, if_system.sys sys,
if_config cfg,
input [7:0] gpio_i, input [7:0] gpio_i,
output [7:0] gpio_o, output [7:0] gpio_o,
output [7:0] gpio_oe, output [7:0] gpio_oe,
inout i2c_scl, output i2c_scl,
inout i2c_sda, inout i2c_sda,
output usb_clk, output usb_clk,
@ -17,56 +18,48 @@ module cpu_soc (
input uart_rxd, input uart_rxd,
output uart_txd, output uart_txd,
input uart_cts, input uart_cts,
output uart_rts output uart_rts,
output sd_clk,
inout sd_cmd,
inout [3:0] sd_dat
); );
enum bit [3:0] { if_cpu_bus bus ();
RAM,
BOOTLOADER,
GPIO,
I2C,
USB,
UART,
__NUM_DEVICES
} e_address_map;
if_cpu_bus #( cpu_wrapper cpu_wrapper_inst (
.NUM_DEVICES(__NUM_DEVICES) .sys(sys),
) bus (
.clk(sys.clk),
.reset(sys.reset)
);
cpu_wrapper # (
.ENTRY_DEVICE(BOOTLOADER)
) cpu_wrapper_inst (
.bus(bus) .bus(bus)
); );
cpu_ram cpu_ram_inst ( 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 ( 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 ( 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_i(gpio_i),
.gpio_o(gpio_o), .gpio_o(gpio_o),
.gpio_oe(gpio_oe) .gpio_oe(gpio_oe)
); );
cpu_i2c cpu_i2c_inst ( 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_scl(i2c_scl),
.i2c_sda(i2c_sda) .i2c_sda(i2c_sda)
); );
cpu_usb cpu_usb_inst ( cpu_usb cpu_usb_inst (
.sys(sys), .sys(sys),
.bus(bus.at[USB].device), .bus(bus.at[sc64::ID_CPU_USB].device),
.usb_clk(usb_clk), .usb_clk(usb_clk),
.usb_cs(usb_cs), .usb_cs(usb_cs),
.usb_miso(usb_miso), .usb_miso(usb_miso),
@ -74,10 +67,9 @@ module cpu_soc (
.usb_pwren(usb_pwren) .usb_pwren(usb_pwren)
); );
cpu_uart #( cpu_uart cpu_uart_inst (
.BAUD_RATE(1_000_000) .sys(sys),
) cpu_uart_inst ( .bus(bus.at[sc64::ID_CPU_UART].device),
.bus(bus.at[UART].device),
.uart_rxd(uart_rxd), .uart_rxd(uart_rxd),
.uart_txd(uart_txd), .uart_txd(uart_txd),
.uart_cts(uart_cts), .uart_cts(uart_cts),

View File

@ -1,6 +1,5 @@
module cpu_uart # ( module cpu_uart (
parameter BAUD_RATE = 1_000_000 if_system.sys sys,
) (
if_cpu_bus bus, if_cpu_bus bus,
input uart_rxd, input uart_rxd,
@ -9,78 +8,145 @@ module cpu_uart # (
output uart_rts 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] { typedef enum bit [1:0] {
S_TX_IDLE, S_TRX_IDLE,
S_TX_DATA S_TRX_DATA,
} e_tx_state; S_TRX_SAMPLING_OFFSET
} e_trx_state;
e_tx_state tx_state;
logic [7:0] tx_data; // CPU bus controller
logic tx_start;
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 always_comb begin
bus.rdata = 32'd0; bus.rdata = 32'd0;
if (bus.ack) begin if (bus.ack) begin
case (bus.address[2:2]) 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; default: bus.rdata = 32'd0;
endcase endcase
end end
end end
always_ff @(posedge bus.clk) begin
bus.ack <= 1'b0;
tx_start <= 1'b0;
if (bus.request) begin // TX path
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
logic [6:0] tx_baud_counter; logic [6:0] tx_baud_counter;
logic [3:0] tx_bit_counter; logic [3:0] tx_bit_counter;
logic [9:0] tx_shifter; 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; tx_baud_counter <= tx_baud_counter + 1'd1;
uart_txd <= tx_shifter[0]; uart_txd <= tx_shifter[0];
if (bus.reset) begin if (sys.reset) begin
tx_state <= S_TX_IDLE; tx_state <= S_TRX_IDLE;
tx_shifter <= 10'h3FF; tx_shifter <= 10'h3FF;
end else begin end else begin
case (tx_state) case (tx_state)
S_TX_IDLE: begin S_TRX_IDLE: begin
if (tx_start) begin if (bus.request && bus.wmask[0] && bus.address[2]) begin
tx_state <= S_TX_DATA; tx_state <= S_TRX_DATA;
tx_baud_counter <= 7'd0; tx_baud_counter <= 7'd0;
tx_bit_counter <= 4'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
end end
S_TX_DATA: begin S_TRX_DATA: begin
if (tx_baud_counter == BAUD_GEN_VALUE) begin if (tx_baud_counter == BAUD_GEN_VALUE) begin
tx_baud_counter <= 7'd0; tx_baud_counter <= 7'd0;
tx_bit_counter <= tx_bit_counter + 1'd1; tx_bit_counter <= tx_bit_counter + 1'd1;
tx_shifter <= {1'b1, tx_shifter[9:1]}; tx_shifter <= {1'b1, tx_shifter[9:1]};
if (tx_bit_counter == 4'd9) begin if (tx_bit_counter == 4'd9) begin
tx_state <= S_TX_IDLE; tx_state <= S_TRX_IDLE;
end end
end end
end end
default: begin 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 end
endcase endcase
end end

View File

@ -19,6 +19,13 @@ module cpu_usb (
logic tx_write; logic tx_write;
logic [7:0] tx_wdata; 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 always_comb begin
bus.rdata = 32'd0; bus.rdata = 32'd0;
if (bus.ack) begin if (bus.ack) begin
@ -30,18 +37,13 @@ module cpu_usb (
end end
end end
always_ff @(posedge bus.clk) begin always_ff @(posedge sys.clk) begin
rx_flush <= 1'b0; rx_flush <= 1'b0;
rx_read <= 1'b0; rx_read <= 1'b0;
tx_flush <= 1'b0; tx_flush <= 1'b0;
tx_write <= 1'b0; tx_write <= 1'b0;
bus.ack <= 1'b0;
if (bus.request) begin
bus.ack <= 1'b1;
end
if (bus.request) begin if (bus.request) begin
case (bus.address[2:2]) case (bus.address[2:2])
2'd0: if (bus.wmask[0]) begin 2'd0: if (bus.wmask[0]) begin

View File

@ -1,20 +1,21 @@
module cpu_wrapper #( module cpu_wrapper (
parameter [3:0] ENTRY_DEVICE = 4'h0 if_system.sys sys,
) (
if_cpu_bus.cpu bus 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; e_bus_state state;
wire mem_la_read; logic mem_la_read;
wire mem_la_write; logic mem_la_write;
always_ff @(posedge bus.clk) begin always_ff @(posedge sys.clk) begin
bus.request <= 1'b0; bus.request <= 1'b0;
if (sys.reset) begin
if (bus.reset) begin
state <= S_IDLE; state <= S_IDLE;
end else begin end else begin
if (state == S_IDLE && (mem_la_read || mem_la_write)) begin if (state == S_IDLE && (mem_la_read || mem_la_write)) begin
@ -33,10 +34,10 @@ module cpu_wrapper #(
.TWO_STAGE_SHIFT(0), .TWO_STAGE_SHIFT(0),
.CATCH_MISALIGN(0), .CATCH_MISALIGN(0),
.CATCH_ILLINSN(0), .CATCH_ILLINSN(0),
.PROGADDR_RESET({ENTRY_DEVICE, 28'h000_0000}) .PROGADDR_RESET({4'(sc64::ID_CPU_BOOTLOADER), 28'h000_0000})
) cpu_inst ( ) cpu_inst (
.clk(bus.clk), .clk(sys.clk),
.resetn(~bus.reset), .resetn(~sys.reset),
.mem_addr(bus.address), .mem_addr(bus.address),
.mem_wdata(bus.wdata), .mem_wdata(bus.wdata),
.mem_wstrb(bus.wmask), .mem_wstrb(bus.wmask),

View File

@ -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"

View File

@ -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: <?xml version="1.0"?>
//<!--
// Generated by Altera MegaWizard Launcher Utility version 1.0
// ************************************************************
// THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE!
// ************************************************************
// Copyright (C) 1991-2021 Altera Corporation
// Any megafunction design, and related net list (encrypted or decrypted),
// support information, device programming or simulation file, and any other
// associated documentation or information provided by Altera or a partner
// under Altera's Megafunction Partnership Program may be used only to
// program PLD devices (but not masked PLD devices) from Altera. Any other
// use of such megafunction design, net list, support information, device
// programming or simulation file, or any other related documentation or
// information is prohibited for any other purpose, including, but not
// limited to modification, reverse engineering, de-compiling, or use with
// any other silicon devices, unless such use is explicitly licensed under
// a separate agreement with Altera or a megafunction partner. Title to
// the intellectual property, including patents, copyrights, trademarks,
// trade secrets, or maskworks, embodied in any such megafunction design,
// net list, support information, device programming or simulation file, or
// any other related documentation or information provided by Altera or a
// megafunction partner, remains with Altera, the megafunction partner, or
// their respective licensors. No other licenses, including any licenses
// needed under any third party's intellectual property, are provided herein.
//-->
// Retrieval info: <instance entity-name="altera_gpio_lite" version="20.1" >
// Retrieval info: <generic name="DEVICE_FAMILY" value="MAX 10" />
// Retrieval info: <generic name="PIN_TYPE" value="output" />
// Retrieval info: <generic name="SIZE" value="1" />
// Retrieval info: <generic name="gui_true_diff_buf" value="false" />
// Retrieval info: <generic name="gui_pseudo_diff_buf" value="false" />
// Retrieval info: <generic name="gui_bus_hold" value="false" />
// Retrieval info: <generic name="gui_open_drain" value="false" />
// Retrieval info: <generic name="gui_enable_oe_port" value="false" />
// Retrieval info: <generic name="gui_enable_nsleep_port" value="false" />
// Retrieval info: <generic name="gui_io_reg_mode" value="ddr" />
// Retrieval info: <generic name="gui_enable_aclr_port" value="false" />
// Retrieval info: <generic name="gui_enable_aset_port" value="false" />
// Retrieval info: <generic name="gui_enable_sclr_port" value="false" />
// Retrieval info: <generic name="gui_set_registers_to_power_up_high" value="false" />
// Retrieval info: <generic name="gui_clock_enable" value="false" />
// Retrieval info: <generic name="gui_invert_output" value="false" />
// Retrieval info: <generic name="gui_invert_input_clock" value="false" />
// Retrieval info: <generic name="gui_use_register_to_drive_obuf_oe" value="false" />
// Retrieval info: <generic name="gui_use_ddio_reg_to_drive_oe" value="false" />
// Retrieval info: <generic name="gui_use_advanced_ddr_features" value="false" />
// Retrieval info: <generic name="gui_enable_phase_detector_for_ck" value="false" />
// Retrieval info: <generic name="gui_enable_oe_half_cycle_delay" value="true" />
// Retrieval info: <generic name="gui_enable_hr_clock" value="false" />
// Retrieval info: <generic name="gui_enable_invert_hr_clock_port" value="false" />
// Retrieval info: <generic name="gui_invert_clkdiv_input_clock" value="false" />
// Retrieval info: <generic name="gui_invert_output_clock" value="false" />
// Retrieval info: <generic name="gui_invert_oe_inclock" value="false" />
// Retrieval info: <generic name="gui_use_hardened_ddio_input_registers" value="false" />
// Retrieval info: </instance>
// IPFS_FILES : intel_gpio_ddro.vo
// RELATED_FILES: intel_gpio_ddro.v, altera_gpio_lite.sv

File diff suppressed because it is too large Load Diff

View File

@ -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

View File

@ -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

445
fw/rtl/memory/sdram.vhd Normal file
View File

@ -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;

56
fw/rtl/n64/n64_bus.sv Normal file
View File

@ -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

View File

@ -1,18 +1,13 @@
module n64_pi ( module n64_pi (
if_system.sys sys, if_system.sys sys,
if_config.pi cfg,
if_n64_bus.n64 bus,
input n64_pi_alel, input n64_pi_alel,
input n64_pi_aleh, input n64_pi_aleh,
input n64_pi_read, input n64_pi_read,
input n64_pi_write, input n64_pi_write,
inout [15:0] n64_pi_ad, inout [15:0] n64_pi_ad
output request,
input ack,
output write,
output [31:0] address,
output [15:0] wdata,
input [15:0] rdata
); );
// Control signals input synchronization // Control signals input synchronization
@ -35,7 +30,6 @@ module n64_pi (
logic pi_read; logic pi_read;
logic pi_read_delayed; logic pi_read_delayed;
logic pi_write; logic pi_write;
logic pi_write_delayed;
always_comb begin always_comb begin
pi_reset = sys.n64_hard_reset; pi_reset = sys.n64_hard_reset;
@ -43,8 +37,7 @@ module n64_pi (
pi_alel = n64_pi_alel_ff[2]; pi_alel = n64_pi_alel_ff[2];
pi_read = n64_pi_read_ff[1]; pi_read = n64_pi_read_ff[1];
pi_read_delayed = n64_pi_read_ff[2]; pi_read_delayed = n64_pi_read_ff[2];
pi_write = n64_pi_write_ff[1]; pi_write = n64_pi_write_ff[2];
pi_write_delayed = n64_pi_write_ff[2];
end end
// PI bus state and event generator // PI bus state and event generator
@ -92,9 +85,11 @@ module n64_pi (
logic n64_pi_ad_output_enable; logic n64_pi_ad_output_enable;
logic n64_pi_ad_output_enable_data; logic n64_pi_ad_output_enable_data;
logic n64_pi_address_valid;
always_comb begin always_comb begin
n64_pi_ad = n64_pi_ad_output_enable ? n64_pi_ad_output : 16'hZZZZ; 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 end
always_ff @(posedge sys.clk) begin always_ff @(posedge sys.clk) begin
@ -118,34 +113,81 @@ module n64_pi (
logic pending_operation; logic pending_operation;
logic pending_write; logic pending_write;
sc64::e_n64_id next_id;
logic [25:0] next_offset;
always_ff @(posedge sys.clk) begin 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 if (sys.reset || sys.n64_hard_reset || sys.n64_soft_reset) begin
state <= S_IDLE; state <= S_IDLE;
first_operation <= 1'b0;
pending_operation <= 1'b0; pending_operation <= 1'b0;
end else begin end else begin
case (state) case (state)
S_IDLE: begin S_IDLE: begin
if (aleh_op) address[31:16] <= n64_pi_ad_input; if (aleh_op) begin
if (alel_op) address[15:0] <= {n64_pi_ad_input[15:1], 1'b0}; bus.address[31:16] <= n64_pi_ad_input;
if (alel_op || read_op || write_op || pending_operation) begin
state <= S_WAIT;
request <= 1'b1;
write <= write_op || (pending_operation && pending_write);
if (!alel_op && !(first_operation && write_op)) begin
address[31:1] <= address[31:1] + 1'd1;
end end
wdata <= n64_pi_ad_input; 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;
bus.id <= next_id;
bus.request <= 1'b1;
bus.write <= write_op || (pending_operation && pending_write);
if (!alel_op && !(first_operation && write_op)) begin
bus.address[31:1] <= bus.address[31:1] + 1'd1;
end
bus.wdata <= n64_pi_ad_input;
first_operation <= alel_op; first_operation <= alel_op;
end end
end end
S_WAIT: begin S_WAIT: begin
if (ack) begin if (bus.ack) begin
state <= S_IDLE; state <= S_IDLE;
n64_pi_ad_output_data_buffer <= rdata; n64_pi_ad_output_data_buffer <= bus.rdata;
end end
if (read_op || write_op) begin if (read_op || write_op) begin
pending_operation <= 1'b1; pending_operation <= 1'b1;
@ -155,7 +197,6 @@ module n64_pi (
default: begin default: begin
state <= S_IDLE; state <= S_IDLE;
first_operation <= 1'b0;
pending_operation <= 1'b0; pending_operation <= 1'b0;
end end
endcase endcase

57
fw/rtl/n64/n64_soc.sv Normal file
View File

@ -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

34
fw/rtl/system/config.sv Normal file
View File

@ -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

24
fw/rtl/system/sc64.sv Normal file
View File

@ -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

File diff suppressed because one or more lines are too long

View File

@ -16,7 +16,7 @@ HEADER_NAME = header
PROG_NAME = SummerLoader64 PROG_NAME = SummerLoader64
ROM_SIZE = 32k ROM_SIZE = 90k
SOURCE_DIR = src SOURCE_DIR = src
BUILD_DIR = build BUILD_DIR = build