mirror of https://github.com/openXC7/prjxray.git
Merge pull request #1218 from antmicro/ddr-uart-bridge
Added UART DDR minitest
This commit is contained in:
commit
f02800daf5
|
|
@ -0,0 +1,99 @@
|
||||||
|
# LiteX UART DDR minitest
|
||||||
|
|
||||||
|
This test aims at providing a minimal DDR design.
|
||||||
|
The design is tested with a python script that provides memory control signals to the DDR controller
|
||||||
|
using an UART bridge.
|
||||||
|
|
||||||
|
The script performs the calbiration process, therfore it looks for the bitslip as well as the delay values.
|
||||||
|
|
||||||
|
### Litex environment
|
||||||
|
|
||||||
|
The litex module used is LiteDRAM, which should be checked-out at the correct commit:
|
||||||
|
|
||||||
|
| Repo URL | SHA |
|
||||||
|
| --- | --- |
|
||||||
|
| <https://github.com/antmicro/litex> | 3350d33 |
|
||||||
|
| <https://github.com/enjoy-digital/litedram> | d8f3feb |
|
||||||
|
| <https://github.com/m-labs/migen> | d11565a |
|
||||||
|
|
||||||
|
|
||||||
|
### Implementation
|
||||||
|
|
||||||
|
There are two different ways to test this design:
|
||||||
|
|
||||||
|
1. Vivado: the flow is entirely managed by Vivado, including Synthesis. To make use of this flow do the following:
|
||||||
|
|
||||||
|
```
|
||||||
|
cd src.vivado
|
||||||
|
make
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Yosys + Vivado: the flow is divided in two steps. Yosys handles synthesys, while Vivado handles P&R and bitstream generation. To make use of this flow do the following:
|
||||||
|
|
||||||
|
```
|
||||||
|
cd src.yosys
|
||||||
|
make
|
||||||
|
```
|
||||||
|
|
||||||
|
### Testing
|
||||||
|
|
||||||
|
To test the implemented design, load the bitstream produced in the previous step, and do the following:
|
||||||
|
|
||||||
|
1. Open the litex server:
|
||||||
|
|
||||||
|
```
|
||||||
|
lxserver --uart --uart-port=/dev/ttyUSBX
|
||||||
|
```
|
||||||
|
|
||||||
|
2. On a different terminal, connect to the server through the client script
|
||||||
|
```
|
||||||
|
cd scripts
|
||||||
|
make test_sdram
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Output
|
||||||
|
|
||||||
|
Depending on the clock frequency selected during the gateware generation, different outputs are generated:
|
||||||
|
|
||||||
|
- 50 MHz sysytem clock:
|
||||||
|
|
||||||
|
```
|
||||||
|
Minimal Arty DDR3 Design for tests with Project X-Ray 2020-02-03 11:30:24
|
||||||
|
Release reset
|
||||||
|
Bring CKE high
|
||||||
|
Load Mode Register 2, CWL=5
|
||||||
|
Load Mode Register 3
|
||||||
|
Load Mode Register 1
|
||||||
|
Load Mode Register 0, CL=6, BL=8
|
||||||
|
ZQ Calibration
|
||||||
|
bitslip 0: |..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|31|
|
||||||
|
bitslip 1: |..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|
|
||||||
|
bitslip 2: |..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|
|
||||||
|
bitslip 3: |..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|
|
||||||
|
bitslip 4: |..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|
|
||||||
|
bitslip 5: |..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|
|
||||||
|
bitslip 6: |..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|
|
||||||
|
bitslip 7: |..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|
|
||||||
|
```
|
||||||
|
|
||||||
|
- 100 MHz system clock:
|
||||||
|
|
||||||
|
|
||||||
|
```
|
||||||
|
Minimal Arty DDR3 Design for tests with Project X-Ray 2020-01-31 15:41:14
|
||||||
|
Release reset
|
||||||
|
Bring CKE high
|
||||||
|
Load Mode Register 2, CWL=5
|
||||||
|
Load Mode Register 3
|
||||||
|
Load Mode Register 1
|
||||||
|
Load Mode Register 0, CL=6, BL=8
|
||||||
|
ZQ Calibration
|
||||||
|
bitslip 0: |00|01|02|03|04|05|06|07|08|09|10|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|
|
||||||
|
bitslip 1: |..|..|..|..|..|..|..|..|..|..|..|..|..|13|14|15|16|17|18|19|20|21|22|23|24|25|..|..|..|..|..|..|
|
||||||
|
bitslip 2: |..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|29|30|31|
|
||||||
|
bitslip 3: |..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|
|
||||||
|
bitslip 4: |..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|
|
||||||
|
bitslip 5: |..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|
|
||||||
|
bitslip 6: |..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|
|
||||||
|
bitslip 7: |..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|..|
|
||||||
|
```
|
||||||
|
|
@ -0,0 +1,74 @@
|
||||||
|
4d
|
||||||
|
69
|
||||||
|
6e
|
||||||
|
69
|
||||||
|
6d
|
||||||
|
61
|
||||||
|
6c
|
||||||
|
20
|
||||||
|
41
|
||||||
|
72
|
||||||
|
74
|
||||||
|
79
|
||||||
|
20
|
||||||
|
44
|
||||||
|
44
|
||||||
|
52
|
||||||
|
33
|
||||||
|
20
|
||||||
|
44
|
||||||
|
65
|
||||||
|
73
|
||||||
|
69
|
||||||
|
67
|
||||||
|
6e
|
||||||
|
20
|
||||||
|
66
|
||||||
|
6f
|
||||||
|
72
|
||||||
|
20
|
||||||
|
74
|
||||||
|
65
|
||||||
|
73
|
||||||
|
74
|
||||||
|
73
|
||||||
|
20
|
||||||
|
77
|
||||||
|
69
|
||||||
|
74
|
||||||
|
68
|
||||||
|
20
|
||||||
|
50
|
||||||
|
72
|
||||||
|
6f
|
||||||
|
6a
|
||||||
|
65
|
||||||
|
63
|
||||||
|
74
|
||||||
|
20
|
||||||
|
58
|
||||||
|
2d
|
||||||
|
52
|
||||||
|
61
|
||||||
|
79
|
||||||
|
20
|
||||||
|
32
|
||||||
|
30
|
||||||
|
32
|
||||||
|
30
|
||||||
|
2d
|
||||||
|
30
|
||||||
|
32
|
||||||
|
2d
|
||||||
|
30
|
||||||
|
33
|
||||||
|
20
|
||||||
|
31
|
||||||
|
31
|
||||||
|
3a
|
||||||
|
33
|
||||||
|
30
|
||||||
|
3a
|
||||||
|
32
|
||||||
|
34
|
||||||
|
0
|
||||||
File diff suppressed because one or more lines are too long
|
|
@ -0,0 +1,314 @@
|
||||||
|
################################################################################
|
||||||
|
# IO constraints
|
||||||
|
################################################################################
|
||||||
|
# serial:0.tx
|
||||||
|
set_property LOC D10 [get_ports serial_tx]
|
||||||
|
set_property IOSTANDARD LVCMOS33 [get_ports serial_tx]
|
||||||
|
|
||||||
|
# serial:0.rx
|
||||||
|
set_property LOC A9 [get_ports serial_rx]
|
||||||
|
set_property IOSTANDARD LVCMOS33 [get_ports serial_rx]
|
||||||
|
|
||||||
|
# cpu_reset:0
|
||||||
|
set_property LOC C2 [get_ports cpu_reset]
|
||||||
|
set_property IOSTANDARD LVCMOS33 [get_ports cpu_reset]
|
||||||
|
|
||||||
|
# clk100:0
|
||||||
|
set_property LOC E3 [get_ports clk100]
|
||||||
|
set_property IOSTANDARD LVCMOS33 [get_ports clk100]
|
||||||
|
|
||||||
|
# led[0]
|
||||||
|
set_property LOC H5 [get_ports led[0]]
|
||||||
|
set_property IOSTANDARD LVCMOS33 [get_ports led[0]]
|
||||||
|
|
||||||
|
# led[1]
|
||||||
|
set_property LOC J5 [get_ports led[1]]
|
||||||
|
set_property IOSTANDARD LVCMOS33 [get_ports led[1]]
|
||||||
|
|
||||||
|
# led[2]
|
||||||
|
set_property LOC T9 [get_ports led[2]]
|
||||||
|
set_property IOSTANDARD LVCMOS33 [get_ports led[2]]
|
||||||
|
|
||||||
|
# led[3]
|
||||||
|
set_property LOC T10 [get_ports led[3]]
|
||||||
|
set_property IOSTANDARD LVCMOS33 [get_ports led[3]]
|
||||||
|
|
||||||
|
# ddram:0.a
|
||||||
|
set_property LOC R2 [get_ports ddram_a[0]]
|
||||||
|
set_property SLEW FAST [get_ports ddram_a[0]]
|
||||||
|
set_property IOSTANDARD SSTL135 [get_ports ddram_a[0]]
|
||||||
|
|
||||||
|
# ddram:0.a
|
||||||
|
set_property LOC M6 [get_ports ddram_a[1]]
|
||||||
|
set_property SLEW FAST [get_ports ddram_a[1]]
|
||||||
|
set_property IOSTANDARD SSTL135 [get_ports ddram_a[1]]
|
||||||
|
|
||||||
|
# ddram:0.a
|
||||||
|
set_property LOC N4 [get_ports ddram_a[2]]
|
||||||
|
set_property SLEW FAST [get_ports ddram_a[2]]
|
||||||
|
set_property IOSTANDARD SSTL135 [get_ports ddram_a[2]]
|
||||||
|
|
||||||
|
# ddram:0.a
|
||||||
|
set_property LOC T1 [get_ports ddram_a[3]]
|
||||||
|
set_property SLEW FAST [get_ports ddram_a[3]]
|
||||||
|
set_property IOSTANDARD SSTL135 [get_ports ddram_a[3]]
|
||||||
|
|
||||||
|
# ddram:0.a
|
||||||
|
set_property LOC N6 [get_ports ddram_a[4]]
|
||||||
|
set_property SLEW FAST [get_ports ddram_a[4]]
|
||||||
|
set_property IOSTANDARD SSTL135 [get_ports ddram_a[4]]
|
||||||
|
|
||||||
|
# ddram:0.a
|
||||||
|
set_property LOC R7 [get_ports ddram_a[5]]
|
||||||
|
set_property SLEW FAST [get_ports ddram_a[5]]
|
||||||
|
set_property IOSTANDARD SSTL135 [get_ports ddram_a[5]]
|
||||||
|
|
||||||
|
# ddram:0.a
|
||||||
|
set_property LOC V6 [get_ports ddram_a[6]]
|
||||||
|
set_property SLEW FAST [get_ports ddram_a[6]]
|
||||||
|
set_property IOSTANDARD SSTL135 [get_ports ddram_a[6]]
|
||||||
|
|
||||||
|
# ddram:0.a
|
||||||
|
set_property LOC U7 [get_ports ddram_a[7]]
|
||||||
|
set_property SLEW FAST [get_ports ddram_a[7]]
|
||||||
|
set_property IOSTANDARD SSTL135 [get_ports ddram_a[7]]
|
||||||
|
|
||||||
|
# ddram:0.a
|
||||||
|
set_property LOC R8 [get_ports ddram_a[8]]
|
||||||
|
set_property SLEW FAST [get_ports ddram_a[8]]
|
||||||
|
set_property IOSTANDARD SSTL135 [get_ports ddram_a[8]]
|
||||||
|
|
||||||
|
# ddram:0.a
|
||||||
|
set_property LOC V7 [get_ports ddram_a[9]]
|
||||||
|
set_property SLEW FAST [get_ports ddram_a[9]]
|
||||||
|
set_property IOSTANDARD SSTL135 [get_ports ddram_a[9]]
|
||||||
|
|
||||||
|
# ddram:0.a
|
||||||
|
set_property LOC R6 [get_ports ddram_a[10]]
|
||||||
|
set_property SLEW FAST [get_ports ddram_a[10]]
|
||||||
|
set_property IOSTANDARD SSTL135 [get_ports ddram_a[10]]
|
||||||
|
|
||||||
|
# ddram:0.a
|
||||||
|
set_property LOC U6 [get_ports ddram_a[11]]
|
||||||
|
set_property SLEW FAST [get_ports ddram_a[11]]
|
||||||
|
set_property IOSTANDARD SSTL135 [get_ports ddram_a[11]]
|
||||||
|
|
||||||
|
# ddram:0.a
|
||||||
|
set_property LOC T6 [get_ports ddram_a[12]]
|
||||||
|
set_property SLEW FAST [get_ports ddram_a[12]]
|
||||||
|
set_property IOSTANDARD SSTL135 [get_ports ddram_a[12]]
|
||||||
|
|
||||||
|
# ddram:0.a
|
||||||
|
set_property LOC T8 [get_ports ddram_a[13]]
|
||||||
|
set_property SLEW FAST [get_ports ddram_a[13]]
|
||||||
|
set_property IOSTANDARD SSTL135 [get_ports ddram_a[13]]
|
||||||
|
|
||||||
|
# ddram:0.ba
|
||||||
|
set_property LOC R1 [get_ports ddram_ba[0]]
|
||||||
|
set_property SLEW FAST [get_ports ddram_ba[0]]
|
||||||
|
set_property IOSTANDARD SSTL135 [get_ports ddram_ba[0]]
|
||||||
|
|
||||||
|
# ddram:0.ba
|
||||||
|
set_property LOC P4 [get_ports ddram_ba[1]]
|
||||||
|
set_property SLEW FAST [get_ports ddram_ba[1]]
|
||||||
|
set_property IOSTANDARD SSTL135 [get_ports ddram_ba[1]]
|
||||||
|
|
||||||
|
# ddram:0.ba
|
||||||
|
set_property LOC P2 [get_ports ddram_ba[2]]
|
||||||
|
set_property SLEW FAST [get_ports ddram_ba[2]]
|
||||||
|
set_property IOSTANDARD SSTL135 [get_ports ddram_ba[2]]
|
||||||
|
|
||||||
|
# ddram:0.ras_n
|
||||||
|
set_property LOC P3 [get_ports ddram_ras_n]
|
||||||
|
set_property SLEW FAST [get_ports ddram_ras_n]
|
||||||
|
set_property IOSTANDARD SSTL135 [get_ports ddram_ras_n]
|
||||||
|
|
||||||
|
# ddram:0.cas_n
|
||||||
|
set_property LOC M4 [get_ports ddram_cas_n]
|
||||||
|
set_property SLEW FAST [get_ports ddram_cas_n]
|
||||||
|
set_property IOSTANDARD SSTL135 [get_ports ddram_cas_n]
|
||||||
|
|
||||||
|
# ddram:0.we_n
|
||||||
|
set_property LOC P5 [get_ports ddram_we_n]
|
||||||
|
set_property SLEW FAST [get_ports ddram_we_n]
|
||||||
|
set_property IOSTANDARD SSTL135 [get_ports ddram_we_n]
|
||||||
|
|
||||||
|
# ddram:0.cs_n
|
||||||
|
set_property LOC U8 [get_ports ddram_cs_n]
|
||||||
|
set_property SLEW FAST [get_ports ddram_cs_n]
|
||||||
|
set_property IOSTANDARD SSTL135 [get_ports ddram_cs_n]
|
||||||
|
|
||||||
|
# ddram:0.dm
|
||||||
|
set_property LOC L1 [get_ports ddram_dm[0]]
|
||||||
|
set_property SLEW FAST [get_ports ddram_dm[0]]
|
||||||
|
set_property IOSTANDARD SSTL135 [get_ports ddram_dm[0]]
|
||||||
|
|
||||||
|
# ddram:0.dm
|
||||||
|
set_property LOC U1 [get_ports ddram_dm[1]]
|
||||||
|
set_property SLEW FAST [get_ports ddram_dm[1]]
|
||||||
|
set_property IOSTANDARD SSTL135 [get_ports ddram_dm[1]]
|
||||||
|
|
||||||
|
# ddram:0.dq
|
||||||
|
set_property LOC K5 [get_ports ddram_dq[0]]
|
||||||
|
set_property SLEW FAST [get_ports ddram_dq[0]]
|
||||||
|
set_property IOSTANDARD SSTL135 [get_ports ddram_dq[0]]
|
||||||
|
set_property IN_TERM UNTUNED_SPLIT_40 [get_ports ddram_dq[0]]
|
||||||
|
|
||||||
|
# ddram:0.dq
|
||||||
|
set_property LOC L3 [get_ports ddram_dq[1]]
|
||||||
|
set_property SLEW FAST [get_ports ddram_dq[1]]
|
||||||
|
set_property IOSTANDARD SSTL135 [get_ports ddram_dq[1]]
|
||||||
|
set_property IN_TERM UNTUNED_SPLIT_40 [get_ports ddram_dq[1]]
|
||||||
|
|
||||||
|
# ddram:0.dq
|
||||||
|
set_property LOC K3 [get_ports ddram_dq[2]]
|
||||||
|
set_property SLEW FAST [get_ports ddram_dq[2]]
|
||||||
|
set_property IOSTANDARD SSTL135 [get_ports ddram_dq[2]]
|
||||||
|
set_property IN_TERM UNTUNED_SPLIT_40 [get_ports ddram_dq[2]]
|
||||||
|
|
||||||
|
# ddram:0.dq
|
||||||
|
set_property LOC L6 [get_ports ddram_dq[3]]
|
||||||
|
set_property SLEW FAST [get_ports ddram_dq[3]]
|
||||||
|
set_property IOSTANDARD SSTL135 [get_ports ddram_dq[3]]
|
||||||
|
set_property IN_TERM UNTUNED_SPLIT_40 [get_ports ddram_dq[3]]
|
||||||
|
|
||||||
|
# ddram:0.dq
|
||||||
|
set_property LOC M3 [get_ports ddram_dq[4]]
|
||||||
|
set_property SLEW FAST [get_ports ddram_dq[4]]
|
||||||
|
set_property IOSTANDARD SSTL135 [get_ports ddram_dq[4]]
|
||||||
|
set_property IN_TERM UNTUNED_SPLIT_40 [get_ports ddram_dq[4]]
|
||||||
|
|
||||||
|
# ddram:0.dq
|
||||||
|
set_property LOC M1 [get_ports ddram_dq[5]]
|
||||||
|
set_property SLEW FAST [get_ports ddram_dq[5]]
|
||||||
|
set_property IOSTANDARD SSTL135 [get_ports ddram_dq[5]]
|
||||||
|
set_property IN_TERM UNTUNED_SPLIT_40 [get_ports ddram_dq[5]]
|
||||||
|
|
||||||
|
# ddram:0.dq
|
||||||
|
set_property LOC L4 [get_ports ddram_dq[6]]
|
||||||
|
set_property SLEW FAST [get_ports ddram_dq[6]]
|
||||||
|
set_property IOSTANDARD SSTL135 [get_ports ddram_dq[6]]
|
||||||
|
set_property IN_TERM UNTUNED_SPLIT_40 [get_ports ddram_dq[6]]
|
||||||
|
|
||||||
|
# ddram:0.dq
|
||||||
|
set_property LOC M2 [get_ports ddram_dq[7]]
|
||||||
|
set_property SLEW FAST [get_ports ddram_dq[7]]
|
||||||
|
set_property IOSTANDARD SSTL135 [get_ports ddram_dq[7]]
|
||||||
|
set_property IN_TERM UNTUNED_SPLIT_40 [get_ports ddram_dq[7]]
|
||||||
|
|
||||||
|
# ddram:0.dq
|
||||||
|
set_property LOC V4 [get_ports ddram_dq[8]]
|
||||||
|
set_property SLEW FAST [get_ports ddram_dq[8]]
|
||||||
|
set_property IOSTANDARD SSTL135 [get_ports ddram_dq[8]]
|
||||||
|
set_property IN_TERM UNTUNED_SPLIT_40 [get_ports ddram_dq[8]]
|
||||||
|
|
||||||
|
# ddram:0.dq
|
||||||
|
set_property LOC T5 [get_ports ddram_dq[9]]
|
||||||
|
set_property SLEW FAST [get_ports ddram_dq[9]]
|
||||||
|
set_property IOSTANDARD SSTL135 [get_ports ddram_dq[9]]
|
||||||
|
set_property IN_TERM UNTUNED_SPLIT_40 [get_ports ddram_dq[9]]
|
||||||
|
|
||||||
|
# ddram:0.dq
|
||||||
|
set_property LOC U4 [get_ports ddram_dq[10]]
|
||||||
|
set_property SLEW FAST [get_ports ddram_dq[10]]
|
||||||
|
set_property IOSTANDARD SSTL135 [get_ports ddram_dq[10]]
|
||||||
|
set_property IN_TERM UNTUNED_SPLIT_40 [get_ports ddram_dq[10]]
|
||||||
|
|
||||||
|
# ddram:0.dq
|
||||||
|
set_property LOC V5 [get_ports ddram_dq[11]]
|
||||||
|
set_property SLEW FAST [get_ports ddram_dq[11]]
|
||||||
|
set_property IOSTANDARD SSTL135 [get_ports ddram_dq[11]]
|
||||||
|
set_property IN_TERM UNTUNED_SPLIT_40 [get_ports ddram_dq[11]]
|
||||||
|
|
||||||
|
# ddram:0.dq
|
||||||
|
set_property LOC V1 [get_ports ddram_dq[12]]
|
||||||
|
set_property SLEW FAST [get_ports ddram_dq[12]]
|
||||||
|
set_property IOSTANDARD SSTL135 [get_ports ddram_dq[12]]
|
||||||
|
set_property IN_TERM UNTUNED_SPLIT_40 [get_ports ddram_dq[12]]
|
||||||
|
|
||||||
|
# ddram:0.dq
|
||||||
|
set_property LOC T3 [get_ports ddram_dq[13]]
|
||||||
|
set_property SLEW FAST [get_ports ddram_dq[13]]
|
||||||
|
set_property IOSTANDARD SSTL135 [get_ports ddram_dq[13]]
|
||||||
|
set_property IN_TERM UNTUNED_SPLIT_40 [get_ports ddram_dq[13]]
|
||||||
|
|
||||||
|
# ddram:0.dq
|
||||||
|
set_property LOC U3 [get_ports ddram_dq[14]]
|
||||||
|
set_property SLEW FAST [get_ports ddram_dq[14]]
|
||||||
|
set_property IOSTANDARD SSTL135 [get_ports ddram_dq[14]]
|
||||||
|
set_property IN_TERM UNTUNED_SPLIT_40 [get_ports ddram_dq[14]]
|
||||||
|
|
||||||
|
# ddram:0.dq
|
||||||
|
set_property LOC R3 [get_ports ddram_dq[15]]
|
||||||
|
set_property SLEW FAST [get_ports ddram_dq[15]]
|
||||||
|
set_property IOSTANDARD SSTL135 [get_ports ddram_dq[15]]
|
||||||
|
set_property IN_TERM UNTUNED_SPLIT_40 [get_ports ddram_dq[15]]
|
||||||
|
|
||||||
|
# ddram:0.dqs_p
|
||||||
|
set_property LOC N2 [get_ports ddram_dqs_p[0]]
|
||||||
|
set_property SLEW FAST [get_ports ddram_dqs_p[0]]
|
||||||
|
set_property IOSTANDARD DIFF_SSTL135 [get_ports ddram_dqs_p[0]]
|
||||||
|
|
||||||
|
# ddram:0.dqs_p
|
||||||
|
set_property LOC U2 [get_ports ddram_dqs_p[1]]
|
||||||
|
set_property SLEW FAST [get_ports ddram_dqs_p[1]]
|
||||||
|
set_property IOSTANDARD DIFF_SSTL135 [get_ports ddram_dqs_p[1]]
|
||||||
|
|
||||||
|
# ddram:0.dqs_n
|
||||||
|
set_property LOC N1 [get_ports ddram_dqs_n[0]]
|
||||||
|
set_property SLEW FAST [get_ports ddram_dqs_n[0]]
|
||||||
|
set_property IOSTANDARD DIFF_SSTL135 [get_ports ddram_dqs_n[0]]
|
||||||
|
|
||||||
|
# ddram:0.dqs_n
|
||||||
|
set_property LOC V2 [get_ports ddram_dqs_n[1]]
|
||||||
|
set_property SLEW FAST [get_ports ddram_dqs_n[1]]
|
||||||
|
set_property IOSTANDARD DIFF_SSTL135 [get_ports ddram_dqs_n[1]]
|
||||||
|
|
||||||
|
# ddram:0.clk_p
|
||||||
|
set_property LOC U9 [get_ports ddram_clk_p]
|
||||||
|
set_property SLEW FAST [get_ports ddram_clk_p]
|
||||||
|
set_property IOSTANDARD DIFF_SSTL135 [get_ports ddram_clk_p]
|
||||||
|
|
||||||
|
# ddram:0.clk_n
|
||||||
|
set_property LOC V9 [get_ports ddram_clk_n]
|
||||||
|
set_property SLEW FAST [get_ports ddram_clk_n]
|
||||||
|
set_property IOSTANDARD DIFF_SSTL135 [get_ports ddram_clk_n]
|
||||||
|
|
||||||
|
# ddram:0.cke
|
||||||
|
set_property LOC N5 [get_ports ddram_cke]
|
||||||
|
set_property SLEW FAST [get_ports ddram_cke]
|
||||||
|
set_property IOSTANDARD SSTL135 [get_ports ddram_cke]
|
||||||
|
|
||||||
|
# ddram:0.odt
|
||||||
|
set_property LOC R5 [get_ports ddram_odt]
|
||||||
|
set_property SLEW FAST [get_ports ddram_odt]
|
||||||
|
set_property IOSTANDARD SSTL135 [get_ports ddram_odt]
|
||||||
|
|
||||||
|
# ddram:0.reset_n
|
||||||
|
set_property LOC K6 [get_ports ddram_reset_n]
|
||||||
|
set_property SLEW FAST [get_ports ddram_reset_n]
|
||||||
|
set_property IOSTANDARD SSTL135 [get_ports ddram_reset_n]
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
# Design constraints
|
||||||
|
################################################################################
|
||||||
|
|
||||||
|
set_property INTERNAL_VREF 0.675 [get_iobanks 34]
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
# Clock constraints
|
||||||
|
################################################################################
|
||||||
|
|
||||||
|
|
||||||
|
create_clock -name clk100 -period 10.0 [get_nets clk100]
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
# False path constraints
|
||||||
|
################################################################################
|
||||||
|
|
||||||
|
|
||||||
|
set_false_path -quiet -to [get_nets -quiet -filter {mr_ff == TRUE}]
|
||||||
|
|
||||||
|
set_false_path -quiet -to [get_pins -quiet -filter {REF_PIN_NAME == PRE} -of [get_cells -quiet -filter {ars_ff1 == TRUE || ars_ff2 == TRUE}]]
|
||||||
|
|
||||||
|
set_max_delay 2 -quiet -from [get_pins -quiet -filter {REF_PIN_NAME == Q} -of [get_cells -quiet -filter {ars_ff1 == TRUE}]] -to [get_pins -quiet -filter {REF_PIN_NAME == D} -of [get_cells -quiet -filter {ars_ff2 == TRUE}]]
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
litex
|
||||||
|
|
@ -0,0 +1,6 @@
|
||||||
|
litex/litex/tools/litex_client.py:
|
||||||
|
git clone https://github.com/enjoy-digital/litex.git
|
||||||
|
cd litex && git checkout 3350d33 && cd ../
|
||||||
|
|
||||||
|
test_dram: litex/litex/tools/litex_client.py
|
||||||
|
./test_sdram.py
|
||||||
|
|
@ -0,0 +1,117 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
# This file is Copyright (c) 2015-2020 Florent Kermarrec <florent@enjoy-digital.fr>
|
||||||
|
# License: BSD
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
|
||||||
|
from migen import *
|
||||||
|
|
||||||
|
from litex_boards.platforms import arty
|
||||||
|
from litex.build.xilinx import VivadoProgrammer
|
||||||
|
from litex.build.xilinx.vivado import vivado_build_args, vivado_build_argdict
|
||||||
|
|
||||||
|
from litex.soc.cores.clock import *
|
||||||
|
from litex.soc.integration.soc_sdram import *
|
||||||
|
from litex.soc.integration.builder import *
|
||||||
|
|
||||||
|
from litedram.init import get_sdram_phy_py_header
|
||||||
|
from litedram.modules import MT41K128M16
|
||||||
|
from litedram.phy import s7ddrphy
|
||||||
|
|
||||||
|
# CRG ----------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
class _CRG(Module):
|
||||||
|
def __init__(self, platform, sys_clk_freq):
|
||||||
|
self.clock_domains.cd_sys = ClockDomain()
|
||||||
|
self.clock_domains.cd_sys4x = ClockDomain(reset_less=True)
|
||||||
|
self.clock_domains.cd_sys4x_dqs = ClockDomain(reset_less=True)
|
||||||
|
self.clock_domains.cd_clk200 = ClockDomain()
|
||||||
|
|
||||||
|
# # #
|
||||||
|
|
||||||
|
self.submodules.pll = pll = S7PLL(speedgrade=-1)
|
||||||
|
self.comb += pll.reset.eq(~platform.request("cpu_reset"))
|
||||||
|
pll.register_clkin(platform.request("clk100"), 100e6)
|
||||||
|
pll.create_clkout(self.cd_sys, sys_clk_freq)
|
||||||
|
pll.create_clkout(self.cd_sys4x, 4 * sys_clk_freq)
|
||||||
|
pll.create_clkout(self.cd_sys4x_dqs, 4 * sys_clk_freq, phase=90)
|
||||||
|
pll.create_clkout(self.cd_clk200, 200e6)
|
||||||
|
|
||||||
|
self.submodules.idelayctrl = S7IDELAYCTRL(self.cd_clk200)
|
||||||
|
|
||||||
|
|
||||||
|
# BaseSoC ------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
class BaseSoC(SoCSDRAM):
|
||||||
|
def __init__(self):
|
||||||
|
platform = arty.Platform()
|
||||||
|
sys_clk_freq = int(50e6)
|
||||||
|
|
||||||
|
# SoCSDRAM ---------------------------------------------------------------------------------
|
||||||
|
SoCSDRAM.__init__(
|
||||||
|
self,
|
||||||
|
platform,
|
||||||
|
clk_freq=sys_clk_freq,
|
||||||
|
ident="Minimal Arty DDR3 Design for tests with Project X-Ray",
|
||||||
|
ident_version=True,
|
||||||
|
cpu_type=None,
|
||||||
|
l2_size=16,
|
||||||
|
uart_name="bridge")
|
||||||
|
|
||||||
|
# CRG --------------------------------------------------------------------------------------
|
||||||
|
self.submodules.crg = _CRG(platform, sys_clk_freq)
|
||||||
|
|
||||||
|
# DDR3 SDRAM -------------------------------------------------------------------------------
|
||||||
|
if not self.integrated_main_ram_size:
|
||||||
|
self.submodules.ddrphy = s7ddrphy.A7DDRPHY(
|
||||||
|
platform.request("ddram"),
|
||||||
|
memtype="DDR3",
|
||||||
|
nphases=4,
|
||||||
|
sys_clk_freq=sys_clk_freq)
|
||||||
|
self.add_csr("ddrphy")
|
||||||
|
sdram_module = MT41K128M16(sys_clk_freq, "1:4")
|
||||||
|
self.register_sdram(
|
||||||
|
self.ddrphy,
|
||||||
|
geom_settings=sdram_module.geom_settings,
|
||||||
|
timing_settings=sdram_module.timing_settings)
|
||||||
|
|
||||||
|
def generate_sdram_phy_py_header(self):
|
||||||
|
f = open("sdram_init.py", "w")
|
||||||
|
f.write(
|
||||||
|
get_sdram_phy_py_header(
|
||||||
|
self.sdram.controller.settings.phy,
|
||||||
|
self.sdram.controller.settings.timing))
|
||||||
|
f.close()
|
||||||
|
|
||||||
|
|
||||||
|
# Load ---------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
def load():
|
||||||
|
prog = VivadoProgrammer()
|
||||||
|
prog.load_bitstream("build/gateware/top.bit")
|
||||||
|
|
||||||
|
|
||||||
|
# Build --------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
parser = argparse.ArgumentParser(
|
||||||
|
description="Minimal Arty DDR3 Design for tests with Project X-Ray")
|
||||||
|
parser.add_argument("--build", action="store_true", help="Build bitstream")
|
||||||
|
parser.add_argument("--load", action="store_true", help="Load bitstream")
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
if args.load:
|
||||||
|
load()
|
||||||
|
soc = BaseSoC()
|
||||||
|
builder = Builder(soc, output_dir="build", csr_csv="csr.csv")
|
||||||
|
builder.build(run=args.build)
|
||||||
|
soc.generate_sdram_phy_py_header()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
|
|
@ -0,0 +1,62 @@
|
||||||
|
#--------------------------------------------------------------------------------
|
||||||
|
# Auto-generated by Migen (--------) & LiteX (3350d33f) on 2020-02-03 11:41:31
|
||||||
|
#--------------------------------------------------------------------------------
|
||||||
|
csr_base,ctrl,0x82000000,,
|
||||||
|
csr_base,identifier_mem,0x82001800,,
|
||||||
|
csr_base,timer0,0x82002000,,
|
||||||
|
csr_base,ddrphy,0x82002800,,
|
||||||
|
csr_base,sdram,0x82004000,,
|
||||||
|
csr_register,ctrl_reset,0x82000000,1,rw
|
||||||
|
csr_register,ctrl_scratch,0x82000004,4,rw
|
||||||
|
csr_register,ctrl_bus_errors,0x82000014,4,ro
|
||||||
|
csr_register,timer0_load,0x82002000,4,rw
|
||||||
|
csr_register,timer0_reload,0x82002010,4,rw
|
||||||
|
csr_register,timer0_en,0x82002020,1,rw
|
||||||
|
csr_register,timer0_update_value,0x82002024,1,rw
|
||||||
|
csr_register,timer0_value,0x82002028,4,ro
|
||||||
|
csr_register,timer0_ev_status,0x82002038,1,rw
|
||||||
|
csr_register,timer0_ev_pending,0x8200203c,1,rw
|
||||||
|
csr_register,timer0_ev_enable,0x82002040,1,rw
|
||||||
|
csr_register,ddrphy_half_sys8x_taps,0x82002800,1,rw
|
||||||
|
csr_register,ddrphy_cdly_rst,0x82002804,1,rw
|
||||||
|
csr_register,ddrphy_cdly_inc,0x82002808,1,rw
|
||||||
|
csr_register,ddrphy_dly_sel,0x8200280c,1,rw
|
||||||
|
csr_register,ddrphy_rdly_dq_rst,0x82002810,1,rw
|
||||||
|
csr_register,ddrphy_rdly_dq_inc,0x82002814,1,rw
|
||||||
|
csr_register,ddrphy_rdly_dq_bitslip_rst,0x82002818,1,rw
|
||||||
|
csr_register,ddrphy_rdly_dq_bitslip,0x8200281c,1,rw
|
||||||
|
csr_register,sdram_dfii_control,0x82004000,1,rw
|
||||||
|
csr_register,sdram_dfii_pi0_command,0x82004004,1,rw
|
||||||
|
csr_register,sdram_dfii_pi0_command_issue,0x82004008,1,rw
|
||||||
|
csr_register,sdram_dfii_pi0_address,0x8200400c,2,rw
|
||||||
|
csr_register,sdram_dfii_pi0_baddress,0x82004014,1,rw
|
||||||
|
csr_register,sdram_dfii_pi0_wrdata,0x82004018,4,rw
|
||||||
|
csr_register,sdram_dfii_pi0_rddata,0x82004028,4,ro
|
||||||
|
csr_register,sdram_dfii_pi1_command,0x82004038,1,rw
|
||||||
|
csr_register,sdram_dfii_pi1_command_issue,0x8200403c,1,rw
|
||||||
|
csr_register,sdram_dfii_pi1_address,0x82004040,2,rw
|
||||||
|
csr_register,sdram_dfii_pi1_baddress,0x82004048,1,rw
|
||||||
|
csr_register,sdram_dfii_pi1_wrdata,0x8200404c,4,rw
|
||||||
|
csr_register,sdram_dfii_pi1_rddata,0x8200405c,4,ro
|
||||||
|
csr_register,sdram_dfii_pi2_command,0x8200406c,1,rw
|
||||||
|
csr_register,sdram_dfii_pi2_command_issue,0x82004070,1,rw
|
||||||
|
csr_register,sdram_dfii_pi2_address,0x82004074,2,rw
|
||||||
|
csr_register,sdram_dfii_pi2_baddress,0x8200407c,1,rw
|
||||||
|
csr_register,sdram_dfii_pi2_wrdata,0x82004080,4,rw
|
||||||
|
csr_register,sdram_dfii_pi2_rddata,0x82004090,4,ro
|
||||||
|
csr_register,sdram_dfii_pi3_command,0x820040a0,1,rw
|
||||||
|
csr_register,sdram_dfii_pi3_command_issue,0x820040a4,1,rw
|
||||||
|
csr_register,sdram_dfii_pi3_address,0x820040a8,2,rw
|
||||||
|
csr_register,sdram_dfii_pi3_baddress,0x820040b0,1,rw
|
||||||
|
csr_register,sdram_dfii_pi3_wrdata,0x820040b4,4,rw
|
||||||
|
csr_register,sdram_dfii_pi3_rddata,0x820040c4,4,ro
|
||||||
|
constant,config_clock_frequency,50000000,,
|
||||||
|
constant,config_cpu_type,none,,
|
||||||
|
constant,config_cpu_type_none,None,,
|
||||||
|
constant,config_csr_alignment,32,,
|
||||||
|
constant,config_csr_data_width,8,,
|
||||||
|
constant,config_l2_size,32,,
|
||||||
|
constant,config_shadow_base,2147483648,,
|
||||||
|
memory_region,sram,0x01000000,4096,cached
|
||||||
|
memory_region,csr,0x82000000,65536,cached
|
||||||
|
memory_region,main_ram,0x40000000,268435456,cached
|
||||||
|
|
|
@ -0,0 +1,33 @@
|
||||||
|
dfii_control_sel = 0x01
|
||||||
|
dfii_control_cke = 0x02
|
||||||
|
dfii_control_odt = 0x04
|
||||||
|
dfii_control_reset_n = 0x08
|
||||||
|
|
||||||
|
dfii_command_cs = 0x01
|
||||||
|
dfii_command_we = 0x02
|
||||||
|
dfii_command_cas = 0x04
|
||||||
|
dfii_command_ras = 0x08
|
||||||
|
dfii_command_wrdata = 0x10
|
||||||
|
dfii_command_rddata = 0x20
|
||||||
|
|
||||||
|
ddrx_mr1 = 0x6
|
||||||
|
|
||||||
|
init_sequence = [
|
||||||
|
("Release reset", 0, 0, dfii_control_odt | dfii_control_reset_n, 50000),
|
||||||
|
(
|
||||||
|
"Bring CKE high", 0, 0,
|
||||||
|
dfii_control_cke | dfii_control_odt | dfii_control_reset_n, 10000),
|
||||||
|
(
|
||||||
|
"Load Mode Register 2, CWL=5", 512, 2, dfii_command_ras
|
||||||
|
| dfii_command_cas | dfii_command_we | dfii_command_cs, 0),
|
||||||
|
(
|
||||||
|
"Load Mode Register 3", 0, 3, dfii_command_ras | dfii_command_cas
|
||||||
|
| dfii_command_we | dfii_command_cs, 0),
|
||||||
|
(
|
||||||
|
"Load Mode Register 1", 6, 1, dfii_command_ras | dfii_command_cas
|
||||||
|
| dfii_command_we | dfii_command_cs, 0),
|
||||||
|
(
|
||||||
|
"Load Mode Register 0, CL=6, BL=8", 2336, 0, dfii_command_ras
|
||||||
|
| dfii_command_cas | dfii_command_we | dfii_command_cs, 200),
|
||||||
|
("ZQ Calibration", 1024, 0, dfii_command_we | dfii_command_cs, 200),
|
||||||
|
]
|
||||||
|
|
@ -0,0 +1,228 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
import sys
|
||||||
|
import time
|
||||||
|
import argparse
|
||||||
|
|
||||||
|
from litex import RemoteClient
|
||||||
|
|
||||||
|
from sdram_init import *
|
||||||
|
|
||||||
|
|
||||||
|
def identify_fpga(wb):
|
||||||
|
""" Gets the FPGA identifier and prints it on terminal."""
|
||||||
|
fpga_id = ""
|
||||||
|
for i in range(256):
|
||||||
|
c = chr(wb.read(wb.bases.identifier_mem + 4 * i) & 0xff)
|
||||||
|
fpga_id += c
|
||||||
|
if c == "\0":
|
||||||
|
break
|
||||||
|
print(fpga_id)
|
||||||
|
|
||||||
|
|
||||||
|
def seed_to_data(seed, random=True):
|
||||||
|
if random:
|
||||||
|
return (1664525 * seed + 1013904223) & 0xffffffff
|
||||||
|
else:
|
||||||
|
return seed
|
||||||
|
|
||||||
|
|
||||||
|
def write_pattern(wb, length):
|
||||||
|
for i in range(length):
|
||||||
|
wb.write(wb.mems.main_ram.base + 4 * i, seed_to_data(i))
|
||||||
|
|
||||||
|
|
||||||
|
def check_pattern(wb, length, debug=False):
|
||||||
|
errors = 0
|
||||||
|
for i in range(length):
|
||||||
|
error = 0
|
||||||
|
if wb.read(wb.mems.main_ram.base + 4 * i) != seed_to_data(i):
|
||||||
|
error = 1
|
||||||
|
if debug:
|
||||||
|
print(
|
||||||
|
"{}: 0x{:08x}, 0x{:08x} KO".format(
|
||||||
|
i, wb.read(wb.mems.main_ram.base + 4 * i),
|
||||||
|
seed_to_data(i)))
|
||||||
|
else:
|
||||||
|
if debug:
|
||||||
|
print(
|
||||||
|
"{}: 0x{:08x}, 0x{:08x} OK".format(
|
||||||
|
i, wb.read(wb.mems.main_ram.base + 4 * i),
|
||||||
|
seed_to_data(i)))
|
||||||
|
errors += error
|
||||||
|
return errors
|
||||||
|
|
||||||
|
|
||||||
|
def find_bitslips_delays(wb):
|
||||||
|
""" Finds bitslip and delay values that can be used with the implemented DDR design."""
|
||||||
|
nbitslips = 8
|
||||||
|
ndelays = 32
|
||||||
|
nmodules = 2
|
||||||
|
nwords = 16
|
||||||
|
|
||||||
|
final_bitslip = None
|
||||||
|
final_delay = None
|
||||||
|
|
||||||
|
for bitslip in range(nbitslips):
|
||||||
|
print("bitslip {:d}: |".format(bitslip), end="")
|
||||||
|
for delay in range(ndelays):
|
||||||
|
for module in range(nmodules):
|
||||||
|
wb.regs.ddrphy_dly_sel.write(1 << module)
|
||||||
|
wb.regs.ddrphy_rdly_dq_rst.write(1)
|
||||||
|
wb.regs.ddrphy_rdly_dq_bitslip_rst.write(1)
|
||||||
|
for i in range(bitslip):
|
||||||
|
wb.regs.ddrphy_rdly_dq_bitslip.write(1)
|
||||||
|
for i in range(delay):
|
||||||
|
wb.regs.ddrphy_rdly_dq_inc.write(1)
|
||||||
|
write_pattern(wb, nwords)
|
||||||
|
errors = check_pattern(wb, nwords)
|
||||||
|
if errors:
|
||||||
|
print("..|", end="")
|
||||||
|
else:
|
||||||
|
print("{:02d}|".format(delay), end="")
|
||||||
|
final_bitslip = bitslip if final_bitslip is None else final_bitslip
|
||||||
|
final_delay = delay if final_delay is None else final_delay
|
||||||
|
sys.stdout.flush()
|
||||||
|
print("")
|
||||||
|
|
||||||
|
assert final_bitslip is not None and final_delay is not None, "bitslip/delay values not found"
|
||||||
|
|
||||||
|
return final_bitslip, final_delay
|
||||||
|
|
||||||
|
|
||||||
|
def set_bitslip_delay(wb, bitslip, delay):
|
||||||
|
""" Sets bitslip and delay values."""
|
||||||
|
nmodules = 2
|
||||||
|
|
||||||
|
for module in range(nmodules):
|
||||||
|
wb.regs.ddrphy_dly_sel.write(1 << module)
|
||||||
|
wb.regs.ddrphy_rdly_dq_rst.write(1)
|
||||||
|
wb.regs.ddrphy_rdly_dq_bitslip_rst.write(1)
|
||||||
|
for i in range(bitslip):
|
||||||
|
wb.regs.ddrphy_rdly_dq_bitslip.write(1)
|
||||||
|
for i in range(delay):
|
||||||
|
wb.regs.ddrphy_rdly_dq_inc.write(1)
|
||||||
|
|
||||||
|
|
||||||
|
def read_word_offset(read_only=False):
|
||||||
|
word = None
|
||||||
|
if not read_only:
|
||||||
|
print("\n==================================================\n")
|
||||||
|
print(
|
||||||
|
"Set a byte long word to write to memory (e.g. 0xdeadbeef): ",
|
||||||
|
end="")
|
||||||
|
word = int(input(), 16) & 0xffffffff
|
||||||
|
|
||||||
|
print("\n==================================================\n")
|
||||||
|
print("Set offset from base memory address: ", end="")
|
||||||
|
offset = int(input())
|
||||||
|
|
||||||
|
print("\n==================================================\n")
|
||||||
|
print("Set number of words to read or write: ", end="")
|
||||||
|
length = int(input())
|
||||||
|
|
||||||
|
return word, offset, length
|
||||||
|
|
||||||
|
|
||||||
|
def write_user_pattern(wb, offset, length, pattern):
|
||||||
|
for i in range(length):
|
||||||
|
wb.write(wb.mems.main_ram.base + 4 * (offset + i), pattern)
|
||||||
|
|
||||||
|
|
||||||
|
def read_user_pattern(wb, offset, length, pattern=None):
|
||||||
|
for i in range(length):
|
||||||
|
read_value = wb.read(wb.mems.main_ram.base + 4 * (offset + i))
|
||||||
|
|
||||||
|
if pattern is None:
|
||||||
|
print("0x{:08x}".format(read_value))
|
||||||
|
else:
|
||||||
|
if read_value == pattern:
|
||||||
|
outcome = "CORRECT"
|
||||||
|
else:
|
||||||
|
outcome = "INCORRECT"
|
||||||
|
|
||||||
|
print(
|
||||||
|
"{} --> 0x{:08x}, 0x{:08x}".format(
|
||||||
|
outcome, read_value, pattern))
|
||||||
|
|
||||||
|
|
||||||
|
def start_command_interface(wb):
|
||||||
|
|
||||||
|
cmd_list = """
|
||||||
|
Commands list:
|
||||||
|
0 --> Write memory
|
||||||
|
1 --> Read memory
|
||||||
|
2 --> Write/Read memory
|
||||||
|
3 --> Print commands list
|
||||||
|
4 --> Exit
|
||||||
|
"""
|
||||||
|
|
||||||
|
print(cmd_list)
|
||||||
|
|
||||||
|
while True:
|
||||||
|
print("\nWaiting for command: ", end="")
|
||||||
|
cmd = int(input())
|
||||||
|
|
||||||
|
if cmd == 0:
|
||||||
|
word, offset, length = read_word_offset()
|
||||||
|
write_user_pattern(wb, offset, length, word)
|
||||||
|
elif cmd == 1:
|
||||||
|
word, offset, length = read_word_offset(True)
|
||||||
|
read_user_pattern(wb, offset, length)
|
||||||
|
elif cmd == 2:
|
||||||
|
word, offset, length = read_word_offset()
|
||||||
|
write_user_pattern(wb, offset, length, word)
|
||||||
|
read_user_pattern(wb, offset, length, word)
|
||||||
|
elif cmd == 3:
|
||||||
|
print(cmd_list)
|
||||||
|
elif cmd == 4:
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
print("Command not recognized, try again...")
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
parser = argparse.ArgumentParser(
|
||||||
|
description="Script to test correct DDR behaviour.")
|
||||||
|
|
||||||
|
parser.add_argument(
|
||||||
|
'--bitslip', default=None, help="Defines a bitslip value.")
|
||||||
|
parser.add_argument('--delay', default=None, help="Defines a delay value.")
|
||||||
|
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
wb = RemoteClient(debug=False)
|
||||||
|
wb.open()
|
||||||
|
|
||||||
|
# software control
|
||||||
|
wb.regs.sdram_dfii_control.write(0)
|
||||||
|
|
||||||
|
# sdram initialization
|
||||||
|
for i, (comment, a, ba, cmd, delay) in enumerate(init_sequence):
|
||||||
|
print(comment)
|
||||||
|
wb.regs.sdram_dfii_pi0_address.write(a)
|
||||||
|
wb.regs.sdram_dfii_pi0_baddress.write(ba)
|
||||||
|
if i < 2:
|
||||||
|
wb.regs.sdram_dfii_control.write(cmd)
|
||||||
|
else:
|
||||||
|
wb.regs.sdram_dfii_pi0_command.write(cmd)
|
||||||
|
wb.regs.sdram_dfii_pi0_command_issue.write(1)
|
||||||
|
|
||||||
|
# hardware control
|
||||||
|
wb.regs.sdram_dfii_control.write(dfii_control_sel)
|
||||||
|
|
||||||
|
if args.bitslip is None or args.delay is None:
|
||||||
|
bitslip, delay = find_bitslips_delays(wb)
|
||||||
|
else:
|
||||||
|
bitslip = int(args.bitslip)
|
||||||
|
delay = int(args.delay)
|
||||||
|
|
||||||
|
set_bitslip_delay(wb, bitslip, delay)
|
||||||
|
|
||||||
|
start_command_interface(wb)
|
||||||
|
|
||||||
|
wb.close()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
|
|
@ -0,0 +1,33 @@
|
||||||
|
PART = xc7a35tcsg324-1
|
||||||
|
BIT2FASM_ARGS = --part "$(XRAY_DIR)/database/artix7/$(PART)" --verbose
|
||||||
|
SOURCES = ../generated/mem.init ../generated/mem_1.init ../generated/top.v ../generated/top.xdc
|
||||||
|
|
||||||
|
all: top.fasm top.bits segprint.log
|
||||||
|
|
||||||
|
clean:
|
||||||
|
@rm -f *.bit
|
||||||
|
@rm -f *.bin
|
||||||
|
@rm -f *.bits
|
||||||
|
@rm -f *.fasm
|
||||||
|
@rm -f *.log
|
||||||
|
@rm -rf build
|
||||||
|
|
||||||
|
.PHONY: all clean
|
||||||
|
|
||||||
|
top.bit: $(VIVADO) $(SOURCES) top.tcl
|
||||||
|
mkdir -p build
|
||||||
|
cd build && $(XRAY_VIVADO) -mode batch -source ../top.tcl -nojournal -tempDir build -log vivado.log -verbose
|
||||||
|
cp build/*.bit ./
|
||||||
|
|
||||||
|
top.fasm: top.bit
|
||||||
|
PYTHONPATH="$(XRAY_DIR):$(XRAY_DIR)/utils:$(XRAY_DIR)/third_party/fasm" \
|
||||||
|
PATH="$(XRAY_DIR)/build/tools:$(PATH)" \
|
||||||
|
$(XRAY_BIT2FASM) $(BIT2FASM_ARGS) \
|
||||||
|
top.bit >top.fasm \
|
||||||
|
|| (rm -f top.fasm && exit 1)
|
||||||
|
|
||||||
|
top.bits: top.bit
|
||||||
|
$(XRAY_BITREAD) -part_file $(XRAY_DIR)/database/artix7/$(PART)/part.yaml -o top.bits -z -y top.bit
|
||||||
|
|
||||||
|
segprint.log: top.bits
|
||||||
|
$(XRAY_SEGPRINT) -z -D -b top.bits > segprint.log
|
||||||
|
|
@ -0,0 +1,26 @@
|
||||||
|
create_project -force -name top -part xc7a35ticsg324-1L
|
||||||
|
add_files {../../generated/top.v}
|
||||||
|
read_xdc ../../generated/top.xdc
|
||||||
|
synth_design -top top -part xc7a35ticsg324-1L
|
||||||
|
report_timing_summary -file top_timing_synth.rpt
|
||||||
|
report_utilization -hierarchical -file top_utilization_hierarchical_synth.rpt
|
||||||
|
report_utilization -file top_utilization_synth.rpt
|
||||||
|
opt_design
|
||||||
|
place_design
|
||||||
|
report_utilization -hierarchical -file top_utilization_hierarchical_place.rpt
|
||||||
|
report_utilization -file top_utilization_place.rpt
|
||||||
|
report_io -file top_io.rpt
|
||||||
|
report_control_sets -verbose -file top_control_sets.rpt
|
||||||
|
report_clock_utilization -file top_clock_utilization.rpt
|
||||||
|
route_design
|
||||||
|
phys_opt_design
|
||||||
|
report_timing_summary -no_header -no_detailed_paths
|
||||||
|
write_checkpoint -force top_route.dcp
|
||||||
|
report_route_status -file top_route_status.rpt
|
||||||
|
report_drc -file top_drc.rpt
|
||||||
|
report_timing_summary -datasheet -max_paths 10 -file top_timing.rpt
|
||||||
|
report_power -file top_power.rpt
|
||||||
|
set_property BITSTREAM.CONFIG.SPI_BUSWIDTH 4 [current_design]
|
||||||
|
write_bitstream -force top.bit
|
||||||
|
write_cfgmem -force -format bin -interface spix4 -size 16 -loadbit "up 0x0 top.bit" -file top.bin
|
||||||
|
quit
|
||||||
|
|
@ -0,0 +1,51 @@
|
||||||
|
export XRAY_PART = xc7a35tcsg324-1
|
||||||
|
export XRAY_PART_YAML = $(XRAY_DATABASE_DIR)/$(XRAY_DATABASE)/$(XRAY_PART)/part.yaml
|
||||||
|
YOSYS = $(XRAY_DIR)/third_party/yosys/yosys
|
||||||
|
SOURCES = ../generated/mem.init ../generated/mem_1.init ../generated/top.v ../generated/top.xdc
|
||||||
|
PORT ?= /dev/ttyUSB1
|
||||||
|
|
||||||
|
all: top.f2b.bit
|
||||||
|
|
||||||
|
clean:
|
||||||
|
@rm -f *.edif
|
||||||
|
@rm -f *.bit
|
||||||
|
@rm -f *.bin
|
||||||
|
@rm -f *.bits
|
||||||
|
@rm -f *.fasm
|
||||||
|
@rm -f *.frames
|
||||||
|
@rm -f *.log
|
||||||
|
@rm -rf build
|
||||||
|
|
||||||
|
.PHONY: all clean
|
||||||
|
|
||||||
|
$(YOSYS):
|
||||||
|
cd $(XRAY_DIR)/third_party/yosys && make config-gcc && make -j$(shell nproc)
|
||||||
|
|
||||||
|
top.edif: $(YOSYS) synth.ys $(SOURCES)
|
||||||
|
$(YOSYS) -s synth.ys -l yosys.log
|
||||||
|
|
||||||
|
top.bit: $(VIVADO) top.edif top.tcl
|
||||||
|
mkdir -p build
|
||||||
|
cd build && $(XRAY_VIVADO) -mode batch -source ../top.tcl -nojournal -tempDir build -log vivado.log -verbose
|
||||||
|
python3 $(XRAY_DIR)/minitests/timing/clean_json5.py < build/iobuf_report.json5 > build/iobuf_report.json
|
||||||
|
cp build/*.bit ./
|
||||||
|
|
||||||
|
top.fasm: top.bit
|
||||||
|
$(XRAY_BIT2FASM) --verbose $< > $@ \
|
||||||
|
|| (rm -f top.fasm && exit 1)
|
||||||
|
|
||||||
|
top.bits: top.bit
|
||||||
|
$(XRAY_BITREAD) -part_file $(XRAY_PART_YAML) -o top.bits -z -y top.bit
|
||||||
|
|
||||||
|
segprint.log: top.bits
|
||||||
|
$(XRAY_SEGPRINT) -z -D -b top.bits > segprint.log
|
||||||
|
|
||||||
|
top.frames: top.fasm
|
||||||
|
$(XRAY_FASM2FRAMES) $< $@
|
||||||
|
|
||||||
|
top.f2b.bit: top.frames
|
||||||
|
$(XRAY_DIR)/build/tools/xc7frames2bit --output_file $@ --part_name $(XRAY_PART) --part_file $(XRAY_PART_YAML) --frm_file $<
|
||||||
|
|
||||||
|
program: top.f2b.bit
|
||||||
|
xc3sprog -c nexys4 top.f2b.bit
|
||||||
|
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
../generated/mem.init
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
../generated/mem_1.init
|
||||||
|
|
@ -0,0 +1,2 @@
|
||||||
|
read_verilog ../generated/top.v
|
||||||
|
synth_xilinx -edif top.edif
|
||||||
|
|
@ -0,0 +1,60 @@
|
||||||
|
proc write_iobuf_report {filename} {
|
||||||
|
set fp [open $filename w]
|
||||||
|
puts $fp "{ \"tiles\": \["
|
||||||
|
foreach port [get_ports] {
|
||||||
|
set net [get_nets -of $port]
|
||||||
|
if { $net == "" } {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
set cell [get_cells -of $net]
|
||||||
|
set site [get_sites -of $cell]
|
||||||
|
set tile [get_tiles -of $site]
|
||||||
|
|
||||||
|
puts $fp "{"
|
||||||
|
puts $fp "\"port\": \"$port\","
|
||||||
|
puts $fp "\"pad_wire\": \"$net\","
|
||||||
|
puts $fp "\"cell\": \"$cell\","
|
||||||
|
puts $fp "\"site\": \"$site\","
|
||||||
|
puts $fp "\"tile\": \"$tile\","
|
||||||
|
puts $fp "\"type\": \"[get_property REF_NAME $cell]\","
|
||||||
|
puts $fp "\"IOSTANDARD\": \"\\\"[get_property IOSTANDARD $cell]\\\"\","
|
||||||
|
puts $fp "\"PULLTYPE\": \"\\\"[get_property PULLTYPE $cell]\\\"\","
|
||||||
|
puts $fp "\"DRIVE\": \"[get_property DRIVE $cell]\","
|
||||||
|
puts $fp "\"SLEW\": \"\\\"[get_property SLEW $cell]\\\"\","
|
||||||
|
puts $fp "},"
|
||||||
|
}
|
||||||
|
puts $fp "\]}"
|
||||||
|
close $fp
|
||||||
|
}
|
||||||
|
|
||||||
|
create_project -force -name top -part xc7a35ticsg324-1L
|
||||||
|
read_xdc ../../generated/top.xdc
|
||||||
|
read_edif ../top.edif
|
||||||
|
link_design -top top -part xc7a35ticsg324-1L
|
||||||
|
report_timing_summary -file top_timing_synth.rpt
|
||||||
|
report_utilization -hierarchical -file top_utilization_hierarchical_synth.rpt
|
||||||
|
report_utilization -file top_utilization_synth.rpt
|
||||||
|
opt_design
|
||||||
|
place_design
|
||||||
|
report_utilization -hierarchical -file top_utilization_hierarchical_place.rpt
|
||||||
|
report_utilization -file top_utilization_place.rpt
|
||||||
|
report_io -file top_io.rpt
|
||||||
|
report_control_sets -verbose -file top_control_sets.rpt
|
||||||
|
report_clock_utilization -file top_clock_utilization.rpt
|
||||||
|
route_design
|
||||||
|
phys_opt_design
|
||||||
|
report_timing_summary -no_header -no_detailed_paths
|
||||||
|
write_checkpoint -force top_route.dcp
|
||||||
|
report_route_status -file top_route_status.rpt
|
||||||
|
report_drc -file top_drc.rpt
|
||||||
|
report_timing_summary -datasheet -max_paths 10 -file top_timing.rpt
|
||||||
|
report_power -file top_power.rpt
|
||||||
|
set_property BITSTREAM.CONFIG.SPI_BUSWIDTH 4 [current_design]
|
||||||
|
write_bitstream -force top.bit
|
||||||
|
write_cfgmem -force -format bin -interface spix4 -size 16 -loadbit "up 0x0 top.bit" -file top.bin
|
||||||
|
|
||||||
|
write_iobuf_report iobuf_report.json5
|
||||||
|
|
||||||
|
|
||||||
|
quit
|
||||||
Loading…
Reference in New Issue