Skip to content

Commit

Permalink
Merge pull request #2 from daveshah1/new-docs
Browse files Browse the repository at this point in the history
Start writing docs & creating tools
  • Loading branch information
gatecat committed Apr 28, 2018
2 parents 581bb63 + 9a87582 commit 53c0077
Show file tree
Hide file tree
Showing 27 changed files with 1,300 additions and 1 deletion.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
__pycache__/
*.pyc

158 changes: 158 additions & 0 deletions diamond.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
#!/bin/bash

# Script to run Lattice Diamond on a Verilog source file and LPF constraints file, then run some extra commands
# to create debug/dump output for the design

# Based on Clifford Wolf's icecube.sh from Project Icestorm

# Usage:
# ./diamond.sh part design.v
# Currently supported parts:
# - lfe5u-85
# - lfe5u-45
# - lfe5u-25

# Currently this script supports Linux only.

# You need to set the DIAMONDDIR environment variable to the path where you have
# installed Lattice Diamond, unless it matches this default.

diamonddir="${DIAMONDDIR:-/usr/local/diamond/3.10_x64}"
export FOUNDRY="${diamonddir}/ispfpga"
bindir="${diamonddir}/bin/lin64"
LSC_DIAMOND=true
export LSC_DIAMOND
export NEOCAD_MAXLINEWIDTH=32767
export TCL_LIBRARY="${diamonddir}/tcltk/lib/tcl8.5"
export fpgabindir=${FOUNDRY}/bin/lin64
export LD_LIBRARY_PATH="${bindir}:${fpgabindir}"
export LM_LICENSE_FILE="${diamonddir}/license/license.dat"

set -ex
set -- "$1" ${2%.v}

PART=$1

case "${PART}" in
LFE5U-85F)
PACKAGE="${DEV_PACKAGE:-CABGA756}"
DEVICE="LFE5U-85F"
LSE_ARCH="ECP5U"
;;
LFE5U-45F)
PACKAGE="${DEV_PACKAGE:-CABGA381}"
DEVICE="LFE5U-45F"
LSE_ARCH="ECP5U"
;;
LFE5U-25F)
PACKAGE="${DEV_PACKAGE:-CABGA381}"
DEVICE="LFE5U-25F"
LSE_ARCH="ECP5U"
;;
LFE5UM-85F)
PACKAGE="${DEV_PACKAGE:-CABGA756}"
DEVICE="LFE5UM-85F"
LSE_ARCH="ECP5UM"
;;
LCMXO2-2000HC)
PACKAGE="${DEV_PACKAGE:-TQFP100}"
DEVICE="LCMXO2-2000HC"
LSE_ARCH="MachXO2"
;;
LCMXO2-7000HC)
PACKAGE="${DEV_PACKAGE:-TQFP144}"
DEVICE="LCMXO2-7000HC"
LSE_ARCH="MachXO2"
;;
LCMXO3LF-9400C)
PACKAGE="${DEV_PACKAGE:-CABGA256}"
DEVICE="LCMXO3LF-9400C"
LSE_ARCH="MachXO3LF"
;;
LIF-MD6000)
PACKAGE="${DEV_PACKAGE:-csFBGA81}"
DEVICE="LIF-MD6000"
LSE_ARCH="LIFMD"
;;
esac

(
rm -rf "$2.tmp"
mkdir -p "$2.tmp"
cp "$2.v" "$2.tmp/input.v"
if test -f "$2.sdc"; then cp "$2.sdc" "$2.tmp/input.sdc"; fi
if test -f "$2.lpf"; then cp "$2.lpf" "$2.tmp/input.lpf"; fi
cd "$2.tmp"

touch input.sdc
touch input.lpf

cat > impl_lse.prj << EOT
#device
-a "$LSE_ARCH"
-d $DEVICE
-t $PACKAGE
-frequency 200
-optimization_goal Timing
-bram_utilization 100
-ramstyle Auto
-romstyle auto
-dsp_utilization 100
-use_dsp 1
-use_carry_chain 1
-carry_chain_length 0
-force_gsr Auto
-resource_sharing 1
-propagate_constants 1
-remove_duplicate_regs 1
-mux_style Auto
-max_fanout 1000
-fsm_encoding_style Auto
-twr_paths 3
-fix_gated_clocks 1
-loop_limit 1950
-use_io_insertion 1
-resolve_mixed_drivers 0
-use_io_reg auto
-ver "input.v"
-p "$PWD"
-ngd "synth_impl.ngd"
-lpf 1
EOT

# run LSE synthesis
"$fpgabindir"/synthesis -f "impl_lse.prj"

# map design
"$fpgabindir"/map -a $LSE_ARCH -p $DEVICE -t $PACKAGE synth_impl.ngd -o map_impl.ncd -lpf synth_impl.lpf -lpf input.lpf

# place and route design
"$fpgabindir"/par map_impl.ncd par_impl.ncd synth_impl.prf

# make bitmap
"$fpgabindir"/bitgen par_impl.ncd output.bit

# dump bitmap
"$fpgabindir"/bstool -d output.bit > output.dump

# run test on bitmap (for tilemap)
"$fpgabindir"/bstool -t output.bit > output.test

# convert ngd to ncl
"$FOUNDRY"/userware/unix/bin/lin64/ncd2ncl par_impl.ncd output.ncl

# run incdelay
"$fpgabindir"/incdelay -d par_impl.ncd > output.incd


export LD_LIBRARY_PATH=""
)

