initial commit for sd card example

This commit is contained in:
Fischer Moseley 2023-02-15 11:48:58 -05:00
parent 979f1591b6
commit 218b2ffd20
9 changed files with 1742 additions and 25 deletions

View File

@ -28,7 +28,7 @@ Copy `manta.py` into the root of your project directory. You'll also need a conf
Clone the repo, and then run `build.py`. This will output an executable `manta` with no file extension, which you're free to use.
## Examples
Examples can be found under `examples/`.
Examples can be found under `examples/`. These target the [Nexys4 DDR](https://digilent.com/reference/programmable-logic/nexys-4-ddr/start) and [Nexys A7-100T](https://digilent.com/reference/programmable-logic/nexys-a7/start) from Digilent, which are functionally equivalent.
## About
Manta was originally developed as part of my [Master's Thesis at MIT](dspace.mit.edu) in 2023, done under the supervision of Joe Steinmeyer. But I think it's a neat tool, so I'm still working on it :)

View File

@ -1,33 +1,611 @@
`default_nettype none
`timescale 1ns / 1ps
module top_level (
input wire clk,
input wire btnc,
input wire btnu,
input wire [15:0] sw,
/*
This manta definition was autogenerated on 15 Feb 2023 at 11:06:14 by fischerm
output logic [15:0] led,
input wire uart_txd_in,
output logic uart_rxd_out
);
// Signal Generator
logic [7:0] count;
always_ff @(posedge clk) count <= count + 1;
If this breaks or if you've got dank formal verification memes,
please contact fischerm [at] mit.edu.
*/
// debugger
manta manta(
`define IDLE 0
`define ARM 1
`define FILL 2
`define DOWNLINK 3
`define ARM_BYTE 8'b00110000
module manta (
input wire clk,
input wire rst,
/* Begin autogenerated probe definitions */
input wire larry,
input wire curly,
input wire moe,
input wire [3:0] shemp,
/* End autogenerated probe definitions */
input wire rxd,
output logic txd);
/* Begin autogenerated parameters */
localparam SAMPLE_WIDTH = 7;
localparam SAMPLE_DEPTH = 4096;
localparam DATA_WIDTH = 8;
localparam BAUDRATE = 115200;
localparam CLK_FREQ_HZ = 100000000;
logic trigger;
assign trigger = (larry && curly && ~moe);
logic [SAMPLE_WIDTH - 1 : 0] concat;
assign concat = {larry, curly, moe, shemp};
/* End autogenerated parameters */
// FIFO
logic [7:0] fifo_data_in;
logic fifo_input_ready;
logic fifo_request_output;
logic [7:0] fifo_data_out;
logic fifo_output_valid;
logic [11:0] fifo_size;
logic fifo_empty;
logic fifo_full;
fifo #(
.WIDTH(SAMPLE_WIDTH),
.DEPTH(SAMPLE_DEPTH)
) fifo (
.clk(clk),
.rst(btnc),
.larry(count[0]),
.curly(count[1]),
.moe(count[2]),
.shemp(count[3:0]),
.rxd(uart_txd_in),
.txd(uart_rxd_out));
.rst(rst),
.data_in(fifo_data_in),
.input_ready(fifo_input_ready),
.request_output(fifo_request_output),
.data_out(fifo_data_out),
.output_valid(fifo_output_valid),
.size(fifo_size),
.empty(fifo_empty),
.full(fifo_full));
// Serial interface
logic tx_start;
logic [7:0] tx_data;
logic tx_busy;
logic [7:0] rx_data;
logic rx_ready;
logic rx_busy;
uart_tx #(
.DATA_WIDTH(DATA_WIDTH),
.CLK_FREQ_HZ(CLK_FREQ_HZ),
.BAUDRATE(BAUDRATE))
tx (
.clk(clk),
.rst(rst),
.start(tx_start),
.data(tx_data),
.busy(tx_busy),
.txd(txd));
uart_rx #(
.DATA_WIDTH(DATA_WIDTH),
.CLK_FREQ_HZ(CLK_FREQ_HZ),
.BAUDRATE(BAUDRATE))
rx (
.clk(clk),
.rst(rst),
.rxd(rxd),
.data(rx_data),
.ready(rx_ready),
.busy(rx_busy));
/* State Machine */
/*
IDLE:
- literally nothing is happening. the FIFO isn't being written to or read from. it should be empty.
- an arm command over serial is what brings us into the ARM state
ARM:
- popping things onto FIFO. if the fifo is halfway full, we pop them off too.
- meeting the trigger condition is what moves us into the filing state
FILL:
- popping things onto FIFO, until it's full. once it is full, we move into the downlinking state
DOWNLINK:
- popping thing off of the FIFO until it's empty. once it's empty, we move back into the IDLE state
*/
/* Downlink State Machine Controller */
/*
- ila enters the downlink state
- set fifo_output_request high for a clock cycle
- when fifo_output_valid goes high, send fifo_data_out across the line
- do nothing until tx_busy goes low
- goto step 2
*/
logic [1:0] state;
logic [2:0] downlink_fsm_state;
always_ff @(posedge clk) begin
if(rst) begin
state <= `IDLE;
downlink_fsm_state <= 0;
tx_data <= 0;
tx_start <= 0;
end
else begin
case (state)
`IDLE : begin
fifo_input_ready <= 0;
fifo_request_output <= 0;
if (rx_ready && rx_data == `ARM_BYTE) state <= `ARM;
end
`ARM : begin
// place samples into FIFO
fifo_input_ready <= 1;
fifo_data_in <= concat;
// remove old samples if we're more than halfway full
fifo_request_output <= (fifo_size >= SAMPLE_DEPTH / 2);
if(trigger) state <= `FILL;
end
`FILL : begin
// place samples into FIFO
fifo_input_ready <= 1;
fifo_data_in <= concat;
// don't pop anything out the FIFO
fifo_request_output <= 0;
if(fifo_size == SAMPLE_DEPTH - 1) state <= `DOWNLINK;
end
`DOWNLINK : begin
// place no samples into FIFO
fifo_input_ready <= 0;
case (downlink_fsm_state)
0 : begin
if (~fifo_empty) begin
fifo_request_output <= 1;
downlink_fsm_state <= 1;
end
else state <= `IDLE;
end
1 : begin
fifo_request_output <= 0;
if (fifo_output_valid) begin
tx_data <= fifo_data_out;
tx_start <= 1;
downlink_fsm_state <= 2;
end
end
2 : begin
tx_start <= 0;
if (~tx_busy && ~tx_start) downlink_fsm_state <= 0;
end
endcase
end
endcase
end
end
endmodule
`default_nettype wire
`default_nettype wire`default_nettype none
`timescale 1ns / 1ps
module fifo (
input wire clk,
input wire rst,
input wire [WIDTH - 1:0] data_in,
input wire input_ready,
input wire request_output,
output logic [WIDTH - 1:0] data_out,
output logic output_valid,
output logic [AW:0] size,
output logic empty,
output logic full
);
parameter WIDTH = 8;
parameter DEPTH = 4096;
localparam AW = $clog2(DEPTH);
logic [AW:0] write_pointer;
logic [AW:0] read_pointer;
logic empty_int;
assign empty_int = (write_pointer[AW] == read_pointer[AW]);
logic full_or_empty;
assign full_or_empty = (write_pointer[AW-1:0] == read_pointer[AW-1:0]);
assign full = full_or_empty & !empty_int;
assign empty = full_or_empty & empty_int;
assign size = write_pointer - read_pointer;
logic output_valid_pip_0;
logic output_valid_pip_1;
always @(posedge clk) begin
if (input_ready && ~full)
write_pointer <= write_pointer + 1'd1;
if (request_output && ~empty)
read_pointer <= read_pointer + 1'd1;
output_valid_pip_0 <= request_output;
output_valid_pip_1 <= output_valid_pip_0;
output_valid <= output_valid_pip_1;
if (rst) begin
read_pointer <= 0;
write_pointer <= 0;
end
end
xilinx_true_dual_port_read_first_2_clock_ram #(
.RAM_WIDTH(WIDTH),
.RAM_DEPTH(DEPTH),
.RAM_PERFORMANCE("HIGH_PERFORMANCE")
) buffer (
// write port
.clka(clk),
.rsta(rst),
.ena(1),
.addra(write_pointer),
.dina(data_in),
.wea(input_ready),
.regcea(1),
.douta(),
// read port
.clkb(clk),
.rstb(rst),
.enb(1),
.addrb(read_pointer),
.dinb(),
.web(0),
.regceb(1),
.doutb(data_out));
endmodule
`default_nettype wire
`default_nettype none
`timescale 1ns / 1ps
module uart_tx(
input wire clk,
input wire rst,
input wire [DATA_WIDTH-1:0] data,
input wire start,
output logic busy,
output logic txd
);
// Just going to stick to 8N1 for now, we'll come back and
// parameterize this later.
parameter DATA_WIDTH = 8;
parameter CLK_FREQ_HZ = 100_000_000;
parameter BAUDRATE = 115200;
localparam PRESCALER = CLK_FREQ_HZ / BAUDRATE;
logic [$clog2(PRESCALER) - 1:0] baud_counter;
logic [$clog2(DATA_WIDTH + 2):0] bit_index;
logic [DATA_WIDTH - 1:0] data_buf;
// make secondary logic for baudrate
always_ff @(posedge clk) begin
if(rst) baud_counter <= 0;
else begin
baud_counter <= (baud_counter == PRESCALER - 1) ? 0 : baud_counter + 1;
end
end
always_ff @(posedge clk) begin
// reset logic
if(rst) begin
bit_index <= 0;
busy <= 0;
txd <= 1; // idle high
end
// enter transmitting state logic
// don't allow new requests to interrupt current
// transfers
if(start && ~busy) begin
busy <= 1;
data_buf <= data;
end
// transmitting state logic
else if(baud_counter == 0 && busy) begin
if (bit_index == 0) begin
txd <= 0;
bit_index <= bit_index + 1;
end
else if ((bit_index < DATA_WIDTH + 1) && (bit_index > 0)) begin
txd <= data_buf[bit_index - 1];
bit_index <= bit_index + 1;
end
else if (bit_index == DATA_WIDTH + 1) begin
txd <= 1;
bit_index <= bit_index + 1;
end
else if (bit_index >= DATA_WIDTH + 1) begin
busy <= 0;
bit_index <= 0;
end
end
end
endmodule
`default_nettype wire
`default_nettype none
`timescale 1ns / 1ps
module uart_rx(
input wire clk,
input wire rst,
input wire rxd,
output logic [DATA_WIDTH - 1:0] data,
output logic ready,
output logic busy
);
// Just going to stick to 8N1 for now, we'll come back and
// parameterize this later.
parameter DATA_WIDTH = 8;
parameter CLK_FREQ_HZ = 100_000_000;
parameter BAUDRATE = 115200;
localparam PRESCALER = CLK_FREQ_HZ / BAUDRATE;
logic [$clog2(PRESCALER) - 1:0] baud_counter;
logic [$clog2(DATA_WIDTH + 2):0] bit_index;
logic [DATA_WIDTH + 2 : 0] data_buf;
logic prev_rxd;
always_ff @(posedge clk) begin
prev_rxd <= rxd;
ready <= 0;
baud_counter <= (baud_counter == PRESCALER - 1) ? 0 : baud_counter + 1;
// reset logic
if(rst) begin
bit_index <= 0;
data <= 0;
busy <= 0;
baud_counter <= 0;
end
// start receiving if we see a falling edge, and not already busy
else if (prev_rxd && ~rxd && ~busy) begin
busy <= 1;
data_buf <= 0;
baud_counter <= 0;
end
// if we're actually receiving
else if (busy) begin
if (baud_counter == PRESCALER / 2) begin
data_buf[bit_index] <= rxd;
bit_index <= bit_index + 1;
if (bit_index == DATA_WIDTH + 1) begin
busy <= 0;
bit_index <= 0;
if (rxd && ~data_buf[0]) begin
data <= data_buf[DATA_WIDTH : 1];
ready <= 1;
end
end
end
end
end
endmodule
`default_nettype wire
// Xilinx True Dual Port RAM, Read First, Dual Clock
// This code implements a parameterizable true dual port memory (both ports can read and write).
// The behavior of this RAM is when data is written, the prior memory contents at the write
// address are presented on the output port. If the output data is
// not needed during writes or the last read value is desired to be retained,
// it is suggested to use a no change RAM as it is more power efficient.
// If a reset or enable is not necessary, it may be tied off or removed from the code.
module xilinx_true_dual_port_read_first_2_clock_ram #(
parameter RAM_WIDTH = 18, // Specify RAM data width
parameter RAM_DEPTH = 1024, // Specify RAM depth (number of entries)
parameter RAM_PERFORMANCE = "HIGH_PERFORMANCE", // Select "HIGH_PERFORMANCE" or "LOW_LATENCY"
parameter INIT_FILE = "" // Specify name/location of RAM initialization file if using one (leave blank if not)
) (
input [clogb2(RAM_DEPTH-1)-1:0] addra, // Port A address bus, width determined from RAM_DEPTH
input [clogb2(RAM_DEPTH-1)-1:0] addrb, // Port B address bus, width determined from RAM_DEPTH
input [RAM_WIDTH-1:0] dina, // Port A RAM input data
input [RAM_WIDTH-1:0] dinb, // Port B RAM input data
input clka, // Port A clock
input clkb, // Port B clock
input wea, // Port A write enable
input web, // Port B write enable
input ena, // Port A RAM Enable, for additional power savings, disable port when not in use
input enb, // Port B RAM Enable, for additional power savings, disable port when not in use
input rsta, // Port A output reset (does not affect memory contents)
input rstb, // Port B output reset (does not affect memory contents)
input regcea, // Port A output register enable
input regceb, // Port B output register enable
output [RAM_WIDTH-1:0] douta, // Port A RAM output data
output [RAM_WIDTH-1:0] doutb // Port B RAM output data
);
reg [RAM_WIDTH-1:0] BRAM [RAM_DEPTH-1:0];
reg [RAM_WIDTH-1:0] ram_data_a = {RAM_WIDTH{1'b0}};
reg [RAM_WIDTH-1:0] ram_data_b = {RAM_WIDTH{1'b0}};
//this loop below allows for rendering with iverilog simulations!
/*
integer idx;
for(idx = 0; idx < RAM_DEPTH; idx = idx+1) begin: cats
wire [RAM_WIDTH-1:0] tmp;
assign tmp = BRAM[idx];
end
*/
// The following code either initializes the memory values to a specified file or to all zeros to match hardware
generate
if (INIT_FILE != "") begin: use_init_file
initial
$readmemh(INIT_FILE, BRAM, 0, RAM_DEPTH-1);
end else begin: init_bram_to_zero
integer ram_index;
initial
for (ram_index = 0; ram_index < RAM_DEPTH; ram_index = ram_index + 1)
BRAM[ram_index] = {RAM_WIDTH{1'b0}};
end
endgenerate
integer idx;
// initial begin
// for (idx = 0; idx < RAM_DEPTH; idx = idx + 1) begin
// $dumpvars(0, BRAM[idx]);
// end
// end
always @(posedge clka)
if (ena) begin
if (wea)
BRAM[addra] <= dina;
ram_data_a <= BRAM[addra];
end
always @(posedge clkb)
if (enb) begin
if (web)
BRAM[addrb] <= dinb;
ram_data_b <= BRAM[addrb];
end
// The following code generates HIGH_PERFORMANCE (use output register) or LOW_LATENCY (no output register)
generate
if (RAM_PERFORMANCE == "LOW_LATENCY") begin: no_output_register
// The following is a 1 clock cycle read latency at the cost of a longer clock-to-out timing
assign douta = ram_data_a;
assign doutb = ram_data_b;
end else begin: output_register
// The following is a 2 clock cycle read latency with improve clock-to-out timing
reg [RAM_WIDTH-1:0] douta_reg = {RAM_WIDTH{1'b0}};
reg [RAM_WIDTH-1:0] doutb_reg = {RAM_WIDTH{1'b0}};
always @(posedge clka)
if (rsta)
douta_reg <= {RAM_WIDTH{1'b0}};
else if (regcea)
douta_reg <= ram_data_a;
always @(posedge clkb)
if (rstb)
doutb_reg <= {RAM_WIDTH{1'b0}};
else if (regceb)
doutb_reg <= ram_data_b;
assign douta = douta_reg;
assign doutb = doutb_reg;
end
endgenerate
// The following function calculates the address width based on specified RAM depth
function integer clogb2;
input integer depth;
for (clogb2=0; depth>0; clogb2=clogb2+1)
depth = depth >> 1;
endfunction
endmodule
// The following is an instantiation template for xilinx_true_dual_port_read_first_2_clock_ram
/*
// Xilinx True Dual Port RAM, Read First, Dual Clock
xilinx_true_dual_port_read_first_2_clock_ram #(
.RAM_WIDTH(18), // Specify RAM data width
.RAM_DEPTH(1024), // Specify RAM depth (number of entries)
.RAM_PERFORMANCE("HIGH_PERFORMANCE"), // Select "HIGH_PERFORMANCE" or "LOW_LATENCY"
.INIT_FILE("") // Specify name/location of RAM initialization file if using one (leave blank if not)
) your_instance_name (
.addra(addra), // Port A address bus, width determined from RAM_DEPTH
.addrb(addrb), // Port B address bus, width determined from RAM_DEPTH
.dina(dina), // Port A RAM input data, width determined from RAM_WIDTH
.dinb(dinb), // Port B RAM input data, width determined from RAM_WIDTH
.clka(clka), // Port A clock
.clkb(clkb), // Port B clock
.wea(wea), // Port A write enable
.web(web), // Port B write enable
.ena(ena), // Port A RAM Enable, for additional power savings, disable port when not in use
.enb(enb), // Port B RAM Enable, for additional power savings, disable port when not in use
.rsta(rsta), // Port A output reset (does not affect memory contents)
.rstb(rstb), // Port B output reset (does not affect memory contents)
.regcea(regcea), // Port A output register enable
.regceb(regceb), // Port B output register enable
.douta(douta), // Port A RAM output data, width determined from RAM_WIDTH
.doutb(doutb) // Port B RAM output data, width determined from RAM_WIDTH
);
*/

301
examples/sd_card/lab-bc.py Normal file
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,21 @@
---
downlink:
sample_depth: 4096
clock_freq: 100000000
probes:
larry: 1
curly: 1
moe: 1
shemp: 4
triggers:
- larry && curly && ~moe
uart:
baudrate: 115200
port: "/dev/tty.usbserial-2102926963071"
data: 8
parity: none
stop: 1
timeout: 1

View File

@ -0,0 +1,27 @@
`timescale 1ns / 1ps
// Audio PWM module.
module audio_PWM(
input clk, // 100MHz clock.
input reset, // Reset assertion.
input [7:0] music_data, // 8-bit music sample
output reg PWM_out // PWM output. Connect this to ampPWM.
);
reg [7:0] pwm_counter = 8'd0; // counts up to 255 clock cycles per pwm period
always @(posedge clk) begin
if(reset) begin
pwm_counter <= 0;
PWM_out <= 0;
end
else begin
pwm_counter <= pwm_counter + 1;
if(pwm_counter >= music_data) PWM_out <= 0;
else PWM_out <= 1;
end
end
endmodule

View File

@ -0,0 +1,198 @@
// file: sd_clk_gen.v
//
// (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
//----------------------------------------------------------------------------
// None
//
//----------------------------------------------------------------------------
// Output Output Phase Duty Cycle Pk-to-Pk Phase
// Clock Freq (MHz) (degrees) (%) Jitter (ps) Error (ps)
//----------------------------------------------------------------------------
// clk_25mhz__25.00000______0.000______50.0______181.828____104.359
//
//----------------------------------------------------------------------------
// Input Clock Freq (MHz) Input Jitter (UI)
//----------------------------------------------------------------------------
// __primary_________100.000____________0.010
`timescale 1ps/1ps
module sd_clk_gen
(// Clock in ports
// Clock out ports
output clk_25mhz,
input clk_100mhz
);
// Input buffering
//------------------------------------
wire clk_100mhz_sd_clk_gen;
wire clk_in2_sd_clk_gen;
IBUF clkin1_ibufg
(.O (clk_100mhz_sd_clk_gen),
.I (clk_100mhz));
// Clocking PRIMITIVE
//------------------------------------
// Instantiation of the MMCM PRIMITIVE
// * Unused inputs are tied off
// * Unused outputs are labeled unused
wire clk_25mhz_sd_clk_gen;
wire clk_out2_sd_clk_gen;
wire clk_out3_sd_clk_gen;
wire clk_out4_sd_clk_gen;
wire clk_out5_sd_clk_gen;
wire clk_out6_sd_clk_gen;
wire clk_out7_sd_clk_gen;
wire [15:0] do_unused;
wire drdy_unused;
wire psdone_unused;
wire locked_int;
wire clkfbout_sd_clk_gen;
wire clkfbout_buf_sd_clk_gen;
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 (9.125),
.CLKFBOUT_PHASE (0.000),
.CLKFBOUT_USE_FINE_PS ("FALSE"),
.CLKOUT0_DIVIDE_F (36.500),
.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_sd_clk_gen),
.CLKFBOUTB (clkfboutb_unused),
.CLKOUT0 (clk_25mhz_sd_clk_gen),
.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_sd_clk_gen),
.CLKIN1 (clk_100mhz_sd_clk_gen),
.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_sd_clk_gen),
.I (clkfbout_sd_clk_gen));
BUFG clkout1_buf
(.O (clk_25mhz),
.I (clk_25mhz_sd_clk_gen));
endmodule

View File

@ -0,0 +1,276 @@
/* SD Card controller module. Allows reading from and writing to a microSD card
through SPI mode. */
`timescale 1ns / 1ps
module sd_controller(
output reg cs, // Connect to SD_DAT[3].
output mosi, // Connect to SD_CMD.
input miso, // Connect to SD_DAT[0].
output sclk, // Connect to SD_SCK.
// For SPI mode, SD_DAT[2] and SD_DAT[1] should be held HIGH.
// SD_RESET should be held LOW.
input rd, // Read-enable. When [ready] is HIGH, asseting [rd] will
// begin a 512-byte READ operation at [address].
// [byte_available] will transition HIGH as a new byte has been
// read from the SD card. The byte is presented on [dout].
output reg [7:0] dout, // Data output for READ operation.
output reg byte_available, // A new byte has been presented on [dout].
input wr, // Write-enable. When [ready] is HIGH, asserting [wr] will
// begin a 512-byte WRITE operation at [address].
// [ready_for_next_byte] will transition HIGH to request that
// the next byte to be written should be presentaed on [din].
input [7:0] din, // Data input for WRITE operation.
output reg ready_for_next_byte, // A new byte should be presented on [din].
input reset, // Resets controller on assertion.
output ready, // HIGH if the SD card is ready for a read or write operation.
input [31:0] address, // Memory address for read/write operation. This MUST
// be a multiple of 512 bytes, due to SD sectoring.
input clk, // 25 MHz clock.
output [4:0] status // For debug purposes: Current state of controller.
);
parameter RST = 0;
parameter INIT = 1;
parameter CMD0 = 2;
parameter CMD55 = 3;
parameter CMD41 = 4;
parameter POLL_CMD = 5;
parameter IDLE = 6;
parameter READ_BLOCK = 7;
parameter READ_BLOCK_WAIT = 8;
parameter READ_BLOCK_DATA = 9;
parameter READ_BLOCK_CRC = 10;
parameter SEND_CMD = 11;
parameter RECEIVE_BYTE_WAIT = 12;
parameter RECEIVE_BYTE = 13;
parameter WRITE_BLOCK_CMD = 14;
parameter WRITE_BLOCK_INIT = 15;
parameter WRITE_BLOCK_DATA = 16;
parameter WRITE_BLOCK_BYTE = 17;
parameter WRITE_BLOCK_WAIT = 18;
parameter WRITE_DATA_SIZE = 515;
reg [4:0] state = RST;
assign status = state;
reg [4:0] return_state;
reg sclk_sig = 0;
reg [55:0] cmd_out;
reg [7:0] recv_data;
reg cmd_mode = 1;
reg [7:0] data_sig = 8'hFF;
reg [9:0] byte_counter;
reg [9:0] bit_counter;
reg [26:0] boot_counter = 27'd100_000_000;
always @(posedge clk) begin
if(reset == 1) begin
state <= RST;
sclk_sig <= 0;
boot_counter <= 27'd100_000_000;
end
else begin
case(state)
RST: begin
if(boot_counter == 0) begin
sclk_sig <= 0;
cmd_out <= {56{1'b1}};
byte_counter <= 0;
byte_available <= 0;
ready_for_next_byte <= 0;
cmd_mode <= 1;
bit_counter <= 160;
cs <= 1;
state <= INIT;
end
else begin
boot_counter <= boot_counter - 1;
end
end
INIT: begin
if(bit_counter == 0) begin
cs <= 0;
state <= CMD0;
end
else begin
bit_counter <= bit_counter - 1;
sclk_sig <= ~sclk_sig;
end
end
CMD0: begin
cmd_out <= 56'hFF_40_00_00_00_00_95;
bit_counter <= 55;
return_state <= CMD55;
state <= SEND_CMD;
end
CMD55: begin
cmd_out <= 56'hFF_77_00_00_00_00_01;
bit_counter <= 55;
return_state <= CMD41;
state <= SEND_CMD;
end
CMD41: begin
cmd_out <= 56'hFF_69_00_00_00_00_01;
bit_counter <= 55;
return_state <= POLL_CMD;
state <= SEND_CMD;
end
POLL_CMD: begin
if(recv_data[0] == 0) begin
state <= IDLE;
end
else begin
state <= CMD55;
end
end
IDLE: begin
if(rd == 1) begin
state <= READ_BLOCK;
end
else if(wr == 1) begin
state <= WRITE_BLOCK_CMD;
end
else begin
state <= IDLE;
end
end
READ_BLOCK: begin
cmd_out <= {16'hFF_51, address, 8'hFF};
bit_counter <= 55;
return_state <= READ_BLOCK_WAIT;
state <= SEND_CMD;
end
READ_BLOCK_WAIT: begin
if(sclk_sig == 1 && miso == 0) begin
byte_counter <= 511;
bit_counter <= 7;
return_state <= READ_BLOCK_DATA;
state <= RECEIVE_BYTE;
end
sclk_sig <= ~sclk_sig;
end
READ_BLOCK_DATA: begin
dout <= recv_data;
byte_available <= 1;
if (byte_counter == 0) begin
bit_counter <= 7;
return_state <= READ_BLOCK_CRC;
state <= RECEIVE_BYTE;
end
else begin
byte_counter <= byte_counter - 1;
return_state <= READ_BLOCK_DATA;
bit_counter <= 7;
state <= RECEIVE_BYTE;
end
end
READ_BLOCK_CRC: begin
bit_counter <= 7;
return_state <= IDLE;
state <= RECEIVE_BYTE;
end
SEND_CMD: begin
if (sclk_sig == 1) begin
if (bit_counter == 0) begin
state <= RECEIVE_BYTE_WAIT;
end
else begin
bit_counter <= bit_counter - 1;
cmd_out <= {cmd_out[54:0], 1'b1};
end
end
sclk_sig <= ~sclk_sig;
end
RECEIVE_BYTE_WAIT: begin
if (sclk_sig == 1) begin
if (miso == 0) begin
recv_data <= 0;
bit_counter <= 6;
state <= RECEIVE_BYTE;
end
end
sclk_sig <= ~sclk_sig;
end
RECEIVE_BYTE: begin
byte_available <= 0;
if (sclk_sig == 1) begin
recv_data <= {recv_data[6:0], miso};
if (bit_counter == 0) begin
state <= return_state;
end
else begin
bit_counter <= bit_counter - 1;
end
end
sclk_sig <= ~sclk_sig;
end
WRITE_BLOCK_CMD: begin
cmd_out <= {16'hFF_58, address, 8'hFF};
bit_counter <= 55;
return_state <= WRITE_BLOCK_INIT;
state <= SEND_CMD;
ready_for_next_byte <= 1;
end
WRITE_BLOCK_INIT: begin
cmd_mode <= 0;
byte_counter <= WRITE_DATA_SIZE;
state <= WRITE_BLOCK_DATA;
ready_for_next_byte <= 0;
end
WRITE_BLOCK_DATA: begin
if (byte_counter == 0) begin
state <= RECEIVE_BYTE_WAIT;
return_state <= WRITE_BLOCK_WAIT;
end
else begin
if ((byte_counter == 2) || (byte_counter == 1)) begin
data_sig <= 8'hFF;
end
else if (byte_counter == WRITE_DATA_SIZE) begin
data_sig <= 8'hFE;
end
else begin
data_sig <= din;
ready_for_next_byte <= 1;
end
bit_counter <= 7;
state <= WRITE_BLOCK_BYTE;
byte_counter <= byte_counter - 1;
end
end
WRITE_BLOCK_BYTE: begin
if (sclk_sig == 1) begin
if (bit_counter == 0) begin
state <= WRITE_BLOCK_DATA;
ready_for_next_byte <= 0;
end
else begin
data_sig <= {data_sig[6:0], 1'b1};
bit_counter <= bit_counter - 1;
end;
end;
sclk_sig <= ~sclk_sig;
end
WRITE_BLOCK_WAIT: begin
if (sclk_sig == 1) begin
if (miso == 1) begin
state <= IDLE;
cmd_mode <= 1;
end
end
sclk_sig = ~sclk_sig;
end
endcase
end
end
assign sclk = sclk_sig;
assign mosi = cmd_mode ? cmd_out[55] : data_sig[7];
assign ready = (state == IDLE);
endmodule

View File

@ -0,0 +1,56 @@
`timescale 1ns / 1ps
module top_level(
input wire clk,
input wire sd_cd,
input wire btnc,
output logic [15:0] led,
inout [3:0] sd_dat,
output logic sd_reset,
output logic sd_sck,
output logic sd_cmd
);
assign sd_dat[2:1] = 2'b11;
assign sd_reset = 0;
// generate 25 mhz clock for sd_controller
logic clk_25mhz;
sd_clk_gen clk_gen(
.clk_100mhz(clk),
.clk_25mhz(clk_25mhz));
// sd_controller inputs
logic rd; // read enable
logic wr; // write enable
logic [7:0] din; // data to sd card
logic [31:0] addr; // starting address for read/write operation
// sd_controller outputs
logic ready; // high when ready for new read/write operation
logic [7:0] dout; // data from sd card
logic byte_available; // high when byte available for read
logic ready_for_next_byte; // high when ready for new byte to be written
// handles reading from the SD card
sd_controller sd(
.reset(btnc),
.clk(clk_25mhz),
.cs(sd_dat[3]),
.mosi(sd_cmd),
.miso(sd_dat[0]),
.sclk(sd_sck),
.ready(ready),
.address(addr),
.rd(rd),
.dout(dout),
.byte_available(byte_available),
.wr(wr),
.din(din),
.ready_for_next_byte(ready_for_next_byte));
// your Verilog here :)
endmodule

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