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