cp "$2.tmp"/output.bit "$2.bit"
cp "$2.tmp"/output.dump "$2.dump"
cp "$2.tmp"/output.ncl "$2.ncl"
cp "$2.tmp"/output.incd "$2.incd"
1 change: 1 addition & 0 deletions docs/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
_build
24 changes: 24 additions & 0 deletions docs/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Minimal makefile for Sphinx documentation
#

# You can set these variables from the command line.
SPHINXOPTS =
SPHINXBUILD = sphinx-build
SPHINXAUTOBUILD = sphinx-autobuild
SPHINXPROJ = ProjectX-Ray
SOURCEDIR = .
BUILDDIR = _build

# Put it first so that "make" without argument is like "make help".
help:
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)

livehtml:
@$(SPHINXAUTOBUILD) -b html --ignore \*.swp --ignore \*~ $(SPHINXOPTS) "$(SOURCEDIR)" "$(BUILDDIR)/html"

.PHONY: help livereload Makefile

# Catch-all target: route all unknown targets to Sphinx using the new
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
%: Makefile
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
12 changes: 12 additions & 0 deletions docs/architecture/bitstream_format.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
Bitstream format
================

.. todo::
Expand on rough notes


* Lattice BIT header

* Additional information about how bitstream was generated
* A series of null-terminated strings, with FF 00 at the start and 00 FF at the end
* Is ignored entirely by devices
2 changes: 2 additions & 0 deletions docs/architecture/general_routing.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
General Routing
===============
158 changes: 158 additions & 0 deletions docs/architecture/global_routing.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
Global Routing
===============

The ECP5's global clock routing is split into a number of parts. A high level overview of its structure is contained
in Lattice Technical Note TN1263.

From a point of view of clock distribution, the device is split into four quadrants: upper left (UL), upper right (UR),
lower left (LL) and lower right (LR). Throughout this document, *qq* refers to any quadrant named in this way,
*s* refers to a side of the device (B, T, L, or R).

This document is a work in progress! Some information is still incomplete and subject to change.

Mid Muxes
----------
The mid muxes are located in the middle of each edge of the device, and take clock inputs from a range of sources
(clock input pins, PLL ouputs, CLKDIV outputs, etc) and feed them into the centre clock muxes.

Depending on the location, mid muxes have between 12 and 16 outputs to the centre muxes.

Between each mid mux multiplexer output and the centre mux is a Dynamic Clock Control component (DCC),
which provides glitch free clock disable.

Inputs to the mid muxes are named as follows:

- **PCLKx_y** for the dedicated clock input pins
- **qqC_PCLKGPLLx_y** for the PLL outputs
- **s_CDIVX_x** for the clock divider outputs
- **qqQ_PCLKCIB_x** and **qqM_PCLKCIBx** have unknown function, most likely a connection to fabric (TODO: check)
- **PCSx_TXCLK_y** and **PCSx_RXCLK_y** are the SERDES transmit and receive clocks
- **SERDES_REFCLK_x** are the SERDES reference clocks

Outputs from the muxes themselves into the DCCs are named **sDCC00CLKI** through **sDCCnnCLKI**.

The outputs from the DCCs into the centre muxes are named **HPFE0000** through **HPFE1300** for the left side;
**HPFW0000** through **HPFW1300** for the right side; **VPFN0000** through **VPFN1500** for the bottom side and
**VPFS0000** through **VPFS1100** for the top side.

The left and right muxes are located in a single tile, **LMID_0** and **RMID_0** respectively. The top side is
split between **TMID_0** and **TMID_1**, and the bottom side between **BMID_0** and **BMID_2V**.

Centre Muxes
------------

The centre muxes select the 16 global clocks for each quadrant from the outputs of the mid muxes and from a few other
sources. They also contain a total of two Dynamic Clock Select blocks, for glitch-free clock switching.

There are four fabric entries to the centre muxes from each of the four quadrants. These connect through DCCs in the
same way as the mid mux outputs (but in this case the DCC is considered as part of the centre mux rather than mid mux).

The fabric entries come from nearby CIBs, but the exact net still need to be traced.

Inputs to the mid muxes (and DCSs) are named as follows:

- **HPFExx00**, **HPFWxx00**, **VPFNxx00** and **VPFSxx00** for the mid mux (via DCC) outputs
- **qqCPCLKCIB0** for the fabric clock inputs (via DCC)
- **DCSx** for the DCS outputs
- **VCC_INT** for constant one

Outputs from the centre muxes, going into the spine tiles, are named **qqPCLK0** through **qqPCLK15**.

Centre muxes also contain *CLKTEST*, a component with unknown function used in Lattice's testing.

The exact split of centre mux functionality between tiles varies depending on device, this is an example
for the LFE5U-85F.

