mirror of
https://github.com/Polprzewodnikowy/SummerCart64.git
synced 2024-11-25 15:16:53 +01:00
update
This commit is contained in:
parent
0992680dd7
commit
5fe242df64
@ -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
|
@ -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}]
|
||||
|
@ -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)
|
||||
|
54
fw/btldr/btldr.sv
Normal file
54
fw/btldr/btldr.sv
Normal 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
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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),
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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),
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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),
|
||||
|
77
fw/rtl/intel/gpio/intel_gpio_ddro.qip
Normal file
77
fw/rtl/intel/gpio/intel_gpio_ddro.qip
Normal 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"
|
123
fw/rtl/intel/gpio/intel_gpio_ddro.v
Normal file
123
fw/rtl/intel/gpio/intel_gpio_ddro.v
Normal 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
|
1200
fw/rtl/intel/gpio/intel_gpio_ddro/altera_gpio_lite.sv
Normal file
1200
fw/rtl/intel/gpio/intel_gpio_ddro/altera_gpio_lite.sv
Normal file
File diff suppressed because it is too large
Load Diff
55
fw/rtl/memory/memory_flash.sv
Normal file
55
fw/rtl/memory/memory_flash.sv
Normal 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
|
@ -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
445
fw/rtl/memory/sdram.vhd
Normal 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
56
fw/rtl/n64/n64_bus.sv
Normal 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
|
@ -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
|
||||
@ -92,9 +85,11 @@ module n64_pi (
|
||||
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
|
||||
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;
|
||||
if (aleh_op) begin
|
||||
bus.address[31:16] <= n64_pi_ad_input;
|
||||
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;
|
||||
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
|
||||
|
57
fw/rtl/n64/n64_soc.sv
Normal file
57
fw/rtl/n64/n64_soc.sv
Normal 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
34
fw/rtl/system/config.sv
Normal 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
24
fw/rtl/system/sc64.sv
Normal 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
|
976
fw/stp.stp
976
fw/stp.stp
File diff suppressed because one or more lines are too long
@ -16,7 +16,7 @@ HEADER_NAME = header
|
||||
|
||||
PROG_NAME = SummerLoader64
|
||||
|
||||
ROM_SIZE = 32k
|
||||
ROM_SIZE = 90k
|
||||
|
||||
SOURCE_DIR = src
|
||||
BUILD_DIR = build
|
||||
|
Loading…
Reference in New Issue
Block a user