tidy examples
This commit is contained in:
parent
7cd8a2cfa5
commit
7f9012b542
|
|
@ -1,301 +0,0 @@
|
|||
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
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
---
|
||||
cores:
|
||||
my_lut_ram:
|
||||
type: lut_ram
|
||||
size: 64
|
||||
|
||||
uart:
|
||||
port: "auto"
|
||||
baudrate: 115200
|
||||
clock_freq: 100000000
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
from manta import Manta
|
||||
from random import randint
|
||||
|
||||
m = Manta('manta.yaml')
|
||||
|
||||
for addr in range(m.my_lut_ram.size):
|
||||
write_data = randint(0, (2**16)-1)
|
||||
m.my_lut_ram.write(addr, write_data)
|
||||
|
||||
read_data = m.my_lut_ram.read(addr)
|
||||
print(f"test addr: {addr} with data: {write_data}")
|
||||
print(f" -> correct data received on readback?: {write_data == read_data}")
|
||||
|
|
@ -1,169 +0,0 @@
|
|||
`default_nettype none
|
||||
`timescale 1ns/1ps
|
||||
|
||||
module bram_core (
|
||||
input wire clk,
|
||||
|
||||
// input port
|
||||
input wire [15:0] addr_i,
|
||||
input wire [15:0] wdata_i,
|
||||
input wire [15:0] rdata_i,
|
||||
input wire rw_i,
|
||||
input wire valid_i,
|
||||
|
||||
// output port
|
||||
output reg [15:0] addr_o,
|
||||
output reg [15:0] wdata_o,
|
||||
output reg [15:0] rdata_o,
|
||||
output reg rw_o,
|
||||
output reg valid_o,
|
||||
|
||||
// BRAM itself
|
||||
input wire bram_clk,
|
||||
input wire [ADDR_WIDTH-1:0] addr,
|
||||
input wire [BRAM_WIDTH-1:0] din,
|
||||
output reg [BRAM_WIDTH-1:0] dout,
|
||||
input wire we);
|
||||
|
||||
parameter BASE_ADDR = 0;
|
||||
|
||||
|
||||
// for now, let's pretend that this bram has a width of 33, and a depth of 256
|
||||
// parameter BRAM_WIDTH = 0;
|
||||
// parameter BRAM_DEPTH = 0;
|
||||
parameter BRAM_WIDTH = 18;
|
||||
parameter BRAM_DEPTH = 256;
|
||||
localparam ADDR_WIDTH = $clog2(BRAM_DEPTH);
|
||||
|
||||
// Bus-Controlled side of BRAMs
|
||||
reg [ADDR_WIDTH-1:0] addra_0 = 0;
|
||||
reg [15:0] dina_0 = 0;
|
||||
reg [15:0] douta_0;
|
||||
reg wea_0 = 0;
|
||||
|
||||
reg [ADDR_WIDTH-1:0] addra_1 = 0;
|
||||
reg [1:0] dina_1 = 0;
|
||||
reg [1:0] douta_1;
|
||||
reg wea_1 = 0;
|
||||
|
||||
// Pipelining
|
||||
reg [3:0][15:0] addr_pipe = 0;
|
||||
reg [3:0][15:0] wdata_pipe = 0;
|
||||
reg [3:0][15:0] rdata_pipe = 0;
|
||||
reg [3:0] valid_pipe = 0;
|
||||
reg [3:0] rw_pipe = 0;
|
||||
|
||||
always @(posedge clk) begin
|
||||
addr_pipe[0] <= addr_i;
|
||||
wdata_pipe[0] <= wdata_i;
|
||||
rdata_pipe[0] <= rdata_i;
|
||||
valid_pipe[0] <= valid_i;
|
||||
rw_pipe[0] <= rw_i;
|
||||
|
||||
addr_o <= addr_pipe[3];
|
||||
wdata_o <= wdata_pipe[3];
|
||||
rdata_o <= rdata_pipe[3];
|
||||
valid_o <= valid_pipe[3];
|
||||
rw_o <= rw_pipe[3];
|
||||
|
||||
for(int i=1; i<4; i=i+1) begin
|
||||
addr_pipe[i] <= addr_pipe[i-1];
|
||||
wdata_pipe[i] <= wdata_pipe[i-1];
|
||||
rdata_pipe[i] <= rdata_pipe[i-1];
|
||||
valid_pipe[i] <= valid_pipe[i-1];
|
||||
rw_pipe[i] <= rw_pipe[i-1];
|
||||
end
|
||||
|
||||
|
||||
|
||||
wea_0 <= 0;
|
||||
wea_1 <= 0;
|
||||
|
||||
// put re
|
||||
if( (valid_i) && (addr_i >= BASE_ADDR) && (addr_i <= BASE_ADDR + (2 * BRAM_DEPTH))) begin
|
||||
// compute correct bram to talk to
|
||||
case (addr_i % 2)
|
||||
0: begin
|
||||
wea_0 <= rw_i;
|
||||
addra_0 <= (addr_i - BASE_ADDR) / 2;
|
||||
dina_0 <= wdata_i;
|
||||
rdata_o <= douta_0;
|
||||
end
|
||||
|
||||
1: begin
|
||||
wea_1 <= rw_i;
|
||||
addra_1 <= (addr_i - BASE_ADDR) / 2;
|
||||
dina_1 <= wdata_i[1:0];
|
||||
rdata_o <= {14'b0, douta_1};
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
||||
if( (valid_pipe[3]) && (addr_pipe[3] >= BASE_ADDR) && (addr_pipe[3] <= BASE_ADDR + (2 * BRAM_DEPTH))) begin
|
||||
// compute correct bram to talk to
|
||||
case (addr_pipe[3] % 2)
|
||||
0: begin
|
||||
rdata_o <= douta_0;
|
||||
end
|
||||
|
||||
1: begin
|
||||
rdata_o <= {14'b0, douta_1};
|
||||
end
|
||||
endcase
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
// User-Controlled Side of BRAMs
|
||||
reg [15:0] dinb_0;
|
||||
reg [15:0] doutb_0;
|
||||
reg [1:0] dinb_1;
|
||||
reg [1:0] doutb_1;
|
||||
|
||||
assign dinb_0 = din[15:0];
|
||||
assign dinb_1 = din[17:16];
|
||||
assign dout = {doutb_1, doutb_0};
|
||||
|
||||
dual_port_bram #(
|
||||
.RAM_WIDTH(16),
|
||||
.RAM_DEPTH(BRAM_DEPTH)
|
||||
) bram_0 (
|
||||
|
||||
// port A is controlled by the bus
|
||||
.clka(clk),
|
||||
.addra(addra_0),
|
||||
.dina(dina_0),
|
||||
.douta(douta_0),
|
||||
.wea(wea_0),
|
||||
|
||||
// port B is exposed to the user
|
||||
.clkb(bram_clk),
|
||||
.addrb(addr),
|
||||
.dinb(dinb_0),
|
||||
.doutb(doutb_0),
|
||||
.web(we));
|
||||
|
||||
dual_port_bram #(
|
||||
.RAM_WIDTH(2),
|
||||
.RAM_DEPTH(BRAM_DEPTH)
|
||||
) bram_1 (
|
||||
|
||||
// port A is controlled by the bus
|
||||
.clka(clk),
|
||||
.addra(addra_1),
|
||||
.dina(dina_1),
|
||||
.douta(douta_1),
|
||||
.wea(wea_1),
|
||||
|
||||
// port B is exposed to the user
|
||||
.clkb(bram_clk),
|
||||
.addrb(addr),
|
||||
.dinb(dinb_1),
|
||||
.doutb(doutb_1),
|
||||
.web(we));
|
||||
|
||||
|
||||
endmodule
|
||||
`default_nettype wire
|
||||
|
|
@ -1,60 +0,0 @@
|
|||
|
||||
// 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.
|
||||
|
||||
// Modified from the xilinx_true_dual_port_read_first_2_clock_ram verilog language template.
|
||||
|
||||
module dual_port_bram #(
|
||||
parameter RAM_WIDTH = 0,
|
||||
parameter RAM_DEPTH = 0
|
||||
) (
|
||||
input wire [$clog2(RAM_DEPTH-1)-1:0] addra,
|
||||
input wire [$clog2(RAM_DEPTH-1)-1:0] addrb,
|
||||
input wire [RAM_WIDTH-1:0] dina,
|
||||
input wire [RAM_WIDTH-1:0] dinb,
|
||||
input wire clka,
|
||||
input wire clkb,
|
||||
input wire wea,
|
||||
input wire web,
|
||||
output wire [RAM_WIDTH-1:0] douta,
|
||||
output wire [RAM_WIDTH-1:0] doutb
|
||||
);
|
||||
|
||||
// The following code either initializes the memory values to a specified file or to all zeros to match hardware
|
||||
generate
|
||||
integer i;
|
||||
initial begin
|
||||
for (i = 0; i < RAM_DEPTH; i = i + 1)
|
||||
BRAM[i] = {RAM_WIDTH{1'b0}};
|
||||
end
|
||||
endgenerate
|
||||
|
||||
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}};
|
||||
|
||||
always @(posedge clka) begin
|
||||
if (wea) BRAM[addra] <= dina;
|
||||
ram_data_a <= BRAM[addra];
|
||||
end
|
||||
|
||||
always @(posedge clkb) begin
|
||||
if (web) BRAM[addrb] <= dinb;
|
||||
ram_data_b <= BRAM[addrb];
|
||||
end
|
||||
|
||||
// Add a 2 clock cycle read latency to 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) douta_reg <= ram_data_a;
|
||||
always @(posedge clkb) doutb_reg <= ram_data_b;
|
||||
|
||||
assign douta = douta_reg;
|
||||
assign doutb = doutb_reg;
|
||||
endmodule
|
||||
|
|
@ -1,85 +0,0 @@
|
|||
module ssd(
|
||||
input wire clk_in,
|
||||
input wire rst_in,
|
||||
input wire [31:0] val_in,
|
||||
output reg[6:0] cat_out,
|
||||
output reg[7:0] an_out);
|
||||
|
||||
parameter COUNT_TO = 100000;
|
||||
logic[7:0] segment_state;
|
||||
logic[31:0] segment_counter;
|
||||
logic [3:0] routed_vals;
|
||||
logic [6:0] led_out;
|
||||
|
||||
bto7s mbto7s (.x_in(routed_vals), .s_out(led_out));
|
||||
|
||||
assign cat_out = ~led_out;
|
||||
assign an_out = ~segment_state;
|
||||
|
||||
always @(*) begin
|
||||
case(segment_state)
|
||||
8'b0000_0001: routed_vals = val_in[3:0];
|
||||
8'b0000_0010: routed_vals = val_in[7:4];
|
||||
8'b0000_0100: routed_vals = val_in[11:8];
|
||||
8'b0000_1000: routed_vals = val_in[15:12];
|
||||
8'b0001_0000: routed_vals = val_in[19:16];
|
||||
8'b0010_0000: routed_vals = val_in[23:20];
|
||||
8'b0100_0000: routed_vals = val_in[27:24];
|
||||
8'b1000_0000: routed_vals = val_in[31:28];
|
||||
default: routed_vals = val_in[3:0];
|
||||
endcase
|
||||
end
|
||||
|
||||
always @(posedge clk_in) begin
|
||||
if (rst_in) begin
|
||||
segment_state <= 8'b0000_0001;
|
||||
segment_counter <= 32'b0;
|
||||
end
|
||||
|
||||
else begin
|
||||
if (segment_counter == COUNT_TO) begin
|
||||
segment_counter <= 32'd0;
|
||||
segment_state <= {segment_state[6:0],segment_state[7]};
|
||||
end else begin
|
||||
segment_counter <= segment_counter +1;
|
||||
end
|
||||
end
|
||||
end
|
||||
endmodule
|
||||
|
||||
|
||||
module bto7s(
|
||||
input wire [3:0] x_in,
|
||||
output reg [6:0] s_out);
|
||||
|
||||
reg sa, sb, sc, sd, se, sf, sg;
|
||||
assign s_out = {sg, sf, se, sd, sc, sb, sa};
|
||||
|
||||
// array of bits that are "one hot" with numbers 0 through 15
|
||||
reg [15:0] num;
|
||||
|
||||
assign num[0] = ~x_in[3] && ~x_in[2] && ~x_in[1] && ~x_in[0];
|
||||
assign num[1] = ~x_in[3] && ~x_in[2] && ~x_in[1] && x_in[0];
|
||||
assign num[2] = x_in == 4'd2;
|
||||
assign num[3] = x_in == 4'd3;
|
||||
assign num[4] = x_in == 4'd4;
|
||||
assign num[5] = x_in == 4'd5;
|
||||
assign num[6] = x_in == 4'd6;
|
||||
assign num[7] = x_in == 4'd7;
|
||||
assign num[8] = x_in == 4'd8;
|
||||
assign num[9] = x_in == 4'd9;
|
||||
assign num[10] = x_in == 4'd10;
|
||||
assign num[11] = x_in == 4'd11;
|
||||
assign num[12] = x_in == 4'd12;
|
||||
assign num[13] = x_in == 4'd13;
|
||||
assign num[14] = x_in == 4'd14;
|
||||
assign num[15] = x_in == 4'd15;
|
||||
|
||||
assign sa = num[0] || num[2] || num[3] || num[5] || num[6] || num[7] || num[8] || num[9] || num[10] || num[12] ||num[14] ||num[15];
|
||||
assign sb = num[0] || num[1] || num[2] || num[3] || num[4] || num[7] || num[8] || num[9] || num[10] || num[13];
|
||||
assign sc = num[0] || num[1] || num[3] || num[4] || num[5] || num[6] || num[7] || num[8] || num[9] || num[10] || num[11] || num[13];
|
||||
assign sd = num[0] || num[2] || num[3] || num[5] || num[6] || num[8] || num[9] || num[11] || num[12] || num[13] || num[14];
|
||||
assign se = num[0] || num[2] || num[6] || num[8] || num[10] || num[11] || num[12] || num[13] || num[14] || num[15];
|
||||
assign sf = num[0] || num[4] || num[5] || num[6] || num[8] || num[9] || num[10] || num[11] || num[12] || num[14] || num[15];
|
||||
assign sg = num[2] || num[3] || num[4] || num[5] || num[6] || num[8] || num[9] || num[10] || num[11] || num[13] || num[14] ||num[15];
|
||||
endmodule
|
||||
|
|
@ -1,35 +0,0 @@
|
|||
`default_nettype none
|
||||
`timescale 1ns / 1ps
|
||||
|
||||
module top_level (
|
||||
input wire clk,
|
||||
input wire btnc,
|
||||
|
||||
output logic [15:0] led,
|
||||
output logic ca, cb, cc, cd, ce, cf, cg,
|
||||
output logic [7:0] an,
|
||||
|
||||
input wire uart_txd_in,
|
||||
output logic uart_rxd_out
|
||||
);
|
||||
|
||||
manta manta_inst (
|
||||
.clk(clk),
|
||||
|
||||
.rx(uart_txd_in),
|
||||
.tx(uart_rxd_out));
|
||||
|
||||
assign led = manta_inst.brx_my_bram_core_addr;
|
||||
|
||||
logic [6:0] cat;
|
||||
assign {cg,cf,ce,cd,cc,cb,ca} = cat;
|
||||
ssd ssd (
|
||||
.clk_in(clk),
|
||||
.rst_in(btnc),
|
||||
.val_in( {manta_inst.my_bram_core_btx_rdata, manta_inst.brx_my_bram_core_wdata} ),
|
||||
.cat_out(cat),
|
||||
.an_out(an));
|
||||
|
||||
endmodule
|
||||
|
||||
`default_nettype wire
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
#!/usr/bin/tclsh
|
||||
# jay's build script
|
||||
# pass -tclargs -d to generate diagnostics
|
||||
|
||||
# switches
|
||||
|
||||
set partNum xc7a100tcsg324-1
|
||||
set outputDir output_files
|
||||
set verbose 0
|
||||
|
||||
if { $argc > 0 } {
|
||||
if { $argc == 1 && [string compare [ lindex $argv 0 ] "-d"] == 0 } {
|
||||
set verbose 1
|
||||
} else {
|
||||
puts "usage: $argv0 \[-d\]"
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
|
||||
file mkdir $outputDir
|
||||
set files [glob -nocomplain "$outputDir/*"]
|
||||
if {[llength $files] != 0} {
|
||||
file delete -force {*}[glob -directory $outputDir *];
|
||||
}
|
||||
|
||||
read_verilog -sv [ glob ./src/*.{sv,v,svh,vh} ]
|
||||
read_xdc ./xdc/top_level.xdc
|
||||
|
||||
set_part $partNum
|
||||
|
||||
# synth
|
||||
synth_design -top top_level -part $partNum -verbose
|
||||
report_utilization -file $outputDir/post_synth_util.rpt
|
||||
if { $verbose } {
|
||||
report_timing_summary -file $outputDir/post_synth_timing_summary.rpt
|
||||
report_timing -file $outputDir/post_synth_timing.rpt
|
||||
}
|
||||
|
||||
# place
|
||||
opt_design
|
||||
place_design
|
||||
phys_opt_design
|
||||
report_utilization -file $outputDir/post_place_util.rpt
|
||||
|
||||
if { $verbose } {
|
||||
report_clock_utilization -file $outputDir/clock_util.rpt
|
||||
report_timing_summary -file $outputDir/post_place_timing_summary.rpt
|
||||
report_timing -file $outputDir/post_place_timing.rpt
|
||||
}
|
||||
|
||||
# route design and generate bitstream
|
||||
|
||||
route_design -directive Explore
|
||||
write_bitstream -force $outputDir/final.bit
|
||||
|
||||
if { $verbose } {
|
||||
report_route_status -file $outputDir/post_route_status.rpt
|
||||
report_timing_summary -file $outputDir/post_route_timing_summary.rpt
|
||||
report_timing -file $outputDir/post_route_timing.rpt
|
||||
report_power -file $outputDir/post_route_power.rpt
|
||||
report_drc -file $outputDir/post_imp_drc.rpt
|
||||
write_verilog -force $outputDir/cpu_impl_netlist.v -mode timesim -sdf_anno true
|
||||
# unfortunately, does nothing
|
||||
show_schematic [ get_cells ]
|
||||
}
|
||||
|
||||
exec sh -c "rm -rf *.jou *.log"
|
||||
|
||||
|
|
@ -0,0 +1,73 @@
|
|||
`default_nettype none
|
||||
`timescale 1ns/1ps
|
||||
|
||||
module ssd (
|
||||
input wire clk,
|
||||
input wire [31:0] val,
|
||||
output reg [6:0] cat,
|
||||
output reg [7:0] an);
|
||||
|
||||
parameter COUNT_TO = 100000;
|
||||
|
||||
reg [7:0] segment_state = 8'b0000_0001;
|
||||
reg [31:0] segment_counter = 32'b0;
|
||||
reg [3:0] digit;
|
||||
reg [6:0] led_out;
|
||||
|
||||
bto7s mbto7s (
|
||||
.x_in(digit),
|
||||
.s_out(led_out));
|
||||
|
||||
assign cat = ~led_out;
|
||||
assign an = ~segment_state;
|
||||
|
||||
always @(*) begin
|
||||
case(segment_state)
|
||||
8'b0000_0001: digit = val[3:0];
|
||||
8'b0000_0010: digit = val[7:4];
|
||||
8'b0000_0100: digit = val[11:8];
|
||||
8'b0000_1000: digit = val[15:12];
|
||||
8'b0001_0000: digit = val[19:16];
|
||||
8'b0010_0000: digit = val[23:20];
|
||||
8'b0100_0000: digit = val[27:24];
|
||||
8'b1000_0000: digit = val[31:28];
|
||||
default: digit = val[3:0];
|
||||
endcase
|
||||
end
|
||||
|
||||
always @(posedge clk) begin
|
||||
segment_counter <= segment_counter + 1;
|
||||
|
||||
if (segment_counter == COUNT_TO) begin
|
||||
segment_counter <= 32'd0;
|
||||
segment_state <= {segment_state[6:0], segment_state[7]};
|
||||
end
|
||||
end
|
||||
endmodule
|
||||
|
||||
module bto7s (
|
||||
input wire [3:0] x_in,
|
||||
output reg [6:0] s_out);
|
||||
|
||||
reg sa, sb, sc, sd, se, sf, sg;
|
||||
assign s_out = {sg, sf, se, sd, sc, sb, sa};
|
||||
|
||||
// array of bits that are "one hot" with numbers 0 through 15
|
||||
reg [15:0] num;
|
||||
genvar i;
|
||||
generate
|
||||
for(i=0; i<16; i=i+1)
|
||||
assign num[i] = (x_in == i);
|
||||
endgenerate
|
||||
|
||||
// map one-hot bits to active segments
|
||||
assign sa = (num & 16'b1101_0111_1110_1101) > 0;
|
||||
assign sb = (num & 16'b0010_0111_1001_1111) > 0;
|
||||
assign sc = (num & 16'b0010_1111_1111_1011) > 0;
|
||||
assign sd = (num & 16'b0111_1011_0110_1101) > 0;
|
||||
assign se = (num & 16'b1111_1101_0100_0101) > 0;
|
||||
assign sf = (num & 16'b1101_1111_0111_0001) > 0;
|
||||
assign sg = (num & 16'b1110_1111_0111_1100) > 0;
|
||||
endmodule
|
||||
|
||||
`default_nettype wire
|
||||
|
|
@ -1,301 +0,0 @@
|
|||
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
|
||||
|
|
@ -1,46 +0,0 @@
|
|||
from manta import Manta
|
||||
from scapy.all import *
|
||||
|
||||
m = Manta('manta.yaml')
|
||||
print(m.my_io_core.led.base_addr)
|
||||
|
||||
|
||||
def set_led(val):
|
||||
src_mac = "00:e0:4c:68:06:aa"
|
||||
dst_mac = "69:69:5a:06:54:91"
|
||||
ifc = "en8"
|
||||
|
||||
mypkt = Ether()
|
||||
mypkt.src = src_mac
|
||||
mypkt.dst = dst_mac
|
||||
mypkt.type = 0x1234
|
||||
|
||||
msg = b'\x00\x06' + val.to_bytes(2, 'big')
|
||||
|
||||
mypkt = mypkt / msg
|
||||
mypkt.load = msg
|
||||
sendpfast(mypkt, iface=ifc)
|
||||
|
||||
|
||||
|
||||
from time import sleep
|
||||
led_val = 1
|
||||
direction = True
|
||||
while True:
|
||||
if direction:
|
||||
if led_val == 2**15:
|
||||
direction = False
|
||||
|
||||
else:
|
||||
led_val = led_val * 2
|
||||
set_led(led_val)
|
||||
|
||||
else:
|
||||
if led_val == 1:
|
||||
direction = True
|
||||
|
||||
else:
|
||||
led_val = led_val // 2
|
||||
set_led(led_val)
|
||||
|
||||
sleep(0.01)
|
||||
|
|
@ -1,64 +0,0 @@
|
|||
`default_nettype none
|
||||
`timescale 1ns / 1ps
|
||||
|
||||
/* Aggregates the first 64 bits of an incoming
|
||||
* Ethernet transmission (thus shedding the FCS
|
||||
* and anything else extraneous) and outputs the
|
||||
* first 32 bits on an AXI bus for a single cycle.
|
||||
* If the packet is not at least 64 bits long,
|
||||
* nothing happens
|
||||
*
|
||||
* This value can then be fed into the seven
|
||||
* segment display to verify proper operation
|
||||
* of your module!
|
||||
*/
|
||||
|
||||
`define AGR_MAX 32
|
||||
`define AGR_SHOW 64
|
||||
|
||||
module aggregate(clk, rst, axiid, axiiv, axiod, axiov);
|
||||
|
||||
/* batteries */
|
||||
input logic clk, rst;
|
||||
|
||||
/* AXI input valid, and AXI input data from the
|
||||
* Ethernet pipeline. Comprises only data, i.e.
|
||||
* source/destination/ethertype are omitted via
|
||||
* previous stages in the pipeline. Also technically
|
||||
* comprises the FCS, but we assume that the actual
|
||||
* data in the ethernet frame is >= 32 bits long
|
||||
* so we'll lose the FCS in this stage by design
|
||||
*/
|
||||
input logic[1:0] axiid;
|
||||
input logic axiiv;
|
||||
|
||||
/* AXI output valid, and AXI output data. Comprises
|
||||
* just the first 32 bits of the incoming transmission,
|
||||
* asserted for a single cycle
|
||||
*/
|
||||
output logic[31:0] axiod;
|
||||
output logic axiov;
|
||||
|
||||
/* A quick and dirty counter. As long as this is below
|
||||
* 32, we'll dump packets into the AXI output data buffer.
|
||||
* Once the counter gets to AGR_MAX, we'll assert AXI valid.
|
||||
* Then we'll hang until axiiv drops
|
||||
*/
|
||||
logic[31:0] counter;
|
||||
|
||||
assign axiov = counter == `AGR_SHOW;
|
||||
|
||||
always_ff @(posedge clk) begin: COUNTER
|
||||
if (rst || !axiiv) counter <= 32'b0;
|
||||
else counter <= counter + 2;
|
||||
end
|
||||
|
||||
always_ff @(posedge clk) begin: AXIOD
|
||||
if (rst || !axiiv) axiod <= 32'b0;
|
||||
else if (counter < `AGR_MAX && axiiv)
|
||||
axiod[`AGR_MAX - counter - 2 +: 2] = axiid;
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
||||
`default_nettype wire
|
||||
|
|
@ -1,138 +0,0 @@
|
|||
`default_nettype none
|
||||
`timescale 1ns / 1ps
|
||||
|
||||
/* Ethernet sends packets in least significant
|
||||
* bit order, most significant byte order. This
|
||||
* module is responsible for changing that to
|
||||
* make things legible - in particular, we convert
|
||||
* from LSb/MSB to MSb/MSB.
|
||||
*/
|
||||
|
||||
`define BO_SENDA 2'b00
|
||||
`define BO_SENDB 2'b01
|
||||
`define BO_EMPTYA 2'b10
|
||||
`define BO_EMPTYB 2'b11
|
||||
|
||||
module bitorder(clk, rst, axiiv, axiid, axiod, axiov);
|
||||
|
||||
/* batteries */
|
||||
input logic clk, rst;
|
||||
|
||||
/* AXI input valid and AXI input data
|
||||
* from the module upstream from us in the
|
||||
* pipeline - that being the physical layer
|
||||
* This will transport bits from off the wire
|
||||
* in least significant bit first order
|
||||
*/
|
||||
input logic[1:0] axiid;
|
||||
input logic axiiv;
|
||||
|
||||
/* AXI output valid and AXI output data
|
||||
* Transports the correctly bit-ordered Ethernet
|
||||
* data (most significant bit first) up the pipeline
|
||||
* for further processing...
|
||||
*/
|
||||
output logic[1:0] axiod;
|
||||
output logic axiov;
|
||||
|
||||
/* Two registers to hold data coming in off the wire,
|
||||
* byte by byte. This is where we'll buffer until
|
||||
* we've received a byte of data, at which point
|
||||
* we'll start sending out the byte in the correct
|
||||
* order using one register. Meanwhile, we'll start
|
||||
* receiving into the other register - dual buffers.
|
||||
*/
|
||||
logic[7:0] bufa, bufb;
|
||||
|
||||
/* A counter. This indicates what 'stage' we're in,
|
||||
* and always refers to the index we're reading into
|
||||
* in the receiving buffer or sending out of in the
|
||||
* sending buffer
|
||||
*/
|
||||
logic[2:0] countera, counterb;
|
||||
|
||||
/* Which state we're in - should we be using buffer
|
||||
* A to send, buffer B to send, or neither because
|
||||
* we've just come out of reset?
|
||||
*/
|
||||
logic[1:0] state;
|
||||
|
||||
always_comb begin: AXIOV
|
||||
if (state == `BO_SENDA || state == `BO_SENDB) axiov = 1'b1;
|
||||
else axiov = 1'b0;
|
||||
end
|
||||
|
||||
always_comb begin: AXIOD
|
||||
if (state == `BO_SENDA) axiod = bufa[countera +: 2];
|
||||
else if (state == `BO_SENDB) axiod = bufb[counterb +: 2];
|
||||
else axiod = 1'b0;
|
||||
end
|
||||
|
||||
always_ff @(posedge clk) begin: BUFFERIN
|
||||
if (rst) begin
|
||||
bufa <= 8'b0;
|
||||
bufb <= 8'b0;
|
||||
end else if (axiiv) begin
|
||||
case (state)
|
||||
`BO_EMPTYB, `BO_SENDB:
|
||||
bufa[countera +: 2] <= axiid;
|
||||
`BO_EMPTYA, `BO_SENDA:
|
||||
bufb[counterb +: 2] <= axiid;
|
||||
endcase
|
||||
end else if (state == `BO_EMPTYB || state == `BO_EMPTYA) begin
|
||||
bufa <= 8'b0;
|
||||
bufb <= 8'b0;
|
||||
end
|
||||
end
|
||||
|
||||
always_ff @(posedge clk) begin: STATES
|
||||
if (rst) begin
|
||||
state <= `BO_EMPTYB;
|
||||
countera <= 3'b0;
|
||||
counterb <= 3'b0;
|
||||
end else begin
|
||||
case (state)
|
||||
`BO_EMPTYB: begin
|
||||
if (axiiv) begin
|
||||
if (countera == 3'h6)
|
||||
state <= `BO_SENDA;
|
||||
else countera <= countera + 2;
|
||||
end else countera <= 3'b0;
|
||||
end
|
||||
|
||||
`BO_EMPTYA: begin
|
||||
if (axiiv) begin
|
||||
if (counterb == 3'h6)
|
||||
state <= `BO_SENDB;
|
||||
else counterb <= counterb + 2;
|
||||
end else counterb <= 3'b0;
|
||||
end
|
||||
|
||||
`BO_SENDB: begin
|
||||
if (counterb == 3'h0) state <= `BO_EMPTYB;
|
||||
else counterb <= counterb - 2;
|
||||
|
||||
if (axiiv) begin
|
||||
if (countera == 3'h6)
|
||||
state <= `BO_SENDA;
|
||||
else countera <= countera + 2;
|
||||
end
|
||||
end
|
||||
|
||||
`BO_SENDA: begin
|
||||
if (countera == 3'h0) state <= `BO_EMPTYA;
|
||||
else countera <= countera - 2;
|
||||
|
||||
if (axiiv) begin
|
||||
if (counterb == 3'h6)
|
||||
state <= `BO_SENDB;
|
||||
else counterb <= counterb + 2;
|
||||
end
|
||||
end
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
||||
`default_nettype wire
|
||||
|
|
@ -1,95 +0,0 @@
|
|||
`default_nettype none
|
||||
`timescale 1ns / 1ps
|
||||
|
||||
/* Computes the ethernet checksum
|
||||
* The following combinations of `done` and `kill`
|
||||
* represent the state of the module:
|
||||
*
|
||||
* - done = 0, kill = 0: processing data or freshly reset
|
||||
* - done = 1, kill = 0: correct ethernet checksum verified
|
||||
* - done = 1, kill = 1: data valid set to zero before correct
|
||||
* checksum value computed, therefore bad checksum
|
||||
* - done = 0, kill = 1: never asserted
|
||||
*
|
||||
* the done and/or kill signals are asserted high beginning
|
||||
* the cycle after input data ceases, and until new data
|
||||
* is received via the AXI input
|
||||
*/
|
||||
|
||||
`define CK_FRESH 2'b00
|
||||
`define CK_COMPUTING 2'b01
|
||||
`define CK_DONE 2'b10
|
||||
|
||||
`define MAGIC_CHECK 32'h38_fb_22_84
|
||||
|
||||
module cksum(clk, rst, axiid, axiiv, done, kill);
|
||||
|
||||
/* batteries */
|
||||
input logic clk, rst;
|
||||
|
||||
/* AXI input valid, and AXI input data from the
|
||||
* physical layer. Comprises unmodified data directly
|
||||
* from the wire, in Ethernet bit order, to be fed
|
||||
* directly into the CRC32 module you wrote for the
|
||||
* pset
|
||||
*/
|
||||
input logic[1:0] axiid;
|
||||
input logic axiiv;
|
||||
|
||||
/* Done and kill, as described in the module synopsis */
|
||||
output logic done, kill;
|
||||
|
||||
/* CRC32 AXI output data bus, which is the 32-bit
|
||||
* checksum calculated so far via the checksum module
|
||||
* you implemented in one of the last psets (CRC32-BZIP2)
|
||||
*/
|
||||
logic[31:0] crcd;
|
||||
logic crcv;
|
||||
|
||||
/* Decoupled logic to reset the CRC module independently
|
||||
* Used to compute multiple CRCs back to back
|
||||
*/
|
||||
logic crcrst;
|
||||
|
||||
/* Our finite state machine - bonus points if you can identify
|
||||
* whether this is a Moore or Mealy FSM!
|
||||
*/
|
||||
logic[1:0] state;
|
||||
|
||||
crc32 cksum(.clk(clk),
|
||||
.rst(crcrst | rst),
|
||||
.axiiv(axiiv),
|
||||
.axiid(axiid),
|
||||
.axiov(crcv),
|
||||
.axiod(crcd));
|
||||
|
||||
always_ff @(posedge clk) begin: OUTPUTS
|
||||
if (rst || axiiv) begin
|
||||
done <= 1'b0;
|
||||
kill <= 1'b0;
|
||||
crcrst <= 1'b0;
|
||||
end else begin
|
||||
if (state == `CK_COMPUTING && !axiiv) begin
|
||||
done <= 1'b1;
|
||||
crcrst <= 1'b1;
|
||||
|
||||
if (crcd == `MAGIC_CHECK) kill <= 1'b0;
|
||||
else kill <= 1'b1;
|
||||
end else crcrst <= 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
always_ff @(posedge clk) begin: FSM
|
||||
if (rst) state <= `CK_FRESH;
|
||||
else begin
|
||||
case (state)
|
||||
`CK_FRESH: if (axiiv) state <= `CK_COMPUTING;
|
||||
`CK_COMPUTING: if (!axiiv) state <= `CK_DONE;
|
||||
`CK_DONE: if (axiiv) state <= `CK_COMPUTING;
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
||||
`default_nettype wire
|
||||
|
|
@ -1,74 +0,0 @@
|
|||
`default_nettype none
|
||||
`timescale 1ns / 1ps
|
||||
|
||||
`define LAGGING_SHIFT_IN (caxiod[30] ^ axiid[1])
|
||||
`define LEADING_SHIFT_IN (caxiod[31] ^ axiid[0])
|
||||
`define DOUBLED_SHIFT_IN (`LEADING_SHIFT_IN ^ `LAGGING_SHIFT_IN)
|
||||
|
||||
`define LAGGING_TAPS 4, 7, 10, 16, 22, 26
|
||||
`define DOUBLED_TAPS 2, 5, 8, 11, 12, 23
|
||||
`define LEADING_TAPS 3, 6, 9, 13, 17, 24, 27
|
||||
|
||||
/* this module implements CRC32-BZIP2, with a two bit input:
|
||||
* - poly 0x04C11DB7
|
||||
* - init 0xFFFFFFFF
|
||||
* - NEW: XOR outputs
|
||||
*
|
||||
* == check: 0xfc891918 ==
|
||||
*
|
||||
* this is the ethernet checksum!!
|
||||
*/
|
||||
|
||||
module crc32(clk, rst, axiiv, axiid, axiov, axiod);
|
||||
|
||||
/* old style i/o declaration, for clarity.
|
||||
* easier on 80-char line limits...
|
||||
* use this if you want, we don't care
|
||||
*/
|
||||
input logic clk, rst;
|
||||
|
||||
input logic axiiv;
|
||||
input logic[1:0] axiid;
|
||||
|
||||
output logic axiov;
|
||||
output logic[31:0] axiod;
|
||||
|
||||
logic[31:0] caxiod, saxiod;
|
||||
integer i;
|
||||
|
||||
assign axiov = 1;
|
||||
assign axiod = ~caxiod;
|
||||
|
||||
always @(*) begin
|
||||
for (i = 0; i < 32; i = i + 1) begin
|
||||
case (i)
|
||||
0: saxiod[i] = `LAGGING_SHIFT_IN;
|
||||
1: saxiod[i] = `DOUBLED_SHIFT_IN;
|
||||
|
||||
`LAGGING_TAPS:
|
||||
saxiod[i] = caxiod[i - 2] ^ `LAGGING_SHIFT_IN;
|
||||
`DOUBLED_TAPS:
|
||||
saxiod[i] = caxiod[i - 2] ^ `DOUBLED_SHIFT_IN;
|
||||
`LEADING_TAPS:
|
||||
saxiod[i] = caxiod[i - 2] ^ `LEADING_SHIFT_IN;
|
||||
|
||||
default: saxiod[i] = caxiod[i - 2];
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (rst) caxiod <= 32'hFFFF_FFFF;
|
||||
|
||||
/* our output validity hinges on whether
|
||||
* we are calculating anything or not
|
||||
* on this clock cycle. if there is no
|
||||
* valid input for us, don't do a shift
|
||||
* this cycle
|
||||
*/
|
||||
else caxiod <= (axiiv) ? saxiod : caxiod;
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
||||
`default_nettype wire
|
||||
|
|
@ -1,151 +0,0 @@
|
|||
/* The catsoop checker does not like to see `timescale declarations
|
||||
* in your code. However, we obviously need them when we synthesize
|
||||
* for iverilog - they tell iverilog that #5 means 5ns, for example.
|
||||
* Without these iverilog has no basis for how long *stuff* should
|
||||
* wait for when you use #, so it blows up!
|
||||
*
|
||||
* When you use the catsoop checker, it `defines the CATSOOP macro.
|
||||
* So we can check whether CATSOOP is defined or not - if it isn't,
|
||||
* then we'll put the timescale thing in so code works right on your
|
||||
* system.
|
||||
*/
|
||||
|
||||
`default_nettype none
|
||||
`timescale 1ns / 1ps
|
||||
|
||||
/* This module receives packets from the RJ45 (Ethernet) port on your
|
||||
* FPGA from the _physical layer_, i.e. the electronic (or optical!)
|
||||
* connection between devices running through an Ethernet cable.
|
||||
*
|
||||
* Ethernet is very diverse set of specifications, with all sorts of
|
||||
* different physical layers (which we abbreviate 'the medium' or
|
||||
* 'media' in plural). Ethernet media have transfer speeds ranging
|
||||
* from 1 Mbps to 400 gigabits per second in modern data centers!
|
||||
* For this implementation, we will implement "Fast Ethernet", which
|
||||
* (not fast by today's standards) utilizes a physical layer capable
|
||||
* of 100 Mbps communication. Most modern cables are backwards
|
||||
* compatible with this standard.
|
||||
*/
|
||||
|
||||
/* Note: this file uses tabs instead of spaces for indentation.
|
||||
* More modern editors should pick this up automatically, but if yours
|
||||
* doesn't that might explain trouble getting things to line up. You
|
||||
* can probably configure this (e.g. in vim, type ":set noexpandtab"
|
||||
* in normal mode and then type ":set tabstop=8")
|
||||
*/
|
||||
|
||||
`define EF_IDLE 3'b000
|
||||
`define EF_PREAM 3'b001
|
||||
`define EF_DATA 3'b011
|
||||
`define EF_BAD 3'b101
|
||||
|
||||
`define PREAM_BITS 64
|
||||
`define PREAM_SIZE (`PREAM_BITS / 2)
|
||||
|
||||
`define PREAM_FIRST 2'b00
|
||||
`define PREAM_EXPECT 2'b01
|
||||
`define PREAM_LAST 2'b11
|
||||
`define PREAM_BAD 2'b10
|
||||
|
||||
module ether(clk, rst, rxd, crsdv, axiov, axiod);
|
||||
|
||||
input logic clk, rst;
|
||||
|
||||
/* Carrier Sense (CRS) / Data Valid (DV): indicates
|
||||
* whether there is a valid signal currently being
|
||||
* transmitted over the Ethernet medium by another
|
||||
* sender.
|
||||
*
|
||||
* In the past, >2 computers were connected
|
||||
* to the same Ethernet cable, so this helped
|
||||
* distinguish if one machine was trying to talk over
|
||||
* another. Nowadays, usually Ethernet connections are
|
||||
* point to point (have you ever seen an Ethernet cable
|
||||
* with three ports on it? no? that's what i thought),
|
||||
* and shared media isn't even supported in the 100 Mbps
|
||||
* spec.
|
||||
*
|
||||
* So just use this input to determine whether valid
|
||||
* data is on the line coming in.
|
||||
*/
|
||||
input logic crsdv;
|
||||
|
||||
/* Receive Data (RXD): If crsdv is high, receives
|
||||
* two bits off the wire. Otherwise, undefined
|
||||
* (let's say 2'bXX)
|
||||
*
|
||||
* According to the IEEE 802.3 Fast Ethernet
|
||||
* specification, with the exception of the FCS,
|
||||
* bytes in Ethernet world are sent least significant
|
||||
* bit first, most significant byte first. Confusing!
|
||||
* Basically, if you have a two byte (16 bit) message,
|
||||
* the bits will come in over RXD as:
|
||||
*
|
||||
* 7:6 -> 5:4 -> 3:2 -> 1:0 -> 15:14 -> ... -> 9:8
|
||||
*
|
||||
* For now, this idiosyncracy won't matter to you.
|
||||
* Later, it will.
|
||||
*/
|
||||
input logic[1:0] rxd;
|
||||
|
||||
/* 2-bit AXI output: forward whatever we receive
|
||||
* on to the outside world for further processing
|
||||
*/
|
||||
output logic axiov;
|
||||
output logic[1:0] axiod;
|
||||
|
||||
/* END OF STARTER CODE */
|
||||
|
||||
logic[4:0] count;
|
||||
logic[2:0] state;
|
||||
|
||||
logic[1:0] preamex;
|
||||
logic preamok, start;
|
||||
|
||||
always @(*) begin: PREAM
|
||||
if (count == `PREAM_SIZE - 1) preamex = `PREAM_LAST;
|
||||
else preamex = `PREAM_EXPECT;
|
||||
|
||||
preamok = crsdv && rxd == preamex;
|
||||
end
|
||||
|
||||
always @(*) start = crsdv && rxd != `PREAM_FIRST;
|
||||
|
||||
always @(posedge clk) begin: COUNT
|
||||
if (state == `EF_PREAM) count <= count + 1;
|
||||
else if (state == `EF_IDLE && start) count <= count + 1;
|
||||
else count <= 0;
|
||||
end
|
||||
|
||||
always @(posedge clk) begin: FSM
|
||||
if (rst) begin
|
||||
axiod <= 2'b0;
|
||||
axiov <= 1'b0;
|
||||
state <= 3'b0;
|
||||
end else begin
|
||||
case (state)
|
||||
`EF_BAD: if (!crsdv) state <= `EF_IDLE;
|
||||
`EF_IDLE: if (start) state <= `EF_PREAM;
|
||||
|
||||
`EF_PREAM: begin
|
||||
if (!preamok || !crsdv) state <= `EF_BAD;
|
||||
else if (count == `PREAM_SIZE - 1)
|
||||
state <= `EF_DATA;
|
||||
end
|
||||
|
||||
`EF_DATA: begin
|
||||
if (crsdv) begin
|
||||
axiov <= 1'b1;
|
||||
axiod <= rxd;
|
||||
end else begin
|
||||
axiov <= 1'b0;
|
||||
axiod <= 2'b0;
|
||||
state <= `EF_IDLE;
|
||||
end
|
||||
end
|
||||
endcase
|
||||
end
|
||||
end
|
||||
endmodule
|
||||
|
||||
`default_nettype wire
|
||||
|
|
@ -1,121 +0,0 @@
|
|||
`default_nettype none
|
||||
`timescale 1ns / 1ps
|
||||
|
||||
/* Sometimes we might receive packets not
|
||||
* intended for us on the wire. This is especially
|
||||
* true if we're operating in old school mode, where
|
||||
* Ethernet used to have many devices on the same
|
||||
* medium. Alternatively, several virtual NICs may
|
||||
* exist in software on a given machine, or a machine
|
||||
* may support MAC address randomization.
|
||||
*
|
||||
* All of this means we need to make sure inbound
|
||||
* packets are actually intended for us, and not
|
||||
* for some other NIC. That's what this module is
|
||||
* for. In addition, this module will also strip
|
||||
* the MAC address pair (and Ethertype) off of the
|
||||
* Ethernet header, leaving only data and the FCS.
|
||||
* We'll clean up the FCS later...
|
||||
*/
|
||||
|
||||
/* "Intended for us" means the following:
|
||||
* - has the destination MAC "`FW_ME" as defined below. Make this
|
||||
* your own MAC of your choice - get creative!
|
||||
* - has the destination MAC of all 1s, i.e. a 'broadcast' packet
|
||||
*
|
||||
* If these conditions are not met on a given input stream, data
|
||||
* from the packet is dropped / not forwarded on through the
|
||||
* pipeline
|
||||
*/
|
||||
|
||||
`define FW_ME 48'h69_69_5A_06_54_91
|
||||
`define FW_DESTSTART 0
|
||||
`define FW_DESTEND (`FW_DESTSTART + 48)
|
||||
|
||||
`define FW_DATASTART (48 + 48 + 16)
|
||||
|
||||
module firewall(clk, rst, axiiv, axiid, axiov, axiod);
|
||||
|
||||
/* batteries */
|
||||
input logic clk, rst;
|
||||
|
||||
/* AXI input valid, and AXI input data from the bit order
|
||||
* flip module. So this will transport MSb/MSB first data
|
||||
* coming off the wire - allowing you to compare with src/dst
|
||||
* MAC addresses a bit more easily
|
||||
*/
|
||||
input logic[1:0] axiid;
|
||||
input logic axiiv;
|
||||
|
||||
/* AXI output valid, and AXI output data. If and only if
|
||||
* the packet is intended for our device as described above,
|
||||
* this line will stream out the _data_ and _fcs_ (NOT the MAC
|
||||
* addresses in the header, nor the ethertype - we're ignoring
|
||||
* the latter this time around) we're receiving off the wire.
|
||||
* If a kill-worthy condition is detected, these lines are
|
||||
* deasserted for the duration of the incoming packet
|
||||
*/
|
||||
output logic[1:0] axiod;
|
||||
output logic axiov;
|
||||
|
||||
/* Buffers to hold our MAC address in the reverse order,
|
||||
* to make comparison easier than it otherwise would be
|
||||
*/
|
||||
logic[0:47] me;
|
||||
|
||||
/* A counter, to determine whether we should be comparing
|
||||
* with a MAC address or stripping off data
|
||||
*/
|
||||
logic[31:0] counter;
|
||||
|
||||
/* An internal set of flags to mark whether the currently
|
||||
* traversing packet is valid, i.e we should forward data,
|
||||
* or not. One of these flags tracks whether the destination
|
||||
* MAC address matches _our_ (FW_ME) mac address, the other
|
||||
* tracks whether the destination matches the broadcast
|
||||
* (FW_BCAST) MAC. If either one of these is high once the
|
||||
* destination MAC finishes rolling through, the packet
|
||||
* is forwarded.
|
||||
*/
|
||||
logic matchme, matchbcast;
|
||||
|
||||
assign me = `FW_ME;
|
||||
|
||||
always_ff @(posedge clk) begin: MATCH
|
||||
if (counter == 32'b0) begin
|
||||
matchme <= 1'b1;
|
||||
matchbcast <= 1'b1;
|
||||
end
|
||||
|
||||
/* could overwrite the above, which is ideal if
|
||||
* FW_DESTSTART == 0 (it is) and we have a mismatch
|
||||
* out the gate
|
||||
*/
|
||||
if (counter >= `FW_DESTSTART && counter < `FW_DESTEND) begin
|
||||
if (axiiv) begin
|
||||
if (axiid != {me[counter], me[counter + 1]})
|
||||
matchme <= 1'b0;
|
||||
if (axiid != 2'b11)
|
||||
matchbcast <= 1'b0;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
always_comb begin: AXIOUT
|
||||
if (counter >= `FW_DATASTART && (matchme | matchbcast)) begin
|
||||
axiod = axiid;
|
||||
axiov = axiiv;
|
||||
end else begin
|
||||
axiod = 2'b00;
|
||||
axiov = 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
always_ff @(posedge clk) begin: COUNTER
|
||||
if (axiiv) counter <= counter + 2;
|
||||
else counter <= 32'b0;
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
||||
`default_nettype wire
|
||||
|
|
@ -1,45 +0,0 @@
|
|||
module seven_segment_controller #(parameter COUNT_TO = 100000)
|
||||
( input wire clk_in,
|
||||
input wire rst_in,
|
||||
input wire [31:0] val_in,
|
||||
output logic[6:0] cat_out,
|
||||
output logic[7:0] an_out
|
||||
);
|
||||
|
||||
logic[7:0] segment_state;
|
||||
logic[31:0] segment_counter;
|
||||
logic [3:0] routed_vals;
|
||||
logic [6:0] led_out;
|
||||
|
||||
bto7s mbto7s (.x_in(routed_vals), .s_out(led_out));
|
||||
|
||||
assign cat_out = ~led_out;
|
||||
assign an_out = ~segment_state;
|
||||
|
||||
always_comb begin
|
||||
case(segment_state)
|
||||
8'b0000_0001: routed_vals = val_in[3:0];
|
||||
8'b0000_0010: routed_vals = val_in[7:4];
|
||||
8'b0000_0100: routed_vals = val_in[11:8];
|
||||
8'b0000_1000: routed_vals = val_in[15:12];
|
||||
8'b0001_0000: routed_vals = val_in[19:16];
|
||||
8'b0010_0000: routed_vals = val_in[23:20];
|
||||
8'b0100_0000: routed_vals = val_in[27:24];
|
||||
8'b1000_0000: routed_vals = val_in[31:28];
|
||||
default: routed_vals = val_in[3:0];
|
||||
endcase
|
||||
end
|
||||
always_ff @(posedge clk_in)begin
|
||||
if (rst_in)begin
|
||||
segment_state <= 8'b0000_0001;
|
||||
segment_counter <= 32'b0;
|
||||
end else begin
|
||||
if (segment_counter == COUNT_TO)begin
|
||||
segment_counter <= 32'd0;
|
||||
segment_state <= {segment_state[6:0],segment_state[7]};
|
||||
end else begin
|
||||
segment_counter <= segment_counter +1;
|
||||
end
|
||||
end
|
||||
end
|
||||
endmodule //seven_segment_controller
|
||||
|
|
@ -1,85 +0,0 @@
|
|||
module ssd(
|
||||
input wire clk_in,
|
||||
input wire rst_in,
|
||||
input wire [31:0] val_in,
|
||||
output reg[6:0] cat_out,
|
||||
output reg[7:0] an_out);
|
||||
|
||||
parameter COUNT_TO = 100000;
|
||||
logic[7:0] segment_state;
|
||||
logic[31:0] segment_counter;
|
||||
logic [3:0] routed_vals;
|
||||
logic [6:0] led_out;
|
||||
|
||||
bto7s mbto7s (.x_in(routed_vals), .s_out(led_out));
|
||||
|
||||
assign cat_out = ~led_out;
|
||||
assign an_out = ~segment_state;
|
||||
|
||||
always @(*) begin
|
||||
case(segment_state)
|
||||
8'b0000_0001: routed_vals = val_in[3:0];
|
||||
8'b0000_0010: routed_vals = val_in[7:4];
|
||||
8'b0000_0100: routed_vals = val_in[11:8];
|
||||
8'b0000_1000: routed_vals = val_in[15:12];
|
||||
8'b0001_0000: routed_vals = val_in[19:16];
|
||||
8'b0010_0000: routed_vals = val_in[23:20];
|
||||
8'b0100_0000: routed_vals = val_in[27:24];
|
||||
8'b1000_0000: routed_vals = val_in[31:28];
|
||||
default: routed_vals = val_in[3:0];
|
||||
endcase
|
||||
end
|
||||
|
||||
always @(posedge clk_in) begin
|
||||
if (rst_in) begin
|
||||
segment_state <= 8'b0000_0001;
|
||||
segment_counter <= 32'b0;
|
||||
end
|
||||
|
||||
else begin
|
||||
if (segment_counter == COUNT_TO) begin
|
||||
segment_counter <= 32'd0;
|
||||
segment_state <= {segment_state[6:0],segment_state[7]};
|
||||
end else begin
|
||||
segment_counter <= segment_counter +1;
|
||||
end
|
||||
end
|
||||
end
|
||||
endmodule
|
||||
|
||||
|
||||
module bto7s(
|
||||
input wire [3:0] x_in,
|
||||
output reg [6:0] s_out);
|
||||
|
||||
reg sa, sb, sc, sd, se, sf, sg;
|
||||
assign s_out = {sg, sf, se, sd, sc, sb, sa};
|
||||
|
||||
// array of bits that are "one hot" with numbers 0 through 15
|
||||
reg [15:0] num;
|
||||
|
||||
assign num[0] = ~x_in[3] && ~x_in[2] && ~x_in[1] && ~x_in[0];
|
||||
assign num[1] = ~x_in[3] && ~x_in[2] && ~x_in[1] && x_in[0];
|
||||
assign num[2] = x_in == 4'd2;
|
||||
assign num[3] = x_in == 4'd3;
|
||||
assign num[4] = x_in == 4'd4;
|
||||
assign num[5] = x_in == 4'd5;
|
||||
assign num[6] = x_in == 4'd6;
|
||||
assign num[7] = x_in == 4'd7;
|
||||
assign num[8] = x_in == 4'd8;
|
||||
assign num[9] = x_in == 4'd9;
|
||||
assign num[10] = x_in == 4'd10;
|
||||
assign num[11] = x_in == 4'd11;
|
||||
assign num[12] = x_in == 4'd12;
|
||||
assign num[13] = x_in == 4'd13;
|
||||
assign num[14] = x_in == 4'd14;
|
||||
assign num[15] = x_in == 4'd15;
|
||||
|
||||
assign sa = num[0] || num[2] || num[3] || num[5] || num[6] || num[7] || num[8] || num[9] || num[10] || num[12] ||num[14] ||num[15];
|
||||
assign sb = num[0] || num[1] || num[2] || num[3] || num[4] || num[7] || num[8] || num[9] || num[10] || num[13];
|
||||
assign sc = num[0] || num[1] || num[3] || num[4] || num[5] || num[6] || num[7] || num[8] || num[9] || num[10] || num[11] || num[13];
|
||||
assign sd = num[0] || num[2] || num[3] || num[5] || num[6] || num[8] || num[9] || num[11] || num[12] || num[13] || num[14];
|
||||
assign se = num[0] || num[2] || num[6] || num[8] || num[10] || num[11] || num[12] || num[13] || num[14] || num[15];
|
||||
assign sf = num[0] || num[4] || num[5] || num[6] || num[8] || num[9] || num[10] || num[11] || num[12] || num[14] || num[15];
|
||||
assign sg = num[2] || num[3] || num[4] || num[5] || num[6] || num[8] || num[9] || num[10] || num[11] || num[13] || num[14] ||num[15];
|
||||
endmodule
|
||||
|
|
@ -1,301 +0,0 @@
|
|||
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
|
||||
|
|
@ -1,85 +0,0 @@
|
|||
module ssd(
|
||||
input wire clk_in,
|
||||
input wire rst_in,
|
||||
input wire [31:0] val_in,
|
||||
output reg[6:0] cat_out,
|
||||
output reg[7:0] an_out);
|
||||
|
||||
parameter COUNT_TO = 100000;
|
||||
logic[7:0] segment_state;
|
||||
logic[31:0] segment_counter;
|
||||
logic [3:0] routed_vals;
|
||||
logic [6:0] led_out;
|
||||
|
||||
bto7s mbto7s (.x_in(routed_vals), .s_out(led_out));
|
||||
|
||||
assign cat_out = ~led_out;
|
||||
assign an_out = ~segment_state;
|
||||
|
||||
always @(*) begin
|
||||
case(segment_state)
|
||||
8'b0000_0001: routed_vals = val_in[3:0];
|
||||
8'b0000_0010: routed_vals = val_in[7:4];
|
||||
8'b0000_0100: routed_vals = val_in[11:8];
|
||||
8'b0000_1000: routed_vals = val_in[15:12];
|
||||
8'b0001_0000: routed_vals = val_in[19:16];
|
||||
8'b0010_0000: routed_vals = val_in[23:20];
|
||||
8'b0100_0000: routed_vals = val_in[27:24];
|
||||
8'b1000_0000: routed_vals = val_in[31:28];
|
||||
default: routed_vals = val_in[3:0];
|
||||
endcase
|
||||
end
|
||||
|
||||
always @(posedge clk_in) begin
|
||||
if (rst_in) begin
|
||||
segment_state <= 8'b0000_0001;
|
||||
segment_counter <= 32'b0;
|
||||
end
|
||||
|
||||
else begin
|
||||
if (segment_counter == COUNT_TO) begin
|
||||
segment_counter <= 32'd0;
|
||||
segment_state <= {segment_state[6:0],segment_state[7]};
|
||||
end else begin
|
||||
segment_counter <= segment_counter +1;
|
||||
end
|
||||
end
|
||||
end
|
||||
endmodule
|
||||
|
||||
|
||||
module bto7s(
|
||||
input wire [3:0] x_in,
|
||||
output reg [6:0] s_out);
|
||||
|
||||
reg sa, sb, sc, sd, se, sf, sg;
|
||||
assign s_out = {sg, sf, se, sd, sc, sb, sa};
|
||||
|
||||
// array of bits that are "one hot" with numbers 0 through 15
|
||||
reg [15:0] num;
|
||||
|
||||
assign num[0] = ~x_in[3] && ~x_in[2] && ~x_in[1] && ~x_in[0];
|
||||
assign num[1] = ~x_in[3] && ~x_in[2] && ~x_in[1] && x_in[0];
|
||||
assign num[2] = x_in == 4'd2;
|
||||
assign num[3] = x_in == 4'd3;
|
||||
assign num[4] = x_in == 4'd4;
|
||||
assign num[5] = x_in == 4'd5;
|
||||
assign num[6] = x_in == 4'd6;
|
||||
assign num[7] = x_in == 4'd7;
|
||||
assign num[8] = x_in == 4'd8;
|
||||
assign num[9] = x_in == 4'd9;
|
||||
assign num[10] = x_in == 4'd10;
|
||||
assign num[11] = x_in == 4'd11;
|
||||
assign num[12] = x_in == 4'd12;
|
||||
assign num[13] = x_in == 4'd13;
|
||||
assign num[14] = x_in == 4'd14;
|
||||
assign num[15] = x_in == 4'd15;
|
||||
|
||||
assign sa = num[0] || num[2] || num[3] || num[5] || num[6] || num[7] || num[8] || num[9] || num[10] || num[12] ||num[14] ||num[15];
|
||||
assign sb = num[0] || num[1] || num[2] || num[3] || num[4] || num[7] || num[8] || num[9] || num[10] || num[13];
|
||||
assign sc = num[0] || num[1] || num[3] || num[4] || num[5] || num[6] || num[7] || num[8] || num[9] || num[10] || num[11] || num[13];
|
||||
assign sd = num[0] || num[2] || num[3] || num[5] || num[6] || num[8] || num[9] || num[11] || num[12] || num[13] || num[14];
|
||||
assign se = num[0] || num[2] || num[6] || num[8] || num[10] || num[11] || num[12] || num[13] || num[14] || num[15];
|
||||
assign sf = num[0] || num[4] || num[5] || num[6] || num[8] || num[9] || num[10] || num[11] || num[12] || num[14] || num[15];
|
||||
assign sg = num[2] || num[3] || num[4] || num[5] || num[6] || num[8] || num[9] || num[10] || num[11] || num[13] || num[14] ||num[15];
|
||||
endmodule
|
||||
|
|
@ -0,0 +1 @@
|
|||
../common/ssd.v
|
||||
|
|
@ -49,14 +49,11 @@ module top_level (
|
|||
.led17_g(led17_g),
|
||||
.led17_r(led17_r));
|
||||
|
||||
logic [6:0] cat;
|
||||
assign {cg,cf,ce,cd,cc,cb,ca} = cat;
|
||||
ssd ssd (
|
||||
.clk_in(clk),
|
||||
.rst_in(!cpu_resetn),
|
||||
.val_in( (manta.my_io_core_btx_rdata << 16) | (manta.brx_my_io_core_wdata) ),
|
||||
.cat_out(cat),
|
||||
.an_out(an));
|
||||
.clk(clk),
|
||||
.val( (manta.my_io_core_btx_rdata << 16) | (manta.brx_my_io_core_wdata) ),
|
||||
.cat({cg,cf,ce,cd,cc,cb,ca}),
|
||||
.an(an));
|
||||
|
||||
endmodule
|
||||
|
||||
|
|
@ -0,0 +1 @@
|
|||
../common/ssd.v
|
||||
|
|
@ -133,17 +133,13 @@ module top_level (
|
|||
.led17_g(led17_g),
|
||||
.led17_r(led17_r));
|
||||
|
||||
logic [6:0] cat;
|
||||
assign {cg,cf,ce,cd,cc,cb,ca} = cat;
|
||||
|
||||
logic [31:0] aggregate_axiod_persistent;
|
||||
always_ff @(posedge ethclk) if (aggregate_axiov) aggregate_axiod_persistent <= aggregate_axiod;
|
||||
ssd ssd (
|
||||
.clk_in(ethclk),
|
||||
.rst_in(!cpu_resetn),
|
||||
.val_in(aggregate_axiod_persistent),
|
||||
.cat_out(cat),
|
||||
.an_out(an));
|
||||
.clk(ethclk),
|
||||
.val(aggregate_axiod_persistent),
|
||||
.cat({cg,cf,ce,cd,cc,cb,ca}),
|
||||
.an(an));
|
||||
|
||||
endmodule
|
||||
|
||||
|
|
@ -1,301 +0,0 @@
|
|||
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
|
||||
|
|
@ -1,20 +0,0 @@
|
|||
---
|
||||
cores:
|
||||
my_logic_analyzer:
|
||||
type: logic_analyzer
|
||||
sample_depth: 4096
|
||||
|
||||
probes:
|
||||
larry: 1
|
||||
curly: 1
|
||||
moe: 1
|
||||
shemp: 4
|
||||
|
||||
triggers:
|
||||
- moe RISING
|
||||
- curly FALLING
|
||||
|
||||
uart:
|
||||
port: "auto"
|
||||
baudrate: 115200
|
||||
clock_freq: 100000000
|
||||
|
|
@ -1,42 +0,0 @@
|
|||
`default_nettype none
|
||||
`timescale 1ns/1ps
|
||||
|
||||
module playback_tb();
|
||||
logic clk;
|
||||
|
||||
always begin
|
||||
#5;
|
||||
clk = !clk;
|
||||
end
|
||||
|
||||
logic larry;
|
||||
logic curly;
|
||||
logic moe;
|
||||
logic [3:0] shemp;
|
||||
|
||||
my_logic_analyzer_playback #(.MEM_FILE("capture.mem")) my_logic_analyzer_playback_inst (
|
||||
.clk(clk),
|
||||
.enable(1'b1),
|
||||
|
||||
.larry(larry),
|
||||
.curly(curly),
|
||||
.moe(moe),
|
||||
.shemp(shemp));
|
||||
|
||||
|
||||
initial begin
|
||||
clk = 0;
|
||||
$dumpfile("playback_tb.vcd");
|
||||
$dumpvars(0, playback_tb);
|
||||
|
||||
#(4500*5);
|
||||
$finish();
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
`default_nettype wire
|
||||
|
|
@ -1,33 +0,0 @@
|
|||
`default_nettype none
|
||||
`timescale 1ns / 1ps
|
||||
|
||||
module top_level (
|
||||
input wire clk,
|
||||
|
||||
input wire uart_txd_in,
|
||||
output logic uart_rxd_out
|
||||
);
|
||||
|
||||
logic larry = 0;
|
||||
logic curly = 0;
|
||||
logic moe = 0;
|
||||
logic [3:0] shemp = 0;
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
{shemp, moe, curly, larry} <= {shemp, moe, curly, larry} + 1;
|
||||
end
|
||||
|
||||
manta manta_inst (
|
||||
.clk(clk),
|
||||
|
||||
.rx(uart_txd_in),
|
||||
.tx(uart_rxd_out),
|
||||
|
||||
.larry(larry),
|
||||
.curly(curly),
|
||||
.moe(moe),
|
||||
.shemp(shemp));
|
||||
|
||||
endmodule
|
||||
|
||||
`default_nettype wire
|
||||
|
|
@ -1,260 +0,0 @@
|
|||
## 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
|
||||
|
||||
|
||||
|
|
@ -1,301 +0,0 @@
|
|||
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
|
||||
|
|
@ -1,85 +0,0 @@
|
|||
module ssd(
|
||||
input wire clk_in,
|
||||
input wire rst_in,
|
||||
input wire [31:0] val_in,
|
||||
output reg[6:0] cat_out,
|
||||
output reg[7:0] an_out);
|
||||
|
||||
parameter COUNT_TO = 100000;
|
||||
logic[7:0] segment_state;
|
||||
logic[31:0] segment_counter;
|
||||
logic [3:0] routed_vals;
|
||||
logic [6:0] led_out;
|
||||
|
||||
bto7s mbto7s (.x_in(routed_vals), .s_out(led_out));
|
||||
|
||||
assign cat_out = ~led_out;
|
||||
assign an_out = ~segment_state;
|
||||
|
||||
always @(*) begin
|
||||
case(segment_state)
|
||||
8'b0000_0001: routed_vals = val_in[3:0];
|
||||
8'b0000_0010: routed_vals = val_in[7:4];
|
||||
8'b0000_0100: routed_vals = val_in[11:8];
|
||||
8'b0000_1000: routed_vals = val_in[15:12];
|
||||
8'b0001_0000: routed_vals = val_in[19:16];
|
||||
8'b0010_0000: routed_vals = val_in[23:20];
|
||||
8'b0100_0000: routed_vals = val_in[27:24];
|
||||
8'b1000_0000: routed_vals = val_in[31:28];
|
||||
default: routed_vals = val_in[3:0];
|
||||
endcase
|
||||
end
|
||||
|
||||
always @(posedge clk_in) begin
|
||||
if (rst_in) begin
|
||||
segment_state <= 8'b0000_0001;
|
||||
segment_counter <= 32'b0;
|
||||
end
|
||||
|
||||
else begin
|
||||
if (segment_counter == COUNT_TO) begin
|
||||
segment_counter <= 32'd0;
|
||||
segment_state <= {segment_state[6:0],segment_state[7]};
|
||||
end else begin
|
||||
segment_counter <= segment_counter +1;
|
||||
end
|
||||
end
|
||||
end
|
||||
endmodule
|
||||
|
||||
|
||||
module bto7s(
|
||||
input wire [3:0] x_in,
|
||||
output reg [6:0] s_out);
|
||||
|
||||
reg sa, sb, sc, sd, se, sf, sg;
|
||||
assign s_out = {sg, sf, se, sd, sc, sb, sa};
|
||||
|
||||
// array of bits that are "one hot" with numbers 0 through 15
|
||||
reg [15:0] num;
|
||||
|
||||
assign num[0] = ~x_in[3] && ~x_in[2] && ~x_in[1] && ~x_in[0];
|
||||
assign num[1] = ~x_in[3] && ~x_in[2] && ~x_in[1] && x_in[0];
|
||||
assign num[2] = x_in == 4'd2;
|
||||
assign num[3] = x_in == 4'd3;
|
||||
assign num[4] = x_in == 4'd4;
|
||||
assign num[5] = x_in == 4'd5;
|
||||
assign num[6] = x_in == 4'd6;
|
||||
assign num[7] = x_in == 4'd7;
|
||||
assign num[8] = x_in == 4'd8;
|
||||
assign num[9] = x_in == 4'd9;
|
||||
assign num[10] = x_in == 4'd10;
|
||||
assign num[11] = x_in == 4'd11;
|
||||
assign num[12] = x_in == 4'd12;
|
||||
assign num[13] = x_in == 4'd13;
|
||||
assign num[14] = x_in == 4'd14;
|
||||
assign num[15] = x_in == 4'd15;
|
||||
|
||||
assign sa = num[0] || num[2] || num[3] || num[5] || num[6] || num[7] || num[8] || num[9] || num[10] || num[12] ||num[14] ||num[15];
|
||||
assign sb = num[0] || num[1] || num[2] || num[3] || num[4] || num[7] || num[8] || num[9] || num[10] || num[13];
|
||||
assign sc = num[0] || num[1] || num[3] || num[4] || num[5] || num[6] || num[7] || num[8] || num[9] || num[10] || num[11] || num[13];
|
||||
assign sd = num[0] || num[2] || num[3] || num[5] || num[6] || num[8] || num[9] || num[11] || num[12] || num[13] || num[14];
|
||||
assign se = num[0] || num[2] || num[6] || num[8] || num[10] || num[11] || num[12] || num[13] || num[14] || num[15];
|
||||
assign sf = num[0] || num[4] || num[5] || num[6] || num[8] || num[9] || num[10] || num[11] || num[12] || num[14] || num[15];
|
||||
assign sg = num[2] || num[3] || num[4] || num[5] || num[6] || num[8] || num[9] || num[10] || num[11] || num[13] || num[14] ||num[15];
|
||||
endmodule
|
||||
|
|
@ -0,0 +1 @@
|
|||
../common/ssd.v
|
||||
|
|
@ -21,14 +21,11 @@ module top_level (
|
|||
|
||||
assign led = manta_inst.brx_my_lut_ram_addr;
|
||||
|
||||
logic [6:0] cat;
|
||||
assign {cg,cf,ce,cd,cc,cb,ca} = cat;
|
||||
ssd ssd (
|
||||
.clk_in(clk),
|
||||
.rst_in(btnc),
|
||||
.val_in( {manta_inst.my_lut_ram_btx_rdata, manta_inst.brx_my_lut_ram_wdata} ),
|
||||
.cat_out(cat),
|
||||
.an_out(an));
|
||||
.clk(clk),
|
||||
.val( {manta_inst.my_lut_ram_btx_rdata, manta_inst.brx_my_lut_ram_wdata} ),
|
||||
.cat({cg,cf,ce,cd,cc,cb,ca}),
|
||||
.an(an));
|
||||
|
||||
endmodule
|
||||
|
||||
|
|
@ -1,260 +0,0 @@
|
|||
## 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
|
||||
|
||||
|
||||
|
|
@ -1,301 +0,0 @@
|
|||
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
|
||||
|
|
@ -1 +0,0 @@
|
|||
!manta.v
|
||||
|
|
@ -1,64 +0,0 @@
|
|||
`default_nettype none
|
||||
`timescale 1ns / 1ps
|
||||
|
||||
/* Aggregates the first 64 bits of an incoming
|
||||
* Ethernet transmission (thus shedding the FCS
|
||||
* and anything else extraneous) and outputs the
|
||||
* first 32 bits on an AXI bus for a single cycle.
|
||||
* If the packet is not at least 64 bits long,
|
||||
* nothing happens
|
||||
*
|
||||
* This value can then be fed into the seven
|
||||
* segment display to verify proper operation
|
||||
* of your module!
|
||||
*/
|
||||
|
||||
`define AGR_MAX 48
|
||||
`define AGR_SHOW 64
|
||||
|
||||
module aggregate(clk, rst, axiid, axiiv, axiod, axiov);
|
||||
|
||||
/* batteries */
|
||||
input logic clk, rst;
|
||||
|
||||
/* AXI input valid, and AXI input data from the
|
||||
* Ethernet pipeline. Comprises only data, i.e.
|
||||
* source/destination/ethertype are omitted via
|
||||
* previous stages in the pipeline. Also technically
|
||||
* comprises the FCS, but we assume that the actual
|
||||
* data in the ethernet frame is >= 32 bits long
|
||||
* so we'll lose the FCS in this stage by design
|
||||
*/
|
||||
input logic[1:0] axiid;
|
||||
input logic axiiv;
|
||||
|
||||
/* AXI output valid, and AXI output data. Comprises
|
||||
* just the first 32 bits of the incoming transmission,
|
||||
* asserted for a single cycle
|
||||
*/
|
||||
output logic[47:0] axiod;
|
||||
output logic axiov;
|
||||
|
||||
/* A quick and dirty counter. As long as this is below
|
||||
* 32, we'll dump packets into the AXI output data buffer.
|
||||
* Once the counter gets to AGR_MAX, we'll assert AXI valid.
|
||||
* Then we'll hang until axiiv drops
|
||||
*/
|
||||
logic[31:0] counter;
|
||||
|
||||
assign axiov = counter == `AGR_SHOW;
|
||||
|
||||
always_ff @(posedge clk) begin: COUNTER
|
||||
if (rst || !axiiv) counter <= 32'b0;
|
||||
else counter <= counter + 2;
|
||||
end
|
||||
|
||||
always_ff @(posedge clk) begin: AXIOD
|
||||
if (rst || !axiiv) axiod <= 32'b0;
|
||||
else if (counter < `AGR_MAX && axiiv)
|
||||
axiod[`AGR_MAX - counter - 2 +: 2] <= axiid;
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
||||
`default_nettype wire
|
||||
|
|
@ -1,138 +0,0 @@
|
|||
`default_nettype none
|
||||
`timescale 1ns / 1ps
|
||||
|
||||
/* Ethernet sends packets in least significant
|
||||
* bit order, most significant byte order. This
|
||||
* module is responsible for changing that to
|
||||
* make things legible - in particular, we convert
|
||||
* from LSb/MSB to MSb/MSB.
|
||||
*/
|
||||
|
||||
`define BO_SENDA 2'b00
|
||||
`define BO_SENDB 2'b01
|
||||
`define BO_EMPTYA 2'b10
|
||||
`define BO_EMPTYB 2'b11
|
||||
|
||||
module bitorder(clk, rst, axiiv, axiid, axiod, axiov);
|
||||
|
||||
/* batteries */
|
||||
input logic clk, rst;
|
||||
|
||||
/* AXI input valid and AXI input data
|
||||
* from the module upstream from us in the
|
||||
* pipeline - that being the physical layer
|
||||
* This will transport bits from off the wire
|
||||
* in least significant bit first order
|
||||
*/
|
||||
input logic[1:0] axiid;
|
||||
input logic axiiv;
|
||||
|
||||
/* AXI output valid and AXI output data
|
||||
* Transports the correctly bit-ordered Ethernet
|
||||
* data (most significant bit first) up the pipeline
|
||||
* for further processing...
|
||||
*/
|
||||
output logic[1:0] axiod;
|
||||
output logic axiov;
|
||||
|
||||
/* Two registers to hold data coming in off the wire,
|
||||
* byte by byte. This is where we'll buffer until
|
||||
* we've received a byte of data, at which point
|
||||
* we'll start sending out the byte in the correct
|
||||
* order using one register. Meanwhile, we'll start
|
||||
* receiving into the other register - dual buffers.
|
||||
*/
|
||||
logic[7:0] bufa, bufb;
|
||||
|
||||
/* A counter. This indicates what 'stage' we're in,
|
||||
* and always refers to the index we're reading into
|
||||
* in the receiving buffer or sending out of in the
|
||||
* sending buffer
|
||||
*/
|
||||
logic[2:0] countera, counterb;
|
||||
|
||||
/* Which state we're in - should we be using buffer
|
||||
* A to send, buffer B to send, or neither because
|
||||
* we've just come out of reset?
|
||||
*/
|
||||
logic[1:0] state;
|
||||
|
||||
always_comb begin: AXIOV
|
||||
if (state == `BO_SENDA || state == `BO_SENDB) axiov = 1'b1;
|
||||
else axiov = 1'b0;
|
||||
end
|
||||
|
||||
always_comb begin: AXIOD
|
||||
if (state == `BO_SENDA) axiod = bufa[countera +: 2];
|
||||
else if (state == `BO_SENDB) axiod = bufb[counterb +: 2];
|
||||
else axiod = 1'b0;
|
||||
end
|
||||
|
||||
always_ff @(posedge clk) begin: BUFFERIN
|
||||
if (rst) begin
|
||||
bufa <= 8'b0;
|
||||
bufb <= 8'b0;
|
||||
end else if (axiiv) begin
|
||||
case (state)
|
||||
`BO_EMPTYB, `BO_SENDB:
|
||||
bufa[countera +: 2] <= axiid;
|
||||
`BO_EMPTYA, `BO_SENDA:
|
||||
bufb[counterb +: 2] <= axiid;
|
||||
endcase
|
||||
end else if (state == `BO_EMPTYB || state == `BO_EMPTYA) begin
|
||||
bufa <= 8'b0;
|
||||
bufb <= 8'b0;
|
||||
end
|
||||
end
|
||||
|
||||
always_ff @(posedge clk) begin: STATES
|
||||
if (rst) begin
|
||||
state <= `BO_EMPTYB;
|
||||
countera <= 3'b0;
|
||||
counterb <= 3'b0;
|
||||
end else begin
|
||||
case (state)
|
||||
`BO_EMPTYB: begin
|
||||
if (axiiv) begin
|
||||
if (countera == 3'h6)
|
||||
state <= `BO_SENDA;
|
||||
else countera <= countera + 2;
|
||||
end else countera <= 3'b0;
|
||||
end
|
||||
|
||||
`BO_EMPTYA: begin
|
||||
if (axiiv) begin
|
||||
if (counterb == 3'h6)
|
||||
state <= `BO_SENDB;
|
||||
else counterb <= counterb + 2;
|
||||
end else counterb <= 3'b0;
|
||||
end
|
||||
|
||||
`BO_SENDB: begin
|
||||
if (counterb == 3'h0) state <= `BO_EMPTYB;
|
||||
else counterb <= counterb - 2;
|
||||
|
||||
if (axiiv) begin
|
||||
if (countera == 3'h6)
|
||||
state <= `BO_SENDA;
|
||||
else countera <= countera + 2;
|
||||
end
|
||||
end
|
||||
|
||||
`BO_SENDA: begin
|
||||
if (countera == 3'h0) state <= `BO_EMPTYA;
|
||||
else countera <= countera - 2;
|
||||
|
||||
if (axiiv) begin
|
||||
if (counterb == 3'h6)
|
||||
state <= `BO_SENDB;
|
||||
else counterb <= counterb + 2;
|
||||
end
|
||||
end
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
||||
`default_nettype wire
|
||||
|
|
@ -1,95 +0,0 @@
|
|||
`default_nettype none
|
||||
`timescale 1ns / 1ps
|
||||
|
||||
/* Computes the ethernet checksum
|
||||
* The following combinations of `done` and `kill`
|
||||
* represent the state of the module:
|
||||
*
|
||||
* - done = 0, kill = 0: processing data or freshly reset
|
||||
* - done = 1, kill = 0: correct ethernet checksum verified
|
||||
* - done = 1, kill = 1: data valid set to zero before correct
|
||||
* checksum value computed, therefore bad checksum
|
||||
* - done = 0, kill = 1: never asserted
|
||||
*
|
||||
* the done and/or kill signals are asserted high beginning
|
||||
* the cycle after input data ceases, and until new data
|
||||
* is received via the AXI input
|
||||
*/
|
||||
|
||||
`define CK_FRESH 2'b00
|
||||
`define CK_COMPUTING 2'b01
|
||||
`define CK_DONE 2'b10
|
||||
|
||||
`define MAGIC_CHECK 32'h38_fb_22_84
|
||||
|
||||
module cksum(clk, rst, axiid, axiiv, done, kill);
|
||||
|
||||
/* batteries */
|
||||
input logic clk, rst;
|
||||
|
||||
/* AXI input valid, and AXI input data from the
|
||||
* physical layer. Comprises unmodified data directly
|
||||
* from the wire, in Ethernet bit order, to be fed
|
||||
* directly into the CRC32 module you wrote for the
|
||||
* pset
|
||||
*/
|
||||
input logic[1:0] axiid;
|
||||
input logic axiiv;
|
||||
|
||||
/* Done and kill, as described in the module synopsis */
|
||||
output logic done, kill;
|
||||
|
||||
/* CRC32 AXI output data bus, which is the 32-bit
|
||||
* checksum calculated so far via the checksum module
|
||||
* you implemented in one of the last psets (CRC32-BZIP2)
|
||||
*/
|
||||
logic[31:0] crcd;
|
||||
logic crcv;
|
||||
|
||||
/* Decoupled logic to reset the CRC module independently
|
||||
* Used to compute multiple CRCs back to back
|
||||
*/
|
||||
logic crcrst;
|
||||
|
||||
/* Our finite state machine - bonus points if you can identify
|
||||
* whether this is a Moore or Mealy FSM!
|
||||
*/
|
||||
logic[1:0] state;
|
||||
|
||||
crc32 cksum(.clk(clk),
|
||||
.rst(crcrst | rst),
|
||||
.axiiv(axiiv),
|
||||
.axiid(axiid),
|
||||
.axiov(crcv),
|
||||
.axiod(crcd));
|
||||
|
||||
always_ff @(posedge clk) begin: OUTPUTS
|
||||
if (rst || axiiv) begin
|
||||
done <= 1'b0;
|
||||
kill <= 1'b0;
|
||||
crcrst <= 1'b0;
|
||||
end else begin
|
||||
if (state == `CK_COMPUTING && !axiiv) begin
|
||||
done <= 1'b1;
|
||||
crcrst <= 1'b1;
|
||||
|
||||
if (crcd == `MAGIC_CHECK) kill <= 1'b0;
|
||||
else kill <= 1'b1;
|
||||
end else crcrst <= 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
always_ff @(posedge clk) begin: FSM
|
||||
if (rst) state <= `CK_FRESH;
|
||||
else begin
|
||||
case (state)
|
||||
`CK_FRESH: if (axiiv) state <= `CK_COMPUTING;
|
||||
`CK_COMPUTING: if (!axiiv) state <= `CK_DONE;
|
||||
`CK_DONE: if (axiiv) state <= `CK_COMPUTING;
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
||||
`default_nettype wire
|
||||
|
|
@ -1,74 +0,0 @@
|
|||
`default_nettype none
|
||||
`timescale 1ns / 1ps
|
||||
|
||||
`define LAGGING_SHIFT_IN (caxiod[30] ^ axiid[1])
|
||||
`define LEADING_SHIFT_IN (caxiod[31] ^ axiid[0])
|
||||
`define DOUBLED_SHIFT_IN (`LEADING_SHIFT_IN ^ `LAGGING_SHIFT_IN)
|
||||
|
||||
`define LAGGING_TAPS 4, 7, 10, 16, 22, 26
|
||||
`define DOUBLED_TAPS 2, 5, 8, 11, 12, 23
|
||||
`define LEADING_TAPS 3, 6, 9, 13, 17, 24, 27
|
||||
|
||||
/* this module implements CRC32-BZIP2, with a two bit input:
|
||||
* - poly 0x04C11DB7
|
||||
* - init 0xFFFFFFFF
|
||||
* - NEW: XOR outputs
|
||||
*
|
||||
* == check: 0xfc891918 ==
|
||||
*
|
||||
* this is the ethernet checksum!!
|
||||
*/
|
||||
|
||||
module crc32(clk, rst, axiiv, axiid, axiov, axiod);
|
||||
|
||||
/* old style i/o declaration, for clarity.
|
||||
* easier on 80-char line limits...
|
||||
* use this if you want, we don't care
|
||||
*/
|
||||
input logic clk, rst;
|
||||
|
||||
input logic axiiv;
|
||||
input logic[1:0] axiid;
|
||||
|
||||
output logic axiov;
|
||||
output logic[31:0] axiod;
|
||||
|
||||
logic[31:0] caxiod, saxiod;
|
||||
integer i;
|
||||
|
||||
assign axiov = 1;
|
||||
assign axiod = ~caxiod;
|
||||
|
||||
always @(*) begin
|
||||
for (i = 0; i < 32; i = i + 1) begin
|
||||
case (i)
|
||||
0: saxiod[i] = `LAGGING_SHIFT_IN;
|
||||
1: saxiod[i] = `DOUBLED_SHIFT_IN;
|
||||
|
||||
`LAGGING_TAPS:
|
||||
saxiod[i] = caxiod[i - 2] ^ `LAGGING_SHIFT_IN;
|
||||
`DOUBLED_TAPS:
|
||||
saxiod[i] = caxiod[i - 2] ^ `DOUBLED_SHIFT_IN;
|
||||
`LEADING_TAPS:
|
||||
saxiod[i] = caxiod[i - 2] ^ `LEADING_SHIFT_IN;
|
||||
|
||||
default: saxiod[i] = caxiod[i - 2];
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (rst) caxiod <= 32'hFFFF_FFFF;
|
||||
|
||||
/* our output validity hinges on whether
|
||||
* we are calculating anything or not
|
||||
* on this clock cycle. if there is no
|
||||
* valid input for us, don't do a shift
|
||||
* this cycle
|
||||
*/
|
||||
else caxiod <= (axiiv) ? saxiod : caxiod;
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
||||
`default_nettype wire
|
||||
|
|
@ -1,193 +0,0 @@
|
|||
`default_nettype wire
|
||||
|
||||
// file: divider.sv
|
||||
//
|
||||
// (c) Copyright 2008 - 2013 Xilinx, Inc. All rights reserved.
|
||||
//
|
||||
// This file contains confidential and proprietary information
|
||||
// of Xilinx, Inc. and is protected under U.S. and
|
||||
// international copyright and other intellectual property
|
||||
// laws.
|
||||
//
|
||||
// DISCLAIMER
|
||||
// This disclaimer is not a license and does not grant any
|
||||
// rights to the materials distributed herewith. Except as
|
||||
// otherwise provided in a valid license issued to you by
|
||||
// Xilinx, and to the maximum extent permitted by applicable
|
||||
// law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND
|
||||
// WITH ALL FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES
|
||||
// AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY, INCLUDING
|
||||
// BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-
|
||||
// INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE; and
|
||||
// (2) Xilinx shall not be liable (whether in contract or tort,
|
||||
// including negligence, or under any other theory of
|
||||
// liability) for any loss or damage of any kind or nature
|
||||
// related to, arising under or in connection with these
|
||||
// materials, including for any direct, or any indirect,
|
||||
// special, incidental, or consequential loss or damage
|
||||
// (including loss of data, profits, goodwill, or any type of
|
||||
// loss or damage suffered as a result of any action brought
|
||||
// by a third party) even if such damage or loss was
|
||||
// reasonably foreseeable or Xilinx had been advised of the
|
||||
// possibility of the same.
|
||||
//
|
||||
// CRITICAL APPLICATIONS
|
||||
// Xilinx products are not designed or intended to be fail-
|
||||
// safe, or for use in any application requiring fail-safe
|
||||
// performance, such as life-support or safety devices or
|
||||
// systems, Class III medical devices, nuclear facilities,
|
||||
// applications related to the deployment of airbags, or any
|
||||
// other applications that could lead to death, personal
|
||||
// injury, or severe property or environmental damage
|
||||
// (individually and collectively, "Critical
|
||||
// Applications"). Customer assumes the sole risk and
|
||||
// liability of any use of Xilinx products in Critical
|
||||
// Applications, subject only to applicable laws and
|
||||
// regulations governing limitations on product liability.
|
||||
//
|
||||
// THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS
|
||||
// PART OF THIS FILE AT ALL TIMES.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// User entered comments
|
||||
//----------------------------------------------------------------------------
|
||||
// popopopopopopopopopopop
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// Output Output Phase Duty Cycle Pk-to-Pk Phase
|
||||
// Clock Freq (MHz) (degrees) (%) Jitter (ps) Error (ps)
|
||||
//----------------------------------------------------------------------------
|
||||
// __ethclk__50.00000______0.000______50.0______151.636_____98.575
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// Input Clock Freq (MHz) Input Jitter (UI)
|
||||
//----------------------------------------------------------------------------
|
||||
// __primary_________100.000____________0.010
|
||||
|
||||
`timescale 1ps/1ps
|
||||
|
||||
module divider
|
||||
|
||||
(// Clock in ports
|
||||
// Clock out ports
|
||||
output ethclk,
|
||||
input clk
|
||||
);
|
||||
// Input buffering
|
||||
//------------------------------------
|
||||
wire clk_divider;
|
||||
wire clk_in2_divider;
|
||||
IBUF clkin1_ibufg
|
||||
(.O (clk_divider),
|
||||
.I (clk));
|
||||
|
||||
|
||||
|
||||
|
||||
// Clocking PRIMITIVE
|
||||
//------------------------------------
|
||||
|
||||
// Instantiation of the MMCM PRIMITIVE
|
||||
// * Unused inputs are tied off
|
||||
// * Unused outputs are labeled unused
|
||||
|
||||
wire ethclk_divider;
|
||||
wire clk_out2_divider;
|
||||
wire clk_out3_divider;
|
||||
wire clk_out4_divider;
|
||||
wire clk_out5_divider;
|
||||
wire clk_out6_divider;
|
||||
wire clk_out7_divider;
|
||||
|
||||
wire [15:0] do_unused;
|
||||
wire drdy_unused;
|
||||
wire psdone_unused;
|
||||
wire locked_int;
|
||||
wire clkfbout_divider;
|
||||
wire clkfbout_buf_divider;
|
||||
wire clkfboutb_unused;
|
||||
wire clkout0b_unused;
|
||||
wire clkout1_unused;
|
||||
wire clkout1b_unused;
|
||||
wire clkout2_unused;
|
||||
wire clkout2b_unused;
|
||||
wire clkout3_unused;
|
||||
wire clkout3b_unused;
|
||||
wire clkout4_unused;
|
||||
wire clkout5_unused;
|
||||
wire clkout6_unused;
|
||||
wire clkfbstopped_unused;
|
||||
wire clkinstopped_unused;
|
||||
|
||||
MMCME2_ADV
|
||||
#(.BANDWIDTH ("OPTIMIZED"),
|
||||
.CLKOUT4_CASCADE ("FALSE"),
|
||||
.COMPENSATION ("ZHOLD"),
|
||||
.STARTUP_WAIT ("FALSE"),
|
||||
.DIVCLK_DIVIDE (1),
|
||||
.CLKFBOUT_MULT_F (10.000),
|
||||
.CLKFBOUT_PHASE (0.000),
|
||||
.CLKFBOUT_USE_FINE_PS ("FALSE"),
|
||||
.CLKOUT0_DIVIDE_F (20.000),
|
||||
.CLKOUT0_PHASE (0.000),
|
||||
.CLKOUT0_DUTY_CYCLE (0.500),
|
||||
.CLKOUT0_USE_FINE_PS ("FALSE"),
|
||||
.CLKIN1_PERIOD (10.000))
|
||||
mmcm_adv_inst
|
||||
// Output clocks
|
||||
(
|
||||
.CLKFBOUT (clkfbout_divider),
|
||||
.CLKFBOUTB (clkfboutb_unused),
|
||||
.CLKOUT0 (ethclk_divider),
|
||||
.CLKOUT0B (clkout0b_unused),
|
||||
.CLKOUT1 (clkout1_unused),
|
||||
.CLKOUT1B (clkout1b_unused),
|
||||
.CLKOUT2 (clkout2_unused),
|
||||
.CLKOUT2B (clkout2b_unused),
|
||||
.CLKOUT3 (clkout3_unused),
|
||||
.CLKOUT3B (clkout3b_unused),
|
||||
.CLKOUT4 (clkout4_unused),
|
||||
.CLKOUT5 (clkout5_unused),
|
||||
.CLKOUT6 (clkout6_unused),
|
||||
// Input clock control
|
||||
.CLKFBIN (clkfbout_buf_divider),
|
||||
.CLKIN1 (clk_divider),
|
||||
.CLKIN2 (1'b0),
|
||||
// Tied to always select the primary input clock
|
||||
.CLKINSEL (1'b1),
|
||||
// Ports for dynamic reconfiguration
|
||||
.DADDR (7'h0),
|
||||
.DCLK (1'b0),
|
||||
.DEN (1'b0),
|
||||
.DI (16'h0),
|
||||
.DO (do_unused),
|
||||
.DRDY (drdy_unused),
|
||||
.DWE (1'b0),
|
||||
// Ports for dynamic phase shift
|
||||
.PSCLK (1'b0),
|
||||
.PSEN (1'b0),
|
||||
.PSINCDEC (1'b0),
|
||||
.PSDONE (psdone_unused),
|
||||
// Other control and status signals
|
||||
.LOCKED (locked_int),
|
||||
.CLKINSTOPPED (clkinstopped_unused),
|
||||
.CLKFBSTOPPED (clkfbstopped_unused),
|
||||
.PWRDWN (1'b0),
|
||||
.RST (1'b0));
|
||||
|
||||
// Clock Monitor clock assigning
|
||||
//--------------------------------------
|
||||
// Output buffering
|
||||
//-----------------------------------
|
||||
|
||||
BUFG clkf_buf
|
||||
(.O (clkfbout_buf_divider),
|
||||
.I (clkfbout_divider));
|
||||
|
||||
BUFG clkout1_buf
|
||||
(.O (ethclk),
|
||||
.I (ethclk_divider));
|
||||
|
||||
endmodule
|
||||
|
||||
`default_nettype none
|
||||
|
|
@ -1,139 +0,0 @@
|
|||
`default_nettype none
|
||||
`timescale 1ns / 1ps
|
||||
|
||||
/* This module receives packets from the RJ45 (Ethernet) port on your
|
||||
* FPGA from the _physical layer_, i.e. the electronic (or optical!)
|
||||
* connection between devices running through an Ethernet cable.
|
||||
*
|
||||
* Ethernet is very diverse set of specifications, with all sorts of
|
||||
* different physical layers (which we abbreviate 'the medium' or
|
||||
* 'media' in plural). Ethernet media have transfer speeds ranging
|
||||
* from 1 Mbps to 400 gigabits per second in modern data centers!
|
||||
* For this implementation, we will implement "Fast Ethernet", which
|
||||
* (not fast by today's standards) utilizes a physical layer capable
|
||||
* of 100 Mbps communication. Most modern cables are backwards
|
||||
* compatible with this standard.
|
||||
*/
|
||||
|
||||
/* Note: this file uses tabs instead of spaces for indentation.
|
||||
* More modern editors should pick this up automatically, but if yours
|
||||
* doesn't that might explain trouble getting things to line up. You
|
||||
* can probably configure this (e.g. in vim, type ":set noexpandtab"
|
||||
* in normal mode and then type ":set tabstop=8")
|
||||
*/
|
||||
|
||||
`define EF_IDLE 3'b000
|
||||
`define EF_PREAM 3'b001
|
||||
`define EF_DATA 3'b011
|
||||
`define EF_BAD 3'b101
|
||||
|
||||
`define PREAM_BITS 64
|
||||
`define PREAM_SIZE (`PREAM_BITS / 2)
|
||||
|
||||
`define PREAM_FIRST 2'b00
|
||||
`define PREAM_EXPECT 2'b01
|
||||
`define PREAM_LAST 2'b11
|
||||
`define PREAM_BAD 2'b10
|
||||
|
||||
module ether(clk, rst, rxd, crsdv, axiov, axiod);
|
||||
|
||||
input logic clk, rst;
|
||||
|
||||
/* Carrier Sense (CRS) / Data Valid (DV): indicates
|
||||
* whether there is a valid signal currently being
|
||||
* transmitted over the Ethernet medium by another
|
||||
* sender.
|
||||
*
|
||||
* In the past, >2 computers were connected
|
||||
* to the same Ethernet cable, so this helped
|
||||
* distinguish if one machine was trying to talk over
|
||||
* another. Nowadays, usually Ethernet connections are
|
||||
* point to point (have you ever seen an Ethernet cable
|
||||
* with three ports on it? no? that's what i thought),
|
||||
* and shared media isn't even supported in the 100 Mbps
|
||||
* spec.
|
||||
*
|
||||
* So just use this input to determine whether valid
|
||||
* data is on the line coming in.
|
||||
*/
|
||||
input logic crsdv;
|
||||
|
||||
/* Receive Data (RXD): If crsdv is high, receives
|
||||
* two bits off the wire. Otherwise, undefined
|
||||
* (let's say 2'bXX)
|
||||
*
|
||||
* According to the IEEE 802.3 Fast Ethernet
|
||||
* specification, with the exception of the FCS,
|
||||
* bytes in Ethernet world are sent least significant
|
||||
* bit first, most significant byte first. Confusing!
|
||||
* Basically, if you have a two byte (16 bit) message,
|
||||
* the bits will come in over RXD as:
|
||||
*
|
||||
* 7:6 -> 5:4 -> 3:2 -> 1:0 -> 15:14 -> ... -> 9:8
|
||||
*
|
||||
* For now, this idiosyncracy won't matter to you.
|
||||
* Later, it will.
|
||||
*/
|
||||
input logic[1:0] rxd;
|
||||
|
||||
/* 2-bit AXI output: forward whatever we receive
|
||||
* on to the outside world for further processing
|
||||
*/
|
||||
output logic axiov;
|
||||
output logic[1:0] axiod;
|
||||
|
||||
/* END OF STARTER CODE */
|
||||
|
||||
logic[4:0] count;
|
||||
logic[2:0] state;
|
||||
|
||||
logic[1:0] preamex;
|
||||
logic preamok, start;
|
||||
|
||||
always @(*) begin: PREAM
|
||||
if (count == `PREAM_SIZE - 1) preamex = `PREAM_LAST;
|
||||
else preamex = `PREAM_EXPECT;
|
||||
|
||||
preamok = crsdv && rxd == preamex;
|
||||
end
|
||||
|
||||
always @(*) start = crsdv && rxd != `PREAM_FIRST;
|
||||
|
||||
always @(posedge clk) begin: COUNT
|
||||
if (state == `EF_PREAM) count <= count + 1;
|
||||
else if (state == `EF_IDLE && start) count <= count + 1;
|
||||
else count <= 0;
|
||||
end
|
||||
|
||||
always @(posedge clk) begin: FSM
|
||||
if (rst) begin
|
||||
axiod <= 2'b0;
|
||||
axiov <= 1'b0;
|
||||
state <= 3'b0;
|
||||
end else begin
|
||||
case (state)
|
||||
`EF_BAD: if (!crsdv) state <= `EF_IDLE;
|
||||
`EF_IDLE: if (start) state <= `EF_PREAM;
|
||||
|
||||
`EF_PREAM: begin
|
||||
if (!preamok || !crsdv) state <= `EF_BAD;
|
||||
else if (count == `PREAM_SIZE - 1)
|
||||
state <= `EF_DATA;
|
||||
end
|
||||
|
||||
`EF_DATA: begin
|
||||
if (crsdv) begin
|
||||
axiov <= 1'b1;
|
||||
axiod <= rxd;
|
||||
end else begin
|
||||
axiov <= 1'b0;
|
||||
axiod <= 2'b0;
|
||||
state <= `EF_IDLE;
|
||||
end
|
||||
end
|
||||
endcase
|
||||
end
|
||||
end
|
||||
endmodule
|
||||
|
||||
`default_nettype wire
|
||||
|
|
@ -1,40 +0,0 @@
|
|||
`default_nettype none
|
||||
`timescale 1ns/1ps
|
||||
|
||||
module ethernet_rx (
|
||||
input wire clk,
|
||||
|
||||
input wire crsdv,
|
||||
input wire [1:0] rxd,
|
||||
|
||||
output reg [15:0] addr_o,
|
||||
output reg [15:0] wdata_o,
|
||||
output reg rw_o,
|
||||
output reg valid_o
|
||||
);
|
||||
|
||||
// we know if the packet is a read or write
|
||||
// based on the ethertype.
|
||||
|
||||
reg [15:0] ethertype;
|
||||
reg [31:0] data;
|
||||
reg valid;
|
||||
|
||||
mac_rx mrx (
|
||||
.clk(clk),
|
||||
|
||||
.crsdv(crsdv),
|
||||
.rxd(rxd),
|
||||
|
||||
.ethertype(ethertype),
|
||||
.data(data),
|
||||
.valid(valid));
|
||||
|
||||
assign addr_o = data[31:16];
|
||||
assign wdata_o = data[15:0];
|
||||
assign rw_o = (ethertype == 4);
|
||||
assign valid_o = valid && ((ethertype == 4) || (ethertype == 2));
|
||||
|
||||
endmodule
|
||||
|
||||
`default_nettype wire
|
||||
|
|
@ -1,30 +0,0 @@
|
|||
`default_nettype none
|
||||
`timescale 1ns/1ps
|
||||
|
||||
module ethernet_tx(
|
||||
input wire clk,
|
||||
|
||||
output reg txen,
|
||||
output reg [1:0] txd,
|
||||
|
||||
input wire [15:0] rdata_i,
|
||||
input wire rw_i,
|
||||
input wire valid_i
|
||||
);
|
||||
|
||||
reg [15:0] data_buf = 0;
|
||||
always @(posedge clk) if(~rw_i && valid_i) data_buf <= rdata_i;
|
||||
|
||||
mac_tx mtx (
|
||||
.clk(clk),
|
||||
|
||||
.data(data_buf),
|
||||
.ethertype(16'h2),
|
||||
.start(~rw_i && valid_i),
|
||||
|
||||
.txen(txen),
|
||||
.txd(txd));
|
||||
|
||||
endmodule
|
||||
|
||||
`default_nettype wire
|
||||
|
|
@ -1,121 +0,0 @@
|
|||
`default_nettype none
|
||||
`timescale 1ns / 1ps
|
||||
|
||||
/* Sometimes we might receive packets not
|
||||
* intended for us on the wire. This is especially
|
||||
* true if we're operating in old school mode, where
|
||||
* Ethernet used to have many devices on the same
|
||||
* medium. Alternatively, several virtual NICs may
|
||||
* exist in software on a given machine, or a machine
|
||||
* may support MAC address randomization.
|
||||
*
|
||||
* All of this means we need to make sure inbound
|
||||
* packets are actually intended for us, and not
|
||||
* for some other NIC. That's what this module is
|
||||
* for. In addition, this module will also strip
|
||||
* the MAC address pair (and Ethertype) off of the
|
||||
* Ethernet header, leaving only data and the FCS.
|
||||
* We'll clean up the FCS later...
|
||||
*/
|
||||
|
||||
/* "Intended for us" means the following:
|
||||
* - has the destination MAC "`FW_ME" as defined below. Make this
|
||||
* your own MAC of your choice - get creative!
|
||||
* - has the destination MAC of all 1s, i.e. a 'broadcast' packet
|
||||
*
|
||||
* If these conditions are not met on a given input stream, data
|
||||
* from the packet is dropped / not forwarded on through the
|
||||
* pipeline
|
||||
*/
|
||||
|
||||
`define FW_ME 48'h69_69_5A_06_54_91
|
||||
`define FW_DESTSTART 0
|
||||
`define FW_DESTEND (`FW_DESTSTART + 48)
|
||||
|
||||
`define FW_DATASTART (48 + 48)
|
||||
|
||||
module firewall(clk, rst, axiiv, axiid, axiov, axiod);
|
||||
|
||||
/* batteries */
|
||||
input logic clk, rst;
|
||||
|
||||
/* AXI input valid, and AXI input data from the bit order
|
||||
* flip module. So this will transport MSb/MSB first data
|
||||
* coming off the wire - allowing you to compare with src/dst
|
||||
* MAC addresses a bit more easily
|
||||
*/
|
||||
input logic[1:0] axiid;
|
||||
input logic axiiv;
|
||||
|
||||
/* AXI output valid, and AXI output data. If and only if
|
||||
* the packet is intended for our device as described above,
|
||||
* this line will stream out the _data_ and _fcs_ (NOT the MAC
|
||||
* addresses in the header, nor the ethertype - we're ignoring
|
||||
* the latter this time around) we're receiving off the wire.
|
||||
* If a kill-worthy condition is detected, these lines are
|
||||
* deasserted for the duration of the incoming packet
|
||||
*/
|
||||
output logic[1:0] axiod;
|
||||
output logic axiov;
|
||||
|
||||
/* Buffers to hold our MAC address in the reverse order,
|
||||
* to make comparison easier than it otherwise would be
|
||||
*/
|
||||
logic[0:47] me;
|
||||
|
||||
/* A counter, to determine whether we should be comparing
|
||||
* with a MAC address or stripping off data
|
||||
*/
|
||||
logic[31:0] counter;
|
||||
|
||||
/* An internal set of flags to mark whether the currently
|
||||
* traversing packet is valid, i.e we should forward data,
|
||||
* or not. One of these flags tracks whether the destination
|
||||
* MAC address matches _our_ (FW_ME) mac address, the other
|
||||
* tracks whether the destination matches the broadcast
|
||||
* (FW_BCAST) MAC. If either one of these is high once the
|
||||
* destination MAC finishes rolling through, the packet
|
||||
* is forwarded.
|
||||
*/
|
||||
logic matchme, matchbcast;
|
||||
|
||||
assign me = `FW_ME;
|
||||
|
||||
always_ff @(posedge clk) begin: MATCH
|
||||
if (counter == 32'b0) begin
|
||||
matchme <= 1'b1;
|
||||
matchbcast <= 1'b1;
|
||||
end
|
||||
|
||||
/* could overwrite the above, which is ideal if
|
||||
* FW_DESTSTART == 0 (it is) and we have a mismatch
|
||||
* out the gate
|
||||
*/
|
||||
if (counter >= `FW_DESTSTART && counter < `FW_DESTEND) begin
|
||||
if (axiiv) begin
|
||||
if (axiid != {me[counter], me[counter + 1]})
|
||||
matchme <= 1'b0;
|
||||
if (axiid != 2'b11)
|
||||
matchbcast <= 1'b0;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
always_comb begin: AXIOUT
|
||||
if (counter >= `FW_DATASTART && (matchme | matchbcast)) begin
|
||||
axiod = axiid;
|
||||
axiov = axiiv;
|
||||
end else begin
|
||||
axiod = 2'b00;
|
||||
axiov = 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
always_ff @(posedge clk) begin: COUNTER
|
||||
if (axiiv) counter <= counter + 2;
|
||||
else counter <= 32'b0;
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
||||
`default_nettype wire
|
||||
|
|
@ -1,116 +0,0 @@
|
|||
`default_nettype none
|
||||
`timescale 1ns/1ps
|
||||
|
||||
module mac_rx (
|
||||
input wire clk,
|
||||
|
||||
input wire crsdv,
|
||||
input wire [1:0] rxd,
|
||||
|
||||
output reg [15:0] ethertype,
|
||||
output reg [31:0] data,
|
||||
output reg valid);
|
||||
|
||||
// TODO: rewrite modules to not need external reset
|
||||
reg rst = 1;
|
||||
always @(posedge clk) rst <= 0;
|
||||
|
||||
/* ether -> { cksum, bitorder } */
|
||||
reg[1:0] ether_axiod;
|
||||
reg ether_axiov;
|
||||
|
||||
ether e(
|
||||
.clk(clk),
|
||||
.rst(rst),
|
||||
.rxd(rxd),
|
||||
.crsdv(crsdv),
|
||||
.axiov(ether_axiov),
|
||||
.axiod(ether_axiod));
|
||||
|
||||
/* bitorder -> firewall */
|
||||
reg[1:0] bitorder_axiod;
|
||||
reg bitorder_axiov;
|
||||
|
||||
bitorder b(
|
||||
.clk(clk),
|
||||
.rst(rst),
|
||||
.axiiv(ether_axiov),
|
||||
.axiid(ether_axiod),
|
||||
.axiov(bitorder_axiov),
|
||||
.axiod(bitorder_axiod));
|
||||
|
||||
/* firewall -> aggregate */
|
||||
reg[1:0] firewall_axiod;
|
||||
reg firewall_axiov;
|
||||
|
||||
firewall f(
|
||||
.clk(clk),
|
||||
.rst(rst),
|
||||
.axiiv(bitorder_axiov),
|
||||
.axiid(bitorder_axiod),
|
||||
.axiov(firewall_axiov),
|
||||
.axiod(firewall_axiod));
|
||||
|
||||
/* aggregate output */
|
||||
reg[47:0] aggregate_axiod;
|
||||
reg aggregate_axiov;
|
||||
|
||||
aggregate a(
|
||||
.clk(clk),
|
||||
.rst(rst),
|
||||
.axiiv(firewall_axiov),
|
||||
.axiid(firewall_axiod),
|
||||
.axiov(aggregate_axiov),
|
||||
.axiod(aggregate_axiod));
|
||||
|
||||
/* cksum -> top_level */
|
||||
reg cksum_done;
|
||||
reg cksum_kill;
|
||||
|
||||
cksum c(
|
||||
.clk(clk),
|
||||
.rst(rst),
|
||||
.axiiv(ether_axiov),
|
||||
.axiid(ether_axiod),
|
||||
.done(cksum_done),
|
||||
.kill(cksum_kill));
|
||||
|
||||
// state machine
|
||||
localparam IDLE = 0;
|
||||
localparam WAIT_FOR_DATA = 1;
|
||||
localparam WAIT_FOR_FCS = 2;
|
||||
|
||||
reg [1:0] state = IDLE;
|
||||
|
||||
initial valid = 0;
|
||||
initial data = 0;
|
||||
|
||||
always @(posedge clk) begin
|
||||
valid <= 0;
|
||||
|
||||
if(state == IDLE) begin
|
||||
if(crsdv) state <= WAIT_FOR_DATA;
|
||||
end
|
||||
|
||||
else if(state == WAIT_FOR_DATA) begin
|
||||
if(aggregate_axiov) begin
|
||||
state <= WAIT_FOR_FCS;
|
||||
ethertype <= aggregate_axiod[47:32];
|
||||
data <= aggregate_axiod[31:0];
|
||||
|
||||
end
|
||||
|
||||
// if aggregate never gives us data, go back to idle when the packet ends
|
||||
else if(cksum_done) state <= IDLE;
|
||||
end
|
||||
|
||||
else if(state == WAIT_FOR_FCS) begin
|
||||
if(cksum_done) begin
|
||||
state <= IDLE;
|
||||
valid <= ~cksum_kill;
|
||||
end
|
||||
end
|
||||
end
|
||||
endmodule
|
||||
|
||||
`default_nettype wire
|
||||
|
|
@ -1,248 +0,0 @@
|
|||
`default_nettype none
|
||||
`timescale 1ns/1ps
|
||||
|
||||
module mac_tx (
|
||||
input wire clk,
|
||||
|
||||
// TODO: make this variable width
|
||||
input wire [15:0] data,
|
||||
input wire [15:0] ethertype,
|
||||
input wire start,
|
||||
|
||||
output reg txen,
|
||||
output reg [1:0] txd);
|
||||
|
||||
// packet magic numbers
|
||||
localparam PREAMBLE = {7{8'b01010101}};
|
||||
localparam SFD = 8'b11010101;
|
||||
parameter SRC_MAC = 48'h69_69_5A_06_54_91;
|
||||
parameter DST_MAC = 48'h00_E0_4C_68_1E_0C;
|
||||
|
||||
// all lengths are in units of dibits, hence all the mulitplies by four
|
||||
localparam PREAMBLE_LEN = 7 * 4;
|
||||
localparam SFD_LEN = 1 * 4;
|
||||
localparam SRC_MAC_LEN = 6 * 4;
|
||||
localparam DST_MAC_LEN = 6 * 4;
|
||||
localparam ETHERTYPE_LEN = 2 * 4;
|
||||
localparam PAYLOAD_LEN = 2 * 4;
|
||||
// localparam ZERO_PAD_LEN = (46 * 4) - PAYLOAD_LEN ; // minimum payload size is 46 bytes
|
||||
localparam ZERO_PAD_LEN = (46 * 4) - PAYLOAD_LEN + 4; // minimum payload size is 46 bytes
|
||||
localparam FCS_LEN = 4 * 4;
|
||||
localparam IPG_LEN = 96 / 2;
|
||||
|
||||
// TODO: make crc and bitorder modules not need reset
|
||||
reg rst = 1;
|
||||
always @(posedge clk) rst <= 0;
|
||||
|
||||
reg [1:0] bitorder_axiid;
|
||||
reg [1:0] bitorder_axiod;
|
||||
reg bitorder_axiiv;
|
||||
reg bitorder_axiov;
|
||||
|
||||
bitorder bitorder (
|
||||
.clk(clk),
|
||||
.rst(rst),
|
||||
|
||||
.axiiv(bitorder_axiiv),
|
||||
.axiid(bitorder_axiid),
|
||||
|
||||
.axiov(bitorder_axiov),
|
||||
.axiod(bitorder_axiod));
|
||||
|
||||
reg crc_rst = 1;
|
||||
reg crc_axiiv = 0;
|
||||
reg [31:0] crc_axiod;
|
||||
|
||||
crc32 crc (
|
||||
.clk(clk),
|
||||
.rst(crc_rst),
|
||||
|
||||
.axiiv(crc_axiiv),
|
||||
.axiid(bitorder_axiod),
|
||||
|
||||
// TODO: remove axiov from crc32 module, it's always valid
|
||||
.axiov(),
|
||||
.axiod(crc_axiod));
|
||||
|
||||
|
||||
// state machine
|
||||
reg [8:0] counter = 0;
|
||||
reg [3:0] state = 0;
|
||||
|
||||
localparam IDLE_STATE = 0;
|
||||
localparam PREAMBLE_STATE = 1;
|
||||
localparam SFD_STATE = 2;
|
||||
localparam DST_MAC_STATE = 3;
|
||||
localparam SRC_MAC_STATE = 4;
|
||||
localparam ETHERTYPE_STATE = 5;
|
||||
localparam PAYLOAD_STATE = 6;
|
||||
localparam ZERO_PAD_STATE = 7;
|
||||
localparam FCS_STATE = 8;
|
||||
localparam IPG_STATE = 9;
|
||||
|
||||
|
||||
// sequential logic manages the state machine
|
||||
always @(posedge clk) begin
|
||||
counter <= counter + 1;
|
||||
crc_rst <= 0;
|
||||
|
||||
if(state == IDLE_STATE) begin
|
||||
counter <= 0;
|
||||
crc_axiiv <= 0;
|
||||
if(start) state <= PREAMBLE_STATE;
|
||||
end
|
||||
|
||||
else if(state == PREAMBLE_STATE) begin
|
||||
if(counter == PREAMBLE_LEN - 1) begin
|
||||
counter <= 0;
|
||||
state <= SFD_STATE;
|
||||
end
|
||||
end
|
||||
|
||||
else if(state == SFD_STATE) begin
|
||||
if(counter == SFD_LEN - 1) begin
|
||||
counter <= 0;
|
||||
state <= DST_MAC_STATE;
|
||||
end
|
||||
end
|
||||
|
||||
else if(state == DST_MAC_STATE) begin
|
||||
// this is because the crc module lags behind the FSM,
|
||||
// as it has to go through bitorder first
|
||||
if(counter == 3) crc_axiiv <= 1;
|
||||
|
||||
if(counter == DST_MAC_LEN - 1) begin
|
||||
counter <= 0;
|
||||
state <= SRC_MAC_STATE;
|
||||
end
|
||||
end
|
||||
|
||||
else if(state == SRC_MAC_STATE) begin
|
||||
if(counter == SRC_MAC_LEN - 1) begin
|
||||
counter <= 0;
|
||||
state <= ETHERTYPE_STATE;
|
||||
end
|
||||
end
|
||||
|
||||
else if(state == ETHERTYPE_STATE) begin
|
||||
if(counter == ETHERTYPE_LEN - 1) begin
|
||||
counter <= 0;
|
||||
state <= PAYLOAD_STATE;
|
||||
end
|
||||
end
|
||||
|
||||
else if(state == PAYLOAD_STATE) begin
|
||||
if(counter == PAYLOAD_LEN - 1) begin
|
||||
counter <= 0;
|
||||
state <= ZERO_PAD_STATE;
|
||||
end
|
||||
end
|
||||
|
||||
else if(state == ZERO_PAD_STATE) begin
|
||||
if(counter == ZERO_PAD_LEN - 1) begin
|
||||
crc_axiiv <= 0;
|
||||
counter <= 0;
|
||||
state <= FCS_STATE;
|
||||
end
|
||||
end
|
||||
|
||||
else if(state == FCS_STATE) begin
|
||||
if(counter == FCS_LEN - 1) begin
|
||||
counter <= 0;
|
||||
state <= IPG_STATE;
|
||||
end
|
||||
end
|
||||
|
||||
else if(state == IPG_STATE) begin
|
||||
if(counter == IPG_LEN - 1) begin
|
||||
crc_rst <= 1;
|
||||
counter <= 0;
|
||||
state <= IDLE_STATE;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// combinational logic handles the pipeline
|
||||
always @(*) begin
|
||||
case (state)
|
||||
IDLE_STATE: begin
|
||||
bitorder_axiiv = 0;
|
||||
bitorder_axiid = 0;
|
||||
txen = 0;
|
||||
txd = 0;
|
||||
end
|
||||
|
||||
PREAMBLE_STATE: begin
|
||||
bitorder_axiiv = 1;
|
||||
bitorder_axiid = PREAMBLE[2*(PREAMBLE_LEN-counter)-1-:2];
|
||||
txen = bitorder_axiov;
|
||||
txd = bitorder_axiod;
|
||||
end
|
||||
|
||||
SFD_STATE: begin
|
||||
bitorder_axiiv = 1;
|
||||
bitorder_axiid = SFD[2*(SFD_LEN-counter)-1-:2];
|
||||
txen = bitorder_axiov;
|
||||
txd = bitorder_axiod;
|
||||
end
|
||||
|
||||
DST_MAC_STATE: begin
|
||||
bitorder_axiiv = 1;
|
||||
bitorder_axiid = DST_MAC[2*(DST_MAC_LEN-counter)-1-:2];
|
||||
txen = bitorder_axiov;
|
||||
txd = bitorder_axiod;
|
||||
end
|
||||
|
||||
SRC_MAC_STATE: begin
|
||||
bitorder_axiiv = 1;
|
||||
bitorder_axiid = SRC_MAC[2*(SRC_MAC_LEN-counter)-1-:2];
|
||||
txen = bitorder_axiov;
|
||||
txd = bitorder_axiod;
|
||||
end
|
||||
|
||||
ETHERTYPE_STATE: begin
|
||||
bitorder_axiiv = 1;
|
||||
bitorder_axiid = ethertype[2*(ETHERTYPE_LEN-counter)-1-:2];
|
||||
txen = bitorder_axiov;
|
||||
txd = bitorder_axiod;
|
||||
end
|
||||
|
||||
PAYLOAD_STATE: begin
|
||||
bitorder_axiiv = 1;
|
||||
bitorder_axiid = data[2*(PAYLOAD_LEN-counter)-1-:2];
|
||||
txen = bitorder_axiov;
|
||||
txd = bitorder_axiod;
|
||||
end
|
||||
|
||||
ZERO_PAD_STATE: begin
|
||||
bitorder_axiiv = 1;
|
||||
bitorder_axiid = 0;
|
||||
txen = bitorder_axiov;
|
||||
txd = bitorder_axiod;
|
||||
end
|
||||
|
||||
FCS_STATE: begin
|
||||
bitorder_axiiv = 0;
|
||||
bitorder_axiid = 0;
|
||||
txen = 1;
|
||||
txd = {crc_axiod[2*(FCS_LEN-counter)-2], crc_axiod[2*(FCS_LEN-counter)-1]};
|
||||
end
|
||||
|
||||
IPG_STATE: begin
|
||||
bitorder_axiiv = 0;
|
||||
bitorder_axiid = 0;
|
||||
txen = 0;
|
||||
txd = 0;
|
||||
end
|
||||
|
||||
default: begin
|
||||
bitorder_axiiv = 0;
|
||||
bitorder_axiid = 0;
|
||||
txen = 0;
|
||||
txd = 0;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
endmodule
|
||||
|
||||
`default_nettype wire
|
||||
|
|
@ -1,130 +0,0 @@
|
|||
`default_nettype none
|
||||
`timescale 1ns/1ps
|
||||
/*
|
||||
This playback module was generated with Manta v0.0.0 on 24 Apr 2023 at 22:17:57 by fischerm
|
||||
|
||||
If this breaks or if you've got dank formal verification memes, contact fischerm [at] mit.edu
|
||||
|
||||
Provided under a GNU GPLv3 license. Go wild.
|
||||
|
||||
Here's an example instantiation of the Manta module you configured, feel free to copy-paste
|
||||
this into your source!
|
||||
|
||||
manta manta_inst (
|
||||
.clk(clk),
|
||||
|
||||
.rx(rx),
|
||||
.tx(tx));
|
||||
|
||||
*/
|
||||
|
||||
module manta(
|
||||
input wire clk,
|
||||
|
||||
input wire crsdv,
|
||||
input wire [1:0] rxd,
|
||||
|
||||
output reg txen,
|
||||
output reg [1:0] txd);
|
||||
|
||||
ethernet_rx # (
|
||||
.FPGA_MAC(48'h69_69_5A_06_54_91),
|
||||
.ETHERTYPE(16'h88_B5)
|
||||
) erx (
|
||||
.clk(clk),
|
||||
|
||||
.crsdv(crsdv),
|
||||
.rxd(rxd),
|
||||
|
||||
.addr_o(brx_my_lut_ram_addr),
|
||||
.wdata_o(brx_my_lut_ram_wdata),
|
||||
.rw_o(brx_my_lut_ram_rw),
|
||||
.valid_o(brx_my_lut_ram_valid));
|
||||
|
||||
reg [15:0] brx_my_lut_ram_addr;
|
||||
reg [15:0] brx_my_lut_ram_wdata;
|
||||
reg brx_my_lut_ram_rw;
|
||||
reg brx_my_lut_ram_valid;
|
||||
|
||||
|
||||
lut_ram #(.DEPTH(64)) my_lut_ram (
|
||||
.clk(clk),
|
||||
|
||||
.addr_i(brx_my_lut_ram_addr),
|
||||
.wdata_i(brx_my_lut_ram_wdata),
|
||||
.rdata_i(),
|
||||
.rw_i(brx_my_lut_ram_rw),
|
||||
.valid_i(brx_my_lut_ram_valid),
|
||||
|
||||
.addr_o(),
|
||||
.wdata_o(),
|
||||
.rdata_o(my_lut_ram_btx_rdata),
|
||||
.rw_o(my_lut_ram_btx_rw),
|
||||
.valid_o(my_lut_ram_btx_valid));
|
||||
|
||||
|
||||
reg [15:0] my_lut_ram_btx_rdata;
|
||||
reg my_lut_ram_btx_rw;
|
||||
reg my_lut_ram_btx_valid;
|
||||
|
||||
ethernet_tx #(
|
||||
.FPGA_MAC(48'h69_69_5A_06_54_91),
|
||||
.HOST_MAC(48'h00_E0_4C_68_1E_0C),
|
||||
.ETHERTYPE(16'h88_B5)
|
||||
) etx (
|
||||
.clk(clk),
|
||||
|
||||
.txen(txen),
|
||||
.txd(txd),
|
||||
|
||||
.rdata_i(my_lut_ram_btx_rdata),
|
||||
.rw_i(my_lut_ram_btx_rw),
|
||||
.valid_i(my_lut_ram_btx_valid));
|
||||
|
||||
endmodule
|
||||
|
||||
|
||||
module lut_ram (
|
||||
input wire clk,
|
||||
|
||||
// input port
|
||||
input wire [15:0] addr_i,
|
||||
input wire [15:0] wdata_i,
|
||||
input wire [15:0] rdata_i,
|
||||
input wire rw_i,
|
||||
input wire valid_i,
|
||||
|
||||
// output port
|
||||
output reg [15:0] addr_o,
|
||||
output reg [15:0] wdata_o,
|
||||
output reg [15:0] rdata_o,
|
||||
output reg rw_o,
|
||||
output reg valid_o);
|
||||
|
||||
parameter DEPTH = 8;
|
||||
parameter BASE_ADDR = 0;
|
||||
parameter READ_ONLY = 0;
|
||||
reg [DEPTH-1:0] mem [15:0];
|
||||
|
||||
always @(posedge clk) begin
|
||||
addr_o <= addr_i;
|
||||
wdata_o <= wdata_i;
|
||||
rdata_o <= rdata_i;
|
||||
rw_o <= rw_i;
|
||||
valid_o <= valid_i;
|
||||
rdata_o <= rdata_i;
|
||||
|
||||
|
||||
if(valid_i) begin
|
||||
// check if address is valid
|
||||
if( (addr_i >= BASE_ADDR) && (addr_i <= BASE_ADDR + DEPTH - 1) ) begin
|
||||
|
||||
// read/write
|
||||
if (rw_i && !READ_ONLY) mem[addr_i - BASE_ADDR] <= wdata_i;
|
||||
else rdata_o <= mem[addr_i - BASE_ADDR];
|
||||
end
|
||||
end
|
||||
end
|
||||
endmodule
|
||||
|
||||
`default_nettype wire
|
||||
|
|
@ -1,85 +0,0 @@
|
|||
module ssd(
|
||||
input wire clk_in,
|
||||
input wire rst_in,
|
||||
input wire [31:0] val_in,
|
||||
output reg[6:0] cat_out,
|
||||
output reg[7:0] an_out);
|
||||
|
||||
parameter COUNT_TO = 100000;
|
||||
logic[7:0] segment_state;
|
||||
logic[31:0] segment_counter;
|
||||
logic [3:0] routed_vals;
|
||||
logic [6:0] led_out;
|
||||
|
||||
bto7s mbto7s (.x_in(routed_vals), .s_out(led_out));
|
||||
|
||||
assign cat_out = ~led_out;
|
||||
assign an_out = ~segment_state;
|
||||
|
||||
always @(*) begin
|
||||
case(segment_state)
|
||||
8'b0000_0001: routed_vals = val_in[3:0];
|
||||
8'b0000_0010: routed_vals = val_in[7:4];
|
||||
8'b0000_0100: routed_vals = val_in[11:8];
|
||||
8'b0000_1000: routed_vals = val_in[15:12];
|
||||
8'b0001_0000: routed_vals = val_in[19:16];
|
||||
8'b0010_0000: routed_vals = val_in[23:20];
|
||||
8'b0100_0000: routed_vals = val_in[27:24];
|
||||
8'b1000_0000: routed_vals = val_in[31:28];
|
||||
default: routed_vals = val_in[3:0];
|
||||
endcase
|
||||
end
|
||||
|
||||
always @(posedge clk_in) begin
|
||||
if (rst_in) begin
|
||||
segment_state <= 8'b0000_0001;
|
||||
segment_counter <= 32'b0;
|
||||
end
|
||||
|
||||
else begin
|
||||
if (segment_counter == COUNT_TO) begin
|
||||
segment_counter <= 32'd0;
|
||||
segment_state <= {segment_state[6:0],segment_state[7]};
|
||||
end else begin
|
||||
segment_counter <= segment_counter +1;
|
||||
end
|
||||
end
|
||||
end
|
||||
endmodule
|
||||
|
||||
|
||||
module bto7s(
|
||||
input wire [3:0] x_in,
|
||||
output reg [6:0] s_out);
|
||||
|
||||
reg sa, sb, sc, sd, se, sf, sg;
|
||||
assign s_out = {sg, sf, se, sd, sc, sb, sa};
|
||||
|
||||
// array of bits that are "one hot" with numbers 0 through 15
|
||||
reg [15:0] num;
|
||||
|
||||
assign num[0] = ~x_in[3] && ~x_in[2] && ~x_in[1] && ~x_in[0];
|
||||
assign num[1] = ~x_in[3] && ~x_in[2] && ~x_in[1] && x_in[0];
|
||||
assign num[2] = x_in == 4'd2;
|
||||
assign num[3] = x_in == 4'd3;
|
||||
assign num[4] = x_in == 4'd4;
|
||||
assign num[5] = x_in == 4'd5;
|
||||
assign num[6] = x_in == 4'd6;
|
||||
assign num[7] = x_in == 4'd7;
|
||||
assign num[8] = x_in == 4'd8;
|
||||
assign num[9] = x_in == 4'd9;
|
||||
assign num[10] = x_in == 4'd10;
|
||||
assign num[11] = x_in == 4'd11;
|
||||
assign num[12] = x_in == 4'd12;
|
||||
assign num[13] = x_in == 4'd13;
|
||||
assign num[14] = x_in == 4'd14;
|
||||
assign num[15] = x_in == 4'd15;
|
||||
|
||||
assign sa = num[0] || num[2] || num[3] || num[5] || num[6] || num[7] || num[8] || num[9] || num[10] || num[12] ||num[14] ||num[15];
|
||||
assign sb = num[0] || num[1] || num[2] || num[3] || num[4] || num[7] || num[8] || num[9] || num[10] || num[13];
|
||||
assign sc = num[0] || num[1] || num[3] || num[4] || num[5] || num[6] || num[7] || num[8] || num[9] || num[10] || num[11] || num[13];
|
||||
assign sd = num[0] || num[2] || num[3] || num[5] || num[6] || num[8] || num[9] || num[11] || num[12] || num[13] || num[14];
|
||||
assign se = num[0] || num[2] || num[6] || num[8] || num[10] || num[11] || num[12] || num[13] || num[14] || num[15];
|
||||
assign sf = num[0] || num[4] || num[5] || num[6] || num[8] || num[9] || num[10] || num[11] || num[12] || num[14] || num[15];
|
||||
assign sg = num[2] || num[3] || num[4] || num[5] || num[6] || num[8] || num[9] || num[10] || num[11] || num[13] || num[14] ||num[15];
|
||||
endmodule
|
||||
|
|
@ -0,0 +1 @@
|
|||
../common/ssd.v
|
||||
|
|
@ -38,14 +38,11 @@ module top_level (
|
|||
assign led16_r = manta_inst.brx_my_lut_ram_rw;
|
||||
assign led17_r = manta_inst.brx_my_lut_ram_valid;
|
||||
|
||||
logic [6:0] cat;
|
||||
assign {cg,cf,ce,cd,cc,cb,ca} = cat;
|
||||
ssd ssd (
|
||||
.clk_in(clk_50mhz),
|
||||
.rst_in(btnc),
|
||||
.val_in( {manta_inst.my_lut_ram_btx_rdata, manta_inst.brx_my_lut_ram_wdata} ),
|
||||
.cat_out(cat),
|
||||
.an_out(an));
|
||||
.clk(clk_50mhz),
|
||||
.val( {manta_inst.my_lut_ram_btx_rdata, manta_inst.brx_my_lut_ram_wdata} ),
|
||||
.cat({cg,cf,ce,cd,cc,cb,ca}),
|
||||
.an(an));
|
||||
|
||||
manta manta_inst (
|
||||
.clk(clk_50mhz),
|
||||
|
|
@ -1,301 +0,0 @@
|
|||
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
|
||||
|
|
@ -1,301 +0,0 @@
|
|||
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
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
---
|
||||
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
|
||||
|
|
@ -1,27 +0,0 @@
|
|||
`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
|
||||
|
|
@ -1,198 +0,0 @@
|
|||
|
||||
// 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
|
||||
|
|
@ -1,276 +0,0 @@
|
|||
/* 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
|
||||
|
|
@ -1,56 +0,0 @@
|
|||
`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
|
||||
|
|
@ -1,260 +0,0 @@
|
|||
## 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
|
||||
|
||||
|
||||
|
Before Width: | Height: | Size: 68 KiB After Width: | Height: | Size: 68 KiB |
|
Before Width: | Height: | Size: 93 KiB After Width: | Height: | Size: 93 KiB |
|
Before Width: | Height: | Size: 58 KiB After Width: | Height: | Size: 58 KiB |
|
|
@ -1,241 +0,0 @@
|
|||
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:
|
||||
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'
|
||||
|
||||
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
|
||||
|
|
@ -1,85 +0,0 @@
|
|||
module ssd(
|
||||
input wire clk_in,
|
||||
input wire rst_in,
|
||||
input wire [31:0] val_in,
|
||||
output reg[6:0] cat_out,
|
||||
output reg[7:0] an_out);
|
||||
|
||||
parameter COUNT_TO = 100000;
|
||||
logic[7:0] segment_state;
|
||||
logic[31:0] segment_counter;
|
||||
logic [3:0] routed_vals;
|
||||
logic [6:0] led_out;
|
||||
|
||||
bto7s mbto7s (.x_in(routed_vals), .s_out(led_out));
|
||||
|
||||
assign cat_out = ~led_out;
|
||||
assign an_out = ~segment_state;
|
||||
|
||||
always @(*) begin
|
||||
case(segment_state)
|
||||
8'b0000_0001: routed_vals = val_in[3:0];
|
||||
8'b0000_0010: routed_vals = val_in[7:4];
|
||||
8'b0000_0100: routed_vals = val_in[11:8];
|
||||
8'b0000_1000: routed_vals = val_in[15:12];
|
||||
8'b0001_0000: routed_vals = val_in[19:16];
|
||||
8'b0010_0000: routed_vals = val_in[23:20];
|
||||
8'b0100_0000: routed_vals = val_in[27:24];
|
||||
8'b1000_0000: routed_vals = val_in[31:28];
|
||||
default: routed_vals = val_in[3:0];
|
||||
endcase
|
||||
end
|
||||
|
||||
always @(posedge clk_in) begin
|
||||
if (rst_in) begin
|
||||
segment_state <= 8'b0000_0001;
|
||||
segment_counter <= 32'b0;
|
||||
end
|
||||
|
||||
else begin
|
||||
if (segment_counter == COUNT_TO) begin
|
||||
segment_counter <= 32'd0;
|
||||
segment_state <= {segment_state[6:0],segment_state[7]};
|
||||
end else begin
|
||||
segment_counter <= segment_counter +1;
|
||||
end
|
||||
end
|
||||
end
|
||||
endmodule
|
||||
|
||||
|
||||
module bto7s(
|
||||
input wire [3:0] x_in,
|
||||
output reg [6:0] s_out);
|
||||
|
||||
reg sa, sb, sc, sd, se, sf, sg;
|
||||
assign s_out = {sg, sf, se, sd, sc, sb, sa};
|
||||
|
||||
// array of bits that are "one hot" with numbers 0 through 15
|
||||
reg [15:0] num;
|
||||
|
||||
assign num[0] = ~x_in[3] && ~x_in[2] && ~x_in[1] && ~x_in[0];
|
||||
assign num[1] = ~x_in[3] && ~x_in[2] && ~x_in[1] && x_in[0];
|
||||
assign num[2] = x_in == 4'd2;
|
||||
assign num[3] = x_in == 4'd3;
|
||||
assign num[4] = x_in == 4'd4;
|
||||
assign num[5] = x_in == 4'd5;
|
||||
assign num[6] = x_in == 4'd6;
|
||||
assign num[7] = x_in == 4'd7;
|
||||
assign num[8] = x_in == 4'd8;
|
||||
assign num[9] = x_in == 4'd9;
|
||||
assign num[10] = x_in == 4'd10;
|
||||
assign num[11] = x_in == 4'd11;
|
||||
assign num[12] = x_in == 4'd12;
|
||||
assign num[13] = x_in == 4'd13;
|
||||
assign num[14] = x_in == 4'd14;
|
||||
assign num[15] = x_in == 4'd15;
|
||||
|
||||
assign sa = num[0] || num[2] || num[3] || num[5] || num[6] || num[7] || num[8] || num[9] || num[10] || num[12] ||num[14] ||num[15];
|
||||
assign sb = num[0] || num[1] || num[2] || num[3] || num[4] || num[7] || num[8] || num[9] || num[10] || num[13];
|
||||
assign sc = num[0] || num[1] || num[3] || num[4] || num[5] || num[6] || num[7] || num[8] || num[9] || num[10] || num[11] || num[13];
|
||||
assign sd = num[0] || num[2] || num[3] || num[5] || num[6] || num[8] || num[9] || num[11] || num[12] || num[13] || num[14];
|
||||
assign se = num[0] || num[2] || num[6] || num[8] || num[10] || num[11] || num[12] || num[13] || num[14] || num[15];
|
||||
assign sf = num[0] || num[4] || num[5] || num[6] || num[8] || num[9] || num[10] || num[11] || num[12] || num[14] || num[15];
|
||||
assign sg = num[2] || num[3] || num[4] || num[5] || num[6] || num[8] || num[9] || num[10] || num[11] || num[13] || num[14] ||num[15];
|
||||
endmodule
|
||||
|
|
@ -0,0 +1 @@
|
|||
../../common/ssd.v
|
||||
|
|
@ -95,14 +95,11 @@
|
|||
// debug
|
||||
assign led = manta_inst.brx_image_mem_addr;
|
||||
|
||||
logic [6:0] cat;
|
||||
assign {cg,cf,ce,cd,cc,cb,ca} = cat;
|
||||
ssd ssd (
|
||||
.clk_in(clk_65mhz),
|
||||
.rst_in(btnc),
|
||||
.val_in( {manta_inst.image_mem_btx_rdata, manta_inst.brx_image_mem_wdata} ),
|
||||
.cat_out(cat),
|
||||
.an_out(an));
|
||||
.clk(clk_65mhz),
|
||||
.val( {manta_inst.image_mem_btx_rdata, manta_inst.brx_image_mem_wdata} ),
|
||||
.cat({cg,cf,ce,cd,cc,cb,ca}),
|
||||
.an(an));
|
||||
endmodule
|
||||
|
||||
`default_nettype wire
|
||||
|
|
|
|||
Loading…
Reference in New Issue