+-------------+---------------+-----------------------------------------+-----------------+
| Tile | Tile Type | Functions | Notes |
+=============+===============+=========================================+=================+
| MIB_R22C66 | EBR_CMUX_UL | DCS0 config, CLKTEST | Shared with EBR |
+-------------+---------------+-----------------------------------------+-----------------+
| MIB_R22C67 | CMUX_UL_0 | UL clocks mux, DCS0CLK0 input mux, DCC2 | |
+-------------+---------------+-----------------------------------------+-----------------+
| MIB_R22C68 | CMUX_UR_0 | UR clocks mux, DCS0CLK1 input mux, DCC3 | |
+-------------+---------------+-----------------------------------------+-----------------+
| MIB_R22C69 | EBR_CMUX_UR | CLKTEST | Shared with EBR |
+-------------+---------------+-----------------------------------------+-----------------+
| MIB_R70C66 | EBR_CMUX_LL | DCS1 config, CLKTEST | Shared with EBR |
+-------------+---------------+-----------------------------------------+-----------------+
| MIB_R70C67 | CMUX_LL_0 | LL clocks mux, DCS1CLK0 input mux, DCC0 | |
+-------------+---------------+-----------------------------------------+-----------------+
| MIB_R70C68 | CMUX_LR_0 | LR clocks mux, DCS1CLK1 input mux, DCC1 | |
+-------------+---------------+-----------------------------------------+-----------------+
| MIB_R70C69 | EBR_CMUX_LR | CLKTEST | Shared with EBR |
+-------------+---------------+-----------------------------------------+-----------------+

Spine Tiles
------------
The outputs from the centre muxes go horizontally into each quadrant and connect to a few spine tiles (there are three
spine tiles per quadrant in the 85k part). Spine tiles are located adjacent to a column of TAP_DRIVEs (see next section)
and are combined with another function (EBR or DSP).

The purpose of a spine tile is to selectively connect the centre mux outputs to the vertical global wires feeding the
adjacent column of TAP_DRIVEs through a buffer. There is one buffer per wire, with a 1:1 mapping - the only reason
spine tiles are configurable is to disable unused buffers to save power, there is no other routing or selection
capability in them.

The inputs to spine tiles from the quadrant's centre mux are named **qqPCLK0** through **qqPCLK15**.

The outputs are named **LHPRX0000** through **LHPRX15000** for left side spine tiles, and **RHPRX0000** through
**RHPRX1500** for right side spine tiles, which feed one row of TAP_DRIVEs.

TAP_DRIVE Tiles
---------------
TAP_DRIVE tiles are arranged in columns throughout the device.

The purpose of TAP_DRIVE tiles is to selectively connect the vertical global wires coming out of the adjacent spine tile
to horizontal wires serving tiles to the left and right of the TAP_DRIVE. A TAP_DRIVE will typically serve a row of
about 20 tiles, 10 to the left and 10 to the right.

Like spine tiles, TAP_DRIVE tiles have a 1:1 input-output mapping and only offer the ability to turn on/of buffers
to save power.

The inputs to the TAP_DRIVE tiles from the spine are named **HPRX0000** through **HPRX1500**. The outputs feeding
tiles to the left are named **LVPTX0000** through **LVPTX1500**, and the outputs feeding tiles to the right are named
**RVPTX0000** through **RVPTX1500**.

Non-Clock Global Usage
-----------------------
Inside PLBs, global nets can not only be connected to the clock signal, but also to clock enable, set/reset and general
local wires. This does not seem to be commonly used by Diamond, which prefers to use general routing and the GSR signal.

Not all globals can be used for all functions, the allowed usage depending on net is shown below.

+--------+-----+-----+-----+-------+
| Global | CLK | LSR | CEN | Local |
+--------+-----+-----+-----+-------+
| 0 | Y | | | Y |
+--------+-----+-----+-----+-------+
| 1 | Y | | | Y |
+--------+-----+-----+-----+-------+
| 2 | Y | | | Y |
+--------+-----+-----+-----+-------+
| 3 | Y | | | Y |
+--------+-----+-----+-----+-------+
| 4 | Y | Y | | Y |
+--------+-----+-----+-----+-------+
| 5 | Y | Y | | Y |
+--------+-----+-----+-----+-------+
| 6 | Y | Y | | Y |
+--------+-----+-----+-----+-------+
| 7 | Y | Y | | Y |
+--------+-----+-----+-----+-------+
| 8 | Y | Y | | |
+--------+-----+-----+-----+-------+
| 9 | Y | | Y | |
+--------+-----+-----+-----+-------+
| 10 | Y | | Y | |
+--------+-----+-----+-----+-------+
| 11 | Y | | Y | |
+--------+-----+-----+-----+-------+
| 12 | Y | | Y | |
+--------+-----+-----+-----+-------+
| 13 | Y | | Y | |
+--------+-----+-----+-----+-------+
| 14 | Y | Y | Y | |
+--------+-----+-----+-----+-------+
| 15 | Y | Y | Y | |
+--------+-----+-----+-----+-------+

0 comments on commit 53c0077

Please sign in to comment.