Disabled external gits
This commit is contained in:
169
cs309-psoc/lab_4_0/README
Normal file
169
cs309-psoc/lab_4_0/README
Normal file
@ -0,0 +1,169 @@
|
||||
README
|
||||
======
|
||||
|
||||
The file tree shown at the end of this README lists all the contents of the
|
||||
provided template. In addition to the standard file hierarchy you have been
|
||||
using for the previous labs, the template for this lab contains the VHDL files
|
||||
and Linux kernel module of 2 new custom interfaces:
|
||||
|
||||
1) framebuffer device
|
||||
2) VGA output
|
||||
|
||||
The hardware files are available under hw/hdl/displays/
|
||||
The Linux kernel device tree is available under sw/hps/linux/device_tree/
|
||||
The Linux kernel module is available under sw/hps/linux/driver/fbdev/
|
||||
|
||||
How to use the template
|
||||
=======================
|
||||
|
||||
Background
|
||||
==========
|
||||
We need to re-create a linux system in this lab, but we cannot directly copy
|
||||
and modify the one you created in the previous labs since some of the tools
|
||||
used in the middle hard-code absolute paths in many generated files...
|
||||
|
||||
Therefore, we provide you with a shell script which performs all the steps
|
||||
you did in lab 3.0 and 3.1 in order to get a bootable linux system. Namely
|
||||
the script performs the following steps automatically:
|
||||
|
||||
1) Compiles the Quartus project.
|
||||
2) Generates and compiles the Preloader.
|
||||
3) Downloads and compiles U-Boot.
|
||||
4) Downloads and compiles Linux.
|
||||
5) Downloads and creates a Ubuntu 14.04.5 root filesystem.
|
||||
6) Partitions the sdcard.
|
||||
7) Writes all files to the sdcard.
|
||||
|
||||
BEFORE you start your mini-project
|
||||
==================================
|
||||
Follow the steps listed below in order to create a bootable sdcard
|
||||
containing a Linux OS:
|
||||
|
||||
1) Replace all files indicated with the "OVERWRITE" label in the file
|
||||
tree shown at the end of this README with the files you implemented
|
||||
in the previous labs.
|
||||
|
||||
2) Plug in your sdcard into your Linux computer/VM and take note of the
|
||||
identifier the OS assigned to it. This README assumes the identifier
|
||||
assigned to the sdcard is "/dev/sdb".
|
||||
|
||||
WARNING : Be ABSOLUTELY SURE that you have the correct drive
|
||||
identifier or else we will later accidentally format the
|
||||
wrong drive!
|
||||
|
||||
3) Start an embedded command shell.
|
||||
|
||||
4) Execute the create_linux_system.sh script as follows:
|
||||
$ ./create_linux_system.sh /dev/sdb
|
||||
|
||||
WARNING : Again, be absolutely sure that you have used the correct
|
||||
drive identifier before running the command above!
|
||||
|
||||
The lower bound for the execution time of the script is around 25
|
||||
minutes (the time it takes to compile all files). However, the script
|
||||
also clones large git repositories, so the total execution time can
|
||||
vary greatly depending on the download speed. Be patient :).
|
||||
|
||||
AFTER you start your mini-project
|
||||
=================================
|
||||
You can now follow the steps explained in the lab statement.
|
||||
|
||||
File tree
|
||||
=========
|
||||
lab_4_0_template/
|
||||
├── create_hw_headers.sh
|
||||
├── create_linux_system.sh
|
||||
├── hw
|
||||
│ ├── hdl
|
||||
│ │ ├── DE0_Nano_SoC_PrSoC_extn_board_top_level.vhd
|
||||
│ │ ├── displays
|
||||
│ │ │ ├── framebuffer_manager
|
||||
│ │ │ │ └── hdl
|
||||
│ │ │ │ ├── dc_video_fifo.vhd
|
||||
│ │ │ │ ├── framebuffer_manager_hw.tcl
|
||||
│ │ │ │ └── framebuffer_manager.vhd
|
||||
│ │ │ └── vga_sequencer
|
||||
│ │ │ └── hdl
|
||||
│ │ │ ├── vga_sequencer_hw.tcl
|
||||
│ │ │ └── vga_sequencer.vhd
|
||||
│ │ ├── joysticks
|
||||
│ │ │ ├── hdl
|
||||
│ │ │ │ ├── mcp3204_hw.tcl
|
||||
│ │ │ │ ├── mcp3204_spi.vhd ------------------------> # OVERWRITE : Overwrite with your previous implementation.
|
||||
│ │ │ │ └── mcp3204.vhd
|
||||
│ │ │ └── tb
|
||||
│ │ │ ├── tb_mcp3204_spi.vhd
|
||||
│ │ │ └── tb_mcp3204.vhd
|
||||
│ │ ├── lepton
|
||||
│ │ │ ├── hdl
|
||||
│ │ │ │ ├── avalon_st_spi_master.vhd
|
||||
│ │ │ │ ├── byte2pix.vhd
|
||||
│ │ │ │ ├── dual_ported_ram.vhd
|
||||
│ │ │ │ ├── lepton_hw.tcl
|
||||
│ │ │ │ ├── lepton_manager.vhd
|
||||
│ │ │ │ ├── lepton_stats.vhd -----------------------> # OVERWRITE : Overwrite with your previous implementation.
|
||||
│ │ │ │ ├── lepton.vhd
|
||||
│ │ │ │ ├── level_adjuster.vhd ---------------------> # OVERWRITE : Overwrite with your previous implementation.
|
||||
│ │ │ │ ├── lpm_divider.vhd
|
||||
│ │ │ │ ├── ram_writer.vhd
|
||||
│ │ │ │ └── utils.vhd
|
||||
│ │ │ └── tb
|
||||
│ │ │ └── lepton_tb.vhd
|
||||
│ │ └── pantilt
|
||||
│ │ ├── hdl
|
||||
│ │ │ ├── pwm_constants.vhd ----------------------> # OVERWRITE : Overwrite with your previous implementation.
|
||||
│ │ │ ├── pwm_hw.tcl
|
||||
│ │ │ └── pwm.vhd --------------------------------> # OVERWRITE : Overwrite with your previous implementation.
|
||||
│ │ └── tb
|
||||
│ │ └── tb_pwm.vhd
|
||||
│ ├── modelsim
|
||||
│ └── quartus
|
||||
│ ├── ip
|
||||
│ │ └── components.ipx
|
||||
│ ├── lab_4_0.qpf
|
||||
│ ├── lab_4_0.qsf
|
||||
│ ├── lab_4_0.sdc
|
||||
│ └── soc_system.qsys
|
||||
├── README
|
||||
└── sw
|
||||
└── hps
|
||||
├── application
|
||||
│ ├── hw_headers
|
||||
│ └── lab_4_0
|
||||
│ ├── app.c ----------------------------------> # TODO : Your lab_4_0 mini-project application code goes here.
|
||||
│ ├── displays
|
||||
│ │ ├── batman_320x240.jpg -----------------> # IMAGE : sample input images for "fbv" binary.
|
||||
│ │ ├── batman_480x272.jpg -----------------> # IMAGE : sample input images for "fbv" binary.
|
||||
│ │ ├── fb_multiple_buffering_example.c ----> # DEMO : how to use a framebuffer driver.
|
||||
│ │ └── fbv --------------------------------> # BINARY : "framebuffer viewer" outputs an image to a framebuffer device (http://freecode.com/projects/fbv).
|
||||
│ ├── io_custom.h
|
||||
│ ├── joysticks
|
||||
│ │ ├── joysticks.c ------------------------> # OVERWRITE : Overwrite with your previous implementation.
|
||||
│ │ ├── joysticks.h ------------------------> # OVERWRITE : Overwrite with your previous implementation.
|
||||
│ │ └── mcp3204
|
||||
│ │ ├── mcp3204.c ----------------------> # OVERWRITE : Overwrite with your previous implementation.
|
||||
│ │ ├── mcp3204.h ----------------------> # OVERWRITE : Overwrite with your previous implementation.
|
||||
│ │ └── mcp3204_regs.h -----------------> # OVERWRITE : Overwrite with your previous implementation.
|
||||
│ ├── lepton
|
||||
│ │ ├── lepton.c ---------------------------> # OVERWRITE : Overwrite with your previous implementation.
|
||||
│ │ ├── lepton.h ---------------------------> # OVERWRITE : Overwrite with your previous implementation.
|
||||
│ │ └── lepton_regs.h ----------------------> # OVERWRITE : Overwrite with your previous implementation.
|
||||
│ └── pantilt
|
||||
│ ├── pantilt.c --------------------------> # OVERWRITE : Overwrite with your previous implementation.
|
||||
│ ├── pantilt.h --------------------------> # OVERWRITE : Overwrite with your previous implementation.
|
||||
│ └── pwm
|
||||
│ ├── pwm.c --------------------------> # OVERWRITE : Overwrite with your previous implementation.
|
||||
│ ├── pwm.h --------------------------> # OVERWRITE : Overwrite with your previous implementation.
|
||||
│ └── pwm_regs.h ---------------------> # OVERWRITE : Overwrite with your previous implementation.
|
||||
└── linux
|
||||
├── device_tree
|
||||
│ └── socfpga_cyclone5_de0_sockit_prsoc.dts --> # DEMO : source code of our custom device tree.
|
||||
├── driver
|
||||
│ └── fbdev
|
||||
│ ├── Makefile ---------------------------> # DEMO : makefile of our custom framebuffer driver.
|
||||
│ └── prsoc_fbdev.c ----------------------> # DEMO : source code of our custom framebuffer driver.
|
||||
└── rootfs
|
||||
├── config_post_install.sh
|
||||
└── config_system.sh
|
||||
|
||||
35 directories, 59 files
|
14
cs309-psoc/lab_4_0/create_hw_headers.sh
Executable file
14
cs309-psoc/lab_4_0/create_hw_headers.sh
Executable file
@ -0,0 +1,14 @@
|
||||
#!/bin/bash -x
|
||||
|
||||
# make sure to be in the same directory as this script
|
||||
script_dir_abs=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
|
||||
cd "${script_dir_abs}"
|
||||
|
||||
rm -rf sw/hps/application/hw_headers
|
||||
|
||||
# create target directory if not present
|
||||
mkdir -p sw/hps/application/hw_headers
|
||||
|
||||
sopc-create-header-files \
|
||||
hw/quartus/soc_system.sopcinfo \
|
||||
--output-dir sw/hps/application/hw_headers
|
510
cs309-psoc/lab_4_0/create_linux_system.sh
Executable file
510
cs309-psoc/lab_4_0/create_linux_system.sh
Executable file
@ -0,0 +1,510 @@
|
||||
#!/bin/bash -x
|
||||
|
||||
# ===================================================================================
|
||||
# usage: create_linux_system.sh [sdcard_device]
|
||||
#
|
||||
# positional arguments:
|
||||
# sdcard_device path to sdcard device file [ex: "/dev/sdb", "/dev/mmcblk0"]
|
||||
# ===================================================================================
|
||||
|
||||
# make sure to be in the same directory as this script
|
||||
script_dir_abs=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
|
||||
cd "${script_dir_abs}"
|
||||
|
||||
# constants ####################################################################
|
||||
quartus_dir="$(readlink -m "hw/quartus")"
|
||||
quartus_project_name="$(basename "$(find "${quartus_dir}" -name "*.qpf")" .qpf)"
|
||||
quartus_sof_file="$(readlink -m "${quartus_dir}/output_files/${quartus_project_name}.sof")"
|
||||
|
||||
fpga_device_part_number="5CSEMA4U23C6" # 5CSEMA5F31C6
|
||||
|
||||
preloader_dir="$(readlink -m "sw/hps/preloader")"
|
||||
preloader_settings_dir="$(readlink -m "${quartus_dir}/hps_isw_handoff/soc_system_hps_0")"
|
||||
preloader_settings_file="$(readlink -m "${preloader_dir}/settings.bsp")"
|
||||
preloader_source_tgz_file="$(readlink -m "${SOCEDS_DEST_ROOT}/host_tools/altera/preloader/uboot-socfpga.tar.gz")"
|
||||
preloader_bin_file="${preloader_dir}/preloader-mkpimage.bin"
|
||||
|
||||
uboot_src_dir="$(readlink -m "sw/hps/u-boot")"
|
||||
uboot_src_git_repo="git://git.denx.de/u-boot.git"
|
||||
uboot_src_git_checkout_commit="b104b3dc1dd90cdbf67ccf3c51b06e4f1592fe91"
|
||||
uboot_src_make_config_file="socfpga_de0_nano_soc_defconfig" # socfpga_cyclone5_config
|
||||
uboot_src_config_file="${uboot_src_dir}/include/configs/socfpga_de0_nano_soc.h" # socfpga_cyclone5_socdk.h
|
||||
uboot_script_file="$(readlink -m "${uboot_src_dir}/u-boot.script")"
|
||||
uboot_img_file="$(readlink -m "${uboot_src_dir}/u-boot.img")"
|
||||
|
||||
linux_dir="$(readlink -m "sw/hps/linux")"
|
||||
linux_src_git_repo="https://github.com/altera-opensource/linux-socfpga.git"
|
||||
linux_src_dir="$(readlink -m "${linux_dir}/source")"
|
||||
linux_src_git_checkout_commit="9735a22799b9214d17d3c231fe377fc852f042e9"
|
||||
linux_src_make_config_file="socfpga_defconfig"
|
||||
linux_kernel_mem_arg="1024M"
|
||||
linux_zImage_file="$(readlink -m "${linux_src_dir}/arch/arm/boot/zImage")"
|
||||
linux_dtb_file="$(readlink -m "${linux_src_dir}/arch/arm/boot/dts/socfpga_cyclone5_de0_sockit.dtb")" # socfpga_cyclone5_socdk.dtb
|
||||
|
||||
rootfs_dir="${linux_dir}/rootfs"
|
||||
rootfs_chroot_dir="$(readlink -m ${rootfs_dir}/ubuntu-core-rootfs)"
|
||||
rootfs_src_tgz_link="http://cdimage.ubuntu.com/ubuntu-base/releases/14.04.5/release/ubuntu-base-14.04.5-base-armhf.tar.gz"
|
||||
rootfs_src_tgz_file="$(readlink -m "${rootfs_dir}/${rootfs_src_tgz_link##*/}")"
|
||||
rootfs_system_config_script_file="${rootfs_dir}/config_system.sh"
|
||||
rootfs_post_install_config_script_file="${rootfs_dir}/config_post_install.sh"
|
||||
|
||||
sdcard_fat32_dir="$(readlink -m "sdcard/fat32")"
|
||||
sdcard_fat32_rbf_file="$(readlink -m "${sdcard_fat32_dir}/socfpga.rbf")"
|
||||
sdcard_fat32_uboot_img_file="$(readlink -m "${sdcard_fat32_dir}/$(basename "${uboot_img_file}")")"
|
||||
sdcard_fat32_uboot_scr_file="$(readlink -m "${sdcard_fat32_dir}/u-boot.scr")"
|
||||
sdcard_fat32_zImage_file="$(readlink -m "${sdcard_fat32_dir}/zImage")"
|
||||
sdcard_fat32_dtb_file="$(readlink -m "${sdcard_fat32_dir}/socfpga.dtb")"
|
||||
|
||||
sdcard_dev="$(readlink -m "${1}")"
|
||||
|
||||
sdcard_ext3_rootfs_tgz_file="$(readlink -m "sdcard/ext3_rootfs.tar.gz")"
|
||||
|
||||
sdcard_a2_dir="$(readlink -m "sdcard/a2")"
|
||||
sdcard_a2_preloader_bin_file="$(readlink -m "${sdcard_a2_dir}/$(basename "${preloader_bin_file}")")"
|
||||
|
||||
sdcard_partition_size_fat32="32M"
|
||||
sdcard_partition_size_linux="512M"
|
||||
|
||||
sdcard_partition_number_fat32="1"
|
||||
sdcard_partition_number_ext3="2"
|
||||
sdcard_partition_number_a2="3"
|
||||
|
||||
if [ "$(echo "${sdcard_dev}" | grep -P "/dev/sd\w.*$")" ]; then
|
||||
sdcard_dev_fat32_id="${sdcard_partition_number_fat32}"
|
||||
sdcard_dev_ext3_id="${sdcard_partition_number_ext3}"
|
||||
sdcard_dev_a2_id="${sdcard_partition_number_a2}"
|
||||
elif [ "$(echo "${sdcard_dev}" | grep -P "/dev/mmcblk\w.*$")" ]; then
|
||||
sdcard_dev_fat32_id="p${sdcard_partition_number_fat32}"
|
||||
sdcard_dev_ext3_id="p${sdcard_partition_number_ext3}"
|
||||
sdcard_dev_a2_id="p${sdcard_partition_number_a2}"
|
||||
fi
|
||||
|
||||
sdcard_dev_fat32="${sdcard_dev}${sdcard_dev_fat32_id}"
|
||||
sdcard_dev_ext3="${sdcard_dev}${sdcard_dev_ext3_id}"
|
||||
sdcard_dev_a2="${sdcard_dev}${sdcard_dev_a2_id}"
|
||||
sdcard_dev_fat32_mount_point="$(readlink -m "sdcard/mount_point_fat32")"
|
||||
sdcard_dev_ext3_mount_point="$(readlink -m "sdcard/mount_point_ext3")"
|
||||
|
||||
# compile_quartus_project() ####################################################
|
||||
compile_quartus_project() {
|
||||
# change working directory to quartus directory
|
||||
pushd "${quartus_dir}"
|
||||
|
||||
# delete old artifacts
|
||||
rm -rf "c5_pin_model_dump.txt" \
|
||||
"db/" \
|
||||
"hps_isw_handoff/" \
|
||||
"hps_sdram_p0_all_pins.txt" \
|
||||
"incremental_db/" \
|
||||
"output_files/" \
|
||||
"soc_system.sopcinfo" \
|
||||
"soc_system/" \
|
||||
"${quartus_project_name}.qws" \
|
||||
"${sdcard_fat32_rbf_file}"
|
||||
|
||||
qsys-generate "soc_system.qsys" --synthesis=VHDL --output-directory="soc_system/" --part="${fpga_device_part_number}"
|
||||
|
||||
# Analysis and synthesis
|
||||
quartus_map "${quartus_project_name}"
|
||||
|
||||
# Execute HPS DDR3 pin assignment TCL script
|
||||
# it is normal for the following script to report an error, but it was
|
||||
# sucessfully executed
|
||||
ddr3_pin_assignment_script="$(find . -name "hps_sdram_p0_pin_assignments.tcl")"
|
||||
quartus_sta -t "${ddr3_pin_assignment_script}" "${quartus_project_name}"
|
||||
|
||||
# Fitter
|
||||
quartus_fit "${quartus_project_name}"
|
||||
|
||||
# Assembler
|
||||
quartus_asm "${quartus_project_name}"
|
||||
|
||||
# convert .sof to .rbf in associated sdcard directory
|
||||
quartus_cpf -c "${quartus_sof_file}" "${sdcard_fat32_rbf_file}"
|
||||
|
||||
# change working directory back to script directory
|
||||
popd
|
||||
}
|
||||
|
||||
# compile_preloader() ##########################################################
|
||||
compile_preloader() {
|
||||
# delete old artifacts
|
||||
rm -rf "${preloader_dir}" \
|
||||
"${sdcard_a2_preloader_bin_file}"
|
||||
|
||||
# create directory for preloader
|
||||
mkdir -p "${preloader_dir}"
|
||||
|
||||
# change working directory to preloader directory
|
||||
pushd "${preloader_dir}"
|
||||
|
||||
# create bsp settings file
|
||||
bsp-create-settings \
|
||||
--bsp-dir "${preloader_dir}" \
|
||||
--preloader-settings-dir "${preloader_settings_dir}" \
|
||||
--settings "${preloader_settings_file}" \
|
||||
--type spl \
|
||||
--set spl.CROSS_COMPILE "arm-altera-eabi-" \
|
||||
--set spl.PRELOADER_TGZ "${preloader_source_tgz_file}" \
|
||||
--set spl.boot.BOOTROM_HANDSHAKE_CFGIO "1" \
|
||||
--set spl.boot.BOOT_FROM_NAND "0" \
|
||||
--set spl.boot.BOOT_FROM_QSPI "0" \
|
||||
--set spl.boot.BOOT_FROM_RAM "0" \
|
||||
--set spl.boot.BOOT_FROM_SDMMC "1" \
|
||||
--set spl.boot.CHECKSUM_NEXT_IMAGE "1" \
|
||||
--set spl.boot.EXE_ON_FPGA "0" \
|
||||
--set spl.boot.FAT_BOOT_PARTITION "1" \
|
||||
--set spl.boot.FAT_LOAD_PAYLOAD_NAME "$(basename "${uboot_img_file}")" \
|
||||
--set spl.boot.FAT_SUPPORT "1" \
|
||||
--set spl.boot.FPGA_DATA_BASE "0xffff0000" \
|
||||
--set spl.boot.FPGA_DATA_MAX_SIZE "0x10000" \
|
||||
--set spl.boot.FPGA_MAX_SIZE "0x10000" \
|
||||
--set spl.boot.NAND_NEXT_BOOT_IMAGE "0xc0000" \
|
||||
--set spl.boot.QSPI_NEXT_BOOT_IMAGE "0x60000" \
|
||||
--set spl.boot.RAMBOOT_PLLRESET "1" \
|
||||
--set spl.boot.SDMMC_NEXT_BOOT_IMAGE "0x40000" \
|
||||
--set spl.boot.SDRAM_SCRUBBING "0" \
|
||||
--set spl.boot.SDRAM_SCRUB_BOOT_REGION_END "0x2000000" \
|
||||
--set spl.boot.SDRAM_SCRUB_BOOT_REGION_START "0x1000000" \
|
||||
--set spl.boot.SDRAM_SCRUB_REMAIN_REGION "1" \
|
||||
--set spl.boot.STATE_REG_ENABLE "1" \
|
||||
--set spl.boot.WARMRST_SKIP_CFGIO "1" \
|
||||
--set spl.boot.WATCHDOG_ENABLE "1" \
|
||||
--set spl.debug.DEBUG_MEMORY_ADDR "0xfffffd00" \
|
||||
--set spl.debug.DEBUG_MEMORY_SIZE "0x200" \
|
||||
--set spl.debug.DEBUG_MEMORY_WRITE "0" \
|
||||
--set spl.debug.HARDWARE_DIAGNOSTIC "0" \
|
||||
--set spl.debug.SEMIHOSTING "0" \
|
||||
--set spl.debug.SKIP_SDRAM "0" \
|
||||
--set spl.performance.SERIAL_SUPPORT "1" \
|
||||
--set spl.reset_assert.DMA "0" \
|
||||
--set spl.reset_assert.GPIO0 "0" \
|
||||
--set spl.reset_assert.GPIO1 "0" \
|
||||
--set spl.reset_assert.GPIO2 "0" \
|
||||
--set spl.reset_assert.L4WD1 "0" \
|
||||
--set spl.reset_assert.OSC1TIMER1 "0" \
|
||||
--set spl.reset_assert.SDR "0" \
|
||||
--set spl.reset_assert.SPTIMER0 "0" \
|
||||
--set spl.reset_assert.SPTIMER1 "0" \
|
||||
--set spl.warm_reset_handshake.ETR "1" \
|
||||
--set spl.warm_reset_handshake.FPGA "1" \
|
||||
--set spl.warm_reset_handshake.SDRAM "0"
|
||||
|
||||
# generate bsp
|
||||
bsp-generate-files \
|
||||
--bsp-dir "${preloader_dir}" \
|
||||
--settings "${preloader_settings_file}"
|
||||
|
||||
# compile preloader
|
||||
make -j4
|
||||
|
||||
# copy artifacts to associated sdcard directory
|
||||
cp "${preloader_bin_file}" "${sdcard_a2_preloader_bin_file}"
|
||||
|
||||
# change working directory back to script directory
|
||||
popd
|
||||
}
|
||||
|
||||
# compile_uboot ################################################################
|
||||
compile_uboot() {
|
||||
# delete old artifacts
|
||||
rm -rf "${sdcard_fat32_uboot_scr_file}" \
|
||||
"${sdcard_fat32_uboot_img_file}"
|
||||
|
||||
# if uboot source tree doesn't exist, then download it
|
||||
if [ ! -d "${uboot_src_dir}" ]; then
|
||||
git clone "${uboot_src_git_repo}" "${uboot_src_dir}"
|
||||
fi
|
||||
|
||||
# change working directory to uboot source tree directory
|
||||
pushd "${uboot_src_dir}"
|
||||
|
||||
# use cross compiler instead of standard x86 version of gcc
|
||||
export CROSS_COMPILE=arm-linux-gnueabihf-
|
||||
|
||||
# clean up source tree
|
||||
make distclean
|
||||
|
||||
# checkout the following commit (tested and working):
|
||||
git checkout "${uboot_src_git_checkout_commit}"
|
||||
|
||||
# configure uboot for socfpga_cyclone5 architecture
|
||||
make "${uboot_src_make_config_file}"
|
||||
|
||||
## patch the uboot configuration file that describes environment variables
|
||||
# replace value of CONFIG_BOOTCOMMAND macro (we will always use a script for configuring everything)
|
||||
# result:
|
||||
# #define CONFIG_BOOTCOMMAND "run callscript"
|
||||
perl -pi -e 's/^(#define\s+CONFIG_BOOTCOMMAND)(.*)/$1\t"run callscript"/g' "${uboot_src_config_file}"
|
||||
|
||||
# replace value of CONFIG_EXTRA_ENV_SETTINGS macro
|
||||
# result:
|
||||
# #define CONFIG_EXTRA_ENV_SETTINGS \
|
||||
# "scriptfile=u-boot.scr" "\0" \
|
||||
# "fpgadata=0x2000000" "\0" \
|
||||
# "callscript=fatload mmc 0:1 $fpgadata $scriptfile;" \
|
||||
# "source $fpgadata" "\0"
|
||||
perl -pi -e 'BEGIN{undef $/;} s/^(#define\s+CONFIG_EXTRA_ENV_SETTINGS)(.*)#include/$1\t"scriptfile=u-boot.scr\\0" "fpgadata=0x2000000\\0" "callscript=fatload mmc 0:1 \$fpgadata \$scriptfile; source \$fpgadata\\0"\n\n#include/smg' "${uboot_src_config_file}"
|
||||
|
||||
# compile uboot
|
||||
make -j4
|
||||
|
||||
# create uboot script
|
||||
cat <<EOF > "${uboot_script_file}"
|
||||
################################################################################
|
||||
echo --- Resetting Env variables ---
|
||||
|
||||
# reset environment variables to default
|
||||
env default -a
|
||||
|
||||
echo --- Setting Env variables ---
|
||||
|
||||
# Set the kernel image
|
||||
setenv bootimage $(basename ${sdcard_fat32_zImage_file});
|
||||
|
||||
# address to which the device tree will be loaded
|
||||
setenv fdtaddr 0x00000100
|
||||
|
||||
# Set the devicetree image
|
||||
setenv fdtimage $(basename ${sdcard_fat32_dtb_file});
|
||||
|
||||
# set kernel boot arguments, then boot the kernel
|
||||
setenv mmcboot 'setenv bootargs mem=${linux_kernel_mem_arg} console=ttyS0,115200 root=\${mmcroot} rw rootwait; \
|
||||
bootz \${loadaddr} - \${fdtaddr}';
|
||||
|
||||
# load linux kernel image and device tree to memory
|
||||
setenv mmcload 'mmc rescan; \
|
||||
\${mmcloadcmd} mmc 0:\${mmcloadpart} \${loadaddr} \${bootimage}; \
|
||||
\${mmcloadcmd} mmc 0:\${mmcloadpart} \${fdtaddr} \${fdtimage}'
|
||||
|
||||
# command to be executed to read from sdcard
|
||||
setenv mmcloadcmd fatload
|
||||
|
||||
# sdcard fat32 partition number
|
||||
setenv mmcloadpart ${sdcard_partition_number_fat32}
|
||||
|
||||
# sdcard ext3 identifier
|
||||
setenv mmcroot /dev/mmcblk0p${sdcard_partition_number_ext3}
|
||||
|
||||
# standard input/output
|
||||
setenv stderr serial
|
||||
setenv stdin serial
|
||||
setenv stdout serial
|
||||
|
||||
# save environment to sdcard (not needed, but useful to avoid CRC errors on a new sdcard)
|
||||
saveenv
|
||||
|
||||
################################################################################
|
||||
echo --- Programming FPGA ---
|
||||
|
||||
# load rbf from FAT partition into memory
|
||||
fatload mmc 0:1 \${fpgadata} $(basename ${sdcard_fat32_rbf_file});
|
||||
|
||||
# program FPGA
|
||||
fpga load 0 \${fpgadata} \${filesize};
|
||||
|
||||
# enable HPS-to-FPGA, FPGA-to-HPS, LWHPS-to-FPGA bridges
|
||||
bridge enable;
|
||||
|
||||
################################################################################
|
||||
echo --- Booting Linux ---
|
||||
|
||||
# load linux kernel image and device tree to memory
|
||||
run mmcload;
|
||||
|
||||
# set kernel boot arguments, then boot the kernel
|
||||
run mmcboot;
|
||||
EOF
|
||||
|
||||
# compile uboot script to binary form
|
||||
mkimage -A arm -O linux -T script -C none -a 0 -e 0 -n "${quartus_project_name}" -d "${uboot_script_file}" "${sdcard_fat32_uboot_scr_file}"
|
||||
|
||||
# copy artifacts to associated sdcard directory
|
||||
cp "${uboot_img_file}" "${sdcard_fat32_uboot_img_file}"
|
||||
|
||||
# change working directory back to script directory
|
||||
popd
|
||||
}
|
||||
|
||||
# compile_linux() ##############################################################
|
||||
compile_linux() {
|
||||
# if linux source tree doesn't exist, then download it
|
||||
if [ ! -d "${linux_src_dir}" ]; then
|
||||
git clone "${linux_src_git_repo}" "${linux_src_dir}"
|
||||
fi
|
||||
|
||||
# change working directory to linux source tree directory
|
||||
pushd "${linux_src_dir}"
|
||||
|
||||
# compile for the ARM architecture
|
||||
export ARCH=arm
|
||||
|
||||
# use cross compiler instead of standard x86 version of gcc
|
||||
export CROSS_COMPILE=arm-linux-gnueabihf-
|
||||
|
||||
# clean up source tree
|
||||
make distclean
|
||||
|
||||
# checkout the following commit (tested and working):
|
||||
git checkout "${linux_src_git_checkout_commit}"
|
||||
|
||||
# configure kernel for socfpga architecture
|
||||
make "${linux_src_make_config_file}"
|
||||
|
||||
# compile zImage
|
||||
make -j4 zImage
|
||||
|
||||
# compile device tree
|
||||
make -j4 "$(basename "${linux_dtb_file}")"
|
||||
|
||||
# copy artifacts to associated sdcard directory
|
||||
cp "${linux_zImage_file}" "${sdcard_fat32_zImage_file}"
|
||||
cp "${linux_dtb_file}" "${sdcard_fat32_dtb_file}"
|
||||
|
||||
# change working directory back to script directory
|
||||
popd
|
||||
}
|
||||
|
||||
# create_rootfs() ##############################################################
|
||||
create_rootfs() {
|
||||
# if rootfs tarball doesn't exist, then download it
|
||||
if [ ! -f "${rootfs_src_tgz_file}" ]; then
|
||||
wget "${rootfs_src_tgz_link}" -O "${rootfs_src_tgz_file}"
|
||||
fi
|
||||
|
||||
# delete old artifacts
|
||||
sudo rm -rf "${rootfs_chroot_dir}" \
|
||||
"${sdcard_ext3_rootfs_tgz_file}"
|
||||
|
||||
# create dir to extract rootfs
|
||||
mkdir -p "${rootfs_chroot_dir}"
|
||||
|
||||
# extract ubuntu core rootfs
|
||||
pushd "${rootfs_chroot_dir}"
|
||||
sudo tar -xzpf "${rootfs_src_tgz_file}"
|
||||
popd
|
||||
|
||||
# copy chroot SYSTEM configuration script to chroot directory
|
||||
sudo cp "${rootfs_system_config_script_file}" "${rootfs_chroot_dir}"
|
||||
|
||||
# edit chroot environment's /etc/rc.local to execute the rootfs
|
||||
# configuration script
|
||||
sudo tee "${rootfs_chroot_dir}/etc/rc.local" > "/dev/null" <<EOF
|
||||
#!/bin/sh -e
|
||||
#
|
||||
# rc.local
|
||||
#
|
||||
# This script is executed at the end of each multiuser runlevel.
|
||||
# Make sure that the script will "exit 0" on success or any other
|
||||
# value on error.
|
||||
#
|
||||
# In order to enable or disable this script just change the execution
|
||||
# bits.
|
||||
#
|
||||
# By default this script does nothing.
|
||||
|
||||
/$(basename ${rootfs_system_config_script_file})
|
||||
|
||||
exit 0
|
||||
EOF
|
||||
|
||||
# copy chroot POST-INSTALL configuration script to chroot directory
|
||||
sudo cp "${rootfs_post_install_config_script_file}" "${rootfs_chroot_dir}"
|
||||
|
||||
# create archive of updated rootfs
|
||||
pushd "${rootfs_chroot_dir}"
|
||||
sudo tar -czpf "${sdcard_ext3_rootfs_tgz_file}" .
|
||||
popd
|
||||
}
|
||||
|
||||
# partition_sdcard() ###########################################################
|
||||
partition_sdcard() {
|
||||
# manually partitioning the sdcard
|
||||
# sudo fdisk /dev/sdx
|
||||
# use the following commands
|
||||
# n p 3 <default> 4095 t a2 (2048 is default first sector)
|
||||
# n p 1 <default> +32M t 1 b (4096 is default first sector)
|
||||
# n p 2 <default> +512M t 2 83 (69632 is default first sector)
|
||||
# w
|
||||
# result
|
||||
# Device Boot Start End Sectors Size Id Type
|
||||
# /dev/sdb1 4096 69631 65536 32M b W95 FAT32
|
||||
# /dev/sdb2 69632 1118207 1048576 512M 83 Linux
|
||||
# /dev/sdb3 2048 4095 2048 1M a2 unknown
|
||||
# note that you can choose any size for the FAT32 and Linux partitions,
|
||||
# but the a2 partition must be 1M.
|
||||
|
||||
# automatically partitioning the sdcard
|
||||
# wipe partition table
|
||||
sudo dd if="/dev/zero" of="${sdcard_dev}" bs=512 count=1
|
||||
|
||||
# create partitions
|
||||
# no need to specify the partition number for the first invocation of
|
||||
# the "t" command in fdisk, because there is only 1 partition at this
|
||||
# point
|
||||
echo -e "n\np\n3\n\n4095\nt\na2\nn\np\n1\n\n+${sdcard_partition_size_fat32}\nt\n1\nb\nn\np\n2\n\n+${sdcard_partition_size_linux}\nt\n2\n83\nw\nq\n" | sudo fdisk "${sdcard_dev}"
|
||||
|
||||
# create filesystems
|
||||
sudo mkfs.vfat "${sdcard_dev_fat32}"
|
||||
sudo mkfs.ext3 -F "${sdcard_dev_ext3}"
|
||||
}
|
||||
|
||||
# write_sdcard() ###############################################################
|
||||
write_sdcard() {
|
||||
# create mount point for sdcard
|
||||
mkdir -p "${sdcard_dev_fat32_mount_point}"
|
||||
mkdir -p "${sdcard_dev_ext3_mount_point}"
|
||||
|
||||
# mount sdcard partitions
|
||||
sudo mount "${sdcard_dev_fat32}" "${sdcard_dev_fat32_mount_point}"
|
||||
sudo mount "${sdcard_dev_ext3}" "${sdcard_dev_ext3_mount_point}"
|
||||
|
||||
# preloader
|
||||
sudo dd if="${sdcard_a2_preloader_bin_file}" of="${sdcard_dev_a2}" bs=64K seek=0
|
||||
|
||||
# fpga .rbf, uboot .img, uboot .scr, linux zImage, linux .dtb
|
||||
sudo cp "${sdcard_fat32_dir}"/* "${sdcard_dev_fat32_mount_point}"
|
||||
|
||||
# linux rootfs
|
||||
pushd "${sdcard_dev_ext3_mount_point}"
|
||||
sudo tar -xzf "${sdcard_ext3_rootfs_tgz_file}"
|
||||
popd
|
||||
|
||||
# flush write buffers to target
|
||||
sudo sync
|
||||
|
||||
# unmount sdcard partitions
|
||||
sudo umount "${sdcard_dev_fat32_mount_point}"
|
||||
sudo umount "${sdcard_dev_ext3_mount_point}"
|
||||
|
||||
# delete mount points for sdcard
|
||||
rm -rf "${sdcard_dev_fat32_mount_point}"
|
||||
rm -rf "${sdcard_dev_ext3_mount_point}"
|
||||
}
|
||||
|
||||
# Script execution #############################################################
|
||||
|
||||
# Report script line number on any error (non-zero exit code).
|
||||
trap 'echo "Error on line ${LINENO}" 1>&2' ERR
|
||||
set -e
|
||||
|
||||
# Create sdcard output directories
|
||||
mkdir -p "${sdcard_a2_dir}"
|
||||
mkdir -p "${sdcard_fat32_dir}"
|
||||
|
||||
compile_quartus_project
|
||||
compile_preloader
|
||||
compile_uboot
|
||||
compile_linux
|
||||
create_rootfs
|
||||
|
||||
# Write sdcard if it exists
|
||||
if [ -z "${sdcard_dev}" ]; then
|
||||
echo "sdcard argument not provided => no sdcard written."
|
||||
|
||||
elif [ -b "${sdcard_dev}" ]; then
|
||||
partition_sdcard
|
||||
write_sdcard
|
||||
fi
|
||||
|
||||
# Make sure MSEL = 000000
|
@ -0,0 +1,347 @@
|
||||
-- #############################################################################
|
||||
-- DE0_Nano_SoC_PrSoC_extn_board_top_level.vhd
|
||||
--
|
||||
-- BOARD : PrSoC extension board for DE0-Nano-SoC
|
||||
-- Author : Florian Depraz based on Sahand Kashani-Akhavan work
|
||||
-- Revision : 1.1
|
||||
-- Creation date : 06/02/2016
|
||||
--
|
||||
-- Syntax Rule : GROUP_NAME_N[bit]
|
||||
--
|
||||
-- GROUP : specify a particular interface (ex: SDR_)
|
||||
-- NAME : signal name (ex: CONFIG, D, ...)
|
||||
-- bit : signal index
|
||||
-- _N : to specify an active-low signal
|
||||
-- #############################################################################
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
|
||||
entity DE0_Nano_SoC_PrSoC_extn_board_top_level is
|
||||
port(
|
||||
-------------------------------
|
||||
-- Comment ALL unused ports. --
|
||||
-------------------------------
|
||||
|
||||
-- CLOCK
|
||||
FPGA_CLK1_50 : in std_logic;
|
||||
-- FPGA_CLK2_50 : in std_logic;
|
||||
-- FPGA_CLK3_50 : in std_logic;
|
||||
|
||||
-- KEY on DE0 Nano SoC
|
||||
KEY_N : in std_logic_vector(1 downto 0);
|
||||
|
||||
-- LEDs on DE0 Nano SoC
|
||||
-- LED : out std_logic_vector(7 downto 0);
|
||||
|
||||
-- SWITCHES on DE0 Nano SoC
|
||||
-- SW : in std_logic_vector(3 downto 0);
|
||||
|
||||
-- Servomotors pwm
|
||||
SERVO_0 : out std_logic;
|
||||
SERVO_1 : out std_logic;
|
||||
|
||||
-- ADC Joysticks
|
||||
J0_SPI_CS_n : out std_logic;
|
||||
J0_SPI_MOSI : out std_logic;
|
||||
J0_SPI_MISO : in std_logic;
|
||||
J0_SPI_CLK : out std_logic;
|
||||
|
||||
-- Lepton
|
||||
CAM_TH_SPI_CS_N : out std_logic;
|
||||
CAM_TH_MISO : in std_logic;
|
||||
CAM_TH_MOSI : out std_logic;
|
||||
CAM_TH_CLK : out std_logic;
|
||||
|
||||
-- PCA9637
|
||||
-- PIO_SCL : inout std_logic;
|
||||
-- PIO_SDA : inout std_logic;
|
||||
-- PIO_INT_N : in std_logic;
|
||||
-- RESET_N : out std_logic;
|
||||
|
||||
-- OV7670
|
||||
-- CAM_D : in std_logic_vector(9 downto 0);
|
||||
-- CAM_PIX_CLK : in std_logic;
|
||||
-- CAM_LV : in std_logic;
|
||||
-- CAM_FV : in std_logic;
|
||||
-- CAM_SYS_CLK : out std_logic;
|
||||
|
||||
-- VGA and LCD shared signals
|
||||
VIDEO_CLK : out std_logic;
|
||||
VIDEO_VSYNC : out std_logic;
|
||||
VIDEO_HSYNC : out std_logic;
|
||||
VIDEO_B : out std_logic_vector(7 downto 0);
|
||||
VIDEO_G : out std_logic_vector(7 downto 0);
|
||||
VIDEO_R : out std_logic_vector(7 downto 0);
|
||||
|
||||
-- LCD Specific signals
|
||||
LCD_DE : out std_logic;
|
||||
-- LCD_PIN_DAV_N : ? ?? std_logic;
|
||||
LCD_DISPLAY_EN : out std_logic;
|
||||
-- SPI_MISO : in std_logic;
|
||||
-- SPI_ENA_N : out std_logic;
|
||||
-- SPI_CLK : out std_logic;
|
||||
-- SPI_MOSI : out std_logic;
|
||||
-- SPI_DAT : inout std_logic;
|
||||
|
||||
-- I2C TOUCH SCREEN
|
||||
-- TS_SCL : inout std_logic;
|
||||
-- TS_SDA : inout std_logic;
|
||||
|
||||
-- BLUETOOTH (BLE)
|
||||
-- BLT_TXD : in std_logic;
|
||||
-- BLT_RXD : out std_logic;
|
||||
|
||||
-- I2C For VGA, PAL and OV7670 cameras
|
||||
-- CAM_PAL_VGA_SDA : inout std_logic;
|
||||
-- CAM_PAL_VGA_SCL : inout std_logic;
|
||||
|
||||
-- ONE WIRE
|
||||
-- BOARD_ID : inout std_logic;
|
||||
|
||||
-- PAL Camera
|
||||
-- PAL_VD_VD : in std_logic_vector(7 downto 0);
|
||||
-- PAL_VD_VSO : in std_logic;
|
||||
-- PAL_VD_HSO : in std_logic;
|
||||
-- PAL_VD_CLKO : in std_logic;
|
||||
-- PAL_PWDN : out std_logic;
|
||||
|
||||
-- WIFI
|
||||
-- FROM_ESP_TXD : in std_logic;
|
||||
-- TO_ESP_RXD : out std_logic;
|
||||
|
||||
-- LED RGB
|
||||
-- LED_BGR : out std_logic;
|
||||
|
||||
-- HPS
|
||||
HPS_CONV_USB_N : inout std_logic;
|
||||
HPS_DDR3_ADDR : out std_logic_vector(14 downto 0);
|
||||
HPS_DDR3_BA : out std_logic_vector(2 downto 0);
|
||||
HPS_DDR3_CAS_N : out std_logic;
|
||||
HPS_DDR3_CK_N : out std_logic;
|
||||
HPS_DDR3_CK_P : out std_logic;
|
||||
HPS_DDR3_CKE : out std_logic;
|
||||
HPS_DDR3_CS_N : out std_logic;
|
||||
HPS_DDR3_DM : out std_logic_vector(3 downto 0);
|
||||
HPS_DDR3_DQ : inout std_logic_vector(31 downto 0);
|
||||
HPS_DDR3_DQS_N : inout std_logic_vector(3 downto 0);
|
||||
HPS_DDR3_DQS_P : inout std_logic_vector(3 downto 0);
|
||||
HPS_DDR3_ODT : out std_logic;
|
||||
HPS_DDR3_RAS_N : out std_logic;
|
||||
HPS_DDR3_RESET_N : out std_logic;
|
||||
HPS_DDR3_RZQ : in std_logic;
|
||||
HPS_DDR3_WE_N : out std_logic;
|
||||
HPS_ENET_GTX_CLK : out std_logic;
|
||||
HPS_ENET_INT_N : inout std_logic;
|
||||
HPS_ENET_MDC : out std_logic;
|
||||
HPS_ENET_MDIO : inout std_logic;
|
||||
HPS_ENET_RX_CLK : in std_logic;
|
||||
HPS_ENET_RX_DATA : in std_logic_vector(3 downto 0);
|
||||
HPS_ENET_RX_DV : in std_logic;
|
||||
HPS_ENET_TX_DATA : out std_logic_vector(3 downto 0);
|
||||
HPS_ENET_TX_EN : out std_logic;
|
||||
HPS_GSENSOR_INT : inout std_logic;
|
||||
HPS_I2C0_SCLK : inout std_logic;
|
||||
HPS_I2C0_SDAT : inout std_logic;
|
||||
HPS_I2C1_SCLK : inout std_logic;
|
||||
HPS_I2C1_SDAT : inout std_logic;
|
||||
HPS_KEY_N : inout std_logic;
|
||||
HPS_LED : inout std_logic;
|
||||
HPS_LTC_GPIO : inout std_logic;
|
||||
HPS_SD_CLK : out std_logic;
|
||||
HPS_SD_CMD : inout std_logic;
|
||||
HPS_SD_DATA : inout std_logic_vector(3 downto 0);
|
||||
HPS_SPIM_CLK : out std_logic;
|
||||
HPS_SPIM_MISO : in std_logic;
|
||||
HPS_SPIM_MOSI : out std_logic;
|
||||
HPS_SPIM_SS : inout std_logic;
|
||||
HPS_UART_RX : in std_logic;
|
||||
HPS_UART_TX : out std_logic;
|
||||
HPS_USB_CLKOUT : in std_logic;
|
||||
HPS_USB_DATA : inout std_logic_vector(7 downto 0);
|
||||
HPS_USB_DIR : in std_logic;
|
||||
HPS_USB_NXT : in std_logic;
|
||||
HPS_USB_STP : out std_logic
|
||||
);
|
||||
end entity DE0_Nano_SoC_PrSoC_extn_board_top_level;
|
||||
|
||||
architecture rtl of DE0_Nano_SoC_PrSoC_extn_board_top_level is
|
||||
component soc_system is
|
||||
port(
|
||||
clk_clk : in std_logic := 'X';
|
||||
reset_reset_n : in std_logic := 'X';
|
||||
hps_0_ddr_mem_a : out std_logic_vector(14 downto 0);
|
||||
hps_0_ddr_mem_ba : out std_logic_vector(2 downto 0);
|
||||
hps_0_ddr_mem_ck : out std_logic;
|
||||
hps_0_ddr_mem_ck_n : out std_logic;
|
||||
hps_0_ddr_mem_cke : out std_logic;
|
||||
hps_0_ddr_mem_cs_n : out std_logic;
|
||||
hps_0_ddr_mem_ras_n : out std_logic;
|
||||
hps_0_ddr_mem_cas_n : out std_logic;
|
||||
hps_0_ddr_mem_we_n : out std_logic;
|
||||
hps_0_ddr_mem_reset_n : out std_logic;
|
||||
hps_0_ddr_mem_dq : inout std_logic_vector(31 downto 0) := (others => 'X');
|
||||
hps_0_ddr_mem_dqs : inout std_logic_vector(3 downto 0) := (others => 'X');
|
||||
hps_0_ddr_mem_dqs_n : inout std_logic_vector(3 downto 0) := (others => 'X');
|
||||
hps_0_ddr_mem_odt : out std_logic;
|
||||
hps_0_ddr_mem_dm : out std_logic_vector(3 downto 0);
|
||||
hps_0_ddr_oct_rzqin : in std_logic := 'X';
|
||||
hps_0_io_hps_io_emac1_inst_TX_CLK : out std_logic;
|
||||
hps_0_io_hps_io_emac1_inst_TX_CTL : out std_logic;
|
||||
hps_0_io_hps_io_emac1_inst_TXD0 : out std_logic;
|
||||
hps_0_io_hps_io_emac1_inst_TXD1 : out std_logic;
|
||||
hps_0_io_hps_io_emac1_inst_TXD2 : out std_logic;
|
||||
hps_0_io_hps_io_emac1_inst_TXD3 : out std_logic;
|
||||
hps_0_io_hps_io_emac1_inst_RX_CLK : in std_logic := 'X';
|
||||
hps_0_io_hps_io_emac1_inst_RX_CTL : in std_logic := 'X';
|
||||
hps_0_io_hps_io_emac1_inst_RXD0 : in std_logic := 'X';
|
||||
hps_0_io_hps_io_emac1_inst_RXD1 : in std_logic := 'X';
|
||||
hps_0_io_hps_io_emac1_inst_RXD2 : in std_logic := 'X';
|
||||
hps_0_io_hps_io_emac1_inst_RXD3 : in std_logic := 'X';
|
||||
hps_0_io_hps_io_emac1_inst_MDIO : inout std_logic := 'X';
|
||||
hps_0_io_hps_io_emac1_inst_MDC : out std_logic;
|
||||
hps_0_io_hps_io_sdio_inst_CLK : out std_logic;
|
||||
hps_0_io_hps_io_sdio_inst_CMD : inout std_logic := 'X';
|
||||
hps_0_io_hps_io_sdio_inst_D0 : inout std_logic := 'X';
|
||||
hps_0_io_hps_io_sdio_inst_D1 : inout std_logic := 'X';
|
||||
hps_0_io_hps_io_sdio_inst_D2 : inout std_logic := 'X';
|
||||
hps_0_io_hps_io_sdio_inst_D3 : inout std_logic := 'X';
|
||||
hps_0_io_hps_io_usb1_inst_CLK : in std_logic := 'X';
|
||||
hps_0_io_hps_io_usb1_inst_STP : out std_logic;
|
||||
hps_0_io_hps_io_usb1_inst_DIR : in std_logic := 'X';
|
||||
hps_0_io_hps_io_usb1_inst_NXT : in std_logic := 'X';
|
||||
hps_0_io_hps_io_usb1_inst_D0 : inout std_logic := 'X';
|
||||
hps_0_io_hps_io_usb1_inst_D1 : inout std_logic := 'X';
|
||||
hps_0_io_hps_io_usb1_inst_D2 : inout std_logic := 'X';
|
||||
hps_0_io_hps_io_usb1_inst_D3 : inout std_logic := 'X';
|
||||
hps_0_io_hps_io_usb1_inst_D4 : inout std_logic := 'X';
|
||||
hps_0_io_hps_io_usb1_inst_D5 : inout std_logic := 'X';
|
||||
hps_0_io_hps_io_usb1_inst_D6 : inout std_logic := 'X';
|
||||
hps_0_io_hps_io_usb1_inst_D7 : inout std_logic := 'X';
|
||||
hps_0_io_hps_io_spim1_inst_CLK : out std_logic;
|
||||
hps_0_io_hps_io_spim1_inst_MOSI : out std_logic;
|
||||
hps_0_io_hps_io_spim1_inst_MISO : in std_logic := 'X';
|
||||
hps_0_io_hps_io_spim1_inst_SS0 : out std_logic;
|
||||
hps_0_io_hps_io_uart0_inst_RX : in std_logic := 'X';
|
||||
hps_0_io_hps_io_uart0_inst_TX : out std_logic;
|
||||
hps_0_io_hps_io_i2c0_inst_SDA : inout std_logic := 'X';
|
||||
hps_0_io_hps_io_i2c0_inst_SCL : inout std_logic := 'X';
|
||||
hps_0_io_hps_io_i2c1_inst_SDA : inout std_logic := 'X';
|
||||
hps_0_io_hps_io_i2c1_inst_SCL : inout std_logic := 'X';
|
||||
hps_0_io_hps_io_gpio_inst_GPIO09 : inout std_logic := 'X';
|
||||
hps_0_io_hps_io_gpio_inst_GPIO35 : inout std_logic := 'X';
|
||||
hps_0_io_hps_io_gpio_inst_GPIO40 : inout std_logic := 'X';
|
||||
hps_0_io_hps_io_gpio_inst_GPIO53 : inout std_logic := 'X';
|
||||
hps_0_io_hps_io_gpio_inst_GPIO54 : inout std_logic := 'X';
|
||||
hps_0_io_hps_io_gpio_inst_GPIO61 : inout std_logic := 'X';
|
||||
pwm_0_conduit_end_pwm : out std_logic;
|
||||
pwm_1_conduit_end_pwm : out std_logic;
|
||||
mcp3204_0_conduit_end_cs_n : out std_logic;
|
||||
mcp3204_0_conduit_end_mosi : out std_logic;
|
||||
mcp3204_0_conduit_end_miso : in std_logic := 'X';
|
||||
mcp3204_0_conduit_end_sclk : out std_logic;
|
||||
lepton_0_spi_cs_n : out std_logic;
|
||||
lepton_0_spi_mosi : out std_logic;
|
||||
lepton_0_spi_miso : in std_logic := 'X';
|
||||
lepton_0_spi_sclk : out std_logic;
|
||||
pixclk_clk : out std_logic;
|
||||
vga_hsync : out std_logic;
|
||||
vga_vsync : out std_logic;
|
||||
vga_r : out std_logic_vector(7 downto 0);
|
||||
vga_g : out std_logic_vector(7 downto 0);
|
||||
vga_b : out std_logic_vector(7 downto 0);
|
||||
vga_de : out std_logic
|
||||
);
|
||||
end component soc_system;
|
||||
|
||||
begin
|
||||
soc_system_inst : component soc_system
|
||||
port map(
|
||||
clk_clk => FPGA_CLK1_50,
|
||||
reset_reset_n => KEY_N(0),
|
||||
hps_0_ddr_mem_a => HPS_DDR3_ADDR,
|
||||
hps_0_ddr_mem_ba => HPS_DDR3_BA,
|
||||
hps_0_ddr_mem_ck => HPS_DDR3_CK_P,
|
||||
hps_0_ddr_mem_ck_n => HPS_DDR3_CK_N,
|
||||
hps_0_ddr_mem_cke => HPS_DDR3_CKE,
|
||||
hps_0_ddr_mem_cs_n => HPS_DDR3_CS_N,
|
||||
hps_0_ddr_mem_ras_n => HPS_DDR3_RAS_N,
|
||||
hps_0_ddr_mem_cas_n => HPS_DDR3_CAS_N,
|
||||
hps_0_ddr_mem_we_n => HPS_DDR3_WE_N,
|
||||
hps_0_ddr_mem_reset_n => HPS_DDR3_RESET_N,
|
||||
hps_0_ddr_mem_dq => HPS_DDR3_DQ,
|
||||
hps_0_ddr_mem_dqs => HPS_DDR3_DQS_P,
|
||||
hps_0_ddr_mem_dqs_n => HPS_DDR3_DQS_N,
|
||||
hps_0_ddr_mem_odt => HPS_DDR3_ODT,
|
||||
hps_0_ddr_mem_dm => HPS_DDR3_DM,
|
||||
hps_0_ddr_oct_rzqin => HPS_DDR3_RZQ,
|
||||
hps_0_io_hps_io_emac1_inst_TX_CLK => HPS_ENET_GTX_CLK,
|
||||
hps_0_io_hps_io_emac1_inst_TX_CTL => HPS_ENET_TX_EN,
|
||||
hps_0_io_hps_io_emac1_inst_TXD0 => HPS_ENET_TX_DATA(0),
|
||||
hps_0_io_hps_io_emac1_inst_TXD1 => HPS_ENET_TX_DATA(1),
|
||||
hps_0_io_hps_io_emac1_inst_TXD2 => HPS_ENET_TX_DATA(2),
|
||||
hps_0_io_hps_io_emac1_inst_TXD3 => HPS_ENET_TX_DATA(3),
|
||||
hps_0_io_hps_io_emac1_inst_RX_CLK => HPS_ENET_RX_CLK,
|
||||
hps_0_io_hps_io_emac1_inst_RX_CTL => HPS_ENET_RX_DV,
|
||||
hps_0_io_hps_io_emac1_inst_RXD0 => HPS_ENET_RX_DATA(0),
|
||||
hps_0_io_hps_io_emac1_inst_RXD1 => HPS_ENET_RX_DATA(1),
|
||||
hps_0_io_hps_io_emac1_inst_RXD2 => HPS_ENET_RX_DATA(2),
|
||||
hps_0_io_hps_io_emac1_inst_RXD3 => HPS_ENET_RX_DATA(3),
|
||||
hps_0_io_hps_io_emac1_inst_MDIO => HPS_ENET_MDIO,
|
||||
hps_0_io_hps_io_emac1_inst_MDC => HPS_ENET_MDC,
|
||||
hps_0_io_hps_io_sdio_inst_CLK => HPS_SD_CLK,
|
||||
hps_0_io_hps_io_sdio_inst_CMD => HPS_SD_CMD,
|
||||
hps_0_io_hps_io_sdio_inst_D0 => HPS_SD_DATA(0),
|
||||
hps_0_io_hps_io_sdio_inst_D1 => HPS_SD_DATA(1),
|
||||
hps_0_io_hps_io_sdio_inst_D2 => HPS_SD_DATA(2),
|
||||
hps_0_io_hps_io_sdio_inst_D3 => HPS_SD_DATA(3),
|
||||
hps_0_io_hps_io_usb1_inst_CLK => HPS_USB_CLKOUT,
|
||||
hps_0_io_hps_io_usb1_inst_STP => HPS_USB_STP,
|
||||
hps_0_io_hps_io_usb1_inst_DIR => HPS_USB_DIR,
|
||||
hps_0_io_hps_io_usb1_inst_NXT => HPS_USB_NXT,
|
||||
hps_0_io_hps_io_usb1_inst_D0 => HPS_USB_DATA(0),
|
||||
hps_0_io_hps_io_usb1_inst_D1 => HPS_USB_DATA(1),
|
||||
hps_0_io_hps_io_usb1_inst_D2 => HPS_USB_DATA(2),
|
||||
hps_0_io_hps_io_usb1_inst_D3 => HPS_USB_DATA(3),
|
||||
hps_0_io_hps_io_usb1_inst_D4 => HPS_USB_DATA(4),
|
||||
hps_0_io_hps_io_usb1_inst_D5 => HPS_USB_DATA(5),
|
||||
hps_0_io_hps_io_usb1_inst_D6 => HPS_USB_DATA(6),
|
||||
hps_0_io_hps_io_usb1_inst_D7 => HPS_USB_DATA(7),
|
||||
hps_0_io_hps_io_spim1_inst_CLK => HPS_SPIM_CLK,
|
||||
hps_0_io_hps_io_spim1_inst_MOSI => HPS_SPIM_MOSI,
|
||||
hps_0_io_hps_io_spim1_inst_MISO => HPS_SPIM_MISO,
|
||||
hps_0_io_hps_io_spim1_inst_SS0 => HPS_SPIM_SS,
|
||||
hps_0_io_hps_io_uart0_inst_RX => HPS_UART_RX,
|
||||
hps_0_io_hps_io_uart0_inst_TX => HPS_UART_TX,
|
||||
hps_0_io_hps_io_i2c0_inst_SDA => HPS_I2C0_SDAT,
|
||||
hps_0_io_hps_io_i2c0_inst_SCL => HPS_I2C0_SCLK,
|
||||
hps_0_io_hps_io_i2c1_inst_SDA => HPS_I2C1_SDAT,
|
||||
hps_0_io_hps_io_i2c1_inst_SCL => HPS_I2C1_SCLK,
|
||||
hps_0_io_hps_io_gpio_inst_GPIO09 => HPS_CONV_USB_N,
|
||||
hps_0_io_hps_io_gpio_inst_GPIO35 => HPS_ENET_INT_N,
|
||||
hps_0_io_hps_io_gpio_inst_GPIO40 => HPS_LTC_GPIO,
|
||||
hps_0_io_hps_io_gpio_inst_GPIO53 => HPS_LED,
|
||||
hps_0_io_hps_io_gpio_inst_GPIO54 => HPS_KEY_N,
|
||||
hps_0_io_hps_io_gpio_inst_GPIO61 => HPS_GSENSOR_INT,
|
||||
pwm_0_conduit_end_pwm => SERVO_0,
|
||||
pwm_1_conduit_end_pwm => SERVO_1,
|
||||
mcp3204_0_conduit_end_cs_n => J0_SPI_CS_n,
|
||||
mcp3204_0_conduit_end_mosi => J0_SPI_MOSI,
|
||||
mcp3204_0_conduit_end_miso => J0_SPI_MISO,
|
||||
mcp3204_0_conduit_end_sclk => J0_SPI_CLK,
|
||||
lepton_0_spi_cs_n => CAM_TH_SPI_CS_N,
|
||||
lepton_0_spi_mosi => CAM_TH_MOSI,
|
||||
lepton_0_spi_miso => CAM_TH_MISO,
|
||||
lepton_0_spi_sclk => CAM_TH_CLK,
|
||||
pixclk_clk => VIDEO_CLK,
|
||||
vga_hsync => VIDEO_HSYNC,
|
||||
vga_vsync => VIDEO_VSYNC,
|
||||
vga_r => VIDEO_R,
|
||||
vga_g => VIDEO_G,
|
||||
vga_b => VIDEO_B,
|
||||
vga_de => LCD_DE
|
||||
);
|
||||
|
||||
LCD_DISPLAY_EN <= '1';
|
||||
|
||||
end;
|
@ -0,0 +1,214 @@
|
||||
-- megafunction wizard: %FIFO%
|
||||
-- GENERATION: STANDARD
|
||||
-- VERSION: WM1.0
|
||||
-- MODULE: dcfifo_mixed_widths
|
||||
|
||||
-- ============================================================
|
||||
-- File Name: dc_video_fifo.vhd
|
||||
-- Megafunction Name(s):
|
||||
-- dcfifo_mixed_widths
|
||||
--
|
||||
-- Simulation Library Files(s):
|
||||
-- altera_mf
|
||||
-- ============================================================
|
||||
-- ************************************************************
|
||||
-- THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE!
|
||||
--
|
||||
-- 15.1.0 Build 185 10/21/2015 SJ Lite Edition
|
||||
-- ************************************************************
|
||||
|
||||
|
||||
--Copyright (C) 1991-2015 Altera Corporation. All rights reserved.
|
||||
--Your use of Altera Corporation's design tools, logic functions
|
||||
--and other software and tools, and its AMPP partner logic
|
||||
--functions, and any output files from any of the foregoing
|
||||
--(including device programming or simulation files), and any
|
||||
--associated documentation or information are expressly subject
|
||||
--to the terms and conditions of the Altera Program License
|
||||
--Subscription Agreement, the Altera Quartus Prime License Agreement,
|
||||
--the Altera MegaCore Function License Agreement, or other
|
||||
--applicable license agreement, including, without limitation,
|
||||
--that your use is for the sole purpose of programming logic
|
||||
--devices manufactured by Altera and sold by Altera or its
|
||||
--authorized distributors. Please refer to the applicable
|
||||
--agreement for further details.
|
||||
|
||||
|
||||
LIBRARY ieee;
|
||||
USE ieee.std_logic_1164.all;
|
||||
|
||||
LIBRARY altera_mf;
|
||||
USE altera_mf.all;
|
||||
|
||||
ENTITY dc_video_fifo IS
|
||||
PORT
|
||||
(
|
||||
aclr : IN STD_LOGIC := '0';
|
||||
data : IN STD_LOGIC_VECTOR (95 DOWNTO 0);
|
||||
rdclk : IN STD_LOGIC ;
|
||||
rdreq : IN STD_LOGIC ;
|
||||
wrclk : IN STD_LOGIC ;
|
||||
wrreq : IN STD_LOGIC ;
|
||||
q : OUT STD_LOGIC_VECTOR (23 DOWNTO 0);
|
||||
rdempty : OUT STD_LOGIC ;
|
||||
wrusedw : OUT STD_LOGIC_VECTOR (8 DOWNTO 0)
|
||||
);
|
||||
END dc_video_fifo;
|
||||
|
||||
|
||||
ARCHITECTURE SYN OF dc_video_fifo IS
|
||||
|
||||
SIGNAL sub_wire0 : STD_LOGIC_VECTOR (23 DOWNTO 0);
|
||||
SIGNAL sub_wire1 : STD_LOGIC ;
|
||||
SIGNAL sub_wire2 : STD_LOGIC_VECTOR (8 DOWNTO 0);
|
||||
|
||||
|
||||
|
||||
COMPONENT dcfifo_mixed_widths
|
||||
GENERIC (
|
||||
add_usedw_msb_bit : STRING;
|
||||
intended_device_family : STRING;
|
||||
lpm_numwords : NATURAL;
|
||||
lpm_showahead : STRING;
|
||||
lpm_type : STRING;
|
||||
lpm_width : NATURAL;
|
||||
lpm_widthu : NATURAL;
|
||||
lpm_widthu_r : NATURAL;
|
||||
lpm_width_r : NATURAL;
|
||||
overflow_checking : STRING;
|
||||
rdsync_delaypipe : NATURAL;
|
||||
read_aclr_synch : STRING;
|
||||
underflow_checking : STRING;
|
||||
use_eab : STRING;
|
||||
write_aclr_synch : STRING;
|
||||
wrsync_delaypipe : NATURAL
|
||||
);
|
||||
PORT (
|
||||
aclr : IN STD_LOGIC ;
|
||||
data : IN STD_LOGIC_VECTOR (95 DOWNTO 0);
|
||||
rdclk : IN STD_LOGIC ;
|
||||
rdreq : IN STD_LOGIC ;
|
||||
wrclk : IN STD_LOGIC ;
|
||||
wrreq : IN STD_LOGIC ;
|
||||
q : OUT STD_LOGIC_VECTOR (23 DOWNTO 0);
|
||||
rdempty : OUT STD_LOGIC ;
|
||||
wrusedw : OUT STD_LOGIC_VECTOR (8 DOWNTO 0)
|
||||
);
|
||||
END COMPONENT;
|
||||
|
||||
BEGIN
|
||||
q <= sub_wire0(23 DOWNTO 0);
|
||||
rdempty <= sub_wire1;
|
||||
wrusedw <= sub_wire2(8 DOWNTO 0);
|
||||
|
||||
dcfifo_mixed_widths_component : dcfifo_mixed_widths
|
||||
GENERIC MAP (
|
||||
add_usedw_msb_bit => "ON",
|
||||
intended_device_family => "Cyclone V",
|
||||
lpm_numwords => 256,
|
||||
lpm_showahead => "ON",
|
||||
lpm_type => "dcfifo_mixed_widths",
|
||||
lpm_width => 96,
|
||||
lpm_widthu => 9,
|
||||
lpm_widthu_r => 11,
|
||||
lpm_width_r => 24,
|
||||
overflow_checking => "ON",
|
||||
rdsync_delaypipe => 5,
|
||||
read_aclr_synch => "OFF",
|
||||
underflow_checking => "ON",
|
||||
use_eab => "ON",
|
||||
write_aclr_synch => "OFF",
|
||||
wrsync_delaypipe => 5
|
||||
)
|
||||
PORT MAP (
|
||||
aclr => aclr,
|
||||
data => data,
|
||||
rdclk => rdclk,
|
||||
rdreq => rdreq,
|
||||
wrclk => wrclk,
|
||||
wrreq => wrreq,
|
||||
q => sub_wire0,
|
||||
rdempty => sub_wire1,
|
||||
wrusedw => sub_wire2
|
||||
);
|
||||
|
||||
|
||||
|
||||
END SYN;
|
||||
|
||||
-- ============================================================
|
||||
-- CNX file retrieval info
|
||||
-- ============================================================
|
||||
-- Retrieval info: PRIVATE: AlmostEmpty NUMERIC "0"
|
||||
-- Retrieval info: PRIVATE: AlmostEmptyThr NUMERIC "-1"
|
||||
-- Retrieval info: PRIVATE: AlmostFull NUMERIC "0"
|
||||
-- Retrieval info: PRIVATE: AlmostFullThr NUMERIC "-1"
|
||||
-- Retrieval info: PRIVATE: CLOCKS_ARE_SYNCHRONIZED NUMERIC "0"
|
||||
-- Retrieval info: PRIVATE: Clock NUMERIC "4"
|
||||
-- Retrieval info: PRIVATE: Depth NUMERIC "256"
|
||||
-- Retrieval info: PRIVATE: Empty NUMERIC "1"
|
||||
-- Retrieval info: PRIVATE: Full NUMERIC "1"
|
||||
-- Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "Cyclone V"
|
||||
-- Retrieval info: PRIVATE: LE_BasedFIFO NUMERIC "0"
|
||||
-- Retrieval info: PRIVATE: LegacyRREQ NUMERIC "0"
|
||||
-- Retrieval info: PRIVATE: MAX_DEPTH_BY_9 NUMERIC "0"
|
||||
-- Retrieval info: PRIVATE: OVERFLOW_CHECKING NUMERIC "0"
|
||||
-- Retrieval info: PRIVATE: Optimize NUMERIC "2"
|
||||
-- Retrieval info: PRIVATE: RAM_BLOCK_TYPE NUMERIC "0"
|
||||
-- Retrieval info: PRIVATE: SYNTH_WRAPPER_GEN_POSTFIX STRING "0"
|
||||
-- Retrieval info: PRIVATE: UNDERFLOW_CHECKING NUMERIC "0"
|
||||
-- Retrieval info: PRIVATE: UsedW NUMERIC "1"
|
||||
-- Retrieval info: PRIVATE: Width NUMERIC "96"
|
||||
-- Retrieval info: PRIVATE: dc_aclr NUMERIC "1"
|
||||
-- Retrieval info: PRIVATE: diff_widths NUMERIC "1"
|
||||
-- Retrieval info: PRIVATE: msb_usedw NUMERIC "1"
|
||||
-- Retrieval info: PRIVATE: output_width NUMERIC "24"
|
||||
-- Retrieval info: PRIVATE: rsEmpty NUMERIC "1"
|
||||
-- Retrieval info: PRIVATE: rsFull NUMERIC "0"
|
||||
-- Retrieval info: PRIVATE: rsUsedW NUMERIC "0"
|
||||
-- Retrieval info: PRIVATE: sc_aclr NUMERIC "0"
|
||||
-- Retrieval info: PRIVATE: sc_sclr NUMERIC "0"
|
||||
-- Retrieval info: PRIVATE: wsEmpty NUMERIC "0"
|
||||
-- Retrieval info: PRIVATE: wsFull NUMERIC "0"
|
||||
-- Retrieval info: PRIVATE: wsUsedW NUMERIC "1"
|
||||
-- Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all
|
||||
-- Retrieval info: CONSTANT: ADD_USEDW_MSB_BIT STRING "ON"
|
||||
-- Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone V"
|
||||
-- Retrieval info: CONSTANT: LPM_NUMWORDS NUMERIC "256"
|
||||
-- Retrieval info: CONSTANT: LPM_SHOWAHEAD STRING "ON"
|
||||
-- Retrieval info: CONSTANT: LPM_TYPE STRING "dcfifo_mixed_widths"
|
||||
-- Retrieval info: CONSTANT: LPM_WIDTH NUMERIC "96"
|
||||
-- Retrieval info: CONSTANT: LPM_WIDTHU NUMERIC "9"
|
||||
-- Retrieval info: CONSTANT: LPM_WIDTHU_R NUMERIC "11"
|
||||
-- Retrieval info: CONSTANT: LPM_WIDTH_R NUMERIC "24"
|
||||
-- Retrieval info: CONSTANT: OVERFLOW_CHECKING STRING "ON"
|
||||
-- Retrieval info: CONSTANT: RDSYNC_DELAYPIPE NUMERIC "5"
|
||||
-- Retrieval info: CONSTANT: READ_ACLR_SYNCH STRING "OFF"
|
||||
-- Retrieval info: CONSTANT: UNDERFLOW_CHECKING STRING "ON"
|
||||
-- Retrieval info: CONSTANT: USE_EAB STRING "ON"
|
||||
-- Retrieval info: CONSTANT: WRITE_ACLR_SYNCH STRING "OFF"
|
||||
-- Retrieval info: CONSTANT: WRSYNC_DELAYPIPE NUMERIC "5"
|
||||
-- Retrieval info: USED_PORT: aclr 0 0 0 0 INPUT GND "aclr"
|
||||
-- Retrieval info: USED_PORT: data 0 0 96 0 INPUT NODEFVAL "data[95..0]"
|
||||
-- Retrieval info: USED_PORT: q 0 0 24 0 OUTPUT NODEFVAL "q[23..0]"
|
||||
-- Retrieval info: USED_PORT: rdclk 0 0 0 0 INPUT NODEFVAL "rdclk"
|
||||
-- Retrieval info: USED_PORT: rdempty 0 0 0 0 OUTPUT NODEFVAL "rdempty"
|
||||
-- Retrieval info: USED_PORT: rdreq 0 0 0 0 INPUT NODEFVAL "rdreq"
|
||||
-- Retrieval info: USED_PORT: wrclk 0 0 0 0 INPUT NODEFVAL "wrclk"
|
||||
-- Retrieval info: USED_PORT: wrreq 0 0 0 0 INPUT NODEFVAL "wrreq"
|
||||
-- Retrieval info: USED_PORT: wrusedw 0 0 9 0 OUTPUT NODEFVAL "wrusedw[8..0]"
|
||||
-- Retrieval info: CONNECT: @aclr 0 0 0 0 aclr 0 0 0 0
|
||||
-- Retrieval info: CONNECT: @data 0 0 96 0 data 0 0 96 0
|
||||
-- Retrieval info: CONNECT: @rdclk 0 0 0 0 rdclk 0 0 0 0
|
||||
-- Retrieval info: CONNECT: @rdreq 0 0 0 0 rdreq 0 0 0 0
|
||||
-- Retrieval info: CONNECT: @wrclk 0 0 0 0 wrclk 0 0 0 0
|
||||
-- Retrieval info: CONNECT: @wrreq 0 0 0 0 wrreq 0 0 0 0
|
||||
-- Retrieval info: CONNECT: q 0 0 24 0 @q 0 0 24 0
|
||||
-- Retrieval info: CONNECT: rdempty 0 0 0 0 @rdempty 0 0 0 0
|
||||
-- Retrieval info: CONNECT: wrusedw 0 0 9 0 @wrusedw 0 0 9 0
|
||||
-- Retrieval info: GEN_FILE: TYPE_NORMAL dc_video_fifo.vhd TRUE
|
||||
-- Retrieval info: GEN_FILE: TYPE_NORMAL dc_video_fifo.inc FALSE
|
||||
-- Retrieval info: GEN_FILE: TYPE_NORMAL dc_video_fifo.cmp FALSE
|
||||
-- Retrieval info: GEN_FILE: TYPE_NORMAL dc_video_fifo.bsf FALSE
|
||||
-- Retrieval info: GEN_FILE: TYPE_NORMAL dc_video_fifo_inst.vhd FALSE
|
||||
-- Retrieval info: LIB_FILE: altera_mf
|
@ -0,0 +1,363 @@
|
||||
-------------------------------------------------------------------------------
|
||||
-- Title : Frame Buffer Manager
|
||||
-- Project : From FPGA to Linux: An embedded system exploration
|
||||
-------------------------------------------------------------------------------
|
||||
-- File : framebuffer_manager.vhd
|
||||
-- Author : Philemon Orphee Favrod <philemon.favrod@epfl.ch>
|
||||
-- Company :
|
||||
-- Created : 2016-03-10
|
||||
-- Last update: 2017-02-21
|
||||
-- Platform :
|
||||
-- Standard : VHDL'87
|
||||
-------------------------------------------------------------------------------
|
||||
-- Description: DMA-capable unit that manages reads to a framebuffer.
|
||||
-------------------------------------------------------------------------------
|
||||
-- Copyright (c) 2016
|
||||
-------------------------------------------------------------------------------
|
||||
-- Revisions :
|
||||
-- Date Version Author Description
|
||||
-- 2016-03-10 1.0 P. Favrod Created
|
||||
-- 2016-04-25 1.1 P. Favrod Debuged
|
||||
-- 2016-05-23 1.2 P. Favrod Increased bandwidth + fifo sync @ VFP
|
||||
-- 2016-05-29 1.3 P. Favrod Added MSB to FIFO + removed wrfull
|
||||
-------------------------------------------------------------------------------
|
||||
-- Register Memory Mapping
|
||||
-- +-------+--------+-----+-----+-----+-----+----+-----------+
|
||||
-- | Regno | Access | B31 | ... | B10 | ... | B1 | B0 |
|
||||
-- +-------+--------+-----+-----+-----+-----+----+-----------+
|
||||
-- | 0 | R/W | FRAME_START_ADDRESS |
|
||||
-- +-------+--------+----------------------------------------+
|
||||
-- | 1 | R/W | FRAME_PIXEL_PER_LINE |
|
||||
-- +-------+--------+----------------------------------------+
|
||||
-- | 2 | R/W | FRAME_LINES_PER_FRAME |
|
||||
-- +-------+--------+----------------------------------------+
|
||||
-- | 3 | R/W | FRAME_EOL_BYTE_OFFSET |
|
||||
-- +-------+--------+----------------------------------------+
|
||||
-- | 4 | WO | COMMAND_REGISTER |
|
||||
-- +-------+--------+---------------------------+------------+
|
||||
-- | 5 | R/W | | FB_BURST_COUNT |
|
||||
-- +-------+--------+-----------+----------------------------+
|
||||
--
|
||||
-- Command register:
|
||||
-- [0] Enable DMA loop
|
||||
-- [1] Disable DMA loop
|
||||
-- [2] Enable interrupts
|
||||
-- [3] Disable interrupts
|
||||
-- [4] Acknowledge IRQ
|
||||
--
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
entity framebuffer_manager is
|
||||
|
||||
port(
|
||||
clk : in std_logic;
|
||||
pixclk : in std_logic;
|
||||
reset : in std_logic;
|
||||
|
||||
-- Avalon-MM Slave Interface
|
||||
as_address : in std_logic_vector(3 downto 0);
|
||||
as_read : in std_logic;
|
||||
as_readdata : out std_logic_vector(31 downto 0);
|
||||
as_write : in std_logic;
|
||||
as_writedata : in std_logic_vector(31 downto 0);
|
||||
|
||||
-- Avalon-MM Master Interface
|
||||
am_address : out std_logic_vector(31 downto 0);
|
||||
am_waitrequest : in std_logic;
|
||||
am_burstcount : out std_logic_vector(10 downto 0);
|
||||
am_read : out std_logic;
|
||||
am_readdata : in std_logic_vector(127 downto 0);
|
||||
am_readdatavalid : in std_logic;
|
||||
|
||||
frame_sync : in std_logic;
|
||||
|
||||
-- Interrupt Sender Interface
|
||||
irq : out std_logic;
|
||||
|
||||
-- Avalon-ST Source Interface
|
||||
src_data : out std_logic_vector(23 downto 0);
|
||||
src_valid : out std_logic;
|
||||
src_ready : in std_logic);
|
||||
end framebuffer_manager;
|
||||
|
||||
architecture rtl of framebuffer_manager is
|
||||
|
||||
constant MAX_BURST_COUNT : integer := 1024;
|
||||
|
||||
constant FRAME_START_ADDRESS_REGNO : std_logic_vector(as_address'range) := std_logic_vector(to_unsigned(0, as_address'length));
|
||||
constant FRAME_PIXEL_PER_LINE_REGNO : std_logic_vector(as_address'range) := std_logic_vector(to_unsigned(1, as_address'length));
|
||||
constant FRAME_LINES_PER_FRAME_REGNO : std_logic_vector(as_address'range) := std_logic_vector(to_unsigned(2, as_address'length));
|
||||
constant FRAME_EOL_BYTE_OFFSET_REGNO : std_logic_vector(as_address'range) := std_logic_vector(to_unsigned(3, as_address'length));
|
||||
constant FB_COMMAND_REGNO : std_logic_vector(as_address'range) := std_logic_vector(to_unsigned(4, as_address'length));
|
||||
constant FB_BURST_COUNT_REGNO : std_logic_vector(as_address'range) := std_logic_vector(to_unsigned(5, as_address'length));
|
||||
|
||||
signal start_address : integer;
|
||||
signal current_address : integer;
|
||||
signal pix_per_line, pix_per_line_copy : integer;
|
||||
signal num_lines, num_lines_copy : integer;
|
||||
signal eol_byte_offset, eol_byte_offset_copy : integer;
|
||||
signal enabled : boolean;
|
||||
signal burst_count, burst_count_copy : integer;
|
||||
signal irq_enabled : boolean;
|
||||
signal irq_acknowledged : boolean;
|
||||
|
||||
signal burst_counter : integer range 1 to MAX_BURST_COUNT;
|
||||
signal pix_counter : integer;
|
||||
signal line_counter : integer;
|
||||
|
||||
type state is (IDLE, MEMSTARTREAD, MEMRESTARTREAD, MEMREAD, FLUSHBURST, WAITSYNC);
|
||||
signal current_state : state;
|
||||
|
||||
constant INTERNAL_FIFO_DEPTH : integer := 256;
|
||||
signal fifo_clr : std_logic;
|
||||
signal fifo_data_in : std_logic_vector(95 downto 0);
|
||||
signal fifo_data_out : std_logic_vector(23 downto 0);
|
||||
signal fifo_read : std_logic;
|
||||
signal fifo_write : std_logic;
|
||||
signal fifo_usedw : std_logic_vector(8 downto 0);
|
||||
signal fifo_freew : integer range 0 to INTERNAL_FIFO_DEPTH;
|
||||
signal fifo_empty : std_logic;
|
||||
signal fifo_large_enough : boolean;
|
||||
begin
|
||||
dc_video_fifo_inst : entity work.dc_video_fifo port map (
|
||||
aclr => fifo_clr,
|
||||
data => fifo_data_in,
|
||||
rdclk => pixclk,
|
||||
rdreq => fifo_read,
|
||||
wrclk => clk,
|
||||
wrreq => fifo_write,
|
||||
q => fifo_data_out,
|
||||
rdempty => fifo_empty,
|
||||
wrusedw => fifo_usedw);
|
||||
|
||||
fifo_write <= am_readdatavalid and not fifo_clr when current_state = MEMREAD else '0';
|
||||
fifo_read <= src_ready and not fifo_empty;
|
||||
fifo_clr <= '1' when current_state = IDLE else '0';
|
||||
fifo_freew <= INTERNAL_FIFO_DEPTH - to_integer(unsigned(fifo_usedw));
|
||||
fifo_large_enough <= fifo_freew >= burst_count_copy;
|
||||
fifo_data_in <= am_readdata(119 downto 96) & am_readdata(87 downto 64) & am_readdata(55 downto 32) & am_readdata(23 downto 0);
|
||||
|
||||
src_data <= fifo_data_out when fifo_empty = '0' else X"ff0000";
|
||||
src_valid <= not fifo_empty;
|
||||
|
||||
p_as_write : process (clk, reset)
|
||||
begin
|
||||
if reset = '1' then
|
||||
start_address <= 0;
|
||||
pix_per_line <= 0;
|
||||
num_lines <= 0;
|
||||
eol_byte_offset <= 0;
|
||||
burst_count <= 4;
|
||||
enabled <= false;
|
||||
irq_enabled <= false;
|
||||
irq_acknowledged <= false;
|
||||
|
||||
elsif rising_edge(clk) then
|
||||
|
||||
irq_acknowledged <= false;
|
||||
|
||||
if as_write = '1' then
|
||||
case as_address is
|
||||
when FRAME_START_ADDRESS_REGNO =>
|
||||
start_address <= to_integer(unsigned(as_writedata));
|
||||
|
||||
when FRAME_PIXEL_PER_LINE_REGNO =>
|
||||
pix_per_line <= to_integer(unsigned(as_writedata));
|
||||
|
||||
when FRAME_LINES_PER_FRAME_REGNO =>
|
||||
num_lines <= to_integer(unsigned(as_writedata));
|
||||
|
||||
when FRAME_EOL_BYTE_OFFSET_REGNO =>
|
||||
eol_byte_offset <= to_integer(unsigned(as_writedata));
|
||||
|
||||
when FB_COMMAND_REGNO =>
|
||||
if as_writedata(0) = '1' then
|
||||
enabled <= true;
|
||||
end if;
|
||||
|
||||
if as_writedata(1) = '1' then
|
||||
enabled <= false;
|
||||
end if;
|
||||
|
||||
if as_writedata(2) = '1' then
|
||||
irq_enabled <= true;
|
||||
end if;
|
||||
|
||||
if as_writedata(3) = '1' then
|
||||
irq_enabled <= false;
|
||||
end if;
|
||||
|
||||
if as_writedata(4) = '1' then
|
||||
irq_acknowledged <= true;
|
||||
end if;
|
||||
|
||||
when FB_BURST_COUNT_REGNO =>
|
||||
if unsigned(as_writedata) > MAX_BURST_COUNT then
|
||||
burst_count <= MAX_BURST_COUNT;
|
||||
else
|
||||
burst_count <= to_integer(unsigned(as_writedata));
|
||||
end if;
|
||||
|
||||
when others => null;
|
||||
end case;
|
||||
end if;
|
||||
|
||||
end if;
|
||||
end process p_as_write;
|
||||
|
||||
p_as_read : process (clk, reset)
|
||||
begin
|
||||
if reset = '1' then
|
||||
as_readdata <= (others => '0');
|
||||
|
||||
elsif rising_edge(clk) then
|
||||
|
||||
as_readdata <= (others => '0');
|
||||
|
||||
if as_read = '1' then
|
||||
case as_address is
|
||||
when FRAME_START_ADDRESS_REGNO =>
|
||||
as_readdata <= std_logic_vector(to_unsigned(start_address, as_readdata'length));
|
||||
|
||||
when FRAME_PIXEL_PER_LINE_REGNO =>
|
||||
as_readdata <= std_logic_vector(to_unsigned(pix_per_line, as_readdata'length));
|
||||
|
||||
when FRAME_LINES_PER_FRAME_REGNO =>
|
||||
as_readdata <= std_logic_vector(to_unsigned(num_lines, as_readdata'length));
|
||||
|
||||
when FRAME_EOL_BYTE_OFFSET_REGNO =>
|
||||
as_readdata <= std_logic_vector(to_unsigned(eol_byte_offset, as_readdata'length));
|
||||
|
||||
when FB_BURST_COUNT_REGNO =>
|
||||
as_readdata <= std_logic_vector(to_unsigned(burst_count, as_readdata'length));
|
||||
|
||||
when others => null;
|
||||
end case;
|
||||
end if;
|
||||
|
||||
end if;
|
||||
end process p_as_read;
|
||||
|
||||
|
||||
p_fsm : process (clk, reset)
|
||||
begin
|
||||
if reset = '1' then
|
||||
|
||||
current_address <= 0;
|
||||
pix_per_line_copy <= 0;
|
||||
num_lines_copy <= 0;
|
||||
eol_byte_offset_copy <= 0;
|
||||
burst_count_copy <= 0;
|
||||
|
||||
burst_counter <= 1;
|
||||
pix_counter <= 0;
|
||||
line_counter <= 0;
|
||||
|
||||
current_state <= IDLE;
|
||||
|
||||
elsif rising_edge(clk) then
|
||||
-- If the interrupts have been disabled or acknowledged
|
||||
-- we deassert the interrupt request line.
|
||||
if not irq_enabled or irq_acknowledged then
|
||||
irq <= '0';
|
||||
end if;
|
||||
|
||||
case current_state is
|
||||
when IDLE =>
|
||||
-- In IDLE state, wait for enabled to be high Then, save a copy of registers
|
||||
-- in shadow registers and start reading memory.
|
||||
if enabled then
|
||||
current_address <= start_address;
|
||||
pix_per_line_copy <= pix_per_line;
|
||||
num_lines_copy <= num_lines;
|
||||
eol_byte_offset_copy <= eol_byte_offset;
|
||||
burst_count_copy <= burst_count;
|
||||
current_state <= MEMSTARTREAD;
|
||||
|
||||
pix_counter <= 4 * burst_count; -- so that when pix_counter =
|
||||
-- pix_per_line_copy we are done
|
||||
line_counter <= 1;
|
||||
end if;
|
||||
|
||||
-- wait state for the DC fifo signal to be updated
|
||||
when MEMRESTARTREAD =>
|
||||
current_state <= MEMSTARTREAD;
|
||||
|
||||
when MEMSTARTREAD =>
|
||||
-- If there is room for a full burst in the FIFO and
|
||||
-- no wait request on the bus, we start reading!
|
||||
if fifo_large_enough and am_waitrequest = '0' then
|
||||
burst_counter <= 1;
|
||||
current_state <= MEMREAD;
|
||||
end if;
|
||||
|
||||
when MEMREAD =>
|
||||
-- If a valid data is received
|
||||
if am_readdatavalid = '1' then
|
||||
|
||||
-- If in the middle of a burst, increment the burst counter
|
||||
if burst_counter < burst_count_copy then
|
||||
burst_counter <= burst_counter + 1;
|
||||
else
|
||||
|
||||
-- If in the middle of a line, increment the pixel counter and the
|
||||
-- address accordingly
|
||||
if pix_counter < pix_per_line_copy then
|
||||
pix_counter <= pix_counter + 4 * burst_count_copy;
|
||||
current_address <= current_address + 16 * burst_count_copy;
|
||||
current_state <= MEMRESTARTREAD;
|
||||
|
||||
-- If at the end of a line, increment the line counter and the
|
||||
-- address accordingly. Reset pix_counter too!
|
||||
elsif line_counter < num_lines_copy then
|
||||
line_counter <= line_counter + 1;
|
||||
pix_counter <= 4 * burst_count_copy;
|
||||
current_address <= current_address + 16 * burst_count_copy + eol_byte_offset_copy;
|
||||
current_state <= MEMRESTARTREAD;
|
||||
|
||||
-- If at the end of a frame, go back to WAITSYNC until blanking
|
||||
else
|
||||
current_state <= WAITSYNC;
|
||||
|
||||
-- End of frame => IRQ!
|
||||
if irq_enabled then
|
||||
irq <= '1';
|
||||
end if;
|
||||
|
||||
end if;
|
||||
|
||||
|
||||
end if;
|
||||
|
||||
end if;
|
||||
|
||||
if frame_sync = '1' then
|
||||
current_state <= FLUSHBURST;
|
||||
end if;
|
||||
|
||||
when FLUSHBURST =>
|
||||
if burst_counter = burst_count_copy then
|
||||
current_state <= IDLE;
|
||||
|
||||
elsif am_readdatavalid = '1' then
|
||||
burst_counter <= burst_counter + 1;
|
||||
end if;
|
||||
|
||||
when WAITSYNC =>
|
||||
-- Wait for vertical blanking to occur to avoid filling the FIFO
|
||||
-- just before it is cleared!
|
||||
if frame_sync = '1' then
|
||||
current_state <= IDLE;
|
||||
end if;
|
||||
|
||||
when others => null;
|
||||
end case;
|
||||
end if;
|
||||
end process p_fsm;
|
||||
|
||||
am_address <= std_logic_vector(to_unsigned(current_address, am_address'length));
|
||||
am_read <= '1' when fifo_large_enough and current_state = MEMSTARTREAD else '0';
|
||||
am_burstcount <= std_logic_vector(to_unsigned(burst_count_copy, am_burstcount'length));
|
||||
end architecture;
|
@ -0,0 +1,233 @@
|
||||
# TCL File Generated by Component Editor 16.0
|
||||
# Sun Feb 05 18:18:01 CET 2017
|
||||
# DO NOT MODIFY
|
||||
|
||||
|
||||
#
|
||||
# framebuffer_manager "framebuffer_manager" v1.0
|
||||
# 2017.02.05.18:18:01
|
||||
#
|
||||
#
|
||||
|
||||
#
|
||||
# request TCL package from ACDS 16.0
|
||||
#
|
||||
package require -exact qsys 16.0
|
||||
|
||||
|
||||
#
|
||||
# module framebuffer_manager
|
||||
#
|
||||
set_module_property DESCRIPTION ""
|
||||
set_module_property NAME framebuffer_manager
|
||||
set_module_property VERSION 1.0
|
||||
set_module_property INTERNAL false
|
||||
set_module_property OPAQUE_ADDRESS_MAP true
|
||||
set_module_property GROUP LCD
|
||||
set_module_property AUTHOR "Philemon Favrod"
|
||||
set_module_property DISPLAY_NAME framebuffer_manager
|
||||
set_module_property INSTANTIATE_IN_SYSTEM_MODULE true
|
||||
set_module_property EDITABLE true
|
||||
set_module_property REPORT_TO_TALKBACK false
|
||||
set_module_property ALLOW_GREYBOX_GENERATION false
|
||||
set_module_property REPORT_HIERARCHY false
|
||||
|
||||
|
||||
#
|
||||
# file sets
|
||||
#
|
||||
add_fileset QUARTUS_SYNTH QUARTUS_SYNTH "" ""
|
||||
set_fileset_property QUARTUS_SYNTH TOP_LEVEL framebuffer_manager
|
||||
set_fileset_property QUARTUS_SYNTH ENABLE_RELATIVE_INCLUDE_PATHS false
|
||||
set_fileset_property QUARTUS_SYNTH ENABLE_FILE_OVERWRITE_MODE false
|
||||
add_fileset_file framebuffer_manager.vhd VHDL PATH framebuffer_manager.vhd TOP_LEVEL_FILE
|
||||
add_fileset_file dc_video_fifo.vhd VHDL PATH dc_video_fifo.vhd
|
||||
|
||||
|
||||
#
|
||||
# parameters
|
||||
#
|
||||
|
||||
|
||||
#
|
||||
# module assignments
|
||||
#
|
||||
set_module_assignment embeddedsw.dts.compatible prsoc,framebuffer-manager
|
||||
set_module_assignment embeddedsw.dts.group any
|
||||
set_module_assignment embeddedsw.dts.vendor prsoc
|
||||
|
||||
|
||||
#
|
||||
# display items
|
||||
#
|
||||
|
||||
|
||||
#
|
||||
# connection point clock
|
||||
#
|
||||
add_interface clock clock end
|
||||
set_interface_property clock clockRate 0
|
||||
set_interface_property clock ENABLED true
|
||||
set_interface_property clock EXPORT_OF ""
|
||||
set_interface_property clock PORT_NAME_MAP ""
|
||||
set_interface_property clock CMSIS_SVD_VARIABLES ""
|
||||
set_interface_property clock SVD_ADDRESS_GROUP ""
|
||||
|
||||
add_interface_port clock clk clk Input 1
|
||||
|
||||
|
||||
#
|
||||
# connection point reset
|
||||
#
|
||||
add_interface reset reset end
|
||||
set_interface_property reset associatedClock clock
|
||||
set_interface_property reset synchronousEdges DEASSERT
|
||||
set_interface_property reset ENABLED true
|
||||
set_interface_property reset EXPORT_OF ""
|
||||
set_interface_property reset PORT_NAME_MAP ""
|
||||
set_interface_property reset CMSIS_SVD_VARIABLES ""
|
||||
set_interface_property reset SVD_ADDRESS_GROUP ""
|
||||
|
||||
add_interface_port reset reset reset Input 1
|
||||
|
||||
|
||||
#
|
||||
# connection point interrupt_sender
|
||||
#
|
||||
add_interface interrupt_sender interrupt end
|
||||
set_interface_property interrupt_sender associatedAddressablePoint ""
|
||||
set_interface_property interrupt_sender associatedClock clock
|
||||
set_interface_property interrupt_sender associatedReset reset
|
||||
set_interface_property interrupt_sender bridgedReceiverOffset ""
|
||||
set_interface_property interrupt_sender bridgesToReceiver ""
|
||||
set_interface_property interrupt_sender ENABLED true
|
||||
set_interface_property interrupt_sender EXPORT_OF ""
|
||||
set_interface_property interrupt_sender PORT_NAME_MAP ""
|
||||
set_interface_property interrupt_sender CMSIS_SVD_VARIABLES ""
|
||||
set_interface_property interrupt_sender SVD_ADDRESS_GROUP ""
|
||||
|
||||
add_interface_port interrupt_sender irq irq Output 1
|
||||
|
||||
|
||||
#
|
||||
# connection point csr
|
||||
#
|
||||
add_interface csr avalon end
|
||||
set_interface_property csr addressUnits WORDS
|
||||
set_interface_property csr associatedClock clock
|
||||
set_interface_property csr associatedReset reset
|
||||
set_interface_property csr bitsPerSymbol 8
|
||||
set_interface_property csr burstOnBurstBoundariesOnly false
|
||||
set_interface_property csr burstcountUnits WORDS
|
||||
set_interface_property csr explicitAddressSpan 0
|
||||
set_interface_property csr holdTime 0
|
||||
set_interface_property csr linewrapBursts false
|
||||
set_interface_property csr maximumPendingReadTransactions 0
|
||||
set_interface_property csr maximumPendingWriteTransactions 0
|
||||
set_interface_property csr readLatency 0
|
||||
set_interface_property csr readWaitTime 1
|
||||
set_interface_property csr setupTime 0
|
||||
set_interface_property csr timingUnits Cycles
|
||||
set_interface_property csr writeWaitTime 0
|
||||
set_interface_property csr ENABLED true
|
||||
set_interface_property csr EXPORT_OF ""
|
||||
set_interface_property csr PORT_NAME_MAP ""
|
||||
set_interface_property csr CMSIS_SVD_VARIABLES ""
|
||||
set_interface_property csr SVD_ADDRESS_GROUP ""
|
||||
|
||||
add_interface_port csr as_address address Input 4
|
||||
add_interface_port csr as_read read Input 1
|
||||
add_interface_port csr as_readdata readdata Output 32
|
||||
add_interface_port csr as_write write Input 1
|
||||
add_interface_port csr as_writedata writedata Input 32
|
||||
set_interface_assignment csr embeddedsw.configuration.isFlash 0
|
||||
set_interface_assignment csr embeddedsw.configuration.isMemoryDevice 0
|
||||
set_interface_assignment csr embeddedsw.configuration.isNonVolatileStorage 0
|
||||
set_interface_assignment csr embeddedsw.configuration.isPrintableDevice 0
|
||||
|
||||
|
||||
#
|
||||
# connection point dma
|
||||
#
|
||||
add_interface dma avalon start
|
||||
set_interface_property dma addressUnits SYMBOLS
|
||||
set_interface_property dma associatedClock clock
|
||||
set_interface_property dma associatedReset reset
|
||||
set_interface_property dma bitsPerSymbol 8
|
||||
set_interface_property dma burstOnBurstBoundariesOnly false
|
||||
set_interface_property dma burstcountUnits WORDS
|
||||
set_interface_property dma doStreamReads false
|
||||
set_interface_property dma doStreamWrites false
|
||||
set_interface_property dma holdTime 0
|
||||
set_interface_property dma linewrapBursts false
|
||||
set_interface_property dma maximumPendingReadTransactions 0
|
||||
set_interface_property dma maximumPendingWriteTransactions 0
|
||||
set_interface_property dma readLatency 0
|
||||
set_interface_property dma readWaitTime 1
|
||||
set_interface_property dma setupTime 0
|
||||
set_interface_property dma timingUnits Cycles
|
||||
set_interface_property dma writeWaitTime 0
|
||||
set_interface_property dma ENABLED true
|
||||
set_interface_property dma EXPORT_OF ""
|
||||
set_interface_property dma PORT_NAME_MAP ""
|
||||
set_interface_property dma CMSIS_SVD_VARIABLES ""
|
||||
set_interface_property dma SVD_ADDRESS_GROUP ""
|
||||
|
||||
add_interface_port dma am_address address Output 32
|
||||
add_interface_port dma am_burstcount burstcount Output 11
|
||||
add_interface_port dma am_read read Output 1
|
||||
add_interface_port dma am_readdata readdata Input 128
|
||||
add_interface_port dma am_readdatavalid readdatavalid Input 1
|
||||
add_interface_port dma am_waitrequest waitrequest Input 1
|
||||
|
||||
|
||||
#
|
||||
# connection point video_out
|
||||
#
|
||||
add_interface video_out avalon_streaming start
|
||||
set_interface_property video_out associatedClock pixclk
|
||||
set_interface_property video_out associatedReset reset
|
||||
set_interface_property video_out dataBitsPerSymbol 24
|
||||
set_interface_property video_out errorDescriptor ""
|
||||
set_interface_property video_out firstSymbolInHighOrderBits true
|
||||
set_interface_property video_out maxChannel 0
|
||||
set_interface_property video_out readyLatency 0
|
||||
set_interface_property video_out ENABLED true
|
||||
set_interface_property video_out EXPORT_OF ""
|
||||
set_interface_property video_out PORT_NAME_MAP ""
|
||||
set_interface_property video_out CMSIS_SVD_VARIABLES ""
|
||||
set_interface_property video_out SVD_ADDRESS_GROUP ""
|
||||
|
||||
add_interface_port video_out src_data data Output 24
|
||||
add_interface_port video_out src_valid valid Output 1
|
||||
add_interface_port video_out src_ready ready Input 1
|
||||
|
||||
|
||||
#
|
||||
# connection point sync
|
||||
#
|
||||
add_interface sync conduit end
|
||||
set_interface_property sync associatedClock clock
|
||||
set_interface_property sync associatedReset ""
|
||||
set_interface_property sync ENABLED true
|
||||
set_interface_property sync EXPORT_OF ""
|
||||
set_interface_property sync PORT_NAME_MAP ""
|
||||
set_interface_property sync CMSIS_SVD_VARIABLES ""
|
||||
set_interface_property sync SVD_ADDRESS_GROUP ""
|
||||
|
||||
add_interface_port sync frame_sync frame_sync Input 1
|
||||
|
||||
|
||||
#
|
||||
# connection point pixclk
|
||||
#
|
||||
add_interface pixclk clock end
|
||||
set_interface_property pixclk clockRate 0
|
||||
set_interface_property pixclk ENABLED true
|
||||
set_interface_property pixclk EXPORT_OF ""
|
||||
set_interface_property pixclk PORT_NAME_MAP ""
|
||||
set_interface_property pixclk CMSIS_SVD_VARIABLES ""
|
||||
set_interface_property pixclk SVD_ADDRESS_GROUP ""
|
||||
|
||||
add_interface_port pixclk pixclk clk Input 1
|
||||
|
@ -0,0 +1,358 @@
|
||||
|
||||
--+--------+------------+-------------------------------------------------------------------+
|
||||
--| Offset | Name | Description |
|
||||
--+--------+------------+-------------------------------------------------------------------+
|
||||
--| 0x0 | CSR | [0] Enable/Disable |
|
||||
--| 0x1 | HBP | [15..0] Horizontal Back Porch (in DCLK) |
|
||||
--| 0x2 | HFP | [15..0] Horizontal Front Porch (in DCLK) |
|
||||
--| 0x3 | VBP | [15..0] Vertical Back Porch (in # lines) |
|
||||
--| 0x4 | VFP | [15..0] Vertical Front Porch (in # lines) |
|
||||
--| 0x5 | HDATA | [15..0] Horizontal data (in DCLK) |
|
||||
--| 0x6 | VDATA | [15..0] [15..0] Vertical data (in # lines) |
|
||||
--| 0x7 | HSync | [15..0] HSync width (in DCLK) |
|
||||
--| 0x8 | Vsync | [15..0] VSync width (in # lines) |
|
||||
--+--------+------------+-------------------------------------------------------------------+
|
||||
--
|
||||
-- As usual, the horizontal timings are specified in number of data clock
|
||||
-- cycles, and the vertical timings are specified in number of lines.
|
||||
--
|
||||
-- For naming conventions, please refer to the following diagram:
|
||||
-- +----------------------------------------------------------------------------------------------+-----
|
||||
-- | A | B | C | D | ...
|
||||
-- +----------------------------------------------------------------------------------------------+-----
|
||||
-- --+ +------------------------------------------------------------------------------------------+ +-
|
||||
-- | | | |
|
||||
-- +---+ +---+
|
||||
--
|
||||
-- A is the pulse width
|
||||
-- B is the back porch
|
||||
-- C is the valid data
|
||||
-- D is the front porch
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
entity vga_sequencer is
|
||||
generic (
|
||||
HBP_DEFAULT : positive := 12;
|
||||
HFP_DEFAULT : positive := 18;
|
||||
VBP_DEFAULT : positive := 8;
|
||||
VFP_DEFAULT : positive := 20;
|
||||
HDATA_DEFAULT : positive := 240;
|
||||
VDATA_DEFAULT : positive := 320;
|
||||
HSYNC_DEFAULT : positive := 2;
|
||||
VSYNC_DEFAULT : positive := 7);
|
||||
port (
|
||||
pixclk : in std_logic; -- A copy of the pixclk from the PLL
|
||||
clk : in std_logic; -- The clock of the bus
|
||||
reset : in std_logic;
|
||||
|
||||
-- Avalon-MM CSR Interface
|
||||
address : in std_logic_vector(4 downto 0);
|
||||
read, write : in std_logic;
|
||||
readdata : out std_logic_vector(31 downto 0);
|
||||
writedata : in std_logic_vector(31 downto 0);
|
||||
|
||||
-- Avalon-ST sink Interface
|
||||
sink_data : in std_logic_vector(23 downto 0);
|
||||
sink_valid : in std_logic;
|
||||
sink_ready : out std_logic;
|
||||
|
||||
-- TFT Interface
|
||||
r : out std_logic_vector(7 downto 0);
|
||||
g : out std_logic_vector(7 downto 0);
|
||||
b : out std_logic_vector(7 downto 0);
|
||||
hsync : out std_logic;
|
||||
vsync : out std_logic;
|
||||
de : out std_logic;
|
||||
|
||||
-- Indicates when we enter the front porch of the vertical sync.
|
||||
-- Used to flush the FIFO and restart reading the frame in memory.
|
||||
frame_sync : out std_logic);
|
||||
end entity vga_sequencer;
|
||||
|
||||
architecture rtl of vga_sequencer is
|
||||
|
||||
-- Both counters should be able to count up to the addition of any four 16-bit numbers.
|
||||
signal horizontal_counter, horizontal_max : unsigned(19 downto 0);
|
||||
constant HORIZONTAL_COUNTER_RESET : unsigned(horizontal_counter'range) := to_unsigned(1, horizontal_counter'length);
|
||||
signal vertical_counter, vertical_max : unsigned(19 downto 0);
|
||||
constant VERTICAL_COUNTER_RESET : unsigned(horizontal_counter'range) := to_unsigned(1, horizontal_counter'length);
|
||||
|
||||
-- Registers
|
||||
signal hbp, hfp, vbp, vfp, hdata_width, vdata_width, hsync_width, vsync_width : unsigned(15 downto 0);
|
||||
|
||||
signal enabled : boolean;
|
||||
|
||||
-- Output registers
|
||||
signal i_r : std_logic_vector(7 downto 0);
|
||||
signal i_g : std_logic_vector(7 downto 0);
|
||||
signal i_b : std_logic_vector(7 downto 0);
|
||||
signal i_hsync : std_logic;
|
||||
signal i_vsync : std_logic;
|
||||
signal i_de : std_logic;
|
||||
|
||||
-- couting becomes true whenever enabled is true and sink_valid='1'
|
||||
signal counting : boolean;
|
||||
|
||||
constant CSR_REG_OFST : unsigned(address'range) := to_unsigned(0, address'length);
|
||||
constant HBP_REG_OFST : unsigned(address'range) := to_unsigned(1, address'length);
|
||||
constant HFP_REG_OFST : unsigned(address'range) := to_unsigned(2, address'length);
|
||||
constant VBP_REG_OFST : unsigned(address'range) := to_unsigned(3, address'length);
|
||||
constant VFP_REG_OFST : unsigned(address'range) := to_unsigned(4, address'length);
|
||||
constant HDATA_REG_OFST : unsigned(address'range) := to_unsigned(5, address'length);
|
||||
constant VDATA_REG_OFST : unsigned(address'range) := to_unsigned(6, address'length);
|
||||
constant HSYNC_REG_OFST : unsigned(address'range) := to_unsigned(7, address'length);
|
||||
constant VSYNC_REG_OFST : unsigned(address'range) := to_unsigned(8, address'length);
|
||||
begin
|
||||
|
||||
p_csr_write : process (clk, reset)
|
||||
begin
|
||||
if reset = '1' then
|
||||
enabled <= false;
|
||||
hbp <= to_unsigned(HBP_DEFAULT, hbp'length);
|
||||
hfp <= to_unsigned(HFP_DEFAULT, hfp'length);
|
||||
vbp <= to_unsigned(VBP_DEFAULT, vbp'length);
|
||||
vfp <= to_unsigned(VFP_DEFAULT, vfp'length);
|
||||
hdata_width <= to_unsigned(HDATA_DEFAULT, hdata_width'length);
|
||||
vdata_width <= to_unsigned(VDATA_DEFAULT, vdata_width'length);
|
||||
hsync_width <= to_unsigned(HSYNC_DEFAULT, hsync_width'length);
|
||||
vsync_width <= to_unsigned(VSYNC_DEFAULT, vsync_width'length);
|
||||
|
||||
elsif rising_edge(clk) then
|
||||
if write = '1' then
|
||||
case unsigned(address) is
|
||||
-- Status
|
||||
when CSR_REG_OFST =>
|
||||
if writedata(0) = '1' then
|
||||
enabled <= true;
|
||||
else
|
||||
enabled <= false;
|
||||
end if;
|
||||
|
||||
-- HBP
|
||||
when HBP_REG_OFST =>
|
||||
hbp <= unsigned(writedata(15 downto 0));
|
||||
|
||||
-- HFP
|
||||
when HFP_REG_OFST =>
|
||||
hfp <= unsigned(writedata(15 downto 0));
|
||||
|
||||
-- VBP
|
||||
when VBP_REG_OFST =>
|
||||
vbp <= unsigned(writedata(15 downto 0));
|
||||
|
||||
-- VFP
|
||||
when VFP_REG_OFST =>
|
||||
vfp <= unsigned(writedata(15 downto 0));
|
||||
|
||||
-- HDATA
|
||||
when HDATA_REG_OFST =>
|
||||
hdata_width <= unsigned(writedata(15 downto 0));
|
||||
|
||||
-- VDATA
|
||||
when VDATA_REG_OFST =>
|
||||
vdata_width <= unsigned(writedata(15 downto 0));
|
||||
|
||||
-- HSYNC
|
||||
when HSYNC_REG_OFST =>
|
||||
hsync_width <= unsigned(writedata(15 downto 0));
|
||||
|
||||
-- VSYNC
|
||||
when VSYNC_REG_OFST =>
|
||||
vsync_width <= unsigned(writedata(15 downto 0));
|
||||
|
||||
|
||||
when others => null;
|
||||
end case;
|
||||
end if;
|
||||
end if;
|
||||
end process p_csr_write;
|
||||
|
||||
p_csr_read : process (clk, reset)
|
||||
begin
|
||||
if reset = '1' then
|
||||
readdata <= (others => '0');
|
||||
elsif rising_edge(clk) then
|
||||
readdata <= (others => '0');
|
||||
if read = '1' then
|
||||
case unsigned(address) is
|
||||
-- Status
|
||||
when CSR_REG_OFST =>
|
||||
readdata <= (others => '0');
|
||||
if enabled then
|
||||
readdata(0) <= '1';
|
||||
end if;
|
||||
|
||||
-- HBP
|
||||
when HBP_REG_OFST =>
|
||||
readdata(15 downto 0) <= std_logic_vector(hbp);
|
||||
|
||||
-- HFP
|
||||
when HFP_REG_OFST =>
|
||||
readdata(15 downto 0) <= std_logic_vector(hfp);
|
||||
|
||||
-- VBP
|
||||
when VBP_REG_OFST =>
|
||||
readdata(15 downto 0) <= std_logic_vector(vbp);
|
||||
|
||||
-- VFP
|
||||
when VFP_REG_OFST =>
|
||||
readdata(15 downto 0) <= std_logic_vector(vfp);
|
||||
|
||||
-- HDATA
|
||||
when HDATA_REG_OFST =>
|
||||
readdata(15 downto 0) <= std_logic_vector(hdata_width);
|
||||
|
||||
-- VDATA
|
||||
when VDATA_REG_OFST =>
|
||||
readdata(15 downto 0) <= std_logic_vector(vdata_width);
|
||||
|
||||
-- HSYNC
|
||||
when HSYNC_REG_OFST =>
|
||||
readdata(15 downto 0) <= std_logic_vector(hsync_width);
|
||||
|
||||
-- VSYNC
|
||||
when VSYNC_REG_OFST =>
|
||||
readdata(15 downto 0) <= std_logic_vector(vsync_width);
|
||||
|
||||
when others => null;
|
||||
end case;
|
||||
end if;
|
||||
end if;
|
||||
end process p_csr_read;
|
||||
|
||||
horizontal_max <=
|
||||
resize(hsync_width, horizontal_max 'length) +
|
||||
resize(hbp, horizontal_max'length) +
|
||||
resize(hdata_width, horizontal_max'length) +
|
||||
resize(hfp, horizontal_max'length);
|
||||
|
||||
vertical_max <=
|
||||
resize(vsync_width, horizontal_max 'length) +
|
||||
resize(vbp, horizontal_max'length) +
|
||||
resize(vdata_width, horizontal_max'length) +
|
||||
resize(vfp, horizontal_max'length);
|
||||
|
||||
p_cnt_trigger : process (pixclk, reset)
|
||||
begin
|
||||
if reset = '1' then
|
||||
counting <= false;
|
||||
elsif rising_edge(pixclk) then
|
||||
|
||||
if enabled and sink_valid = '1' then
|
||||
counting <= true;
|
||||
|
||||
elsif not enabled then
|
||||
counting <= false;
|
||||
end if;
|
||||
|
||||
end if;
|
||||
end process p_cnt_trigger;
|
||||
|
||||
p_horizontal_count : process (pixclk, reset)
|
||||
begin
|
||||
if reset = '1' then
|
||||
horizontal_counter <= HORIZONTAL_COUNTER_RESET;
|
||||
elsif rising_edge(pixclk) then
|
||||
horizontal_counter <= HORIZONTAL_COUNTER_RESET;
|
||||
if counting and horizontal_counter < horizontal_max then
|
||||
horizontal_counter <= horizontal_counter + 1;
|
||||
end if;
|
||||
end if;
|
||||
end process p_horizontal_count;
|
||||
|
||||
p_vertical_count : process (pixclk, reset)
|
||||
begin
|
||||
if reset = '1' then
|
||||
vertical_counter <= VERTICAL_COUNTER_RESET;
|
||||
elsif rising_edge(pixclk) then
|
||||
if counting then
|
||||
if horizontal_counter = horizontal_max then
|
||||
if vertical_counter < vertical_max then
|
||||
vertical_counter <= vertical_counter + 1;
|
||||
else
|
||||
vertical_counter <= VERTICAL_COUNTER_RESET;
|
||||
end if;
|
||||
end if;
|
||||
else
|
||||
vertical_counter <= VERTICAL_COUNTER_RESET;
|
||||
end if;
|
||||
end if;
|
||||
end process p_vertical_count;
|
||||
|
||||
p_hsync_vsync_gen : process (counting, horizontal_counter, hsync_width,
|
||||
vertical_counter, vsync_width)
|
||||
begin
|
||||
-- HSYNC generation
|
||||
i_hsync <= '1';
|
||||
if horizontal_counter <= hsync_width then
|
||||
i_hsync <= '0';
|
||||
end if;
|
||||
|
||||
-- VSYNC generation
|
||||
i_vsync <= '1';
|
||||
if vertical_counter <= vsync_width then
|
||||
i_vsync <= '0';
|
||||
end if;
|
||||
|
||||
if not counting then
|
||||
i_vsync <= '1';
|
||||
i_hsync <= '1';
|
||||
end if;
|
||||
|
||||
end process p_hsync_vsync_gen;
|
||||
|
||||
p_rgb_out : process (hbp, hdata_width, horizontal_counter, hsync_width,
|
||||
sink_data, vbp, vdata_width, vertical_counter,
|
||||
vsync_width)
|
||||
begin
|
||||
i_r <= (others => '0');
|
||||
i_g <= (others => '0');
|
||||
i_b <= (others => '0');
|
||||
i_de <= '0';
|
||||
sink_ready <= '0';
|
||||
frame_sync <= '0';
|
||||
|
||||
if
|
||||
vertical_counter > (resize(vsync_width, vertical_counter'length) + resize(vbp, vertical_counter'length)) and
|
||||
vertical_counter <= (resize(vsync_width, vertical_counter'length) + resize(vbp, vertical_counter'length) + resize(vdata_width, vertical_counter'length)) and
|
||||
horizontal_counter > (resize(hsync_width, horizontal_counter'length) + resize(hbp, horizontal_counter'length)) and
|
||||
horizontal_counter <= (resize(hsync_width, horizontal_counter'length) + resize(hbp, horizontal_counter'length) + resize(hdata_width, horizontal_counter'length))
|
||||
then
|
||||
i_de <= '1';
|
||||
i_r <= sink_data(23 downto 16);
|
||||
i_g <= sink_data(15 downto 8);
|
||||
i_b <= sink_data(7 downto 0);
|
||||
sink_ready <= '1';
|
||||
end if;
|
||||
|
||||
if
|
||||
vertical_counter > (resize(vsync_width, vertical_counter'length) + resize(vbp, vertical_counter'length) + resize(vdata_width, vertical_counter'length))
|
||||
then
|
||||
frame_sync <= '1';
|
||||
end if;
|
||||
|
||||
end process p_rgb_out;
|
||||
|
||||
p_output_reg : process (pixclk, reset)
|
||||
begin
|
||||
if reset = '1' then
|
||||
r <= (others => '0');
|
||||
g <= (others => '0');
|
||||
b <= (others => '0');
|
||||
de <= '0';
|
||||
hsync <= '1';
|
||||
vsync <= '1';
|
||||
elsif rising_edge(pixclk) then
|
||||
de <= i_de;
|
||||
r <= i_r;
|
||||
g <= i_g;
|
||||
b <= i_b;
|
||||
vsync <= i_vsync;
|
||||
hsync <= i_hsync;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
end architecture rtl;
|
@ -0,0 +1,247 @@
|
||||
# TCL File Generated by Component Editor 16.0
|
||||
# Sun Feb 05 18:18:28 CET 2017
|
||||
# DO NOT MODIFY
|
||||
|
||||
|
||||
#
|
||||
# vga_sequencer "vga_sequencer" v1.0
|
||||
# 2017.02.05.18:18:28
|
||||
#
|
||||
#
|
||||
|
||||
#
|
||||
# request TCL package from ACDS 16.0
|
||||
#
|
||||
package require -exact qsys 16.0
|
||||
|
||||
|
||||
#
|
||||
# module vga_sequencer
|
||||
#
|
||||
set_module_property DESCRIPTION ""
|
||||
set_module_property NAME vga_sequencer
|
||||
set_module_property VERSION 1.0
|
||||
set_module_property INTERNAL false
|
||||
set_module_property OPAQUE_ADDRESS_MAP true
|
||||
set_module_property GROUP LCD
|
||||
set_module_property AUTHOR "Philemon Favrod"
|
||||
set_module_property DISPLAY_NAME vga_sequencer
|
||||
set_module_property INSTANTIATE_IN_SYSTEM_MODULE true
|
||||
set_module_property EDITABLE true
|
||||
set_module_property REPORT_TO_TALKBACK false
|
||||
set_module_property ALLOW_GREYBOX_GENERATION false
|
||||
set_module_property REPORT_HIERARCHY false
|
||||
|
||||
|
||||
#
|
||||
# file sets
|
||||
#
|
||||
add_fileset QUARTUS_SYNTH QUARTUS_SYNTH "" ""
|
||||
set_fileset_property QUARTUS_SYNTH TOP_LEVEL vga_sequencer
|
||||
set_fileset_property QUARTUS_SYNTH ENABLE_RELATIVE_INCLUDE_PATHS false
|
||||
set_fileset_property QUARTUS_SYNTH ENABLE_FILE_OVERWRITE_MODE false
|
||||
add_fileset_file vga_sequencer.vhd VHDL PATH vga_sequencer.vhd TOP_LEVEL_FILE
|
||||
|
||||
|
||||
#
|
||||
# parameters
|
||||
#
|
||||
add_parameter HBP_DEFAULT POSITIVE 12
|
||||
set_parameter_property HBP_DEFAULT DEFAULT_VALUE 12
|
||||
set_parameter_property HBP_DEFAULT DISPLAY_NAME HBP_DEFAULT
|
||||
set_parameter_property HBP_DEFAULT TYPE POSITIVE
|
||||
set_parameter_property HBP_DEFAULT UNITS None
|
||||
set_parameter_property HBP_DEFAULT ALLOWED_RANGES 1:2147483647
|
||||
set_parameter_property HBP_DEFAULT HDL_PARAMETER true
|
||||
add_parameter HFP_DEFAULT POSITIVE 18
|
||||
set_parameter_property HFP_DEFAULT DEFAULT_VALUE 18
|
||||
set_parameter_property HFP_DEFAULT DISPLAY_NAME HFP_DEFAULT
|
||||
set_parameter_property HFP_DEFAULT TYPE POSITIVE
|
||||
set_parameter_property HFP_DEFAULT UNITS None
|
||||
set_parameter_property HFP_DEFAULT ALLOWED_RANGES 1:2147483647
|
||||
set_parameter_property HFP_DEFAULT HDL_PARAMETER true
|
||||
add_parameter VBP_DEFAULT POSITIVE 8
|
||||
set_parameter_property VBP_DEFAULT DEFAULT_VALUE 8
|
||||
set_parameter_property VBP_DEFAULT DISPLAY_NAME VBP_DEFAULT
|
||||
set_parameter_property VBP_DEFAULT TYPE POSITIVE
|
||||
set_parameter_property VBP_DEFAULT UNITS None
|
||||
set_parameter_property VBP_DEFAULT ALLOWED_RANGES 1:2147483647
|
||||
set_parameter_property VBP_DEFAULT HDL_PARAMETER true
|
||||
add_parameter VFP_DEFAULT POSITIVE 20
|
||||
set_parameter_property VFP_DEFAULT DEFAULT_VALUE 20
|
||||
set_parameter_property VFP_DEFAULT DISPLAY_NAME VFP_DEFAULT
|
||||
set_parameter_property VFP_DEFAULT TYPE POSITIVE
|
||||
set_parameter_property VFP_DEFAULT UNITS None
|
||||
set_parameter_property VFP_DEFAULT ALLOWED_RANGES 1:2147483647
|
||||
set_parameter_property VFP_DEFAULT HDL_PARAMETER true
|
||||
add_parameter HDATA_DEFAULT POSITIVE 240
|
||||
set_parameter_property HDATA_DEFAULT DEFAULT_VALUE 240
|
||||
set_parameter_property HDATA_DEFAULT DISPLAY_NAME HDATA_DEFAULT
|
||||
set_parameter_property HDATA_DEFAULT TYPE POSITIVE
|
||||
set_parameter_property HDATA_DEFAULT UNITS None
|
||||
set_parameter_property HDATA_DEFAULT ALLOWED_RANGES 1:2147483647
|
||||
set_parameter_property HDATA_DEFAULT HDL_PARAMETER true
|
||||
add_parameter VDATA_DEFAULT POSITIVE 320
|
||||
set_parameter_property VDATA_DEFAULT DEFAULT_VALUE 320
|
||||
set_parameter_property VDATA_DEFAULT DISPLAY_NAME VDATA_DEFAULT
|
||||
set_parameter_property VDATA_DEFAULT TYPE POSITIVE
|
||||
set_parameter_property VDATA_DEFAULT UNITS None
|
||||
set_parameter_property VDATA_DEFAULT ALLOWED_RANGES 1:2147483647
|
||||
set_parameter_property VDATA_DEFAULT HDL_PARAMETER true
|
||||
add_parameter HSYNC_DEFAULT POSITIVE 2
|
||||
set_parameter_property HSYNC_DEFAULT DEFAULT_VALUE 2
|
||||
set_parameter_property HSYNC_DEFAULT DISPLAY_NAME HSYNC_DEFAULT
|
||||
set_parameter_property HSYNC_DEFAULT TYPE POSITIVE
|
||||
set_parameter_property HSYNC_DEFAULT UNITS None
|
||||
set_parameter_property HSYNC_DEFAULT ALLOWED_RANGES 1:2147483647
|
||||
set_parameter_property HSYNC_DEFAULT HDL_PARAMETER true
|
||||
add_parameter VSYNC_DEFAULT POSITIVE 7
|
||||
set_parameter_property VSYNC_DEFAULT DEFAULT_VALUE 7
|
||||
set_parameter_property VSYNC_DEFAULT DISPLAY_NAME VSYNC_DEFAULT
|
||||
set_parameter_property VSYNC_DEFAULT TYPE POSITIVE
|
||||
set_parameter_property VSYNC_DEFAULT UNITS None
|
||||
set_parameter_property VSYNC_DEFAULT ALLOWED_RANGES 1:2147483647
|
||||
set_parameter_property VSYNC_DEFAULT HDL_PARAMETER true
|
||||
|
||||
|
||||
#
|
||||
# display items
|
||||
#
|
||||
|
||||
|
||||
#
|
||||
# connection point clock
|
||||
#
|
||||
add_interface clock clock end
|
||||
set_interface_property clock clockRate 0
|
||||
set_interface_property clock ENABLED true
|
||||
set_interface_property clock EXPORT_OF ""
|
||||
set_interface_property clock PORT_NAME_MAP ""
|
||||
set_interface_property clock CMSIS_SVD_VARIABLES ""
|
||||
set_interface_property clock SVD_ADDRESS_GROUP ""
|
||||
|
||||
add_interface_port clock clk clk Input 1
|
||||
|
||||
|
||||
#
|
||||
# connection point reset
|
||||
#
|
||||
add_interface reset reset end
|
||||
set_interface_property reset associatedClock clock
|
||||
set_interface_property reset synchronousEdges DEASSERT
|
||||
set_interface_property reset ENABLED true
|
||||
set_interface_property reset EXPORT_OF ""
|
||||
set_interface_property reset PORT_NAME_MAP ""
|
||||
set_interface_property reset CMSIS_SVD_VARIABLES ""
|
||||
set_interface_property reset SVD_ADDRESS_GROUP ""
|
||||
|
||||
add_interface_port reset reset reset Input 1
|
||||
|
||||
|
||||
#
|
||||
# connection point csr
|
||||
#
|
||||
add_interface csr avalon end
|
||||
set_interface_property csr addressUnits WORDS
|
||||
set_interface_property csr associatedClock clock
|
||||
set_interface_property csr associatedReset reset
|
||||
set_interface_property csr bitsPerSymbol 8
|
||||
set_interface_property csr burstOnBurstBoundariesOnly false
|
||||
set_interface_property csr burstcountUnits WORDS
|
||||
set_interface_property csr explicitAddressSpan 0
|
||||
set_interface_property csr holdTime 0
|
||||
set_interface_property csr linewrapBursts false
|
||||
set_interface_property csr maximumPendingReadTransactions 0
|
||||
set_interface_property csr maximumPendingWriteTransactions 0
|
||||
set_interface_property csr readLatency 0
|
||||
set_interface_property csr readWaitTime 1
|
||||
set_interface_property csr setupTime 0
|
||||
set_interface_property csr timingUnits Cycles
|
||||
set_interface_property csr writeWaitTime 0
|
||||
set_interface_property csr ENABLED true
|
||||
set_interface_property csr EXPORT_OF ""
|
||||
set_interface_property csr PORT_NAME_MAP ""
|
||||
set_interface_property csr CMSIS_SVD_VARIABLES ""
|
||||
set_interface_property csr SVD_ADDRESS_GROUP ""
|
||||
|
||||
add_interface_port csr address address Input 5
|
||||
add_interface_port csr read read Input 1
|
||||
add_interface_port csr write write Input 1
|
||||
add_interface_port csr readdata readdata Output 32
|
||||
add_interface_port csr writedata writedata Input 32
|
||||
set_interface_assignment csr embeddedsw.configuration.isFlash 0
|
||||
set_interface_assignment csr embeddedsw.configuration.isMemoryDevice 0
|
||||
set_interface_assignment csr embeddedsw.configuration.isNonVolatileStorage 0
|
||||
set_interface_assignment csr embeddedsw.configuration.isPrintableDevice 0
|
||||
|
||||
|
||||
#
|
||||
# connection point out
|
||||
#
|
||||
add_interface out conduit end
|
||||
set_interface_property out associatedClock clock
|
||||
set_interface_property out associatedReset ""
|
||||
set_interface_property out ENABLED true
|
||||
set_interface_property out EXPORT_OF ""
|
||||
set_interface_property out PORT_NAME_MAP ""
|
||||
set_interface_property out CMSIS_SVD_VARIABLES ""
|
||||
set_interface_property out SVD_ADDRESS_GROUP ""
|
||||
|
||||
add_interface_port out hsync hsync Output 1
|
||||
add_interface_port out g g Output 8
|
||||
add_interface_port out b b Output 8
|
||||
add_interface_port out de de Output 1
|
||||
add_interface_port out vsync vsync Output 1
|
||||
add_interface_port out r r Output 8
|
||||
|
||||
|
||||
#
|
||||
# connection point in
|
||||
#
|
||||
add_interface in avalon_streaming end
|
||||
set_interface_property in associatedClock pixclk
|
||||
set_interface_property in associatedReset reset
|
||||
set_interface_property in dataBitsPerSymbol 24
|
||||
set_interface_property in errorDescriptor ""
|
||||
set_interface_property in firstSymbolInHighOrderBits true
|
||||
set_interface_property in maxChannel 0
|
||||
set_interface_property in readyLatency 0
|
||||
set_interface_property in ENABLED true
|
||||
set_interface_property in EXPORT_OF ""
|
||||
set_interface_property in PORT_NAME_MAP ""
|
||||
set_interface_property in CMSIS_SVD_VARIABLES ""
|
||||
set_interface_property in SVD_ADDRESS_GROUP ""
|
||||
|
||||
add_interface_port in sink_ready ready Output 1
|
||||
add_interface_port in sink_valid valid Input 1
|
||||
add_interface_port in sink_data data Input 24
|
||||
|
||||
|
||||
#
|
||||
# connection point pixclk
|
||||
#
|
||||
add_interface pixclk clock end
|
||||
set_interface_property pixclk clockRate 0
|
||||
set_interface_property pixclk ENABLED true
|
||||
set_interface_property pixclk EXPORT_OF ""
|
||||
set_interface_property pixclk PORT_NAME_MAP ""
|
||||
set_interface_property pixclk CMSIS_SVD_VARIABLES ""
|
||||
set_interface_property pixclk SVD_ADDRESS_GROUP ""
|
||||
|
||||
add_interface_port pixclk pixclk clk Input 1
|
||||
|
||||
|
||||
#
|
||||
# connection point frame_sync
|
||||
#
|
||||
add_interface frame_sync conduit end
|
||||
set_interface_property frame_sync associatedClock clock
|
||||
set_interface_property frame_sync associatedReset ""
|
||||
set_interface_property frame_sync ENABLED true
|
||||
set_interface_property frame_sync EXPORT_OF ""
|
||||
set_interface_property frame_sync PORT_NAME_MAP ""
|
||||
set_interface_property frame_sync CMSIS_SVD_VARIABLES ""
|
||||
set_interface_property frame_sync SVD_ADDRESS_GROUP ""
|
||||
|
||||
add_interface_port frame_sync frame_sync frame_sync Output 1
|
||||
|
138
cs309-psoc/lab_4_0/hw/hdl/joysticks/hdl/mcp3204.vhd
Normal file
138
cs309-psoc/lab_4_0/hw/hdl/joysticks/hdl/mcp3204.vhd
Normal file
@ -0,0 +1,138 @@
|
||||
-- #############################################################################
|
||||
-- mcp3204.vhd
|
||||
-- ===========
|
||||
-- MCP3204 Avalon-MM slave interface.
|
||||
--
|
||||
-- Register map
|
||||
-- +-------+-----------+--------+------------------------------------+
|
||||
-- | RegNo | Name | Access | Description |
|
||||
-- +-------+-----------+--------+------------------------------------+
|
||||
-- | 0 | CHANNEL_0 | RO | 12-bit digital value of channel 0. |
|
||||
-- +-------+-----------+--------+------------------------------------+
|
||||
-- | 1 | CHANNEL_1 | RO | 12-bit digital value of channel 1. |
|
||||
-- +-------+-----------+--------+------------------------------------+
|
||||
-- | 2 | CHANNEL_2 | RO | 12-bit digital value of channel 2. |
|
||||
-- +-------+-----------+--------+------------------------------------+
|
||||
-- | 3 | CHANNEL_3 | RO | 12-bit digital value of channel 3. |
|
||||
-- +-------+-----------+--------+------------------------------------+
|
||||
--
|
||||
-- Author : Philémon Favrod [philemon.favrod@epfl.ch]
|
||||
-- Author : Sahand Kashani-Akhavan [sahand.kashani-akhavan@epfl.ch]
|
||||
-- Revision : 2
|
||||
-- Last modified : 2018-03-06
|
||||
-- #############################################################################
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
use ieee.math_real.all;
|
||||
|
||||
entity mcp3204 is
|
||||
port(
|
||||
-- Avalon Clock interface
|
||||
clk : in std_logic;
|
||||
|
||||
-- Avalon Reset interface
|
||||
reset : in std_logic;
|
||||
|
||||
-- Avalon-MM Slave interface
|
||||
address : in std_logic_vector(1 downto 0);
|
||||
read : in std_logic;
|
||||
readdata : out std_logic_vector(31 downto 0);
|
||||
|
||||
-- Avalon Conduit interface
|
||||
CS_N : out std_logic;
|
||||
MOSI : out std_logic;
|
||||
MISO : in std_logic;
|
||||
SCLK : out std_logic
|
||||
);
|
||||
end entity;
|
||||
|
||||
architecture arch of mcp3204 is
|
||||
constant NUM_CHANNELS : positive := 4;
|
||||
constant CHANNEL_WIDTH : positive := integer(ceil(log2(real(NUM_CHANNELS))));
|
||||
|
||||
type data_array is array (NUM_CHANNELS - 1 downto 0) of std_logic_vector(readdata'range);
|
||||
signal data_reg : data_array;
|
||||
|
||||
signal spi_busy, spi_start, spi_datavalid : std_logic;
|
||||
signal spi_channel : std_logic_vector(1 downto 0);
|
||||
signal spi_data : std_logic_vector(11 downto 0);
|
||||
|
||||
type state_t is (READY, INIT_READ_CHANNEL, WAIT_FOR_DATA);
|
||||
signal state : state_t;
|
||||
|
||||
signal channel : unsigned(CHANNEL_WIDTH - 1 downto 0);
|
||||
|
||||
begin
|
||||
SPI : entity work.mcp3204_spi
|
||||
port map(
|
||||
clk => clk,
|
||||
reset => reset,
|
||||
busy => spi_busy,
|
||||
start => spi_start,
|
||||
channel => spi_channel,
|
||||
data_valid => spi_datavalid,
|
||||
data => spi_data,
|
||||
SCLK => SCLK,
|
||||
CS_N => CS_N,
|
||||
MOSI => MOSI,
|
||||
MISO => MISO
|
||||
);
|
||||
|
||||
-- FSM that dictates which channel is being read. The state of the component
|
||||
-- should be thought as the pair (state, channel)
|
||||
p_fsm : process(reset, clk)
|
||||
begin
|
||||
if reset = '1' then
|
||||
state <= READY;
|
||||
channel <= (others => '0');
|
||||
elsif rising_edge(clk) then
|
||||
case state is
|
||||
when READY =>
|
||||
if spi_busy = '0' then
|
||||
state <= INIT_READ_CHANNEL;
|
||||
end if;
|
||||
|
||||
when INIT_READ_CHANNEL =>
|
||||
state <= WAIT_FOR_DATA;
|
||||
|
||||
when WAIT_FOR_DATA =>
|
||||
if spi_datavalid = '1' then
|
||||
state <= READY;
|
||||
channel <= channel + 1;
|
||||
end if;
|
||||
end case;
|
||||
end if;
|
||||
end process p_fsm;
|
||||
|
||||
-- Updates the internal registers when a new data is available
|
||||
p_data : process(reset, clk)
|
||||
begin
|
||||
if reset = '1' then
|
||||
for i in 0 to NUM_CHANNELS - 1 loop
|
||||
data_reg(i) <= (others => '0');
|
||||
end loop;
|
||||
elsif rising_edge(clk) then
|
||||
if state = WAIT_FOR_DATA and spi_datavalid = '1' then
|
||||
data_reg(to_integer(channel)) <= (31 downto 12 => '0') & spi_data;
|
||||
end if;
|
||||
end if;
|
||||
end process p_data;
|
||||
|
||||
spi_start <= '1' when state = INIT_READ_CHANNEL else '0';
|
||||
spi_channel <= std_logic_vector(channel);
|
||||
|
||||
-- Interface with the Avalon Switch Fabric
|
||||
p_avalon_read : process(reset, clk)
|
||||
begin
|
||||
if reset = '1' then
|
||||
readdata <= (others => '0');
|
||||
elsif rising_edge(clk) then
|
||||
if read = '1' then
|
||||
readdata <= data_reg(to_integer(unsigned(address)));
|
||||
end if;
|
||||
end if;
|
||||
end process p_avalon_read;
|
||||
|
||||
end architecture;
|
137
cs309-psoc/lab_4_0/hw/hdl/joysticks/hdl/mcp3204_hw.tcl
Normal file
137
cs309-psoc/lab_4_0/hw/hdl/joysticks/hdl/mcp3204_hw.tcl
Normal file
@ -0,0 +1,137 @@
|
||||
# TCL File Generated by Component Editor 16.0
|
||||
# Sun Feb 05 18:14:06 CET 2017
|
||||
# DO NOT MODIFY
|
||||
|
||||
|
||||
#
|
||||
# mcp3204 "mcp3204" v1.0
|
||||
# Philemon Favrod & Sahand Kashani-Akhavan 2017.02.05.18:14:06
|
||||
# 4-Channel 12-Bit A/D Converter with SPI Serial Interface
|
||||
#
|
||||
|
||||
#
|
||||
# request TCL package from ACDS 16.0
|
||||
#
|
||||
package require -exact qsys 16.0
|
||||
|
||||
|
||||
#
|
||||
# module mcp3204
|
||||
#
|
||||
set_module_property DESCRIPTION "4-Channel 12-Bit A/D Converter with SPI Serial Interface"
|
||||
set_module_property NAME mcp3204
|
||||
set_module_property VERSION 1.0
|
||||
set_module_property INTERNAL false
|
||||
set_module_property OPAQUE_ADDRESS_MAP true
|
||||
set_module_property GROUP Joystick
|
||||
set_module_property AUTHOR "Philemon Favrod & Sahand Kashani-Akhavan"
|
||||
set_module_property DISPLAY_NAME mcp3204
|
||||
set_module_property INSTANTIATE_IN_SYSTEM_MODULE true
|
||||
set_module_property EDITABLE true
|
||||
set_module_property REPORT_TO_TALKBACK false
|
||||
set_module_property ALLOW_GREYBOX_GENERATION false
|
||||
set_module_property REPORT_HIERARCHY false
|
||||
|
||||
|
||||
#
|
||||
# file sets
|
||||
#
|
||||
add_fileset QUARTUS_SYNTH QUARTUS_SYNTH "" ""
|
||||
set_fileset_property QUARTUS_SYNTH TOP_LEVEL mcp3204
|
||||
set_fileset_property QUARTUS_SYNTH ENABLE_RELATIVE_INCLUDE_PATHS false
|
||||
set_fileset_property QUARTUS_SYNTH ENABLE_FILE_OVERWRITE_MODE false
|
||||
add_fileset_file mcp3204.vhd VHDL PATH mcp3204.vhd TOP_LEVEL_FILE
|
||||
add_fileset_file mcp3204_spi.vhd VHDL PATH mcp3204_spi.vhd
|
||||
|
||||
|
||||
#
|
||||
# parameters
|
||||
#
|
||||
|
||||
|
||||
#
|
||||
# display items
|
||||
#
|
||||
|
||||
|
||||
#
|
||||
# connection point clock
|
||||
#
|
||||
add_interface clock clock end
|
||||
set_interface_property clock clockRate 0
|
||||
set_interface_property clock ENABLED true
|
||||
set_interface_property clock EXPORT_OF ""
|
||||
set_interface_property clock PORT_NAME_MAP ""
|
||||
set_interface_property clock CMSIS_SVD_VARIABLES ""
|
||||
set_interface_property clock SVD_ADDRESS_GROUP ""
|
||||
|
||||
add_interface_port clock clk clk Input 1
|
||||
|
||||
|
||||
#
|
||||
# connection point reset
|
||||
#
|
||||
add_interface reset reset end
|
||||
set_interface_property reset associatedClock clock
|
||||
set_interface_property reset synchronousEdges DEASSERT
|
||||
set_interface_property reset ENABLED true
|
||||
set_interface_property reset EXPORT_OF ""
|
||||
set_interface_property reset PORT_NAME_MAP ""
|
||||
set_interface_property reset CMSIS_SVD_VARIABLES ""
|
||||
set_interface_property reset SVD_ADDRESS_GROUP ""
|
||||
|
||||
add_interface_port reset reset reset Input 1
|
||||
|
||||
|
||||
#
|
||||
# connection point avalon_slave_0
|
||||
#
|
||||
add_interface avalon_slave_0 avalon end
|
||||
set_interface_property avalon_slave_0 addressUnits WORDS
|
||||
set_interface_property avalon_slave_0 associatedClock clock
|
||||
set_interface_property avalon_slave_0 associatedReset reset
|
||||
set_interface_property avalon_slave_0 bitsPerSymbol 8
|
||||
set_interface_property avalon_slave_0 burstOnBurstBoundariesOnly false
|
||||
set_interface_property avalon_slave_0 burstcountUnits WORDS
|
||||
set_interface_property avalon_slave_0 explicitAddressSpan 0
|
||||
set_interface_property avalon_slave_0 holdTime 0
|
||||
set_interface_property avalon_slave_0 linewrapBursts false
|
||||
set_interface_property avalon_slave_0 maximumPendingReadTransactions 0
|
||||
set_interface_property avalon_slave_0 maximumPendingWriteTransactions 0
|
||||
set_interface_property avalon_slave_0 readLatency 0
|
||||
set_interface_property avalon_slave_0 readWaitTime 1
|
||||
set_interface_property avalon_slave_0 setupTime 0
|
||||
set_interface_property avalon_slave_0 timingUnits Cycles
|
||||
set_interface_property avalon_slave_0 writeWaitTime 0
|
||||
set_interface_property avalon_slave_0 ENABLED true
|
||||
set_interface_property avalon_slave_0 EXPORT_OF ""
|
||||
set_interface_property avalon_slave_0 PORT_NAME_MAP ""
|
||||
set_interface_property avalon_slave_0 CMSIS_SVD_VARIABLES ""
|
||||
set_interface_property avalon_slave_0 SVD_ADDRESS_GROUP ""
|
||||
|
||||
add_interface_port avalon_slave_0 address address Input 2
|
||||
add_interface_port avalon_slave_0 read read Input 1
|
||||
add_interface_port avalon_slave_0 readdata readdata Output 32
|
||||
set_interface_assignment avalon_slave_0 embeddedsw.configuration.isFlash 0
|
||||
set_interface_assignment avalon_slave_0 embeddedsw.configuration.isMemoryDevice 0
|
||||
set_interface_assignment avalon_slave_0 embeddedsw.configuration.isNonVolatileStorage 0
|
||||
set_interface_assignment avalon_slave_0 embeddedsw.configuration.isPrintableDevice 0
|
||||
|
||||
|
||||
#
|
||||
# connection point conduit_end
|
||||
#
|
||||
add_interface conduit_end conduit end
|
||||
set_interface_property conduit_end associatedClock clock
|
||||
set_interface_property conduit_end associatedReset ""
|
||||
set_interface_property conduit_end ENABLED true
|
||||
set_interface_property conduit_end EXPORT_OF ""
|
||||
set_interface_property conduit_end PORT_NAME_MAP ""
|
||||
set_interface_property conduit_end CMSIS_SVD_VARIABLES ""
|
||||
set_interface_property conduit_end SVD_ADDRESS_GROUP ""
|
||||
|
||||
add_interface_port conduit_end CS_N cs_n Output 1
|
||||
add_interface_port conduit_end MOSI mosi Output 1
|
||||
add_interface_port conduit_end MISO miso Input 1
|
||||
add_interface_port conduit_end SCLK sclk Output 1
|
||||
|
87
cs309-psoc/lab_4_0/hw/hdl/joysticks/hdl/mcp3204_spi.vhd
Normal file
87
cs309-psoc/lab_4_0/hw/hdl/joysticks/hdl/mcp3204_spi.vhd
Normal file
@ -0,0 +1,87 @@
|
||||
-- #############################################################################
|
||||
-- mcp3204_spi.vhd
|
||||
-- ===============
|
||||
-- MCP3204 SPI interface.
|
||||
--
|
||||
-- Author : Philémon Favrod [philemon.favrod@epfl.ch]
|
||||
-- Author : Sahand Kashani-Akhavan [sahand.kashani-akhavan@epfl.ch]
|
||||
-- Author : <insert your name> (<insert your e-mail address>)
|
||||
-- Revision : 1
|
||||
-- Last modified : <insert date>
|
||||
-- #############################################################################
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
entity mcp3204_spi is
|
||||
port(
|
||||
-- 50 MHz
|
||||
clk : in std_logic;
|
||||
reset : in std_logic;
|
||||
busy : out std_logic;
|
||||
start : in std_logic;
|
||||
channel : in std_logic_vector(1 downto 0);
|
||||
data_valid : out std_logic;
|
||||
data : out std_logic_vector(11 downto 0);
|
||||
|
||||
-- 1 MHz
|
||||
SCLK : out std_logic;
|
||||
CS_N : out std_logic;
|
||||
MOSI : out std_logic;
|
||||
MISO : in std_logic
|
||||
);
|
||||
end mcp3204_spi;
|
||||
|
||||
architecture rtl of mcp3204_spi is
|
||||
signal reg_clk_divider_counter : unsigned(4 downto 0) := (others => '0'); -- need to be able to count until 24
|
||||
signal reg_spi_en : std_logic := '0'; -- pulses every 0.5 MHz
|
||||
signal reg_rising_edge_sclk : std_logic := '0';
|
||||
signal reg_falling_edge_sclk : std_logic := '0';
|
||||
|
||||
signal reg_sclk : std_logic := '0';
|
||||
|
||||
begin
|
||||
clk_divider_generation : process(clk, reset)
|
||||
begin
|
||||
if reset = '1' then
|
||||
reg_clk_divider_counter <= (others => '0');
|
||||
elsif rising_edge(clk) then
|
||||
reg_clk_divider_counter <= reg_clk_divider_counter + 1;
|
||||
reg_spi_en <= '0';
|
||||
reg_rising_edge_sclk <= '0';
|
||||
reg_falling_edge_sclk <= '0';
|
||||
|
||||
if reg_clk_divider_counter = 24 then
|
||||
reg_clk_divider_counter <= (others => '0');
|
||||
reg_spi_en <= '1';
|
||||
|
||||
if reg_sclk = '0' then
|
||||
reg_rising_edge_sclk <= '1';
|
||||
elsif reg_sclk = '1' then
|
||||
reg_falling_edge_sclk <= '1';
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
SCLK_generation : process(clk, reset)
|
||||
begin
|
||||
if reset = '1' then
|
||||
reg_sclk <= '0';
|
||||
elsif rising_edge(clk) then
|
||||
if reg_spi_en = '1' then
|
||||
reg_sclk <= not reg_sclk;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
STATE_LOGIC : process(clk, reset)
|
||||
begin
|
||||
-- TODO: complete this process
|
||||
if reset = '1' then
|
||||
elsif rising_edge(clk) then
|
||||
end if;
|
||||
end process;
|
||||
|
||||
end architecture rtl;
|
105
cs309-psoc/lab_4_0/hw/hdl/joysticks/tb/tb_mcp3204.vhd
Normal file
105
cs309-psoc/lab_4_0/hw/hdl/joysticks/tb/tb_mcp3204.vhd
Normal file
@ -0,0 +1,105 @@
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
library osvvm;
|
||||
use osvvm.RandomPkg.all;
|
||||
|
||||
entity tb_mcp3204 is
|
||||
end entity;
|
||||
|
||||
architecture rtl of tb_mcp3204 is
|
||||
constant CLK_PERIOD : time := 20 ns;
|
||||
signal clk : std_logic := '0';
|
||||
signal reset : std_logic := '0';
|
||||
signal sim_finished : boolean := false;
|
||||
|
||||
-- mcp3204 -----------------------------------------------------------------
|
||||
signal address : std_logic_vector(1 downto 0) := (others => '0');
|
||||
signal read : std_logic := '0';
|
||||
signal readdata : std_logic_vector(31 downto 0) := (others => '0');
|
||||
signal CS_N : std_logic := '0';
|
||||
signal MOSI : std_logic := '0';
|
||||
signal MISO : std_logic := '0';
|
||||
signal SCLK : std_logic := '0';
|
||||
|
||||
begin
|
||||
duv : entity work.mcp3204
|
||||
port map(
|
||||
clk => clk,
|
||||
reset => reset,
|
||||
address => address,
|
||||
read => read,
|
||||
readdata => readdata,
|
||||
CS_N => CS_N,
|
||||
MOSI => MOSI,
|
||||
MISO => MISO,
|
||||
SCLK => SCLK
|
||||
);
|
||||
|
||||
clk <= not clk after CLK_PERIOD / 2 when not sim_finished;
|
||||
|
||||
MISO_generation : process
|
||||
variable rand_gen : RandomPType;
|
||||
variable rint : integer;
|
||||
begin
|
||||
rand_gen.InitSeed(rand_gen'instance_name);
|
||||
rand_gen.SetRandomParm(UNIFORM);
|
||||
|
||||
while true loop
|
||||
if not sim_finished then
|
||||
wait until falling_edge(SCLK);
|
||||
rint := rand_gen.RandInt(0, 1);
|
||||
|
||||
if rint = 0 then
|
||||
MISO <= '0';
|
||||
else
|
||||
MISO <= '1';
|
||||
end if;
|
||||
else
|
||||
wait;
|
||||
end if;
|
||||
end loop;
|
||||
|
||||
end process MISO_generation;
|
||||
|
||||
sim : process
|
||||
procedure async_reset is
|
||||
begin
|
||||
wait until rising_edge(clk);
|
||||
wait for CLK_PERIOD / 4;
|
||||
reset <= '1';
|
||||
|
||||
wait for CLK_PERIOD / 2;
|
||||
reset <= '0';
|
||||
end procedure async_reset;
|
||||
|
||||
procedure read_register(constant channel_number : natural range 0 to 3) is
|
||||
begin
|
||||
wait until falling_edge(clk);
|
||||
address <= std_logic_vector(to_unsigned(channel_number, address'length));
|
||||
read <= '1';
|
||||
|
||||
wait until falling_edge(clk);
|
||||
address <= (others => '0');
|
||||
read <= '0';
|
||||
|
||||
wait until falling_edge(clk);
|
||||
end procedure;
|
||||
|
||||
begin
|
||||
async_reset;
|
||||
|
||||
wait for 10000 * CLK_PERIOD;
|
||||
|
||||
for i in 0 to 3 loop
|
||||
read_register(i);
|
||||
end loop;
|
||||
|
||||
sim_finished <= true;
|
||||
wait;
|
||||
end process sim;
|
||||
end architecture rtl;
|
||||
|
||||
|
||||
|
103
cs309-psoc/lab_4_0/hw/hdl/joysticks/tb/tb_mcp3204_spi.vhd
Normal file
103
cs309-psoc/lab_4_0/hw/hdl/joysticks/tb/tb_mcp3204_spi.vhd
Normal file
@ -0,0 +1,103 @@
|
||||
-- #############################################################################
|
||||
-- tb_mcp3204_spi.vhd
|
||||
-- ==================
|
||||
-- Testbench for MCP3204 SPI interface.
|
||||
--
|
||||
-- Author : Sahand Kashani-Akhavan [sahand.kashani-akhavan@epfl.ch]
|
||||
-- Revision : 1
|
||||
-- Last modified : 2018-03-06
|
||||
-- #############################################################################
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
entity tb_mcp3204_spi is
|
||||
end entity;
|
||||
|
||||
architecture rtl of tb_mcp3204_spi is
|
||||
constant CLK_PERIOD : time := 20 ns;
|
||||
signal clk : std_logic := '0';
|
||||
signal reset : std_logic := '0';
|
||||
signal sim_finished : boolean := false;
|
||||
|
||||
-- mcp3204_spi ------------------------------------------------------------
|
||||
signal busy : std_logic := '0';
|
||||
signal start : std_logic := '0';
|
||||
signal channel : std_logic_vector(1 downto 0) := (others => '0');
|
||||
signal data_valid : std_logic := '0';
|
||||
signal data : std_logic_vector(11 downto 0) := (others => '0');
|
||||
signal SCLK : std_logic := '0';
|
||||
signal CS_N : std_logic := '1';
|
||||
signal MOSI : std_logic := '0';
|
||||
signal MISO : std_logic := '0';
|
||||
|
||||
begin
|
||||
duv : entity work.mcp3204_spi
|
||||
port map(
|
||||
clk => clk,
|
||||
reset => reset,
|
||||
busy => busy,
|
||||
start => start,
|
||||
channel => channel,
|
||||
data_valid => data_valid,
|
||||
data => data,
|
||||
SCLK => SCLK,
|
||||
CS_N => CS_N,
|
||||
MOSI => MOSI,
|
||||
MISO => MISO
|
||||
);
|
||||
|
||||
clk <= not clk after CLK_PERIOD / 2 when not sim_finished;
|
||||
|
||||
sim : process
|
||||
procedure async_reset is
|
||||
begin
|
||||
wait until rising_edge(clk);
|
||||
wait for CLK_PERIOD / 4;
|
||||
reset <= '1';
|
||||
|
||||
wait for CLK_PERIOD / 2;
|
||||
reset <= '0';
|
||||
end procedure async_reset;
|
||||
|
||||
procedure spi_transfer(constant channel_number : natural range 0 to 3) is
|
||||
begin
|
||||
if busy = '1' then
|
||||
wait until busy = '0';
|
||||
|
||||
else
|
||||
wait until falling_edge(clk);
|
||||
start <= '1';
|
||||
channel <= std_logic_vector(to_unsigned(channel_number, channel'length));
|
||||
|
||||
wait until falling_edge(clk);
|
||||
start <= '0';
|
||||
channel <= (others => '0');
|
||||
|
||||
wait until rising_edge(data_valid);
|
||||
wait until falling_edge(busy);
|
||||
end if;
|
||||
end procedure spi_transfer;
|
||||
|
||||
begin
|
||||
async_reset;
|
||||
|
||||
MISO <= '1';
|
||||
spi_transfer(0);
|
||||
|
||||
MISO <= '0';
|
||||
spi_transfer(1);
|
||||
|
||||
MISO <= '1';
|
||||
spi_transfer(2);
|
||||
|
||||
MISO <= '0';
|
||||
spi_transfer(3);
|
||||
|
||||
sim_finished <= true;
|
||||
wait;
|
||||
end process sim;
|
||||
end architecture rtl;
|
||||
|
||||
|
139
cs309-psoc/lab_4_0/hw/hdl/lepton/hdl/avalon_st_spi_master.vhd
Normal file
139
cs309-psoc/lab_4_0/hw/hdl/lepton/hdl/avalon_st_spi_master.vhd
Normal file
@ -0,0 +1,139 @@
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
use work.utils.all;
|
||||
|
||||
entity avalon_st_spi_master is
|
||||
generic(
|
||||
INPUT_CLK_FREQ : integer := 50000000;
|
||||
SPI_SCLK_FREQ : integer := 10000000;
|
||||
CPOL : integer := 1;
|
||||
CPHA : integer := 1
|
||||
);
|
||||
port(
|
||||
-- Input clock
|
||||
clk : in std_logic;
|
||||
|
||||
-- Reset
|
||||
reset : in std_logic;
|
||||
spi_cs_n : in std_logic;
|
||||
-- Sink Avalon ST Interface
|
||||
mosi_sink_data : in std_logic_vector(7 downto 0);
|
||||
mosi_sink_valid : in std_logic;
|
||||
mosi_sink_ready : out std_logic;
|
||||
|
||||
-- Source Avalon ST Interface
|
||||
miso_src_data : out std_logic_vector(7 downto 0);
|
||||
miso_src_valid : out std_logic;
|
||||
|
||||
-- SPI Master signals
|
||||
SCLK : out std_logic;
|
||||
MISO : in std_logic;
|
||||
MOSI : out std_logic;
|
||||
CS_n : out std_logic
|
||||
);
|
||||
end avalon_st_spi_master;
|
||||
|
||||
architecture rtl of avalon_st_spi_master is
|
||||
constant SCLK_PRESCALER_MAX : integer := INPUT_CLK_FREQ / SPI_SCLK_FREQ / 2;
|
||||
signal sclk_prescaler : unsigned(bitlength(SCLK_PRESCALER_MAX) downto 0);
|
||||
signal sclk_toggle : std_logic;
|
||||
|
||||
signal new_sink_buffer, cur_sink_buffer : std_logic_vector(mosi_sink_data'range);
|
||||
signal new_sink_buffer_busy, cur_sink_buffer_busy : std_logic;
|
||||
|
||||
signal miso_src_buffer : std_logic_vector(7 downto 0);
|
||||
|
||||
signal spi_done, i_sclk : std_logic;
|
||||
signal spi_bit_index : unsigned(2 downto 0);
|
||||
begin
|
||||
CS_n <= spi_cs_n;
|
||||
|
||||
p_sclk_prescaler : process(clk, reset) is
|
||||
begin
|
||||
if reset = '1' then
|
||||
sclk_prescaler <= to_unsigned(1, sclk_prescaler'length);
|
||||
elsif rising_edge(clk) then
|
||||
if sclk_prescaler = SCLK_PRESCALER_MAX then
|
||||
sclk_prescaler <= to_unsigned(1, sclk_prescaler'length);
|
||||
else
|
||||
sclk_prescaler <= sclk_prescaler + 1;
|
||||
end if;
|
||||
end if;
|
||||
end process p_sclk_prescaler;
|
||||
sclk_toggle <= '1' when sclk_prescaler = SCLK_PRESCALER_MAX else '0';
|
||||
|
||||
p_avalon_st_sink : process(clk, reset) is
|
||||
begin
|
||||
if reset = '1' then
|
||||
new_sink_buffer_busy <= '0';
|
||||
new_sink_buffer <= (others => '0');
|
||||
elsif rising_edge(clk) then
|
||||
if mosi_sink_valid = '1' then
|
||||
if new_sink_buffer_busy = '0' and cur_sink_buffer_busy = '1' then
|
||||
new_sink_buffer <= mosi_sink_data;
|
||||
new_sink_buffer_busy <= '1';
|
||||
end if;
|
||||
elsif new_sink_buffer_busy = '1' and cur_sink_buffer_busy = '0' then
|
||||
new_sink_buffer_busy <= '0';
|
||||
end if;
|
||||
end if;
|
||||
end process p_avalon_st_sink;
|
||||
mosi_sink_ready <= not new_sink_buffer_busy;
|
||||
|
||||
p_cur_buffer : process(clk, reset) is
|
||||
begin
|
||||
if reset = '1' then
|
||||
cur_sink_buffer <= (others => '0');
|
||||
cur_sink_buffer_busy <= '0';
|
||||
elsif rising_edge(clk) then
|
||||
if mosi_sink_valid = '1' and cur_sink_buffer_busy = '0' then
|
||||
cur_sink_buffer <= mosi_sink_data;
|
||||
cur_sink_buffer_busy <= '1';
|
||||
elsif cur_sink_buffer_busy = '0' and new_sink_buffer_busy = '1' then
|
||||
cur_sink_buffer <= new_sink_buffer;
|
||||
cur_sink_buffer_busy <= '1';
|
||||
elsif cur_sink_buffer_busy = '1' and spi_done = '1' then
|
||||
cur_sink_buffer_busy <= '0';
|
||||
end if;
|
||||
end if;
|
||||
end process p_cur_buffer;
|
||||
|
||||
p_spi : process(clk, reset) is
|
||||
begin
|
||||
if reset = '1' then
|
||||
spi_done <= '0';
|
||||
i_sclk <= to_unsigned(CPOL, 1)(0);
|
||||
spi_bit_index <= "000";
|
||||
MOSI <= '0';
|
||||
miso_src_data <= (others => '0');
|
||||
miso_src_valid <= '0';
|
||||
miso_src_buffer <= (others => '0');
|
||||
|
||||
elsif rising_edge(clk) then
|
||||
spi_done <= '0';
|
||||
miso_src_valid <= '0';
|
||||
if cur_sink_buffer_busy = '1' and sclk_toggle = '1' then
|
||||
if i_sclk /= to_unsigned(CPHA, 1)(0) then
|
||||
if spi_bit_index = "111" then
|
||||
spi_done <= '1';
|
||||
spi_bit_index <= "000";
|
||||
miso_src_valid <= '1';
|
||||
miso_src_data <= miso_src_buffer(7 downto 1) & MISO;
|
||||
else
|
||||
MOSI <= cur_sink_buffer(7 - to_integer(spi_bit_index));
|
||||
miso_src_buffer(7 - to_integer(spi_bit_index)) <= MISO;
|
||||
spi_bit_index <= spi_bit_index + 1;
|
||||
|
||||
end if;
|
||||
|
||||
end if;
|
||||
|
||||
i_sclk <= not i_sclk;
|
||||
|
||||
end if;
|
||||
end if;
|
||||
end process p_spi;
|
||||
SCLK <= i_sclk;
|
||||
|
||||
end rtl;
|
87
cs309-psoc/lab_4_0/hw/hdl/lepton/hdl/byte2pix.vhd
Normal file
87
cs309-psoc/lab_4_0/hw/hdl/lepton/hdl/byte2pix.vhd
Normal file
@ -0,0 +1,87 @@
|
||||
-------------------------------------------------------------------------------
|
||||
-- Title : Byte stream to pixel converter for the Lepton Camera
|
||||
-- Project : PrSoC
|
||||
-------------------------------------------------------------------------------
|
||||
-- File : byte2pix.vhd
|
||||
-- Author : Philemon Orphee Favrod <pofavrod@lappc5.epfl.ch>
|
||||
-- Company :
|
||||
-- Created : 2016-03-21
|
||||
-- Last update: 2017-03-19
|
||||
-- Platform :
|
||||
-- Standard : VHDL'87
|
||||
-------------------------------------------------------------------------------
|
||||
-- Description: Converts a byte stream to a 14-bit pixel stream.
|
||||
-------------------------------------------------------------------------------
|
||||
-- Copyright (c) 2016
|
||||
-------------------------------------------------------------------------------
|
||||
-- Revisions :
|
||||
-- Date Version Author Description
|
||||
-- 2016-03-21 1.0 pofavrod Created
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
entity byte2pix is
|
||||
port(
|
||||
clk, reset : in std_logic;
|
||||
byte_data : in std_logic_vector(7 downto 0);
|
||||
byte_valid : in std_logic;
|
||||
byte_sof : in std_logic;
|
||||
byte_eof : in std_logic;
|
||||
pix_data : out std_logic_vector(13 downto 0);
|
||||
pix_valid : out std_logic;
|
||||
pix_sof : out std_logic;
|
||||
pix_eof : out std_logic);
|
||||
|
||||
end byte2pix;
|
||||
|
||||
architecture rtl of byte2pix is
|
||||
signal last_sof : std_logic;
|
||||
signal msb : std_logic_vector(5 downto 0);
|
||||
signal cnt : std_logic; -- used to skip msb sampling every other time
|
||||
begin
|
||||
process(clk, reset)
|
||||
begin
|
||||
if reset = '1' then
|
||||
msb <= (others => '0');
|
||||
cnt <= '0';
|
||||
last_sof <= '0';
|
||||
elsif rising_edge(clk) then
|
||||
if byte_valid = '1' then
|
||||
if cnt = '0' then
|
||||
msb <= byte_data(5 downto 0);
|
||||
last_sof <= byte_sof;
|
||||
end if;
|
||||
cnt <= not cnt;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
process(clk, reset)
|
||||
begin
|
||||
if reset = '1' then
|
||||
pix_data <= (others => '0');
|
||||
pix_valid <= '0';
|
||||
pix_sof <= '0';
|
||||
pix_eof <= '0';
|
||||
elsif rising_edge(clk) then
|
||||
pix_data <= (others => '0');
|
||||
pix_valid <= '0';
|
||||
pix_sof <= '0';
|
||||
pix_eof <= '0';
|
||||
|
||||
if byte_valid = '1' then
|
||||
if cnt = '1' then
|
||||
pix_data <= msb & byte_data;
|
||||
pix_valid <= '1';
|
||||
pix_sof <= last_sof;
|
||||
pix_eof <= byte_eof;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
end architecture rtl;
|
192
cs309-psoc/lab_4_0/hw/hdl/lepton/hdl/dual_ported_ram.vhd
Normal file
192
cs309-psoc/lab_4_0/hw/hdl/lepton/hdl/dual_ported_ram.vhd
Normal file
@ -0,0 +1,192 @@
|
||||
-- megafunction wizard: %RAM: 2-PORT%
|
||||
-- GENERATION: STANDARD
|
||||
-- VERSION: WM1.0
|
||||
-- MODULE: altsyncram
|
||||
|
||||
-- ============================================================
|
||||
-- File Name: dual_ported_ram.vhd
|
||||
-- Megafunction Name(s):
|
||||
-- altsyncram
|
||||
--
|
||||
-- Simulation Library Files(s):
|
||||
-- altera_mf
|
||||
-- ============================================================
|
||||
-- ************************************************************
|
||||
-- THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE!
|
||||
--
|
||||
-- 15.1.0 Build 185 10/21/2015 SJ Lite Edition
|
||||
-- ************************************************************
|
||||
|
||||
|
||||
--Copyright (C) 1991-2015 Altera Corporation. All rights reserved.
|
||||
--Your use of Altera Corporation's design tools, logic functions
|
||||
--and other software and tools, and its AMPP partner logic
|
||||
--functions, and any output files from any of the foregoing
|
||||
--(including device programming or simulation files), and any
|
||||
--associated documentation or information are expressly subject
|
||||
--to the terms and conditions of the Altera Program License
|
||||
--Subscription Agreement, the Altera Quartus Prime License Agreement,
|
||||
--the Altera MegaCore Function License Agreement, or other
|
||||
--applicable license agreement, including, without limitation,
|
||||
--that your use is for the sole purpose of programming logic
|
||||
--devices manufactured by Altera and sold by Altera or its
|
||||
--authorized distributors. Please refer to the applicable
|
||||
--agreement for further details.
|
||||
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
|
||||
library altera_mf;
|
||||
use altera_mf.altera_mf_components.all;
|
||||
|
||||
entity dual_ported_ram is
|
||||
port(
|
||||
clock : in std_logic := '1';
|
||||
data : in std_logic_vector(15 downto 0);
|
||||
rdaddress : in std_logic_vector(12 downto 0);
|
||||
wraddress : in std_logic_vector(12 downto 0);
|
||||
wren : in std_logic := '0';
|
||||
q : out std_logic_vector(15 downto 0)
|
||||
);
|
||||
end dual_ported_ram;
|
||||
|
||||
architecture SYN of dual_ported_ram is
|
||||
signal sub_wire0 : std_logic_vector(15 downto 0);
|
||||
|
||||
begin
|
||||
q <= sub_wire0(15 downto 0);
|
||||
|
||||
altsyncram_component : altsyncram
|
||||
generic map(
|
||||
address_aclr_b => "NONE",
|
||||
address_reg_b => "CLOCK0",
|
||||
clock_enable_input_a => "BYPASS",
|
||||
clock_enable_input_b => "BYPASS",
|
||||
clock_enable_output_b => "BYPASS",
|
||||
intended_device_family => "Cyclone V",
|
||||
lpm_type => "altsyncram",
|
||||
numwords_a => 8192,
|
||||
numwords_b => 8192,
|
||||
operation_mode => "DUAL_PORT",
|
||||
outdata_aclr_b => "NONE",
|
||||
outdata_reg_b => "CLOCK0",
|
||||
power_up_uninitialized => "FALSE",
|
||||
read_during_write_mode_mixed_ports => "DONT_CARE",
|
||||
widthad_a => 13,
|
||||
widthad_b => 13,
|
||||
width_a => 16,
|
||||
width_b => 16,
|
||||
width_byteena_a => 1
|
||||
)
|
||||
port map(
|
||||
address_a => wraddress,
|
||||
address_b => rdaddress,
|
||||
clock0 => clock,
|
||||
data_a => data,
|
||||
wren_a => wren,
|
||||
q_b => sub_wire0
|
||||
);
|
||||
|
||||
end SYN;
|
||||
|
||||
-- ============================================================
|
||||
-- CNX file retrieval info
|
||||
-- ============================================================
|
||||
-- Retrieval info: PRIVATE: ADDRESSSTALL_A NUMERIC "0"
|
||||
-- Retrieval info: PRIVATE: ADDRESSSTALL_B NUMERIC "0"
|
||||
-- Retrieval info: PRIVATE: BYTEENA_ACLR_A NUMERIC "0"
|
||||
-- Retrieval info: PRIVATE: BYTEENA_ACLR_B NUMERIC "0"
|
||||
-- Retrieval info: PRIVATE: BYTE_ENABLE_A NUMERIC "0"
|
||||
-- Retrieval info: PRIVATE: BYTE_ENABLE_B NUMERIC "0"
|
||||
-- Retrieval info: PRIVATE: BYTE_SIZE NUMERIC "8"
|
||||
-- Retrieval info: PRIVATE: BlankMemory NUMERIC "1"
|
||||
-- Retrieval info: PRIVATE: CLOCK_ENABLE_INPUT_A NUMERIC "0"
|
||||
-- Retrieval info: PRIVATE: CLOCK_ENABLE_INPUT_B NUMERIC "0"
|
||||
-- Retrieval info: PRIVATE: CLOCK_ENABLE_OUTPUT_A NUMERIC "0"
|
||||
-- Retrieval info: PRIVATE: CLOCK_ENABLE_OUTPUT_B NUMERIC "0"
|
||||
-- Retrieval info: PRIVATE: CLRdata NUMERIC "0"
|
||||
-- Retrieval info: PRIVATE: CLRq NUMERIC "0"
|
||||
-- Retrieval info: PRIVATE: CLRrdaddress NUMERIC "0"
|
||||
-- Retrieval info: PRIVATE: CLRrren NUMERIC "0"
|
||||
-- Retrieval info: PRIVATE: CLRwraddress NUMERIC "0"
|
||||
-- Retrieval info: PRIVATE: CLRwren NUMERIC "0"
|
||||
-- Retrieval info: PRIVATE: Clock NUMERIC "0"
|
||||
-- Retrieval info: PRIVATE: Clock_A NUMERIC "0"
|
||||
-- Retrieval info: PRIVATE: Clock_B NUMERIC "0"
|
||||
-- Retrieval info: PRIVATE: IMPLEMENT_IN_LES NUMERIC "0"
|
||||
-- Retrieval info: PRIVATE: INDATA_ACLR_B NUMERIC "0"
|
||||
-- Retrieval info: PRIVATE: INDATA_REG_B NUMERIC "0"
|
||||
-- Retrieval info: PRIVATE: INIT_FILE_LAYOUT STRING "PORT_B"
|
||||
-- Retrieval info: PRIVATE: INIT_TO_SIM_X NUMERIC "0"
|
||||
-- Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "Cyclone V"
|
||||
-- Retrieval info: PRIVATE: JTAG_ENABLED NUMERIC "0"
|
||||
-- Retrieval info: PRIVATE: JTAG_ID STRING "NONE"
|
||||
-- Retrieval info: PRIVATE: MAXIMUM_DEPTH NUMERIC "0"
|
||||
-- Retrieval info: PRIVATE: MEMSIZE NUMERIC "131072"
|
||||
-- Retrieval info: PRIVATE: MEM_IN_BITS NUMERIC "0"
|
||||
-- Retrieval info: PRIVATE: MIFfilename STRING ""
|
||||
-- Retrieval info: PRIVATE: OPERATION_MODE NUMERIC "2"
|
||||
-- Retrieval info: PRIVATE: OUTDATA_ACLR_B NUMERIC "0"
|
||||
-- Retrieval info: PRIVATE: OUTDATA_REG_B NUMERIC "1"
|
||||
-- Retrieval info: PRIVATE: RAM_BLOCK_TYPE NUMERIC "0"
|
||||
-- Retrieval info: PRIVATE: READ_DURING_WRITE_MODE_MIXED_PORTS NUMERIC "2"
|
||||
-- Retrieval info: PRIVATE: READ_DURING_WRITE_MODE_PORT_A NUMERIC "3"
|
||||
-- Retrieval info: PRIVATE: READ_DURING_WRITE_MODE_PORT_B NUMERIC "3"
|
||||
-- Retrieval info: PRIVATE: REGdata NUMERIC "1"
|
||||
-- Retrieval info: PRIVATE: REGq NUMERIC "1"
|
||||
-- Retrieval info: PRIVATE: REGrdaddress NUMERIC "1"
|
||||
-- Retrieval info: PRIVATE: REGrren NUMERIC "1"
|
||||
-- Retrieval info: PRIVATE: REGwraddress NUMERIC "1"
|
||||
-- Retrieval info: PRIVATE: REGwren NUMERIC "1"
|
||||
-- Retrieval info: PRIVATE: SYNTH_WRAPPER_GEN_POSTFIX STRING "0"
|
||||
-- Retrieval info: PRIVATE: USE_DIFF_CLKEN NUMERIC "0"
|
||||
-- Retrieval info: PRIVATE: UseDPRAM NUMERIC "1"
|
||||
-- Retrieval info: PRIVATE: VarWidth NUMERIC "0"
|
||||
-- Retrieval info: PRIVATE: WIDTH_READ_A NUMERIC "16"
|
||||
-- Retrieval info: PRIVATE: WIDTH_READ_B NUMERIC "16"
|
||||
-- Retrieval info: PRIVATE: WIDTH_WRITE_A NUMERIC "16"
|
||||
-- Retrieval info: PRIVATE: WIDTH_WRITE_B NUMERIC "16"
|
||||
-- Retrieval info: PRIVATE: WRADDR_ACLR_B NUMERIC "0"
|
||||
-- Retrieval info: PRIVATE: WRADDR_REG_B NUMERIC "0"
|
||||
-- Retrieval info: PRIVATE: WRCTRL_ACLR_B NUMERIC "0"
|
||||
-- Retrieval info: PRIVATE: enable NUMERIC "0"
|
||||
-- Retrieval info: PRIVATE: rden NUMERIC "0"
|
||||
-- Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all
|
||||
-- Retrieval info: CONSTANT: ADDRESS_ACLR_B STRING "NONE"
|
||||
-- Retrieval info: CONSTANT: ADDRESS_REG_B STRING "CLOCK0"
|
||||
-- Retrieval info: CONSTANT: CLOCK_ENABLE_INPUT_A STRING "BYPASS"
|
||||
-- Retrieval info: CONSTANT: CLOCK_ENABLE_INPUT_B STRING "BYPASS"
|
||||
-- Retrieval info: CONSTANT: CLOCK_ENABLE_OUTPUT_B STRING "BYPASS"
|
||||
-- Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone V"
|
||||
-- Retrieval info: CONSTANT: LPM_TYPE STRING "altsyncram"
|
||||
-- Retrieval info: CONSTANT: NUMWORDS_A NUMERIC "8192"
|
||||
-- Retrieval info: CONSTANT: NUMWORDS_B NUMERIC "8192"
|
||||
-- Retrieval info: CONSTANT: OPERATION_MODE STRING "DUAL_PORT"
|
||||
-- Retrieval info: CONSTANT: OUTDATA_ACLR_B STRING "NONE"
|
||||
-- Retrieval info: CONSTANT: OUTDATA_REG_B STRING "CLOCK0"
|
||||
-- Retrieval info: CONSTANT: POWER_UP_UNINITIALIZED STRING "FALSE"
|
||||
-- Retrieval info: CONSTANT: READ_DURING_WRITE_MODE_MIXED_PORTS STRING "DONT_CARE"
|
||||
-- Retrieval info: CONSTANT: WIDTHAD_A NUMERIC "13"
|
||||
-- Retrieval info: CONSTANT: WIDTHAD_B NUMERIC "13"
|
||||
-- Retrieval info: CONSTANT: WIDTH_A NUMERIC "16"
|
||||
-- Retrieval info: CONSTANT: WIDTH_B NUMERIC "16"
|
||||
-- Retrieval info: CONSTANT: WIDTH_BYTEENA_A NUMERIC "1"
|
||||
-- Retrieval info: USED_PORT: clock 0 0 0 0 INPUT VCC "clock"
|
||||
-- Retrieval info: USED_PORT: data 0 0 16 0 INPUT NODEFVAL "data[15..0]"
|
||||
-- Retrieval info: USED_PORT: q 0 0 16 0 OUTPUT NODEFVAL "q[15..0]"
|
||||
-- Retrieval info: USED_PORT: rdaddress 0 0 13 0 INPUT NODEFVAL "rdaddress[12..0]"
|
||||
-- Retrieval info: USED_PORT: wraddress 0 0 13 0 INPUT NODEFVAL "wraddress[12..0]"
|
||||
-- Retrieval info: USED_PORT: wren 0 0 0 0 INPUT GND "wren"
|
||||
-- Retrieval info: CONNECT: @address_a 0 0 13 0 wraddress 0 0 13 0
|
||||
-- Retrieval info: CONNECT: @address_b 0 0 13 0 rdaddress 0 0 13 0
|
||||
-- Retrieval info: CONNECT: @clock0 0 0 0 0 clock 0 0 0 0
|
||||
-- Retrieval info: CONNECT: @data_a 0 0 16 0 data 0 0 16 0
|
||||
-- Retrieval info: CONNECT: @wren_a 0 0 0 0 wren 0 0 0 0
|
||||
-- Retrieval info: CONNECT: q 0 0 16 0 @q_b 0 0 16 0
|
||||
-- Retrieval info: GEN_FILE: TYPE_NORMAL dual_ported_ram.vhd TRUE
|
||||
-- Retrieval info: GEN_FILE: TYPE_NORMAL dual_ported_ram.inc FALSE
|
||||
-- Retrieval info: GEN_FILE: TYPE_NORMAL dual_ported_ram.cmp FALSE
|
||||
-- Retrieval info: GEN_FILE: TYPE_NORMAL dual_ported_ram.bsf FALSE
|
||||
-- Retrieval info: GEN_FILE: TYPE_NORMAL dual_ported_ram_inst.vhd FALSE
|
||||
-- Retrieval info: LIB_FILE: altera_mf
|
288
cs309-psoc/lab_4_0/hw/hdl/lepton/hdl/lepton.vhd
Normal file
288
cs309-psoc/lab_4_0/hw/hdl/lepton/hdl/lepton.vhd
Normal file
@ -0,0 +1,288 @@
|
||||
-- Lepton Avalon Memory-Mapped Slave Interface
|
||||
-- Author: Philémon Favrod (philemon.favrod@epfl.ch)
|
||||
-- Modified by: Sahand Kashani-Akhavan (sahand.kashani-akhavan@epfl.ch)
|
||||
-- Revision: 2
|
||||
|
||||
-- Register map
|
||||
-- +---------------+-----------------+--------+---------------------------------------------------+
|
||||
-- | RegNo | Name | Access | Description |
|
||||
-- +---------------+-----------------+--------+---------------------------------------------------+
|
||||
-- | 0 | COMMAND | WO | Command |
|
||||
-- | | | | - Writing 1 starts capturing a frame & resets the |
|
||||
-- | | | | ERROR bit (bit 1) in the STATUS register. |
|
||||
-- +---------------+-----------------+--------+---------------------------------------------------+
|
||||
-- | 1 | STATUS | RO | Status |
|
||||
-- | | | | - Bit 0: 0 --> no capture in progress. |
|
||||
-- | | | | 1 --> capture in progress. |
|
||||
-- | | | | - Bit 1: 0 --> previous capture successful. |
|
||||
-- | | | | 1 --> error during previous capture. |
|
||||
-- +---------------+-----------------+--------+---------------------------------------------------+
|
||||
-- | 2 | MIN | RO | Minimum pixel value in frame. |
|
||||
-- +---------------+-----------------+--------+---------------------------------------------------+
|
||||
-- | 3 | MAX | RO | Maximum pixel value in frame. |
|
||||
-- +---------------+-----------------+--------+---------------------------------------------------+
|
||||
-- | 4 | SUM_LSB | RO | Sum of all pixels in frame (low 16 bits). |
|
||||
-- +---------------+-----------------+--------+---------------------------------------------------+
|
||||
-- | 5 | SUM_MSB | RO | Sum of all pixels in frame (high 16 bits). |
|
||||
-- +---------------+-----------------+--------+---------------------------------------------------+
|
||||
-- | 6 | ROW_IDX | RO | Current line being captured (1 <= ROW_IDX <= 60). |
|
||||
-- | | | | Available for debugging purposes. |
|
||||
-- +---------------+-----------------+--------+---------------------------------------------------+
|
||||
-- | 7 | RESERVED | - | Reserved |
|
||||
-- +---------------+-----------------+--------+---------------------------------------------------+
|
||||
-- | 8 - 4807 | RAW BUFFER | RO | View into RAW pixel buffer. |
|
||||
-- +---------------+-----------------+--------+---------------------------------------------------+
|
||||
-- | 4808 - 8191 | RESERVED | - | Reserved |
|
||||
-- +---------------+-----------------+--------+---------------------------------------------------+
|
||||
-- | 8192 - 12991 | ADJUSTED BUFFER | RO | View into adjusted (scaled) pixel buffer. |
|
||||
-- | | | | Values are scaled between MIN and MAX. |
|
||||
-- +---------------+-----------------+--------+---------------------------------------------------+
|
||||
-- | 12992 - 16383 | RESERVED | - | Reserved |
|
||||
-- +---------------+-----------------+--------+---------------------------------------------------+
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
entity lepton is
|
||||
port(
|
||||
clk : in std_logic;
|
||||
reset : in std_logic;
|
||||
address : in std_logic_vector(13 downto 0);
|
||||
readdata : out std_logic_vector(15 downto 0);
|
||||
writedata : in std_logic_vector(15 downto 0);
|
||||
read : in std_logic;
|
||||
write : in std_logic;
|
||||
|
||||
SCLK : out std_logic;
|
||||
CSn : out std_logic;
|
||||
MOSI : out std_logic;
|
||||
MISO : in std_logic
|
||||
);
|
||||
|
||||
end lepton;
|
||||
|
||||
architecture rtl of lepton is
|
||||
signal spi_cs_n : std_logic;
|
||||
signal spi_mosi_data : std_logic_vector(7 downto 0);
|
||||
signal spi_mosi_valid : std_logic;
|
||||
signal spi_mosi_ready : std_logic;
|
||||
signal spi_miso_data : std_logic_vector(7 downto 0);
|
||||
signal spi_miso_valid : std_logic;
|
||||
signal lepton_manager_start : std_logic;
|
||||
signal lepton_manager_error : std_logic;
|
||||
signal byte_data : std_logic_vector(7 downto 0);
|
||||
signal byte_valid : std_logic;
|
||||
signal byte_sof : std_logic;
|
||||
signal byte_eof : std_logic;
|
||||
signal pix_data : std_logic_vector(13 downto 0);
|
||||
signal pix_valid : std_logic;
|
||||
signal pix_sof : std_logic;
|
||||
signal pix_eof : std_logic;
|
||||
signal stat_min : std_logic_vector(13 downto 0);
|
||||
signal stat_max : std_logic_vector(13 downto 0);
|
||||
signal stat_sum : std_logic_vector(26 downto 0);
|
||||
signal stat_valid : std_logic;
|
||||
signal ram_data : std_logic_vector(15 downto 0);
|
||||
signal ram_wren : std_logic;
|
||||
signal ram_wraddress : std_logic_vector(12 downto 0);
|
||||
signal ram_rdaddress : std_logic_vector(12 downto 0);
|
||||
signal ram_q : std_logic_vector(15 downto 0);
|
||||
signal row_idx : std_logic_vector(5 downto 0);
|
||||
signal raw_pixel : std_logic_vector(13 downto 0);
|
||||
signal raw_max : std_logic_vector(13 downto 0);
|
||||
signal raw_min : std_logic_vector(13 downto 0);
|
||||
signal raw_sum : std_logic_vector(26 downto 0);
|
||||
signal adjusted_pixel : std_logic_vector(13 downto 0);
|
||||
|
||||
constant COMMAND_REG_OFFSET : std_logic_vector(address'range) := "00000000000000";
|
||||
constant STATUS_REG_OFFSET : std_logic_vector(address'range) := "00000000000001";
|
||||
constant MIN_REG_OFFSET : std_logic_vector(address'range) := "00000000000010";
|
||||
constant MAX_REG_OFFSET : std_logic_vector(address'range) := "00000000000011";
|
||||
constant SUM_LSB_REG_OFFSET : std_logic_vector(address'range) := "00000000000100";
|
||||
constant SUM_MSB_REG_OFFSET : std_logic_vector(address'range) := "00000000000101";
|
||||
constant ROW_IDX_REG_OFFSET : std_logic_vector(address'range) := "00000000000110";
|
||||
constant BUFFER_REG_OFFSET : unsigned(address'range) := "00000000001000";
|
||||
constant ADJUSTED_BUFFER_REG_OFFSET : unsigned(address'range) := "10000000000000";
|
||||
|
||||
constant IMAGE_SIZE : integer := 80 * 60;
|
||||
constant BUFFER_REG_LIMIT : unsigned(address'range) := unsigned(BUFFER_REG_OFFSET) + IMAGE_SIZE;
|
||||
|
||||
constant ADJUSTED_BUFFER_LIMIT : unsigned(address'range) := unsigned(ADJUSTED_BUFFER_REG_OFFSET) + IMAGE_SIZE;
|
||||
|
||||
signal max_reg : std_logic_vector(stat_max'range);
|
||||
signal min_reg : std_logic_vector(stat_min'range);
|
||||
signal sum_reg : std_logic_vector(stat_sum'range);
|
||||
signal error_reg : std_logic;
|
||||
|
||||
begin
|
||||
spi_controller0 : entity work.avalon_st_spi_master
|
||||
port map(
|
||||
clk => clk,
|
||||
reset => reset,
|
||||
spi_cs_n => spi_cs_n,
|
||||
mosi_sink_data => spi_mosi_data,
|
||||
mosi_sink_valid => spi_mosi_valid,
|
||||
mosi_sink_ready => spi_mosi_ready,
|
||||
miso_src_data => spi_miso_data,
|
||||
miso_src_valid => spi_miso_valid,
|
||||
SCLK => SCLK,
|
||||
MISO => MISO,
|
||||
MOSI => MOSI,
|
||||
CS_n => CSn
|
||||
);
|
||||
|
||||
lepton_manager0 : entity work.lepton_manager
|
||||
port map(
|
||||
clk => clk,
|
||||
reset => reset,
|
||||
spi_miso_sink_data => spi_miso_data,
|
||||
spi_miso_sink_valid => spi_miso_valid,
|
||||
spi_mosi_src_data => spi_mosi_data,
|
||||
spi_mosi_src_valid => spi_mosi_valid,
|
||||
spi_mosi_src_ready => spi_mosi_ready,
|
||||
lepton_out_data => byte_data,
|
||||
lepton_out_valid => byte_valid,
|
||||
lepton_out_sof => byte_sof,
|
||||
lepton_out_eof => byte_eof,
|
||||
row_idx => row_idx,
|
||||
error => lepton_manager_error,
|
||||
start => lepton_manager_start,
|
||||
spi_cs_n => spi_cs_n
|
||||
);
|
||||
|
||||
byte2pix0 : entity work.byte2pix
|
||||
port map(
|
||||
clk => clk,
|
||||
reset => reset,
|
||||
byte_data => byte_data,
|
||||
byte_valid => byte_valid,
|
||||
byte_sof => byte_sof,
|
||||
byte_eof => byte_eof,
|
||||
pix_data => pix_data,
|
||||
pix_valid => pix_valid,
|
||||
pix_sof => pix_sof,
|
||||
pix_eof => pix_eof
|
||||
);
|
||||
|
||||
lepton_stats0 : entity work.lepton_stats
|
||||
port map(
|
||||
reset => reset,
|
||||
clk => clk,
|
||||
pix_data => pix_data,
|
||||
pix_valid => pix_valid,
|
||||
pix_sof => pix_sof,
|
||||
pix_eof => pix_eof,
|
||||
stat_min => stat_min,
|
||||
stat_max => stat_max,
|
||||
stat_sum => stat_sum,
|
||||
stat_valid => stat_valid
|
||||
);
|
||||
|
||||
ram_writer0 : entity work.ram_writer
|
||||
port map(
|
||||
clk => clk,
|
||||
reset => reset,
|
||||
pix_data => pix_data,
|
||||
pix_valid => pix_valid,
|
||||
pix_sof => pix_sof,
|
||||
pix_eof => pix_eof,
|
||||
ram_data => ram_data,
|
||||
ram_wren => ram_wren,
|
||||
ram_wraddress => ram_wraddress
|
||||
);
|
||||
|
||||
dual_ported_ram0 : entity work.dual_ported_ram
|
||||
port map(
|
||||
clock => clk,
|
||||
data => ram_data,
|
||||
rdaddress => ram_rdaddress,
|
||||
wraddress => ram_wraddress,
|
||||
wren => ram_wren,
|
||||
q => ram_q
|
||||
);
|
||||
|
||||
level_adjuster0 : entity work.level_adjuster
|
||||
port map(
|
||||
clk => clk,
|
||||
raw_pixel => ram_q(13 downto 0),
|
||||
raw_max => max_reg,
|
||||
raw_min => min_reg,
|
||||
raw_sum => sum_reg,
|
||||
adjusted_pixel => adjusted_pixel
|
||||
);
|
||||
|
||||
p_lepton_start : process(clk, reset)
|
||||
begin
|
||||
if reset = '1' then
|
||||
lepton_manager_start <= '0';
|
||||
error_reg <= '0';
|
||||
elsif rising_edge(clk) then
|
||||
if write = '1' and address = COMMAND_REG_OFFSET then
|
||||
lepton_manager_start <= writedata(0);
|
||||
error_reg <= '0';
|
||||
elsif pix_eof = '1' then
|
||||
lepton_manager_start <= '0';
|
||||
elsif lepton_manager_error = '1' then
|
||||
error_reg <= '1';
|
||||
end if;
|
||||
end if;
|
||||
end process p_lepton_start;
|
||||
|
||||
p_stat_reg : process(clk, reset)
|
||||
begin
|
||||
if reset = '1' then
|
||||
min_reg <= (others => '0');
|
||||
max_reg <= (others => '0');
|
||||
sum_reg <= (others => '0');
|
||||
elsif rising_edge(clk) then
|
||||
if stat_valid = '1' then
|
||||
min_reg <= stat_min;
|
||||
max_reg <= stat_max;
|
||||
sum_reg <= stat_sum;
|
||||
end if;
|
||||
end if;
|
||||
end process p_stat_reg;
|
||||
|
||||
p_read : process(clk, reset)
|
||||
begin
|
||||
if reset = '1' then
|
||||
readdata <= (others => '0');
|
||||
ram_rdaddress <= (others => '0');
|
||||
elsif rising_edge(clk) then
|
||||
readdata <= (others => '0');
|
||||
if read = '1' then
|
||||
case address is
|
||||
when STATUS_REG_OFFSET =>
|
||||
readdata(1) <= error_reg;
|
||||
readdata(0) <= lepton_manager_start;
|
||||
|
||||
when MIN_REG_OFFSET =>
|
||||
readdata <= "00" & min_reg;
|
||||
|
||||
when MAX_REG_OFFSET =>
|
||||
readdata <= "00" & max_reg;
|
||||
|
||||
when SUM_MSB_REG_OFFSET =>
|
||||
readdata <= "00000" & sum_reg(26 downto 16);
|
||||
|
||||
when SUM_LSB_REG_OFFSET =>
|
||||
readdata <= sum_reg(15 downto 0);
|
||||
|
||||
when ROW_IDX_REG_OFFSET =>
|
||||
readdata(5 downto 0) <= row_idx;
|
||||
|
||||
when others =>
|
||||
if unsigned(address) >= BUFFER_REG_OFFSET and unsigned(address) < BUFFER_REG_LIMIT then
|
||||
ram_rdaddress <= std_logic_vector(resize(unsigned(address) - BUFFER_REG_OFFSET, ram_rdaddress'length));
|
||||
readdata <= ram_q;
|
||||
elsif unsigned(address) >= ADJUSTED_BUFFER_REG_OFFSET and unsigned(address) < ADJUSTED_BUFFER_LIMIT then
|
||||
ram_rdaddress <= std_logic_vector(resize(unsigned(address) - ADJUSTED_BUFFER_REG_OFFSET, ram_rdaddress'length));
|
||||
readdata <= "00" & adjusted_pixel;
|
||||
end if;
|
||||
end case;
|
||||
end if;
|
||||
end if;
|
||||
end process p_read;
|
||||
|
||||
end rtl;
|
148
cs309-psoc/lab_4_0/hw/hdl/lepton/hdl/lepton_hw.tcl
Normal file
148
cs309-psoc/lab_4_0/hw/hdl/lepton/hdl/lepton_hw.tcl
Normal file
@ -0,0 +1,148 @@
|
||||
# TCL File Generated by Component Editor 16.0
|
||||
# Sun Feb 05 19:05:24 CET 2017
|
||||
# DO NOT MODIFY
|
||||
|
||||
|
||||
#
|
||||
# lepton "lepton" v1.0
|
||||
# Philemon Favrod & Sahand Kashani-Akhavan 2017.02.05.19:05:24
|
||||
# IR Camera 80x60
|
||||
#
|
||||
|
||||
#
|
||||
# request TCL package from ACDS 16.0
|
||||
#
|
||||
package require -exact qsys 16.0
|
||||
|
||||
|
||||
#
|
||||
# module lepton
|
||||
#
|
||||
set_module_property DESCRIPTION "IR Camera 80x60"
|
||||
set_module_property NAME lepton
|
||||
set_module_property VERSION 1.0
|
||||
set_module_property INTERNAL false
|
||||
set_module_property OPAQUE_ADDRESS_MAP true
|
||||
set_module_property GROUP Camera
|
||||
set_module_property AUTHOR "Philemon Favrod & Sahand Kashani-Akhavan"
|
||||
set_module_property DISPLAY_NAME lepton
|
||||
set_module_property INSTANTIATE_IN_SYSTEM_MODULE true
|
||||
set_module_property EDITABLE true
|
||||
set_module_property REPORT_TO_TALKBACK false
|
||||
set_module_property ALLOW_GREYBOX_GENERATION false
|
||||
set_module_property REPORT_HIERARCHY false
|
||||
|
||||
|
||||
#
|
||||
# file sets
|
||||
#
|
||||
add_fileset QUARTUS_SYNTH QUARTUS_SYNTH "" ""
|
||||
set_fileset_property QUARTUS_SYNTH TOP_LEVEL lepton
|
||||
set_fileset_property QUARTUS_SYNTH ENABLE_RELATIVE_INCLUDE_PATHS false
|
||||
set_fileset_property QUARTUS_SYNTH ENABLE_FILE_OVERWRITE_MODE false
|
||||
add_fileset_file avalon_st_spi_master.vhd VHDL PATH avalon_st_spi_master.vhd
|
||||
add_fileset_file byte2pix.vhd VHDL PATH byte2pix.vhd
|
||||
add_fileset_file dual_ported_ram.vhd VHDL PATH dual_ported_ram.vhd
|
||||
add_fileset_file lepton.vhd VHDL PATH lepton.vhd TOP_LEVEL_FILE
|
||||
add_fileset_file lepton_manager.vhd VHDL PATH lepton_manager.vhd
|
||||
add_fileset_file lepton_stats.vhd VHDL PATH lepton_stats.vhd
|
||||
add_fileset_file ram_writer.vhd VHDL PATH ram_writer.vhd
|
||||
add_fileset_file utils.vhd VHDL PATH utils.vhd
|
||||
add_fileset_file level_adjuster.vhd VHDL PATH level_adjuster.vhd
|
||||
add_fileset_file lpm_divider.vhd VHDL PATH lpm_divider.vhd
|
||||
|
||||
|
||||
#
|
||||
# parameters
|
||||
#
|
||||
|
||||
|
||||
#
|
||||
# display items
|
||||
#
|
||||
|
||||
|
||||
#
|
||||
# connection point clock
|
||||
#
|
||||
add_interface clock clock end
|
||||
set_interface_property clock clockRate 0
|
||||
set_interface_property clock ENABLED true
|
||||
set_interface_property clock EXPORT_OF ""
|
||||
set_interface_property clock PORT_NAME_MAP ""
|
||||
set_interface_property clock CMSIS_SVD_VARIABLES ""
|
||||
set_interface_property clock SVD_ADDRESS_GROUP ""
|
||||
|
||||
add_interface_port clock clk clk Input 1
|
||||
|
||||
|
||||
#
|
||||
# connection point reset
|
||||
#
|
||||
add_interface reset reset end
|
||||
set_interface_property reset associatedClock clock
|
||||
set_interface_property reset synchronousEdges DEASSERT
|
||||
set_interface_property reset ENABLED true
|
||||
set_interface_property reset EXPORT_OF ""
|
||||
set_interface_property reset PORT_NAME_MAP ""
|
||||
set_interface_property reset CMSIS_SVD_VARIABLES ""
|
||||
set_interface_property reset SVD_ADDRESS_GROUP ""
|
||||
|
||||
add_interface_port reset reset reset Input 1
|
||||
|
||||
|
||||
#
|
||||
# connection point avalon_slave_0
|
||||
#
|
||||
add_interface avalon_slave_0 avalon end
|
||||
set_interface_property avalon_slave_0 addressUnits WORDS
|
||||
set_interface_property avalon_slave_0 associatedClock clock
|
||||
set_interface_property avalon_slave_0 associatedReset reset
|
||||
set_interface_property avalon_slave_0 bitsPerSymbol 8
|
||||
set_interface_property avalon_slave_0 burstOnBurstBoundariesOnly false
|
||||
set_interface_property avalon_slave_0 burstcountUnits WORDS
|
||||
set_interface_property avalon_slave_0 explicitAddressSpan 0
|
||||
set_interface_property avalon_slave_0 holdTime 0
|
||||
set_interface_property avalon_slave_0 linewrapBursts false
|
||||
set_interface_property avalon_slave_0 maximumPendingReadTransactions 0
|
||||
set_interface_property avalon_slave_0 maximumPendingWriteTransactions 0
|
||||
set_interface_property avalon_slave_0 readLatency 0
|
||||
set_interface_property avalon_slave_0 readWaitStates 9
|
||||
set_interface_property avalon_slave_0 readWaitTime 9
|
||||
set_interface_property avalon_slave_0 setupTime 0
|
||||
set_interface_property avalon_slave_0 timingUnits Cycles
|
||||
set_interface_property avalon_slave_0 writeWaitTime 0
|
||||
set_interface_property avalon_slave_0 ENABLED true
|
||||
set_interface_property avalon_slave_0 EXPORT_OF ""
|
||||
set_interface_property avalon_slave_0 PORT_NAME_MAP ""
|
||||
set_interface_property avalon_slave_0 CMSIS_SVD_VARIABLES ""
|
||||
set_interface_property avalon_slave_0 SVD_ADDRESS_GROUP ""
|
||||
|
||||
add_interface_port avalon_slave_0 address address Input 14
|
||||
add_interface_port avalon_slave_0 readdata readdata Output 16
|
||||
add_interface_port avalon_slave_0 writedata writedata Input 16
|
||||
add_interface_port avalon_slave_0 read read Input 1
|
||||
add_interface_port avalon_slave_0 write write Input 1
|
||||
set_interface_assignment avalon_slave_0 embeddedsw.configuration.isFlash 0
|
||||
set_interface_assignment avalon_slave_0 embeddedsw.configuration.isMemoryDevice 0
|
||||
set_interface_assignment avalon_slave_0 embeddedsw.configuration.isNonVolatileStorage 0
|
||||
set_interface_assignment avalon_slave_0 embeddedsw.configuration.isPrintableDevice 0
|
||||
|
||||
|
||||
#
|
||||
# connection point spi
|
||||
#
|
||||
add_interface spi conduit end
|
||||
set_interface_property spi associatedClock clock
|
||||
set_interface_property spi associatedReset ""
|
||||
set_interface_property spi ENABLED true
|
||||
set_interface_property spi EXPORT_OF ""
|
||||
set_interface_property spi PORT_NAME_MAP ""
|
||||
set_interface_property spi CMSIS_SVD_VARIABLES ""
|
||||
set_interface_property spi SVD_ADDRESS_GROUP ""
|
||||
|
||||
add_interface_port spi CSn cs_n Output 1
|
||||
add_interface_port spi MISO miso Input 1
|
||||
add_interface_port spi MOSI mosi Output 1
|
||||
add_interface_port spi SCLK sclk Output 1
|
||||
|
235
cs309-psoc/lab_4_0/hw/hdl/lepton/hdl/lepton_manager.vhd
Normal file
235
cs309-psoc/lab_4_0/hw/hdl/lepton/hdl/lepton_manager.vhd
Normal file
@ -0,0 +1,235 @@
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
entity lepton_manager is
|
||||
generic(
|
||||
INPUT_CLK_FREQ : integer := 50000000);
|
||||
port(
|
||||
clk : in std_logic := '0';
|
||||
reset : in std_logic := '0';
|
||||
|
||||
-- Avalon ST Sink to receive SPI data
|
||||
spi_miso_sink_data : in std_logic_vector(7 downto 0);
|
||||
spi_miso_sink_valid : in std_logic;
|
||||
|
||||
-- Avalon ST Source to send SPI data
|
||||
spi_mosi_src_data : out std_logic_vector(7 downto 0);
|
||||
spi_mosi_src_valid : out std_logic;
|
||||
spi_mosi_src_ready : in std_logic := '0';
|
||||
|
||||
-- Filtered output to retransmit cleaned data (without the discard packets, see Lepton Datasheet on page 31)
|
||||
-- lepton_out_data is valid on rising edge when lepton_src_valid = '1'
|
||||
lepton_out_data : out std_logic_vector(7 downto 0);
|
||||
lepton_out_valid : out std_logic;
|
||||
lepton_out_sof : out std_logic;
|
||||
lepton_out_eof : out std_logic;
|
||||
|
||||
-- Some status
|
||||
row_idx : out std_logic_vector(5 downto 0);
|
||||
error : out std_logic;
|
||||
|
||||
-- Avalon MM Slave interface for configuration
|
||||
start : in std_logic;
|
||||
|
||||
-- The SPI Chip Select (Active low !)
|
||||
spi_cs_n : out std_logic := '0');
|
||||
end entity lepton_manager;
|
||||
|
||||
architecture rtl of lepton_manager is
|
||||
type state_t is (Idle, CSn, ReadHeader, ReadPayload, DiscardPayload, WaitBeforeIdle);
|
||||
signal state, next_state : state_t;
|
||||
|
||||
signal header_3_last_nibbles : std_logic_vector(11 downto 0);
|
||||
|
||||
constant CLOCK_TICKS_PER_37_MS : integer := 37 * (INPUT_CLK_FREQ / 1e3); -- the timeout delay for a frame
|
||||
constant CLOCK_TICKS_PER_200_MS : integer := 200 * (INPUT_CLK_FREQ / 1e3);
|
||||
constant CLOCK_TICKS_PER_200_NS : integer := (200 * (INPUT_CLK_FREQ / 1e6)) / 1e3;
|
||||
constant BYTES_PER_HEADER : integer := 4;
|
||||
constant BYTES_PER_PAYLOAD : integer := 160;
|
||||
|
||||
constant NUMBER_OF_LINES_PER_FRAME : positive := 60;
|
||||
signal counter, counter_max : integer range 1 to CLOCK_TICKS_PER_200_MS;
|
||||
signal line_counter : integer range 1 to NUMBER_OF_LINES_PER_FRAME;
|
||||
signal timeout_counter : integer range 1 to CLOCK_TICKS_PER_37_MS;
|
||||
signal counter_enabled : boolean;
|
||||
signal waited_long_enough : boolean;
|
||||
signal header_end, payload_end : boolean;
|
||||
begin
|
||||
|
||||
-- purpose: register for state
|
||||
p_fsm : process(clk, reset)
|
||||
begin
|
||||
if reset = '1' then
|
||||
state <= Idle;
|
||||
elsif rising_edge(clk) then
|
||||
state <= next_state;
|
||||
end if;
|
||||
end process p_fsm;
|
||||
|
||||
-- purpose: compute the next state
|
||||
p_nsl : process(header_3_last_nibbles, header_end, payload_end, start, spi_miso_sink_valid, state, waited_long_enough, line_counter)
|
||||
begin
|
||||
next_state <= state;
|
||||
|
||||
case state is
|
||||
when Idle =>
|
||||
if waited_long_enough and start = '1' then
|
||||
next_state <= CSn;
|
||||
end if;
|
||||
|
||||
when CSn =>
|
||||
if waited_long_enough then
|
||||
next_state <= ReadHeader;
|
||||
end if;
|
||||
|
||||
when ReadHeader =>
|
||||
if header_end then
|
||||
if header_3_last_nibbles(11 downto 8) = X"F" then
|
||||
next_state <= DiscardPayload;
|
||||
else
|
||||
next_state <= ReadPayload;
|
||||
end if;
|
||||
end if;
|
||||
|
||||
when DiscardPayload | ReadPayload =>
|
||||
if payload_end then
|
||||
next_state <= ReadHeader;
|
||||
|
||||
if line_counter = NUMBER_OF_LINES_PER_FRAME then
|
||||
next_state <= WaitBeforeIdle;
|
||||
end if;
|
||||
end if;
|
||||
|
||||
when WaitBeforeIdle =>
|
||||
if spi_miso_sink_valid = '1' then
|
||||
next_state <= Idle;
|
||||
end if;
|
||||
|
||||
end case;
|
||||
end process p_nsl;
|
||||
|
||||
p_counter : process(clk, reset)
|
||||
begin
|
||||
if reset = '1' then
|
||||
counter <= 1;
|
||||
line_counter <= 1;
|
||||
elsif rising_edge(clk) then
|
||||
if counter = counter_max and counter_enabled then
|
||||
counter <= 1;
|
||||
|
||||
if state = ReadPayload then
|
||||
if line_counter = NUMBER_OF_LINES_PER_FRAME then
|
||||
line_counter <= 1;
|
||||
else
|
||||
line_counter <= line_counter + 1;
|
||||
end if;
|
||||
end if;
|
||||
|
||||
elsif counter_enabled then
|
||||
counter <= counter + 1;
|
||||
end if;
|
||||
end if;
|
||||
end process p_counter;
|
||||
|
||||
p_error : process(clk, reset)
|
||||
begin
|
||||
if reset = '1' then
|
||||
error <= '0';
|
||||
timeout_counter <= 1;
|
||||
elsif rising_edge(clk) then
|
||||
if state /= ReadHeader and state /= ReadPayload and state /= ReadHeader then
|
||||
timeout_counter <= 1;
|
||||
error <= '0';
|
||||
else
|
||||
if timeout_counter = CLOCK_TICKS_PER_37_MS then
|
||||
error <= '1';
|
||||
else
|
||||
timeout_counter <= timeout_counter + 1;
|
||||
end if;
|
||||
end if;
|
||||
if state = ReadPayload and header_3_last_nibbles /= std_logic_vector(to_unsigned(line_counter - 1, header_3_last_nibbles'length)) then
|
||||
error <= '1';
|
||||
end if;
|
||||
end if;
|
||||
end process p_error;
|
||||
|
||||
-- purpose: wire the datapath
|
||||
p_datapath : process(counter, counter_enabled, counter_max, line_counter, spi_miso_sink_data, spi_miso_sink_valid, spi_mosi_src_ready, state)
|
||||
variable counter_ended : boolean;
|
||||
|
||||
begin
|
||||
counter_max <= 1;
|
||||
counter_enabled <= true;
|
||||
waited_long_enough <= false;
|
||||
lepton_out_data <= (others => '0');
|
||||
lepton_out_valid <= '0';
|
||||
lepton_out_sof <= '0';
|
||||
lepton_out_eof <= '0';
|
||||
spi_mosi_src_valid <= '0';
|
||||
spi_mosi_src_data <= (others => '0');
|
||||
spi_cs_n <= '0';
|
||||
header_end <= false;
|
||||
payload_end <= false;
|
||||
|
||||
counter_ended := (counter = counter_max and counter_enabled);
|
||||
|
||||
case state is
|
||||
when Idle =>
|
||||
counter_max <= CLOCK_TICKS_PER_200_MS;
|
||||
waited_long_enough <= counter_ended;
|
||||
spi_cs_n <= '1';
|
||||
|
||||
when CSn =>
|
||||
counter_max <= CLOCK_TICKS_PER_200_NS;
|
||||
waited_long_enough <= counter_ended;
|
||||
|
||||
when ReadHeader =>
|
||||
counter_max <= BYTES_PER_HEADER;
|
||||
counter_enabled <= spi_miso_sink_valid = '1';
|
||||
header_end <= counter_ended;
|
||||
spi_mosi_src_valid <= spi_mosi_src_ready;
|
||||
|
||||
when ReadPayload =>
|
||||
counter_max <= BYTES_PER_PAYLOAD;
|
||||
counter_enabled <= spi_miso_sink_valid = '1';
|
||||
lepton_out_data <= spi_miso_sink_data;
|
||||
lepton_out_valid <= spi_miso_sink_valid;
|
||||
payload_end <= counter_ended;
|
||||
spi_mosi_src_valid <= spi_mosi_src_ready;
|
||||
if spi_miso_sink_valid = '1' then
|
||||
if counter = 1 and counter_enabled and line_counter = 1 then
|
||||
lepton_out_sof <= '1';
|
||||
elsif counter_ended and line_counter = NUMBER_OF_LINES_PER_FRAME then
|
||||
lepton_out_eof <= '1';
|
||||
end if;
|
||||
end if;
|
||||
|
||||
when DiscardPayload =>
|
||||
counter_max <= BYTES_PER_PAYLOAD;
|
||||
counter_enabled <= spi_miso_sink_valid = '1';
|
||||
payload_end <= counter_ended;
|
||||
spi_mosi_src_valid <= spi_mosi_src_ready;
|
||||
|
||||
when others => null;
|
||||
end case;
|
||||
end process p_datapath;
|
||||
|
||||
p_capture_header : process(clk, reset)
|
||||
begin
|
||||
if reset = '1' then
|
||||
header_3_last_nibbles <= X"000";
|
||||
elsif rising_edge(clk) then
|
||||
if state = ReadHeader and spi_miso_sink_valid = '1' then
|
||||
if counter = 1 then
|
||||
header_3_last_nibbles(11 downto 8) <= spi_miso_sink_data(3 downto 0);
|
||||
elsif counter = 2 then
|
||||
header_3_last_nibbles(7 downto 0) <= spi_miso_sink_data;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process p_capture_header;
|
||||
|
||||
row_idx <= std_logic_vector(to_unsigned(line_counter, row_idx'length));
|
||||
|
||||
end architecture rtl;
|
78
cs309-psoc/lab_4_0/hw/hdl/lepton/hdl/lepton_stats.vhd
Normal file
78
cs309-psoc/lab_4_0/hw/hdl/lepton/hdl/lepton_stats.vhd
Normal file
@ -0,0 +1,78 @@
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
entity lepton_stats is
|
||||
port(
|
||||
clk : in std_logic;
|
||||
reset : in std_logic;
|
||||
pix_data : in std_logic_vector(13 downto 0);
|
||||
pix_valid : in std_logic;
|
||||
pix_sof : in std_logic;
|
||||
pix_eof : in std_logic;
|
||||
stat_min : out std_logic_vector(13 downto 0);
|
||||
stat_max : out std_logic_vector(13 downto 0);
|
||||
stat_sum : out std_logic_vector(26 downto 0);
|
||||
stat_valid : out std_logic);
|
||||
end lepton_stats;
|
||||
|
||||
architecture rtl of lepton_stats is
|
||||
|
||||
-- The accumulated sum, min and max of the pixel values
|
||||
signal curr_min : unsigned(13 downto 0);
|
||||
signal curr_max : unsigned(13 downto 0);
|
||||
signal curr_sum : unsigned(26 downto 0);
|
||||
|
||||
-- The next value of the registers
|
||||
signal next_min : unsigned(13 downto 0);
|
||||
signal next_max : unsigned(13 downto 0);
|
||||
signal next_sum : unsigned(26 downto 0);
|
||||
|
||||
begin
|
||||
|
||||
-- This is the synchronous transition logic
|
||||
transition_logic : process(clk, reset)
|
||||
begin
|
||||
if reset = '1' then
|
||||
curr_sum <= (others => '0');
|
||||
curr_min <= (others => '0');
|
||||
curr_max <= (others => '0');
|
||||
elsif rising_edge(clk) then
|
||||
curr_min <= next_min;
|
||||
curr_max <= next_max;
|
||||
curr_sum <= next_sum;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
-- This is the combinatorial transition logic
|
||||
next_min <=
|
||||
curr_min when pix_valid = '0' else
|
||||
unsigned(pix_data) when pix_sof = '1' else
|
||||
curr_min when unsigned(pix_data) >= curr_min else
|
||||
unsigned(pix_data);
|
||||
|
||||
next_max <=
|
||||
curr_max when pix_valid = '0' else
|
||||
unsigned(pix_data) when pix_sof = '1' else
|
||||
curr_max when unsigned(pix_data) <= curr_max else
|
||||
unsigned(pix_data);
|
||||
|
||||
next_sum <=
|
||||
curr_sum when pix_valid = '0' else
|
||||
unsigned((26 downto 14 => '0') & pix_data) when pix_sof = '1' else
|
||||
curr_sum + unsigned((26 downto 14 => '0') & pix_data);
|
||||
|
||||
-- This is the synchronous output logic
|
||||
output_logic : process(clk, reset)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
stat_valid <= pix_eof;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
-- This is the combinatorial output logic
|
||||
stat_min <= std_logic_vector(curr_min);
|
||||
stat_max <= std_logic_vector(curr_max);
|
||||
stat_sum <= std_logic_vector(curr_sum);
|
||||
|
||||
end rtl;
|
50
cs309-psoc/lab_4_0/hw/hdl/lepton/hdl/level_adjuster.vhd
Normal file
50
cs309-psoc/lab_4_0/hw/hdl/lepton/hdl/level_adjuster.vhd
Normal file
@ -0,0 +1,50 @@
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
entity level_adjuster is
|
||||
port(
|
||||
clk : in std_logic;
|
||||
raw_pixel : in std_logic_vector(13 downto 0);
|
||||
raw_max : in std_logic_vector(13 downto 0);
|
||||
raw_min : in std_logic_vector(13 downto 0);
|
||||
raw_sum : in std_logic_vector(26 downto 0);
|
||||
adjusted_pixel : out std_logic_vector(13 downto 0));
|
||||
end level_adjuster;
|
||||
|
||||
architecture rtl of level_adjuster is
|
||||
component lpm_divider
|
||||
port(
|
||||
clock : in std_logic;
|
||||
denom : in std_logic_vector(13 downto 0);
|
||||
numer : in std_logic_vector(27 downto 0);
|
||||
quotient : out std_logic_vector(27 downto 0);
|
||||
remain : out std_logic_vector(13 downto 0));
|
||||
end component;
|
||||
|
||||
-- Intermediate signals needed by the divider
|
||||
signal numer : std_logic_vector(27 downto 0);
|
||||
signal denom : std_logic_vector(13 downto 0);
|
||||
signal quot : std_logic_vector(27 downto 0);
|
||||
|
||||
begin
|
||||
|
||||
-- Computation of the intermediate signals
|
||||
numer <= std_logic_vector((13 downto 0 => '1') * (unsigned(raw_pixel) - unsigned(raw_min)));
|
||||
denom <= std_logic_vector(unsigned(raw_max) - unsigned(raw_min));
|
||||
|
||||
-- We compute the remaineder of (x - min) / (max - min)
|
||||
divider : lpm_divider port map(
|
||||
clock => clk,
|
||||
numer => numer,
|
||||
denom => denom,
|
||||
quotient => quot,
|
||||
remain => open
|
||||
);
|
||||
|
||||
-- And we only keep the LSB of the quotient (we know the MSB must be 0)
|
||||
adjusted_pixel <=
|
||||
(adjusted_pixel'range => '0') when denom = (denom'range => '0') else
|
||||
quot(13 downto 0);
|
||||
|
||||
end rtl;
|
133
cs309-psoc/lab_4_0/hw/hdl/lepton/hdl/lpm_divider.vhd
Normal file
133
cs309-psoc/lab_4_0/hw/hdl/lepton/hdl/lpm_divider.vhd
Normal file
@ -0,0 +1,133 @@
|
||||
-- megafunction wizard: %LPM_DIVIDE%
|
||||
-- GENERATION: STANDARD
|
||||
-- VERSION: WM1.0
|
||||
-- MODULE: LPM_DIVIDE
|
||||
|
||||
-- ============================================================
|
||||
-- File Name: lpm_divider.vhd
|
||||
-- Megafunction Name(s):
|
||||
-- LPM_DIVIDE
|
||||
--
|
||||
-- Simulation Library Files(s):
|
||||
-- lpm
|
||||
-- ============================================================
|
||||
-- ************************************************************
|
||||
-- THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE!
|
||||
--
|
||||
-- 15.1.0 Build 185 10/21/2015 SJ Lite Edition
|
||||
-- ************************************************************
|
||||
|
||||
|
||||
--Copyright (C) 1991-2015 Altera Corporation. All rights reserved.
|
||||
--Your use of Altera Corporation's design tools, logic functions
|
||||
--and other software and tools, and its AMPP partner logic
|
||||
--functions, and any output files from any of the foregoing
|
||||
--(including device programming or simulation files), and any
|
||||
--associated documentation or information are expressly subject
|
||||
--to the terms and conditions of the Altera Program License
|
||||
--Subscription Agreement, the Altera Quartus Prime License Agreement,
|
||||
--the Altera MegaCore Function License Agreement, or other
|
||||
--applicable license agreement, including, without limitation,
|
||||
--that your use is for the sole purpose of programming logic
|
||||
--devices manufactured by Altera and sold by Altera or its
|
||||
--authorized distributors. Please refer to the applicable
|
||||
--agreement for further details.
|
||||
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
|
||||
library lpm;
|
||||
use lpm.all;
|
||||
|
||||
entity lpm_divider is
|
||||
port(
|
||||
clock : in std_logic;
|
||||
denom : in std_logic_vector(13 downto 0);
|
||||
numer : in std_logic_vector(27 downto 0);
|
||||
quotient : out std_logic_vector(27 downto 0);
|
||||
remain : out std_logic_vector(13 downto 0)
|
||||
);
|
||||
end lpm_divider;
|
||||
|
||||
architecture SYN of lpm_divider is
|
||||
signal sub_wire0 : std_logic_vector(27 downto 0);
|
||||
signal sub_wire1 : std_logic_vector(13 downto 0);
|
||||
|
||||
component lpm_divide
|
||||
generic(
|
||||
lpm_drepresentation : string;
|
||||
lpm_hint : string;
|
||||
lpm_nrepresentation : string;
|
||||
lpm_pipeline : natural;
|
||||
lpm_type : string;
|
||||
lpm_widthd : natural;
|
||||
lpm_widthn : natural
|
||||
);
|
||||
port(
|
||||
clock : in std_logic;
|
||||
denom : in std_logic_vector(13 downto 0);
|
||||
numer : in std_logic_vector(27 downto 0);
|
||||
quotient : out std_logic_vector(27 downto 0);
|
||||
remain : out std_logic_vector(13 downto 0)
|
||||
);
|
||||
end component;
|
||||
|
||||
begin
|
||||
quotient <= sub_wire0(27 downto 0);
|
||||
remain <= sub_wire1(13 downto 0);
|
||||
|
||||
LPM_DIVIDE_component : LPM_DIVIDE
|
||||
generic map(
|
||||
lpm_drepresentation => "UNSIGNED",
|
||||
lpm_hint => "LPM_REMAINDERPOSITIVE=TRUE",
|
||||
lpm_nrepresentation => "UNSIGNED",
|
||||
lpm_pipeline => 5,
|
||||
lpm_type => "LPM_DIVIDE",
|
||||
lpm_widthd => 14,
|
||||
lpm_widthn => 28
|
||||
)
|
||||
port map(
|
||||
clock => clock,
|
||||
denom => denom,
|
||||
numer => numer,
|
||||
quotient => sub_wire0,
|
||||
remain => sub_wire1
|
||||
);
|
||||
|
||||
end SYN;
|
||||
|
||||
-- ============================================================
|
||||
-- CNX file retrieval info
|
||||
-- ============================================================
|
||||
-- Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "Cyclone V"
|
||||
-- Retrieval info: PRIVATE: PRIVATE_LPM_REMAINDERPOSITIVE STRING "TRUE"
|
||||
-- Retrieval info: PRIVATE: PRIVATE_MAXIMIZE_SPEED NUMERIC "-1"
|
||||
-- Retrieval info: PRIVATE: SYNTH_WRAPPER_GEN_POSTFIX STRING "0"
|
||||
-- Retrieval info: PRIVATE: USING_PIPELINE NUMERIC "1"
|
||||
-- Retrieval info: PRIVATE: VERSION_NUMBER NUMERIC "2"
|
||||
-- Retrieval info: PRIVATE: new_diagram STRING "1"
|
||||
-- Retrieval info: LIBRARY: lpm lpm.lpm_components.all
|
||||
-- Retrieval info: CONSTANT: LPM_DREPRESENTATION STRING "UNSIGNED"
|
||||
-- Retrieval info: CONSTANT: LPM_HINT STRING "LPM_REMAINDERPOSITIVE=TRUE"
|
||||
-- Retrieval info: CONSTANT: LPM_NREPRESENTATION STRING "UNSIGNED"
|
||||
-- Retrieval info: CONSTANT: LPM_PIPELINE NUMERIC "5"
|
||||
-- Retrieval info: CONSTANT: LPM_TYPE STRING "LPM_DIVIDE"
|
||||
-- Retrieval info: CONSTANT: LPM_WIDTHD NUMERIC "14"
|
||||
-- Retrieval info: CONSTANT: LPM_WIDTHN NUMERIC "28"
|
||||
-- Retrieval info: USED_PORT: clock 0 0 0 0 INPUT NODEFVAL "clock"
|
||||
-- Retrieval info: USED_PORT: denom 0 0 14 0 INPUT NODEFVAL "denom[13..0]"
|
||||
-- Retrieval info: USED_PORT: numer 0 0 28 0 INPUT NODEFVAL "numer[27..0]"
|
||||
-- Retrieval info: USED_PORT: quotient 0 0 28 0 OUTPUT NODEFVAL "quotient[27..0]"
|
||||
-- Retrieval info: USED_PORT: remain 0 0 14 0 OUTPUT NODEFVAL "remain[13..0]"
|
||||
-- Retrieval info: CONNECT: @clock 0 0 0 0 clock 0 0 0 0
|
||||
-- Retrieval info: CONNECT: @denom 0 0 14 0 denom 0 0 14 0
|
||||
-- Retrieval info: CONNECT: @numer 0 0 28 0 numer 0 0 28 0
|
||||
-- Retrieval info: CONNECT: quotient 0 0 28 0 @quotient 0 0 28 0
|
||||
-- Retrieval info: CONNECT: remain 0 0 14 0 @remain 0 0 14 0
|
||||
-- Retrieval info: GEN_FILE: TYPE_NORMAL lpm_divider.vhd TRUE
|
||||
-- Retrieval info: GEN_FILE: TYPE_NORMAL lpm_divider.inc FALSE
|
||||
-- Retrieval info: GEN_FILE: TYPE_NORMAL lpm_divider.cmp FALSE
|
||||
-- Retrieval info: GEN_FILE: TYPE_NORMAL lpm_divider.bsf FALSE
|
||||
-- Retrieval info: GEN_FILE: TYPE_NORMAL lpm_divider_inst.vhd FALSE
|
||||
-- Retrieval info: LIB_FILE: lpm
|
38
cs309-psoc/lab_4_0/hw/hdl/lepton/hdl/ram_writer.vhd
Normal file
38
cs309-psoc/lab_4_0/hw/hdl/lepton/hdl/ram_writer.vhd
Normal file
@ -0,0 +1,38 @@
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
entity ram_writer is
|
||||
port(
|
||||
clk, reset : in std_logic;
|
||||
pix_data : in std_logic_vector(13 downto 0);
|
||||
pix_valid : in std_logic;
|
||||
pix_sof : in std_logic;
|
||||
pix_eof : in std_logic;
|
||||
ram_data : out std_logic_vector(15 downto 0);
|
||||
ram_wren : out std_logic;
|
||||
ram_wraddress : out std_logic_vector(12 downto 0));
|
||||
|
||||
end ram_writer;
|
||||
|
||||
architecture rtl of ram_writer is
|
||||
signal wraddress_counter : unsigned(ram_wraddress'range);
|
||||
begin
|
||||
p_address_gen : process(clk, reset)
|
||||
begin
|
||||
if reset = '1' then
|
||||
wraddress_counter <= (others => '0');
|
||||
elsif rising_edge(clk) then
|
||||
if pix_eof = '1' then
|
||||
wraddress_counter <= (others => '0');
|
||||
elsif pix_valid = '1' then
|
||||
wraddress_counter <= wraddress_counter + 1;
|
||||
end if;
|
||||
end if;
|
||||
end process p_address_gen;
|
||||
|
||||
ram_data <= "00" & pix_data;
|
||||
ram_wren <= pix_valid;
|
||||
ram_wraddress <= std_logic_vector(wraddress_counter);
|
||||
|
||||
end rtl;
|
27
cs309-psoc/lab_4_0/hw/hdl/lepton/hdl/utils.vhd
Normal file
27
cs309-psoc/lab_4_0/hw/hdl/lepton/hdl/utils.vhd
Normal file
@ -0,0 +1,27 @@
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
package utils is
|
||||
function bitlength(number : positive) return positive;
|
||||
|
||||
end package utils;
|
||||
|
||||
package body utils is
|
||||
|
||||
-- purpose: returns the minimum # of bits needed to represent the input number
|
||||
function bitlength(number : positive) return positive is
|
||||
variable acc : positive := 1;
|
||||
variable i : natural := 0;
|
||||
begin
|
||||
while True loop
|
||||
if acc > number then
|
||||
return i;
|
||||
end if;
|
||||
|
||||
acc := acc * 2;
|
||||
i := i + 1;
|
||||
end loop;
|
||||
end function bitlength;
|
||||
|
||||
end package body utils;
|
77
cs309-psoc/lab_4_0/hw/hdl/lepton/tb/lepton_tb.vhd
Normal file
77
cs309-psoc/lab_4_0/hw/hdl/lepton/tb/lepton_tb.vhd
Normal file
@ -0,0 +1,77 @@
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
use ieee.math_real.all;
|
||||
|
||||
entity lepton_tb is
|
||||
end lepton_tb;
|
||||
|
||||
architecture tb of lepton_tb is
|
||||
signal clk : std_logic := '0';
|
||||
signal reset : std_logic := '0';
|
||||
signal address : std_logic_vector(13 downto 0) := (others => '0');
|
||||
signal readdata : std_logic_vector(15 downto 0) := (others => '0');
|
||||
signal writedata : std_logic_vector(15 downto 0) := (others => '0');
|
||||
signal read : std_logic := '0';
|
||||
signal write : std_logic := '0';
|
||||
signal SCLK : std_logic := '0';
|
||||
signal CSn : std_logic := '0';
|
||||
signal MOSI : std_logic := '0';
|
||||
signal MISO : std_logic := '1';
|
||||
|
||||
constant CLK_PERIOD : time := 20 ns;
|
||||
|
||||
signal sim_ended : boolean := false;
|
||||
|
||||
begin
|
||||
dut : entity work.lepton
|
||||
port map(
|
||||
clk => clk,
|
||||
reset => reset,
|
||||
address => address,
|
||||
readdata => readdata,
|
||||
writedata => writedata,
|
||||
read => read,
|
||||
write => write,
|
||||
SCLK => SCLK,
|
||||
CSn => CSn,
|
||||
MOSI => MOSI,
|
||||
MISO => MISO
|
||||
);
|
||||
|
||||
clk <= not clk after CLK_PERIOD / 2 when not sim_ended else '0';
|
||||
|
||||
miso_gen : process
|
||||
variable seed1, seed2 : positive;
|
||||
variable rand : real;
|
||||
begin
|
||||
if sim_ended then
|
||||
wait;
|
||||
else
|
||||
uniform(seed1, seed2, rand);
|
||||
wait until rising_edge(SCLK);
|
||||
MISO <= to_unsigned(integer(rand), 1)(0);
|
||||
|
||||
end if;
|
||||
end process;
|
||||
|
||||
stimuli : process
|
||||
begin
|
||||
reset <= '1';
|
||||
write <= '0';
|
||||
|
||||
wait for 2 * CLK_PERIOD;
|
||||
reset <= '0';
|
||||
|
||||
wait for CLK_PERIOD;
|
||||
write <= '1';
|
||||
writedata(0) <= '1';
|
||||
wait for CLK_PERIOD;
|
||||
write <= '0';
|
||||
|
||||
wait for 17 ms;
|
||||
sim_ended <= true;
|
||||
wait;
|
||||
end process;
|
||||
|
||||
end tb;
|
42
cs309-psoc/lab_4_0/hw/hdl/pantilt/hdl/pwm.vhd
Normal file
42
cs309-psoc/lab_4_0/hw/hdl/pantilt/hdl/pwm.vhd
Normal file
@ -0,0 +1,42 @@
|
||||
-- #############################################################################
|
||||
-- pwm.vhd
|
||||
-- =======
|
||||
-- PWM memory-mapped Avalon slave interface.
|
||||
--
|
||||
-- Author : <insert your name> (<insert your e-mail address>)
|
||||
-- Author : <insert your name> (<insert your e-mail address>)
|
||||
-- Revision : <insert revision>
|
||||
-- Last modified : <insert date>
|
||||
-- #############################################################################
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
use work.pwm_constants.all;
|
||||
|
||||
entity pwm is
|
||||
port(
|
||||
-- Avalon Clock interface
|
||||
clk : in std_logic;
|
||||
|
||||
-- Avalon Reset interface
|
||||
reset : in std_logic;
|
||||
|
||||
-- Avalon-MM Slave interface
|
||||
address : in std_logic_vector(1 downto 0);
|
||||
read : in std_logic;
|
||||
write : in std_logic;
|
||||
readdata : out std_logic_vector(31 downto 0);
|
||||
writedata : in std_logic_vector(31 downto 0);
|
||||
|
||||
-- Avalon Conduit interface
|
||||
pwm_out : out std_logic
|
||||
);
|
||||
end pwm;
|
||||
|
||||
architecture rtl of pwm is
|
||||
|
||||
begin
|
||||
|
||||
end architecture rtl;
|
61
cs309-psoc/lab_4_0/hw/hdl/pantilt/hdl/pwm_constants.vhd
Normal file
61
cs309-psoc/lab_4_0/hw/hdl/pantilt/hdl/pwm_constants.vhd
Normal file
@ -0,0 +1,61 @@
|
||||
-- #############################################################################
|
||||
-- pwm_constants.vhd
|
||||
-- =================
|
||||
-- This package contains constants used in the PWM design files.
|
||||
--
|
||||
-- Author : Sahand Kashani-Akhavan [sahand.kashani-akhavan@epfl.ch]
|
||||
-- Revision : 2
|
||||
-- Last modified : 2018-02-28
|
||||
-- #############################################################################
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
package pwm_constants is
|
||||
-- Register map
|
||||
-- +--------+------------+--------+------------------------------------------------------------------------------+
|
||||
-- | RegNo | Name | Access | Description |
|
||||
-- +--------+------------+--------+------------------------------------------------------------------------------+
|
||||
-- | 0 | PERIOD | R/W | Period in clock cycles [2 <= period <= (2**32) - 1]. |
|
||||
-- | | | | |
|
||||
-- | | | | This value can be read/written while the unit is in the middle of an ongoing |
|
||||
-- | | | | PWM pulse. To allow safe behaviour, one cannot modify the period of an |
|
||||
-- | | | | ongoing pulse, so we adopt the following semantics for this register: |
|
||||
-- | | | | |
|
||||
-- | | | | >> WRITING a value in this register indicates the NEW period to apply to the |
|
||||
-- | | | | next pulse. |
|
||||
-- | | | | |
|
||||
-- | | | | >> READING a value from this register indicates the CURRENT period of the |
|
||||
-- | | | | ongoing pulse. |
|
||||
-- +--------+------------+--------+------------------------------------------------------------------------------+
|
||||
-- | 1 | DUTY_CYCLE | R/W | Duty cycle of the PWM [1 <= duty cycle <= period] |
|
||||
-- | | | | |
|
||||
-- | | | | This value can be read/written while the unit is in the middle of an ongoing |
|
||||
-- | | | | PWM pulse. To allow safe behaviour, one cannot modify the duty cycle of an |
|
||||
-- | | | | ongoing pulse, so we adopt the following semantics for this register: |
|
||||
-- | | | | |
|
||||
-- | | | | >> WRITING a value in this register indicates the NEW duty cycle to apply to |
|
||||
-- | | | | the next pulse. |
|
||||
-- | | | | |
|
||||
-- | | | | >> READING a value from this register indicates the CURRENT duty cycle of |
|
||||
-- | | | | the ongoing pulse. |
|
||||
-- +--------+------------+--------+------------------------------------------------------------------------------+
|
||||
-- | 2 | CTRL | WO | >> Writing 0 to this register stops the PWM once the ongoing pulse has ended.|
|
||||
-- | | | | Writing 1 to this register starts the PWM. |
|
||||
-- | | | | |
|
||||
-- | | | | >> Reading this register always returns 0. |
|
||||
-- +--------+------------+--------+------------------------------------------------------------------------------+
|
||||
constant REG_PERIOD_OFST : std_logic_vector(1 downto 0) := "00";
|
||||
constant REG_DUTY_CYCLE_OFST : std_logic_vector(1 downto 0) := "01";
|
||||
constant REG_CTRL_OFST : std_logic_vector(1 downto 0) := "10";
|
||||
|
||||
-- Default values of registers after reset (BEFORE writing START to the CTRL
|
||||
-- register with a new configuration)
|
||||
constant DEFAULT_PERIOD : natural := 4;
|
||||
constant DEFAULT_DUTY_CYCLE : natural := 2;
|
||||
end package pwm_constants;
|
||||
|
||||
package body pwm_constants is
|
||||
|
||||
end package body pwm_constants;
|
135
cs309-psoc/lab_4_0/hw/hdl/pantilt/hdl/pwm_hw.tcl
Normal file
135
cs309-psoc/lab_4_0/hw/hdl/pantilt/hdl/pwm_hw.tcl
Normal file
@ -0,0 +1,135 @@
|
||||
# TCL File Generated by Component Editor 16.0
|
||||
# Tue Feb 28 12:18:00 CET 2017
|
||||
# DO NOT MODIFY
|
||||
|
||||
|
||||
#
|
||||
# pwm "pwm" v1.0
|
||||
# 2017.02.28.12:18:00
|
||||
# Pan-tilt
|
||||
#
|
||||
|
||||
#
|
||||
# request TCL package from ACDS 16.0
|
||||
#
|
||||
package require -exact qsys 16.0
|
||||
|
||||
|
||||
#
|
||||
# module pwm
|
||||
#
|
||||
set_module_property DESCRIPTION Pan-tilt
|
||||
set_module_property NAME pwm
|
||||
set_module_property VERSION 1.0
|
||||
set_module_property INTERNAL false
|
||||
set_module_property OPAQUE_ADDRESS_MAP true
|
||||
set_module_property GROUP Pan-tilt
|
||||
set_module_property AUTHOR ""
|
||||
set_module_property DISPLAY_NAME pwm
|
||||
set_module_property INSTANTIATE_IN_SYSTEM_MODULE true
|
||||
set_module_property EDITABLE true
|
||||
set_module_property REPORT_TO_TALKBACK false
|
||||
set_module_property ALLOW_GREYBOX_GENERATION false
|
||||
set_module_property REPORT_HIERARCHY false
|
||||
|
||||
|
||||
#
|
||||
# file sets
|
||||
#
|
||||
add_fileset QUARTUS_SYNTH QUARTUS_SYNTH "" ""
|
||||
set_fileset_property QUARTUS_SYNTH TOP_LEVEL pwm
|
||||
set_fileset_property QUARTUS_SYNTH ENABLE_RELATIVE_INCLUDE_PATHS false
|
||||
set_fileset_property QUARTUS_SYNTH ENABLE_FILE_OVERWRITE_MODE false
|
||||
add_fileset_file pwm.vhd VHDL PATH pwm.vhd TOP_LEVEL_FILE
|
||||
add_fileset_file pwm_constants.vhd VHDL PATH pwm_constants.vhd
|
||||
|
||||
|
||||
#
|
||||
# parameters
|
||||
#
|
||||
|
||||
|
||||
#
|
||||
# display items
|
||||
#
|
||||
|
||||
|
||||
#
|
||||
# connection point clock
|
||||
#
|
||||
add_interface clock clock end
|
||||
set_interface_property clock clockRate 0
|
||||
set_interface_property clock ENABLED true
|
||||
set_interface_property clock EXPORT_OF ""
|
||||
set_interface_property clock PORT_NAME_MAP ""
|
||||
set_interface_property clock CMSIS_SVD_VARIABLES ""
|
||||
set_interface_property clock SVD_ADDRESS_GROUP ""
|
||||
|
||||
add_interface_port clock clk clk Input 1
|
||||
|
||||
|
||||
#
|
||||
# connection point reset
|
||||
#
|
||||
add_interface reset reset end
|
||||
set_interface_property reset associatedClock clock
|
||||
set_interface_property reset synchronousEdges DEASSERT
|
||||
set_interface_property reset ENABLED true
|
||||
set_interface_property reset EXPORT_OF ""
|
||||
set_interface_property reset PORT_NAME_MAP ""
|
||||
set_interface_property reset CMSIS_SVD_VARIABLES ""
|
||||
set_interface_property reset SVD_ADDRESS_GROUP ""
|
||||
|
||||
add_interface_port reset reset reset Input 1
|
||||
|
||||
|
||||
#
|
||||
# connection point avalon_slave_0
|
||||
#
|
||||
add_interface avalon_slave_0 avalon end
|
||||
set_interface_property avalon_slave_0 addressUnits WORDS
|
||||
set_interface_property avalon_slave_0 associatedClock clock
|
||||
set_interface_property avalon_slave_0 associatedReset reset
|
||||
set_interface_property avalon_slave_0 bitsPerSymbol 8
|
||||
set_interface_property avalon_slave_0 burstOnBurstBoundariesOnly false
|
||||
set_interface_property avalon_slave_0 burstcountUnits WORDS
|
||||
set_interface_property avalon_slave_0 explicitAddressSpan 0
|
||||
set_interface_property avalon_slave_0 holdTime 0
|
||||
set_interface_property avalon_slave_0 linewrapBursts false
|
||||
set_interface_property avalon_slave_0 maximumPendingReadTransactions 0
|
||||
set_interface_property avalon_slave_0 maximumPendingWriteTransactions 0
|
||||
set_interface_property avalon_slave_0 readLatency 0
|
||||
set_interface_property avalon_slave_0 readWaitTime 1
|
||||
set_interface_property avalon_slave_0 setupTime 0
|
||||
set_interface_property avalon_slave_0 timingUnits Cycles
|
||||
set_interface_property avalon_slave_0 writeWaitTime 0
|
||||
set_interface_property avalon_slave_0 ENABLED true
|
||||
set_interface_property avalon_slave_0 EXPORT_OF ""
|
||||
set_interface_property avalon_slave_0 PORT_NAME_MAP ""
|
||||
set_interface_property avalon_slave_0 CMSIS_SVD_VARIABLES ""
|
||||
set_interface_property avalon_slave_0 SVD_ADDRESS_GROUP ""
|
||||
|
||||
add_interface_port avalon_slave_0 address address Input 2
|
||||
add_interface_port avalon_slave_0 read read Input 1
|
||||
add_interface_port avalon_slave_0 write write Input 1
|
||||
add_interface_port avalon_slave_0 readdata readdata Output 32
|
||||
add_interface_port avalon_slave_0 writedata writedata Input 32
|
||||
set_interface_assignment avalon_slave_0 embeddedsw.configuration.isFlash 0
|
||||
set_interface_assignment avalon_slave_0 embeddedsw.configuration.isMemoryDevice 0
|
||||
set_interface_assignment avalon_slave_0 embeddedsw.configuration.isNonVolatileStorage 0
|
||||
set_interface_assignment avalon_slave_0 embeddedsw.configuration.isPrintableDevice 0
|
||||
|
||||
|
||||
#
|
||||
# connection point conduit_end
|
||||
#
|
||||
add_interface conduit_end conduit end
|
||||
set_interface_property conduit_end associatedClock clock
|
||||
set_interface_property conduit_end associatedReset ""
|
||||
set_interface_property conduit_end ENABLED true
|
||||
set_interface_property conduit_end EXPORT_OF ""
|
||||
set_interface_property conduit_end PORT_NAME_MAP ""
|
||||
set_interface_property conduit_end CMSIS_SVD_VARIABLES ""
|
||||
set_interface_property conduit_end SVD_ADDRESS_GROUP ""
|
||||
|
||||
add_interface_port conduit_end pwm_out pwm Output 1
|
205
cs309-psoc/lab_4_0/hw/hdl/pantilt/tb/tb_pwm.vhd
Normal file
205
cs309-psoc/lab_4_0/hw/hdl/pantilt/tb/tb_pwm.vhd
Normal file
@ -0,0 +1,205 @@
|
||||
-- #############################################################################
|
||||
-- tb_pwm.vhd
|
||||
-- ==========
|
||||
-- Testbench for PWM memory-mapped Avalon slave interface.
|
||||
--
|
||||
-- Modified by : Sahand Kashani-Akhavan [sahand.kashani-akhavan@epfl.ch]
|
||||
-- Revision : 2
|
||||
-- Last modified : 2018-02-28
|
||||
-- #############################################################################
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
use work.pwm_constants.all;
|
||||
|
||||
entity tb_pwm is
|
||||
end entity;
|
||||
|
||||
architecture rtl of tb_pwm is
|
||||
|
||||
-- 50 MHz clock
|
||||
constant CLK_PERIOD : time := 20 ns;
|
||||
|
||||
-- Signal used to end simulator when we finished submitting our test cases
|
||||
signal sim_finished : boolean := false;
|
||||
|
||||
-- PWM PORTS
|
||||
signal clk : std_logic;
|
||||
signal reset : std_logic;
|
||||
signal address : std_logic_vector(1 downto 0);
|
||||
signal read : std_logic;
|
||||
signal write : std_logic;
|
||||
signal readdata : std_logic_vector(31 downto 0);
|
||||
signal writedata : std_logic_vector(31 downto 0);
|
||||
signal pwm_out : std_logic;
|
||||
|
||||
-- Values of registers we are going to use to configure the PWM unit
|
||||
constant CONFIG_PERIOD : natural := 100;
|
||||
constant CONFIG_DUTY_CYCLE : natural := 20;
|
||||
constant CONFIG_CTRL_START : natural := 1;
|
||||
constant CONFIG_CTRL_STOP : natural := 0;
|
||||
|
||||
begin
|
||||
|
||||
-- Instantiate DUT
|
||||
dut : entity work.pwm
|
||||
port map(
|
||||
clk => clk,
|
||||
reset => reset,
|
||||
address => address,
|
||||
read => read,
|
||||
write => write,
|
||||
readdata => readdata,
|
||||
writedata => writedata,
|
||||
pwm_out => pwm_out
|
||||
);
|
||||
|
||||
-- Generate clk signal
|
||||
clk_generation : process
|
||||
begin
|
||||
if not sim_finished then
|
||||
clk <= '1';
|
||||
wait for CLK_PERIOD / 2;
|
||||
clk <= '0';
|
||||
wait for CLK_PERIOD / 2;
|
||||
else
|
||||
wait;
|
||||
end if;
|
||||
end process clk_generation;
|
||||
|
||||
-- Test PWM
|
||||
simulation : process
|
||||
|
||||
procedure async_reset is
|
||||
begin
|
||||
wait until rising_edge(clk);
|
||||
wait for CLK_PERIOD / 4;
|
||||
|
||||
reset <= '1';
|
||||
wait for CLK_PERIOD / 2;
|
||||
|
||||
reset <= '0';
|
||||
wait for CLK_PERIOD / 4;
|
||||
end procedure async_reset;
|
||||
|
||||
procedure write_register(constant ofst : in std_logic_vector(1 downto 0);
|
||||
constant val : in natural) is
|
||||
begin
|
||||
wait until rising_edge(clk);
|
||||
|
||||
address <= ofst;
|
||||
write <= '1';
|
||||
writedata <= std_logic_vector(to_unsigned(val, writedata'length));
|
||||
wait until rising_edge(clk);
|
||||
|
||||
address <= (others => '0');
|
||||
write <= '0';
|
||||
writedata <= (others => '0');
|
||||
wait until rising_edge(clk);
|
||||
end procedure write_register;
|
||||
|
||||
procedure read_register(constant ofst : in std_logic_vector(1 downto 0)) is
|
||||
begin
|
||||
wait until rising_edge(clk);
|
||||
|
||||
address <= ofst;
|
||||
read <= '1';
|
||||
-- The read has a 1 cycle wait-state, so we need to keep the read
|
||||
-- signal high for 2 clock cycles.
|
||||
wait until rising_edge(clk);
|
||||
wait until rising_edge(clk);
|
||||
|
||||
address <= (others => '0');
|
||||
read <= '0';
|
||||
wait until rising_edge(clk);
|
||||
end procedure read_register;
|
||||
|
||||
procedure read_register_check(constant ofst : in std_logic_vector(1 downto 0);
|
||||
constant expected_val : in natural) is
|
||||
begin
|
||||
read_register(ofst);
|
||||
|
||||
case ofst is
|
||||
when REG_PERIOD_OFST =>
|
||||
assert to_integer(unsigned(readdata)) = expected_val
|
||||
report "Unexpected PERIOD: " &
|
||||
"PERIOD = " & integer'image(to_integer(unsigned(readdata))) & "; " &
|
||||
"PERIOD_expected = " & integer'image(expected_val)
|
||||
severity error;
|
||||
|
||||
when REG_DUTY_CYCLE_OFST =>
|
||||
assert to_integer(unsigned(readdata)) = expected_val
|
||||
report "Unexpected DUTY_CYCLE: " &
|
||||
"DUTY_CYCLE = " & integer'image(to_integer(unsigned(readdata))) & "; " &
|
||||
"DUTY_CYCLE_expected = " & integer'image(expected_val)
|
||||
severity error;
|
||||
|
||||
when REG_CTRL_OFST =>
|
||||
assert to_integer(unsigned(readdata)) = expected_val
|
||||
report "Unexpected CTRL: " &
|
||||
"CTRL = " & integer'image(to_integer(unsigned(readdata))) & "; " &
|
||||
"CTRL_expected = " & integer'image(expected_val)
|
||||
severity error;
|
||||
|
||||
when others =>
|
||||
null;
|
||||
end case;
|
||||
end procedure read_register_check;
|
||||
|
||||
begin
|
||||
|
||||
-- Default values
|
||||
reset <= '0';
|
||||
address <= (others => '0');
|
||||
read <= '0';
|
||||
write <= '0';
|
||||
writedata <= (others => '0');
|
||||
wait until rising_edge(clk);
|
||||
|
||||
-- Reset the circuit
|
||||
async_reset;
|
||||
|
||||
-- Write desired configuration to PWM Avalon-MM slave.
|
||||
write_register(REG_PERIOD_OFST, CONFIG_PERIOD);
|
||||
write_register(REG_DUTY_CYCLE_OFST, CONFIG_DUTY_CYCLE);
|
||||
|
||||
-- Read back configuration from PWM Avalon-MM slave. Note that we have
|
||||
-- not started the PWM unit yet, so the new configuration must not be
|
||||
-- read back at this point (as per the register map).
|
||||
read_register_check(REG_PERIOD_OFST, DEFAULT_PERIOD);
|
||||
read_register_check(REG_DUTY_CYCLE_OFST, DEFAULT_DUTY_CYCLE);
|
||||
read_register_check(REG_CTRL_OFST, 0);
|
||||
|
||||
-- Start PWM
|
||||
write_register(REG_CTRL_OFST, CONFIG_CTRL_START);
|
||||
|
||||
-- Wait until PWM pulses for the first time after we sent START.
|
||||
wait until rising_edge(pwm_out);
|
||||
|
||||
-- Read back configuration from PWM Avalon-MM slave. Now that we have
|
||||
-- started the PWM unit, we should be able to read back the
|
||||
-- configuration we wrote (as per the register map).
|
||||
read_register_check(REG_PERIOD_OFST, CONFIG_PERIOD);
|
||||
read_register_check(REG_DUTY_CYCLE_OFST, CONFIG_DUTY_CYCLE);
|
||||
read_register_check(REG_CTRL_OFST, 0);
|
||||
|
||||
-- Wait for 2 PWM periods to finish
|
||||
wait for 2 * CLK_PERIOD * CONFIG_PERIOD;
|
||||
|
||||
-- Stop PWM.
|
||||
write_register(REG_CTRL_OFST, CONFIG_CTRL_STOP);
|
||||
|
||||
-- Wait for PWM period to finish
|
||||
wait for 1 * CLK_PERIOD * CONFIG_PERIOD;
|
||||
|
||||
-- Instruct "clk_generation" process to halt execution.
|
||||
sim_finished <= true;
|
||||
|
||||
-- Make this process wait indefinitely (it will never re-execute from
|
||||
-- its beginning again).
|
||||
wait;
|
||||
end process simulation;
|
||||
end architecture rtl;
|
||||
|
98
cs309-psoc/lab_4_0/hw/quartus/ip/components.ipx
Normal file
98
cs309-psoc/lab_4_0/hw/quartus/ip/components.ipx
Normal file
@ -0,0 +1,98 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<library>
|
||||
<!-- date: 2017.05.14.23:41:43 -->
|
||||
<!-- generated by: ip-make-ipx -->
|
||||
<!-- -->
|
||||
<!-- 5 in ../../hdl/ -->
|
||||
<!-- -->
|
||||
<component
|
||||
name="framebuffer_manager"
|
||||
file="../../hdl/displays/framebuffer_manager/hdl/framebuffer_manager_hw.tcl"
|
||||
displayName="framebuffer_manager"
|
||||
version="1.0"
|
||||
description=""
|
||||
tags="AUTHORSHIP=Philemon Favrod /// CONNECTION_TYPES=avalon,avalon_streaming,clock,conduit,interrupt,reset /// INTERNAL_COMPONENT=false"
|
||||
categories="LCD"
|
||||
factory="TclModuleFactory">
|
||||
<tag2 key="ALLOW_GREYBOX_GENERATION" value="false" />
|
||||
<tag2 key="COMPONENT_EDITABLE" value="true" />
|
||||
<tag2 key="COMPONENT_HIDE_FROM_SOPC" value="true" />
|
||||
<tag2 key="INSTANTIATE_IN_SYSTEM_MODULE" value="true" />
|
||||
<tag2 key="OPAQUE_ADDRESS_MAP" value="true" />
|
||||
<tag2 key="REPORT_HIERARCHY" value="false" />
|
||||
<tag2 key="SUPPORTED_FILE_SETS" value="QUARTUS_SYNTH" />
|
||||
<tag2 key="TCL_PACKAGE_VERSION" value="16.0" />
|
||||
</component>
|
||||
<component
|
||||
name="lepton"
|
||||
file="../../hdl/lepton/hdl/lepton_hw.tcl"
|
||||
displayName="lepton"
|
||||
version="1.0"
|
||||
description="IR Camera 80x60"
|
||||
tags="AUTHORSHIP=Philemon Favrod & Sahand Kashani-Akhavan /// CONNECTION_TYPES=avalon,clock,conduit,reset /// INTERNAL_COMPONENT=false"
|
||||
categories="Camera"
|
||||
factory="TclModuleFactory">
|
||||
<tag2 key="ALLOW_GREYBOX_GENERATION" value="false" />
|
||||
<tag2 key="COMPONENT_EDITABLE" value="true" />
|
||||
<tag2 key="COMPONENT_HIDE_FROM_SOPC" value="true" />
|
||||
<tag2 key="INSTANTIATE_IN_SYSTEM_MODULE" value="true" />
|
||||
<tag2 key="OPAQUE_ADDRESS_MAP" value="true" />
|
||||
<tag2 key="REPORT_HIERARCHY" value="false" />
|
||||
<tag2 key="SUPPORTED_FILE_SETS" value="QUARTUS_SYNTH" />
|
||||
<tag2 key="TCL_PACKAGE_VERSION" value="16.0" />
|
||||
</component>
|
||||
<component
|
||||
name="mcp3204"
|
||||
file="../../hdl/joysticks/hdl/mcp3204_hw.tcl"
|
||||
displayName="mcp3204"
|
||||
version="1.0"
|
||||
description="4-Channel 12-Bit A/D Converter with SPI Serial Interface"
|
||||
tags="AUTHORSHIP=Philemon Favrod & Sahand Kashani-Akhavan /// CONNECTION_TYPES=avalon,clock,conduit,reset /// INTERNAL_COMPONENT=false"
|
||||
categories="Joystick"
|
||||
factory="TclModuleFactory">
|
||||
<tag2 key="ALLOW_GREYBOX_GENERATION" value="false" />
|
||||
<tag2 key="COMPONENT_EDITABLE" value="true" />
|
||||
<tag2 key="COMPONENT_HIDE_FROM_SOPC" value="true" />
|
||||
<tag2 key="INSTANTIATE_IN_SYSTEM_MODULE" value="true" />
|
||||
<tag2 key="OPAQUE_ADDRESS_MAP" value="true" />
|
||||
<tag2 key="REPORT_HIERARCHY" value="false" />
|
||||
<tag2 key="SUPPORTED_FILE_SETS" value="QUARTUS_SYNTH" />
|
||||
<tag2 key="TCL_PACKAGE_VERSION" value="16.0" />
|
||||
</component>
|
||||
<component
|
||||
name="pwm"
|
||||
file="../../hdl/pantilt/hdl/pwm_hw.tcl"
|
||||
displayName="pwm"
|
||||
version="1.0"
|
||||
description="Pan-tilt"
|
||||
tags="AUTHORSHIP= /// CONNECTION_TYPES=avalon,clock,conduit,reset /// INTERNAL_COMPONENT=false"
|
||||
categories="Pan-tilt"
|
||||
factory="TclModuleFactory">
|
||||
<tag2 key="ALLOW_GREYBOX_GENERATION" value="false" />
|
||||
<tag2 key="COMPONENT_EDITABLE" value="true" />
|
||||
<tag2 key="COMPONENT_HIDE_FROM_SOPC" value="true" />
|
||||
<tag2 key="INSTANTIATE_IN_SYSTEM_MODULE" value="true" />
|
||||
<tag2 key="OPAQUE_ADDRESS_MAP" value="true" />
|
||||
<tag2 key="REPORT_HIERARCHY" value="false" />
|
||||
<tag2 key="SUPPORTED_FILE_SETS" value="QUARTUS_SYNTH" />
|
||||
<tag2 key="TCL_PACKAGE_VERSION" value="16.0" />
|
||||
</component>
|
||||
<component
|
||||
name="vga_sequencer"
|
||||
file="../../hdl/displays/vga_sequencer/hdl/vga_sequencer_hw.tcl"
|
||||
displayName="vga_sequencer"
|
||||
version="1.0"
|
||||
description=""
|
||||
tags="AUTHORSHIP=Philemon Favrod /// CONNECTION_TYPES=avalon,avalon_streaming,clock,conduit,reset /// INTERNAL_COMPONENT=false"
|
||||
categories="LCD"
|
||||
factory="TclModuleFactory">
|
||||
<tag2 key="ALLOW_GREYBOX_GENERATION" value="false" />
|
||||
<tag2 key="COMPONENT_EDITABLE" value="true" />
|
||||
<tag2 key="COMPONENT_HIDE_FROM_SOPC" value="true" />
|
||||
<tag2 key="INSTANTIATE_IN_SYSTEM_MODULE" value="true" />
|
||||
<tag2 key="OPAQUE_ADDRESS_MAP" value="true" />
|
||||
<tag2 key="REPORT_HIERARCHY" value="false" />
|
||||
<tag2 key="SUPPORTED_FILE_SETS" value="QUARTUS_SYNTH" />
|
||||
<tag2 key="TCL_PACKAGE_VERSION" value="16.0" />
|
||||
</component>
|
||||
</library>
|
31
cs309-psoc/lab_4_0/hw/quartus/lab_4_0.qpf
Normal file
31
cs309-psoc/lab_4_0/hw/quartus/lab_4_0.qpf
Normal file
@ -0,0 +1,31 @@
|
||||
# -------------------------------------------------------------------------- #
|
||||
#
|
||||
# Copyright (C) 1991-2015 Altera Corporation. All rights reserved.
|
||||
# Your use of Altera Corporation's design tools, logic functions
|
||||
# and other software and tools, and its AMPP partner logic
|
||||
# functions, and any output files from any of the foregoing
|
||||
# (including device programming or simulation files), and any
|
||||
# associated documentation or information are expressly subject
|
||||
# to the terms and conditions of the Altera Program License
|
||||
# Subscription Agreement, the Altera Quartus Prime License Agreement,
|
||||
# the Altera MegaCore Function License Agreement, or other
|
||||
# applicable license agreement, including, without limitation,
|
||||
# that your use is for the sole purpose of programming logic
|
||||
# devices manufactured by Altera and sold by Altera or its
|
||||
# authorized distributors. Please refer to the applicable
|
||||
# agreement for further details.
|
||||
#
|
||||
# -------------------------------------------------------------------------- #
|
||||
#
|
||||
# Quartus Prime
|
||||
# Version 15.1.0 Build 185 10/21/2015 SJ Lite Edition
|
||||
# Date created = 11:03:02 February 05, 2016
|
||||
#
|
||||
# -------------------------------------------------------------------------- #
|
||||
|
||||
QUARTUS_VERSION = "15.1"
|
||||
DATE = "11:03:02 February 05, 2016"
|
||||
|
||||
# Revisions
|
||||
|
||||
PROJECT_REVISION = "lab_4_0"
|
1017
cs309-psoc/lab_4_0/hw/quartus/lab_4_0.qsf
Normal file
1017
cs309-psoc/lab_4_0/hw/quartus/lab_4_0.qsf
Normal file
File diff suppressed because it is too large
Load Diff
6
cs309-psoc/lab_4_0/hw/quartus/lab_4_0.sdc
Normal file
6
cs309-psoc/lab_4_0/hw/quartus/lab_4_0.sdc
Normal file
@ -0,0 +1,6 @@
|
||||
create_clock -period 20 [get_ports FPGA_CLK1_50]
|
||||
create_clock -period 20 [get_ports FPGA_CLK2_50]
|
||||
create_clock -period 20 [get_ports FPGA_CLK3_50]
|
||||
|
||||
derive_pll_clocks
|
||||
derive_clock_uncertainty
|
1197
cs309-psoc/lab_4_0/hw/quartus/soc_system.qsys
Normal file
1197
cs309-psoc/lab_4_0/hw/quartus/soc_system.qsys
Normal file
File diff suppressed because it is too large
Load Diff
BIN
cs309-psoc/lab_4_0/lab_4_0.pdf
Normal file
BIN
cs309-psoc/lab_4_0/lab_4_0.pdf
Normal file
Binary file not shown.
6
cs309-psoc/lab_4_0/sw/hps/application/lab_4_0/app.c
Normal file
6
cs309-psoc/lab_4_0/sw/hps/application/lab_4_0/app.c
Normal file
@ -0,0 +1,6 @@
|
||||
#include <stdlib.h>
|
||||
|
||||
int main(void) {
|
||||
/* TODO : complete this function with your application */
|
||||
return EXIT_SUCCESS;
|
||||
}
|
Binary file not shown.
After Width: | Height: | Size: 8.3 KiB |
Binary file not shown.
After Width: | Height: | Size: 56 KiB |
@ -0,0 +1,84 @@
|
||||
/**
|
||||
* @author Philemon Favrod
|
||||
* @brief Example of ping-pong buffering using the framebuffer.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <stdint.h>
|
||||
#include <assert.h>
|
||||
#include <sys/mman.h>
|
||||
#include <linux/fb.h>
|
||||
#include <unistd.h>
|
||||
|
||||
struct fb_fix_screeninfo fix_info;
|
||||
struct fb_var_screeninfo var_info;
|
||||
uint32_t *frame_buffer;
|
||||
int num_buffers;
|
||||
int num_pixels_per_buffer;
|
||||
int fb_fd;
|
||||
|
||||
inline uint32_t make_color(uint8_t red, uint8_t green, uint8_t blue)
|
||||
{
|
||||
uint32_t r = red << var_info.red.offset;
|
||||
uint32_t g = green << var_info.green.offset;
|
||||
uint32_t b = blue << var_info.blue.offset;
|
||||
return r | g | b;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
fb_fd = open("/dev/fb0", O_RDWR);
|
||||
assert(fb_fd >= 0);
|
||||
|
||||
// Get screen information
|
||||
int ret = ioctl(fb_fd, FBIOGET_FSCREENINFO, &fix_info);
|
||||
assert(ret >= 0);
|
||||
|
||||
ret = ioctl(fb_fd, FBIOGET_VSCREENINFO, &var_info);
|
||||
assert(ret >= 0);
|
||||
|
||||
// Map the frame buffer in user memory
|
||||
frame_buffer = mmap(NULL, var_info.yres_virtual * fix_info.line_length, PROT_READ | PROT_WRITE, MAP_SHARED, fb_fd, 0);
|
||||
assert(frame_buffer != MAP_FAILED);
|
||||
|
||||
// Reminder: with prsoc_fbdev driver the number of buffer can be changed in the device tree
|
||||
num_buffers = (var_info.yres_virtual * var_info.xres_virtual) / (var_info.xres * var_info.yres);
|
||||
num_pixels_per_buffer = var_info.yres * var_info.xres;
|
||||
|
||||
int buffer_idx;
|
||||
for (buffer_idx = 0; buffer_idx < num_buffers; ++buffer_idx) {
|
||||
|
||||
// Compute the color of the buffer
|
||||
// Buffers 0, 3, 6, ... will be red
|
||||
// Buffers 1, 4, 7, ... will be green
|
||||
// Buffers 2, 5, 8, ... will be blue
|
||||
uint32_t color = make_color(0xff, 0, 0);
|
||||
if (buffer_idx % 3 == 1) {
|
||||
color = make_color(0, 0xff, 0);
|
||||
} else if (buffer_idx % 3 == 2) {
|
||||
color = make_color(0, 0, 0xff);
|
||||
}
|
||||
|
||||
int pixel_idx;
|
||||
for (pixel_idx = buffer_idx * num_pixels_per_buffer; pixel_idx < (buffer_idx + 1) * num_pixels_per_buffer; ++pixel_idx) {
|
||||
frame_buffer[pixel_idx] = color;
|
||||
}
|
||||
}
|
||||
|
||||
while (1) {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < num_buffers; ++i) {
|
||||
var_info.yoffset = i * var_info.yres;
|
||||
ret = ioctl(fb_fd, FBIOPAN_DISPLAY, &var_info);
|
||||
assert(ret >= 0);
|
||||
|
||||
usleep(3000000);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
BIN
cs309-psoc/lab_4_0/sw/hps/application/lab_4_0/displays/fbv
Executable file
BIN
cs309-psoc/lab_4_0/sw/hps/application/lab_4_0/displays/fbv
Executable file
Binary file not shown.
24
cs309-psoc/lab_4_0/sw/hps/application/lab_4_0/iorw.h
Normal file
24
cs309-psoc/lab_4_0/sw/hps/application/lab_4_0/iorw.h
Normal file
@ -0,0 +1,24 @@
|
||||
#ifndef __IORW_H__
|
||||
#define __IORW_H__
|
||||
|
||||
#ifdef __nios2_arch__
|
||||
#include <io.h>
|
||||
|
||||
#define io_write_8(base, ofst, data) (IOWR_8DIRECT((base), (ofst), (data)))
|
||||
#define io_write_16(base, ofst, data) (IOWR_16DIRECT((base), (ofst), (data)))
|
||||
#define io_write_32(base, ofst, data) (IOWR_32DIRECT((base), (ofst), (data)))
|
||||
#define io_read_8(base, ofst) (IORD_8DIRECT((base), (ofst)))
|
||||
#define io_read_16(base, ofst) (IORD_16DIRECT((base), (ofst)))
|
||||
#define io_read_32(base, ofst) (IORD_32DIRECT((base), (ofst)))
|
||||
#else
|
||||
#include <socal/socal.h>
|
||||
|
||||
#define io_write_8(base, ofst, data) (alt_write_byte((uintptr_t) (base) + (ofst), (data)))
|
||||
#define io_write_16(base, ofst, data) (alt_write_hword((uintptr_t) (base) + (ofst), (data)))
|
||||
#define io_write_32(base, ofst, data) (alt_write_word((uintptr_t) (base) + (ofst), (data)))
|
||||
#define io_read_8(base, ofst) (alt_read_byte((uintptr_t) (base) + (ofst)))
|
||||
#define io_read_16(base, ofst) (alt_read_hword((uintptr_t) (base) + (ofst)))
|
||||
#define io_read_32(base, ofst) (alt_read_word((uintptr_t) (base) + (ofst)))
|
||||
#endif
|
||||
|
||||
#endif
|
@ -0,0 +1,79 @@
|
||||
#include "joysticks.h"
|
||||
|
||||
#define JOYSTICK_RIGHT_VRY_MCP3204_CHANNEL (0)
|
||||
#define JOYSTICK_RIGHT_VRX_MCP3204_CHANNEL (1)
|
||||
#define JOYSTICK_LEFT_VRY_MCP3204_CHANNEL (2)
|
||||
#define JOYSTICK_LEFT_VRX_MCP3204_CHANNEL (3)
|
||||
|
||||
/**
|
||||
* joysticks_inst
|
||||
*
|
||||
* Instantiate a joysticks device structure.
|
||||
*
|
||||
* @param base Base address of the MCP3204 component connected to the joysticks.
|
||||
*/
|
||||
joysticks_dev joysticks_inst(void *mcp3204_base) {
|
||||
joysticks_dev dev;
|
||||
dev.mcp3204 = mcp3204_inst((void *) mcp3204_base);
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
/**
|
||||
* joysticks_init
|
||||
*
|
||||
* Initializes the joysticks device.
|
||||
*
|
||||
* @param dev joysticks device structure.
|
||||
*/
|
||||
void joysticks_init(joysticks_dev *dev) {
|
||||
mcp3204_init(&(dev->mcp3204));
|
||||
}
|
||||
|
||||
/**
|
||||
* joysticks_read_left_vertical
|
||||
*
|
||||
* Returns the vertical position of the left joystick. Return value ranges
|
||||
* between JOYSTICKS_MIN_VALUE and JOYSTICKS_MAX_VALUE.
|
||||
*
|
||||
* @param dev joysticks device structure.
|
||||
*/
|
||||
uint32_t joysticks_read_left_vertical(joysticks_dev *dev) {
|
||||
return JOYSTICKS_MAX_VALUE - mcp3204_read(&dev->mcp3204, JOYSTICK_RIGHT_VRY_MCP3204_CHANNEL);
|
||||
}
|
||||
|
||||
/**
|
||||
* joysticks_read_left_horizontal
|
||||
*
|
||||
* Returns the horizontal position of the left joystick. Return value ranges
|
||||
* between JOYSTICKS_MIN_VALUE and JOYSTICKS_MAX_VALUE.
|
||||
*
|
||||
* @param dev joysticks device structure.
|
||||
*/
|
||||
uint32_t joysticks_read_left_horizontal(joysticks_dev *dev) {
|
||||
return mcp3204_read(&dev->mcp3204, JOYSTICK_LEFT_VRX_MCP3204_CHANNEL);
|
||||
}
|
||||
|
||||
/**
|
||||
* joysticks_read_right_vertical
|
||||
*
|
||||
* Returns the vertical position of the right joystick. Return value ranges
|
||||
* between JOYSTICKS_MIN_VALUE and JOYSTICKS_MAX_VALUE.
|
||||
*
|
||||
* @param dev joysticks device structure.
|
||||
*/
|
||||
uint32_t joysticks_read_right_vertical(joysticks_dev *dev) {
|
||||
return JOYSTICKS_MAX_VALUE - mcp3204_read(&dev->mcp3204, JOYSTICK_RIGHT_VRY_MCP3204_CHANNEL);
|
||||
}
|
||||
|
||||
/**
|
||||
* joysticks_read_right_horizontal
|
||||
*
|
||||
* Returns the horizontal position of the left joystick. Return value ranges
|
||||
* between JOYSTICKS_MIN_VALUE and JOYSTICKS_MAX_VALUE.
|
||||
*
|
||||
* @param dev joysticks device structure.
|
||||
*/
|
||||
uint32_t joysticks_read_right_horizontal(joysticks_dev *dev) {
|
||||
return mcp3204_read(&dev->mcp3204, JOYSTICK_RIGHT_VRX_MCP3204_CHANNEL);
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
#ifndef __JOYSTICKS_H__
|
||||
#define __JOYSTICKS_H__
|
||||
|
||||
#include "mcp3204/mcp3204.h"
|
||||
|
||||
/* joysticks device structure */
|
||||
typedef struct joysticks_dev {
|
||||
mcp3204_dev mcp3204; /* MCP3204 device handle */
|
||||
} joysticks_dev;
|
||||
|
||||
/*******************************************************************************
|
||||
* Public API
|
||||
******************************************************************************/
|
||||
|
||||
#define JOYSTICKS_MIN_VALUE (MCP3204_MIN_VALUE)
|
||||
#define JOYSTICKS_MAX_VALUE (MCP3204_MAX_VALUE)
|
||||
|
||||
joysticks_dev joysticks_inst(void *mcp3204_base);
|
||||
|
||||
void joysticks_init(joysticks_dev *dev);
|
||||
|
||||
uint32_t joysticks_read_left_vertical(joysticks_dev *dev);
|
||||
uint32_t joysticks_read_left_horizontal(joysticks_dev *dev);
|
||||
uint32_t joysticks_read_right_vertical(joysticks_dev *dev);
|
||||
uint32_t joysticks_read_right_horizontal(joysticks_dev *dev);
|
||||
|
||||
#endif /* __JOYSTICKS_H__ */
|
@ -0,0 +1,44 @@
|
||||
#include "mcp3204.h"
|
||||
#include "iorw.h"
|
||||
|
||||
#define MCP3204_NUM_CHANNELS (4)
|
||||
|
||||
/**
|
||||
* mcp3204_inst
|
||||
*
|
||||
* Instantiate a mcp3204 device structure.
|
||||
*
|
||||
* @param base Base address of the component.
|
||||
*/
|
||||
mcp3204_dev mcp3204_inst(void *base) {
|
||||
mcp3204_dev dev;
|
||||
dev.base = base;
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
/**
|
||||
* mcp3204_init
|
||||
*
|
||||
* Initializes the mcp3204 device.
|
||||
*
|
||||
* @param dev mcp3204 device structure.
|
||||
*/
|
||||
void mcp3204_init(mcp3204_dev *dev) {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* mcp3204_read
|
||||
*
|
||||
* Reads the register corresponding to the supplied channel parameter.
|
||||
*
|
||||
* @param dev mcp3204 device structure.
|
||||
* @param channel channel to be read
|
||||
*/
|
||||
uint32_t mcp3204_read(mcp3204_dev *dev, uint32_t channel) {
|
||||
if (channel >= 4)
|
||||
return 0;
|
||||
|
||||
return io_read_32(dev->base, channel * 4);
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
#ifndef __MCP3204_H__
|
||||
#define __MCP3204_H__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/* mcp3204 device structure */
|
||||
typedef struct mcp3204_dev {
|
||||
void *base; /* Base address of component */
|
||||
} mcp3204_dev;
|
||||
|
||||
/*******************************************************************************
|
||||
* Public API
|
||||
******************************************************************************/
|
||||
|
||||
#define MCP3204_MIN_VALUE (0)
|
||||
#define MCP3204_MAX_VALUE (4095)
|
||||
|
||||
mcp3204_dev mcp3204_inst(void *base);
|
||||
|
||||
void mcp3204_init(mcp3204_dev *dev);
|
||||
uint32_t mcp3204_read(mcp3204_dev *dev, uint32_t channel);
|
||||
|
||||
#endif /* __MCP3204_H__ */
|
@ -0,0 +1,9 @@
|
||||
#ifndef __MCP3204_REGS_H__
|
||||
#define __MCP3204_REGS_H__
|
||||
|
||||
#define MCP3204_CHANNEL_0_OFST (0 * 4) /* RO */
|
||||
#define MCP3204_CHANNEL_1_OFST (1 * 4) /* RO */
|
||||
#define MCP3204_CHANNEL_2_OFST (2 * 4) /* RO */
|
||||
#define MCP3204_CHANNEL_3_OFST (3 * 4) /* RO */
|
||||
|
||||
#endif /* __MCP3204_REGS_H__ */
|
117
cs309-psoc/lab_4_0/sw/hps/application/lab_4_0/lepton/lepton.c
Normal file
117
cs309-psoc/lab_4_0/sw/hps/application/lab_4_0/lepton/lepton.c
Normal file
@ -0,0 +1,117 @@
|
||||
#include <assert.h>
|
||||
#include <inttypes.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "lepton_regs.h"
|
||||
#include "lepton.h"
|
||||
#include "iorw.h"
|
||||
|
||||
/**
|
||||
* lepton_inst
|
||||
*
|
||||
* Instantiate a lepton device structure.
|
||||
*
|
||||
* @param base Base address of the component.
|
||||
*/
|
||||
lepton_dev lepton_inst(void *base) {
|
||||
lepton_dev dev;
|
||||
dev.base = base;
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
/**
|
||||
* lepton_init
|
||||
*
|
||||
* Initializes the lepton device.
|
||||
*
|
||||
* @param dev lepton device structure.
|
||||
*/
|
||||
void lepton_init(lepton_dev *dev) {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* lepton_start_capture
|
||||
*
|
||||
* Instructs the device to start the frame capture process.
|
||||
*
|
||||
* @param dev lepton device structure.
|
||||
*/
|
||||
void lepton_start_capture(lepton_dev *dev) {
|
||||
io_write_16(dev->base, LEPTON_REGS_COMMAND_OFST, 0x1);
|
||||
}
|
||||
|
||||
/**
|
||||
* lepton_error_check
|
||||
*
|
||||
* @abstract Check for errors at the device level.
|
||||
* @param dev lepton device structure.
|
||||
* @return true if there was an error, and false otherwise.
|
||||
*/
|
||||
bool lepton_error_check(lepton_dev *dev) {
|
||||
return (io_read_16(dev->base, LEPTON_REGS_STATUS_OFST) & 0x2) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* lepton_wait_until_eof
|
||||
*
|
||||
* Waits until the frame being captured has been fully received and saved in the
|
||||
* internal memory.
|
||||
*
|
||||
* @param dev lepton device structure.
|
||||
*/
|
||||
void lepton_wait_until_eof(lepton_dev *dev) {
|
||||
while (io_read_16(dev->base, LEPTON_REGS_STATUS_OFST) & 0x1);
|
||||
}
|
||||
|
||||
/**
|
||||
* lepton_save_capture
|
||||
*
|
||||
* Saves the captured frame on the host filesystem under the supplied filename.
|
||||
* The frame will be saved in PGM format.
|
||||
*
|
||||
* @param dev lepton device structure.
|
||||
* @param adjusted Setting this parameter to false will cause RAW sensor data to
|
||||
* be written to the file.
|
||||
* Setting this parameter to true will cause a preprocessed image
|
||||
* (with a stretched dynamic range) to be saved to the file.
|
||||
*
|
||||
* @param fname the output file name.
|
||||
*/
|
||||
void lepton_save_capture(lepton_dev *dev, bool adjusted, FILE* file) {
|
||||
assert(file);
|
||||
|
||||
const uint8_t num_rows = 60;
|
||||
const uint8_t num_cols = 80;
|
||||
|
||||
uint16_t offset = LEPTON_REGS_RAW_BUFFER_OFST;
|
||||
uint16_t max_value = io_read_16(dev->base, LEPTON_REGS_MAX_OFST);
|
||||
if (adjusted) {
|
||||
offset = LEPTON_REGS_ADJUSTED_BUFFER_OFST;
|
||||
max_value = 0x3fff;
|
||||
}
|
||||
|
||||
/* Write PGM header */
|
||||
fprintf(file, "P2\n%" PRIu8 " %" PRIu8 "\n%" PRIu16, num_cols, num_rows, max_value);
|
||||
|
||||
/* Write body */
|
||||
uint8_t row = 0;
|
||||
for (row = 0; row < num_rows; ++row) {
|
||||
fprintf(file, "\n");
|
||||
|
||||
uint8_t col = 0;
|
||||
for (col = 0; col < num_cols; ++col) {
|
||||
if (col > 0) {
|
||||
fprintf(file, " ");
|
||||
}
|
||||
|
||||
uint16_t current_ofst = offset + (row * num_cols + col) * sizeof(uint16_t);
|
||||
uint16_t pix_value = io_read_16(dev->base, current_ofst);
|
||||
fprintf(file, "%" PRIu16, pix_value);
|
||||
}
|
||||
}
|
||||
|
||||
assert(!fclose(file));
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
#ifndef __LEPTON_H__
|
||||
#define __LEPTON_H__
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
/* lepton device structure */
|
||||
typedef struct {
|
||||
void *base; /* Base address of the component */
|
||||
} lepton_dev;
|
||||
|
||||
/*******************************************************************************
|
||||
* Public API
|
||||
******************************************************************************/
|
||||
|
||||
lepton_dev lepton_inst(void *base);
|
||||
|
||||
void lepton_init(lepton_dev *dev);
|
||||
void lepton_start_capture(lepton_dev *dev);
|
||||
void lepton_wait_until_eof(lepton_dev *dev);
|
||||
bool lepton_error_check(lepton_dev *dev);
|
||||
void lepton_save_capture(lepton_dev *dev, bool adjusted, FILE* file);
|
||||
|
||||
#endif /* __LEPTON_H__ */
|
@ -0,0 +1,25 @@
|
||||
#ifndef __LEPTON_REGS_H__
|
||||
#define __LEPTON_REGS_H__
|
||||
|
||||
/* Register offsets */
|
||||
#define LEPTON_REGS_COMMAND_OFST ( 0 * 2) /* WO */
|
||||
#define LEPTON_REGS_STATUS_OFST ( 1 * 2) /* RO */
|
||||
#define LEPTON_REGS_MIN_OFST ( 2 * 2) /* RO */
|
||||
#define LEPTON_REGS_MAX_OFST ( 3 * 2) /* RO */
|
||||
#define LEPTON_REGS_SUM_LSB_OFST ( 4 * 2) /* RO */
|
||||
#define LEPTON_REGS_SUM_MSB_OFST ( 5 * 2) /* RO */
|
||||
#define LEPTON_REGS_ROW_IDX_OFST ( 6 * 2) /* RO */
|
||||
#define LEPTON_REGS_RAW_BUFFER_OFST ( 8 * 2) /* RO */
|
||||
#define LEPTON_REGS_ADJUSTED_BUFFER_OFST (8192 * 2) /* RO */
|
||||
|
||||
/* Command register */
|
||||
#define LEPTON_COMMAND_START (0x0001)
|
||||
|
||||
/* Status register */
|
||||
#define LEPTON_STATUS_CAPTURE_IN_PROGRESS_MASK (1 << 0)
|
||||
#define LEPTON_STATUS_ERROR_MASK (1 << 1)
|
||||
|
||||
#define LEPTON_REGS_BUFFER_NUM_PIXELS (80 * 60)
|
||||
#define LEPTON_REGS_BUFFER_BYTELENGTH (LEPTON_REGS_BUFFER_NUM_PIXELS * 2)
|
||||
|
||||
#endif /* __LEPTON_REGS_H__ */
|
109
cs309-psoc/lab_4_0/sw/hps/application/lab_4_0/pantilt/pantilt.c
Normal file
109
cs309-psoc/lab_4_0/sw/hps/application/lab_4_0/pantilt/pantilt.c
Normal file
@ -0,0 +1,109 @@
|
||||
#include "pantilt.h"
|
||||
|
||||
/**
|
||||
* pantilt_inst
|
||||
*
|
||||
* Instantiate a pantilt device structure.
|
||||
*
|
||||
* @param pwm_v_base Base address of the vertical PWM component.
|
||||
* @param pwm_h_base Base address of the horizontal PWM component.
|
||||
*/
|
||||
pantilt_dev pantilt_inst(void *pwm_v_base, void *pwm_h_base) {
|
||||
pantilt_dev dev;
|
||||
dev.pwm_v = pwm_inst(pwm_v_base);
|
||||
dev.pwm_h = pwm_inst(pwm_h_base);
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
/**
|
||||
* pantilt_init
|
||||
*
|
||||
* Initializes the pantilt device.
|
||||
*
|
||||
* @param dev pantilt device structure.
|
||||
*/
|
||||
void pantilt_init(pantilt_dev *dev) {
|
||||
pwm_init(&(dev->pwm_v));
|
||||
pwm_init(&(dev->pwm_h));
|
||||
}
|
||||
|
||||
/**
|
||||
* pantilt_configure_vertical
|
||||
*
|
||||
* Configure the vertical PWM component.
|
||||
*
|
||||
* @param dev pantilt device structure.
|
||||
* @param duty_cycle pwm duty cycle in us.
|
||||
*/
|
||||
void pantilt_configure_vertical(pantilt_dev *dev, uint32_t duty_cycle) {
|
||||
// Need to compensate for inverted servo rotation.
|
||||
duty_cycle = PANTILT_PWM_V_MAX_DUTY_CYCLE_US - duty_cycle + PANTILT_PWM_V_MIN_DUTY_CYCLE_US;
|
||||
|
||||
pwm_configure(&(dev->pwm_v),
|
||||
duty_cycle,
|
||||
PANTILT_PWM_PERIOD_US,
|
||||
PANTILT_PWM_CLOCK_FREQ_HZ);
|
||||
}
|
||||
|
||||
/**
|
||||
* pantilt_configure_horizontal
|
||||
*
|
||||
* Configure the horizontal PWM component.
|
||||
*
|
||||
* @param dev pantilt device structure.
|
||||
* @param duty_cycle pwm duty cycle in us.
|
||||
*/
|
||||
void pantilt_configure_horizontal(pantilt_dev *dev, uint32_t duty_cycle) {
|
||||
// Need to compensate for inverted servo rotation.
|
||||
duty_cycle = PANTILT_PWM_H_MAX_DUTY_CYCLE_US - duty_cycle + PANTILT_PWM_H_MIN_DUTY_CYCLE_US;
|
||||
|
||||
pwm_configure(&(dev->pwm_h),
|
||||
duty_cycle,
|
||||
PANTILT_PWM_PERIOD_US,
|
||||
PANTILT_PWM_CLOCK_FREQ_HZ);
|
||||
}
|
||||
|
||||
/**
|
||||
* pantilt_start_vertical
|
||||
*
|
||||
* Starts the vertical pwm controller.
|
||||
*
|
||||
* @param dev pantilt device structure.
|
||||
*/
|
||||
void pantilt_start_vertical(pantilt_dev *dev) {
|
||||
pwm_start(&(dev->pwm_v));
|
||||
}
|
||||
|
||||
/**
|
||||
* pantilt_start_horizontal
|
||||
*
|
||||
* Starts the horizontal pwm controller.
|
||||
*
|
||||
* @param dev pantilt device structure.
|
||||
*/
|
||||
void pantilt_start_horizontal(pantilt_dev *dev) {
|
||||
pwm_start(&(dev->pwm_h));
|
||||
}
|
||||
|
||||
/**
|
||||
* pantilt_stop_vertical
|
||||
*
|
||||
* Stops the vertical pwm controller.
|
||||
*
|
||||
* @param dev pantilt device structure.
|
||||
*/
|
||||
void pantilt_stop_vertical(pantilt_dev *dev) {
|
||||
pwm_stop(&(dev->pwm_v));
|
||||
}
|
||||
|
||||
/**
|
||||
* pantilt_stop_horizontal
|
||||
*
|
||||
* Stops the horizontal pwm controller.
|
||||
*
|
||||
* @param dev pantilt device structure.
|
||||
*/
|
||||
void pantilt_stop_horizontal(pantilt_dev *dev) {
|
||||
pwm_stop(&(dev->pwm_h));
|
||||
}
|
@ -0,0 +1,39 @@
|
||||
#ifndef __PANTILT_H__
|
||||
#define __PANTILT_H__
|
||||
|
||||
#include "pwm/pwm.h"
|
||||
|
||||
/* joysticks device structure */
|
||||
typedef struct pantilt_dev {
|
||||
pwm_dev pwm_v; /* Vertical PWM device handle */
|
||||
pwm_dev pwm_h; /* Horizontal PWM device handle */
|
||||
} pantilt_dev;
|
||||
|
||||
/*******************************************************************************
|
||||
* Public API
|
||||
******************************************************************************/
|
||||
|
||||
#define PANTILT_PWM_CLOCK_FREQ_HZ (50000000) // 50.00 MHz
|
||||
|
||||
#define PANTILT_PWM_PERIOD_US (25000) // 25.00 ms
|
||||
|
||||
/* Vertical servo */
|
||||
#define PANTILT_PWM_V_MIN_DUTY_CYCLE_US (950) // 0.95 ms
|
||||
#define PANTILT_PWM_V_MAX_DUTY_CYCLE_US (2150) // 2.15 ms
|
||||
|
||||
/* Horizontal servo */
|
||||
#define PANTILT_PWM_H_MIN_DUTY_CYCLE_US (1000) // 1.00 ms
|
||||
#define PANTILT_PWM_H_MAX_DUTY_CYCLE_US (2000) // 2.00 ms
|
||||
|
||||
pantilt_dev pantilt_inst(void *pwm_v_base, void *pwm_h_base);
|
||||
|
||||
void pantilt_init(pantilt_dev *dev);
|
||||
|
||||
void pantilt_configure_vertical(pantilt_dev *dev, uint32_t duty_cycle);
|
||||
void pantilt_configure_horizontal(pantilt_dev *dev, uint32_t duty_cycle);
|
||||
void pantilt_start_vertical(pantilt_dev *dev);
|
||||
void pantilt_start_horizontal(pantilt_dev *dev);
|
||||
void pantilt_stop_vertical(pantilt_dev *dev);
|
||||
void pantilt_stop_horizontal(pantilt_dev *dev);
|
||||
|
||||
#endif /* __PANTILT_H__ */
|
@ -0,0 +1,68 @@
|
||||
#include "pwm.h"
|
||||
#include "pwm_regs.h"
|
||||
#include "iorw.h"
|
||||
|
||||
#define MICROSEC_TO_CLK(time, freq) ((time) * ((freq) / 1000000))
|
||||
|
||||
/**
|
||||
* pwm_inst
|
||||
*
|
||||
* Instantiate a pwm device structure.
|
||||
*
|
||||
* @param base Base address of the component.
|
||||
*/
|
||||
pwm_dev pwm_inst(void *base) {
|
||||
pwm_dev dev;
|
||||
|
||||
dev.base = base;
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
/**
|
||||
* pwm_init
|
||||
*
|
||||
* Initializes the pwm device. This function stops the controller.
|
||||
*
|
||||
* @param dev pwm device structure.
|
||||
*/
|
||||
void pwm_init(pwm_dev *dev) {
|
||||
pwm_stop(dev);
|
||||
}
|
||||
|
||||
/**
|
||||
* pwm_configure
|
||||
*
|
||||
* Configure pwm component.
|
||||
*
|
||||
* @param dev pwm device structure.
|
||||
* @param duty_cycle pwm duty cycle in us.
|
||||
* @param period pwm period in us.
|
||||
* @param module_frequency frequency at which the component is clocked.
|
||||
*/
|
||||
void pwm_configure(pwm_dev *dev, uint32_t duty_cycle, uint32_t period, uint32_t module_frequency) {
|
||||
io_write_32(dev->base, PWM_PERIOD_OFST, MICROSEC_TO_CLK(period, module_frequency));
|
||||
io_write_32(dev->base, PWM_DUTY_CYCLE_OFST, MICROSEC_TO_CLK(duty_cycle, module_frequency));
|
||||
}
|
||||
|
||||
/**
|
||||
* pwm_start
|
||||
*
|
||||
* Starts the pwm controller.
|
||||
*
|
||||
* @param dev pwm device structure.
|
||||
*/
|
||||
void pwm_start(pwm_dev *dev) {
|
||||
io_write_32(dev->base, PWM_CTRL_OFST, PWM_CTRL_START_MASK);
|
||||
}
|
||||
|
||||
/**
|
||||
* pwm_stop
|
||||
*
|
||||
* Stops the pwm controller.
|
||||
*
|
||||
* @param dev pwm device structure.
|
||||
*/
|
||||
void pwm_stop(pwm_dev *dev) {
|
||||
io_write_32(dev->base, PWM_CTRL_OFST, PWM_CTRL_START_MASK);
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
#ifndef __PWM_H__
|
||||
#define __PWM_H__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/* pwm device structure */
|
||||
typedef struct pwm_dev {
|
||||
void *base; /* Base address of component */
|
||||
} pwm_dev;
|
||||
|
||||
/*******************************************************************************
|
||||
* Public API
|
||||
******************************************************************************/
|
||||
pwm_dev pwm_inst(void *base);
|
||||
|
||||
void pwm_init(pwm_dev *dev);
|
||||
void pwm_configure(pwm_dev *dev, uint32_t duty_cycle, uint32_t period, uint32_t module_frequency);
|
||||
void pwm_start(pwm_dev *dev);
|
||||
void pwm_stop(pwm_dev *dev);
|
||||
|
||||
#endif /* __PWM_H__ */
|
@ -0,0 +1,11 @@
|
||||
#ifndef __PWM_REGS_H__
|
||||
#define __PWM_REGS_H__
|
||||
|
||||
#define PWM_PERIOD_OFST (0 * 4) /* RW */
|
||||
#define PWM_DUTY_CYCLE_OFST (1 * 4) /* RW */
|
||||
#define PWM_CTRL_OFST (2 * 4) /* WO */
|
||||
|
||||
#define PWM_CTRL_STOP_MASK (0)
|
||||
#define PWM_CTRL_START_MASK (1)
|
||||
|
||||
#endif /* __PWM_REGS_H__ */
|
@ -0,0 +1,37 @@
|
||||
#include "socfpga_cyclone5_de0_sockit.dts"
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
#include <dt-bindings/interrupt-controller/irq.h>
|
||||
|
||||
#define VGA_SEQUENCER_REG_CSR 0x00
|
||||
#define VGA_SEQUENCER_REG_HBP 0x04
|
||||
#define VGA_SEQUENCER_REG_HFP 0x08
|
||||
#define VGA_SEQUENCER_REG_VBP 0x0c
|
||||
#define VGA_SEQUENCER_REG_VFP 0x10
|
||||
#define VGA_SEQUENCER_REG_HDATA 0x14
|
||||
#define VGA_SEQUENCER_REG_VDATA 0x18
|
||||
#define VGA_SEQUENCER_REG_HSYNC 0x1c
|
||||
#define VGA_SEQUENCER_REG_VSYNC 0x20
|
||||
|
||||
/ {
|
||||
soc {
|
||||
display {
|
||||
compatible = "prsoc,display";
|
||||
reg = <0xff200080 0x40 /* Frame manager <address span> */
|
||||
0xff200000 0x80>; /* VGA sequencer <address span> */
|
||||
interrupts = <GIC_SPI 40 IRQ_TYPE_EDGE_RISING>;
|
||||
prsoc,screen-width = <480>;
|
||||
prsoc,screen-height = <272>;
|
||||
prsoc,buffer-width = <480>;
|
||||
prsoc,buffer-height = <544>; // -> 2 buffers
|
||||
prsoc,reg-init = <VGA_SEQUENCER_REG_VSYNC 10>,
|
||||
<VGA_SEQUENCER_REG_VBP 2>,
|
||||
<VGA_SEQUENCER_REG_VDATA 272>,
|
||||
<VGA_SEQUENCER_REG_VFP 3>,
|
||||
<VGA_SEQUENCER_REG_HSYNC 41>,
|
||||
<VGA_SEQUENCER_REG_HBP 47>,
|
||||
<VGA_SEQUENCER_REG_HDATA 480>,
|
||||
<VGA_SEQUENCER_REG_HFP 8>,
|
||||
<VGA_SEQUENCER_REG_CSR 1>;
|
||||
};
|
||||
};
|
||||
};
|
9
cs309-psoc/lab_4_0/sw/hps/linux/driver/fbdev/Makefile
Normal file
9
cs309-psoc/lab_4_0/sw/hps/linux/driver/fbdev/Makefile
Normal file
@ -0,0 +1,9 @@
|
||||
obj-m += prsoc_fbdev.o
|
||||
|
||||
KERNEL_SOURCE_PATH='../../source/'
|
||||
|
||||
all:
|
||||
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -C $(KERNEL_SOURCE_PATH) M=$(PWD) modules
|
||||
|
||||
clean:
|
||||
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -C $(KERNEL_SOURCE_PATH) clean
|
416
cs309-psoc/lab_4_0/sw/hps/linux/driver/fbdev/prsoc_fbdev.c
Normal file
416
cs309-psoc/lab_4_0/sw/hps/linux/driver/fbdev/prsoc_fbdev.c
Normal file
@ -0,0 +1,416 @@
|
||||
/*
|
||||
* @file prsoc_vga_fbdev
|
||||
* @author Philemon Favrod
|
||||
* @date 18 May 2016
|
||||
* @brief The framebuffer Linux driver for the PrSoC extension board.
|
||||
*
|
||||
* This file is divided in two sections. The first contains the framebuffer
|
||||
* driver code. The second contains the boilerplate code to create the
|
||||
* device associated with the framebuffer. The latter allow us to use
|
||||
* much less error-prone APIs (devm_* or dmam_*).
|
||||
*
|
||||
* More precisely, the LCD is viewed as a platform device, i.e. a device
|
||||
* that is directly addressable from the CPU. Platform device are loaded
|
||||
* based on their compatible string (here "prsoc,display"). In other words,
|
||||
* once this driver is known to the kernel (c.f. insmod), the kernel will
|
||||
* call its associated probe function if its associated compatible string
|
||||
* is present in a device node (= an element of the device tree).
|
||||
*
|
||||
* In our case, the probe function is prsoc_display_platform_probe that you
|
||||
* can find at the end of this file. Its main role is to allocate the resources
|
||||
* based on what the device tree says. It uses the so-called managed API to
|
||||
* do so. This API has the advantage of letting the kernel do the clean up based on
|
||||
* whether or not the driver is loaded. It makes the code more readable.
|
||||
* At the end of the probe function, the framebuffer is registered.
|
||||
*
|
||||
* For more information about this, here is a collection of resources that
|
||||
* might be helpful:
|
||||
* - https://www.kernel.org/doc/Documentation/driver-model/platform.txt
|
||||
* -
|
||||
*
|
||||
* Revisions:
|
||||
* 5/18/2016 Created (only for simple VGA)
|
||||
* 5/28/2016 Adapted for TFT043
|
||||
* 5/28/2016 Extended with mmap support
|
||||
* 6/15/2016 Extend configurability from DT + panning
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/fb.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/types.h>
|
||||
|
||||
/* Offsets of the framebuffer manager's registers. */
|
||||
#define FM_REG_FRAME_START_ADDRESS 0x00
|
||||
#define FM_REG_FRAME_PIX_PER_LINE 0x04
|
||||
#define FM_REG_FRAME_NUM_LINES 0x08
|
||||
#define FM_REG_FRAME_EOL_BYTE_OFST 0x0C
|
||||
#define FM_REG_CONTROL 0x10
|
||||
#define FM_REG_BURST_COUNT 0x14
|
||||
|
||||
|
||||
#define FM_CONTROL_ENABLE_DMA_MASK (1UL << 0)
|
||||
#define FM_CONTROL_ENABLE_IRQ_MASK (1UL << 2)
|
||||
#define FM_CONTROL_ACKNOWLEDGE_IRQ_MASK (1UL << 4)
|
||||
|
||||
|
||||
/* Enclose the driver data. */
|
||||
struct prsoc_display_drvdata {
|
||||
uint8_t *fm_regs; /* a pointer to the frame manager's regs */
|
||||
uint8_t *lcd_int_regs; /* a pointer to the LCD interface's regs */
|
||||
|
||||
uint32_t *front_buffer; /* a dmable frame buffer */
|
||||
unsigned long front_buffer_phys; /* physical address of the frame buffer */
|
||||
int irq;
|
||||
};
|
||||
|
||||
#define FM_WR(DRVDATA, REG, VAL) \
|
||||
iowrite32((VAL), (DRVDATA)->fm_regs + (REG))
|
||||
#define LCD_INTERFACE_WR(DRVDATA, REG, VAL) \
|
||||
iowrite32((VAL), (DRVDATA)->lcd_int_regs + (REG))
|
||||
|
||||
/* Framebuffer driver */
|
||||
|
||||
/* ISR called at the end of each frame. Called at the beginning
|
||||
* of the vertical back porch, i.e. as soon as possible to avoid
|
||||
* tearing effect. */
|
||||
static irqreturn_t vsync_isr(int irq, void *data)
|
||||
{
|
||||
/*printk("IRQ received.\n");*/
|
||||
|
||||
//int i;
|
||||
struct prsoc_display_drvdata *drvdata = data;
|
||||
|
||||
/* Acknowledge the IRQ */
|
||||
FM_WR(drvdata, FM_REG_CONTROL, FM_CONTROL_ACKNOWLEDGE_IRQ_MASK);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
/* Defaults screen parameters */
|
||||
static struct fb_fix_screeninfo prsocfb_fix_defaults = {
|
||||
.id = "prsocfb",
|
||||
.type = FB_TYPE_PACKED_PIXELS,
|
||||
.visual = FB_VISUAL_DIRECTCOLOR,
|
||||
.accel = FB_ACCEL_NONE,
|
||||
.ypanstep = 1 // support y panning
|
||||
};
|
||||
|
||||
static struct fb_var_screeninfo prsocfb_var_defaults = {
|
||||
.bits_per_pixel = 32,
|
||||
.red = { .offset = 16, .length = 8 },
|
||||
.green = { .offset = 8, .length = 8 },
|
||||
.blue = { .offset = 0, .length = 8 }
|
||||
};
|
||||
|
||||
uint32_t pseudo_palette[16];
|
||||
static int prsocfb_setcoloreg(unsigned regno, unsigned red,
|
||||
unsigned green, unsigned blue,
|
||||
unsigned transp, struct fb_info *info)
|
||||
{
|
||||
if (regno >= 16)
|
||||
return -EINVAL;
|
||||
|
||||
red *= 0xff;
|
||||
green *= 0xff;
|
||||
blue *= 0xff;
|
||||
|
||||
red /= 0xffff;
|
||||
green /= 0xffff;
|
||||
blue /= 0xffff;
|
||||
|
||||
pseudo_palette[regno] = (red << 16) | (green << 8) | blue;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int prsocfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
|
||||
{
|
||||
struct prsoc_display_drvdata *drvdata = (struct prsoc_display_drvdata *)info->par;
|
||||
uint32_t byte_offset;
|
||||
|
||||
if ((var->yoffset + var->yres > var->yres_virtual) ||
|
||||
(var->xoffset + var->xres > var->xres_virtual))
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
byte_offset = (var->yoffset * info->fix.line_length) +
|
||||
(var->xoffset * (var->bits_per_pixel / 8));
|
||||
|
||||
FM_WR(drvdata, FM_REG_FRAME_START_ADDRESS, drvdata->front_buffer_phys + byte_offset);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* purpose: mmap the front buffer. */
|
||||
static int prsocfb_mmap(struct fb_info *info,
|
||||
struct vm_area_struct *vma)
|
||||
{
|
||||
struct prsoc_display_drvdata *drvdata = (struct prsoc_display_drvdata *)info->par;
|
||||
unsigned long start = vma->vm_start;
|
||||
unsigned long size = vma->vm_end - vma->vm_start;
|
||||
unsigned long screen_size = info->var.xres_virtual * info->var.yres_virtual * sizeof(uint32_t);
|
||||
unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
|
||||
unsigned long pfn = -1;
|
||||
void * pos = phys_to_virt(drvdata->front_buffer_phys) + offset;
|
||||
|
||||
vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); // non cachable page
|
||||
vma->vm_flags |= VM_IO;
|
||||
|
||||
/* Compute the screen size in PAGE_SIZE. */
|
||||
screen_size += PAGE_SIZE - 1;
|
||||
screen_size >>= PAGE_SHIFT;
|
||||
screen_size <<= PAGE_SHIFT;
|
||||
|
||||
/* Make sure that it maps only the back buffer */
|
||||
if (offset + size > screen_size) {
|
||||
printk(KERN_ERR "prsocfb: trying to mmap too much memory. %lu %lu %lu\n",
|
||||
offset, size, screen_size);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
while (size > 0) {
|
||||
/* Extract the page number of the current position
|
||||
* in the buffer. */
|
||||
pfn = virt_to_pfn(pos);
|
||||
|
||||
/* Map it in the user virtual memory. */
|
||||
if (remap_pfn_range(vma, start, pfn, PAGE_SIZE, vma->vm_page_prot)) {
|
||||
printk(KERN_ERR "prsocfb: remap_pfn_range failed\n");
|
||||
return -EAGAIN;
|
||||
}
|
||||
|
||||
start += PAGE_SIZE;
|
||||
pos += PAGE_SIZE;
|
||||
|
||||
if (size > PAGE_SIZE)
|
||||
size -= PAGE_SIZE;
|
||||
else
|
||||
size = 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct fb_ops prsocfb_ops = {
|
||||
.owner = THIS_MODULE,
|
||||
.fb_setcolreg = prsocfb_setcoloreg,
|
||||
.fb_fillrect = cfb_fillrect,
|
||||
.fb_copyarea = cfb_copyarea,
|
||||
.fb_imageblit = cfb_imageblit,
|
||||
.fb_mmap = prsocfb_mmap,
|
||||
.fb_pan_display = prsocfb_pan_display
|
||||
};
|
||||
|
||||
/* Platform driver */
|
||||
|
||||
/* Informs the kernel of the corresponding compatible string. */
|
||||
static const struct of_device_id prsoc_display_device_ids[] = {
|
||||
{ .compatible = "prsoc,display" },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, prsoc_display_device_ids);
|
||||
|
||||
/* To understand Device tree parsing, see:
|
||||
* - http://xillybus.com/tutorials/device-tree-zynq-4
|
||||
* - http://xillybus.com/tutorials/device-tree-zynq-5
|
||||
*/
|
||||
#define EXTRACT_INT_FROM_DT_OR_FAIL(NP, PROP) ({ \
|
||||
const void *property = of_get_property((NP), (PROP), NULL); \
|
||||
if (!property) { \
|
||||
printk(KERN_ERR "no '" PROP "' in the device tree."); \
|
||||
return -EINVAL; \
|
||||
} \
|
||||
be32_to_cpup(property); \
|
||||
})
|
||||
|
||||
/* Apply configuration from device tree. */
|
||||
static int configure_from_dt(
|
||||
struct platform_device *pdev,
|
||||
struct prsoc_display_drvdata *drvdata,
|
||||
struct fb_fix_screeninfo *fix_screeninfo,
|
||||
struct fb_var_screeninfo *var_screeninfo)
|
||||
{
|
||||
struct resource *rsrc;
|
||||
int err, i;
|
||||
|
||||
const __be32 *properties;
|
||||
int len;
|
||||
|
||||
/* Extract a pointer to the device node. */
|
||||
struct device_node *np = pdev->dev.of_node;
|
||||
dma_addr_t phys;
|
||||
|
||||
/* Get the width and height properties. */
|
||||
uint32_t screen_width = EXTRACT_INT_FROM_DT_OR_FAIL(np, "prsoc,screen-width");
|
||||
uint32_t screen_height = EXTRACT_INT_FROM_DT_OR_FAIL(np, "prsoc,screen-height");
|
||||
uint32_t buffer_width = EXTRACT_INT_FROM_DT_OR_FAIL(np, "prsoc,buffer-width");
|
||||
uint32_t buffer_height = EXTRACT_INT_FROM_DT_OR_FAIL(np, "prsoc,buffer-height");
|
||||
|
||||
printk(KERN_INFO "According to the device tree, the screen is %ux%u and the buffer is %ux%u.",
|
||||
screen_width, screen_height, buffer_width, buffer_height);
|
||||
|
||||
/* Maps the addresses of the registers of the framebuffer manager. */
|
||||
rsrc = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
drvdata->fm_regs = devm_ioremap_resource(&pdev->dev, rsrc);
|
||||
if (IS_ERR(drvdata->fm_regs))
|
||||
return PTR_ERR(drvdata->fm_regs);
|
||||
|
||||
printk(KERN_INFO "Framebuffer manager regs @ 0x%x-0x%x\n",
|
||||
rsrc->start, rsrc->end);
|
||||
|
||||
/* Maps the addresses of the video interface. */
|
||||
rsrc = platform_get_resource(pdev, IORESOURCE_MEM, 1);
|
||||
drvdata->lcd_int_regs = devm_ioremap_resource(&pdev->dev, rsrc);
|
||||
if (IS_ERR(drvdata->lcd_int_regs))
|
||||
return PTR_ERR(drvdata->lcd_int_regs);
|
||||
|
||||
printk(KERN_INFO "Interface regs @ 0x%x-0x%x\n", rsrc->start,
|
||||
rsrc->end);
|
||||
|
||||
/* Register the ISR for vertical blanking notification. */
|
||||
drvdata->irq = platform_get_irq(pdev, 0);
|
||||
err = devm_request_irq(
|
||||
&pdev->dev, drvdata->irq,
|
||||
(irq_handler_t) vsync_isr,
|
||||
0, "prsoc-fbdev", drvdata);
|
||||
if (err) {
|
||||
printk(KERN_ERR "couldn't register ISR. Is 'interrupts' " \
|
||||
"field in the device tree?\n");
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
/* Set the screeninfo to default values */
|
||||
*fix_screeninfo = prsocfb_fix_defaults;
|
||||
*var_screeninfo = prsocfb_var_defaults;
|
||||
|
||||
/* Set the size properties */
|
||||
var_screeninfo->xres = screen_width;
|
||||
var_screeninfo->yres = screen_height;
|
||||
var_screeninfo->xres_virtual = buffer_width;
|
||||
var_screeninfo->yres_virtual = buffer_height;
|
||||
fix_screeninfo->line_length = screen_width * sizeof(uint32_t);
|
||||
|
||||
/* Allocate DMAble frame buffer. */
|
||||
drvdata->front_buffer = dmam_alloc_coherent(
|
||||
&pdev->dev,
|
||||
buffer_width * buffer_height * sizeof(uint32_t),
|
||||
&phys,
|
||||
GFP_KERNEL);
|
||||
|
||||
if (!drvdata->front_buffer) {
|
||||
printk(KERN_ERR "prsoc_fbdev: couldn't allocate a dmable buffer.\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
drvdata->front_buffer_phys = (unsigned long)phys;
|
||||
printk(KERN_INFO "DMABLE BUFFER @ 0x%lx\n", drvdata->front_buffer_phys);
|
||||
|
||||
/* Parse the reg-init sequence */
|
||||
properties = of_get_property(pdev->dev.of_node, "prsoc,reg-init", &len);
|
||||
|
||||
if (!properties) {
|
||||
printk(KERN_INFO "no 'prsoc,reg-init' property found in Device Tree.\n");
|
||||
return 0; // reg-init is optional
|
||||
}
|
||||
|
||||
len /= sizeof(__be32);
|
||||
|
||||
if (len % 2 != 0) {
|
||||
printk(KERN_ERR "'prsoc,reg-init' in Device Tree should have format <ADDR1 VAL1>, <ADDR2 VAL2>, ...\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
printk(KERN_INFO "Initialize registers as specified in Device Tree:\n");
|
||||
for (i = 0; i < len; i += 2) {
|
||||
uint32_t offset = be32_to_cpup(properties + i);
|
||||
uint32_t value = be32_to_cpup(properties + i + 1);
|
||||
LCD_INTERFACE_WR(drvdata, offset, value);
|
||||
printk(KERN_INFO "\tWrite 0x%x at offset 0x%x\n", value, offset);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* The following method is called when the driver is loaded.
|
||||
* It collects information from the device tree.
|
||||
*/
|
||||
static int
|
||||
prsoc_display_platform_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct prsoc_display_drvdata *drvdata;
|
||||
struct fb_info *info;
|
||||
|
||||
/* Defensive programming: let's make sure this is the right device. */
|
||||
if (!of_match_device(prsoc_display_device_ids, &pdev->dev))
|
||||
return -EINVAL;
|
||||
|
||||
/* Allocate the framebuffer. */
|
||||
info = framebuffer_alloc(sizeof(struct prsoc_display_drvdata), &pdev->dev);
|
||||
if (!info) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* Extract the allocated driver data structure. */
|
||||
drvdata = (struct prsoc_display_drvdata *)info->par;
|
||||
|
||||
platform_set_drvdata(pdev, drvdata);
|
||||
|
||||
printk(KERN_INFO "Configure from Device Tree.\n");
|
||||
configure_from_dt(pdev, drvdata, &info->fix, &info->var);
|
||||
|
||||
printk(KERN_INFO "Initialize the Frame Manager.\n");
|
||||
FM_WR(drvdata, FM_REG_FRAME_START_ADDRESS, drvdata->front_buffer_phys);
|
||||
FM_WR(drvdata, FM_REG_FRAME_PIX_PER_LINE, info->var.xres);
|
||||
FM_WR(drvdata, FM_REG_FRAME_NUM_LINES, info->var.yres);
|
||||
FM_WR(drvdata, FM_REG_FRAME_EOL_BYTE_OFST, 0);
|
||||
FM_WR(drvdata, FM_REG_BURST_COUNT, 4);
|
||||
FM_WR(drvdata, FM_REG_CONTROL, FM_CONTROL_ENABLE_DMA_MASK);
|
||||
|
||||
/* Enable IRQ */
|
||||
// FM_WR(drvdata, FM_REG_CONTROL, FM_CONTROL_ENABLE_IRQ_MASK);
|
||||
|
||||
/* Configure the framebuffer */
|
||||
info->screen_base = (void *)drvdata->front_buffer;
|
||||
info->screen_size = info->var.xres * info->var.yres * sizeof(uint32_t);
|
||||
info->fbops = &prsocfb_ops;
|
||||
info->pseudo_palette = pseudo_palette;
|
||||
info->flags = FBINFO_DEFAULT;
|
||||
|
||||
if (fb_alloc_cmap(&info->cmap, 256, 0))
|
||||
return -ENOMEM;
|
||||
|
||||
return register_framebuffer(info);
|
||||
}
|
||||
|
||||
int prsoc_display_platform_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct prsoc_display_drvdata *drvdata = platform_get_drvdata(pdev);
|
||||
struct fb_info *info = container_of((void *)drvdata, struct fb_info, par);
|
||||
|
||||
unregister_framebuffer(info);
|
||||
fb_dealloc_cmap(&info->cmap);
|
||||
framebuffer_release(info);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver prsoc_display_pdriver = {
|
||||
.probe = prsoc_display_platform_probe,
|
||||
.driver = {
|
||||
.name = "PrSoC displays",
|
||||
.owner = THIS_MODULE,
|
||||
.of_match_table = prsoc_display_device_ids,
|
||||
},
|
||||
};
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
module_platform_driver(prsoc_display_pdriver);
|
23
cs309-psoc/lab_4_0/sw/hps/linux/rootfs/config_post_install.sh
Executable file
23
cs309-psoc/lab_4_0/sw/hps/linux/rootfs/config_post_install.sh
Executable file
@ -0,0 +1,23 @@
|
||||
#!/bin/bash -x
|
||||
|
||||
# apt sources
|
||||
# uncomment the "deb" lines (no need to uncomment "deb src" lines)
|
||||
|
||||
# Edit the “/etc/apt/sources.list” file to configure the package manager. This
|
||||
# file contains a list of mirrors that the package manager queries. By default,
|
||||
# this file has all fields commented out, so the package manager will not have
|
||||
# access to any mirrors. The following command uncomments all commented out
|
||||
# lines starting with "deb". These contain the mirrors we are interested in.
|
||||
sudo perl -pi -e 's/^#+\s+(deb\s+http)/$1/g' "/etc/apt/sources.list"
|
||||
|
||||
# When writing our linux applications, we want to use ARM DS-5’s remote
|
||||
# debugging feature to automatically transfer our binaries to the target device
|
||||
# and to start a debugging session. The remote debugging feature requires an SSH
|
||||
# server and a remote gdb server to be available on the target. These are easy
|
||||
# to install as we have a package manager available
|
||||
sudo apt update
|
||||
sudo apt -y install ssh gdbserver
|
||||
|
||||
# Allow root SSH login with password (needed so we can use ARM DS-5 for remote
|
||||
# debugging)
|
||||
sudo perl -pi -e 's/^(PermitRootLogin) without-password$/$1 yes/g' "/etc/ssh/sshd_config"
|
94
cs309-psoc/lab_4_0/sw/hps/linux/rootfs/config_system.sh
Executable file
94
cs309-psoc/lab_4_0/sw/hps/linux/rootfs/config_system.sh
Executable file
@ -0,0 +1,94 @@
|
||||
#!/bin/bash -x
|
||||
|
||||
# Configure the locale to have proper language support.
|
||||
localedef -i en_US -c -f UTF-8 en_US.UTF-8
|
||||
dpkg-reconfigure locales
|
||||
|
||||
# Configure the timezone.
|
||||
echo "Europe/Zurich" > "/etc/timezone"
|
||||
dpkg-reconfigure -f noninteractive tzdata
|
||||
|
||||
# Set the machine’s hostname.
|
||||
echo "DE0-Nano-SoC" > "/etc/hostname"
|
||||
tee "/etc/hosts" >"/dev/null" <<EOF
|
||||
127.0.0.1 localhost
|
||||
127.0.1.1 DE0-Nano-SoC
|
||||
EOF
|
||||
|
||||
# Create the “/etc/network/interfaces” file that describes the network
|
||||
# interfaces available on the board.
|
||||
tee "/etc/network/interfaces" > "/dev/null" <<EOF
|
||||
# interfaces(5) file used by ifup(8) and ifdown(8)
|
||||
|
||||
# The loopback network interface
|
||||
auto lo
|
||||
iface lo inet loopback
|
||||
|
||||
# The primary network interface
|
||||
auto eth0
|
||||
iface eth0 inet static
|
||||
address 10.42.0.2
|
||||
netmask 255.255.255.0
|
||||
gateway 10.42.0.1
|
||||
EOF
|
||||
|
||||
# DNS configuration for name resolution. We use google's public DNS server here.
|
||||
sudo tee "/etc/resolv.conf" > "/dev/null" <<EOF
|
||||
nameserver 8.8.8.8
|
||||
EOF
|
||||
|
||||
# Configure Ubuntu Core to display a login shell on the serial console once the
|
||||
# kernel boots. We had previously configured U-Boot to supply the command-line
|
||||
# argument "console=ttyS0,115200" to the linux kernel. This argument instructs
|
||||
# the kernel to use serial console “ttyS0” as the boot shell, so here we choose
|
||||
# to use the same serial console for the login shell-
|
||||
tee "/etc/init/ttyS0.conf" > "/dev/null" <<EOF
|
||||
# ttyS0 - getty
|
||||
#
|
||||
# This service maintains a getty on ttyS0
|
||||
|
||||
description "Get a getty on ttyS0"
|
||||
|
||||
start on runlevel [2345]
|
||||
stop on runlevel [016]
|
||||
|
||||
respawn
|
||||
|
||||
exec /sbin/getty -L 115200 ttyS0 vt102
|
||||
EOF
|
||||
|
||||
# Create a user and a password. In this example, we create a user called
|
||||
# “sahand” with password "1234". Note that we compute an encrypted version of
|
||||
# the password, because useradd does not allow plain text passwords to be used
|
||||
# in non-interactive mode.
|
||||
username="sahand"
|
||||
password="1234"
|
||||
encrypted_password="$(perl -e 'printf("%s\n", crypt($ARGV[0], "password"))' "${password}")"
|
||||
useradd -m -p "${encrypted_password}" -s "/bin/bash" "${username}"
|
||||
|
||||
# Ubuntu requires the admin to be part of the "adm" and "sudo" groups, so add
|
||||
# the previously-created user to the 2 groups.
|
||||
addgroup ${username} adm
|
||||
addgroup ${username} sudo
|
||||
|
||||
# Set root password to "1234" (same as previously-created user).
|
||||
echo -e "${password}\n${password}\n" | passwd root
|
||||
|
||||
# Remove "/rootfs_config.sh" from /etc/rc.local to avoid reconfiguring system on
|
||||
# next boot
|
||||
tee "/etc/rc.local" > "/dev/null" <<EOF
|
||||
#!/bin/sh -e
|
||||
#
|
||||
# rc.local
|
||||
#
|
||||
# This script is executed at the end of each multiuser runlevel.
|
||||
# Make sure that the script will "exit 0" on success or any other
|
||||
# value on error.
|
||||
#
|
||||
# In order to enable or disable this script just change the execution
|
||||
# bits.
|
||||
#
|
||||
# By default this script does nothing.
|
||||
|
||||
exit 0
|
||||
EOF
|
Reference in New Issue
Block a user