mirror of
https://github.com/Polprzewodnikowy/SummerCart64.git
synced 2024-11-22 05:59:15 +01:00
[SC64][FW][SW] Made CPU boot process simpler, UART is now an optional module (#12)
This commit is contained in:
parent
8485face13
commit
29aca8aea6
2
.github/workflows/main.yml
vendored
2
.github/workflows/main.yml
vendored
@ -22,7 +22,7 @@ jobs:
|
|||||||
submodules: true
|
submodules: true
|
||||||
|
|
||||||
- name: Build script
|
- name: Build script
|
||||||
run: ./docker_build.sh release
|
run: ./docker_build.sh release --force-clean
|
||||||
|
|
||||||
- name: Upload artifact
|
- name: Upload artifact
|
||||||
uses: actions/upload-artifact@v2
|
uses: actions/upload-artifact@v2
|
||||||
|
2
.gitmodules
vendored
2
.gitmodules
vendored
@ -1,4 +1,4 @@
|
|||||||
[submodule "fw/cpu/picorv32"]
|
[submodule "fw/picorv32"]
|
||||||
path = fw/picorv32
|
path = fw/picorv32
|
||||||
url = https://github.com/cliffordwolf/picorv32.git
|
url = https://github.com/cliffordwolf/picorv32.git
|
||||||
ignore = dirty
|
ignore = dirty
|
||||||
|
35
build.sh
35
build.sh
@ -19,6 +19,9 @@ BUILT_FPGA=false
|
|||||||
BUILT_UPDATE=false
|
BUILT_UPDATE=false
|
||||||
BUILT_RELEASE=false
|
BUILT_RELEASE=false
|
||||||
|
|
||||||
|
FORCE_CLEAN=false
|
||||||
|
SKIP_FPGA_REBUILD=false
|
||||||
|
|
||||||
build_cic () {
|
build_cic () {
|
||||||
if [ "$BUILT_CIC" = true ]; then return; fi
|
if [ "$BUILT_CIC" = true ]; then return; fi
|
||||||
|
|
||||||
@ -33,7 +36,10 @@ build_n64 () {
|
|||||||
if [ "$BUILT_N64" = true ]; then return; fi
|
if [ "$BUILT_N64" = true ]; then return; fi
|
||||||
|
|
||||||
pushd sw/n64
|
pushd sw/n64
|
||||||
make clean all
|
if [ "$FORCE_CLEAN" = true ]; then
|
||||||
|
make clean
|
||||||
|
fi
|
||||||
|
make all
|
||||||
popd
|
popd
|
||||||
|
|
||||||
BUILT_N64=true
|
BUILT_N64=true
|
||||||
@ -43,7 +49,10 @@ build_riscv () {
|
|||||||
if [ "$BUILT_RISCV" = true ]; then return; fi
|
if [ "$BUILT_RISCV" = true ]; then return; fi
|
||||||
|
|
||||||
pushd sw/riscv
|
pushd sw/riscv
|
||||||
make clean all
|
if [ "$FORCE_CLEAN" = true ]; then
|
||||||
|
make clean
|
||||||
|
fi
|
||||||
|
make all
|
||||||
popd
|
popd
|
||||||
|
|
||||||
BUILT_RISCV=true
|
BUILT_RISCV=true
|
||||||
@ -56,7 +65,11 @@ build_fpga () {
|
|||||||
build_riscv
|
build_riscv
|
||||||
|
|
||||||
pushd fw
|
pushd fw
|
||||||
|
if [ "$SKIP_FPGA_REBUILD" = true ] && [ -f output_files/SummerCart64.sof ]; then
|
||||||
|
quartus_cpf -c SummerCart64.cof
|
||||||
|
else
|
||||||
quartus_sh --flow compile ./SummerCart64.qpf
|
quartus_sh --flow compile ./SummerCart64.qpf
|
||||||
|
fi
|
||||||
popd
|
popd
|
||||||
|
|
||||||
BUILT_FPGA=true
|
BUILT_FPGA=true
|
||||||
@ -82,24 +95,28 @@ build_release () {
|
|||||||
build_cic
|
build_cic
|
||||||
build_update
|
build_update
|
||||||
|
|
||||||
if [[ -e "./${PACKAGE_FILE_NAME}.zip" ]]; then
|
if [ -e "./${PACKAGE_FILE_NAME}.zip" ]; then
|
||||||
rm -f "./${PACKAGE_FILE_NAME}.zip"
|
rm -f "./${PACKAGE_FILE_NAME}.zip"
|
||||||
fi
|
fi
|
||||||
zip -r "./${PACKAGE_FILE_NAME}.zip" ${FILES[@]}
|
zip -j -r "./${PACKAGE_FILE_NAME}.zip" ${FILES[@]}
|
||||||
|
|
||||||
BUILT_RELEASE=true
|
BUILT_RELEASE=true
|
||||||
}
|
}
|
||||||
|
|
||||||
print_usage () {
|
print_usage () {
|
||||||
echo "builder script for SummerCart64"
|
echo "builder script for SummerCart64"
|
||||||
echo "usage: ./build.sh [cic] [n64] [riscv] [fpga] [update] [release] [--help]"
|
echo "usage: ./build.sh [cic] [n64] [riscv] [fpga] [update] [release] [-c] [-s] [--help]"
|
||||||
echo "parameters:"
|
echo "parameters:"
|
||||||
echo " cic - assemble UltraCIC-III software"
|
echo " cic - assemble UltraCIC-III software"
|
||||||
echo " n64 - compile N64 bootloader software"
|
echo " n64 - compile N64 bootloader software"
|
||||||
echo " riscv - compile cart governor software"
|
echo " riscv - compile cart governor software"
|
||||||
echo " fpga - compile FPGA design (triggers 'n64' and 'riscv' build)"
|
echo " fpga - compile FPGA design (triggers 'n64' and 'riscv' build)"
|
||||||
echo " update - convert programming .pof file to raw binary for user upgrade (triggers 'fpga' build)"
|
echo " update - convert programming .pof file to raw binary for self-upgrade (triggers 'fpga' build)"
|
||||||
echo " release - collect and zip files for release (triggers 'cic' and 'update' build)"
|
echo " release - collect and zip files for release (triggers 'cic' and 'update' build)"
|
||||||
|
echo " -c | --force-clean"
|
||||||
|
echo " - clean software compilation result directories before build"
|
||||||
|
echo " -s | --skip-fpga-rebuild"
|
||||||
|
echo " - do not recompile whole FPGA design if it's already done, just update software binaries"
|
||||||
echo " --help - print this guide"
|
echo " --help - print this guide"
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -137,6 +154,12 @@ while test $# -gt 0; do
|
|||||||
release)
|
release)
|
||||||
TRIGGER_RELEASE=true
|
TRIGGER_RELEASE=true
|
||||||
;;
|
;;
|
||||||
|
-c|--force-clean)
|
||||||
|
FORCE_CLEAN=true
|
||||||
|
;;
|
||||||
|
-s|--skip-fpga-rebuild)
|
||||||
|
SKIP_FPGA_REBUILD=true
|
||||||
|
;;
|
||||||
--help)
|
--help)
|
||||||
print_usage
|
print_usage
|
||||||
exit 0
|
exit 0
|
||||||
|
@ -28,7 +28,7 @@
|
|||||||
<epof>0</epof>
|
<epof>0</epof>
|
||||||
<ufm_source>2</ufm_source>
|
<ufm_source>2</ufm_source>
|
||||||
<ufm_filepath>../sw/n64/build/SummerLoader64.hex</ufm_filepath>
|
<ufm_filepath>../sw/n64/build/SummerLoader64.hex</ufm_filepath>
|
||||||
<cfm0_filepath>../sw/riscv/build/controller.hex</cfm0_filepath>
|
<cfm0_filepath>../sw/riscv/build/governor.hex</cfm0_filepath>
|
||||||
<cfm0_file_start_addr>305152</cfm0_file_start_addr>
|
<cfm0_file_start_addr>305152</cfm0_file_start_addr>
|
||||||
</MAX10_device_options>
|
</MAX10_device_options>
|
||||||
<advanced_options>
|
<advanced_options>
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
#
|
#
|
||||||
# Quartus Prime
|
# Quartus Prime
|
||||||
# Version 21.1.0 Build 842 10/21/2021 SJ Lite Edition
|
# Version 21.1.0 Build 842 10/21/2021 SJ Lite Edition
|
||||||
# Date created = 23:52:20 November 09, 2021
|
# Date created = 13:29:40 November 11, 2021
|
||||||
#
|
#
|
||||||
# -------------------------------------------------------------------------- #
|
# -------------------------------------------------------------------------- #
|
||||||
#
|
#
|
||||||
@ -52,7 +52,6 @@ set_global_assignment -name QIP_FILE rtl/intel/gpio/intel_gpio_ddro.qip
|
|||||||
set_global_assignment -name QIP_FILE rtl/intel/pll/intel_pll.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 SDC_FILE SummerCart64.sdc
|
||||||
set_global_assignment -name SYSTEMVERILOG_FILE picorv32/picorv32.v
|
set_global_assignment -name SYSTEMVERILOG_FILE picorv32/picorv32.v
|
||||||
set_global_assignment -name SYSTEMVERILOG_FILE ../sw/riscv/build/cpu_bootloader.sv
|
|
||||||
set_global_assignment -name SYSTEMVERILOG_FILE rtl/cpu/cpu_bus.sv
|
set_global_assignment -name SYSTEMVERILOG_FILE rtl/cpu/cpu_bus.sv
|
||||||
set_global_assignment -name SYSTEMVERILOG_FILE rtl/cpu/cpu_cfg.sv
|
set_global_assignment -name SYSTEMVERILOG_FILE rtl/cpu/cpu_cfg.sv
|
||||||
set_global_assignment -name SYSTEMVERILOG_FILE rtl/cpu/cpu_dma.sv
|
set_global_assignment -name SYSTEMVERILOG_FILE rtl/cpu/cpu_dma.sv
|
||||||
@ -83,7 +82,7 @@ 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/sc64.sv
|
||||||
set_global_assignment -name SYSTEMVERILOG_FILE rtl/system/system.sv
|
set_global_assignment -name SYSTEMVERILOG_FILE rtl/system/system.sv
|
||||||
set_global_assignment -name SYSTEMVERILOG_FILE rtl/usb/usb_ft1248.sv
|
set_global_assignment -name SYSTEMVERILOG_FILE rtl/usb/usb_ft1248.sv
|
||||||
set_global_assignment -name POST_FLOW_SCRIPT_FILE "quartus_sh:scripts/post_flow.tcl"
|
set_global_assignment -name POST_MODULE_SCRIPT_FILE "quartus_sh:scripts/post_module.tcl"
|
||||||
|
|
||||||
# Pin & Location Assignments
|
# Pin & Location Assignments
|
||||||
# ==========================
|
# ==========================
|
||||||
@ -290,21 +289,3 @@ set_global_assignment -name OUTPUT_IO_TIMING_FAR_END_VMEAS "HALF SIGNAL SWING" -
|
|||||||
|
|
||||||
# end ENTITY(SummerCart64)
|
# end ENTITY(SummerCart64)
|
||||||
# ------------------------
|
# ------------------------
|
||||||
|
|
||||||
# ------------------------------
|
|
||||||
# start ENTITY(altera_gpio_lite)
|
|
||||||
|
|
||||||
# Project-Wide Assignments
|
|
||||||
# ========================
|
|
||||||
|
|
||||||
# end ENTITY(altera_gpio_lite)
|
|
||||||
# ----------------------------
|
|
||||||
|
|
||||||
# -----------------------------
|
|
||||||
# start ENTITY(intel_gpio_ddro)
|
|
||||||
|
|
||||||
# Project-Wide Assignments
|
|
||||||
# ========================
|
|
||||||
|
|
||||||
# end ENTITY(intel_gpio_ddro)
|
|
||||||
# ---------------------------
|
|
@ -40,9 +40,10 @@ module cpu_soc (
|
|||||||
.bus(bus.at[sc64::ID_CPU_RAM].device)
|
.bus(bus.at[sc64::ID_CPU_RAM].device)
|
||||||
);
|
);
|
||||||
|
|
||||||
cpu_bootloader cpu_bootloader_inst (
|
cpu_flash cpu_flash_inst (
|
||||||
.sys(sys),
|
.sys(sys),
|
||||||
.bus(bus.at[sc64::ID_CPU_BOOTLOADER].device)
|
.bus(bus.at[sc64::ID_CPU_FLASH].device),
|
||||||
|
.flash(flash)
|
||||||
);
|
);
|
||||||
|
|
||||||
cpu_gpio cpu_gpio_inst (
|
cpu_gpio cpu_gpio_inst (
|
||||||
@ -71,12 +72,16 @@ module cpu_soc (
|
|||||||
.usb_pwren(usb_pwren)
|
.usb_pwren(usb_pwren)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
generate
|
||||||
|
if (sc64::CPU_HAS_UART) begin
|
||||||
cpu_uart cpu_uart_inst (
|
cpu_uart cpu_uart_inst (
|
||||||
.sys(sys),
|
.sys(sys),
|
||||||
.bus(bus.at[sc64::ID_CPU_UART].device),
|
.bus(bus.at[sc64::ID_CPU_UART].device),
|
||||||
.uart_rxd(uart_rxd),
|
.uart_rxd(uart_rxd),
|
||||||
.uart_txd(uart_txd)
|
.uart_txd(uart_txd)
|
||||||
);
|
);
|
||||||
|
end
|
||||||
|
endgenerate
|
||||||
|
|
||||||
cpu_dma cpu_dma_inst (
|
cpu_dma cpu_dma_inst (
|
||||||
.sys(sys),
|
.sys(sys),
|
||||||
@ -108,12 +113,6 @@ module cpu_soc (
|
|||||||
.si(si)
|
.si(si)
|
||||||
);
|
);
|
||||||
|
|
||||||
cpu_flash cpu_flash_inst (
|
|
||||||
.sys(sys),
|
|
||||||
.bus(bus.at[sc64::ID_CPU_FLASH].device),
|
|
||||||
.flash(flash)
|
|
||||||
);
|
|
||||||
|
|
||||||
assign sd_clk = 1'bZ;
|
assign sd_clk = 1'bZ;
|
||||||
assign sd_cmd = 1'bZ;
|
assign sd_cmd = 1'bZ;
|
||||||
assign sd_dat = 4'bZZZZ;
|
assign sd_dat = 4'bZZZZ;
|
||||||
|
@ -33,7 +33,7 @@ module cpu_wrapper (
|
|||||||
.ENABLE_COUNTERS64(0),
|
.ENABLE_COUNTERS64(0),
|
||||||
.CATCH_MISALIGN(0),
|
.CATCH_MISALIGN(0),
|
||||||
.CATCH_ILLINSN(0),
|
.CATCH_ILLINSN(0),
|
||||||
.PROGADDR_RESET({4'(sc64::ID_CPU_BOOTLOADER), 28'h000_0000})
|
.PROGADDR_RESET(sc64::CPU_RESET_VECTOR)
|
||||||
) cpu_inst (
|
) cpu_inst (
|
||||||
.clk(sys.clk),
|
.clk(sys.clk),
|
||||||
.resetn(~sys.reset),
|
.resetn(~sys.reset),
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
version="1.0"
|
version="1.0"
|
||||||
description=""
|
description=""
|
||||||
tags="INTERNAL_COMPONENT=true"
|
tags="INTERNAL_COMPONENT=true"
|
||||||
categories="" />
|
categories="System" />
|
||||||
<parameter name="bonusData"><![CDATA[bonusData
|
<parameter name="bonusData"><![CDATA[bonusData
|
||||||
{
|
{
|
||||||
element onchip_flash_0
|
element onchip_flash_0
|
||||||
@ -78,10 +78,10 @@
|
|||||||
<parameter name="READ_BURST_MODE" value="Incrementing" />
|
<parameter name="READ_BURST_MODE" value="Incrementing" />
|
||||||
<parameter name="SECTOR_ACCESS_MODE">Read and write,Read and write,Hidden,Read and write,Read and write</parameter>
|
<parameter name="SECTOR_ACCESS_MODE">Read and write,Read and write,Hidden,Read and write,Read and write</parameter>
|
||||||
<parameter name="autoInitializationFileName">$${FILENAME}_onchip_flash_0</parameter>
|
<parameter name="autoInitializationFileName">$${FILENAME}_onchip_flash_0</parameter>
|
||||||
<parameter name="initFlashContent" value="true" />
|
<parameter name="initFlashContent" value="false" />
|
||||||
<parameter name="initializationFileName">../sw/n64/build/SummerLoader64.hex</parameter>
|
<parameter name="initializationFileName"></parameter>
|
||||||
<parameter name="initializationFileNameForSim">../sw/n64/build/SummerLoader64.hex</parameter>
|
<parameter name="initializationFileNameForSim"></parameter>
|
||||||
<parameter name="useNonDefaultInitFile" value="true" />
|
<parameter name="useNonDefaultInitFile" value="false" />
|
||||||
</module>
|
</module>
|
||||||
<interconnectRequirement for="$system" name="qsys_mm.clockCrossingAdapter" value="HANDSHAKE" />
|
<interconnectRequirement for="$system" name="qsys_mm.clockCrossingAdapter" value="HANDSHAKE" />
|
||||||
<interconnectRequirement for="$system" name="qsys_mm.enableEccProtection" value="FALSE" />
|
<interconnectRequirement for="$system" name="qsys_mm.enableEccProtection" value="FALSE" />
|
||||||
|
@ -11,7 +11,7 @@ package sc64;
|
|||||||
|
|
||||||
typedef enum bit [3:0] {
|
typedef enum bit [3:0] {
|
||||||
ID_CPU_RAM,
|
ID_CPU_RAM,
|
||||||
ID_CPU_BOOTLOADER,
|
ID_CPU_FLASH,
|
||||||
ID_CPU_GPIO,
|
ID_CPU_GPIO,
|
||||||
ID_CPU_I2C,
|
ID_CPU_I2C,
|
||||||
ID_CPU_USB,
|
ID_CPU_USB,
|
||||||
@ -21,7 +21,6 @@ package sc64;
|
|||||||
ID_CPU_SDRAM,
|
ID_CPU_SDRAM,
|
||||||
ID_CPU_FLASHRAM,
|
ID_CPU_FLASHRAM,
|
||||||
ID_CPU_SI,
|
ID_CPU_SI,
|
||||||
ID_CPU_FLASH,
|
|
||||||
__ID_CPU_END
|
__ID_CPU_END
|
||||||
} e_cpu_id;
|
} e_cpu_id;
|
||||||
|
|
||||||
@ -32,9 +31,9 @@ package sc64;
|
|||||||
} e_dma_id;
|
} e_dma_id;
|
||||||
|
|
||||||
parameter bit [31:0] SC64_VER = 32'h53437632;
|
parameter bit [31:0] SC64_VER = 32'h53437632;
|
||||||
|
|
||||||
parameter int CLOCK_FREQUENCY = 32'd100_000_000;
|
parameter int CLOCK_FREQUENCY = 32'd100_000_000;
|
||||||
|
parameter bit [31:0] CPU_RESET_VECTOR = {4'(ID_CPU_FLASH), 28'h0035800};
|
||||||
|
parameter bit CPU_HAS_UART = 1'b0;
|
||||||
parameter int UART_BAUD_RATE = 32'd1_000_000;
|
parameter int UART_BAUD_RATE = 32'd1_000_000;
|
||||||
|
|
||||||
endpackage
|
endpackage
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
set flow [lindex $quartus(args) 0]
|
set flow [lindex $quartus(args) 0]
|
||||||
|
|
||||||
if [string match "compile" $flow] {
|
if [string match "quartus_asm" $flow] {
|
||||||
post_message "Generating final programming file"
|
post_message "Generating final programming file"
|
||||||
qexec "quartus_cpf -c SummerCart64.cof"
|
qexec "quartus_cpf -c SummerCart64.cof"
|
||||||
}
|
}
|
@ -1,47 +1,44 @@
|
|||||||
TOOLCHAIN = riscv32-unknown-elf-
|
TOOLCHAIN = riscv32-unknown-elf-
|
||||||
CC = $(TOOLCHAIN)gcc
|
CC = $(TOOLCHAIN)gcc
|
||||||
|
AS = $(TOOLCHAIN)as
|
||||||
OBJCOPY = $(TOOLCHAIN)objcopy
|
OBJCOPY = $(TOOLCHAIN)objcopy
|
||||||
|
OBJDUMP = $(TOOLCHAIN)objdump
|
||||||
SIZE = $(TOOLCHAIN)size
|
SIZE = $(TOOLCHAIN)size
|
||||||
|
|
||||||
FLAGS = -mabi=ilp32 -march=rv32i $(USER_FLAGS)
|
FLAGS = -mabi=ilp32 -march=rv32i
|
||||||
CFLAGS = -Os -Wall -ffunction-sections -fdata-sections -ffreestanding -MMD -MP
|
CFLAGS = -Os -Wall -ffunction-sections -fdata-sections -ffreestanding -MMD -MP
|
||||||
LDFLAGS = -nostartfiles -Wl,--gc-sections
|
LDFLAGS = -nostartfiles -Wl,--gc-sections
|
||||||
|
|
||||||
SRC_DIR = src
|
SRC_DIR = src
|
||||||
BUILD_DIR = build
|
BUILD_DIR = build
|
||||||
|
|
||||||
SRCS = $(wildcard $(patsubst %, %/*.c, . $(SRC_DIR)))
|
SRC_FILES = startup.S process.c usb.c cfg.c dma.c joybus.c rtc.c i2c.c flashram.c uart.c flash.c
|
||||||
OBJS = $(addprefix $(BUILD_DIR)/, $(notdir $(SRCS:.c=.o)))
|
|
||||||
|
SRCS = $(addprefix $(SRC_DIR)/, $(SRC_FILES))
|
||||||
|
OBJS = $(addprefix $(BUILD_DIR)/, $(notdir $(patsubst %,%.o,$(SRCS))))
|
||||||
DEPS = $(OBJS:.o=.d)
|
DEPS = $(OBJS:.o=.d)
|
||||||
|
|
||||||
VPATH = $(SRC_DIR)
|
VPATH = $(SRC_DIR)
|
||||||
|
|
||||||
$(@info $(shell mkdir -p ./$(BUILD_DIR) &> /dev/null))
|
$(@info $(shell mkdir -p ./$(BUILD_DIR) &> /dev/null))
|
||||||
|
|
||||||
all: $(BUILD_DIR)/cpu_bootloader.sv $(BUILD_DIR)/controller.rom
|
all: $(BUILD_DIR)/governor.hex
|
||||||
|
|
||||||
$(BUILD_DIR)/%.o: %.c
|
$(BUILD_DIR)/%.c.o: %.c
|
||||||
$(CC) $(FLAGS) $(CFLAGS) -c $< -o $@
|
$(CC) $(FLAGS) $(CFLAGS) $(USER_FLAGS) -c $< -o $@
|
||||||
|
|
||||||
$(BUILD_DIR)/uc.elf: $(OBJS) SC64.ld
|
$(BUILD_DIR)/%.S.o: %.S
|
||||||
$(CC) $(FLAGS) $(LDFLAGS) -TSC64.ld $(OBJS) -o $@
|
$(AS) $(FLAGS) $(ASFLAGS) -c $< -o $@
|
||||||
|
|
||||||
$(BUILD_DIR)/controller.rom: $(BUILD_DIR)/uc.elf
|
$(BUILD_DIR)/governor.hex: $(OBJS) SC64.ld
|
||||||
$(OBJCOPY) -R .bootloader $(BUILD_DIR)/uc.elf $(BUILD_DIR)/controller.elf
|
$(CC) $(FLAGS) $(LDFLAGS) -TSC64.ld $(OBJS) -o $(BUILD_DIR)/governor.elf
|
||||||
$(OBJCOPY) -O binary --set-section-flags .bss=alloc,contents $(BUILD_DIR)/controller.elf $(BUILD_DIR)/controller.bin
|
$(OBJDUMP) -D $(BUILD_DIR)/governor.elf > $(BUILD_DIR)/governor.map
|
||||||
$(OBJCOPY) -I binary -O ihex $(BUILD_DIR)/controller.bin $(BUILD_DIR)/controller.hex
|
$(OBJCOPY) -O binary $(BUILD_DIR)/governor.elf $(BUILD_DIR)/governor.bin
|
||||||
python3 tools/bin2rom.py $@ < $(BUILD_DIR)/controller.bin
|
$(OBJCOPY) -I binary -O ihex $(BUILD_DIR)/governor.bin $@
|
||||||
@echo 'Size of controller modules:'
|
@echo 'Size of modules:'
|
||||||
@$(SIZE) -B -t --common $(OBJS)
|
@$(SIZE) -B -t --common $(OBJS)
|
||||||
@echo 'Size of controller:'
|
@echo 'Size of governor:'
|
||||||
@$(SIZE) -B $(BUILD_DIR)/controller.elf
|
@$(SIZE) -B $(BUILD_DIR)/governor.elf
|
||||||
|
|
||||||
$(BUILD_DIR)/cpu_bootloader.sv: $(BUILD_DIR)/uc.elf
|
|
||||||
$(OBJCOPY) -j .bootloader $(BUILD_DIR)/uc.elf $(BUILD_DIR)/bootloader.elf
|
|
||||||
$(OBJCOPY) -O binary $(BUILD_DIR)/bootloader.elf $(BUILD_DIR)/bootloader.bin
|
|
||||||
python3 tools/bin2sv.py tools/cpu_bootloader_template.sv $@ < $(BUILD_DIR)/bootloader.bin
|
|
||||||
@echo 'Size of bootloader:'
|
|
||||||
@$(SIZE) -B $(BUILD_DIR)/bootloader.elf
|
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -rf ./$(BUILD_DIR)/*
|
rm -rf ./$(BUILD_DIR)/*
|
||||||
|
@ -1,51 +1,49 @@
|
|||||||
MEMORY {
|
MEMORY {
|
||||||
RAM (rwx) : org = 0x00000000, len = 16k
|
ram (rwx) : org = 0x00000000, len = 16k
|
||||||
ROM (rx) : org = 0x10000000, len = 128
|
rom (rx) : org = 0x10035800, len = 16k
|
||||||
}
|
}
|
||||||
|
|
||||||
__stack_pointer = ORIGIN(RAM) + LENGTH(RAM) - 16;
|
|
||||||
|
|
||||||
ENTRY(reset_handler)
|
ENTRY(reset_handler)
|
||||||
|
|
||||||
SECTIONS {
|
SECTIONS {
|
||||||
.text : {
|
.text.reset_handler : {
|
||||||
*(.text.app_handler)
|
*(.text.reset_handler)
|
||||||
*(.text.unlikely .text.unlikely.*)
|
} > rom
|
||||||
*(.text.startup .text.startup.*)
|
|
||||||
*(.text .text.*)
|
|
||||||
*(.gnu.linkonce.t.*)
|
|
||||||
} > RAM
|
|
||||||
|
|
||||||
.rodata : {
|
.text : {
|
||||||
*(.rdata)
|
_sitext = LOADADDR(.text);
|
||||||
*(.rodata .rodata.*)
|
. = ALIGN(4);
|
||||||
*(.gnu.linkonce.r.*)
|
_stext = .;
|
||||||
. = ALIGN(8);
|
*(.text .text.* .gnu.linkonce.t.*)
|
||||||
*(.srodata.cst16)
|
*(.rodata .rodata.* .gnu.linkonce.r.*)
|
||||||
*(.srodata.cst8)
|
. = ALIGN(4);
|
||||||
*(.srodata.cst4)
|
_etext = .;
|
||||||
*(.srodata.cst2)
|
} > ram AT > rom
|
||||||
*(.srodata .srodata.*)
|
|
||||||
} > RAM
|
|
||||||
|
|
||||||
.data : {
|
.data : {
|
||||||
*(.data .data.*)
|
_sidata = LOADADDR(.data);
|
||||||
*(.gnu.linkonce.d.*)
|
. = ALIGN(4);
|
||||||
. = ALIGN(8);
|
_sdata = .;
|
||||||
PROVIDE(__global_pointer = . + 0x800);
|
*(.data .data.* .gnu.linkonce.d.*)
|
||||||
*(.sdata .sdata.* .sdata2.*)
|
. = ALIGN(4);
|
||||||
*(.gnu.linkonce.s.*)
|
_ssdata = .;
|
||||||
} > RAM
|
*(.srodata.cst16) *(.srodata.cst8) *(.srodata.cst4) *(.srodata.cst2) *(.srodata .srodata.*)
|
||||||
|
*(.sdata .sdata.* .gnu.linkonce.s.*)
|
||||||
|
. = ALIGN(4);
|
||||||
|
_edata = .;
|
||||||
|
} > ram AT > rom
|
||||||
|
|
||||||
.bss : ALIGN(8) {
|
.bss : {
|
||||||
*(.sbss*)
|
. = ALIGN(4);
|
||||||
*(.gnu.linkonce.sb.*)
|
_sbss = .;
|
||||||
*(.bss .bss.*)
|
*(.sbss .sbss.* .gnu.linkonce.sb.*)
|
||||||
*(.gnu.linkonce.b.*)
|
*(.scommon)
|
||||||
|
*(.bss .bss.* .gnu.linkonce.b.*)
|
||||||
*(COMMON)
|
*(COMMON)
|
||||||
} > RAM
|
. = ALIGN(4);
|
||||||
|
_ebss = .;
|
||||||
|
} > ram
|
||||||
|
|
||||||
.bootloader : {
|
__global_pointer$ = MIN(_ssdata + 0x800, MAX(_sdata + 0x800, _ebss - 0x800));
|
||||||
*(.text.reset_handler)
|
__stack_pointer$ = ORIGIN(ram) + LENGTH(ram);
|
||||||
} > ROM
|
|
||||||
}
|
}
|
||||||
|
@ -19,8 +19,3 @@ void dma_stop (void) {
|
|||||||
void dma_init (void) {
|
void dma_init (void) {
|
||||||
dma_stop();
|
dma_stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void process_dma (void) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
@ -20,7 +20,6 @@ bool dma_busy (void);
|
|||||||
void dma_start (uint32_t memory_address, size_t length, enum dma_id id, enum dma_dir dir);
|
void dma_start (uint32_t memory_address, size_t length, enum dma_id id, enum dma_dir dir);
|
||||||
void dma_stop (void);
|
void dma_stop (void);
|
||||||
void dma_init (void);
|
void dma_init (void);
|
||||||
void process_dma (void);
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -14,6 +14,17 @@ enum operation {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct process {
|
||||||
|
bool save_in_progress;
|
||||||
|
enum operation op;
|
||||||
|
io32_t *save_pointer;
|
||||||
|
uint32_t num_words;
|
||||||
|
uint32_t current_word;
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct process p;
|
||||||
|
|
||||||
|
|
||||||
static enum operation get_operation_type (void) {
|
static enum operation get_operation_type (void) {
|
||||||
uint32_t scr = FLASHRAM->SCR;
|
uint32_t scr = FLASHRAM->SCR;
|
||||||
|
|
||||||
@ -44,26 +55,38 @@ static size_t get_operation_length (enum operation op) {
|
|||||||
|
|
||||||
void flashram_init (void) {
|
void flashram_init (void) {
|
||||||
FLASHRAM->SCR = FLASHRAM_OPERATION_DONE;
|
FLASHRAM->SCR = FLASHRAM_OPERATION_DONE;
|
||||||
|
|
||||||
|
p.save_in_progress = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void process_flashram (void) {
|
void process_flashram (void) {
|
||||||
enum operation op = get_operation_type();
|
if (!p.save_in_progress) {
|
||||||
size_t length;
|
p.op = get_operation_type();
|
||||||
io32_t *save_data;
|
|
||||||
|
|
||||||
if (op != OP_NONE) {
|
if (p.op != OP_NONE) {
|
||||||
length = get_operation_length(op);
|
uint32_t sdram_address = SDRAM_BASE + CFG->SAVE_OFFSET;
|
||||||
save_data = (io32_t *) (SDRAM_BASE + CFG->SAVE_OFFSET + ((FLASHRAM->SCR >> FLASHRAM_PAGE_BIT) * FLASHRAM_PAGE_SIZE));
|
|
||||||
|
|
||||||
for (uint32_t i = 0; i < (length / 4); i++) {
|
p.save_in_progress = true;
|
||||||
if (op == OP_WRITE_PAGE) {
|
if (p.op != OP_ERASE_ALL) {
|
||||||
*save_data++ &= FLASHRAM->BUFFER[i];
|
sdram_address += (FLASHRAM->SCR >> FLASHRAM_PAGE_BIT) * FLASHRAM_PAGE_SIZE;
|
||||||
|
}
|
||||||
|
p.save_pointer = (io32_t *) (sdram_address);
|
||||||
|
p.num_words = get_operation_length(p.op) / sizeof(uint32_t);
|
||||||
|
p.current_word = 0;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
*save_data++ = FLASHRAM_ERASE_VALUE;
|
if (p.op == OP_WRITE_PAGE) {
|
||||||
}
|
*p.save_pointer++ &= FLASHRAM->BUFFER[p.current_word];
|
||||||
|
} else {
|
||||||
|
*p.save_pointer++ = FLASHRAM_ERASE_VALUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
p.current_word += 1;
|
||||||
|
|
||||||
|
if (p.current_word >= p.num_words) {
|
||||||
|
p.save_in_progress = false;
|
||||||
FLASHRAM->SCR = FLASHRAM_OPERATION_DONE;
|
FLASHRAM->SCR = FLASHRAM_OPERATION_DONE;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,26 +0,0 @@
|
|||||||
#include <stdint.h>
|
|
||||||
#include "sys.h"
|
|
||||||
|
|
||||||
|
|
||||||
__attribute__ ((naked, section(".bootloader"))) void reset_handler (void) {
|
|
||||||
io32_t *ram = (io32_t *) &RAM;
|
|
||||||
io32_t *flash = (io32_t *) (FLASH_BASE + FLASH_CPU_IMAGE_OFFSET);
|
|
||||||
|
|
||||||
for (int i = 0; i < RAM_SIZE; i += 4) {
|
|
||||||
*ram++ = *flash++;
|
|
||||||
}
|
|
||||||
|
|
||||||
__asm__ volatile (
|
|
||||||
"la t0, app_handler \n"
|
|
||||||
"jalr zero, t0 \n"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
__attribute__ ((naked)) void app_handler (void) {
|
|
||||||
__asm__ volatile (
|
|
||||||
"la sp, __stack_pointer \n"
|
|
||||||
"la gp, __global_pointer \n"
|
|
||||||
"jal zero, main \n"
|
|
||||||
);
|
|
||||||
}
|
|
@ -1,7 +0,0 @@
|
|||||||
#include "process.h"
|
|
||||||
|
|
||||||
|
|
||||||
void main (void) {
|
|
||||||
process_init();
|
|
||||||
process_loop();
|
|
||||||
}
|
|
@ -9,7 +9,20 @@
|
|||||||
#include "uart.h"
|
#include "uart.h"
|
||||||
|
|
||||||
|
|
||||||
void process_init (void) {
|
static const void (*process_table[])(void) = {
|
||||||
|
process_usb,
|
||||||
|
process_cfg,
|
||||||
|
process_rtc,
|
||||||
|
process_i2c,
|
||||||
|
process_flashram,
|
||||||
|
process_uart,
|
||||||
|
NULL,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
__attribute__((naked)) void process_loop (void) {
|
||||||
|
void (**process_func)(void) = process_table;
|
||||||
|
|
||||||
usb_init();
|
usb_init();
|
||||||
cfg_init();
|
cfg_init();
|
||||||
dma_init();
|
dma_init();
|
||||||
@ -18,18 +31,12 @@ void process_init (void) {
|
|||||||
i2c_init();
|
i2c_init();
|
||||||
flashram_init();
|
flashram_init();
|
||||||
uart_init();
|
uart_init();
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void process_loop (void) {
|
|
||||||
while (1) {
|
while (1) {
|
||||||
process_usb();
|
|
||||||
process_cfg();
|
|
||||||
process_dma();
|
|
||||||
process_joybus();
|
process_joybus();
|
||||||
process_rtc();
|
(*process_func++)();
|
||||||
process_i2c();
|
if (*process_func == NULL) {
|
||||||
process_flashram();
|
process_func = process_table;
|
||||||
process_uart();
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -86,7 +86,13 @@ bool rtc_is_time_running (void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void rtc_set_time (rtc_time_t *time) {
|
void rtc_set_time (rtc_time_t *time) {
|
||||||
p.time = *time;
|
p.time.second = time->second;
|
||||||
|
p.time.minute = time->minute;
|
||||||
|
p.time.hour = time->hour;
|
||||||
|
p.time.weekday = time->weekday;
|
||||||
|
p.time.day = time->day;
|
||||||
|
p.time.month = time->month;
|
||||||
|
p.time.year = time->year;
|
||||||
p.new_time_valid = true;
|
p.new_time_valid = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
48
sw/riscv/src/startup.S
Normal file
48
sw/riscv/src/startup.S
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
.section .text.reset_handler
|
||||||
|
|
||||||
|
reset_handler:
|
||||||
|
.global reset_handler
|
||||||
|
|
||||||
|
.option push
|
||||||
|
.option norelax
|
||||||
|
la gp, __global_pointer$
|
||||||
|
.option pop
|
||||||
|
|
||||||
|
la sp, __stack_pointer$
|
||||||
|
|
||||||
|
init_text:
|
||||||
|
la a0, _sitext
|
||||||
|
la a1, _stext
|
||||||
|
la a2, _etext
|
||||||
|
call copy_section
|
||||||
|
|
||||||
|
init_data:
|
||||||
|
la a0, _sidata
|
||||||
|
la a1, _sdata
|
||||||
|
la a2, _edata
|
||||||
|
call copy_section
|
||||||
|
|
||||||
|
init_bss:
|
||||||
|
la a0, _sbss
|
||||||
|
la a1, _ebss
|
||||||
|
bge a0, a1, 2f
|
||||||
|
1:
|
||||||
|
sw zero, 0(a0)
|
||||||
|
addi a0, a0, 4
|
||||||
|
blt a0, a1, 1b
|
||||||
|
2:
|
||||||
|
|
||||||
|
run_in_ram:
|
||||||
|
la ra, process_loop
|
||||||
|
jalr zero, 0(ra)
|
||||||
|
|
||||||
|
copy_section:
|
||||||
|
bge a1, a2, 2f
|
||||||
|
1:
|
||||||
|
lw a3, 0(a0)
|
||||||
|
sw a3, 0(a1)
|
||||||
|
addi a0, a0, 4
|
||||||
|
addi a1, a1, 4
|
||||||
|
blt a1, a2, 1b
|
||||||
|
2:
|
||||||
|
ret
|
@ -16,8 +16,35 @@ typedef volatile uint32_t io32_t;
|
|||||||
#define RAM_SIZE (16 * 1024)
|
#define RAM_SIZE (16 * 1024)
|
||||||
|
|
||||||
|
|
||||||
#define BOOTLOADER_BASE (0x10000000UL)
|
#define FLASH_BASE (0x10000000UL)
|
||||||
#define BOOTLOADER (*((io32_t *) BOOTLOADER_BASE))
|
#define FLASH (*((io32_t *) FLASH_BASE))
|
||||||
|
|
||||||
|
#define FLASH_SIZE (0x39800)
|
||||||
|
#define FLASH_NUM_SECTORS (4)
|
||||||
|
|
||||||
|
|
||||||
|
typedef volatile struct flash_config_regs {
|
||||||
|
io32_t SR;
|
||||||
|
io32_t CR;
|
||||||
|
} flash_config_regs_t;
|
||||||
|
|
||||||
|
#define FLASH_CONFIG_BASE (0x18000000UL)
|
||||||
|
#define FLASH_CONFIG ((flash_config_regs_t *) FLASH_CONFIG_BASE)
|
||||||
|
|
||||||
|
#define FLASH_SR_STATUS_MASK (3 << 0)
|
||||||
|
#define FLASH_SR_STATUS_IDLE (0)
|
||||||
|
#define FLASH_SR_STATUS_BUSY_ERASE (1)
|
||||||
|
#define FLASH_SR_STATUS_BUSY_WRITE (2)
|
||||||
|
#define FLASH_SR_STATUS_BUSY_READ (3)
|
||||||
|
#define FLASH_SR_READ_SUCCESSFUL (1 << 2)
|
||||||
|
#define FLASH_SR_WRITE_SUCCESSFUL (1 << 3)
|
||||||
|
#define FLASH_SR_ERASE_SUCCESSFUL (1 << 4)
|
||||||
|
#define FLASH_SR_WRITE_PROTECT_BIT (5)
|
||||||
|
|
||||||
|
#define FLASH_CR_PAGE_ERASE_BIT (0)
|
||||||
|
#define FLASH_CR_SECTOR_ERASE_BIT (20)
|
||||||
|
#define FLASH_CR_SECTOR_ERASE_MASK (7 << FLASH_CR_SECTOR_ERASE_BIT)
|
||||||
|
#define FLASH_CR_WRITE_PROTECT_BIT (23)
|
||||||
|
|
||||||
|
|
||||||
typedef volatile struct gpio_regs {
|
typedef volatile struct gpio_regs {
|
||||||
@ -158,40 +185,4 @@ typedef volatile struct joybus_regs {
|
|||||||
#define JOYBUS_SCR_TX_LENGTH_BIT (16)
|
#define JOYBUS_SCR_TX_LENGTH_BIT (16)
|
||||||
|
|
||||||
|
|
||||||
#define FLASH_BASE (0xB0000000UL)
|
|
||||||
#define FLASH (*((io32_t *) FLASH_BASE))
|
|
||||||
|
|
||||||
#define FLASH_CPU_IMAGE_OFFSET (0x35800)
|
|
||||||
#define FLASH_SIZE (0x39800)
|
|
||||||
#define FLASH_NUM_SECTORS (4)
|
|
||||||
|
|
||||||
|
|
||||||
typedef volatile struct flash_config_regs {
|
|
||||||
io32_t SR;
|
|
||||||
io32_t CR;
|
|
||||||
} flash_config_regs_t;
|
|
||||||
|
|
||||||
#define FLASH_CONFIG_BASE (0xB8000000UL)
|
|
||||||
#define FLASH_CONFIG ((flash_config_regs_t *) FLASH_CONFIG_BASE)
|
|
||||||
|
|
||||||
#define FLASH_SR_STATUS_MASK (3 << 0)
|
|
||||||
#define FLASH_SR_STATUS_IDLE (0)
|
|
||||||
#define FLASH_SR_STATUS_BUSY_ERASE (1)
|
|
||||||
#define FLASH_SR_STATUS_BUSY_WRITE (2)
|
|
||||||
#define FLASH_SR_STATUS_BUSY_READ (3)
|
|
||||||
#define FLASH_SR_READ_SUCCESSFUL (1 << 2)
|
|
||||||
#define FLASH_SR_WRITE_SUCCESSFUL (1 << 3)
|
|
||||||
#define FLASH_SR_ERASE_SUCCESSFUL (1 << 4)
|
|
||||||
#define FLASH_SR_WRITE_PROTECT_BIT (5)
|
|
||||||
|
|
||||||
#define FLASH_CR_PAGE_ERASE_BIT (0)
|
|
||||||
#define FLASH_CR_SECTOR_ERASE_BIT (20)
|
|
||||||
#define FLASH_CR_SECTOR_ERASE_MASK (7 << FLASH_CR_SECTOR_ERASE_BIT)
|
|
||||||
#define FLASH_CR_WRITE_PROTECT_BIT (23)
|
|
||||||
|
|
||||||
|
|
||||||
void reset_handler (void);
|
|
||||||
void app_handler (void);
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -54,11 +54,6 @@ void process_uart (void) {
|
|||||||
reset_handler();
|
reset_handler();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case '\'':
|
|
||||||
uart_print("App reset...\n");
|
|
||||||
app_handler();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 't':
|
case 't':
|
||||||
time = rtc_get_time();
|
time = rtc_get_time();
|
||||||
uart_print("Current time: ");
|
uart_print("Current time: ");
|
||||||
|
@ -1,22 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
import os
|
|
||||||
import sys
|
|
||||||
|
|
||||||
rom = None
|
|
||||||
|
|
||||||
rom_name = sys.argv[1] or 'rom.bin'
|
|
||||||
|
|
||||||
try:
|
|
||||||
binary_data = sys.stdin.buffer.read()
|
|
||||||
if (os.path.exists(rom_name)):
|
|
||||||
os.remove(rom_name)
|
|
||||||
rom = open(rom_name, mode='wb')
|
|
||||||
rom.write(len(binary_data).to_bytes(4, byteorder='little'))
|
|
||||||
rom.write(binary_data)
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
print(f'Unable to convert the rom: {e}', file=sys.stderr)
|
|
||||||
sys.exit(-1)
|
|
||||||
|
|
||||||
finally:
|
|
||||||
if (rom): rom.close()
|
|
@ -1,34 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
import struct
|
|
||||||
import sys
|
|
||||||
|
|
||||||
sv_template = None
|
|
||||||
sv_code = None
|
|
||||||
|
|
||||||
template_name = sys.argv[1] or 'template.sv'
|
|
||||||
code_name = sys.argv[2] or 'result.sv'
|
|
||||||
|
|
||||||
try:
|
|
||||||
sv_template = open(template_name, mode='r')
|
|
||||||
sv_code = open(code_name, mode='w')
|
|
||||||
|
|
||||||
var_name = sv_template.readline().strip()
|
|
||||||
|
|
||||||
rom_formatted = ''
|
|
||||||
index = 0
|
|
||||||
for line in iter(lambda: sys.stdin.buffer.read(4), ''):
|
|
||||||
if (not line):
|
|
||||||
break
|
|
||||||
value = format(struct.unpack('<I', line)[0], '08x')
|
|
||||||
rom_formatted += f'\n {index}: {var_name} = 32\'h{value};'
|
|
||||||
index += 1
|
|
||||||
|
|
||||||
sv_code.write(sv_template.read().format(rom_formatted=rom_formatted))
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
print(f'Unable to convert the code: {e}', file=sys.stderr)
|
|
||||||
sys.exit(-1)
|
|
||||||
|
|
||||||
finally:
|
|
||||||
if (sv_template): sv_template.close()
|
|
||||||
if (sv_code): sv_code.close()
|
|
@ -1,23 +0,0 @@
|
|||||||
bus.rdata
|
|
||||||
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]){rom_formatted}
|
|
||||||
default: bus.rdata = 32'd0;
|
|
||||||
endcase
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
endmodule
|
|
Loading…
Reference in New Issue
Block a user