Added Nexys Video Vivado/OpenXC7 support
This commit is contained in:
parent
eaa45f01d5
commit
7c196bf595
|
|
@ -194,6 +194,15 @@ The summary under `TEST CALIBRATION` are the results from the **internal** read/
|
|||
|
||||
This will run the DDR3 controller at 333 MHz (3 ns clock period) which is the [maximum clock period for Arty-S7](https://digilent.com/reference/programmable-logic/arty-s7/reference-manual). Upload the bitstream to Arty-S7, after around 2 seconds the 4 LEDS should light up.
|
||||
|
||||
- The [Nexys Video](./nexys_video) project utilizes the DDR3 chip on the Digilent Nexys Video board with xc7a200t. Only one lane is used for simplicity. Supports OpenXC7 toolchain. Makefiles have been included for quick start, just run the following command in the root directory of repo:
|
||||
|
||||
- Vivado compilation: `source /opt/Xilinx/Vivado/2019.1/settings64.sh` then `make -C nexys_video -f Makefile.vivado`
|
||||
- OpenXC7 compilation (using toolchain in Docker): `docker run --rm -v .:/mnt -v /chipdb:/chipdb regymm/openxc7 make -C /mnt/nexys_video -f Makefile.openxc7`
|
||||
|
||||
The bitstream will be compiled as `nexys_video/build/top.bit`.
|
||||
|
||||
- Board test: after programming bitstream, the 8 LEDs will show some pattern, then become all lit up after calibration. When pressing BTND(D22), LD7/LD6 will show a blinky, and LD5-LD0 will show 101110 after successful calibration. BTNC(B22) resets the controller, and calibration will be redone. 9600 baud UART will be the same as the Arty-S7 case: type small `abcd` to write to memory, and type capital `ABCD` to read back. For example, type `abcd` then `ABCDEFGH` will show `abcd<63><64><EFBFBD><EFBFBD>` (because EFGH memory locations are not written yet).
|
||||
|
||||
- The [10Gb Ethernet Switch](https://github.com/ZipCPU/eth10g) project utilizes this DDR3 controller for accessing a single-rank DDR3 module (8 lanes of x8 DDR3) at DDR3-800 (100 MHz controller and 400 MHz PHY).
|
||||
|
||||
# Other Open-Sourced DDR3 Controllers
|
||||
|
|
|
|||
|
|
@ -0,0 +1,50 @@
|
|||
# Generated by https://github.com/FPGAOL-CE/caas-wizard
|
||||
DB_DIR = /nextpnr-xilinx/xilinx/external/prjxray-db
|
||||
CHIPDB = /chipdb
|
||||
|
||||
BUILDDIR := ${CURDIR}/build
|
||||
TOP := nexysvideo_ddr3
|
||||
#SOURCES := $(wildcard *.v) $(wildcard ../rtl/*.v) $(wildcard ../arty_s7/verilog-uart/rtl/*.v)
|
||||
XDC := $(wildcard $(wildcard Nexys-video.xdc) )
|
||||
|
||||
CHIPFAM := artix7
|
||||
PART := xc7a200tsbg484-1
|
||||
|
||||
LOGFILE := ${BUILDDIR}/top.log
|
||||
|
||||
all: ${CHIPDB} ${BUILDDIR} ${BUILDDIR}/top.bit
|
||||
|
||||
${BUILDDIR}:
|
||||
mkdir -m 777 -p ${BUILDDIR} && chown -R nobody ${BUILDDIR} | true
|
||||
|
||||
${CHIPDB}:
|
||||
mkdir -m 777 -p ${CHIPDB} && chown -R nobody ${CHIPDB} | true
|
||||
|
||||
# we run this in parent directory to seeminglessly import user source files
|
||||
# otherwise have to parse user pattern and add ../
|
||||
${BUILDDIR}/top.json: $(wildcard *.v) $(wildcard ../rtl/*.v) $(wildcard ../arty_s7/verilog-uart/rtl/*.v)
|
||||
yosys -p "synth_xilinx -flatten -abc9 -arch xc7 -top ${TOP}; write_json ${BUILDDIR}/top.json" $^ >> ${LOGFILE} 2>&1
|
||||
|
||||
# The chip database only needs to be generated once
|
||||
# that is why we don't clean it with make clean
|
||||
${CHIPDB}/${PART}.bin:
|
||||
pypy3 /nextpnr-xilinx/xilinx/python/bbaexport.py --device ${PART} --bba ${PART}.bba
|
||||
bbasm -l ${PART}.bba ${CHIPDB}/${PART}.bin
|
||||
rm -f ${PART}.bba
|
||||
|
||||
${BUILDDIR}/top.fasm: ${BUILDDIR}/top.json ${CHIPDB}/${PART}.bin
|
||||
nextpnr-xilinx --chipdb ${CHIPDB}/${PART}.bin --xdc ${XDC} --json ${BUILDDIR}/top.json --pre-place constraints.py --pre-route show_bels.py --fasm $@ >> ${LOGFILE} 2>&1
|
||||
#nextpnr-xilinx --chipdb ${CHIPDB}/${PART}.bin --xdc ${XDC} --json ${BUILDDIR}/top.json --fasm $@ >> ${LOGFILE} 2>&1
|
||||
|
||||
${BUILDDIR}/top.frames: ${BUILDDIR}/top.fasm
|
||||
fasm2frames --part ${PART} --db-root ${DB_DIR}/${CHIPFAM} $< > $@
|
||||
|
||||
${BUILDDIR}/top.bit: ${BUILDDIR}/top.frames
|
||||
xc7frames2bit --part_file ${DB_DIR}/${CHIPFAM}/${PART}/part.yaml --part_name ${PART} --frm_file $< --output_file $@ >> ${LOGFILE} 2>&1
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
@rm -f *.bit
|
||||
@rm -f *.frames
|
||||
@rm -f *.fasm
|
||||
@rm -f *.json
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
# Generated by https://github.com/FPGAOL-CE/caas-wizard
|
||||
BUILDDIR := ${CURDIR}/build
|
||||
# TOP := nexysvideo_ddr3
|
||||
# SOURCES := $(wildcard *.v ../rtl/ddr3*.v ../arty_s7/verilog-uart/rtl/*.v)
|
||||
# XDC := $(wildcard $(wildcard Nexys-video.xdc) $(wildcard Nexys-video-vivado.xdc) )
|
||||
|
||||
# PART := xc7a200tsbg484-1
|
||||
|
||||
LOGFILE := ${BUILDDIR}/top.log
|
||||
|
||||
# Build design
|
||||
all: ${BUILDDIR}/top.bit
|
||||
|
||||
${BUILDDIR}:
|
||||
mkdir -m 777 -p ${BUILDDIR} && chown -R nobody ${BUILDDIR} | true
|
||||
|
||||
.ONESHELL:
|
||||
${BUILDDIR}/vivado.tcl: ${BUILDDIR}
|
||||
cat << EOF > $@
|
||||
# vivado.tcl generated for caas
|
||||
# can be launched from any directory
|
||||
cd ${BUILDDIR}
|
||||
create_project -part xc7a200tsbg484-1 -force v_proj
|
||||
set_property target_language Verilog [current_project]
|
||||
cd ..
|
||||
read_verilog [glob *.v ../rtl/ddr3*.v ../arty_s7/verilog-uart/rtl/*.v]
|
||||
read_xdc [glob $(wildcard Nexys-video.xdc) $(wildcard Nexys-video-vivado.xdc) ]
|
||||
cd build
|
||||
synth_design -top nexysvideo_ddr3
|
||||
opt_design
|
||||
place_design
|
||||
phys_opt_design
|
||||
route_design
|
||||
write_bitstream -verbose -force top.bit
|
||||
# report_utilization -file util.rpt
|
||||
# report_timing_summary -file timing.rpt
|
||||
EOF
|
||||
|
||||
${BUILDDIR}/top.bit: ${BUILDDIR}/vivado.tcl
|
||||
cd ${BUILDDIR} && vivado -mode batch -source $< > ${LOGFILE} 2>&1
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
rm -rf ${BUILDDIR}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
set_property INTERNAL_VREF 0.75 [get_iobanks 35]
|
||||
set_property CONFIG_VOLTAGE 3.3 [current_design]
|
||||
set_property CFGBVS VCCO [current_design]
|
||||
|
|
@ -0,0 +1,242 @@
|
|||
set_property -dict {PACKAGE_PIN R4 IOSTANDARD LVCMOS33} [get_ports i_clk]
|
||||
create_clock -period 10.000 -name sys_clk_pin -waveform {0.000 5.000} -add [get_ports i_clk]
|
||||
|
||||
set_property -dict {PACKAGE_PIN T14 IOSTANDARD LVCMOS33} [get_ports {led[0]}]
|
||||
set_property -dict {PACKAGE_PIN T15 IOSTANDARD LVCMOS33} [get_ports {led[1]}]
|
||||
set_property -dict {PACKAGE_PIN T16 IOSTANDARD LVCMOS33} [get_ports {led[2]}]
|
||||
set_property -dict {PACKAGE_PIN U16 IOSTANDARD LVCMOS33} [get_ports {led[3]}]
|
||||
set_property -dict {PACKAGE_PIN V15 IOSTANDARD LVCMOS33} [get_ports {led[4]}]
|
||||
set_property -dict {PACKAGE_PIN W16 IOSTANDARD LVCMOS33} [get_ports {led[5]}]
|
||||
set_property -dict {PACKAGE_PIN W15 IOSTANDARD LVCMOS33} [get_ports {led[6]}]
|
||||
set_property -dict {PACKAGE_PIN Y13 IOSTANDARD LVCMOS33} [get_ports {led[7]}]
|
||||
|
||||
set_property -dict {PACKAGE_PIN B22 IOSTANDARD LVCMOS33} [get_ports i_rst]
|
||||
set_property -dict {PACKAGE_PIN D22 IOSTANDARD LVCMOS33} [get_ports {btn[0]}]
|
||||
set_property -dict {PACKAGE_PIN C22 IOSTANDARD LVCMOS33} [get_ports {btn[1]}]
|
||||
set_property -dict {PACKAGE_PIN D14 IOSTANDARD LVCMOS33} [get_ports {btn[2]}]
|
||||
set_property -dict {PACKAGE_PIN F15 IOSTANDARD LVCMOS33} [get_ports {btn[3]}]
|
||||
|
||||
set_property -dict {PACKAGE_PIN AA19 IOSTANDARD LVCMOS33} [get_ports tx]
|
||||
set_property -dict {PACKAGE_PIN V18 IOSTANDARD LVCMOS33} [get_ports rx]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_dq[0]}]
|
||||
set_property IN_TERM UNTUNED_SPLIT_50 [get_ports {ddr3_dq[0]}]
|
||||
set_property IOSTANDARD SSTL15 [get_ports {ddr3_dq[0]}]
|
||||
set_property PACKAGE_PIN G2 [get_ports {ddr3_dq[0]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_dq[1]}]
|
||||
set_property IN_TERM UNTUNED_SPLIT_50 [get_ports {ddr3_dq[1]}]
|
||||
set_property IOSTANDARD SSTL15 [get_ports {ddr3_dq[1]}]
|
||||
set_property PACKAGE_PIN H4 [get_ports {ddr3_dq[1]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_dq[2]}]
|
||||
set_property IN_TERM UNTUNED_SPLIT_50 [get_ports {ddr3_dq[2]}]
|
||||
set_property IOSTANDARD SSTL15 [get_ports {ddr3_dq[2]}]
|
||||
set_property PACKAGE_PIN H5 [get_ports {ddr3_dq[2]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_dq[3]}]
|
||||
set_property IN_TERM UNTUNED_SPLIT_50 [get_ports {ddr3_dq[3]}]
|
||||
set_property IOSTANDARD SSTL15 [get_ports {ddr3_dq[3]}]
|
||||
set_property PACKAGE_PIN J1 [get_ports {ddr3_dq[3]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_dq[4]}]
|
||||
set_property IN_TERM UNTUNED_SPLIT_50 [get_ports {ddr3_dq[4]}]
|
||||
set_property IOSTANDARD SSTL15 [get_ports {ddr3_dq[4]}]
|
||||
set_property PACKAGE_PIN K1 [get_ports {ddr3_dq[4]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_dq[5]}]
|
||||
set_property IN_TERM UNTUNED_SPLIT_50 [get_ports {ddr3_dq[5]}]
|
||||
set_property IOSTANDARD SSTL15 [get_ports {ddr3_dq[5]}]
|
||||
set_property PACKAGE_PIN H3 [get_ports {ddr3_dq[5]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_dq[6]}]
|
||||
set_property IN_TERM UNTUNED_SPLIT_50 [get_ports {ddr3_dq[6]}]
|
||||
set_property IOSTANDARD SSTL15 [get_ports {ddr3_dq[6]}]
|
||||
set_property PACKAGE_PIN H2 [get_ports {ddr3_dq[6]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_dq[7]}]
|
||||
set_property IN_TERM UNTUNED_SPLIT_50 [get_ports {ddr3_dq[7]}]
|
||||
set_property IOSTANDARD SSTL15 [get_ports {ddr3_dq[7]}]
|
||||
set_property PACKAGE_PIN J5 [get_ports {ddr3_dq[7]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_dq[8]}]
|
||||
set_property IN_TERM UNTUNED_SPLIT_50 [get_ports {ddr3_dq[8]}]
|
||||
set_property IOSTANDARD SSTL15 [get_ports {ddr3_dq[8]}]
|
||||
set_property PACKAGE_PIN E3 [get_ports {ddr3_dq[8]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_dq[9]}]
|
||||
set_property IN_TERM UNTUNED_SPLIT_50 [get_ports {ddr3_dq[9]}]
|
||||
set_property IOSTANDARD SSTL15 [get_ports {ddr3_dq[9]}]
|
||||
set_property PACKAGE_PIN B2 [get_ports {ddr3_dq[9]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_dq[10]}]
|
||||
set_property IN_TERM UNTUNED_SPLIT_50 [get_ports {ddr3_dq[10]}]
|
||||
set_property IOSTANDARD SSTL15 [get_ports {ddr3_dq[10]}]
|
||||
set_property PACKAGE_PIN F3 [get_ports {ddr3_dq[10]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_dq[11]}]
|
||||
set_property IN_TERM UNTUNED_SPLIT_50 [get_ports {ddr3_dq[11]}]
|
||||
set_property IOSTANDARD SSTL15 [get_ports {ddr3_dq[11]}]
|
||||
set_property PACKAGE_PIN D2 [get_ports {ddr3_dq[11]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_dq[12]}]
|
||||
set_property IN_TERM UNTUNED_SPLIT_50 [get_ports {ddr3_dq[12]}]
|
||||
set_property IOSTANDARD SSTL15 [get_ports {ddr3_dq[12]}]
|
||||
set_property PACKAGE_PIN C2 [get_ports {ddr3_dq[12]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_dq[13]}]
|
||||
set_property IN_TERM UNTUNED_SPLIT_50 [get_ports {ddr3_dq[13]}]
|
||||
set_property IOSTANDARD SSTL15 [get_ports {ddr3_dq[13]}]
|
||||
set_property PACKAGE_PIN A1 [get_ports {ddr3_dq[13]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_dq[14]}]
|
||||
set_property IN_TERM UNTUNED_SPLIT_50 [get_ports {ddr3_dq[14]}]
|
||||
set_property IOSTANDARD SSTL15 [get_ports {ddr3_dq[14]}]
|
||||
set_property PACKAGE_PIN E2 [get_ports {ddr3_dq[14]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_dq[15]}]
|
||||
set_property IN_TERM UNTUNED_SPLIT_50 [get_ports {ddr3_dq[15]}]
|
||||
set_property IOSTANDARD SSTL15 [get_ports {ddr3_dq[15]}]
|
||||
set_property PACKAGE_PIN B1 [get_ports {ddr3_dq[15]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_addr[14]}]
|
||||
set_property IOSTANDARD SSTL15 [get_ports {ddr3_addr[14]}]
|
||||
set_property PACKAGE_PIN P6 [get_ports {ddr3_addr[14]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_addr[13]}]
|
||||
set_property IOSTANDARD SSTL15 [get_ports {ddr3_addr[13]}]
|
||||
set_property PACKAGE_PIN P2 [get_ports {ddr3_addr[13]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_addr[12]}]
|
||||
set_property IOSTANDARD SSTL15 [get_ports {ddr3_addr[12]}]
|
||||
set_property PACKAGE_PIN N4 [get_ports {ddr3_addr[12]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_addr[11]}]
|
||||
set_property IOSTANDARD SSTL15 [get_ports {ddr3_addr[11]}]
|
||||
set_property PACKAGE_PIN N5 [get_ports {ddr3_addr[11]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_addr[10]}]
|
||||
set_property IOSTANDARD SSTL15 [get_ports {ddr3_addr[10]}]
|
||||
set_property PACKAGE_PIN L5 [get_ports {ddr3_addr[10]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_addr[9]}]
|
||||
set_property IOSTANDARD SSTL15 [get_ports {ddr3_addr[9]}]
|
||||
set_property PACKAGE_PIN R1 [get_ports {ddr3_addr[9]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_addr[8]}]
|
||||
set_property IOSTANDARD SSTL15 [get_ports {ddr3_addr[8]}]
|
||||
set_property PACKAGE_PIN M6 [get_ports {ddr3_addr[8]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_addr[7]}]
|
||||
set_property IOSTANDARD SSTL15 [get_ports {ddr3_addr[7]}]
|
||||
set_property PACKAGE_PIN N2 [get_ports {ddr3_addr[7]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_addr[6]}]
|
||||
set_property IOSTANDARD SSTL15 [get_ports {ddr3_addr[6]}]
|
||||
set_property PACKAGE_PIN N3 [get_ports {ddr3_addr[6]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_addr[5]}]
|
||||
set_property IOSTANDARD SSTL15 [get_ports {ddr3_addr[5]}]
|
||||
set_property PACKAGE_PIN P1 [get_ports {ddr3_addr[5]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_addr[4]}]
|
||||
set_property IOSTANDARD SSTL15 [get_ports {ddr3_addr[4]}]
|
||||
set_property PACKAGE_PIN L6 [get_ports {ddr3_addr[4]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_addr[3]}]
|
||||
set_property IOSTANDARD SSTL15 [get_ports {ddr3_addr[3]}]
|
||||
set_property PACKAGE_PIN M1 [get_ports {ddr3_addr[3]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_addr[2]}]
|
||||
set_property IOSTANDARD SSTL15 [get_ports {ddr3_addr[2]}]
|
||||
set_property PACKAGE_PIN M3 [get_ports {ddr3_addr[2]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_addr[1]}]
|
||||
set_property IOSTANDARD SSTL15 [get_ports {ddr3_addr[1]}]
|
||||
set_property PACKAGE_PIN M5 [get_ports {ddr3_addr[1]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_addr[0]}]
|
||||
set_property IOSTANDARD SSTL15 [get_ports {ddr3_addr[0]}]
|
||||
set_property PACKAGE_PIN M2 [get_ports {ddr3_addr[0]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_ba[2]}]
|
||||
set_property IOSTANDARD SSTL15 [get_ports {ddr3_ba[2]}]
|
||||
set_property PACKAGE_PIN L4 [get_ports {ddr3_ba[2]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_ba[1]}]
|
||||
set_property IOSTANDARD SSTL15 [get_ports {ddr3_ba[1]}]
|
||||
set_property PACKAGE_PIN K6 [get_ports {ddr3_ba[1]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_ba[0]}]
|
||||
set_property IOSTANDARD SSTL15 [get_ports {ddr3_ba[0]}]
|
||||
set_property PACKAGE_PIN L3 [get_ports {ddr3_ba[0]}]
|
||||
|
||||
set_property SLEW FAST [get_ports ddr3_ras_n]
|
||||
set_property IOSTANDARD SSTL15 [get_ports ddr3_ras_n]
|
||||
set_property PACKAGE_PIN J4 [get_ports ddr3_ras_n]
|
||||
|
||||
set_property SLEW FAST [get_ports ddr3_cas_n]
|
||||
set_property IOSTANDARD SSTL15 [get_ports ddr3_cas_n]
|
||||
set_property PACKAGE_PIN K3 [get_ports ddr3_cas_n]
|
||||
|
||||
set_property SLEW FAST [get_ports ddr3_we_n]
|
||||
set_property IOSTANDARD SSTL15 [get_ports ddr3_we_n]
|
||||
set_property PACKAGE_PIN L1 [get_ports ddr3_we_n]
|
||||
|
||||
set_property SLEW FAST [get_ports ddr3_reset_n]
|
||||
set_property IOSTANDARD SSTL15 [get_ports ddr3_reset_n]
|
||||
set_property PACKAGE_PIN G1 [get_ports ddr3_reset_n]
|
||||
|
||||
set_property SLEW FAST [get_ports ddr3_cke]
|
||||
set_property IOSTANDARD SSTL15 [get_ports ddr3_cke]
|
||||
set_property PACKAGE_PIN J6 [get_ports ddr3_cke]
|
||||
|
||||
set_property SLEW FAST [get_ports ddr3_odt]
|
||||
set_property IOSTANDARD SSTL15 [get_ports ddr3_odt]
|
||||
set_property PACKAGE_PIN K4 [get_ports ddr3_odt]
|
||||
|
||||
set_property SLEW FAST [get_ports ddr3_cs_n]
|
||||
set_property IOSTANDARD LVCMOS33 [get_ports ddr3_cs_n]
|
||||
set_property PACKAGE_PIN R3 [get_ports ddr3_cs_n]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_dm[0]}]
|
||||
set_property IOSTANDARD SSTL15 [get_ports {ddr3_dm[0]}]
|
||||
set_property PACKAGE_PIN G3 [get_ports {ddr3_dm[0]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_dm[1]}]
|
||||
set_property IOSTANDARD SSTL15 [get_ports {ddr3_dm[1]}]
|
||||
set_property PACKAGE_PIN F1 [get_ports {ddr3_dm[1]}]
|
||||
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_dqs_p}]
|
||||
set_property IN_TERM UNTUNED_SPLIT_50 [get_ports {ddr3_dqs_p}]
|
||||
set_property IOSTANDARD DIFF_SSTL15 [get_ports {ddr3_dqs_p}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_dqs_n}]
|
||||
set_property IN_TERM UNTUNED_SPLIT_50 [get_ports {ddr3_dqs_n}]
|
||||
set_property IOSTANDARD DIFF_SSTL15 [get_ports {ddr3_dqs_n}]
|
||||
set_property PACKAGE_PIN K2 [get_ports {ddr3_dqs_p}]
|
||||
set_property PACKAGE_PIN J2 [get_ports {ddr3_dqs_n}]
|
||||
|
||||
#set_property SLEW FAST [get_ports {ddr3_dqs_p[1]}]
|
||||
#set_property IN_TERM UNTUNED_SPLIT_50 [get_ports {ddr3_dqs_p[1]}]
|
||||
#set_property IOSTANDARD DIFF_SSTL15 [get_ports {ddr3_dqs_p[1]}]
|
||||
|
||||
#set_property SLEW FAST [get_ports {ddr3_dqs_n[1]}]
|
||||
#set_property IN_TERM UNTUNED_SPLIT_50 [get_ports {ddr3_dqs_n[1]}]
|
||||
#set_property IOSTANDARD DIFF_SSTL15 [get_ports {ddr3_dqs_n[1]}]
|
||||
#set_property PACKAGE_PIN E1 [get_ports {ddr3_dqs_p[1]}]
|
||||
#set_property PACKAGE_PIN D1 [get_ports {ddr3_dqs_n[1]}]
|
||||
|
||||
set_property SLEW FAST [get_ports ddr3_clk_p]
|
||||
set_property IOSTANDARD DIFF_SSTL15 [get_ports ddr3_clk_p]
|
||||
|
||||
set_property SLEW FAST [get_ports ddr3_clk_n]
|
||||
set_property IOSTANDARD DIFF_SSTL15 [get_ports ddr3_clk_n]
|
||||
set_property PACKAGE_PIN P5 [get_ports ddr3_clk_p]
|
||||
set_property PACKAGE_PIN P4 [get_ports ddr3_clk_n]
|
||||
|
||||
#set_property INTERNAL_VREF 0.75 [get_iobanks 35]
|
||||
#set_property CONFIG_VOLTAGE 3.3 [current_design]
|
||||
#set_property CFGBVS VCCO [current_design]
|
||||
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
`timescale 1ps/1ps
|
||||
|
||||
module clk_wiz
|
||||
(
|
||||
input clk_in1,
|
||||
output clk_out1,
|
||||
output clk_out2,
|
||||
output clk_out3,
|
||||
output clk_out4,
|
||||
input reset,
|
||||
output locked
|
||||
);
|
||||
wire clk_out1_clk_wiz_0;
|
||||
wire clk_out2_clk_wiz_0;
|
||||
wire clk_out3_clk_wiz_0;
|
||||
wire clk_out4_clk_wiz_0;
|
||||
|
||||
wire clkfbout;
|
||||
|
||||
PLLE2_ADV
|
||||
#(.BANDWIDTH ("OPTIMIZED"),
|
||||
.COMPENSATION ("INTERNAL"),
|
||||
.STARTUP_WAIT ("FALSE"),
|
||||
.DIVCLK_DIVIDE (1),
|
||||
.CLKFBOUT_MULT (10), // 100 MHz * 10 = 1000 MHz
|
||||
.CLKFBOUT_PHASE (0.000),
|
||||
.CLKOUT0_DIVIDE (12), // 1000 MHz / 12 = 83.333 MHz
|
||||
.CLKOUT0_PHASE (0.000),
|
||||
.CLKOUT0_DUTY_CYCLE (0.500),
|
||||
.CLKOUT1_DIVIDE (3), // 1000 MHz / 3 = 333.333 MHz
|
||||
.CLKOUT1_PHASE (0.000),
|
||||
.CLKOUT1_DUTY_CYCLE (0.500),
|
||||
.CLKOUT2_DIVIDE (5), // 1000 MHz / 5 = 200 MHz
|
||||
.CLKOUT2_PHASE (0.000),
|
||||
.CLKOUT2_DUTY_CYCLE (0.500),
|
||||
.CLKOUT3_DIVIDE (3), // 1000 MHz / 3 = 333.333 MHz, 90 phase
|
||||
.CLKOUT3_PHASE (90.000),
|
||||
.CLKOUT3_DUTY_CYCLE (0.500),
|
||||
.CLKIN1_PERIOD (10.000) // 100 MHz input
|
||||
)
|
||||
plle2_adv_inst
|
||||
(
|
||||
.CLKFBOUT (clkfbout),
|
||||
.CLKOUT0 (clk_out1_clk_wiz_0),
|
||||
.CLKOUT1 (clk_out2_clk_wiz_0),
|
||||
.CLKOUT2 (clk_out3_clk_wiz_0),
|
||||
.CLKOUT3 (clk_out4_clk_wiz_0),
|
||||
.CLKFBIN (clkfbout),
|
||||
.CLKIN1 (clk_in1),
|
||||
.LOCKED (locked),
|
||||
.RST (reset)
|
||||
);
|
||||
BUFG clkout1_buf
|
||||
(.O (clk_out1),
|
||||
.I (clk_out1_clk_wiz_0));
|
||||
BUFG clkout2_buf
|
||||
(.O (clk_out2),
|
||||
.I (clk_out2_clk_wiz_0));
|
||||
BUFG clkout3_buf
|
||||
(.O (clk_out3),
|
||||
.I (clk_out3_clk_wiz_0));
|
||||
BUFG clkout4_buf
|
||||
(.O (clk_out4),
|
||||
.I (clk_out4_clk_wiz_0));
|
||||
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
#!/usr/bin/env python3
|
||||
ddr3_name = 'ddr3_top_inst.ddr3_phy_inst'
|
||||
def get_cells(name_part):
|
||||
return list(map(lambda c: c.second, filter(lambda c: name_part in c.first, ctx.cells)))
|
||||
|
||||
def get_cell(name_part):
|
||||
return get_cells(name_part)[0]
|
||||
|
||||
c1=get_cell(ddr3_name + '.genblk5[0].ISERDESE2_train')
|
||||
c3=get_cell(ddr3_name + '.genblk5[0].OSERDESE2_train')
|
||||
|
||||
# c2=get_cell(ddr3_name + '.genblk5[1].ISERDESE2_train')
|
||||
# c4=get_cell(ddr3_name + '.genblk5[1].OSERDESE2_train')
|
||||
|
||||
# Usually, nextpnr-xilinx would place these on X0Y149, but
|
||||
# prjxray has missing PIPs on _SING tiles, so we need to
|
||||
# place these on a non-SING tile to make it work
|
||||
c1.setAttr('BEL', 'ILOGIC_X1Y193/ISERDESE2')
|
||||
c3.setAttr('BEL', 'OLOGIC_X1Y193/OSERDESE2')
|
||||
# c2.setAttr('BEL', 'ILOGIC_X0Y245/ISERDESE2')
|
||||
# c4.setAttr('BEL', 'OLOGIC_X0Y245/OSERDESE2')
|
||||
|
|
@ -0,0 +1,195 @@
|
|||
`timescale 1ns / 1ps
|
||||
|
||||
module nexysvideo_ddr3
|
||||
(
|
||||
input wire i_clk,
|
||||
input wire i_rst,
|
||||
// DDR3 I/O Interface
|
||||
output wire ddr3_clk_p, ddr3_clk_n,
|
||||
output wire ddr3_reset_n,
|
||||
output wire ddr3_cke, // CKE
|
||||
output wire ddr3_cs_n, // chip select signal
|
||||
output wire ddr3_ras_n, // RAS#
|
||||
output wire ddr3_cas_n, // CAS#
|
||||
output wire ddr3_we_n, // WE#
|
||||
output wire[14-1:0] ddr3_addr,
|
||||
output wire[3-1:0] ddr3_ba,
|
||||
inout wire[16-1:0] ddr3_dq,
|
||||
inout wire[1-1:0] ddr3_dqs_p, ddr3_dqs_n,
|
||||
output wire[2-1:0] ddr3_dm,
|
||||
output wire ddr3_odt, // on-die termination
|
||||
// UART line
|
||||
input wire rx,
|
||||
output wire tx,
|
||||
//Debug LEDs
|
||||
output reg[7:0] led,
|
||||
input wire[3:0] btn
|
||||
);
|
||||
|
||||
wire i_controller_clk, i_ddr3_clk, i_ref_clk, i_ddr3_clk_90;
|
||||
wire m_axis_tvalid;
|
||||
wire rx_empty;
|
||||
wire tx_full;
|
||||
wire o_wb_ack;
|
||||
wire[7:0] o_wb_data;
|
||||
wire o_aux;
|
||||
wire[7:0] rd_data;
|
||||
wire o_wb_stall;
|
||||
reg i_wb_stb = 0, i_wb_we;
|
||||
wire[63:0] o_debug1;
|
||||
wire[31:0] o_debug2;
|
||||
reg[7:0] i_wb_data;
|
||||
reg[7:0] i_wb_addr;
|
||||
assign ddr3_cs_n = 0; //tie cs_n to ground (same as disabling the chip-select)
|
||||
|
||||
reg [24:0]c;
|
||||
always @ (posedge i_controller_clk) begin
|
||||
if (!i_rst) c <= c + 1;
|
||||
else c <= 0;
|
||||
end
|
||||
|
||||
reg [4:0]od1_last;
|
||||
reg bitt = 0;
|
||||
always @ (posedge i_controller_clk) begin
|
||||
od1_last <= o_debug1[4:0];
|
||||
if (btn[1]) begin
|
||||
if (od1_last != o_debug1[4:0]) bitt <= 1;
|
||||
end else
|
||||
bitt <= 0;
|
||||
end
|
||||
always @(*) begin
|
||||
if (btn[0]) begin
|
||||
led <= {c[24:23], o_debug1[4:0], bitt};
|
||||
end else begin
|
||||
if (!btn[2])
|
||||
led <= o_debug2[7:0];
|
||||
else
|
||||
led <= {4'b0, o_debug2[11:8]};
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge i_controller_clk) begin
|
||||
begin
|
||||
i_wb_stb <= 0;
|
||||
i_wb_we <= 0;
|
||||
i_wb_addr <= 0;
|
||||
i_wb_data <= 0;
|
||||
if(!o_wb_stall && m_axis_tvalid) begin
|
||||
if(rd_data >= 97 && rd_data <= 122) begin //write to DDR3 if ASCII is small letter
|
||||
i_wb_stb <= 1;
|
||||
i_wb_we <= 1;
|
||||
i_wb_addr <= ~rd_data ;
|
||||
i_wb_data <= rd_data;
|
||||
end
|
||||
else if(rd_data >= 65 && rd_data <= 90) begin //read from DDR3 if ASCII is capital letter
|
||||
i_wb_stb <= 1; //make request
|
||||
i_wb_we <= 0; //read
|
||||
i_wb_addr <= ~(rd_data + 8'd32);
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
(* mark_debug = "true" *) wire clk_locked;
|
||||
clk_wiz clk_wiz_inst
|
||||
(
|
||||
// Clock out ports
|
||||
.clk_out1(i_controller_clk), //83.333 Mhz
|
||||
.clk_out2(i_ddr3_clk), // 333.333 MHz
|
||||
.clk_out3(i_ref_clk), //200MHz
|
||||
.clk_out4(i_ddr3_clk_90), // 333.333 MHz with 90degree shift
|
||||
// Status and control signals
|
||||
.reset(i_rst),
|
||||
.locked(clk_locked),
|
||||
// Clock in ports
|
||||
.clk_in1(i_clk)
|
||||
);
|
||||
|
||||
// UART module from https://github.com/alexforencich/verilog-uart
|
||||
uart #(.DATA_WIDTH(8)) uart_m
|
||||
(
|
||||
.clk(i_controller_clk),
|
||||
.rst(i_rst),
|
||||
.s_axis_tdata(o_wb_data),
|
||||
.s_axis_tvalid(o_wb_ack),
|
||||
.s_axis_tready(),
|
||||
.m_axis_tdata(rd_data),
|
||||
.m_axis_tvalid(m_axis_tvalid),
|
||||
.m_axis_tready(1),
|
||||
.rxd(rx),
|
||||
.txd(tx),
|
||||
.prescale(1085) //9600 Baud Rate
|
||||
);
|
||||
|
||||
|
||||
// DDR3 Controller
|
||||
ddr3_top #(
|
||||
.CONTROLLER_CLK_PERIOD(12_000), //12_000ps, clock period of the controller interface
|
||||
.DDR3_CLK_PERIOD(3_000), //3_000ps, clock period of the DDR3 RAM device (must be 1/4 of the CONTROLLER_CLK_PERIOD)
|
||||
.ROW_BITS(14), //width of row address
|
||||
.COL_BITS(10), //width of column address
|
||||
.BA_BITS(3), //width of bank address
|
||||
.DQ_BITS(8), //width of DQ
|
||||
.BYTE_LANES(1), //number of DDR3 modules to be controlled
|
||||
.AUX_WIDTH(4), //width of aux line (must be >= 4)
|
||||
.WB2_ADDR_BITS(32), //width of 2nd wishbone address bus
|
||||
.WB2_DATA_BITS(32), //width of 2nd wishbone data bus
|
||||
.MICRON_SIM(0), //enable faster simulation for micron ddr3 model (shorten POWER_ON_RESET_HIGH and INITIAL_CKE_LOW)
|
||||
.ODELAY_SUPPORTED(0), //set to 1 when ODELAYE2 is supported
|
||||
.SECOND_WISHBONE(0) //set to 1 if 2nd wishbone is needed
|
||||
) ddr3_top_inst
|
||||
(
|
||||
//clock and reset
|
||||
.i_controller_clk(i_controller_clk),
|
||||
.i_ddr3_clk(i_ddr3_clk), //i_controller_clk has period of CONTROLLER_CLK_PERIOD, i_ddr3_clk has period of DDR3_CLK_PERIOD
|
||||
.i_ref_clk(i_ref_clk),
|
||||
.i_ddr3_clk_90(i_ddr3_clk_90),
|
||||
.i_rst_n(!i_rst && clk_locked),
|
||||
// Wishbone inputs
|
||||
.i_wb_cyc(1), //bus cycle active (1 = normal operation, 0 = all ongoing transaction are to be cancelled)
|
||||
.i_wb_stb(i_wb_stb), //request a transfer
|
||||
.i_wb_we(i_wb_we), //write-enable (1 = write, 0 = read)
|
||||
.i_wb_addr(i_wb_addr), //burst-addressable {row,bank,col}
|
||||
.i_wb_data(i_wb_data), //write data, for a 4:1 controller data width is 8 times the number of pins on the device
|
||||
.i_wb_sel(16'hffff), //byte strobe for write (1 = write the byte)
|
||||
.i_aux(i_wb_we), //for AXI-interface compatibility (given upon strobe)
|
||||
// Wishbone outputs
|
||||
.o_wb_stall(o_wb_stall), //1 = busy, cannot accept requests
|
||||
.o_wb_ack(o_wb_ack), //1 = read/write request has completed
|
||||
.o_wb_data(o_wb_data), //read data, for a 4:1 controller data width is 8 times the number of pins on the device
|
||||
.o_aux(o_aux),
|
||||
// Wishbone 2 (PHY) inputs
|
||||
.i_wb2_cyc(), //bus cycle active (1 = normal operation, 0 = all ongoing transaction are to be cancelled)
|
||||
.i_wb2_stb(), //request a transfer
|
||||
.i_wb2_we(), //write-enable (1 = write, 0 = read)
|
||||
.i_wb2_addr(), //burst-addressable {row,bank,col}
|
||||
.i_wb2_data(), //write data, for a 4:1 controller data width is 8 times the number of pins on the device
|
||||
.i_wb2_sel(), //byte strobe for write (1 = write the byte)
|
||||
// Wishbone 2 (Controller) outputs
|
||||
.o_wb2_stall(), //1 = busy, cannot accept requests
|
||||
.o_wb2_ack(), //1 = read/write request has completed
|
||||
.o_wb2_data(), //read data, for a 4:1 controller data width is 8 times the number of pins on the device
|
||||
// PHY Interface (to be added later)
|
||||
// DDR3 I/O Interface
|
||||
.o_ddr3_clk_p(ddr3_clk_p),
|
||||
.o_ddr3_clk_n(ddr3_clk_n),
|
||||
.o_ddr3_reset_n(ddr3_reset_n),
|
||||
.o_ddr3_cke(ddr3_cke), // CKE
|
||||
.o_ddr3_cs_n(/*ddr3_cs_n*/), // chip select signal (controls rank 1 only)
|
||||
.o_ddr3_ras_n(ddr3_ras_n), // RAS#
|
||||
.o_ddr3_cas_n(ddr3_cas_n), // CAS#
|
||||
.o_ddr3_we_n(ddr3_we_n), // WE#
|
||||
.o_ddr3_addr(ddr3_addr),
|
||||
.o_ddr3_ba_addr(ddr3_ba),
|
||||
.io_ddr3_dq(ddr3_dq),
|
||||
.io_ddr3_dqs(ddr3_dqs_p),
|
||||
.io_ddr3_dqs_n(ddr3_dqs_n),
|
||||
.o_ddr3_dm(ddr3_dm),
|
||||
.o_ddr3_odt(ddr3_odt), // on-die termination
|
||||
.o_debug1(o_debug1),
|
||||
.o_debug2(o_debug2),
|
||||
.o_debug3()
|
||||
);
|
||||
|
||||
endmodule
|
||||
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
#!/usr/bin/env python3
|
||||
ddr3_name = 'ddr3_top_inst.ddr3_phy_inst'
|
||||
def get_cells(name_part):
|
||||
return list(map(lambda c: c.second, filter(lambda c: name_part in c.first, ctx.cells)))
|
||||
|
||||
def get_cell(name_part):
|
||||
return get_cells(name_part)[0]
|
||||
|
||||
c1_name = ddr3_name + '.genblk5[0].ISERDESE2_train'
|
||||
# c2_name = ddr3_name + '.genblk5[1].ISERDESE2_train'
|
||||
c3_name = ddr3_name + '.genblk5[0].OSERDESE2_train'
|
||||
# c4_name = ddr3_name + '.genblk5[1].OSERDESE2_train'
|
||||
|
||||
c1=get_cell(c1_name)
|
||||
# c2=get_cell(c2_name)
|
||||
c3=get_cell(c3_name)
|
||||
# c4=get_cell(c4_name)
|
||||
|
||||
print('show_bels: ' + c1_name + ": ", c1.bel)
|
||||
# print('show_bels: ' + c2_name + ": ", c2.bel)
|
||||
print('show_bels: ' + c3_name + ": ", c3.bel)
|
||||
# print('show_bels: ' + c4_name + ": ", c4.bel)
|
||||
Loading…
Reference in New Issue