add working l2 send in hardware

This commit is contained in:
Fischer Moseley 2023-04-20 00:20:18 -04:00
parent a2d14116de
commit 28f40f2b7b
22 changed files with 51955 additions and 4 deletions

View File

@ -16,9 +16,8 @@ cores:
probes:
larry: 1
curly: 1
moe: 1
shemp: 4
curly: 3
moe: 9
triggers:
- moe RISING
@ -37,7 +36,17 @@ Probes are the signals you're trying to observe with the Logic Analyzer core. Wh
### Triggers
Triggers are things that will cause the logic analyzer core to capture data from the probes. Any one of them being satisfied is enough to start the capture.
Attached to each probe is a little piece of logic that allows you to check if some condition on the probe is true, and triggers the capture if so. These conditions look something like:
- `curly GEQ 2`
- `larry EQ 1`
- `moe NEQ 32`
- `larry RISING`
- `moe CHANGING`
- and so on!
Each of these contains a trigger, an operation, and an argument.
Triggers are things that will cause the logic analyzer core to capture data from the probes. Any one of them being satisfied is enough to start the capture. Each trigger can
### Trigger Position

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,39 @@
from datetime import datetime
import numpy as np
from vcd import VCDWriter
vcd_file = open("iladata.vcd", "w")
data = np.genfromtxt("iladata.csv", delimiter=',', names=True)
# Use the same datetime format that iVerilog uses
timestamp = datetime.now().strftime("%a %b %w %H:%M:%S %Y")
with VCDWriter(vcd_file, '10 ns', timestamp, "manta") as writer:
# each probe has a name, width, and writer associated with it
signals = [{
"name" : "eth_crsdv",
"width" : 1,
"data" : [int(str(i).split('.')[0],2) for i in data['eth_crsdv_IBUF']],
"var": writer.register_var("manta", "eth_crsdv", "wire", size=1)
},
{
"name" : "eth_rxd",
"width" : 2,
"data" : [int(str(i).split('.')[0],2) for i in data['eth_rxd_IBUF10']],
"var": writer.register_var("manta", "eth_rxd", "wire", size=2)
},
]
# add the data to each probe in the vcd file
for timestamp in range(32768):
# add other signals
for signal in signals:
var = signal["var"]
sample = signal["data"][timestamp]
writer.change(var, timestamp, sample)
vcd_file.close()

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,301 @@
import atexit
import getopt
import os
import subprocess
import signal
import sys
import time
import pathlib
import platform
progname = sys.argv[0]
diagnostics = False
quiet = False
verbose = False
port = 80
machine = "eecs-digital-56.mit.edu"
projectdir = "."
of = "obj"
p = False
user = "builder"
outfile = f"{of}/out.bit"
logfile = f"{of}/build.log"
synthrpt = [
"report_timing",
"report_timing_summary",
"report_utilization",
]
placerpt = synthrpt.copy()
placerpt.extend(["report_clock_utilization"])
routerpt = [
"report_drc",
"report_power",
"report_route_status",
"report_timing",
"report_timing_summary",
]
usagestr = f"""
{progname}: build SystemVerilog code remotely for 2022 6.205 labs
usage: {progname} [-dqv] [-m machine] [-p projectdir] [-o dir]
options:
-d: emit additional diagnostics during synthesis/implementation
-q: quiet: do not generate any vivado logs except for errors.
-v: be verbose (for debugging stuffs / if you see a bug)
-m: override the DNS name queried to perform the build. use with care.
-p: build the project located in projectdir (default is '.')
-o: set the output products directory (default is {of})
"""
def debuglog(s):
if verbose:
print(s)
def usage():
print(usagestr)
sys.exit(1)
def getargs():
global diagnostics
global quiet
global machine
global logfile
global outfile
global projectdir
global of
global verbose
try:
opts, args = getopt.getopt(sys.argv[1:], "dm:o:p:qv")
except getopt.GetoptError as err:
print(err)
usage()
if args:
usage()
for o, v in opts:
if o == "-d":
diagnostics = True
elif o == "-q":
quiet = True
elif o == "-m":
machine = v
elif o == "-p":
projectdir = v
elif o == "-o":
of = v
elif o == "-v":
verbose = True
else:
print(f"unrecognized option {o}")
usage()
outfile = f"{of}/out.bit"
logfile = f"{of}/build.log"
def make_posix(path):
return str(pathlib.Path(path).as_posix())
def regfiles():
ftt = {}
debuglog(f"projectdir is {projectdir}")
for dirpath, subdirs, files in os.walk(projectdir):
if (
"src" not in dirpath
and "xdc" not in dirpath
and "data" not in dirpath
and "ip" not in dirpath
):
continue
if dirpath.startswith("./"):
dirpath = dirpath[2:]
for file in files:
fpath = os.path.join(dirpath, file)
debuglog(f"considering {fpath}")
fpath = make_posix(fpath)
if file.lower().endswith(".v"):
ftt[fpath] = "source"
elif file.lower().endswith(".sv"):
ftt[fpath] = "source"
elif file.lower().endswith(".vh"):
ftt[fpath] = "source"
elif file.lower().endswith(".svh"):
ftt[fpath] = "source"
elif file.lower().endswith(".xdc"):
ftt[fpath] = "xdc"
elif file.lower().endswith(".mem"):
ftt[fpath] = "mem"
elif file.lower().endswith(".xci"):
ftt[fpath] = "ip"
elif file.lower().endswith(".prj"):
ftt[fpath] = "mig"
debuglog(f"elaborated file list {ftt}")
return ftt
# messages are newline delineated per lab-bs.1
# utilize this to cheat a little bit
def spqsend(p, msg):
debuglog(f"writing {len(msg)} bytes over the wire")
debuglog(f"full message: {msg}")
p.stdin.write(msg + b"\n")
p.stdin.flush()
def spsend(p, msg):
debuglog(f"running {msg}")
p.stdin.write((msg + "\n").encode())
p.stdin.flush()
def sprecv(p):
l = p.stdout.readline().decode()
debuglog(f"got {l}")
return l
def xsprecv(p):
l = sprecv(p)
if l.startswith("ERR"):
print("received unexpected server error!")
print(l)
sys.exit(1)
return l
def spstart(xargv):
debuglog(f"spawning {xargv}")
p = subprocess.PIPE
return subprocess.Popen(xargv, stdin=p, stdout=p, stderr=p)
def copyfiles(p, ftt):
for f, t in ftt.items():
fsize = os.path.getsize(f)
with open(f, "rb") as fd:
spsend(p, f"write {f} {fsize}")
time.sleep(0.1) # ?
spqsend(p, fd.read())
xsprecv(p)
spsend(p, f"type {f} {t}")
xsprecv(p)
# size message returns ... %zu bytes
def readfile(p, file, targetfile):
spsend(p, f"size {file}")
size = int(xsprecv(p).split()[-2])
spsend(p, f"read {file}")
with open(targetfile, "wb+") as fd:
fd.write(p.stdout.read(size))
xsprecv(p)
def build(p):
cmd = "build"
if diagnostics:
cmd += " -d"
if quiet:
cmd += " -q"
cmd += f" obj"
print(f"Output target will be {outfile}")
spsend(p, cmd)
print("Building your code ... (this may take a while, be patient)")
result = sprecv(p)
if result.startswith("ERR"):
print("Something went wrong!")
else:
readfile(p, "obj/out.bit", outfile)
print(f"Build succeeded, output at {outfile}")
readfile(p, "obj/build.log", logfile)
print(f"Log file available at {logfile}")
if diagnostics:
for rpt in synthrpt:
readfile(p, f"obj/synthrpt_{rpt}.rpt", f"{of}/synthrpt_{rpt}.rpt")
for rpt in placerpt:
readfile(p, f"obj/placerpt_{rpt}.rpt", f"{of}/placerpt_{rpt}.rpt")
for rpt in routerpt:
readfile(p, f"obj/routerpt_{rpt}.rpt", f"{of}/routerpt_{rpt}.rpt")
print(f"Diagnostics available in {of}")
def main():
global p
getargs()
ftt = regfiles()
if not os.path.isdir(of):
print(f"output path {of} does not exist! create it or use -o?")
usage()
if platform.system() == "Darwin" or platform.system() == "Linux":
xargv = [
"ssh",
"-p",
f"{port}",
"-o",
"StrictHostKeyChecking=no",
"-o",
"UserKnownHostsFile=/dev/null",
]
elif platform.system() == "Windows":
xargv = [
"ssh",
"-p",
f"{port}",
"-o",
"StrictHostKeyChecking=no",
"-o",
"UserKnownHostsFile=nul",
]
else:
raise RuntimeError(
"Your OS is not recognized, unsure of how to format SSH command."
)
xargv.append(f"{user}@{machine}")
p = spstart(xargv)
spsend(p, "help")
result = xsprecv(p)
debuglog(result)
copyfiles(p, ftt)
build(p)
spsend(p, "exit")
p.wait()
if __name__ == "__main__":
try:
main()
except (Exception, KeyboardInterrupt) as e:
if p:
debuglog("killing ssh")
os.kill(p.pid, signal.SIGINT)
p.wait()
raise e

View File

@ -0,0 +1,20 @@
---
cores:
ether_la:
type: logic_analyzer
sample_depth: 17000
trigger_loc: 50
probes:
eth_crsdv: 1
eth_rxd: 2
eth_txen: 1
eth_txd: 2
triggers:
- eth_crsdv RISING
uart:
port: "auto"
baudrate: 115200
clock_freq: 50000000

View File

@ -0,0 +1,24 @@
from manta import Manta
from scapy.all import *
m = Manta('manta.yaml')
def set_led(val):
src_mac = "00:00:00:00:00:00"
dst_mac = "FF:FF:FF:FF:FF:FF"
ifc = "en8"
mypkt = Ether()
mypkt.src = src_mac
mypkt.dst = dst_mac
mypkt.type = 0x1234
msg = b'\x56\x78' + val.to_bytes(2, 'big')
mypkt = mypkt / msg
mypkt.load = msg
sendpfast(mypkt, iface=ifc)
while(True):
set_led(0)

View File

@ -0,0 +1,257 @@
`define CP 20
`define HCP (`CP / 2)
/* checking helper for testing tasks */
`define CHECK(COND, TESTOK, MSG) do begin \
if (!(COND) && TESTOK) begin \
$display("FAIL: %s", MSG); \
TESTOK = 0; \
end \
end while (0)
`default_nettype none
`timescale 1ns / 1ps
`define PREAM_BAD 2'b10
`define PREAM_FIRST 2'b00
`define CRSDV_HOLD 10
`define MAC_BITS 48
`define ETYPE_BITS 16
`define MAX_MSG_BITS 128
`define AGGREGATE_SIZE 32
`define TIMEOUT 200
`define PREAMBLE 64'h5555_5555_5555_5557 /* pre-flipped for us */
`define MAC_BCAST 48'hFF_FF_FF_FF_FF_FF
`define MAC_SRC 48'h69_69_69_69_69_69 /* don't care if flipped */
`define ETYPE 16'h6969 /* don't care if flipped */
`define MSG(BITS, SIZE) (BITS << (`MAX_MSG_BITS - SIZE))
`define TTINY `MSG(2'b10, 2)
`define T32 `MSG(32'h4353_f92c, 32)
`define T64 `MSG(64'h1234_5678_0000_0000, 64)
`define T128 `MSG({(64){2'b10}}, 128)
`define T64_EXPECT 32'h84_1C_95_2D
`define T128_EXPECT 32'hAA_AA_AA_AA
module integrationsim;
logic clk, rst;
logic[1:0] rxd;
logic crsdv;
/* ether -> bitorder */
logic[1:0] ether_axiod;
logic ether_axiov;
/* bitorder -> firewall */
logic[1:0] bitorder_axiod;
logic bitorder_axiov;
/* firewall -> aggregate */
logic[1:0] firewall_axiod;
logic firewall_axiov;
/* aggregate output */
logic[31:0] axiod;
logic axiov;
/* constants */
logic[0:63] preamble;
logic[0:`MAC_BITS-1] dst, src;
logic[0:`ETYPE_BITS-1] etype;
assign preamble = `PREAMBLE;
assign dst = `MAC_BCAST;
assign src = `MAC_SRC;
assign etype = `ETYPE;
ether e(.clk(clk),
.rst(rst),
.rxd(rxd),
.crsdv(crsdv),
.axiov(ether_axiov),
.axiod(ether_axiod));
bitorder b(.clk(clk),
.rst(rst),
.axiiv(ether_axiov),
.axiid(ether_axiod),
.axiov(bitorder_axiov),
.axiod(bitorder_axiod));
firewall f(.clk(clk),
.rst(rst),
.axiiv(bitorder_axiov),
.axiid(bitorder_axiod),
.axiov(firewall_axiov),
.axiod(firewall_axiod));
aggregate a(.clk(clk),
.rst(rst),
.axiiv(firewall_axiov),
.axiid(firewall_axiod),
.axiov(axiov),
.axiod(axiod));
integer ok;
task test;
input[0:`MAX_MSG_BITS-1] msg;
input[63:0] msgsize;
input[31:0] exp;
input showexp;
input dorst;
begin
integer i, rcv;
rxd = 2'b00;
crsdv = 1'b0;
rcv = 0;
ok = 1;
if (dorst) begin
rst = 1'b1;
#`CP;
end
rst = 1'b0;
#`CP;
`CHECK(axiov === 0, ok, "axiov != 0 @ start");
for (i = 0; i < `CRSDV_HOLD; i = i + 1) begin
crsdv = 1'b1;
rxd = `PREAM_FIRST;
#`CP;
`CHECK(axiov === 0, ok, "crs: axiov != 0");
end
for (i = 0; i < 64; i = i + 2) begin
crsdv = 1'b1;
rxd = {preamble[i], preamble[i+1]};
#`CP;
`CHECK(axiov === 0, ok, "preamble: bad axiov");
end
for (i = 0; i < `MAC_BITS; i = i + 2) begin
crsdv = 1'b1;
rxd = {dst[i], dst[i+1]};
`CHECK(axiov === 0, ok, "axiov>0 in dst");
#`CP;
end
for (i = 0; i < `MAC_BITS; i = i + 2) begin
crsdv = 1'b1;
rxd = {src[i], src[i+1]};
`CHECK(axiov === 0, ok, "axiov>0 in src");
#`CP;
end
for (i = 0; i < `ETYPE_BITS; i = i + 2) begin
crsdv = 1'b1;
rxd = {etype[i], etype[i+1]};
`CHECK(axiov === 0, ok, "axiov>0 before data");
#`CP;
end
for (i = 0; i < msgsize; i = i + 2) begin
crsdv = 1'b1;
rxd = {msg[i], msg[i+1]};
if (axiov) begin
`CHECK(showexp, ok, "unexpected out");
`CHECK(rcv == 0,
ok,
"aggregate valid for >1 cycle");
`CHECK(axiod === exp,
ok,
"axiod != expected output");
rcv = 1;
end
#`CP;
end
rxd = 2'b00;
crsdv = 1'b0;
while (i < `TIMEOUT) begin
if (axiov) begin
`CHECK(showexp, ok, "unexpected out");
`CHECK(rcv == 0,
ok,
"aggregate valid for >1 cycle");
`CHECK(axiod === exp,
ok,
"axiod != expected output");
rcv = 1;
end
#`CP;
i = i + 2;
end
if (showexp) `CHECK(rcv, ok, "timeout");
end
endtask
initial begin: CLK
clk = 1;
forever #`HCP clk = ~clk;
end
initial begin: MAIN
`ifdef MKWAVEFORM
$dumpfile("obj/integration.vcd");
$dumpvars(0, integrationsim);
`endif /* MKWAVEFORM */
rxd = 2'b00;
crsdv = 1'b0;
rst = 1'b0;
#`CP;
$display("=== test 1: tiny 1-bit message ===");
test(`TTINY, 1, 0, 0, 1);
if (ok) $display("OK");
else $finish();
$display("=== test 2: 32-bit message (no FCS) ===");
test(`T32, 32, 0, 0, 0);
if (ok) $display("OK");
else $finish();
$display("=== test 3: 32-bit message (with FCS) ===");
test(`T64, 64, `T64_EXPECT, 1, 0);
if (ok) $display("OK");
else $finish();
$display("=== test 4: 96-bit message (with FCS) ===");
test(`T128, 128, `T128_EXPECT, 1, 0);
if (ok) $display("OK");
else $finish();
$display("=== test 5: one more 32 bit message (+ FCS) ===");
test(`T64, 64, `T64_EXPECT, 1, 0);
if (ok) $display("OK");
else $finish();
$display("=== all tests passed ===");
$finish();
end
endmodule

View File

@ -0,0 +1,133 @@
`default_nettype none
`timescale 1ns/1ps
module packet_blaster_9k_tb();
logic ethclk;
logic rst;
always begin
#5;
ethclk = !ethclk;
end
/* batteries... */
logic eth_crsdv;
logic[1:0] eth_rxd;
logic eth_refclk;
logic eth_rstn;
/* ether -> { cksum, bitorder } */
logic[1:0] ether_axiod;
logic ether_axiov;
/* cksum -> top_level */
logic cksum_done, cksum_kill;
/* bitorder -> firewall */
logic[1:0] bitorder_axiod;
logic bitorder_axiov;
/* firewall -> aggregate */
logic[1:0] firewall_axiod;
logic firewall_axiov;
/* aggregate output */
logic[31:0] aggregate_axiod;
logic aggregate_axiov;
/* and here's the pipeline... */
logic enable;
logic eth_crsdv_ref;
logic [1:0] eth_rxd_ref;
ether_la_playback #(.MEM_FILE("capture.mem")) ether_la_playback_inst (
.clk(ethclk),
.enable(enable),
.done(),
.eth_crsdv(eth_crsdv_ref),
.eth_rxd(eth_rxd_ref),
.eth_txen(),
.eth_txd());
logic start;
packet_blaster_9k pb9k (
.clk(ethclk),
.rst(rst),
//.src_mac(48'h69_2C_08_30_75_FD),
.src_mac(48'h00_00_00_00_00_00),
.dst_mac(48'hFF_FF_FF_FF_FF_FF),
.data(16'h5678),
.start(start),
.txen(eth_crsdv),
.txd(eth_rxd));
ether e(
.clk(ethclk),
.rst(rst),
.rxd(eth_rxd),
.crsdv(eth_crsdv),
.axiov(ether_axiov),
.axiod(ether_axiod));
bitorder b(
.clk(ethclk),
.rst(rst),
.axiiv(ether_axiov),
.axiid(ether_axiod),
.axiov(bitorder_axiov),
.axiod(bitorder_axiod));
firewall f(
.clk(ethclk),
.rst(rst),
.axiiv(bitorder_axiov),
.axiid(bitorder_axiod),
.axiov(firewall_axiov),
.axiod(firewall_axiod));
aggregate a(
.clk(ethclk),
.rst(rst),
.axiiv(firewall_axiov),
.axiid(firewall_axiod),
.axiov(aggregate_axiov),
.axiod(aggregate_axiod));
cksum c(
.clk(ethclk),
.rst(rst),
.axiiv(ether_axiov),
.axiid(ether_axiod),
.done(cksum_done),
.kill(cksum_kill));
initial begin
ethclk = 0;
$dumpfile("packet_blaster_9k_tb.vcd");
$dumpvars(0, packet_blaster_9k_tb);
rst = 0;
start = 0;
#10;
rst = 1;
#10;
rst = 0;
#10;
enable = 1;
#430;
start = 1;
#10;
start = 0;
#5000;
$finish();
end
endmodule
`default_nettype wire

View File

@ -0,0 +1,56 @@
/*
This playback module was generated with Manta v0.0.0 on 19 Apr 2023 at 12:01:24 by fischerm
If this breaks or if you've got dank formal verification memes, contact fischerm [at] mit.edu
Provided under a GNU GPLv3 license. Go wild.
Here's an example instantiation of the Manta module you configured, feel free to copy-paste
this into your source!
ether_la_playback #(.MEM_FILE("capture.mem")) ether_la_playback_inst (
.clk(clk),
.enable(1'b1),
.eth_crsdv(eth_crsdv),
.eth_rxd(eth_rxd),
.eth_txen(eth_txen),
.eth_txd(eth_txd));
*/
module ether_la_playback (
input wire clk,
input wire enable,
output reg done,
output reg eth_crsdv,
output reg [1:0] eth_rxd,
output reg eth_txen,
output reg [1:0] eth_txd);
parameter MEM_FILE = "";
localparam SAMPLE_DEPTH = 17000;
localparam TOTAL_PROBE_WIDTH = 6;
reg [TOTAL_PROBE_WIDTH-1:0] capture [SAMPLE_DEPTH-1:0];
reg [$clog2(SAMPLE_DEPTH)-1:0] addr;
reg [TOTAL_PROBE_WIDTH-1:0] sample;
assign done = (addr >= SAMPLE_DEPTH);
initial begin
$readmemb("capture.mem", capture, 0, SAMPLE_DEPTH-1);
addr = 0;
end
always @(posedge clk) begin
if (enable && !done) begin
addr = addr + 1;
sample = capture[addr];
{eth_txd, eth_txen, eth_rxd, eth_crsdv} = sample;
end
end
endmodule

View File

@ -0,0 +1,64 @@
`default_nettype none
`timescale 1ns / 1ps
/* Aggregates the first 64 bits of an incoming
* Ethernet transmission (thus shedding the FCS
* and anything else extraneous) and outputs the
* first 32 bits on an AXI bus for a single cycle.
* If the packet is not at least 64 bits long,
* nothing happens
*
* This value can then be fed into the seven
* segment display to verify proper operation
* of your module!
*/
`define AGR_MAX 32
`define AGR_SHOW 64
module aggregate(clk, rst, axiid, axiiv, axiod, axiov);
/* batteries */
input logic clk, rst;
/* AXI input valid, and AXI input data from the
* Ethernet pipeline. Comprises only data, i.e.
* source/destination/ethertype are omitted via
* previous stages in the pipeline. Also technically
* comprises the FCS, but we assume that the actual
* data in the ethernet frame is >= 32 bits long
* so we'll lose the FCS in this stage by design
*/
input logic[1:0] axiid;
input logic axiiv;
/* AXI output valid, and AXI output data. Comprises
* just the first 32 bits of the incoming transmission,
* asserted for a single cycle
*/
output logic[31:0] axiod;
output logic axiov;
/* A quick and dirty counter. As long as this is below
* 32, we'll dump packets into the AXI output data buffer.
* Once the counter gets to AGR_MAX, we'll assert AXI valid.
* Then we'll hang until axiiv drops
*/
logic[31:0] counter;
assign axiov = counter == `AGR_SHOW;
always_ff @(posedge clk) begin: COUNTER
if (rst || !axiiv) counter <= 32'b0;
else counter <= counter + 2;
end
always_ff @(posedge clk) begin: AXIOD
if (rst || !axiiv) axiod <= 32'b0;
else if (counter < `AGR_MAX && axiiv)
axiod[`AGR_MAX - counter - 2 +: 2] = axiid;
end
endmodule
`default_nettype wire

View File

@ -0,0 +1,138 @@
`default_nettype none
`timescale 1ns / 1ps
/* Ethernet sends packets in least significant
* bit order, most significant byte order. This
* module is responsible for changing that to
* make things legible - in particular, we convert
* from LSb/MSB to MSb/MSB.
*/
`define BO_SENDA 2'b00
`define BO_SENDB 2'b01
`define BO_EMPTYA 2'b10
`define BO_EMPTYB 2'b11
module bitorder(clk, rst, axiiv, axiid, axiod, axiov);
/* batteries */
input logic clk, rst;
/* AXI input valid and AXI input data
* from the module upstream from us in the
* pipeline - that being the physical layer
* This will transport bits from off the wire
* in least significant bit first order
*/
input logic[1:0] axiid;
input logic axiiv;
/* AXI output valid and AXI output data
* Transports the correctly bit-ordered Ethernet
* data (most significant bit first) up the pipeline
* for further processing...
*/
output logic[1:0] axiod;
output logic axiov;
/* Two registers to hold data coming in off the wire,
* byte by byte. This is where we'll buffer until
* we've received a byte of data, at which point
* we'll start sending out the byte in the correct
* order using one register. Meanwhile, we'll start
* receiving into the other register - dual buffers.
*/
logic[7:0] bufa, bufb;
/* A counter. This indicates what 'stage' we're in,
* and always refers to the index we're reading into
* in the receiving buffer or sending out of in the
* sending buffer
*/
logic[2:0] countera, counterb;
/* Which state we're in - should we be using buffer
* A to send, buffer B to send, or neither because
* we've just come out of reset?
*/
logic[1:0] state;
always_comb begin: AXIOV
if (state == `BO_SENDA || state == `BO_SENDB) axiov = 1'b1;
else axiov = 1'b0;
end
always_comb begin: AXIOD
if (state == `BO_SENDA) axiod = bufa[countera +: 2];
else if (state == `BO_SENDB) axiod = bufb[counterb +: 2];
else axiod = 1'b0;
end
always_ff @(posedge clk) begin: BUFFERIN
if (rst) begin
bufa <= 8'b0;
bufb <= 8'b0;
end else if (axiiv) begin
case (state)
`BO_EMPTYB, `BO_SENDB:
bufa[countera +: 2] <= axiid;
`BO_EMPTYA, `BO_SENDA:
bufb[counterb +: 2] <= axiid;
endcase
end else if (state == `BO_EMPTYB || state == `BO_EMPTYA) begin
bufa <= 8'b0;
bufb <= 8'b0;
end
end
always_ff @(posedge clk) begin: STATES
if (rst) begin
state <= `BO_EMPTYB;
countera <= 3'b0;
counterb <= 3'b0;
end else begin
case (state)
`BO_EMPTYB: begin
if (axiiv) begin
if (countera == 3'h6)
state <= `BO_SENDA;
else countera <= countera + 2;
end else countera <= 3'b0;
end
`BO_EMPTYA: begin
if (axiiv) begin
if (counterb == 3'h6)
state <= `BO_SENDB;
else counterb <= counterb + 2;
end else counterb <= 3'b0;
end
`BO_SENDB: begin
if (counterb == 3'h0) state <= `BO_EMPTYB;
else counterb <= counterb - 2;
if (axiiv) begin
if (countera == 3'h6)
state <= `BO_SENDA;
else countera <= countera + 2;
end
end
`BO_SENDA: begin
if (countera == 3'h0) state <= `BO_EMPTYA;
else countera <= countera - 2;
if (axiiv) begin
if (counterb == 3'h6)
state <= `BO_SENDB;
else counterb <= counterb + 2;
end
end
endcase
end
end
endmodule
`default_nettype wire

View File

@ -0,0 +1,49 @@
module bto7s(
input wire [3:0] x_in,
output logic [6:0] s_out);
logic sa, sb, sc, sd, se, sf, sg;
assign s_out = {sg, sf, se, sd, sc, sb, sa};
// array of bits that are "one hot" with numbers 0 through 15
logic [15:0] num;
assign num[0] = ~x_in[3] && ~x_in[2] && ~x_in[1] && ~x_in[0];
assign num[1] = ~x_in[3] && ~x_in[2] && ~x_in[1] && x_in[0];
assign num[2] = x_in == 4'd2;
assign num[3] = x_in == 4'd3;
assign num[4] = x_in == 4'd4;
assign num[5] = x_in == 4'd5;
assign num[6] = x_in == 4'd6;
assign num[7] = x_in == 4'd7;
assign num[8] = x_in == 4'd8;
assign num[9] = x_in == 4'd9;
assign num[10] = x_in == 4'd10;
assign num[11] = x_in == 4'd11;
assign num[12] = x_in == 4'd12;
assign num[13] = x_in == 4'd13;
assign num[14] = x_in == 4'd14;
assign num[15] = x_in == 4'd15;
/* you could also do this with generation, like this:
*
* genvar i;
* generate
* for (i=0; i<16; i=i+1)begin
* assign num[i] = (x_in == i);
* end
* endgenerate
*/
/* assign the seven output segments, sa through sg, using a "sum of products"
* approach and the diagram above.
*/
assign sa = num[0] || num[2] || num[3] || num[5] || num[6] || num[7] || num[8] || num[9] || num[10] || num[12] ||num[14] ||num[15];
assign sb = num[0] || num[1] || num[2] || num[3] || num[4] || num[7] || num[8] || num[9] || num[10] || num[13];
assign sc = num[0] || num[1] || num[3] || num[4] || num[5] || num[6] || num[7] || num[8] || num[9] || num[10] || num[11] || num[13];
assign sd = num[0] || num[2] || num[3] || num[5] || num[6] || num[8] || num[9] || num[11] || num[12] || num[13] || num[14];
assign se = num[0] || num[2] || num[6] || num[8] || num[10] || num[11] || num[12] || num[13] || num[14] || num[15];
assign sf = num[0] || num[4] || num[5] || num[6] || num[8] || num[9] || num[10] || num[11] || num[12] || num[14] || num[15];
assign sg = num[2] || num[3] || num[4] || num[5] || num[6] || num[8] || num[9] || num[10] || num[11] || num[13] || num[14] ||num[15];
endmodule

View File

@ -0,0 +1,95 @@
`default_nettype none
`timescale 1ns / 1ps
/* Computes the ethernet checksum
* The following combinations of `done` and `kill`
* represent the state of the module:
*
* - done = 0, kill = 0: processing data or freshly reset
* - done = 1, kill = 0: correct ethernet checksum verified
* - done = 1, kill = 1: data valid set to zero before correct
* checksum value computed, therefore bad checksum
* - done = 0, kill = 1: never asserted
*
* the done and/or kill signals are asserted high beginning
* the cycle after input data ceases, and until new data
* is received via the AXI input
*/
`define CK_FRESH 2'b00
`define CK_COMPUTING 2'b01
`define CK_DONE 2'b10
`define MAGIC_CHECK 32'h38_fb_22_84
module cksum(clk, rst, axiid, axiiv, done, kill);
/* batteries */
input logic clk, rst;
/* AXI input valid, and AXI input data from the
* physical layer. Comprises unmodified data directly
* from the wire, in Ethernet bit order, to be fed
* directly into the CRC32 module you wrote for the
* pset
*/
input logic[1:0] axiid;
input logic axiiv;
/* Done and kill, as described in the module synopsis */
output logic done, kill;
/* CRC32 AXI output data bus, which is the 32-bit
* checksum calculated so far via the checksum module
* you implemented in one of the last psets (CRC32-BZIP2)
*/
logic[31:0] crcd;
logic crcv;
/* Decoupled logic to reset the CRC module independently
* Used to compute multiple CRCs back to back
*/
logic crcrst;
/* Our finite state machine - bonus points if you can identify
* whether this is a Moore or Mealy FSM!
*/
logic[1:0] state;
crc32 cksum(.clk(clk),
.rst(crcrst | rst),
.axiiv(axiiv),
.axiid(axiid),
.axiov(crcv),
.axiod(crcd));
always_ff @(posedge clk) begin: OUTPUTS
if (rst || axiiv) begin
done <= 1'b0;
kill <= 1'b0;
crcrst <= 1'b0;
end else begin
if (state == `CK_COMPUTING && !axiiv) begin
done <= 1'b1;
crcrst <= 1'b1;
if (crcd == `MAGIC_CHECK) kill <= 1'b0;
else kill <= 1'b1;
end else crcrst <= 1'b0;
end
end
always_ff @(posedge clk) begin: FSM
if (rst) state <= `CK_FRESH;
else begin
case (state)
`CK_FRESH: if (axiiv) state <= `CK_COMPUTING;
`CK_COMPUTING: if (!axiiv) state <= `CK_DONE;
`CK_DONE: if (axiiv) state <= `CK_COMPUTING;
endcase
end
end
endmodule
`default_nettype wire

View File

@ -0,0 +1,74 @@
`default_nettype none
`timescale 1ns / 1ps
`define LAGGING_SHIFT_IN (caxiod[30] ^ axiid[1])
`define LEADING_SHIFT_IN (caxiod[31] ^ axiid[0])
`define DOUBLED_SHIFT_IN (`LEADING_SHIFT_IN ^ `LAGGING_SHIFT_IN)
`define LAGGING_TAPS 4, 7, 10, 16, 22, 26
`define DOUBLED_TAPS 2, 5, 8, 11, 12, 23
`define LEADING_TAPS 3, 6, 9, 13, 17, 24, 27
/* this module implements CRC32-BZIP2, with a two bit input:
* - poly 0x04C11DB7
* - init 0xFFFFFFFF
* - NEW: XOR outputs
*
* == check: 0xfc891918 ==
*
* this is the ethernet checksum!!
*/
module crc32(clk, rst, axiiv, axiid, axiov, axiod);
/* old style i/o declaration, for clarity.
* easier on 80-char line limits...
* use this if you want, we don't care
*/
input logic clk, rst;
input logic axiiv;
input logic[1:0] axiid;
output logic axiov;
output logic[31:0] axiod;
logic[31:0] caxiod, saxiod;
integer i;
assign axiov = 1;
assign axiod = ~caxiod;
always @(*) begin
for (i = 0; i < 32; i = i + 1) begin
case (i)
0: saxiod[i] = `LAGGING_SHIFT_IN;
1: saxiod[i] = `DOUBLED_SHIFT_IN;
`LAGGING_TAPS:
saxiod[i] = caxiod[i - 2] ^ `LAGGING_SHIFT_IN;
`DOUBLED_TAPS:
saxiod[i] = caxiod[i - 2] ^ `DOUBLED_SHIFT_IN;
`LEADING_TAPS:
saxiod[i] = caxiod[i - 2] ^ `LEADING_SHIFT_IN;
default: saxiod[i] = caxiod[i - 2];
endcase
end
end
always @(posedge clk) begin
if (rst) caxiod <= 32'hFFFF_FFFF;
/* our output validity hinges on whether
* we are calculating anything or not
* on this clock cycle. if there is no
* valid input for us, don't do a shift
* this cycle
*/
else caxiod <= (axiiv) ? saxiod : caxiod;
end
endmodule
`default_nettype wire

View File

@ -0,0 +1,193 @@
`default_nettype wire
// file: divider.sv
//
// (c) Copyright 2008 - 2013 Xilinx, Inc. All rights reserved.
//
// This file contains confidential and proprietary information
// of Xilinx, Inc. and is protected under U.S. and
// international copyright and other intellectual property
// laws.
//
// DISCLAIMER
// This disclaimer is not a license and does not grant any
// rights to the materials distributed herewith. Except as
// otherwise provided in a valid license issued to you by
// Xilinx, and to the maximum extent permitted by applicable
// law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND
// WITH ALL FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES
// AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY, INCLUDING
// BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-
// INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE; and
// (2) Xilinx shall not be liable (whether in contract or tort,
// including negligence, or under any other theory of
// liability) for any loss or damage of any kind or nature
// related to, arising under or in connection with these
// materials, including for any direct, or any indirect,
// special, incidental, or consequential loss or damage
// (including loss of data, profits, goodwill, or any type of
// loss or damage suffered as a result of any action brought
// by a third party) even if such damage or loss was
// reasonably foreseeable or Xilinx had been advised of the
// possibility of the same.
//
// CRITICAL APPLICATIONS
// Xilinx products are not designed or intended to be fail-
// safe, or for use in any application requiring fail-safe
// performance, such as life-support or safety devices or
// systems, Class III medical devices, nuclear facilities,
// applications related to the deployment of airbags, or any
// other applications that could lead to death, personal
// injury, or severe property or environmental damage
// (individually and collectively, "Critical
// Applications"). Customer assumes the sole risk and
// liability of any use of Xilinx products in Critical
// Applications, subject only to applicable laws and
// regulations governing limitations on product liability.
//
// THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS
// PART OF THIS FILE AT ALL TIMES.
//
//----------------------------------------------------------------------------
// User entered comments
//----------------------------------------------------------------------------
// popopopopopopopopopopop
//
//----------------------------------------------------------------------------
// Output Output Phase Duty Cycle Pk-to-Pk Phase
// Clock Freq (MHz) (degrees) (%) Jitter (ps) Error (ps)
//----------------------------------------------------------------------------
// __ethclk__50.00000______0.000______50.0______151.636_____98.575
//
//----------------------------------------------------------------------------
// Input Clock Freq (MHz) Input Jitter (UI)
//----------------------------------------------------------------------------
// __primary_________100.000____________0.010
`timescale 1ps/1ps
module divider
(// Clock in ports
// Clock out ports
output ethclk,
input clk
);
// Input buffering
//------------------------------------
wire clk_divider;
wire clk_in2_divider;
IBUF clkin1_ibufg
(.O (clk_divider),
.I (clk));
// Clocking PRIMITIVE
//------------------------------------
// Instantiation of the MMCM PRIMITIVE
// * Unused inputs are tied off
// * Unused outputs are labeled unused
wire ethclk_divider;
wire clk_out2_divider;
wire clk_out3_divider;
wire clk_out4_divider;
wire clk_out5_divider;
wire clk_out6_divider;
wire clk_out7_divider;
wire [15:0] do_unused;
wire drdy_unused;
wire psdone_unused;
wire locked_int;
wire clkfbout_divider;
wire clkfbout_buf_divider;
wire clkfboutb_unused;
wire clkout0b_unused;
wire clkout1_unused;
wire clkout1b_unused;
wire clkout2_unused;
wire clkout2b_unused;
wire clkout3_unused;
wire clkout3b_unused;
wire clkout4_unused;
wire clkout5_unused;
wire clkout6_unused;
wire clkfbstopped_unused;
wire clkinstopped_unused;
MMCME2_ADV
#(.BANDWIDTH ("OPTIMIZED"),
.CLKOUT4_CASCADE ("FALSE"),
.COMPENSATION ("ZHOLD"),
.STARTUP_WAIT ("FALSE"),
.DIVCLK_DIVIDE (1),
.CLKFBOUT_MULT_F (10.000),
.CLKFBOUT_PHASE (0.000),
.CLKFBOUT_USE_FINE_PS ("FALSE"),
.CLKOUT0_DIVIDE_F (20.000),
.CLKOUT0_PHASE (0.000),
.CLKOUT0_DUTY_CYCLE (0.500),
.CLKOUT0_USE_FINE_PS ("FALSE"),
.CLKIN1_PERIOD (10.000))
mmcm_adv_inst
// Output clocks
(
.CLKFBOUT (clkfbout_divider),
.CLKFBOUTB (clkfboutb_unused),
.CLKOUT0 (ethclk_divider),
.CLKOUT0B (clkout0b_unused),
.CLKOUT1 (clkout1_unused),
.CLKOUT1B (clkout1b_unused),
.CLKOUT2 (clkout2_unused),
.CLKOUT2B (clkout2b_unused),
.CLKOUT3 (clkout3_unused),
.CLKOUT3B (clkout3b_unused),
.CLKOUT4 (clkout4_unused),
.CLKOUT5 (clkout5_unused),
.CLKOUT6 (clkout6_unused),
// Input clock control
.CLKFBIN (clkfbout_buf_divider),
.CLKIN1 (clk_divider),
.CLKIN2 (1'b0),
// Tied to always select the primary input clock
.CLKINSEL (1'b1),
// Ports for dynamic reconfiguration
.DADDR (7'h0),
.DCLK (1'b0),
.DEN (1'b0),
.DI (16'h0),
.DO (do_unused),
.DRDY (drdy_unused),
.DWE (1'b0),
// Ports for dynamic phase shift
.PSCLK (1'b0),
.PSEN (1'b0),
.PSINCDEC (1'b0),
.PSDONE (psdone_unused),
// Other control and status signals
.LOCKED (locked_int),
.CLKINSTOPPED (clkinstopped_unused),
.CLKFBSTOPPED (clkfbstopped_unused),
.PWRDWN (1'b0),
.RST (1'b0));
// Clock Monitor clock assigning
//--------------------------------------
// Output buffering
//-----------------------------------
BUFG clkf_buf
(.O (clkfbout_buf_divider),
.I (clkfbout_divider));
BUFG clkout1_buf
(.O (ethclk),
.I (ethclk_divider));
endmodule
`default_nettype none

View File

@ -0,0 +1,151 @@
/* The catsoop checker does not like to see `timescale declarations
* in your code. However, we obviously need them when we synthesize
* for iverilog - they tell iverilog that #5 means 5ns, for example.
* Without these iverilog has no basis for how long *stuff* should
* wait for when you use #, so it blows up!
*
* When you use the catsoop checker, it `defines the CATSOOP macro.
* So we can check whether CATSOOP is defined or not - if it isn't,
* then we'll put the timescale thing in so code works right on your
* system.
*/
`default_nettype none
`timescale 1ns / 1ps
/* This module receives packets from the RJ45 (Ethernet) port on your
* FPGA from the _physical layer_, i.e. the electronic (or optical!)
* connection between devices running through an Ethernet cable.
*
* Ethernet is very diverse set of specifications, with all sorts of
* different physical layers (which we abbreviate 'the medium' or
* 'media' in plural). Ethernet media have transfer speeds ranging
* from 1 Mbps to 400 gigabits per second in modern data centers!
* For this implementation, we will implement "Fast Ethernet", which
* (not fast by today's standards) utilizes a physical layer capable
* of 100 Mbps communication. Most modern cables are backwards
* compatible with this standard.
*/
/* Note: this file uses tabs instead of spaces for indentation.
* More modern editors should pick this up automatically, but if yours
* doesn't that might explain trouble getting things to line up. You
* can probably configure this (e.g. in vim, type ":set noexpandtab"
* in normal mode and then type ":set tabstop=8")
*/
`define EF_IDLE 3'b000
`define EF_PREAM 3'b001
`define EF_DATA 3'b011
`define EF_BAD 3'b101
`define PREAM_BITS 64
`define PREAM_SIZE (`PREAM_BITS / 2)
`define PREAM_FIRST 2'b00
`define PREAM_EXPECT 2'b01
`define PREAM_LAST 2'b11
`define PREAM_BAD 2'b10
module ether(clk, rst, rxd, crsdv, axiov, axiod);
input logic clk, rst;
/* Carrier Sense (CRS) / Data Valid (DV): indicates
* whether there is a valid signal currently being
* transmitted over the Ethernet medium by another
* sender.
*
* In the past, >2 computers were connected
* to the same Ethernet cable, so this helped
* distinguish if one machine was trying to talk over
* another. Nowadays, usually Ethernet connections are
* point to point (have you ever seen an Ethernet cable
* with three ports on it? no? that's what i thought),
* and shared media isn't even supported in the 100 Mbps
* spec.
*
* So just use this input to determine whether valid
* data is on the line coming in.
*/
input logic crsdv;
/* Receive Data (RXD): If crsdv is high, receives
* two bits off the wire. Otherwise, undefined
* (let's say 2'bXX)
*
* According to the IEEE 802.3 Fast Ethernet
* specification, with the exception of the FCS,
* bytes in Ethernet world are sent least significant
* bit first, most significant byte first. Confusing!
* Basically, if you have a two byte (16 bit) message,
* the bits will come in over RXD as:
*
* 7:6 -> 5:4 -> 3:2 -> 1:0 -> 15:14 -> ... -> 9:8
*
* For now, this idiosyncracy won't matter to you.
* Later, it will.
*/
input logic[1:0] rxd;
/* 2-bit AXI output: forward whatever we receive
* on to the outside world for further processing
*/
output logic axiov;
output logic[1:0] axiod;
/* END OF STARTER CODE */
logic[4:0] count;
logic[2:0] state;
logic[1:0] preamex;
logic preamok, start;
always @(*) begin: PREAM
if (count == `PREAM_SIZE - 1) preamex = `PREAM_LAST;
else preamex = `PREAM_EXPECT;
preamok = crsdv && rxd == preamex;
end
always @(*) start = crsdv && rxd != `PREAM_FIRST;
always @(posedge clk) begin: COUNT
if (state == `EF_PREAM) count <= count + 1;
else if (state == `EF_IDLE && start) count <= count + 1;
else count <= 0;
end
always @(posedge clk) begin: FSM
if (rst) begin
axiod <= 2'b0;
axiov <= 1'b0;
state <= 3'b0;
end else begin
case (state)
`EF_BAD: if (!crsdv) state <= `EF_IDLE;
`EF_IDLE: if (start) state <= `EF_PREAM;
`EF_PREAM: begin
if (!preamok || !crsdv) state <= `EF_BAD;
else if (count == `PREAM_SIZE - 1)
state <= `EF_DATA;
end
`EF_DATA: begin
if (crsdv) begin
axiov <= 1'b1;
axiod <= rxd;
end else begin
axiov <= 1'b0;
axiod <= 2'b0;
state <= `EF_IDLE;
end
end
endcase
end
end
endmodule
`default_nettype wire

View File

@ -0,0 +1,121 @@
`default_nettype none
`timescale 1ns / 1ps
/* Sometimes we might receive packets not
* intended for us on the wire. This is especially
* true if we're operating in old school mode, where
* Ethernet used to have many devices on the same
* medium. Alternatively, several virtual NICs may
* exist in software on a given machine, or a machine
* may support MAC address randomization.
*
* All of this means we need to make sure inbound
* packets are actually intended for us, and not
* for some other NIC. That's what this module is
* for. In addition, this module will also strip
* the MAC address pair (and Ethertype) off of the
* Ethernet header, leaving only data and the FCS.
* We'll clean up the FCS later...
*/
/* "Intended for us" means the following:
* - has the destination MAC "`FW_ME" as defined below. Make this
* your own MAC of your choice - get creative!
* - has the destination MAC of all 1s, i.e. a 'broadcast' packet
*
* If these conditions are not met on a given input stream, data
* from the packet is dropped / not forwarded on through the
* pipeline
*/
`define FW_ME 48'h69_69_5A_06_54_91
`define FW_DESTSTART 0
`define FW_DESTEND (`FW_DESTSTART + 48)
`define FW_DATASTART (48 + 48 + 16)
module firewall(clk, rst, axiiv, axiid, axiov, axiod);
/* batteries */
input logic clk, rst;
/* AXI input valid, and AXI input data from the bit order
* flip module. So this will transport MSb/MSB first data
* coming off the wire - allowing you to compare with src/dst
* MAC addresses a bit more easily
*/
input logic[1:0] axiid;
input logic axiiv;
/* AXI output valid, and AXI output data. If and only if
* the packet is intended for our device as described above,
* this line will stream out the _data_ and _fcs_ (NOT the MAC
* addresses in the header, nor the ethertype - we're ignoring
* the latter this time around) we're receiving off the wire.
* If a kill-worthy condition is detected, these lines are
* deasserted for the duration of the incoming packet
*/
output logic[1:0] axiod;
output logic axiov;
/* Buffers to hold our MAC address in the reverse order,
* to make comparison easier than it otherwise would be
*/
logic[0:47] me;
/* A counter, to determine whether we should be comparing
* with a MAC address or stripping off data
*/
logic[31:0] counter;
/* An internal set of flags to mark whether the currently
* traversing packet is valid, i.e we should forward data,
* or not. One of these flags tracks whether the destination
* MAC address matches _our_ (FW_ME) mac address, the other
* tracks whether the destination matches the broadcast
* (FW_BCAST) MAC. If either one of these is high once the
* destination MAC finishes rolling through, the packet
* is forwarded.
*/
logic matchme, matchbcast;
assign me = `FW_ME;
always_ff @(posedge clk) begin: MATCH
if (counter == 32'b0) begin
matchme <= 1'b1;
matchbcast <= 1'b1;
end
/* could overwrite the above, which is ideal if
* FW_DESTSTART == 0 (it is) and we have a mismatch
* out the gate
*/
if (counter >= `FW_DESTSTART && counter < `FW_DESTEND) begin
if (axiiv) begin
if (axiid != {me[counter], me[counter + 1]})
matchme <= 1'b0;
if (axiid != 2'b11)
matchbcast <= 1'b0;
end
end
end
always_comb begin: AXIOUT
if (counter >= `FW_DATASTART && (matchme | matchbcast)) begin
axiod = axiid;
axiov = axiiv;
end else begin
axiod = 2'b00;
axiov = 1'b0;
end
end
always_ff @(posedge clk) begin: COUNTER
if (axiiv) counter <= counter + 2;
else counter <= 32'b0;
end
endmodule
`default_nettype wire

View File

@ -0,0 +1,97 @@
`default_nettype none
`timescale 1ns/1ps
module packet_blaster_9k(
input wire clk,
input wire rst,
input wire [47:0] src_mac,
input wire [47:0] dst_mac,
input wire [15:0] data,
input wire start,
output reg txen,
output reg [1:0] txd
);
/*
PREAMBLE: 7 bytes
SFD: 1 bytes
DEST MAC: 6 bytes
SOURCE MAC: 6 bytes
LENGTH: 2 bytes
DATA: 46 to 1k bytes
FCS:4 bytes
*/
// how long should our bus transactions be?
/*
coming in:
2 bytes for address
2 bytes for data (if writing)
2 bytes for data (if reading)
yeah for now let's do two and then just mask it off - only other option is trying to have some kind of buffered thing?
but then we have to be able to handle buffering the entire ethernet MTU - which is possible, but annoying. and now we're back
to buffering bus transactions, which was an explicit design anti-goal
maybe for now we just do the stupid thing?
ok so then this module should take output 2 bytes of data at the top of the packet, and then 44 bytes worth of zeros
length is then set to 46?
ok so plan for tomorrow is:
- to see if we can generate the packet we want to see on scapy. verify this in wireshark
- fire that over to the fpga, and save what it looks like with manta.
- make sure that if we replay that back to the host through txen/txd that we get what we think we should
- if not, then we have one FPGA transmit that packet to the other, which is recording with manta
- if so, then just massage packet blaster 9k to produce the right output.
*/
// all of our packets are going to be 72 bytes on wire, which is 288 dibits
reg [8:0] counter = 0;
reg [591:0] buffer = 0;
reg run = 0;
reg prev_start;
localparam PREAMBLE = {7{8'b01010101}};
localparam SFD = 8'b11010101;
localparam FCS = 32'b01001110_00010000_01011001_10011010;
bitorder b(
.clk(clk),
.rst(rst),
.axiiv(run),
.axiid(buffer[591:590]),
.axiov(txen),
.axiod(txd));
always @(posedge clk) begin
prev_start <= start;
if (run) begin
if (counter != 298) begin
counter <= counter + 1;
buffer <= {buffer[589:0], 2'b0};
end
else begin
run <= 0;
end
end
else begin
if (start && ~prev_start) begin
counter <= 0;
run <= 1;
buffer <= {16'b0, PREAMBLE, SFD, dst_mac, src_mac, 16'h1234, data, 352'b0, FCS};
end
end
end
endmodule
`default_nettype wire

View File

@ -0,0 +1,45 @@
module seven_segment_controller #(parameter COUNT_TO = 100000)
( input wire clk_in,
input wire rst_in,
input wire [31:0] val_in,
output logic[6:0] cat_out,
output logic[7:0] an_out
);
logic[7:0] segment_state;
logic[31:0] segment_counter;
logic [3:0] routed_vals;
logic [6:0] led_out;
bto7s mbto7s (.x_in(routed_vals), .s_out(led_out));
assign cat_out = ~led_out;
assign an_out = ~segment_state;
always_comb begin
case(segment_state)
8'b0000_0001: routed_vals = val_in[3:0];
8'b0000_0010: routed_vals = val_in[7:4];
8'b0000_0100: routed_vals = val_in[11:8];
8'b0000_1000: routed_vals = val_in[15:12];
8'b0001_0000: routed_vals = val_in[19:16];
8'b0010_0000: routed_vals = val_in[23:20];
8'b0100_0000: routed_vals = val_in[27:24];
8'b1000_0000: routed_vals = val_in[31:28];
default: routed_vals = val_in[3:0];
endcase
end
always_ff @(posedge clk_in)begin
if (rst_in)begin
segment_state <= 8'b0000_0001;
segment_counter <= 32'b0;
end else begin
if (segment_counter == COUNT_TO)begin
segment_counter <= 32'd0;
segment_state <= {segment_state[6:0],segment_state[7]};
end else begin
segment_counter <= segment_counter +1;
end
end
end
endmodule //seven_segment_controller

View File

@ -0,0 +1,56 @@
`default_nettype none
`timescale 1ns / 1ps
module top_level (
input wire clk,
input wire btnc,
input wire btnd,
output reg eth_refclk,
output reg eth_rstn,
input wire eth_crsdv,
input wire [1:0] eth_rxd,
output reg eth_txen,
output reg [1:0] eth_txd,
input wire uart_txd_in,
output logic uart_rxd_out
);
assign eth_rstn = ~btnc;
logic clk_50mhz;
assign eth_refclk = clk_50mhz;
divider d (.clk(clk), .ethclk(clk_50mhz));
manta manta_inst (
.clk(clk_50mhz),
.rx(uart_txd_in),
.tx(uart_rxd_out),
.eth_crsdv(eth_crsdv),
.eth_rxd(eth_rxd),
.eth_txen(eth_txen),
.eth_txd(eth_txd));
packet_blaster_9k pb9k (
.clk(clk_50mhz),
.rst(btnc),
//.src_mac(48'h69_2C_08_30_75_FD),
.src_mac(48'b00_00_00_00_00_00),
.dst_mac(48'hFF_FF_FF_FF_FF_FF),
.data(16'h5678),
.start(btnd),
.txen(eth_txen),
.txd(eth_txd));
endmodule
`default_nettype wire

View File

@ -0,0 +1,260 @@
## R1.0 2019-08-27
## Updated by jodalyst in 2020-2022
## all inputs/outputs changed to lowercase; arrays start with zero.
## system clock renamed to clk
## ja, jb, jc, jd renamed to 0-7
## xa port renamed 0-3
## seven segments renamed to a,b,c,d,e,f,dp
## This file is a general .xdc for the Nexys4 DDR Rev. C
## To use it in a project:
## - uncomment the lines corresponding to used pins
## - rename the used ports (in each line, after get_ports) according to the top level signal names in the project
## Clock signal - uncomment _both_ of these lines to create clk_100mhz
set_property -dict { PACKAGE_PIN E3 IOSTANDARD LVCMOS33 } [get_ports { clk }]; #IO_L12P_T1_MRCC_35 Sch=clk
create_clock -add -name sys_clk_pin -period 10.00 -waveform {0 5} [get_ports {clk}];
##Switches
# set_property -dict { PACKAGE_PIN J15 IOSTANDARD LVCMOS33 } [get_ports { sw[0] }]; #IO_L24N_T3_RS0_15 Sch=sw[0]
# set_property -dict { PACKAGE_PIN L16 IOSTANDARD LVCMOS33 } [get_ports { sw[1] }]; #IO_L3N_T0_DQS_EMCCLK_14 Sch=sw[1]
# set_property -dict { PACKAGE_PIN M13 IOSTANDARD LVCMOS33 } [get_ports { sw[2] }]; #IO_L6N_T0_D08_VREF_14 Sch=sw[2]
# set_property -dict { PACKAGE_PIN R15 IOSTANDARD LVCMOS33 } [get_ports { sw[3] }]; #IO_L13N_T2_MRCC_14 Sch=sw[3]
# set_property -dict { PACKAGE_PIN R17 IOSTANDARD LVCMOS33 } [get_ports { sw[4] }]; #IO_L12N_T1_MRCC_14 Sch=sw[4]
# set_property -dict { PACKAGE_PIN T18 IOSTANDARD LVCMOS33 } [get_ports { sw[5] }]; #IO_L7N_T1_D10_14 Sch=sw[5]
# set_property -dict { PACKAGE_PIN U18 IOSTANDARD LVCMOS33 } [get_ports { sw[6] }]; #IO_L17N_T2_A13_D29_14 Sch=sw[6]
# set_property -dict { PACKAGE_PIN R13 IOSTANDARD LVCMOS33 } [get_ports { sw[7] }]; #IO_L5N_T0_D07_14 Sch=sw[7]
# set_property -dict { PACKAGE_PIN T8 IOSTANDARD LVCMOS18 } [get_ports { sw[8] }]; #IO_L24N_T3_34 Sch=sw[8]
# set_property -dict { PACKAGE_PIN U8 IOSTANDARD LVCMOS18 } [get_ports { sw[9] }]; #IO_25_34 Sch=sw[9]
# set_property -dict { PACKAGE_PIN R16 IOSTANDARD LVCMOS33 } [get_ports { sw[10] }]; #IO_L15P_T2_DQS_RDWR_B_14 Sch=sw[10]
# set_property -dict { PACKAGE_PIN T13 IOSTANDARD LVCMOS33 } [get_ports { sw[11] }]; #IO_L23P_T3_A03_D19_14 Sch=sw[11]
# set_property -dict { PACKAGE_PIN H6 IOSTANDARD LVCMOS33 } [get_ports { sw[12] }]; #IO_L24P_T3_35 Sch=sw[12]
# set_property -dict { PACKAGE_PIN U12 IOSTANDARD LVCMOS33 } [get_ports { sw[13] }]; #IO_L20P_T3_A08_D24_14 Sch=sw[13]
# set_property -dict { PACKAGE_PIN U11 IOSTANDARD LVCMOS33 } [get_ports { sw[14] }]; #IO_L19N_T3_A09_D25_VREF_14 Sch=sw[14]
# set_property -dict { PACKAGE_PIN V10 IOSTANDARD LVCMOS33 } [get_ports { sw[15] }]; #IO_L21P_T3_DQS_14 Sch=sw[15]
## LEDs
# set_property -dict { PACKAGE_PIN H17 IOSTANDARD LVCMOS33 } [get_ports { led[0] }]; #IO_L18P_T2_A24_15 Sch=led[0]
# set_property -dict { PACKAGE_PIN K15 IOSTANDARD LVCMOS33 } [get_ports { led[1] }]; #IO_L24P_T3_RS1_15 Sch=led[1]
# set_property -dict { PACKAGE_PIN J13 IOSTANDARD LVCMOS33 } [get_ports { led[2] }]; #IO_L17N_T2_A25_15 Sch=led[2]
# set_property -dict { PACKAGE_PIN N14 IOSTANDARD LVCMOS33 } [get_ports { led[3] }]; #IO_L8P_T1_D11_14 Sch=led[3]
# set_property -dict { PACKAGE_PIN R18 IOSTANDARD LVCMOS33 } [get_ports { led[4] }]; #IO_L7P_T1_D09_14 Sch=led[4]
# set_property -dict { PACKAGE_PIN V17 IOSTANDARD LVCMOS33 } [get_ports { led[5] }]; #IO_L18N_T2_A11_D27_14 Sch=led[5]
# set_property -dict { PACKAGE_PIN U17 IOSTANDARD LVCMOS33 } [get_ports { led[6] }]; #IO_L17P_T2_A14_D30_14 Sch=led[6]
# set_property -dict { PACKAGE_PIN U16 IOSTANDARD LVCMOS33 } [get_ports { led[7] }]; #IO_L18P_T2_A12_D28_14 Sch=led[7]
# set_property -dict { PACKAGE_PIN V16 IOSTANDARD LVCMOS33 } [get_ports { led[8] }]; #IO_L16N_T2_A15_D31_14 Sch=led[8]
# set_property -dict { PACKAGE_PIN T15 IOSTANDARD LVCMOS33 } [get_ports { led[9] }]; #IO_L14N_T2_SRCC_14 Sch=led[9]
# set_property -dict { PACKAGE_PIN U14 IOSTANDARD LVCMOS33 } [get_ports { led[10] }]; #IO_L22P_T3_A05_D21_14 Sch=led[10]
# set_property -dict { PACKAGE_PIN T16 IOSTANDARD LVCMOS33 } [get_ports { led[11] }]; #IO_L15N_T2_DQS_DOUT_CSO_B_14 Sch=led[11]
# set_property -dict { PACKAGE_PIN V15 IOSTANDARD LVCMOS33 } [get_ports { led[12] }]; #IO_L16P_T2_CSI_B_14 Sch=led[12]
# set_property -dict { PACKAGE_PIN V14 IOSTANDARD LVCMOS33 } [get_ports { led[13] }]; #IO_L22N_T3_A04_D20_14 Sch=led[13]
# set_property -dict { PACKAGE_PIN V12 IOSTANDARD LVCMOS33 } [get_ports { led[14] }]; #IO_L20N_T3_A07_D23_14 Sch=led[14]
# set_property -dict { PACKAGE_PIN V11 IOSTANDARD LVCMOS33 } [get_ports { led[15] }]; #IO_L21N_T3_DQS_A06_D22_14 Sch=led[15]
# set_property -dict { PACKAGE_PIN R12 IOSTANDARD LVCMOS33 } [get_ports { led16_b }]; #IO_L5P_T0_D06_14 Sch=led16_b
# set_property -dict { PACKAGE_PIN M16 IOSTANDARD LVCMOS33 } [get_ports { led16_g }]; #IO_L10P_T1_D14_14 Sch=led16_g
# set_property -dict { PACKAGE_PIN N15 IOSTANDARD LVCMOS33 } [get_ports { led16_r }]; #IO_L11P_T1_SRCC_14 Sch=led16_r
# set_property -dict { PACKAGE_PIN G14 IOSTANDARD LVCMOS33 } [get_ports { led17_b }]; #IO_L15N_T2_DQS_ADV_B_15 Sch=led17_b
# set_property -dict { PACKAGE_PIN R11 IOSTANDARD LVCMOS33 } [get_ports { led17_g }]; #IO_0_14 Sch=led17_g
# set_property -dict { PACKAGE_PIN N16 IOSTANDARD LVCMOS33 } [get_ports { led17_r }]; #IO_L11N_T1_SRCC_14 Sch=led17_r
##7 segment display
# set_property -dict { PACKAGE_PIN T10 IOSTANDARD LVCMOS33 } [get_ports { ca }]; #IO_L24N_T3_A00_D16_14 Sch=ca
# set_property -dict { PACKAGE_PIN R10 IOSTANDARD LVCMOS33 } [get_ports { cb }]; #IO_25_14 Sch=cb
# set_property -dict { PACKAGE_PIN K16 IOSTANDARD LVCMOS33 } [get_ports { cc }]; #IO_25_15 Sch=cc
# set_property -dict { PACKAGE_PIN K13 IOSTANDARD LVCMOS33 } [get_ports { cd }]; #IO_L17P_T2_A26_15 Sch=cd
# set_property -dict { PACKAGE_PIN P15 IOSTANDARD LVCMOS33 } [get_ports { ce }]; #IO_L13P_T2_MRCC_14 Sch=ce
# set_property -dict { PACKAGE_PIN T11 IOSTANDARD LVCMOS33 } [get_ports { cf }]; #IO_L19P_T3_A10_D26_14 Sch=cf
# set_property -dict { PACKAGE_PIN L18 IOSTANDARD LVCMOS33 } [get_ports { cg }]; #IO_L4P_T0_D04_14 Sch=cg
# set_property -dict { PACKAGE_PIN H15 IOSTANDARD LVCMOS33 } [get_ports { dp }]; #IO_L19N_T3_A21_VREF_15 Sch=dp
# set_property -dict { PACKAGE_PIN J17 IOSTANDARD LVCMOS33 } [get_ports { an[0] }]; #IO_L23P_T3_FOE_B_15 Sch=an[0]
# set_property -dict { PACKAGE_PIN J18 IOSTANDARD LVCMOS33 } [get_ports { an[1] }]; #IO_L23N_T3_FWE_B_15 Sch=an[1]
# set_property -dict { PACKAGE_PIN T9 IOSTANDARD LVCMOS33 } [get_ports { an[2] }]; #IO_L24P_T3_A01_D17_14 Sch=an[2]
# set_property -dict { PACKAGE_PIN J14 IOSTANDARD LVCMOS33 } [get_ports { an[3] }]; #IO_L19P_T3_A22_15 Sch=an[3]
# set_property -dict { PACKAGE_PIN P14 IOSTANDARD LVCMOS33 } [get_ports { an[4] }]; #IO_L8N_T1_D12_14 Sch=an[4]
# set_property -dict { PACKAGE_PIN T14 IOSTANDARD LVCMOS33 } [get_ports { an[5] }]; #IO_L14P_T2_SRCC_14 Sch=an[5]
# set_property -dict { PACKAGE_PIN K2 IOSTANDARD LVCMOS33 } [get_ports { an[6] }]; #IO_L23P_T3_35 Sch=an[6]
# set_property -dict { PACKAGE_PIN U13 IOSTANDARD LVCMOS33 } [get_ports { an[7] }]; #IO_L23N_T3_A02_D18_14 Sch=an[7]
##Buttons
# set_property -dict { PACKAGE_PIN C12 IOSTANDARD LVCMOS33 } [get_ports { cpu_resetn }]; #IO_L3P_T0_DQS_AD1P_15 Sch=cpu_resetn
set_property -dict { PACKAGE_PIN N17 IOSTANDARD LVCMOS33 } [get_ports { btnc }]; #IO_L9P_T1_DQS_14 Sch=btnc
# set_property -dict { PACKAGE_PIN M18 IOSTANDARD LVCMOS33 } [get_ports { btnu }]; #IO_L4N_T0_D05_14 Sch=btnu
# set_property -dict { PACKAGE_PIN P17 IOSTANDARD LVCMOS33 } [get_ports { btnl }]; #IO_L12P_T1_MRCC_14 Sch=btnl
# set_property -dict { PACKAGE_PIN M17 IOSTANDARD LVCMOS33 } [get_ports { btnr }]; #IO_L10N_T1_D15_14 Sch=btnr
set_property -dict { PACKAGE_PIN P18 IOSTANDARD LVCMOS33 } [get_ports { btnd }]; #IO_L9N_T1_DQS_D13_14 Sch=btnd
##Pmod Headers
##Pmod Header JA
#set_property -dict { PACKAGE_PIN C17 IOSTANDARD LVCMOS33 } [get_ports { ja[0] }]; #IO_L20N_T3_A19_15 Sch=ja[1]
#set_property -dict { PACKAGE_PIN D18 IOSTANDARD LVCMOS33 } [get_ports { ja[1] }]; #IO_L21N_T3_DQS_A18_15 Sch=ja[2]
#set_property -dict { PACKAGE_PIN E18 IOSTANDARD LVCMOS33 } [get_ports { ja[2] }]; #IO_L21P_T3_DQS_15 Sch=ja[3]
#set_property -dict { PACKAGE_PIN G17 IOSTANDARD LVCMOS33 } [get_ports { ja[3] }]; #IO_L18N_T2_A23_15 Sch=ja[4]
#set_property -dict { PACKAGE_PIN D17 IOSTANDARD LVCMOS33 } [get_ports { ja[4] }]; #IO_L16N_T2_A27_15 Sch=ja[7]
#set_property -dict { PACKAGE_PIN E17 IOSTANDARD LVCMOS33 } [get_ports { ja[5] }]; #IO_L16P_T2_A28_15 Sch=ja[8]
#set_property -dict { PACKAGE_PIN F18 IOSTANDARD LVCMOS33 } [get_ports { ja[6] }]; #IO_L22N_T3_A16_15 Sch=ja[9]
#set_property -dict { PACKAGE_PIN G18 IOSTANDARD LVCMOS33 } [get_ports { ja[7] }]; #IO_L22P_T3_A17_15 Sch=ja[10]
##Pmod Header JB
#set_property -dict { PACKAGE_PIN D14 IOSTANDARD LVCMOS33 } [get_ports { jb[0] }]; #IO_L1P_T0_AD0P_15 Sch=jb[1]
#set_property -dict { PACKAGE_PIN F16 IOSTANDARD LVCMOS33 } [get_ports { jb[1] }]; #IO_L14N_T2_SRCC_15 Sch=jb[2]
#set_property -dict { PACKAGE_PIN G16 IOSTANDARD LVCMOS33 } [get_ports { jb[2] }]; #IO_L13N_T2_MRCC_15 Sch=jb[3]
#set_property -dict { PACKAGE_PIN H14 IOSTANDARD LVCMOS33 } [get_ports { jb[3] }]; #IO_L15P_T2_DQS_15 Sch=jb[4]
#set_property -dict { PACKAGE_PIN E16 IOSTANDARD LVCMOS33 } [get_ports { jb[4] }]; #IO_L11N_T1_SRCC_15 Sch=jb[7]
#set_property -dict { PACKAGE_PIN F13 IOSTANDARD LVCMOS33 } [get_ports { jb[5] }]; #IO_L5P_T0_AD9P_15 Sch=jb[8]
#set_property -dict { PACKAGE_PIN G13 IOSTANDARD LVCMOS33 } [get_ports { jb[6] }]; #IO_0_15 Sch=jb[9]
#set_property -dict { PACKAGE_PIN H16 IOSTANDARD LVCMOS33 } [get_ports { jb[7] }]; #IO_L13P_T2_MRCC_15 Sch=jb[10]
##Pmod Header JC
#set_property -dict { PACKAGE_PIN K1 IOSTANDARD LVCMOS33 } [get_ports { jc[0] }]; #IO_L23N_T3_35 Sch=jc[1]
#set_property -dict { PACKAGE_PIN F6 IOSTANDARD LVCMOS33 } [get_ports { jc[1] }]; #IO_L19N_T3_VREF_35 Sch=jc[2]
#set_property -dict { PACKAGE_PIN J2 IOSTANDARD LVCMOS33 } [get_ports { jc[2] }]; #IO_L22N_T3_35 Sch=jc[3]
#set_property -dict { PACKAGE_PIN G6 IOSTANDARD LVCMOS33 } [get_ports { jc[3] }]; #IO_L19P_T3_35 Sch=jc[4]
#set_property -dict { PACKAGE_PIN E7 IOSTANDARD LVCMOS33 } [get_ports { jc[4] }]; #IO_L6P_T0_35 Sch=jc[7]
#set_property -dict { PACKAGE_PIN J3 IOSTANDARD LVCMOS33 } [get_ports { jc[5] }]; #IO_L22P_T3_35 Sch=jc[8]
#set_property -dict { PACKAGE_PIN J4 IOSTANDARD LVCMOS33 } [get_ports { jc[6] }]; #IO_L21P_T3_DQS_35 Sch=jc[9]
#set_property -dict { PACKAGE_PIN E6 IOSTANDARD LVCMOS33 } [get_ports { jc[7] }]; #IO_L5P_T0_AD13P_35 Sch=jc[10]
##Pmod Header JD
#set_property -dict { PACKAGE_PIN H4 IOSTANDARD LVCMOS33 } [get_ports { jd[0] }]; #IO_L21N_T3_DQS_35 Sch=jd[1]
#set_property -dict { PACKAGE_PIN H1 IOSTANDARD LVCMOS33 } [get_ports { jd[1] }]; #IO_L17P_T2_35 Sch=jd[2]
#set_property -dict { PACKAGE_PIN G1 IOSTANDARD LVCMOS33 } [get_ports { jd[2] }]; #IO_L17N_T2_35 Sch=jd[3]
#set_property -dict { PACKAGE_PIN G3 IOSTANDARD LVCMOS33 } [get_ports { jd[3] }]; #IO_L20N_T3_35 Sch=jd[4]
#set_property -dict { PACKAGE_PIN H2 IOSTANDARD LVCMOS33 } [get_ports { jd[4] }]; #IO_L15P_T2_DQS_35 Sch=jd[7]
#set_property -dict { PACKAGE_PIN G4 IOSTANDARD LVCMOS33 } [get_ports { jd[5] }]; #IO_L20P_T3_35 Sch=jd[8]
#set_property -dict { PACKAGE_PIN G2 IOSTANDARD LVCMOS33 } [get_ports { jd[6] }]; #IO_L15N_T2_DQS_35 Sch=jd[9]
#set_property -dict { PACKAGE_PIN F3 IOSTANDARD LVCMOS33 } [get_ports { jd[7] }]; #IO_L13N_T2_MRCC_35 Sch=jd[10]
##Pmod Header JXADC
#set_property -dict { PACKAGE_PIN A14 IOSTANDARD LVDS } [get_ports { xa_n[0] }]; #IO_L9N_T1_DQS_AD3N_15 Sch=xa_n[1]
#set_property -dict { PACKAGE_PIN A13 IOSTANDARD LVDS } [get_ports { xa_p[0] }]; #IO_L9P_T1_DQS_AD3P_15 Sch=xa_p[1]
#set_property -dict { PACKAGE_PIN A16 IOSTANDARD LVDS } [get_ports { xa_n[1] }]; #IO_L8N_T1_AD10N_15 Sch=xa_n[2]
#set_property -dict { PACKAGE_PIN A15 IOSTANDARD LVDS } [get_ports { xa_p[1] }]; #IO_L8P_T1_AD10P_15 Sch=xa_p[2]
#set_property -dict { PACKAGE_PIN B17 IOSTANDARD LVDS } [get_ports { xa_n[2] }]; #IO_L7N_T1_AD2N_15 Sch=xa_n[3]
#set_property -dict { PACKAGE_PIN B16 IOSTANDARD LVDS } [get_ports { xa_p[2] }]; #IO_L7P_T1_AD2P_15 Sch=xa_p[3]
#set_property -dict { PACKAGE_PIN A18 IOSTANDARD LVDS } [get_ports { xa_n[3] }]; #IO_L10N_T1_AD11N_15 Sch=xa_n[4]
#set_property -dict { PACKAGE_PIN B18 IOSTANDARD LVDS } [get_ports { xa_p[3] }]; #IO_L10P_T1_AD11P_15 Sch=xa_p[4]
##VGA Connector
#set_property -dict { PACKAGE_PIN A3 IOSTANDARD LVCMOS33 } [get_ports { vga_r[0] }]; #IO_L8N_T1_AD14N_35 Sch=vga_r[0]
#set_property -dict { PACKAGE_PIN B4 IOSTANDARD LVCMOS33 } [get_ports { vga_r[1] }]; #IO_L7N_T1_AD6N_35 Sch=vga_r[1]
#set_property -dict { PACKAGE_PIN C5 IOSTANDARD LVCMOS33 } [get_ports { vga_r[2] }]; #IO_L1N_T0_AD4N_35 Sch=vga_r[2]
#set_property -dict { PACKAGE_PIN A4 IOSTANDARD LVCMOS33 } [get_ports { vga_r[3] }]; #IO_L8P_T1_AD14P_35 Sch=vga_r[3]
#
#set_property -dict { PACKAGE_PIN C6 IOSTANDARD LVCMOS33 } [get_ports { vga_g[0] }]; #IO_L1P_T0_AD4P_35 Sch=vga_g[0]
#set_property -dict { PACKAGE_PIN A5 IOSTANDARD LVCMOS33 } [get_ports { vga_g[1] }]; #IO_L3N_T0_DQS_AD5N_35 Sch=vga_g[1]
#set_property -dict { PACKAGE_PIN B6 IOSTANDARD LVCMOS33 } [get_ports { vga_g[2] }]; #IO_L2N_T0_AD12N_35 Sch=vga_g[2]
#set_property -dict { PACKAGE_PIN A6 IOSTANDARD LVCMOS33 } [get_ports { vga_g[3] }]; #IO_L3P_T0_DQS_AD5P_35 Sch=vga_g[3]
#
#set_property -dict { PACKAGE_PIN B7 IOSTANDARD LVCMOS33 } [get_ports { vga_b[0] }]; #IO_L2P_T0_AD12P_35 Sch=vga_b[0]
#set_property -dict { PACKAGE_PIN C7 IOSTANDARD LVCMOS33 } [get_ports { vga_b[1] }]; #IO_L4N_T0_35 Sch=vga_b[1]
#set_property -dict { PACKAGE_PIN D7 IOSTANDARD LVCMOS33 } [get_ports { vga_b[2] }]; #IO_L6N_T0_VREF_35 Sch=vga_b[2]
#set_property -dict { PACKAGE_PIN D8 IOSTANDARD LVCMOS33 } [get_ports { vga_b[3] }]; #IO_L4P_T0_35 Sch=vga_b[3]
#set_property -dict { PACKAGE_PIN B11 IOSTANDARD LVCMOS33 } [get_ports { vga_hs }]; #IO_L4P_T0_15 Sch=vga_hs
#set_property -dict { PACKAGE_PIN B12 IOSTANDARD LVCMOS33 } [get_ports { vga_vs }]; #IO_L3N_T0_DQS_AD1N_15 Sch=vga_vs
##Micro SD Connector
#set_property -dict { PACKAGE_PIN E2 IOSTANDARD LVCMOS33 } [get_ports { sd_reset }]; #IO_L14P_T2_SRCC_35 Sch=sd_reset
#set_property -dict { PACKAGE_PIN A1 IOSTANDARD LVCMOS33 } [get_ports { sd_cd }]; #IO_L9N_T1_DQS_AD7N_35 Sch=sd_cd
#set_property -dict { PACKAGE_PIN B1 IOSTANDARD LVCMOS33 } [get_ports { sd_sck }]; #IO_L9P_T1_DQS_AD7P_35 Sch=sd_sck
#set_property -dict { PACKAGE_PIN C1 IOSTANDARD LVCMOS33 } [get_ports { sd_cmd }]; #IO_L16N_T2_35 Sch=sd_cmd
#set_property -dict { PACKAGE_PIN C2 IOSTANDARD LVCMOS33 } [get_ports { sd_dat[0] }]; #IO_L16P_T2_35 Sch=sd_dat[0]
#set_property -dict { PACKAGE_PIN E1 IOSTANDARD LVCMOS33 } [get_ports { sd_dat[1] }]; #IO_L18N_T2_35 Sch=sd_dat[1]
#set_property -dict { PACKAGE_PIN F1 IOSTANDARD LVCMOS33 } [get_ports { sd_dat[2] }]; #IO_L18P_T2_35 Sch=sd_dat[2]
#set_property -dict { PACKAGE_PIN D2 IOSTANDARD LVCMOS33 } [get_ports { sd_dat[3] }]; #IO_L14N_T2_SRCC_35 Sch=sd_dat[3]
##Accelerometer
#set_property -dict { PACKAGE_PIN E15 IOSTANDARD LVCMOS33 } [get_ports { acl_miso }]; #IO_L11P_T1_SRCC_15 Sch=acl_miso
#set_property -dict { PACKAGE_PIN F14 IOSTANDARD LVCMOS33 } [get_ports { acl_mosi }]; #IO_L5N_T0_AD9N_15 Sch=acl_mosi
#set_property -dict { PACKAGE_PIN F15 IOSTANDARD LVCMOS33 } [get_ports { acl_sclk }]; #IO_L14P_T2_SRCC_15 Sch=acl_sclk
#set_property -dict { PACKAGE_PIN D15 IOSTANDARD LVCMOS33 } [get_ports { acl_csn }]; #IO_L12P_T1_MRCC_15 Sch=acl_csn
#set_property -dict { PACKAGE_PIN B13 IOSTANDARD LVCMOS33 } [get_ports { acl_int[1] }]; #IO_L2P_T0_AD8P_15 Sch=acl_int[1]
#set_property -dict { PACKAGE_PIN C16 IOSTANDARD LVCMOS33 } [get_ports { acl_int[2] }]; #IO_L20P_T3_A20_15 Sch=acl_int[2]
##Temperature Sensor
#set_property -dict { PACKAGE_PIN C14 IOSTANDARD LVCMOS33 } [get_ports { tmp_scl }]; #IO_L1N_T0_AD0N_15 Sch=tmp_scl
#set_property -dict { PACKAGE_PIN C15 IOSTANDARD LVCMOS33 } [get_ports { tmp_sda }]; #IO_L12N_T1_MRCC_15 Sch=tmp_sda
#set_property -dict { PACKAGE_PIN D13 IOSTANDARD LVCMOS33 } [get_ports { tmp_int }]; #IO_L6N_T0_VREF_15 Sch=tmp_int
#set_property -dict { PACKAGE_PIN B14 IOSTANDARD LVCMOS33 } [get_ports { tmp_ct }]; #IO_L2N_T0_AD8N_15 Sch=tmp_ct
##Omnidirectional Microphone
#set_property -dict { PACKAGE_PIN J5 IOSTANDARD LVCMOS33 } [get_ports { m_clk }]; #IO_25_35 Sch=m_clk
#set_property -dict { PACKAGE_PIN H5 IOSTANDARD LVCMOS33 } [get_ports { m_data }]; #IO_L24N_T3_35 Sch=m_data
#set_property -dict { PACKAGE_PIN F5 IOSTANDARD LVCMOS33 } [get_ports { m_lrsel }]; #IO_0_35 Sch=m_lrsel
##PWM Audio Amplifier
#set_property -dict { PACKAGE_PIN A11 IOSTANDARD LVCMOS33 } [get_ports { aud_pwm }]; #IO_L4N_T0_15 Sch=aud_pwm
#set_property -dict { PACKAGE_PIN D12 IOSTANDARD LVCMOS33 } [get_ports { aud_sd }]; #IO_L6P_T0_15 Sch=aud_sd
##USB-RS232 Interface
set_property -dict { PACKAGE_PIN C4 IOSTANDARD LVCMOS33 } [get_ports { uart_txd_in }]; #IO_L7P_T1_AD6P_35 Sch=uart_txd_in
set_property -dict { PACKAGE_PIN D4 IOSTANDARD LVCMOS33 } [get_ports { uart_rxd_out }]; #IO_L11N_T1_SRCC_35 Sch=uart_rxd_out
#set_property -dict { PACKAGE_PIN D3 IOSTANDARD LVCMOS33 } [get_ports { uart_cts }]; #IO_L12N_T1_MRCC_35 Sch=uart_cts
#set_property -dict { PACKAGE_PIN E5 IOSTANDARD LVCMOS33 } [get_ports { uart_rts }]; #IO_L5N_T0_AD13N_35 Sch=uart_rts
##USB HID (PS/2)
#set_property -dict { PACKAGE_PIN F4 IOSTANDARD LVCMOS33 } [get_ports { ps2_clk }]; #IO_L13P_T2_MRCC_35 Sch=ps2_clk
#set_property -dict { PACKAGE_PIN B2 IOSTANDARD LVCMOS33 } [get_ports { ps2_data }]; #IO_L10N_T1_AD15N_35 Sch=ps2_data
##SMSC Ethernet PHY
#set_property -dict { PACKAGE_PIN C9 IOSTANDARD LVCMOS33 } [get_ports { eth_mdc }]; #IO_L11P_T1_SRCC_16 Sch=eth_mdc
#set_property -dict { PACKAGE_PIN A9 IOSTANDARD LVCMOS33 } [get_ports { eth_mdio }]; #IO_L14N_T2_SRCC_16 Sch=eth_mdio
set_property -dict { PACKAGE_PIN B3 IOSTANDARD LVCMOS33 } [get_ports { eth_rstn }]; #IO_L10P_T1_AD15P_35 Sch=eth_rstn
set_property -dict { PACKAGE_PIN D9 IOSTANDARD LVCMOS33 } [get_ports { eth_crsdv }]; #IO_L6N_T0_VREF_16 Sch=eth_crs/udv
#set_property -dict { PACKAGE_PIN C10 IOSTANDARD LVCMOS33 } [get_ports { eth_rxerr }]; #IO_L13N_T2_MRCC_16 Sch=eth_rxerr
set_property -dict { PACKAGE_PIN C11 IOSTANDARD LVCMOS33 } [get_ports { eth_rxd[0] }]; #IO_L13P_T2_MRCC_16 Sch=eth_rxd[0]
set_property -dict { PACKAGE_PIN D10 IOSTANDARD LVCMOS33 } [get_ports { eth_rxd[1] }]; #IO_L19N_T3_VREF_16 Sch=eth_rxd[1]
set_property -dict { PACKAGE_PIN B9 IOSTANDARD LVCMOS33 } [get_ports { eth_txen }]; #IO_L11N_T1_SRCC_16 Sch=eth_txen
set_property -dict { PACKAGE_PIN A10 IOSTANDARD LVCMOS33 } [get_ports { eth_txd[0] }]; #IO_L14P_T2_SRCC_16 Sch=eth_txd[0]
set_property -dict { PACKAGE_PIN A8 IOSTANDARD LVCMOS33 } [get_ports { eth_txd[1] }]; #IO_L12N_T1_MRCC_16 Sch=eth_txd[1]
set_property -dict { PACKAGE_PIN D5 IOSTANDARD LVCMOS33 } [get_ports { eth_refclk }]; #IO_L11P_T1_SRCC_35 Sch=eth_refclk
#set_property -dict { PACKAGE_PIN B8 IOSTANDARD LVCMOS33 } [get_ports { eth_intn }]; #IO_L12P_T1_MRCC_16 Sch=eth_intn
##Quad SPI Flash
#set_property -dict { PACKAGE_PIN K17 IOSTANDARD LVCMOS33 } [get_ports { qspi_dq[0] }]; #IO_L1P_T0_D00_MOSI_14 Sch=qspi_dq[0]
#set_property -dict { PACKAGE_PIN K18 IOSTANDARD LVCMOS33 } [get_ports { qspi_dq[1] }]; #IO_L1N_T0_D01_DIN_14 Sch=qspi_dq[1]
#set_property -dict { PACKAGE_PIN L14 IOSTANDARD LVCMOS33 } [get_ports { qspi_dq[2] }]; #IO_L2P_T0_D02_14 Sch=qspi_dq[2]
#set_property -dict { PACKAGE_PIN M14 IOSTANDARD LVCMOS33 } [get_ports { qspi_dq[3] }]; #IO_L2N_T0_D03_14 Sch=qspi_dq[3]
#set_property -dict { PACKAGE_PIN L13 IOSTANDARD LVCMOS33 } [get_ports { qspi_csn }]; #IO_L6P_T0_FCS_B_14 Sch=qspi_csn