add working ethernet verilog autogeneration woot woot :)
This commit is contained in:
parent
1d2171faad
commit
54b97fd120
|
|
@ -4,7 +4,5 @@ cores:
|
||||||
type: lut_ram
|
type: lut_ram
|
||||||
size: 64
|
size: 64
|
||||||
|
|
||||||
uart:
|
ethernet:
|
||||||
port: "auto"
|
interface: "en8"
|
||||||
baudrate: 115200
|
|
||||||
clock_freq: 100000000
|
|
||||||
|
|
@ -3,10 +3,20 @@ from random import randint
|
||||||
|
|
||||||
m = Manta('manta.yaml')
|
m = Manta('manta.yaml')
|
||||||
|
|
||||||
for addr in range(m.my_lut_ram.size):
|
from manta import Manta
|
||||||
write_data = randint(0, (2**16)-1)
|
from time import sleep
|
||||||
m.my_lut_ram.write(addr, write_data)
|
|
||||||
|
|
||||||
read_data = m.my_lut_ram.read(addr)
|
m = Manta("manta.yaml")
|
||||||
print(f"test addr: {addr} with data: {write_data}")
|
print(m.my_lut_ram.read(0))
|
||||||
print(f" -> correct data received on readback?: {write_data == read_data}")
|
|
||||||
|
m.my_lut_ram.write(0, 5)
|
||||||
|
|
||||||
|
print(m.my_lut_ram.read(0))
|
||||||
|
|
||||||
|
# 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,124 +0,0 @@
|
||||||
from scapy.all import *
|
|
||||||
|
|
||||||
src_mac = "00:E0:4C:68:1E:0C" # for manta.mit.edu's ethernet adapter
|
|
||||||
dst_mac = "69:69:5A:06:54:91"
|
|
||||||
ifc = "enx00e04c681e0c"
|
|
||||||
|
|
||||||
def read_register(addr):
|
|
||||||
pkt = Ether()
|
|
||||||
pkt.src = src_mac
|
|
||||||
pkt.dst = dst_mac
|
|
||||||
pkt.type = 0x0002
|
|
||||||
|
|
||||||
# two bytes of address, and 44 of padding
|
|
||||||
# makes the 46 byte minimum length
|
|
||||||
msg = addr.to_bytes(2, 'big') + 44*b'\x00'
|
|
||||||
|
|
||||||
pkt = pkt / msg
|
|
||||||
pkt.load = msg
|
|
||||||
|
|
||||||
sniffer = AsyncSniffer(iface = ifc, filter="ether src 69:69:5a:06:54:91")
|
|
||||||
sniffer.start()
|
|
||||||
from time import sleep
|
|
||||||
time.sleep(0.1)
|
|
||||||
sendp(pkt, iface=ifc, verbose = 0)
|
|
||||||
results = sniffer.stop()
|
|
||||||
|
|
||||||
assert len(results) == 1, "Received more packets than expected!"
|
|
||||||
|
|
||||||
for packet in results:
|
|
||||||
raw_response_bytes = bytes(packet.payload)[0:2]
|
|
||||||
data = int.from_bytes(raw_response_bytes, 'big')
|
|
||||||
return data
|
|
||||||
|
|
||||||
def write_register(addr, data):
|
|
||||||
pkt = Ether()
|
|
||||||
pkt.src = src_mac
|
|
||||||
pkt.dst = dst_mac
|
|
||||||
pkt.type = 0x0004
|
|
||||||
|
|
||||||
# two bytes of address, two bytes of
|
|
||||||
# data, and 42 of padding makes the 46 byte
|
|
||||||
# minimum length
|
|
||||||
msg = addr.to_bytes(2, 'big') + data.to_bytes(2, 'big') + 42*b'\x00'
|
|
||||||
|
|
||||||
pkt = pkt / msg
|
|
||||||
pkt.load = msg
|
|
||||||
sendp(pkt, iface=ifc, verbose = 0)
|
|
||||||
|
|
||||||
def read_batch(addrs):
|
|
||||||
pkts = []
|
|
||||||
for addr in addrs:
|
|
||||||
pkt = Ether()
|
|
||||||
pkt.src = src_mac
|
|
||||||
pkt.dst = dst_mac
|
|
||||||
pkt.type = 0x0002
|
|
||||||
|
|
||||||
# two bytes of address, and 44 of padding
|
|
||||||
# makes the 46 byte minimum length
|
|
||||||
msg = addr.to_bytes(2, 'big') + 44*b'\x00'
|
|
||||||
|
|
||||||
pkt = pkt / msg
|
|
||||||
pkt.load = msg
|
|
||||||
pkts.append(pkt)
|
|
||||||
|
|
||||||
sniffer = AsyncSniffer(iface = ifc, count = len(addrs), filter="ether src 69:69:5a:06:54:91")
|
|
||||||
sniffer.start()
|
|
||||||
from time import sleep
|
|
||||||
time.sleep(0.1)
|
|
||||||
|
|
||||||
sendp(pkts, iface=ifc, verbose = 0)
|
|
||||||
sniffer.join()
|
|
||||||
results = sniffer.results
|
|
||||||
|
|
||||||
assert len(results) == len(addrs), "Received more packets than expected!"
|
|
||||||
|
|
||||||
datas = []
|
|
||||||
for packet in results:
|
|
||||||
raw_response_bytes = bytes(packet.payload)[0:2]
|
|
||||||
data = int.from_bytes(raw_response_bytes, 'big')
|
|
||||||
datas.append(data)
|
|
||||||
|
|
||||||
return datas
|
|
||||||
|
|
||||||
def write_batch(addrs, data):
|
|
||||||
pkts = []
|
|
||||||
for i in range(len(addrs)):
|
|
||||||
pkt = Ether()
|
|
||||||
pkt.src = src_mac
|
|
||||||
pkt.dst = dst_mac
|
|
||||||
pkt.type = 0x0002
|
|
||||||
|
|
||||||
addr = addrs[i]
|
|
||||||
data = datas[i]
|
|
||||||
|
|
||||||
# two bytes of address, two bytes of
|
|
||||||
# data, and 42 of padding makes the 46 byte
|
|
||||||
# minimum length
|
|
||||||
msg = addr.to_bytes(2, 'big') + data.to_bytes(2, 'big') + 42*b'\x00'
|
|
||||||
|
|
||||||
pkt = pkt / msg
|
|
||||||
pkt.load = msg
|
|
||||||
|
|
||||||
sendp(pkts, iface=ifc, verbose = 0)
|
|
||||||
|
|
||||||
|
|
||||||
from time import sleep
|
|
||||||
if __name__ == "__main__":
|
|
||||||
for addr in range(64):
|
|
||||||
data = addr
|
|
||||||
write_register(addr, data)
|
|
||||||
retval = read_register(addr)
|
|
||||||
if retval != addr:
|
|
||||||
print(f"ERROR: sent {data} got {retval}")
|
|
||||||
|
|
||||||
else:
|
|
||||||
print(f"SUCCESS: sent {data} got {retval}")
|
|
||||||
|
|
||||||
# addrs = [i for i in range(64)]
|
|
||||||
# datas = addrs
|
|
||||||
# write_batch(addrs, datas)
|
|
||||||
# print("done")
|
|
||||||
# retvals = read_batch(addrs)
|
|
||||||
# print(retvals)
|
|
||||||
|
|
||||||
|
|
@ -3,10 +3,6 @@
|
||||||
|
|
||||||
module top_level (
|
module top_level (
|
||||||
input wire clk,
|
input wire clk,
|
||||||
input wire btnc,
|
|
||||||
input wire btnd,
|
|
||||||
|
|
||||||
input wire [15:0] sw,
|
|
||||||
|
|
||||||
output logic [15:0] led,
|
output logic [15:0] led,
|
||||||
output logic ca, cb, cc, cd, ce, cf, cg,
|
output logic ca, cb, cc, cd, ce, cf, cg,
|
||||||
|
|
@ -22,13 +18,9 @@ module top_level (
|
||||||
input wire [1:0] eth_rxd,
|
input wire [1:0] eth_rxd,
|
||||||
|
|
||||||
output reg eth_txen,
|
output reg eth_txen,
|
||||||
output reg [1:0] eth_txd,
|
output reg [1:0] eth_txd);
|
||||||
|
|
||||||
input wire uart_txd_in,
|
assign eth_rstn = 1;
|
||||||
output logic uart_rxd_out
|
|
||||||
);
|
|
||||||
|
|
||||||
assign eth_rstn = ~btnc;
|
|
||||||
|
|
||||||
logic clk_50mhz;
|
logic clk_50mhz;
|
||||||
assign eth_refclk = clk_50mhz;
|
assign eth_refclk = clk_50mhz;
|
||||||
|
|
|
||||||
|
|
@ -17,22 +17,22 @@ create_clock -add -name sys_clk_pin -period 10.00 -waveform {0 5} [get_ports {cl
|
||||||
|
|
||||||
##Switches
|
##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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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]
|
# set_property -dict { PACKAGE_PIN V10 IOSTANDARD LVCMOS33 } [get_ports { sw[15] }]; #IO_L21P_T3_DQS_14 Sch=sw[15]
|
||||||
|
|
||||||
|
|
||||||
## LEDs
|
## LEDs
|
||||||
|
|
@ -88,11 +88,11 @@ set_property -dict { PACKAGE_PIN U13 IOSTANDARD LVCMOS33 } [get_ports { an[7]
|
||||||
|
|
||||||
# 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 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 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 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 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 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
|
# set_property -dict { PACKAGE_PIN P18 IOSTANDARD LVCMOS33 } [get_ports { btnd }]; #IO_L9N_T1_DQS_D13_14 Sch=btnd
|
||||||
|
|
||||||
|
|
||||||
##Pmod Headers
|
##Pmod Headers
|
||||||
|
|
@ -222,10 +222,10 @@ set_property -dict { PACKAGE_PIN P18 IOSTANDARD LVCMOS33 } [get_ports { btnd }
|
||||||
|
|
||||||
##USB-RS232 Interface
|
##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 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 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 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
|
# set_property -dict { PACKAGE_PIN E5 IOSTANDARD LVCMOS33 } [get_ports { uart_rts }]; #IO_L5N_T0_AD13N_35 Sch=uart_rts
|
||||||
|
|
||||||
##USB HID (PS/2)
|
##USB HID (PS/2)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,10 @@ class Manta:
|
||||||
# set interface
|
# set interface
|
||||||
if "uart" in config:
|
if "uart" in config:
|
||||||
self.interface = UARTInterface(config["uart"])
|
self.interface = UARTInterface(config["uart"])
|
||||||
|
|
||||||
|
elif "ethernet" in config:
|
||||||
|
self.interface = EthernetInterface(config["ethernet"])
|
||||||
|
|
||||||
else:
|
else:
|
||||||
raise ValueError("Unrecognized interface specified.")
|
raise ValueError("Unrecognized interface specified.")
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,203 @@
|
||||||
|
from .verilog_manipulator import *
|
||||||
|
|
||||||
|
from scapy.interfaces import get_if_list
|
||||||
|
from scapy.arch import get_if_hwaddr
|
||||||
|
from scapy.layers.l2 import Ether
|
||||||
|
from scapy.sendrecv import AsyncSniffer, sendp, sendpfast
|
||||||
|
from time import sleep
|
||||||
|
|
||||||
|
class EthernetInterface:
|
||||||
|
def __init__(self, config):
|
||||||
|
# Warn if unrecognized options have been given
|
||||||
|
for option in config:
|
||||||
|
if option not in ["interface", "host mac", "fpga mac", "ethertype", "tcpreplay", "verbose"]:
|
||||||
|
print(f"Warning: Ignoring unrecognized option '{option}' in Ethernet interface.")
|
||||||
|
|
||||||
|
# Obtain interface.
|
||||||
|
assert "interface" in config, "No interface provided for Ethernet core."
|
||||||
|
if config["interface"] not in get_if_list():
|
||||||
|
print(f"Warning: Interface specified is not detected by the host.")
|
||||||
|
self.iface = config["interface"]
|
||||||
|
|
||||||
|
# Obtain Host MAC address
|
||||||
|
if self.iface in get_if_list():
|
||||||
|
self.host_mac = get_if_hwaddr(self.iface)
|
||||||
|
else:
|
||||||
|
assert "host mac" in config, \
|
||||||
|
"Can't automatically detect host mac address from interface, host mac must be manually provided"
|
||||||
|
self.host_mac = config["host mac"]
|
||||||
|
|
||||||
|
# Obtain FPGA MAC address
|
||||||
|
# - the default address is a locally administered unicast address,
|
||||||
|
# which is an important distinction. please refer to:
|
||||||
|
# https://en.wikipedia.org/wiki/MAC_address#Ranges_of_group_and_locally_administered_addresses
|
||||||
|
self.fpga_mac = "12:34:56:78:9A:BC"
|
||||||
|
if "fpga mac" in config:
|
||||||
|
self.fpga_mac = config["fpga mac"]
|
||||||
|
|
||||||
|
# Obtain Ethertype
|
||||||
|
# - the default ethertype being used is reserved for local
|
||||||
|
# experimentation by the IEEE - and might not make it beyond
|
||||||
|
# your NIC as a result.
|
||||||
|
self.ethertype = 0x88B5
|
||||||
|
if "ethertype" in config:
|
||||||
|
self.ethertype = int(config["ethertype"], 16)
|
||||||
|
|
||||||
|
# Set whether we use tcpreplay for faster packet blasting
|
||||||
|
self.send_packet = sendp
|
||||||
|
if "tcpreplay" in config:
|
||||||
|
assert isinstance(config["tcpreplay"], bool), \
|
||||||
|
"tcpreplay configuration option must be boolean!"
|
||||||
|
self.send_packet = sendpfast if config["tcpreplay"] else sendp
|
||||||
|
|
||||||
|
self.verbose = False
|
||||||
|
if "verbose" in config:
|
||||||
|
assert isinstance(config["verbose"], bool), \
|
||||||
|
"verbose configuration option must be boolean!"
|
||||||
|
self.verbose = config["verbose"]
|
||||||
|
|
||||||
|
def read_register(self, addr):
|
||||||
|
pkt = Ether()
|
||||||
|
pkt.src = self.host_mac
|
||||||
|
pkt.dst = self.fpga_mac
|
||||||
|
pkt.type = self.ethertype
|
||||||
|
|
||||||
|
# one byte of rw, two bytes of address, and 44 of padding
|
||||||
|
# makes the 46 byte minimum length
|
||||||
|
msg = b'\x00' + addr.to_bytes(2, 'big') + 43*b'\x00'
|
||||||
|
|
||||||
|
pkt = pkt / msg
|
||||||
|
pkt.load = msg
|
||||||
|
|
||||||
|
sniffer = AsyncSniffer(iface = self.iface, filter=f"ether src {self.fpga_mac}")
|
||||||
|
sniffer.start()
|
||||||
|
sleep(0.1)
|
||||||
|
|
||||||
|
self.send_packet(pkt, iface=self.iface, verbose = 0)
|
||||||
|
|
||||||
|
results = sniffer.stop()
|
||||||
|
|
||||||
|
assert len(results) == 1, "Received more packets than expected!"
|
||||||
|
|
||||||
|
raw_response_bytes = bytes(results[0].payload)[0:2]
|
||||||
|
return int.from_bytes(raw_response_bytes, 'big')
|
||||||
|
|
||||||
|
def write_register(self, addr, data):
|
||||||
|
pkt = Ether()
|
||||||
|
pkt.src = self.host_mac
|
||||||
|
pkt.dst = self.fpga_mac
|
||||||
|
pkt.type = self.ethertype
|
||||||
|
|
||||||
|
# one byte of rw, two bytes of address, two bytes of
|
||||||
|
# data, and 42 of padding makes the 46 byte
|
||||||
|
# minimum length
|
||||||
|
msg = b'\x01' + addr.to_bytes(2, 'big') + data.to_bytes(2, 'big') + 41*b'\x00'
|
||||||
|
|
||||||
|
pkt = pkt / msg
|
||||||
|
pkt.load = msg
|
||||||
|
self.send_packet(pkt, iface=self.iface, verbose = self.verbose)
|
||||||
|
|
||||||
|
# def read_batch(addrs):
|
||||||
|
# pkts = []
|
||||||
|
# for addr in addrs:
|
||||||
|
# pkt = Ether()
|
||||||
|
# pkt.src = src_mac
|
||||||
|
# pkt.dst = dst_mac
|
||||||
|
# pkt.type = 0x0002
|
||||||
|
|
||||||
|
# # two bytes of address, and 44 of padding
|
||||||
|
# # makes the 46 byte minimum length
|
||||||
|
# msg = addr.to_bytes(2, 'big') + 44*b'\x00'
|
||||||
|
|
||||||
|
# pkt = pkt / msg
|
||||||
|
# pkt.load = msg
|
||||||
|
# pkts.append(pkt)
|
||||||
|
|
||||||
|
# sniffer = AsyncSniffer(iface = iface, count = len(addrs), filter="ether src 69:69:5a:06:54:91")
|
||||||
|
# sniffer.start()
|
||||||
|
# from time import sleep
|
||||||
|
# time.sleep(0.1)
|
||||||
|
|
||||||
|
# sendp(pkts, iface=iface, verbose = 0)
|
||||||
|
# sniffer.join()
|
||||||
|
# results = sniffer.results
|
||||||
|
|
||||||
|
# assert len(results) == len(addrs), "Received more packets than expected!"
|
||||||
|
|
||||||
|
# datas = []
|
||||||
|
# for packet in results:
|
||||||
|
# raw_response_bytes = bytes(packet.payload)[0:2]
|
||||||
|
# data = int.from_bytes(raw_response_bytes, 'big')
|
||||||
|
# datas.append(data)
|
||||||
|
|
||||||
|
# return datas
|
||||||
|
|
||||||
|
# def write_batch(addrs, data):
|
||||||
|
# pkts = []
|
||||||
|
# for i in range(len(addrs)):
|
||||||
|
# pkt = Ether()
|
||||||
|
# pkt.src = src_mac
|
||||||
|
# pkt.dst = dst_mac
|
||||||
|
# pkt.type = 0x0002
|
||||||
|
|
||||||
|
# addr = addrs[i]
|
||||||
|
# data = datas[i]
|
||||||
|
|
||||||
|
# # two bytes of address, two bytes of
|
||||||
|
# # data, and 42 of padding makes the 46 byte
|
||||||
|
# # minimum length
|
||||||
|
# msg = addr.to_bytes(2, 'big') + data.to_bytes(2, 'big') + 42*b'\x00'
|
||||||
|
|
||||||
|
# pkt = pkt / msg
|
||||||
|
# pkt.load = msg
|
||||||
|
|
||||||
|
# sendp(pkts, iface=iface, verbose = 0)
|
||||||
|
|
||||||
|
def hdl_top_level_ports(self):
|
||||||
|
return ["input wire crsdv", \
|
||||||
|
"input wire [1:0] rxd", \
|
||||||
|
"output reg txen", \
|
||||||
|
"output reg [1:0] txd"]
|
||||||
|
|
||||||
|
def rx_hdl_def(self):
|
||||||
|
tx = VerilogManipulator("ethernet/ethernet_rx.v").get_hdl() + "\n"
|
||||||
|
tx += VerilogManipulator("ethernet/mac_rx.v").get_hdl() + "\n"
|
||||||
|
tx += VerilogManipulator("ethernet/ether.v").get_hdl() + "\n"
|
||||||
|
tx += VerilogManipulator("ethernet/bitorder.v").get_hdl() + "\n"
|
||||||
|
tx += VerilogManipulator("ethernet/firewall.v").get_hdl() + "\n"
|
||||||
|
tx += VerilogManipulator("ethernet/aggregate.v").get_hdl() + "\n"
|
||||||
|
tx += VerilogManipulator("ethernet/crc32.v").get_hdl() + "\n"
|
||||||
|
tx += VerilogManipulator("ethernet/cksum.v").get_hdl() + "\n"
|
||||||
|
return tx
|
||||||
|
|
||||||
|
def tx_hdl_def(self):
|
||||||
|
tx = VerilogManipulator("ethernet/ethernet_tx.v").get_hdl() + "\n"
|
||||||
|
tx += VerilogManipulator("ethernet/mac_tx.v").get_hdl() + "\n"
|
||||||
|
tx += VerilogManipulator("ethernet/bitorder.v").get_hdl() + "\n"
|
||||||
|
tx += VerilogManipulator("ethernet/crc32.v").get_hdl() + "\n"
|
||||||
|
return tx
|
||||||
|
|
||||||
|
def rx_hdl_inst(self):
|
||||||
|
rx = VerilogManipulator("ethernet/ethernet_rx_inst_tmpl.v")
|
||||||
|
|
||||||
|
fpga_mac_verilog_literal = "48'h" + self.fpga_mac.replace(":", "_").upper()
|
||||||
|
rx.sub(fpga_mac_verilog_literal, "/* FPGA_MAC */")
|
||||||
|
|
||||||
|
ethertype_verilog_literal = f"16'h{self.ethertype:02X}"
|
||||||
|
rx.sub(ethertype_verilog_literal, "/* ETHERTYPE */")
|
||||||
|
|
||||||
|
return rx.get_hdl()
|
||||||
|
|
||||||
|
def tx_hdl_inst(self):
|
||||||
|
tx = VerilogManipulator("ethernet/ethernet_tx_inst_tmpl.v")
|
||||||
|
|
||||||
|
fpga_mac_verilog_literal = "48'h" + self.fpga_mac.replace(":", "_").upper()
|
||||||
|
tx.sub(fpga_mac_verilog_literal, "/* FPGA_MAC */")
|
||||||
|
|
||||||
|
host_mac_verilog_literal = "48'h" + self.host_mac.replace(":", "_").upper()
|
||||||
|
tx.sub(host_mac_verilog_literal, "/* HOST_MAC */")
|
||||||
|
|
||||||
|
ethertype_verilog_literal = f"16'h{self.ethertype:02X}"
|
||||||
|
tx.sub(ethertype_verilog_literal, "/* ETHERTYPE */")
|
||||||
|
|
||||||
|
return tx.get_hdl()
|
||||||
|
|
@ -16,12 +16,12 @@ module ethernet_rx (
|
||||||
parameter FPGA_MAC = 0;
|
parameter FPGA_MAC = 0;
|
||||||
parameter ETHERTYPE = 0;
|
parameter ETHERTYPE = 0;
|
||||||
|
|
||||||
reg [31:0] data;
|
reg [39:0] payload;
|
||||||
reg valid;
|
reg valid;
|
||||||
|
|
||||||
mac_rx #(
|
mac_rx #(
|
||||||
.DST_MAC(48'h69_69_5A_06_54_91),
|
.FPGA_MAC(FPGA_MAC),
|
||||||
.ETHERTYPE(16'h88_B5)
|
.ETHERTYPE(ETHERTYPE)
|
||||||
) mrx (
|
) mrx (
|
||||||
.clk(clk),
|
.clk(clk),
|
||||||
|
|
||||||
|
|
@ -29,13 +29,12 @@ module ethernet_rx (
|
||||||
.rxd(rxd),
|
.rxd(rxd),
|
||||||
|
|
||||||
.payload(payload),
|
.payload(payload),
|
||||||
.length(length)
|
|
||||||
.valid(valid));
|
.valid(valid));
|
||||||
|
|
||||||
|
assign rw_o = (payload[39:32] == 8'd1);
|
||||||
assign addr_o = payload[31:16];
|
assign addr_o = payload[31:16];
|
||||||
assign wdata_o = payload[15:0];
|
assign wdata_o = payload[15:0];
|
||||||
assign rw_o = (length == 4);
|
assign valid_o = valid && ( payload[39:32] == 8'd0 || payload[39:32] == 8'd1);
|
||||||
assign valid_o = valid && ((length == 4) || (length == 2));
|
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
ethernet_rx #(
|
||||||
|
.FPGA_MAC(/* FPGA_MAC */),
|
||||||
|
.ETHERTYPE(/* ETHERTYPE */)
|
||||||
|
) erx (
|
||||||
|
.clk(clk),
|
||||||
|
|
||||||
|
.crsdv(crsdv),
|
||||||
|
.rxd(rxd),
|
||||||
|
|
||||||
|
.addr_o(),
|
||||||
|
.wdata_o(),
|
||||||
|
.rw_o(),
|
||||||
|
.valid_o());
|
||||||
|
|
@ -25,7 +25,7 @@ module ethernet_tx (
|
||||||
.SRC_MAC(FPGA_MAC),
|
.SRC_MAC(FPGA_MAC),
|
||||||
.DST_MAC(HOST_MAC),
|
.DST_MAC(HOST_MAC),
|
||||||
.ETHERTYPE(ETHERTYPE),
|
.ETHERTYPE(ETHERTYPE),
|
||||||
.PAYLOAD_LENGTH_BYTES(2)
|
.PAYLOAD_LENGTH_BYTES(5)
|
||||||
) mtx (
|
) mtx (
|
||||||
.clk(clk),
|
.clk(clk),
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
ethernet_tx #(
|
||||||
|
.FPGA_MAC(/* FPGA_MAC */),
|
||||||
|
.HOST_MAC(/* HOST_MAC */),
|
||||||
|
.ETHERTYPE(/* ETHERTYPE */)
|
||||||
|
) etx (
|
||||||
|
.clk(clk),
|
||||||
|
|
||||||
|
.rdata_i(),
|
||||||
|
.rw_i(),
|
||||||
|
.valid_i(),
|
||||||
|
|
||||||
|
.txen(txen),
|
||||||
|
.txd(txd));
|
||||||
|
|
@ -15,7 +15,7 @@ manta manta_inst (
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
module manta(
|
module manta (
|
||||||
input wire clk,
|
input wire clk,
|
||||||
|
|
||||||
/* TOP_LEVEL_PORTS */);
|
/* TOP_LEVEL_PORTS */);
|
||||||
|
|
|
||||||
|
|
@ -4,8 +4,8 @@ rx_uart #(.CLOCKS_PER_BAUD(/* CLOCKS_PER_BAUD */)) urx (
|
||||||
.o_wr(urx_brx_axiv),
|
.o_wr(urx_brx_axiv),
|
||||||
.o_data(urx_brx_axid));
|
.o_data(urx_brx_axid));
|
||||||
|
|
||||||
logic [7:0] urx_brx_axid;
|
reg [7:0] urx_brx_axid;
|
||||||
logic urx_brx_axiv;
|
reg urx_brx_axiv;
|
||||||
|
|
||||||
bridge_rx brx (
|
bridge_rx brx (
|
||||||
.clk(clk),
|
.clk(clk),
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue