zynq-sandbox

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README

commit 305ecdc23c8e4fd7df9011312fb1b4f122a4c38a
Author: Brian Swetland <swetland@frotz.net>
Date:   Thu,  3 Jul 2014 22:33:23 -0700

initial (non-ipi version)

Old version archived in deprecated-v0

Diffstat:
A.gitignore | 4++++
AMakefile | 28++++++++++++++++++++++++++++
AREADME | 54++++++++++++++++++++++++++++++++++++++++++++++++++++++
Abuild/build-bitfile.tcl | 27+++++++++++++++++++++++++++
Abuild/build.tcl | 27+++++++++++++++++++++++++++
Abuild/init.mk | 24++++++++++++++++++++++++
Abuild/mkzynq.go | 205+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Abuild/review.tcl | 2++
Abuild/testbench.cpp | 121+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Abuild/verilator-sim.mk | 48++++++++++++++++++++++++++++++++++++++++++++++++
Abuild/vivado-bitfile.mk | 57+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ahdl/axi_ifc.sv | 85+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ahdl/axi_registers.sv | 176+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ahdl/hdmi_core.sv | 129+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ahdl/mmcm_1in_3out.sv | 92+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ahdl/serdes_10to1_tx.sv | 88+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ahdl/tmds_encoder.sv | 81+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ahdl/zybo_hdmi.sv | 75+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ahdl/zybo_hdmi.xdc | 40++++++++++++++++++++++++++++++++++++++++
Ahdl/zybo_hdmi_axi.sv | 103+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ahdl/zynq_ps_1m.sv | 638+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
21 files changed, 2104 insertions(+), 0 deletions(-)

diff --git a/.gitignore b/.gitignore @@ -0,0 +1,4 @@ +sim +synth +out +.*.swp diff --git a/Makefile b/Makefile @@ -0,0 +1,28 @@ + +include build/init.mk + +all: + +HDMI_SRCS := \ + hdl/hdmi_core.sv \ + hdl/mmcm_1in_3out.sv \ + hdl/serdes_10to1_tx.sv \ + hdl/tmds_encoder.sv + +MODULE_NAME := zybo-hdmi-axi +MODULE_PART := xc7z010clg400-2 +MODULE_SRCS := hdl/zybo_hdmi_axi.sv +MODULE_SRCS += hdl/axi_ifc.sv hdl/axi_registers.sv hdl/zynq_ps_1m.sv +MODULE_SRCS += $(HDMI_SRCS) +MODULE_SRCS += hdl/zybo_hdmi.xdc +include build/vivado-bitfile.mk + +MODULE_NAME := zybo-hdmi +MODULE_PART := xc7z010clg400-2 +MODULE_SRCS := hdl/zybo_hdmi.sv +MODULE_SRCS += $(HDMI_SRCS) +MODULE_SRCS += hdl/zybo_hdmi.xdc +include build/vivado-bitfile.mk + +clean:: + rm -rf sim synth out diff --git a/README b/README @@ -0,0 +1,54 @@ + +This is a collection of tools, scripts, verilog, etc, for experimenting +with the Xilinx Zynq SoC FPGA, particularly around using a commandline +workflow and avoiding the IPI (IP Integrator) workflow. + +An earlier version that attempted to make use of IPI from the commandline +lives in the deprecated-v0 branch. + +Warning: This is very much a work in progress. + +Projects +-------- +zybo-hdmi - display a test pattern ZYBO board's HDMI output +zybo-hdmi-axi - same, but add an axi slave to adjust the pattern + +Repository Layout +----------------- +hdl/... - verilog, systemverilog, and xdc sources +build/... - makefiles and tcl scripts + +Generated Files +--------------- +ip/${name}/... - where Vivado IP packages are generated +sim/${name}-vsim/... - where Verilator intermediates are generated +synth/${name}/... - where Vivado synthesis intermediates are generated +out/... - where FPGA final products (bitfiles/etc) end up +out/${name}.bit - bitfile for project name + +Build System Notes +------------------ + +1. Declare the name of the module and its sources (.v, .sv, .hex): + +MODULE_NAME := ... +MODULE_SRCS := ... + +2. invoke the appropriate build rules for the module type: + +include build/verilator-sim.mk + - create Verilator simulation target + - required: a top level module named testbench(input clk) + - provided: clock signal + - to run: make modulename-vsim + +include build/vivado-bitfile.mk + - create Xilinx out/$(MODULE_NAME).bit bitfile + - target device MODULE_PART + - required: a top level module named top + - to build: make modulename + +Tools +----- +build/mkzynq.go - Generates useful wrappers around Zynq PS7 macro + diff --git a/build/build-bitfile.tcl b/build/build-bitfile.tcl @@ -0,0 +1,27 @@ + +source config.tcl + +synth_design -top top -part $PART + +write_checkpoint -force ./post-synth-checkpoint.dcp +report_utilization -file ./post-synth-utilization.txt +report_timing -sort_by group -max_paths 5 -path_type summary -file ./post-synth-timing.txt + +opt_design +power_opt_design +place_design +write_checkpoint -force ./post-place-checkpoint.dcp + +phys_opt_design +route_design +write_checkpoint -force ./post-route-checkpoint.dcp + +report_utilization -file ./post-route-utilization.txt +report_timing_summary -file ./post-route-timing-summary.txt +report_timing -sort_by group -max_paths 100 -path_type summary -file ./post-route-timing.txt +report_drc -file ./post-route-drc.txt +write_verilog -force ./post-route-netlist.v +write_xdc -no_fixed_only -force ./post-route-constr.xdc + +write_bitstream -force -file $BITFILE + diff --git a/build/build.tcl b/build/build.tcl @@ -0,0 +1,27 @@ + +source out/files.tcl + +synth_design -top top -part $part xc7z010clg400-2 + +write_checkpoint -force ./out/post-synth-checkpoint.dcp +report_utilization -file ./out/post-synth-utilization.txt +report_timing -sort_by group -max_paths 5 -path_type summary -file ./out/post-synth-timing.txt + +opt_design +power_opt_design +place_design +write_checkpoint -force ./out/post-place-checkpoint.dcp + +phys_opt_design +route_design +write_checkpoint -force ./out/post-route-checkpoint.dcp + +report_utilization -file ./out/post-route-utilization.txt +report_timing_summary -file ./out/post-route-timing-summary.txt +report_timing -sort_by group -max_paths 100 -path_type summary -file ./out/post-route-timing.txt +report_drc -file ./out/post-route-drc.txt +write_verilog -force ./out/post-route-netlist.v +write_xdc -no_fixed_only -force ./out/post-route-constr.xdc + +write_bitstream -force -file ./out/design.bit + diff --git a/build/init.mk b/build/init.mk @@ -0,0 +1,24 @@ +## Copyright 2014 Brian Swetland <swetland@frotz.net> +## +## Licensed under the Apache License, Version 2.0 +## http://www.apache.org/licenses/LICENSE-2.0 + +VERILATOR := VERILATOR_ROOT=/work/verilator /work/verilator/bin/verilator + +VIVADOPATH := /work/xilinx/Vivado/2014.2 +XSDKPATH := /work/xilinx/SDK/2014.2 + +VIVADO := $(VIVADOPATH)/bin/vivado +XELAB := $(VIVADOPATH)/bin/xelab +XSIM := $(VIVADOPATH)/bin/xsim +XMD := $(XSDKPATH)/bin/xmd + +ifeq ("$(VERBOSE)","") +# reduce the firehose of output chatter from Vivado +VIVADO_FILTER := | grep -e "^INFO:.*Inferred" -e "^WARNING:" -e "^ERROR:" +VIVADO_FILTER += | grep -v '\[Board 49-26\]' +endif + +IP_ALL := +VERILATOR_ALL := + diff --git a/build/mkzynq.go b/build/mkzynq.go @@ -0,0 +1,205 @@ +// Copyright 2014 Brian Swetland <swetland@frotz.net> +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Tool to generate a SystemVerilog wrapper around the Xilinx Zynq PS7 Macro + +package main + +import "flag" +import "os" +import "bufio" +import "strings" +import "strconv" +import "fmt" + +type net struct { + next *net + kind string + def string + name string + value string +} + +const ( + SIMPLE_FIXUP = 1 + PREFIX_FIXUP = 2 +) + +type fixup struct { + next *fixup + pattern string + mapping string + kind int +} + +func fixup_nets(netlist *net, fixups *fixup) { + for n := netlist; n != nil; n = n.next { + for f := fixups; f != nil; f = f.next { + if (f.kind == PREFIX_FIXUP) && strings.HasPrefix(n.name, f.pattern) { + n.value = f.mapping + strings.ToLower(strings.TrimPrefix(n.name, f.pattern)) + goto fixedup + } + if (f.kind == SIMPLE_FIXUP) && (n.name == f.pattern) { + n.value = f.mapping + goto fixedup + } + } + // tie off unmapped input nets + if n.kind == "input" { + n.value = "0" + } +fixedup: + } +} + +// extract input|output|inout [...] <name>; lines from blackbox macro verilog source + +func load_template(fn string) *net { + var netlist *net + file, _ := os.Open(fn) + scanner := bufio.NewScanner(file) + for scanner.Scan() { + line := scanner.Text() + line = strings.TrimSpace(line) + if !strings.HasSuffix(line, ";") { + continue + } + line = line[:len(line)-1] + parts := strings.Split(line, " "); + if (parts[0] != "input") && (parts[0] != "output") && (parts[0] != "inout") { + continue; + } + if (len(parts) == 3) { + netlist = &net{ + next: netlist, + kind: parts[0], + def: parts[1], + name: parts[2], + } + } else if (len(parts) == 2) { + netlist = &net{ + next: netlist, + kind: parts[0], + def: "", + name: parts[1], + } + } else { + continue; + } + } + return netlist +} + +var axi_m_gp = flag.Int("axi-master-gp", 0, "number of gp axi master ifcs (0-2)") +var axi_s_gp = flag.Int("axi-slave-gp", 0, "number of gp axi slave ifcs (0-2)") +var axi_s_hp = flag.Int("axi-slave-hp", 0, "number of gp axi slave ifcs (0-4)") +var fclks = flag.Int("fclks", 1, "number of clocks from PS") +var tmpl = flag.String("template", "PS7.v", "template for PS7 macro") + +var fixups *fixup +var ports *net + +func mkport(kind string, def string, name string) { + ports = &net{ + next: ports, + kind: kind, + def: def, + name: name, + } +} + +func prefix_fixup(prefix string, mapping string) { + fixups = &fixup { + next: fixups, + kind: PREFIX_FIXUP, + pattern: prefix, + mapping: mapping, + } +} + +func simple_fixup(prefix string, mapping string) { + fixups = &fixup { + next: fixups, + kind: SIMPLE_FIXUP, + pattern: prefix, + mapping: mapping, + } +} + +func fixup_axi(count int, prefix string, mapping string, kind string) { + defval := "" + if (kind == "axi_ifc.slave") { + defval = "0" + } + for n := 1; n <= count; n++ { + num := strconv.Itoa(n-1) + prefix_fixup(prefix + num, mapping + num + ".") + simple_fixup(prefix + num + "ACLK", mapping + num + "_clk") + simple_fixup(prefix + num + "AWQOS", defval) + simple_fixup(prefix + num + "ARQOS", defval) + simple_fixup(prefix + num + "AWPROT", defval) + simple_fixup(prefix + num + "ARPROT", defval) + simple_fixup(prefix + num + "WID", defval) + simple_fixup(prefix + num + "ARESETN", "") + mkport(kind, "", mapping + num) + mkport("input", "", mapping + num + "_clk") + } +} + +func main() { + flag.Parse() + + netlist := load_template(*tmpl) + + fixup_axi(*axi_m_gp, "MAXIGP", "m_axi_gp", "axi_ifc.master") + fixup_axi(*axi_s_gp, "SAXIGP", "s_axi_gp", "axi_ifc.slave") + fixup_axi(*axi_s_hp, "SAXIHP", "s_axi_hp", "axi_ifc.slave") + + // route clocks out from PS7 + simple_fixup("FCLKCLK", "{ fclk3_i, fclk2_i, fclk1_i, fclk0_i }") + for n := 0; n < *fclks; n++ { + mkport("output", "", "fclk" + strconv.Itoa(n)) + } + + fixup_nets(netlist, fixups) + + fmt.Printf("// machine-generated by mkzynq.go - do not edit\n") + fmt.Printf("`timescale 1ns / 1ps\n\n") + fmt.Printf("module zynq_ps7(\n") + for p := ports; p != nil; p = p.next { + if p.next != nil { + fmt.Printf("\t%s %s,\n", p.kind, p.name) + } else { + fmt.Printf("\t%s %s\n", p.kind, p.name) + } + } + fmt.Printf("\t);\n\n") + + // global buffers for active clocks from PS + fmt.Printf("wire fclk0_i, fclk1_i, fclk2_i, fclk3_i;\n\n") + for n := 0; n < *fclks; n++ { + fmt.Printf("BUFG fclk%d_bufg(.I(fclk%d_i), .O(fclk%d));\n", n, n, n); + } + + fmt.Printf("\nPS7 ps7_i(\n") + for n := netlist; n != nil; n = n.next { + if n.next != nil { + fmt.Printf("\t.%s(%s),\n", n.name, n.value) + } else { + fmt.Printf("\t.%s(%s)\n", n.name, n.value) + } + } + fmt.Printf("\t);\n\nendmodule\n") +} + diff --git a/build/review.tcl b/build/review.tcl @@ -0,0 +1,2 @@ +open_checkpoint post-route-checkpoint.dcp +start_gui diff --git a/build/testbench.cpp b/build/testbench.cpp @@ -0,0 +1,121 @@ +/* Copyright 2014 Brian Swetland <swetland@frotz.net> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* reusable verilator testbench driver + * - expects the top module to be testbench(clk); + * - provides clk to module + * - handles vcd tracing if compiled with TRACE + * - allows tracefilename to be specified via -o +*/ + +#include <sys/types.h> +#include <unistd.h> +#include <fcntl.h> + +#include "Vtestbench.h" +#include "verilated.h" +#include <verilated_vcd_c.h> + +static unsigned memory[4096]; + +void dpi_mem_write(int addr, int data) { + memory[addr & 0xFFF] = data; +} + +void dpi_mem_read(int addr, int *data) { + *data = (int) memory[addr & 0xFFF]; +} + +#ifdef TRACE +static vluint64_t now = 0; + +double sc_time_stamp() { + return now; +} +#endif + +int main(int argc, char **argv) { + const char *vcdname = "trace.vcd"; + const char *memname = NULL; + int fd; + + while (argc > 1) { + if (!strcmp(argv[1], "-o")) { +#ifdef TRACE + if (argc < 3) { + fprintf(stderr,"error: -o requires argument\n"); + return -1; + } + vcdname = argv[2]; + argv += 2; + argc -= 2; + continue; +#else + fprintf(stderr,"error: no trace support\n"); + return -1; +#endif + } else if (!strcmp(argv[1], "-om")) { + if (argc < 3) { + fprintf(stderr, "error: -om requires argument\n"); + return -1; + } + memname = argv[2]; + argv += 2; + argc -= 3; + } else { + break; + } + } + + Verilated::commandArgs(argc, argv); + Verilated::debug(0); + Verilated::randReset(2); + + Vtestbench *testbench = new Vtestbench; + testbench->clk = 0; + +#ifdef TRACE + Verilated::traceEverOn(true); + VerilatedVcdC* tfp = new VerilatedVcdC; + testbench->trace(tfp, 99); + tfp->open(vcdname); +#endif + + while (!Verilated::gotFinish()) { + testbench->clk = !testbench->clk; + testbench->eval(); +#ifdef TRACE + tfp->dump(now); + now += 5; +#endif + } +#ifdef TRACE + tfp->close(); +#endif + testbench->final(); + delete testbench; + + if (memname != NULL) { + fd = open(memname, O_WRONLY | O_CREAT | O_TRUNC, 0640); + if (fd < 0) { + fprintf(stderr, "cannot open '%s' for writing\n", memname); + return -1; + } + write(fd, memory, sizeof(memory)); + close(fd); + } + return 0; +} + diff --git a/build/verilator-sim.mk b/build/verilator-sim.mk @@ -0,0 +1,48 @@ +## Copyright 2014 Brian Swetland <swetland@frotz.net> +## +## Licensed under the Apache License, Version 2.0 +## http://www.apache.org/licenses/LICENSE-2.0 + +MODULE_NAME := $(strip $(MODULE_NAME)) +ifeq ("$(MODULE_NAME)","") +$(error no module name) +endif + +MODULE_OBJDIR := sim/$(MODULE_NAME)-vsim +MODULE_RUN := $(MODULE_NAME)-vsim +MODULE_BIN := $(MODULE_OBJDIR)/Vtestbench + +MODULE_HEX_SRCS := $(filter %.hex,$(MODULE_SRCS)) +MODULE_VLG_SRCS := $(filter-out %.hex,$(MODULE_SRCS)) + +MODULE_OPTS := --top-module testbench +#-Ihdl +MODULE_OPTS += --Mdir $(MODULE_OBJDIR) +MODULE_OPTS += --exe ../../build/testbench.cpp +MODULE_OPTS += --cc +MODULE_OPTS += -DSIMULATION + +MODULE_OPTS += -CFLAGS -DTRACE --trace + +$(MODULE_BIN): _OPTS := $(MODULE_OPTS) +$(MODULE_BIN): _SRCS := $(MODULE_VLG_SRCS) +$(MODULE_BIN): _HEX := $(MODULE_HEX_SRCS) +$(MODULE_BIN): _DIR := $(MODULE_OBJDIR) +$(MODULE_BIN): _NAME := $(MODULE_NAME) + +$(MODULE_BIN): $(MODULE_SRCS) $(MODULE_HEX_SRCS) + @mkdir -p $(_DIR) bin + @for hex in $(_HEX) ; do cp $$hex $(_DIR) ; done + @echo "COMPILE (verilator): $(_NAME)" + $(VERILATOR) $(_OPTS) $(_SRCS) + @echo "COMPILE (C++): $(_NAME)" + @make -C $(_DIR) -f Vtestbench.mk + +$(MODULE_RUN): _BIN := $(MODULE_BIN) +$(MODULE_RUN): _DIR := $(MODULE_OBJDIR) + +$(MODULE_RUN): $(MODULE_BIN) + @(cd $(_DIR) && ./Vtestbench) + +MODULE_NAME := +MODULE_SRCS := diff --git a/build/vivado-bitfile.mk b/build/vivado-bitfile.mk @@ -0,0 +1,57 @@ +## Copyright 2014 Brian Swetland <swetland@frotz.net> +## +## Licensed under the Apache License, Version 2.0 +## http://www.apache.org/licenses/LICENSE-2.0 + +MODULE_NAME := $(strip $(MODULE_NAME)) +ifeq ("$(MODULE_NAME)","") +$(error no module name) +endif + +MODULE_OBJDIR := synth/$(MODULE_NAME) +MODULE_BIT := out/$(MODULE_NAME).bit +MODULE_CFG := $(MODULE_OBJDIR)/config.tcl + +MODULE_HEX_SRCS := $(filter %.hex,$(MODULE_SRCS)) +MODULE_XDC_SRCS := $(filter %.xdc,$(MODULE_SRCS)) +MODULE_V_SRCS := $(filter %.v,$(MODULE_SRCS)) +MODULE_SV_SRCS := $(filter %.sv,$(MODULE_SRCS)) + +$(MODULE_CFG): _V := $(MODULE_V_SRCS) +$(MODULE_CFG): _SV := $(MODULE_SV_SRCS) +$(MODULE_CFG): _XDC := $(MODULE_XDC_SRCS) +$(MODULE_CFG): _DIR := $(MODULE_OBJDIR) +$(MODULE_CFG): _PART := $(MODULE_PART) +$(MODULE_CFG): _NAME := $(MODULE_NAME) +$(MODULE_CFG): _OPTS := -I$(VIVADOPATH)/data/verilog/src/xeclib + +$(MODULE_CFG): $(MODULE_SRCS) Makefile + @echo "LINT (verilator): $(_NAME)" + @$(VERILATOR) --top-module top --lint-only $(_OPTS) $(_SV) $(_V) + @mkdir -p $(_DIR) + @echo "# auto-generated file" > $@ + @echo "set PART {$(_PART)}" >> $@ + @echo "set BITFILE {../../out/$(_NAME).bit}" >> $@ + @for x in $(_V) ; do echo "read_verilog {../../$$x}" ; done >> $@ + @for x in $(_SV) ; do echo "read_verilog -sv {../../$$x}" ; done >> $@ + @for x in $(_XDC) ; do echo "read_xdc {../../$$x}" ; done >> $@ + +$(MODULE_BIT): _HEX := $(MODULE_HEX_SRCS) +$(MODULE_BIT): _DIR := $(MODULE_OBJDIR) +$(MODULE_BIT): _NAME := $(MODULE_NAME) + +$(MODULE_BIT): $(MODULE_HEX_SRCS) $(MODULE_CFG) + @echo "SYNTH (vivado): $(_NAME)" + @mkdir -p $(_DIR) out + @rm -f $(_DIR)/log.txt + @for hex in $(_HEX) ; do cp $$hex $(_DIR) ; done + @(cd $(_DIR) && $(VIVADO) -mode batch -log log.txt -nojournal -source ../../build/build-bitfile.tcl) + +$(MODULE_NAME): $(MODULE_BIT) + +$(MODULE_NAME)-review: $(MODULE_BIT) + @(cd $(_DIR) && $(VIVADO) -nolog -nojournal post-route-checkpoint.dcp) + +MODULE_NAME := +MODULE_SRCS := +MODULE_PART := diff --git a/hdl/axi_ifc.sv b/hdl/axi_ifc.sv @@ -0,0 +1,85 @@ +// Copyright 2014 Brian Swetland <swetland@frotz.net> +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +`timescale 1ns/1ps + +interface axi_ifc; + +parameter AWIDTH = 32; +parameter DWIDTH = 32; +parameter IWIDTH = 1; +parameter AXI3 = 0; + +localparam LENMAX = AXI3 ? 3 : 7; +localparam LOCKMAX = AXI3 ? 1 : 0; +localparam SIZEMAX = AXI3 ? 1 : 0; + +logic [IWIDTH-1:0] awid; +logic [AWIDTH-1:0] awaddr; + logic [1:0]awburst; + logic [3:0]awcache; + logic [LENMAX:0]awlen; + logic [SIZEMAX:0]awsize; + logic [LOCKMAX:0]awlock; +logic awvalid; +logic awready; + +logic [DWIDTH-1:0] wdata; +logic [3:0]wstrb; +logic wvalid; +logic wready; + logic wlast; + +logic [IWIDTH-1:0] bid; +logic [1:0] bresp; +logic bvalid; +logic bready; + +logic [IWIDTH-1:0] arid; +logic [AWIDTH-1:0] araddr; + logic [1:0]arburst; + logic [3:0]arcache; + logic [LENMAX:0]arlen; + logic [SIZEMAX:0]arsize; + logic [LOCKMAX:0]arlock; +logic arvalid; +logic arready; + +logic [IWIDTH-1:0] rid; +logic [DWIDTH-1:0] rdata; +logic [1:0] rresp; +logic rvalid; +logic rready; + logic rlast; + +modport master ( + output awid, awaddr, awvalid, wdata, wstrb, wvalid, bready, + output awburst, awcache, awlen, awsize, awlock, wlast, + output arid, araddr, arvalid, rready, + output arburst, arcache, arlen, arsize, arlock, + input awready, wready, bid, bresp, bvalid, + input arready, rid, rdata, rresp, rvalid, rlast +); + +modport slave ( + input awid, awaddr, awvalid, wdata, wstrb, wvalid, bready, + input awburst, awcache, awlen, awsize, awlock, wlast, + input arid, araddr, arvalid, rready, + input arburst, arcache, arlen, arsize, arlock, + output awready, wready, bid, bresp, bvalid, + output arready, rid, rdata, rresp, rvalid, rlast +); + +endinterface + diff --git a/hdl/axi_registers.sv b/hdl/axi_registers.sv @@ -0,0 +1,176 @@ +// Copyright 2014 Brian Swetland <swetland@frotz.net> +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +`timescale 1ns/1ps + +// AXI Register Bridge +// +// Reads and Writes may happen simultaneously +// +// Reads: +// o_rd=1 o_rreg=n on posedge clk +// i_rdata sampled on next posedge clk +// Writes: +// o_wr=1 o_wreg=n o_wdata=w on posedge clk + +// TODO: deal with non-length-1 bursts + +module axi_registers ( + input clk, + + // AXI Interface + axi_ifc.slave s, + + // Register File Interface + output reg [R_ADDR_WIDTH-1:0]o_rreg, + output reg [R_ADDR_WIDTH-1:0]o_wreg, + input wire [31:0]i_rdata, + output reg [31:0]o_wdata, + output reg o_rd, + output reg o_wr + ); + +parameter integer R_ADDR_WIDTH = 2; + +`define IWIDTH $bits(s.awid) + +typedef enum { W_ADDR, W_DATA, W_RESP } wstate_t; + +assign s.bresp = 0; +assign s.rresp = 0; + +//reg [31:0]wdata = 0; +//reg [31:0]wdata_next; + +wstate_t wstate = W_ADDR; +wstate_t wstate_next; + +reg awready_next; +reg wready_next; +reg bvalid_next; + +reg [R_ADDR_WIDTH-1:0]wreg_next; +reg [R_ADDR_WIDTH-1:0]rreg_next; + +assign o_wdata = s.wdata; +assign o_wr = (s.wvalid & s.wready); + +reg [`IWIDTH-1:0]twid = 0; +reg [`IWIDTH-1:0]twid_next; + +assign s.bid = twid; + +always_comb begin + wstate_next = wstate; + //wdata_next = wdata; + wreg_next = o_wreg; + twid_next = twid; + awready_next = 0; + wready_next = 0; + bvalid_next = 0; + case (wstate) + W_ADDR: if (s.awvalid) begin + wstate_next = W_DATA; + wready_next = 1; + twid_next = s.awid; + wreg_next = s.awaddr[R_ADDR_WIDTH+1:2]; + end else begin + awready_next = 1; + end + W_DATA: if (s.wvalid) begin + wstate_next = W_RESP; + bvalid_next = 1; + end else begin + wready_next = 1; + end + W_RESP: if (s.bready) begin + wstate_next = W_ADDR; + awready_next = 1; + end else begin + bvalid_next = 1; + end + endcase +end + +typedef enum { R_ADDR, R_CAPTURE, R_DATA } rstate_t; + +rstate_t rstate = R_ADDR; +rstate_t rstate_next; + +reg arready_next; +reg rvalid_next; + +reg [31:0]rdata; +reg [31:0]rdata_next; +assign s.rdata = rdata; + +reg rd_next; + +reg [`IWIDTH-1:0]trid = 0; +reg [`IWIDTH-1:0]trid_next; +assign s.rid = trid; + +always_comb begin + rstate_next = rstate; + rdata_next = rdata; + rreg_next = o_rreg; + trid_next = trid; + arready_next = 0; + rvalid_next = 0; + rd_next = 0; + case (rstate) + R_ADDR: if (s.arvalid) begin + // accept address from AXI + rstate_next = R_CAPTURE; + trid_next = s.arid; + rreg_next = s.araddr[R_ADDR_WIDTH+1:2]; + rd_next = 1; + end else begin + arready_next = 1; + end + R_CAPTURE: begin + // present address and rd to register file + rstate_next = R_DATA; + rvalid_next = 1; + rdata_next = i_rdata; + end + R_DATA: if (s.rready) begin + // present register data to AXI + rstate_next = R_ADDR; + arready_next = 1; + end else begin + rvalid_next = 1; + end + endcase +end + +always_ff @(posedge clk) begin + wstate <= wstate_next; + //wdata <= wdata_next; + twid <= twid_next; + s.awready <= awready_next; + s.wready <= wready_next; + s.bvalid <= bvalid_next; + o_wreg <= wreg_next; + + rstate <= rstate_next; + rdata <= rdata_next; + trid <= trid_next; + s.arready <= arready_next; + s.rvalid <= rvalid_next; + o_rreg <= rreg_next; + o_rd <= rd_next; +end + +endmodule diff --git a/hdl/hdmi_core.sv b/hdl/hdmi_core.sv @@ -0,0 +1,129 @@ +// Copyright 2014 Brian Swetland <swetland@frotz.net> +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +`timescale 1ns/1ps + +module hdmi_core ( + input pixclk, + input pixclkx5, + // TMDS33 outputs + output [2:0]hdmi_d_p, + output [2:0]hdmi_d_n, + output hdmi_clk_p, + output hdmi_clk_n, + // RGB data input + output rgb_ready, + input [7:0]red, + input [7:0]grn, + input [7:0]blu, + // core status + output [10:0]xpixel, + output [10:0]ypixel + ); + +parameter HWIDTH = 960; +parameter HSYNC0 = 1000; +parameter HSYNC1 = 1100; +parameter HMAX = 1199; +parameter VHEIGHT = 600; +parameter VSYNC0 = 613; +parameter VSYNC1 = 620; +parameter VMAX = 624; + +reg [10:0] hcount, vcount; +reg hsync, vsync, active; + +always @(posedge pixclk) begin + if (hcount == HMAX) begin + hcount <= 0; + if (vcount == VMAX) begin + vcount <= 0; + end else begin + vcount <= vcount + 1; + end + end else begin + hcount <= hcount + 1; + end + active <= (hcount < HWIDTH) && (vcount < VHEIGHT); + hsync <= (hcount >= HSYNC0) && (hcount < HSYNC1); + vsync <= (vcount >= VSYNC0) && (vcount < VSYNC1); +end + +assign xpixel = hcount; +assign ypixel = vcount; +assign rgb_ready = active; + +wire [9:0] ch0, ch1, ch2; + +tmds_encoder enc2( + .clk(pixclk), + .data(red), + .ctrl(0), + .active(active), + .out(ch2) + ); +tmds_encoder enc1( + .clk(pixclk), + .active(active), + .data(grn), + .ctrl(0), + .out(ch1) + ); +tmds_encoder enc0( + .clk(pixclk), + .active(active), + .data(blu), + .ctrl({vsync,hsync}), + .out(ch0) + ); + +// does not reliably work on cold boot without reset/sync +reg [9:0]txrescnt = 0; +wire txres = (txrescnt[9:1] == 9'b100000000); +always @(posedge pixclk) begin + if (txrescnt != 10'b1111111111) begin + txrescnt <= txrescnt + 1; + end +end + +serdes_10to1_tx tx2( + .clk(pixclk), + .clkx5(pixclkx5), + .reset(txres), + .o_p(hdmi_d_p[2]), + .o_n(hdmi_d_n[2]), + .i_data(ch2) + ); + +serdes_10to1_tx tx1( + .clk(pixclk), + .clkx5(pixclkx5), + .reset(txres), + .o_p(hdmi_d_p[1]), + .o_n(hdmi_d_n[1]), + .i_data(ch1) + ); + +serdes_10to1_tx tx0( + .clk(pixclk), + .clkx5(pixclkx5), + .reset(txres), + .o_p(hdmi_d_p[0]), + .o_n(hdmi_d_n[0]), + .i_data(ch0) + ); + +OBUFDS OBUFDS_clock(.I(pixclk), .O(hdmi_clk_p), .OB(hdmi_clk_n)); + +endmodule diff --git a/hdl/mmcm_1in_3out.sv b/hdl/mmcm_1in_3out.sv @@ -0,0 +1,92 @@ +`timescale 1ps/1ps + +// F(CLKIN) = 1 / CLKIN_PERIOD +// F(VCO) = F(CLKIN) * ( VCOMUL / VCODIV ) +// F(CLKn) = F(VCO) / OUTnDIV + +module mmcm_1in_3out( + input i_clk, + output o_clk0, + output o_clk1, + output o_clk2 + ); + +parameter CLKIN_PERIOD = 10.0; +parameter VCO_MUL = 10.000; +parameter VCO_DIV = 2; +parameter OUT0_DIV = 2.000; +parameter OUT1_DIV = 2; +parameter OUT2_DIV = 2; + +wire clkfb, clkfb_i, clk0, clk1, clk2; + +BUFG bufg_clkfb(.I(clkfb_i), .O(clkfb)); +BUFG bufg_pixclk(.I(clk0), .O(o_clk0)); +BUFG bufg_pixclkx5(.I(clk1), .O(o_clk1)); +BUFG bufg_pixclkx10(.I(clk2), .O(o_clk2)); + +MMCME2_ADV #( + .BANDWIDTH("OPTIMIZED"), + .CLKOUT4_CASCADE("FALSE"), + .COMPENSATION("ZHOLD"), + .STARTUP_WAIT("FALSE"), + .DIVCLK_DIVIDE(VCO_DIV), + .CLKFBOUT_MULT_F(VCO_MUL), + .CLKFBOUT_PHASE(0.000), + .CLKFBOUT_USE_FINE_PS("FALSE"), + .CLKOUT0_DIVIDE_F(OUT0_DIV), + .CLKOUT0_PHASE(0.000), + .CLKOUT0_DUTY_CYCLE(0.500), + .CLKOUT0_USE_FINE_PS("FALSE"), + .CLKOUT1_DIVIDE(OUT1_DIV), + .CLKOUT1_PHASE(0.000), + .CLKOUT1_DUTY_CYCLE(0.500), + .CLKOUT1_USE_FINE_PS("FALSE"), + .CLKOUT2_DIVIDE(OUT2_DIV), + .CLKOUT2_PHASE(0.000), + .CLKOUT2_DUTY_CYCLE(0.500), + .CLKOUT2_USE_FINE_PS("FALSE"), + .CLKIN1_PERIOD(8.0), + .REF_JITTER1(0.010) + ) mmcm_adv_inst ( + .CLKFBOUT(clkfb_i), + .CLKFBOUTB(), + .CLKOUT0(clk0), + .CLKOUT0B(), + .CLKOUT1(clk1), + .CLKOUT1B(), + .CLKOUT2(clk2), + .CLKOUT2B(), + .CLKOUT3(), + .CLKOUT3B(), + .CLKOUT4(), + .CLKOUT5(), + .CLKOUT6(), + + .CLKFBIN(clkfb), + .CLKIN1(i_clk), + .CLKIN2(0), + + .CLKINSEL(1), + + .DADDR(0), + .DCLK(0), + .DEN(0), + .DI(0), + .DO(), + .DRDY(), + .DWE(0), + + .PSCLK(0), + .PSEN(0), + .PSINCDEC(0), + .PSDONE(), + + .LOCKED(), + .CLKINSTOPPED(), + .CLKFBSTOPPED(), + .PWRDWN(0), + .RST(0) + ); + +endmodule diff --git a/hdl/serdes_10to1_tx.sv b/hdl/serdes_10to1_tx.sv @@ -0,0 +1,88 @@ +`timescale 1ns / 1ps + +module serdes_10to1_tx( + input clk, + input clkx5, + input reset, + output o_p, + output o_n, + input [9:0]i_data + ); + +wire out, shift1, shift2; + +OBUFDS bufds(.I(out), .O(o_p), .OB(o_n)); + +OSERDESE2 #( + .DATA_RATE_OQ("DDR"), + .DATA_RATE_TQ("DDR"), + .DATA_WIDTH(10), + .TRISTATE_WIDTH(1), + .SERDES_MODE("MASTER"), + )serdes_lo( + .CLK(clkx5), + .CLKDIV(clk), + .D1(i_data[0]), + .D2(i_data[1]), + .D3(i_data[2]), + .D4(i_data[3]), + .D5(i_data[4]), + .D6(i_data[5]), + .D7(i_data[6]), + .D8(i_data[7]), + .OCE(1), + .OFB(), + .OQ(out), + .RST(reset), + .SHIFTIN1(shift1), + .SHIFTIN2(shift2), + .SHIFTOUT1(), + .SHIFTOUT2(), + .TBYTEIN(0), + .TBYTEOUT(), + .TCE(0), + .TFB(), + .TQ(), + .T1(0), + .T2(0), + .T3(0), + .T4(0) + ); + +OSERDESE2 #( + .DATA_RATE_OQ("DDR"), + .DATA_RATE_TQ("DDR"), + .DATA_WIDTH(10), + .TRISTATE_WIDTH(1), + .SERDES_MODE("SLAVE"), + )serdes_hi( + .CLK(clkx5), + .CLKDIV(clk), + .D1(0), + .D2(0), + .D3(i_data[8]), + .D4(i_data[9]), + .D5(0), + .D6(0), + .D7(0), + .D8(0), + .OCE(1), + .OFB(), + .OQ(), + .RST(reset), + .SHIFTIN1(0), + .SHIFTIN2(0), + .SHIFTOUT1(shift1), + .SHIFTOUT2(shift2), + .TBYTEIN(0), + .TBYTEOUT(), + .TCE(0), + .TFB(), + .TQ(), + .T1(0), + .T2(0), + .T3(0), + .T4(0) + ); + +endmodule diff --git a/hdl/tmds_encoder.sv b/hdl/tmds_encoder.sv @@ -0,0 +1,81 @@ +// Copyright 2014 Brian Swetland <swetland@frotz.net> +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +`timescale 1ns / 1ps + +/* verilator lint_off WIDTH */ +module tmds_encoder( + input clk, + input [7:0]data, + input [1:0]ctrl, + input active, + output reg [9:0]out + ); + +reg [3:0]acc = 0; + +wire [8:0]xo; +wire [8:0]xn; + +assign xn[0] = data[0]; +assign xn[1] = data[1] ~^ xn[0]; +assign xn[2] = data[2] ~^ xn[1]; +assign xn[3] = data[3] ~^ xn[2]; +assign xn[4] = data[4] ~^ xn[3]; +assign xn[5] = data[5] ~^ xn[4]; +assign xn[6] = data[6] ~^ xn[5]; +assign xn[7] = data[7] ~^ xn[6]; +assign xn[8] = 0; + +assign xo[0] = data[0]; +assign xo[1] = data[1] ^ xo[0]; +assign xo[2] = data[2] ^ xo[1]; +assign xo[3] = data[3] ^ xo[2]; +assign xo[4] = data[4] ^ xo[3]; +assign xo[5] = data[5] ^ xo[4]; +assign xo[6] = data[6] ^ xo[5]; +assign xo[7] = data[7] ^ xo[6]; +assign xo[8] = 1; + +wire [3:0]ones = data[0] + data[1] + data[2] + data[3] + data[4] + data[5] + data[6] + data[7]; + +wire use_xn = ((ones > 4) | ((ones == 4) & (data[0] == 0))); + +wire [8:0]tmp = use_xn ? xn : xo; +wire [3:0]tmp_ones = tmp[0]+tmp[1]+tmp[2]+tmp[3]+tmp[4]+tmp[5]+tmp[6]+tmp[7]; + +wire no_bias = (acc == 0) | (tmp_ones == 4); + +wire same_sign = (acc[3] == tmp_ones[3]); + +wire inv = no_bias ? (~tmp[8]) : same_sign; + +wire [9:0]enc = { inv, tmp[8], inv ? ~tmp[7:0] : tmp[7:0] }; + +always @(posedge clk) begin + if (active) begin + out <= enc; + acc = acc - 5 + enc[0]+enc[1]+enc[2]+enc[3]+enc[4]+enc[5]+enc[6]+enc[7]+enc[8]+enc[9]; + end else begin + case (ctrl) + 2'b00: out <= 10'b1101010100; + 2'b01: out <= 10'b0010101011; + 2'b10: out <= 10'b0101010100; + 2'b11: out <= 10'b1010101011; + endcase + acc <= 0; + end +end + +endmodule diff --git a/hdl/zybo_hdmi.sv b/hdl/zybo_hdmi.sv @@ -0,0 +1,75 @@ +// Copyright 2014 Brian Swetland <swetland@frotz.net> +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +`timescale 1ns / 1ps + +module top( + input clk, + output [2:0]hdmi_d_p, + output [2:0]hdmi_d_n, + output hdmi_clk_p, + output hdmi_clk_n + ); + +wire pixclk, pixclkx5, pixclkx10; +wire [10:0] xpixel, ypixel; +reg [7:0] red, grn, blu; + +mmcm_1in_3out #( + .CLKIN_PERIOD(8.0), + .VCO_MUL(36.000), + .VCO_DIV(5), + .OUT0_DIV(20), // 45MHz + .OUT1_DIV(4), // 225MHz + .OUT2_DIV(2) // 450MHz + ) mmcm0 ( + .i_clk(clk), + .o_clk0(pixclk), + .o_clk1(pixclkx5), + .o_clk2(pixclkx10) + ); + +hdmi_core #( + // 640x480 @60 25MHz + //.HWIDTH(640), .HSYNC0(656), .HSYNC1(752), .HMAX(799), + //.VHEIGHT(480), .VSYNC0(490), .VSYNC1(492), .VMAX(524) + // 1280x720 @60 75MHz + //.HWIDTH(1280), .HSYNC0(1320), .HSYNC1(1376). HMAX(1649), + //.VHEIGHT(720), .VSYNC0(722), .VSYNC1(728), .VMAX(750) + // 960x600 @60 45MHz + .HWIDTH(960), .HSYNC0(1000), .HSYNC1(1100), .HMAX(1199), + .VHEIGHT(600), .VSYNC0(613), .VSYNC1(620), .VMAX(624) + ) hdmi0 ( + .pixclk(pixclk), + .pixclkx5(pixclkx5), + .hdmi_d_p(hdmi_d_p), + .hdmi_d_n(hdmi_d_n), + .hdmi_clk_p(hdmi_clk_p), + .hdmi_clk_n(hdmi_clk_n), + .rgb_ready(), + .red(red), + .grn(grn), + .blu(blu), + .xpixel(xpixel), + .ypixel(ypixel) + ); + +// test pattern +always @(posedge pixclk) begin + red <= xpixel[3] ? 8'hFF : 8'h00; + grn <= ypixel[3] ? 8'hFF : 8'h00; + blu <= ypixel[7:0]; +end + +endmodule diff --git a/hdl/zybo_hdmi.xdc b/hdl/zybo_hdmi.xdc @@ -0,0 +1,40 @@ +##Clock signal +##IO_L11P_T1_SRCC_35 +set_property PACKAGE_PIN L16 [get_ports clk] +set_property IOSTANDARD LVCMOS33 [get_ports clk] +create_clock -add -name sys_clk_pin -period 8.00 -waveform {0 4} [get_ports clk] + +##HDMI Signals +##IO_L13N_T2_MRCC_35 +set_property PACKAGE_PIN H17 [get_ports hdmi_clk_n] +set_property IOSTANDARD TMDS_33 [get_ports hdmi_clk_n] + +##IO_L13P_T2_MRCC_35 +set_property PACKAGE_PIN H16 [get_ports hdmi_clk_p] +set_property IOSTANDARD TMDS_33 [get_ports hdmi_clk_p] + +##IO_L4N_T0_35 +set_property PACKAGE_PIN D20 [get_ports {hdmi_d_n[0]}] +set_property IOSTANDARD TMDS_33 [get_ports {hdmi_d_n[0]}] + +##IO_L4P_T0_35 +set_property PACKAGE_PIN D19 [get_ports {hdmi_d_p[0]}] +set_property IOSTANDARD TMDS_33 [get_ports {hdmi_d_p[0]}] + +##IO_L1N_T0_AD0N_35 +set_property PACKAGE_PIN B20 [get_ports {hdmi_d_n[1]}] +set_property IOSTANDARD TMDS_33 [get_ports {hdmi_d_n[1]}] + +##IO_L1P_T0_AD0P_35 +set_property PACKAGE_PIN C20 [get_ports {hdmi_d_p[1]}] +set_property IOSTANDARD TMDS_33 [get_ports {hdmi_d_p[1]}] + +##IO_L2N_T0_AD8N_35 +set_property PACKAGE_PIN A20 [get_ports {hdmi_d_n[2]}] +set_property IOSTANDARD TMDS_33 [get_ports {hdmi_d_n[2]}] + +##IO_L2P_T0_AD8P_35 +set_property PACKAGE_PIN B19 [get_ports {hdmi_d_p[2]}] +set_property IOSTANDARD TMDS_33 [get_ports {hdmi_d_p[2]}] + + diff --git a/hdl/zybo_hdmi_axi.sv b/hdl/zybo_hdmi_axi.sv @@ -0,0 +1,103 @@ +// Copyright 2014 Brian Swetland <swetland@frotz.net> +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +`timescale 1ns / 1ps + +module top( + input clk, + output [2:0]hdmi_d_p, + output [2:0]hdmi_d_n, + output hdmi_clk_p, + output hdmi_clk_n + ); + +wire pixclk, pixclkx5, pixclkx10; +wire [10:0] xpixel, ypixel; +reg [7:0] red, grn, blu; + +mmcm_1in_3out #( + .CLKIN_PERIOD(8.0), + .VCO_MUL(36.000), + .VCO_DIV(5), + .OUT0_DIV(20), // 45MHz + .OUT1_DIV(4), // 225MHz + .OUT2_DIV(2) // 450MHz + ) mmcm0 ( + .i_clk(clk), + .o_clk0(pixclk), + .o_clk1(pixclkx5), + .o_clk2(pixclkx10) + ); + +hdmi_core #( + // 640x480 @60 25MHz + //.HWIDTH(640), .HSYNC0(656), .HSYNC1(752), .HMAX(799), + //.VHEIGHT(480), .VSYNC0(490), .VSYNC1(492), .VMAX(524) + // 1280x720 @60 75MHz + //.HWIDTH(1280), .HSYNC0(1320), .HSYNC1(1376). HMAX(1649), + //.VHEIGHT(720), .VSYNC0(722), .VSYNC1(728), .VMAX(750) + // 960x600 @60 45MHz + .HWIDTH(960), .HSYNC0(1000), .HSYNC1(1100), .HMAX(1199), + .VHEIGHT(600), .VSYNC0(613), .VSYNC1(620), .VMAX(624) + ) hdmi0 ( + .pixclk(pixclk), + .pixclkx5(pixclkx5), + .hdmi_d_p(hdmi_d_p), + .hdmi_d_n(hdmi_d_n), + .hdmi_clk_p(hdmi_clk_p), + .hdmi_clk_n(hdmi_clk_n), + .rgb_ready(), + .red(red), + .grn(grn), + .blu(blu), + .xpixel(xpixel), + .ypixel(ypixel) + ); + +// test pattern +always @(posedge pixclk) begin + red <= xpixel[3] ? 8'hFF : 8'h00; + grn <= ypixel[3] ? 8'hFF : 8'h00; +end + +wire axiclk; + +axi_ifc #(.IWIDTH(12),.AXI3(1)) axi_ctl(); + +zynq_ps7 zynq( + .fclk0(axiclk), + .m_axi_gp0_clk(axiclk), + .m_axi_gp0(axi_ctl) + ); + +wire [31:0]wdata; +wire [1:0]wreg; +wire wr; + +axi_registers regs( + .clk(axiclk), + .s(axi_ctl), + .o_rreg(), + .o_wreg(wreg), + .i_rdata(32'h12345678), + .o_wdata(wdata), + .o_rd(), + .o_wr(wr) + ); + +always @(posedge axiclk) + if (wr) + blu <= wdata[7:0]; + +endmodule diff --git a/hdl/zynq_ps_1m.sv b/hdl/zynq_ps_1m.sv @@ -0,0 +1,638 @@ +// machine-generated by mkzynq.go - do not edit +`timescale 1ns / 1ps + +module zynq_ps7( + output fclk0, + input m_axi_gp0_clk, + axi_ifc.master m_axi_gp0 + ); + +wire fclk0_i, fclk1_i, fclk2_i, fclk3_i; + +BUFG fclk0_bufg(.I(fclk0_i), .O(fclk0)); + +PS7 ps7_i( + .SAXIHP3WSTRB(0), + .SAXIHP2WSTRB(0), + .SAXIHP1WSTRB(0), + .SAXIHP0WSTRB(0), + .SAXIACPWSTRB(0), + .EMIOENET1GMIIRXD(0), + .EMIOENET0GMIIRXD(0), + .SAXIHP3WDATA(0), + .SAXIHP2WDATA(0), + .SAXIHP1WDATA(0), + .SAXIHP0WDATA(0), + .SAXIACPWDATA(0), + .EMIOGPIOI(0), + .SAXIHP3WID(0), + .SAXIHP3AWID(0), + .SAXIHP3ARID(0), + .SAXIHP2WID(0), + .SAXIHP2AWID(0), + .SAXIHP2ARID(0), + .SAXIHP1WID(0), + .SAXIHP1AWID(0), + .SAXIHP1ARID(0), + .SAXIHP0WID(0), + .SAXIHP0AWID(0), + .SAXIHP0ARID(0), + .SAXIGP1WID(0), + .SAXIGP1AWID(0), + .SAXIGP1ARID(0), + .SAXIGP0WID(0), + .SAXIGP0AWID(0), + .SAXIGP0ARID(0), + .SAXIACPAWUSER(0), + .SAXIACPARUSER(0), + .SAXIHP3AWQOS(0), + .SAXIHP3AWLEN(0), + .SAXIHP3AWCACHE(0), + .SAXIHP3ARQOS(0), + .SAXIHP3ARLEN(0), + .SAXIHP3ARCACHE(0), + .SAXIHP2AWQOS(0), + .SAXIHP2AWLEN(0), + .SAXIHP2AWCACHE(0), + .SAXIHP2ARQOS(0), + .SAXIHP2ARLEN(0), + .SAXIHP2ARCACHE(0), + .SAXIHP1AWQOS(0), + .SAXIHP1AWLEN(0), + .SAXIHP1AWCACHE(0), + .SAXIHP1ARQOS(0), + .SAXIHP1ARLEN(0), + .SAXIHP1ARCACHE(0), + .SAXIHP0AWQOS(0), + .SAXIHP0AWLEN(0), + .SAXIHP0AWCACHE(0), + .SAXIHP0ARQOS(0), + .SAXIHP0ARLEN(0), + .SAXIHP0ARCACHE(0), + .SAXIGP1WSTRB(0), + .SAXIGP1AWQOS(0), + .SAXIGP1AWLEN(0), + .SAXIGP1AWCACHE(0), + .SAXIGP1ARQOS(0), + .SAXIGP1ARLEN(0), + .SAXIGP1ARCACHE(0), + .SAXIGP0WSTRB(0), + .SAXIGP0AWQOS(0), + .SAXIGP0AWLEN(0), + .SAXIGP0AWCACHE(0), + .SAXIGP0ARQOS(0), + .SAXIGP0ARLEN(0), + .SAXIGP0ARCACHE(0), + .SAXIACPAWQOS(0), + .SAXIACPAWLEN(0), + .SAXIACPAWCACHE(0), + .SAXIACPARQOS(0), + .SAXIACPARLEN(0), + .SAXIACPARCACHE(0), + .FTMTP2FTRIGACK(0), + .FTMTF2PTRIG(0), + .FTMDTRACEINATID(0), + .FCLKCLKTRIGN(0), + .EMIOSDIO1DATAI(0), + .EMIOSDIO0DATAI(0), + .DDRARB(0), + .SAXIHP3AWADDR(0), + .SAXIHP3ARADDR(0), + .SAXIHP2AWADDR(0), + .SAXIHP2ARADDR(0), + .SAXIHP1AWADDR(0), + .SAXIHP1ARADDR(0), + .SAXIHP0AWADDR(0), + .SAXIHP0ARADDR(0), + .SAXIGP1WDATA(0), + .SAXIGP1AWADDR(0), + .SAXIGP1ARADDR(0), + .SAXIGP0WDATA(0), + .SAXIGP0AWADDR(0), + .SAXIGP0ARADDR(0), + .SAXIACPAWADDR(0), + .SAXIACPARADDR(0), + .MAXIGP1RDATA(0), + .MAXIGP0RDATA(m_axi_gp0.rdata), + .FTMTF2PDEBUG(0), + .FTMDTRACEINDATA(0), + .SAXIHP3AWPROT(0), + .SAXIHP3ARPROT(0), + .SAXIHP2AWPROT(0), + .SAXIHP2ARPROT(0), + .SAXIHP1AWPROT(0), + .SAXIHP1ARPROT(0), + .SAXIHP0AWPROT(0), + .SAXIHP0ARPROT(0), + .SAXIGP1AWPROT(0), + .SAXIGP1ARPROT(0), + .SAXIGP0AWPROT(0), + .SAXIGP0ARPROT(0), + .SAXIACPWID(0), + .SAXIACPAWPROT(0), + .SAXIACPAWID(0), + .SAXIACPARPROT(0), + .SAXIACPARID(0), + .EMIOTTC1CLKI(0), + .EMIOTTC0CLKI(0), + .SAXIHP3AWSIZE(0), + .SAXIHP3AWLOCK(0), + .SAXIHP3AWBURST(0), + .SAXIHP3ARSIZE(0), + .SAXIHP3ARLOCK(0), + .SAXIHP3ARBURST(0), + .SAXIHP2AWSIZE(0), + .SAXIHP2AWLOCK(0), + .SAXIHP2AWBURST(0), + .SAXIHP2ARSIZE(0), + .SAXIHP2ARLOCK(0), + .SAXIHP2ARBURST(0), + .SAXIHP1AWSIZE(0), + .SAXIHP1AWLOCK(0), + .SAXIHP1AWBURST(0), + .SAXIHP1ARSIZE(0), + .SAXIHP1ARLOCK(0), + .SAXIHP1ARBURST(0), + .SAXIHP0AWSIZE(0), + .SAXIHP0AWLOCK(0), + .SAXIHP0AWBURST(0), + .SAXIHP0ARSIZE(0), + .SAXIHP0ARLOCK(0), + .SAXIHP0ARBURST(0), + .SAXIGP1AWSIZE(0), + .SAXIGP1AWLOCK(0), + .SAXIGP1AWBURST(0), + .SAXIGP1ARSIZE(0), + .SAXIGP1ARLOCK(0), + .SAXIGP1ARBURST(0), + .SAXIGP0AWSIZE(0), + .SAXIGP0AWLOCK(0), + .SAXIGP0AWBURST(0), + .SAXIGP0ARSIZE(0), + .SAXIGP0ARLOCK(0), + .SAXIGP0ARBURST(0), + .SAXIACPAWSIZE(0), + .SAXIACPAWLOCK(0), + .SAXIACPAWBURST(0), + .SAXIACPARSIZE(0), + .SAXIACPARLOCK(0), + .SAXIACPARBURST(0), + .MAXIGP1RRESP(0), + .MAXIGP1BRESP(0), + .MAXIGP0RRESP(m_axi_gp0.rresp), + .MAXIGP0BRESP(m_axi_gp0.bresp), + .DMA3DRTYPE(0), + .DMA2DRTYPE(0), + .DMA1DRTYPE(0), + .DMA0DRTYPE(0), + .IRQF2P(0), + .MAXIGP1RID(0), + .MAXIGP1BID(0), + .MAXIGP0RID(m_axi_gp0.rid), + .MAXIGP0BID(m_axi_gp0.bid), + .SAXIHP3WVALID(0), + .SAXIHP3WRISSUECAP1EN(0), + .SAXIHP3WLAST(0), + .SAXIHP3RREADY(0), + .SAXIHP3RDISSUECAP1EN(0), + .SAXIHP3BREADY(0), + .SAXIHP3AWVALID(0), + .SAXIHP3ARVALID(0), + .SAXIHP3ACLK(0), + .SAXIHP2WVALID(0), + .SAXIHP2WRISSUECAP1EN(0), + .SAXIHP2WLAST(0), + .SAXIHP2RREADY(0), + .SAXIHP2RDISSUECAP1EN(0), + .SAXIHP2BREADY(0), + .SAXIHP2AWVALID(0), + .SAXIHP2ARVALID(0), + .SAXIHP2ACLK(0), + .SAXIHP1WVALID(0), + .SAXIHP1WRISSUECAP1EN(0), + .SAXIHP1WLAST(0), + .SAXIHP1RREADY(0), + .SAXIHP1RDISSUECAP1EN(0), + .SAXIHP1BREADY(0), + .SAXIHP1AWVALID(0), + .SAXIHP1ARVALID(0), + .SAXIHP1ACLK(0), + .SAXIHP0WVALID(0), + .SAXIHP0WRISSUECAP1EN(0), + .SAXIHP0WLAST(0), + .SAXIHP0RREADY(0), + .SAXIHP0RDISSUECAP1EN(0), + .SAXIHP0BREADY(0), + .SAXIHP0AWVALID(0), + .SAXIHP0ARVALID(0), + .SAXIHP0ACLK(0), + .SAXIGP1WVALID(0), + .SAXIGP1WLAST(0), + .SAXIGP1RREADY(0), + .SAXIGP1BREADY(0), + .SAXIGP1AWVALID(0), + .SAXIGP1ARVALID(0), + .SAXIGP1ACLK(0), + .SAXIGP0WVALID(0), + .SAXIGP0WLAST(0), + .SAXIGP0RREADY(0), + .SAXIGP0BREADY(0), + .SAXIGP0AWVALID(0), + .SAXIGP0ARVALID(0), + .SAXIGP0ACLK(0), + .SAXIACPWVALID(0), + .SAXIACPWLAST(0), + .SAXIACPRREADY(0), + .SAXIACPBREADY(0), + .SAXIACPAWVALID(0), + .SAXIACPARVALID(0), + .SAXIACPACLK(0), + .MAXIGP1WREADY(0), + .MAXIGP1RVALID(0), + .MAXIGP1RLAST(0), + .MAXIGP1BVALID(0), + .MAXIGP1AWREADY(0), + .MAXIGP1ARREADY(0), + .MAXIGP1ACLK(0), + .MAXIGP0WREADY(m_axi_gp0.wready), + .MAXIGP0RVALID(m_axi_gp0.rvalid), + .MAXIGP0RLAST(m_axi_gp0.rlast), + .MAXIGP0BVALID(m_axi_gp0.bvalid), + .MAXIGP0AWREADY(m_axi_gp0.awready), + .MAXIGP0ARREADY(m_axi_gp0.arready), + .MAXIGP0ACLK(m_axi_gp0_clk), + .FTMDTRACEINVALID(0), + .FTMDTRACEINCLOCK(0), + .FPGAIDLEN(0), + .EVENTEVENTI(0), + .EMIOWDTCLKI(0), + .EMIOUSB1VBUSPWRFAULT(0), + .EMIOUSB0VBUSPWRFAULT(0), + .EMIOUART1RX(0), + .EMIOUART1RIN(0), + .EMIOUART1DSRN(0), + .EMIOUART1DCDN(0), + .EMIOUART1CTSN(0), + .EMIOUART0RX(0), + .EMIOUART0RIN(0), + .EMIOUART0DSRN(0), + .EMIOUART0DCDN(0), + .EMIOUART0CTSN(0), + .EMIOTRACECLK(0), + .EMIOSRAMINTIN(0), + .EMIOSPI1SSIN(0), + .EMIOSPI1SI(0), + .EMIOSPI1SCLKI(0), + .EMIOSPI1MI(0), + .EMIOSPI0SSIN(0), + .EMIOSPI0SI(0), + .EMIOSPI0SCLKI(0), + .EMIOSPI0MI(0), + .EMIOSDIO1WP(0), + .EMIOSDIO1CMDI(0), + .EMIOSDIO1CLKFB(0), + .EMIOSDIO1CDN(0), + .EMIOSDIO0WP(0), + .EMIOSDIO0CMDI(0), + .EMIOSDIO0CLKFB(0), + .EMIOSDIO0CDN(0), + .EMIOPJTAGTMS(0), + .EMIOPJTAGTDI(0), + .EMIOPJTAGTCK(0), + .EMIOI2C1SDAI(0), + .EMIOI2C1SCLI(0), + .EMIOI2C0SDAI(0), + .EMIOI2C0SCLI(0), + .EMIOENET1MDIOI(0), + .EMIOENET1GMIITXCLK(0), + .EMIOENET1GMIIRXER(0), + .EMIOENET1GMIIRXDV(0), + .EMIOENET1GMIIRXCLK(0), + .EMIOENET1GMIICRS(0), + .EMIOENET1GMIICOL(0), + .EMIOENET1EXTINTIN(0), + .EMIOENET0MDIOI(0), + .EMIOENET0GMIITXCLK(0), + .EMIOENET0GMIIRXER(0), + .EMIOENET0GMIIRXDV(0), + .EMIOENET0GMIIRXCLK(0), + .EMIOENET0GMIICRS(0), + .EMIOENET0GMIICOL(0), + .EMIOENET0EXTINTIN(0), + .EMIOCAN1PHYRX(0), + .EMIOCAN0PHYRX(0), + .DMA3DRVALID(0), + .DMA3DRLAST(0), + .DMA3DAREADY(0), + .DMA3ACLK(0), + .DMA2DRVALID(0), + .DMA2DRLAST(0), + .DMA2DAREADY(0), + .DMA2ACLK(0), + .DMA1DRVALID(0), + .DMA1DRLAST(0), + .DMA1DAREADY(0), + .DMA1ACLK(0), + .DMA0DRVALID(0), + .DMA0DRLAST(0), + .DMA0DAREADY(0), + .DMA0ACLK(0), + .MIO(), + .DDRDQSP(), + .DDRDQSN(), + .DDRDM(), + .DDRDQ(), + .DDRBA(), + .DDRA(), + .PSSRSTB(), + .PSPORB(), + .PSCLK(), + .DDRWEB(), + .DDRVRP(), + .DDRVRN(), + .DDRRASB(), + .DDRODT(), + .DDRDRSTB(), + .DDRCSB(), + .DDRCKP(), + .DDRCKN(), + .DDRCKE(), + .DDRCASB(), + .SAXIHP3WCOUNT(), + .SAXIHP3RCOUNT(), + .SAXIHP2WCOUNT(), + .SAXIHP2RCOUNT(), + .SAXIHP1WCOUNT(), + .SAXIHP1RCOUNT(), + .SAXIHP0WCOUNT(), + .SAXIHP0RCOUNT(), + .EMIOENET1GMIITXD(), + .EMIOENET0GMIITXD(), + .SAXIHP3RDATA(), + .SAXIHP2RDATA(), + .SAXIHP1RDATA(), + .SAXIHP0RDATA(), + .SAXIACPRDATA(), + .EMIOGPIOTN(), + .EMIOGPIOO(), + .SAXIHP3WACOUNT(), + .SAXIHP3RID(), + .SAXIHP3BID(), + .SAXIHP2WACOUNT(), + .SAXIHP2RID(), + .SAXIHP2BID(), + .SAXIHP1WACOUNT(), + .SAXIHP1RID(), + .SAXIHP1BID(), + .SAXIHP0WACOUNT(), + .SAXIHP0RID(), + .SAXIHP0BID(), + .SAXIGP1RID(), + .SAXIGP1BID(), + .SAXIGP0RID(), + .SAXIGP0BID(), + .MAXIGP1WSTRB(), + .MAXIGP1AWQOS(), + .MAXIGP1AWLEN(), + .MAXIGP1AWCACHE(), + .MAXIGP1ARQOS(), + .MAXIGP1ARLEN(), + .MAXIGP1ARCACHE(), + .MAXIGP0WSTRB(m_axi_gp0.wstrb), + .MAXIGP0AWQOS(), + .MAXIGP0AWLEN(m_axi_gp0.awlen), + .MAXIGP0AWCACHE(m_axi_gp0.awcache), + .MAXIGP0ARQOS(), + .MAXIGP0ARLEN(m_axi_gp0.arlen), + .MAXIGP0ARCACHE(m_axi_gp0.arcache), + .FTMTP2FTRIG(), + .FTMTF2PTRIGACK(), + .FCLKRESETN(), + .FCLKCLK({ fclk3_i, fclk2_i, fclk1_i, fclk0_i }), + .EMIOSDIO1DATATN(), + .EMIOSDIO1DATAO(), + .EMIOSDIO0DATATN(), + .EMIOSDIO0DATAO(), + .SAXIGP1RDATA(), + .SAXIGP0RDATA(), + .MAXIGP1WDATA(), + .MAXIGP1AWADDR(), + .MAXIGP1ARADDR(), + .MAXIGP0WDATA(m_axi_gp0.wdata), + .MAXIGP0AWADDR(m_axi_gp0.awaddr), + .MAXIGP0ARADDR(m_axi_gp0.araddr), + .FTMTP2FDEBUG(), + .EMIOTRACEDATA(), + .SAXIHP3RACOUNT(), + .SAXIHP2RACOUNT(), + .SAXIHP1RACOUNT(), + .SAXIHP0RACOUNT(), + .SAXIACPRID(), + .SAXIACPBID(), + .MAXIGP1AWPROT(), + .MAXIGP1ARPROT(), + .MAXIGP0AWPROT(), + .MAXIGP0ARPROT(), + .EMIOTTC1WAVEO(), + .EMIOTTC0WAVEO(), + .EMIOSPI1SSON(), + .EMIOSPI0SSON(), + .EMIOSDIO1BUSVOLT(), + .EMIOSDIO0BUSVOLT(), + .IRQP2F(), + .SAXIHP3RRESP(), + .SAXIHP3BRESP(), + .SAXIHP2RRESP(), + .SAXIHP2BRESP(), + .SAXIHP1RRESP(), + .SAXIHP1BRESP(), + .SAXIHP0RRESP(), + .SAXIHP0BRESP(), + .SAXIGP1RRESP(), + .SAXIGP1BRESP(), + .SAXIGP0RRESP(), + .SAXIGP0BRESP(), + .SAXIACPRRESP(), + .SAXIACPBRESP(), + .MAXIGP1AWSIZE(), + .MAXIGP1AWLOCK(), + .MAXIGP1AWBURST(), + .MAXIGP1ARSIZE(), + .MAXIGP1ARLOCK(), + .MAXIGP1ARBURST(), + .MAXIGP0AWSIZE(m_axi_gp0.awsize), + .MAXIGP0AWLOCK(m_axi_gp0.awlock), + .MAXIGP0AWBURST(m_axi_gp0.awburst), + .MAXIGP0ARSIZE(m_axi_gp0.arsize), + .MAXIGP0ARLOCK(m_axi_gp0.arlock), + .MAXIGP0ARBURST(m_axi_gp0.arburst), + .EVENTSTANDBYWFI(), + .EVENTSTANDBYWFE(), + .EMIOUSB1PORTINDCTL(), + .EMIOUSB0PORTINDCTL(), + .DMA3DATYPE(), + .DMA2DATYPE(), + .DMA1DATYPE(), + .DMA0DATYPE(), + .MAXIGP1WID(), + .MAXIGP1AWID(), + .MAXIGP1ARID(), + .MAXIGP0WID(), + .MAXIGP0AWID(m_axi_gp0.awid), + //.MAXIGP0AWID(), + .MAXIGP0ARID(m_axi_gp0.arid), + .SAXIHP3WREADY(), + .SAXIHP3RVALID(), + .SAXIHP3RLAST(), + .SAXIHP3BVALID(), + .SAXIHP3AWREADY(), + .SAXIHP3ARREADY(), + .SAXIHP3ARESETN(), + .SAXIHP2WREADY(), + .SAXIHP2RVALID(), + .SAXIHP2RLAST(), + .SAXIHP2BVALID(), + .SAXIHP2AWREADY(), + .SAXIHP2ARREADY(), + .SAXIHP2ARESETN(), + .SAXIHP1WREADY(), + .SAXIHP1RVALID(), + .SAXIHP1RLAST(), + .SAXIHP1BVALID(), + .SAXIHP1AWREADY(), + .SAXIHP1ARREADY(), + .SAXIHP1ARESETN(), + .SAXIHP0WREADY(), + .SAXIHP0RVALID(), + .SAXIHP0RLAST(), + .SAXIHP0BVALID(), + .SAXIHP0AWREADY(), + .SAXIHP0ARREADY(), + .SAXIHP0ARESETN(), + .SAXIGP1WREADY(), + .SAXIGP1RVALID(), + .SAXIGP1RLAST(), + .SAXIGP1BVALID(), + .SAXIGP1AWREADY(), + .SAXIGP1ARREADY(), + .SAXIGP1ARESETN(), + .SAXIGP0WREADY(), + .SAXIGP0RVALID(), + .SAXIGP0RLAST(), + .SAXIGP0BVALID(), + .SAXIGP0AWREADY(), + .SAXIGP0ARREADY(), + .SAXIGP0ARESETN(), + .SAXIACPWREADY(), + .SAXIACPRVALID(), + .SAXIACPRLAST(), + .SAXIACPBVALID(), + .SAXIACPAWREADY(), + .SAXIACPARREADY(), + .SAXIACPARESETN(), + .MAXIGP1WVALID(), + .MAXIGP1WLAST(), + .MAXIGP1RREADY(), + .MAXIGP1BREADY(), + .MAXIGP1AWVALID(), + .MAXIGP1ARVALID(), + .MAXIGP1ARESETN(), + .MAXIGP0WVALID(m_axi_gp0.wvalid), + .MAXIGP0WLAST(m_axi_gp0.wlast), + .MAXIGP0RREADY(m_axi_gp0.rready), + .MAXIGP0BREADY(m_axi_gp0.bready), + .MAXIGP0AWVALID(m_axi_gp0.awvalid), + .MAXIGP0ARVALID(m_axi_gp0.arvalid), + .MAXIGP0ARESETN(), + .EVENTEVENTO(), + .EMIOWDTRSTO(), + .EMIOUSB1VBUSPWRSELECT(), + .EMIOUSB0VBUSPWRSELECT(), + .EMIOUART1TX(), + .EMIOUART1RTSN(), + .EMIOUART1DTRN(), + .EMIOUART0TX(), + .EMIOUART0RTSN(), + .EMIOUART0DTRN(), + .EMIOTRACECTL(), + .EMIOSPI1STN(), + .EMIOSPI1SSNTN(), + .EMIOSPI1SO(), + .EMIOSPI1SCLKTN(), + .EMIOSPI1SCLKO(), + .EMIOSPI1MOTN(), + .EMIOSPI1MO(), + .EMIOSPI0STN(), + .EMIOSPI0SSNTN(), + .EMIOSPI0SO(), + .EMIOSPI0SCLKTN(), + .EMIOSPI0SCLKO(), + .EMIOSPI0MOTN(), + .EMIOSPI0MO(), + .EMIOSDIO1LED(), + .EMIOSDIO1CMDTN(), + .EMIOSDIO1CMDO(), + .EMIOSDIO1CLK(), + .EMIOSDIO1BUSPOW(), + .EMIOSDIO0LED(), + .EMIOSDIO0CMDTN(), + .EMIOSDIO0CMDO(), + .EMIOSDIO0CLK(), + .EMIOSDIO0BUSPOW(), + .EMIOPJTAGTDTN(), + .EMIOPJTAGTDO(), + .EMIOI2C1SDATN(), + .EMIOI2C1SDAO(), + .EMIOI2C1SCLTN(), + .EMIOI2C1SCLO(), + .EMIOI2C0SDATN(), + .EMIOI2C0SDAO(), + .EMIOI2C0SCLTN(), + .EMIOI2C0SCLO(), + .EMIOENET1SOFTX(), + .EMIOENET1SOFRX(), + .EMIOENET1PTPSYNCFRAMETX(), + .EMIOENET1PTPSYNCFRAMERX(), + .EMIOENET1PTPPDELAYRESPTX(), + .EMIOENET1PTPPDELAYRESPRX(), + .EMIOENET1PTPPDELAYREQTX(), + .EMIOENET1PTPPDELAYREQRX(), + .EMIOENET1PTPDELAYREQTX(), + .EMIOENET1PTPDELAYREQRX(), + .EMIOENET1MDIOTN(), + .EMIOENET1MDIOO(), + .EMIOENET1MDIOMDC(), + .EMIOENET1GMIITXER(), + .EMIOENET1GMIITXEN(), + .EMIOENET0SOFTX(), + .EMIOENET0SOFRX(), + .EMIOENET0PTPSYNCFRAMETX(), + .EMIOENET0PTPSYNCFRAMERX(), + .EMIOENET0PTPPDELAYRESPTX(), + .EMIOENET0PTPPDELAYRESPRX(), + .EMIOENET0PTPPDELAYREQTX(), + .EMIOENET0PTPPDELAYREQRX(), + .EMIOENET0PTPDELAYREQTX(), + .EMIOENET0PTPDELAYREQRX(), + .EMIOENET0MDIOTN(), + .EMIOENET0MDIOO(), + .EMIOENET0MDIOMDC(), + .EMIOENET0GMIITXER(), + .EMIOENET0GMIITXEN(), + .EMIOCAN1PHYTX(), + .EMIOCAN0PHYTX(), + .DMA3RSTN(), + .DMA3DRREADY(), + .DMA3DAVALID(), + .DMA2RSTN(), + .DMA2DRREADY(), + .DMA2DAVALID(), + .DMA1RSTN(), + .DMA1DRREADY(), + .DMA1DAVALID(), + .DMA0RSTN(), + .DMA0DRREADY(), + .DMA0DAVALID() + ); + +endmodule