import from openILA
This commit is contained in:
parent
e481d13b63
commit
d2bcbe2418
|
|
@ -0,0 +1,2 @@
|
|||
*.vcd
|
||||
*.out
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
{
|
||||
"probes": {
|
||||
"larry" : 1,
|
||||
"curly" : 1,
|
||||
"moe" : 1,
|
||||
"shemp" : 3
|
||||
},
|
||||
|
||||
"triggers": [
|
||||
"larry && curly && ~moe"
|
||||
],
|
||||
|
||||
"uart": {
|
||||
"baudrate" : 115200,
|
||||
"data" : 8,
|
||||
"parity" : "none",
|
||||
"stop" : 1,
|
||||
"port" : "/dev/tty.usbserial-2102926963071",
|
||||
"timeout" : 1
|
||||
},
|
||||
|
||||
"sample_depth": 4096,
|
||||
"output_dir" : "src/ila.svh",
|
||||
"clock_freq" : 100e6
|
||||
}
|
||||
|
|
@ -0,0 +1,243 @@
|
|||
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
|
||||
|
|
@ -0,0 +1,227 @@
|
|||
`default_nettype none
|
||||
`timescale 1ns / 1ps
|
||||
|
||||
/*
|
||||
This ILA was autogenerated on 03/02/2023 23:13:51 by fischerm
|
||||
|
||||
If this breaks or if you've got dank formal verification memes,
|
||||
please contact fischerm [at] mit.edu.
|
||||
*/
|
||||
|
||||
`define IDLE 0
|
||||
`define ARM 1
|
||||
`define FILL 2
|
||||
`define DOWNLINK 3
|
||||
|
||||
`define ARM_BYTE 8'b00110000
|
||||
|
||||
module ila (
|
||||
input wire clk,
|
||||
input wire rst,
|
||||
|
||||
/* Begin autogenerated probe definitions */
|
||||
input wire larry,
|
||||
input wire curly,
|
||||
input wire moe,
|
||||
input wire [2:0] shemp,
|
||||
/* End autogenerated probe definitions */
|
||||
|
||||
input wire rxd,
|
||||
output logic txd);
|
||||
|
||||
/* Begin autogenerated parameters */
|
||||
localparam SAMPLE_WIDTH = 6;
|
||||
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(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
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
`default_nettype none
|
||||
`timescale 1ns / 1ps
|
||||
|
||||
module top_level (
|
||||
input wire clk,
|
||||
input wire btnc,
|
||||
input wire btnu,
|
||||
input wire [15:0] sw,
|
||||
|
||||
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;
|
||||
|
||||
// ILA
|
||||
// later make this a #ILA that gets loaded from a svh file that the python script generates
|
||||
ila ila(
|
||||
.clk(clk),
|
||||
.rst(btnc),
|
||||
.larry(count[0]),
|
||||
.curly(count[1]),
|
||||
.moe(count[2]),
|
||||
.shemp(count[5:3]),
|
||||
|
||||
.rxd(uart_txd_in),
|
||||
.txd(uart_rxd_out));
|
||||
|
||||
endmodule
|
||||
|
||||
`default_nettype wire
|
||||
|
|
@ -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
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,72 @@
|
|||
import json
|
||||
from datetime import datetime
|
||||
import os
|
||||
|
||||
# this works by taking a template file, parsing it for hooks, and then dropping in our spicy bits of verilog in those hooks.
|
||||
# might update this later to just properly instantiate an ILA for us and we do this with parameters, but
|
||||
# the fundamental thing i care about is that systemverilog does not live in this file.
|
||||
|
||||
fpath = 'ila.json' # will update for argv soon!
|
||||
|
||||
with open(fpath, 'r') as f:
|
||||
config = json.load(f)
|
||||
|
||||
# make sure file is okay
|
||||
assert config["probes"]
|
||||
assert config["triggers"]
|
||||
assert config["uart"] or config["ethernet"] # <- i have ideas hehe
|
||||
|
||||
def splice(source, find, replace):
|
||||
# find all instances of find in the source, and replace with replace
|
||||
#assert source.count(find) == 1
|
||||
return source.replace(find, replace)
|
||||
|
||||
|
||||
with open('src/ila_template.sv', 'r') as t:
|
||||
ila_template = t.read()
|
||||
|
||||
# add timestamp and user
|
||||
timestamp = datetime.now().strftime("%d/%m/%Y %H:%M:%S")
|
||||
ila_template = splice(ila_template, '@TIMESTAMP', timestamp);
|
||||
|
||||
user = os.environ.get('USER', os.environ.get('USERNAME'))
|
||||
ila_template = splice(ila_template, '@USER', user);
|
||||
|
||||
# add trigger
|
||||
trigger = [f'({trigger})' for trigger in config['triggers']]
|
||||
trigger = ' || '.join(trigger)
|
||||
ila_template = splice(ila_template, '@TRIGGER', trigger);
|
||||
|
||||
# add concat
|
||||
concat = [name for name in config['probes']]
|
||||
concat = ', '.join(concat)
|
||||
concat = '{' + concat + '};'
|
||||
ila_template = splice(ila_template, '@CONCAT', concat);
|
||||
|
||||
|
||||
|
||||
# add probes to ila module definition
|
||||
probe_verilog = []
|
||||
for name, width in config['probes'].items():
|
||||
if width == 1:
|
||||
probe_verilog.append(f'input wire {name},')
|
||||
|
||||
else:
|
||||
probe_verilog.append(f'input wire [{width-1}:0] {name},')
|
||||
|
||||
probe_verilog = '\n\t'.join(probe_verilog)
|
||||
ila_template = splice(ila_template, '@PROBES', probe_verilog);
|
||||
|
||||
# add sample width and depth
|
||||
sample_width = sum([width for name, width in config['probes'].items()])
|
||||
ila_template = splice(ila_template, '@SAMPLE_WIDTH', str(sample_width))
|
||||
ila_template = splice(ila_template, '@SAMPLE_DEPTH', str(config['sample_depth']));
|
||||
|
||||
# add UART configuration
|
||||
ila_template = splice(ila_template, '@DATA_WIDTH', str(int(config['uart']['data'])));
|
||||
ila_template = splice(ila_template, '@BAUDRATE', str(config['uart']['baudrate']));
|
||||
ila_template = splice(ila_template, '@CLK_FREQ_HZ', str(int(config['clock_freq'])));
|
||||
|
||||
# write output file
|
||||
with open('src/ila.sv', 'w') as i:
|
||||
i.write(ila_template)
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
logo = """
|
||||
(\.-./)
|
||||
/ \\
|
||||
.' : '.
|
||||
_.-'` ' `'-._ | Manta 0.0.1
|
||||
.-' : '-. | An In-Situ Debugging Tool for Programmable Hardware
|
||||
,'_.._ . _.._', | https://github.com/fischermoseley/manta
|
||||
'` `'-. ' .-'` `'
|
||||
'. : .' | fischerm@mit.edu
|
||||
\_. ._/
|
||||
\ |^|
|
||||
| | ;
|
||||
\'.___.' /
|
||||
'-....-' """
|
||||
|
||||
print(logo)
|
||||
|
|
@ -0,0 +1,159 @@
|
|||
from sys import argv
|
||||
import json
|
||||
import serial
|
||||
from vcd import VCDWriter
|
||||
from datetime import datetime
|
||||
|
||||
def check_config(config):
|
||||
"""Check that configuration is okay"""
|
||||
assert config["probes"]
|
||||
assert config["triggers"]
|
||||
assert config["uart"]
|
||||
|
||||
def setup_serial(ser, config):
|
||||
ser.baudrate = config['uart']['baudrate']
|
||||
ser.port = config['uart']['port']
|
||||
ser.timeout = config['uart']['timeout']
|
||||
|
||||
# setup number of data bits
|
||||
if config['uart']['data'] == 8:
|
||||
ser.bytesize = serial.EIGHTBITS
|
||||
|
||||
elif config['uart']['data'] == 7:
|
||||
ser.bytesize = serial.SEVENBITS
|
||||
|
||||
elif config['uart']['data'] == 6:
|
||||
ser.bytesize = serial.SIXBITS
|
||||
|
||||
elif config['uart']['data'] == 5:
|
||||
ser.bytesize = serial.FIVEBITS
|
||||
|
||||
else:
|
||||
raise ValueError("Invalid number of data bits in UART configuration.")
|
||||
|
||||
# setup number of stop bits
|
||||
if config['uart']['stop'] == 1:
|
||||
ser.stopbits = serial.STOPBITS_ONE
|
||||
|
||||
elif config['uart']['stop'] == 1.5:
|
||||
ser.stopbits = serial.STOPBITS_ONE_POINT_FIVE
|
||||
|
||||
elif config['uart']['stop'] == 2:
|
||||
ser.stopbits = serial.STOPBITS_TWO
|
||||
|
||||
else:
|
||||
raise ValueError("Invalid number of stop bits in UART configuration.")
|
||||
|
||||
# setup parity
|
||||
if config['uart']['parity'] == 'none':
|
||||
ser.parity = serial.PARITY_NONE
|
||||
|
||||
elif config['uart']['parity'] == 'even':
|
||||
ser.parity = serial.PARITY_EVEN
|
||||
|
||||
elif config['uart']['parity'] == 'odd':
|
||||
ser.parity = serial.PARITY_ODD
|
||||
|
||||
elif config['uart']['parity'] == 'mark':
|
||||
ser.parity = serial.PARITY_MARK
|
||||
|
||||
elif config['uart']['parity'] == 'space':
|
||||
ser.parity = serial.PARITY_SPACE
|
||||
|
||||
else:
|
||||
raise ValueError("Invalid parity setting in UART configuration.")
|
||||
|
||||
def part_select(data, width):
|
||||
top, bottom = width
|
||||
|
||||
assert top >= bottom
|
||||
|
||||
mask = 2**(top - bottom + 1) - 1
|
||||
return (data >> bottom) & mask
|
||||
|
||||
def make_widths(config):
|
||||
# {probe0, probe1, probe2}
|
||||
# [12, 1, 3] should produce
|
||||
# [ (11,0) , (12, 12), (15,13) ]
|
||||
|
||||
widths = list(config['probes'].values())
|
||||
|
||||
parts = []
|
||||
for i, width in enumerate(widths):
|
||||
if (i == 0):
|
||||
parts.append( (width - 1, 0) )
|
||||
|
||||
else:
|
||||
parts.append( ((parts[i-1][1] + width) , (parts[i-1][1] + 1)) )
|
||||
|
||||
# reversing this list is a little bit of a hack, should fix/document
|
||||
return parts[::-1]
|
||||
|
||||
|
||||
## Main Program
|
||||
|
||||
# parse args
|
||||
if len(argv) == 1 or argv[1] == '-h':
|
||||
print("""
|
||||
run_ila.py: interface with the ILA on the FPGA, setting triggers and downlinking waveform data.
|
||||
usage: python3 run_ila.py [config input file] [vcd output file]
|
||||
options:
|
||||
-h: print this help menu
|
||||
-l: list all available serial devices
|
||||
|
||||
example: python3 run_ila.py ila.json ila.vcd
|
||||
""")
|
||||
exit()
|
||||
|
||||
elif argv[1] == '-l':
|
||||
import serial.tools.list_ports
|
||||
|
||||
for info in serial.tools.list_ports.comports():
|
||||
print(info)
|
||||
|
||||
elif len(argv) == 2:
|
||||
config_fpath = argv[1]
|
||||
vcd_fpath = 'ila.vcd'
|
||||
|
||||
|
||||
elif len(argv) == 3:
|
||||
config_fpath = argv[1]
|
||||
vcd_fpath = argv[2]
|
||||
|
||||
else:
|
||||
exit()
|
||||
|
||||
# read config
|
||||
with open(config_fpath, 'r') as f:
|
||||
config = json.load(f)
|
||||
|
||||
# obtain bytestream from FPGA
|
||||
with serial.Serial() as ser:
|
||||
setup_serial(ser, config)
|
||||
ser.open()
|
||||
ser.flushInput()
|
||||
ser.write(b'\x30')
|
||||
data = ser.read(4096)
|
||||
|
||||
# export VCD
|
||||
vcd_file = open(vcd_fpath, 'w')
|
||||
timestamp = datetime.now().strftime("%d/%m/%Y %H:%M:%S")
|
||||
|
||||
with VCDWriter(vcd_file, timescale='10 ns', date=timestamp, version = 'openILA') as writer:
|
||||
|
||||
# add probes to vcd file
|
||||
vcd_probes = []
|
||||
for name, width in config['probes'].items():
|
||||
probe = writer.register_var('ila', name, 'wire', size = width)
|
||||
vcd_probes.append(probe)
|
||||
|
||||
# calculate bit widths for part selecting
|
||||
widths = make_widths(config)
|
||||
|
||||
# slice data, and dump to vcd file
|
||||
for timestamp, value in enumerate(data):
|
||||
for probe_num, probe in enumerate(vcd_probes):
|
||||
val = part_select(value, widths[probe_num])
|
||||
writer.change(probe, timestamp, val)
|
||||
|
||||
vcd_file.close()
|
||||
|
|
@ -0,0 +1,84 @@
|
|||
`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
|
||||
|
|
@ -0,0 +1,224 @@
|
|||
`default_nettype none
|
||||
`timescale 1ns / 1ps
|
||||
|
||||
/*
|
||||
This ILA was autogenerated on @TIMESTAMP by @USER
|
||||
|
||||
If this breaks or if you've got dank formal verification memes,
|
||||
please contact fischerm [at] mit.edu.
|
||||
*/
|
||||
|
||||
`define IDLE 0
|
||||
`define ARM 1
|
||||
`define FILL 2
|
||||
`define DOWNLINK 3
|
||||
|
||||
`define ARM_BYTE 8'b00110000
|
||||
|
||||
module ila (
|
||||
input wire clk,
|
||||
input wire rst,
|
||||
|
||||
/* Begin autogenerated probe definitions */
|
||||
@PROBES
|
||||
/* End autogenerated probe definitions */
|
||||
|
||||
input wire rxd,
|
||||
output logic txd);
|
||||
|
||||
/* Begin autogenerated parameters */
|
||||
localparam SAMPLE_WIDTH = @SAMPLE_WIDTH;
|
||||
localparam SAMPLE_DEPTH = @SAMPLE_DEPTH;
|
||||
|
||||
localparam DATA_WIDTH = @DATA_WIDTH;
|
||||
localparam BAUDRATE = @BAUDRATE;
|
||||
localparam CLK_FREQ_HZ = @CLK_FREQ_HZ;
|
||||
|
||||
logic trigger;
|
||||
assign trigger = @TRIGGER;
|
||||
|
||||
logic [SAMPLE_WIDTH - 1 : 0] concat;
|
||||
assign concat = @CONCAT;
|
||||
/* 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(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
|
||||
|
|
@ -0,0 +1,72 @@
|
|||
`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
|
||||
|
|
@ -0,0 +1,81 @@
|
|||
`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
|
||||
|
|
@ -0,0 +1,149 @@
|
|||
|
||||
// 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
|
||||
);
|
||||
*/
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,71 @@
|
|||
`default_nettype none
|
||||
|
||||
`timescale 1ns / 1ps
|
||||
|
||||
module fifo_tb();
|
||||
logic clk;
|
||||
logic rst;
|
||||
|
||||
logic [7:0] data_in;
|
||||
logic input_ready;
|
||||
|
||||
logic request_output;
|
||||
logic [7:0] data_out;
|
||||
|
||||
logic [11:0] size;
|
||||
logic empty;
|
||||
logic full;
|
||||
|
||||
fifo uut (
|
||||
.clk(clk),
|
||||
.rst(rst),
|
||||
|
||||
.data_in(data_in),
|
||||
.input_ready(input_ready),
|
||||
|
||||
.request_output(request_output),
|
||||
.data_out(data_out),
|
||||
|
||||
.size(size),
|
||||
.empty(empty),
|
||||
.full(full));
|
||||
|
||||
always begin
|
||||
#5;
|
||||
clk = !clk;
|
||||
end
|
||||
|
||||
initial begin
|
||||
$dumpfile("fifo.vcd");
|
||||
$dumpvars(0, fifo_tb);
|
||||
clk = 0;
|
||||
rst = 1;
|
||||
data_in = 0;
|
||||
input_ready = 0;
|
||||
request_output = 0;
|
||||
#10;
|
||||
rst = 0;
|
||||
#10;
|
||||
|
||||
// try and load some data, make sure counter increases
|
||||
input_ready = 1;
|
||||
|
||||
for(int i=0; i < 4097; i++) begin
|
||||
data_in = i;
|
||||
#10;
|
||||
end
|
||||
|
||||
input_ready = 0;
|
||||
|
||||
// try and read out said data
|
||||
request_output = 1;
|
||||
for(int i=0; i < 4097; i++) begin
|
||||
$display("%h", data_out);
|
||||
#10;
|
||||
end
|
||||
|
||||
$finish();
|
||||
end
|
||||
endmodule
|
||||
|
||||
`default_nettype wire
|
||||
|
|
@ -0,0 +1,69 @@
|
|||
`default_nettype none
|
||||
`timescale 1ns / 1ps
|
||||
|
||||
module ila_tb();
|
||||
logic clk;
|
||||
logic rst;
|
||||
logic rxd;
|
||||
logic txd;
|
||||
|
||||
|
||||
logic probe0, probe1, probe2;
|
||||
assign probe0 = count[0];
|
||||
assign probe1 = count[1];
|
||||
assign probe2 = count[2];
|
||||
|
||||
// ILA
|
||||
// later make this a `ILA that gets loaded from a svh file that the python script generates
|
||||
ila #(.FIFO_DEPTH(64)) ila(
|
||||
.clk(clk),
|
||||
.rst(rst),
|
||||
.probe0(probe0),
|
||||
.probe1(probe1),
|
||||
.probe2(probe2),
|
||||
|
||||
.rxd(rxd),
|
||||
.txd(txd));
|
||||
|
||||
/* Signal Generator */
|
||||
logic [7:0] count = 0;
|
||||
always begin
|
||||
count = count + 1;
|
||||
#10;
|
||||
end
|
||||
|
||||
always begin
|
||||
#5;
|
||||
clk = !clk;
|
||||
end
|
||||
|
||||
logic [9:0] uart_data;
|
||||
|
||||
initial begin
|
||||
$dumpfile("ila.vcd");
|
||||
$dumpvars(0, ila_tb);
|
||||
clk = 0;
|
||||
rst = 1;
|
||||
rxd = 1;
|
||||
uart_data = 0;
|
||||
#10;
|
||||
rst = 0;
|
||||
|
||||
// Wait a little bit to make sure that it doesn't like, explode or something
|
||||
#1000;
|
||||
|
||||
// send arm byte!
|
||||
uart_data = {1'b1, 8'b00110000, 1'b0};
|
||||
for (int i=0; i < 10; i++) begin
|
||||
rxd = uart_data[i];
|
||||
#8680;
|
||||
end
|
||||
|
||||
// see what happens lmao
|
||||
#15000000;
|
||||
|
||||
$finish();
|
||||
end
|
||||
endmodule
|
||||
|
||||
`default_nettype wire
|
||||
|
|
@ -0,0 +1,72 @@
|
|||
`default_nettype none
|
||||
|
||||
`timescale 1ns / 1ps
|
||||
|
||||
module uart_tb();
|
||||
logic clk;
|
||||
logic rst;
|
||||
logic [7:0] tx_data, rx_data;
|
||||
logic tx_start, rx_ready;
|
||||
logic tx_busy, rx_busy;
|
||||
logic txd;
|
||||
|
||||
|
||||
uart_tx #(
|
||||
.DATA_WIDTH(8),
|
||||
.CLK_FREQ_HZ(100_000_000),
|
||||
.BAUDRATE(115200))
|
||||
tx (
|
||||
.clk(clk),
|
||||
.rst(rst),
|
||||
.data(tx_data),
|
||||
.start(tx_start),
|
||||
|
||||
.busy(tx_busy),
|
||||
.txd(txd));
|
||||
|
||||
|
||||
uart_rx #(
|
||||
.DATA_WIDTH(8),
|
||||
.CLK_FREQ_HZ(100_000_000),
|
||||
.BAUDRATE(115200))
|
||||
rx (
|
||||
.clk(clk),
|
||||
.rst(rst),
|
||||
.rxd(txd),
|
||||
|
||||
.data(rx_data),
|
||||
.ready(rx_ready),
|
||||
.busy(rx_busy));
|
||||
|
||||
always begin
|
||||
#5;
|
||||
clk = !clk;
|
||||
end
|
||||
|
||||
initial begin
|
||||
$dumpfile("uart.vcd");
|
||||
$dumpvars(0, uart_tb);
|
||||
clk = 0;
|
||||
rst = 1;
|
||||
tx_data = 'h0F;
|
||||
tx_start = 0;
|
||||
#10;
|
||||
rst = 0;
|
||||
#10;
|
||||
tx_start = 1;
|
||||
#10;
|
||||
tx_start = 0;
|
||||
#150000;
|
||||
|
||||
// send another byte!
|
||||
tx_data = 'hBE;
|
||||
tx_start = 1;
|
||||
#10;
|
||||
tx_start = 0;
|
||||
#150000;
|
||||
|
||||
$finish();
|
||||
end
|
||||
endmodule
|
||||
|
||||
`default_nettype wire
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
`default_nettype none
|
||||
|
||||
`timescale 1ns / 1ps
|
||||
|
||||
module uart_tx_tb();
|
||||
logic clk;
|
||||
logic rst;
|
||||
logic [7:0] data;
|
||||
logic start;
|
||||
logic busy;
|
||||
logic txd;
|
||||
|
||||
|
||||
uart_tx #(
|
||||
.DATA_WIDTH(8),
|
||||
.CLK_FREQ_HZ(100_000_000),
|
||||
.BAUDRATE(115200))
|
||||
uut (
|
||||
.clk(clk),
|
||||
.rst(rst),
|
||||
.data(data),
|
||||
.start(start),
|
||||
|
||||
.busy(busy),
|
||||
.txd(txd));
|
||||
|
||||
always begin
|
||||
#5;
|
||||
clk = !clk;
|
||||
end
|
||||
|
||||
initial begin
|
||||
$dumpfile("uart_tx.vcd");
|
||||
$dumpvars(0, uart_tx_tb);
|
||||
clk = 0;
|
||||
rst = 1;
|
||||
start = 0;
|
||||
#10;
|
||||
rst = 0;
|
||||
data = 'h0F;
|
||||
#10;
|
||||
start = 1;
|
||||
#10;
|
||||
start = 0;
|
||||
#150000;
|
||||
$finish();
|
||||
end
|
||||
endmodule
|
||||
|
||||
`default_nettype wire
|
||||
Loading…
Reference in New Issue