enforce consistent naming of lut_mem module
This commit is contained in:
parent
54b97fd120
commit
9c5ea31d14
|
|
@ -32,8 +32,8 @@ jobs:
|
|||
- name: Build logic_analyzer
|
||||
run: make nexys_a7_logic_analyzer
|
||||
|
||||
- name: Build lut_ram
|
||||
run: make nexys_a7_lut_ram
|
||||
- name: Build lut_mem
|
||||
run: make nexys_a7_lut_mem
|
||||
|
||||
icestick_examples:
|
||||
runs-on: ubuntu-latest
|
||||
|
|
@ -62,5 +62,5 @@ jobs:
|
|||
- name: Build io_core
|
||||
run: make icestick_io_core
|
||||
|
||||
- name: Build lut_ram
|
||||
run: make icestick_lut_ram
|
||||
- name: Build lut_mem
|
||||
run: make icestick_lut_mem
|
||||
26
Makefile
26
Makefile
|
|
@ -29,7 +29,7 @@ auto_gen:
|
|||
python3 test/auto_gen/run_tests.py
|
||||
|
||||
# Functional Simulation
|
||||
functional_sim: io_core_tb logic_analyzer_tb bit_fifo_tb bridge_rx_tb bridge_tx_tb lut_ram_tb
|
||||
functional_sim: io_core_tb logic_analyzer_tb bit_fifo_tb bridge_rx_tb bridge_tx_tb lut_mem_tb
|
||||
|
||||
mac_tb:
|
||||
iverilog -g2012 -o sim.out -y src/manta test/functional_sim/mac_tb.sv
|
||||
|
|
@ -72,8 +72,8 @@ bridge_tx_tb:
|
|||
vvp sim.out
|
||||
rm sim.out
|
||||
|
||||
lut_ram_tb:
|
||||
iverilog -g2012 -o sim.out -y src/manta test/functional_sim/lut_ram_tb.sv
|
||||
lut_mem_tb:
|
||||
iverilog -g2012 -o sim.out -y src/manta test/functional_sim/lut_mem_tb.sv
|
||||
vvp sim.out
|
||||
rm sim.out
|
||||
|
||||
|
|
@ -81,7 +81,7 @@ lut_ram_tb:
|
|||
|
||||
examples: icestick nexys_a7
|
||||
|
||||
nexys_a7: nexys_a7_video_sprite nexys_a7_io_core nexys_a7_ps2_logic_analyzer nexys_a7_lut_ram
|
||||
nexys_a7: nexys_a7_video_sprite nexys_a7_io_core nexys_a7_ps2_logic_analyzer nexys_a7_lut_mem
|
||||
|
||||
nexys_a7_video_sprite:
|
||||
cd examples/nexys_a7/video_sprite; \
|
||||
|
|
@ -99,20 +99,20 @@ nexys_a7_ps2_logic_analyzer:
|
|||
manta playback manta.yaml my_logic_analyzer sim/playback.v; \
|
||||
build
|
||||
|
||||
nexys_a7_lut_ram:
|
||||
cd examples/nexys_a7/lut_ram/; \
|
||||
nexys_a7_lut_mem:
|
||||
cd examples/nexys_a7/lut_mem/; \
|
||||
manta gen manta.yaml manta.v; \
|
||||
build
|
||||
|
||||
icestick: icestick_io_core icestick_lut_ram
|
||||
icestick: icestick_io_core icestick_lut_mem
|
||||
|
||||
icestick_io_core:
|
||||
cd examples/icestick/io_core/; \
|
||||
manta gen manta.yaml manta.v; \
|
||||
./build.sh
|
||||
|
||||
icestick_lut_ram:
|
||||
cd examples/icestick/lut_ram/; \
|
||||
icestick_lut_mem:
|
||||
cd examples/icestick/lut_mem/; \
|
||||
manta gen manta.yaml manta.v; \
|
||||
./build.sh
|
||||
|
||||
|
|
@ -123,11 +123,11 @@ clean_examples:
|
|||
rm -f examples/nexys_a7/logic_analyzer/obj/*
|
||||
rm -f examples/nexys_a7/logic_analyzer/src/manta.v
|
||||
|
||||
rm -f examples/nexys_a7/lut_ram/obj/*
|
||||
rm -f examples/nexys_a7/lut_ram/src/manta.v
|
||||
rm -f examples/nexys_a7/lut_mem/obj/*
|
||||
rm -f examples/nexys_a7/lut_mem/src/manta.v
|
||||
|
||||
rm -f examples/icestick/io_core/*.bin
|
||||
rm -f examples/icestick/io_core/manta.v
|
||||
|
||||
rm -f examples/icestick/lut_ram/*.bin
|
||||
rm -f examples/icestick/lut_ram/manta.v
|
||||
rm -f examples/icestick/lut_mem/*.bin
|
||||
rm -f examples/icestick/lut_mem/manta.v
|
||||
|
|
@ -10,8 +10,8 @@ Just like every core, a given LUT Memory core is described in Manta's configurat
|
|||
|
||||
```yaml
|
||||
cores:
|
||||
my_lut_ram:
|
||||
type: lut_ram
|
||||
my_lut_mem:
|
||||
type: lut_mem
|
||||
size: 64
|
||||
```
|
||||
|
||||
|
|
@ -21,9 +21,9 @@ Each register is 16-bits wide, so the only configuration option is just the size
|
|||
The core can be written to and read from in Python with the following:
|
||||
|
||||
```python
|
||||
m.my_lut_ram.write(addr, data)
|
||||
foo = m.my_lut_ram.read(addr)
|
||||
m.my_lut_mem.write(addr, data)
|
||||
foo = m.my_lut_mem.read(addr)
|
||||
```
|
||||
|
||||
## Examples
|
||||
A LUT Memory core is used in the lut_ram examples, for both the [nexys_a7](https://github.com/fischermoseley/manta/tree/main/examples/nexys_a7/lut_ram) and the [icestick](https://github.com/fischermoseley/manta/tree/main/examples/icestick/lut_ram).
|
||||
A LUT Memory core is used in the lut_mem examples, for both the [nexys_a7](https://github.com/fischermoseley/manta/tree/main/examples/nexys_a7/lut_mem_uart) and the [icestick](https://github.com/fischermoseley/manta/tree/main/examples/icestick/lut_mem).
|
||||
|
|
@ -42,7 +42,7 @@ For example, `M1234\r\n` specifies a read operation at address `0x1234` in the m
|
|||
|
||||
## Python API
|
||||
|
||||
The Python API has two main purposes: to generate the Verilog required to instantiate debug cores on the FPGA, and to let the user easily interact with said cores. The exact Verilog and memory operations are dependent on the cores being configured and the interface between the host machine and the FPGA. This information is stored in a YAML (or JSON) configuration file, which is used to configure an instance of the `Manta` class. This maintains instances of `IOCore`, `LogicAnalyzerCore`, `LUTRAMCore`, and `BRAMCore` according to the given configuration.
|
||||
The Python API has two main purposes: to generate the Verilog required to instantiate debug cores on the FPGA, and to let the user easily interact with said cores. The exact Verilog and memory operations are dependent on the cores being configured and the interface between the host machine and the FPGA. This information is stored in a YAML (or JSON) configuration file, which is used to configure an instance of the `Manta` class. This maintains instances of `IOCore`, `LogicAnalyzerCore`, `LUTMemoryCore`, and `BRAMCore` according to the given configuration.
|
||||
|
||||
### Loading configuration
|
||||
|
||||
|
|
@ -78,8 +78,8 @@ cores:
|
|||
triggers:
|
||||
- larry && curly && ~moe
|
||||
|
||||
my_lut_ram:
|
||||
type: lut_ram
|
||||
my_lut_mem:
|
||||
type: lut_mem
|
||||
size: 64
|
||||
|
||||
uart:
|
||||
|
|
@ -88,7 +88,7 @@ uart:
|
|||
clock_freq: 100000000
|
||||
```
|
||||
|
||||
For each core in the config file, an instance of the corresponding Python object is added to the `Manta` object. For instance, the `Manta` instance created by the configuration above will include an `IOCore`, a `LogicAnalyzerCore`, and a `LUTRAMCore`. Each Core object is instantiated by providing the appropriate section of the config file - for instance, the logic analyzer in the config above will be created by calling `LogicAnalyzerCore(foo)`, where `foo` is:
|
||||
For each core in the config file, an instance of the corresponding Python object is added to the `Manta` object. For instance, the `Manta` instance created by the configuration above will include an `IOCore`, a `LogicAnalyzerCore`, and a `LUTMemoryCore`. Each Core object is instantiated by providing the appropriate section of the config file - for instance, the logic analyzer in the config above will be created by calling `LogicAnalyzerCore(foo)`, where `foo` is:
|
||||
|
||||
```yaml
|
||||
my_logic_analyzer:
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
---
|
||||
cores:
|
||||
my_lut_ram:
|
||||
type: lut_ram
|
||||
size: 64
|
||||
my_lut_mem:
|
||||
type: lut_mem
|
||||
size: 64
|
||||
|
||||
uart:
|
||||
port: "auto"
|
||||
|
|
|
|||
|
|
@ -3,10 +3,10 @@ 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)
|
||||
for addr in range(m.my_lut_mem.size):
|
||||
write_data = randint(0, (2**16)-1)
|
||||
m.my_lut_mem.write(addr, write_data)
|
||||
|
||||
read_data = m.my_lut_ram.read(addr)
|
||||
read_data = m.my_lut_mem.read(addr)
|
||||
print(f"test addr: {addr} with data: {write_data}")
|
||||
print(f" -> correct data received on readback?: {write_data == read_data}")
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
---
|
||||
cores:
|
||||
my_lut_mem:
|
||||
type: lut_mem
|
||||
size: 64
|
||||
|
||||
ethernet:
|
||||
interface: "en3"
|
||||
|
|
@ -7,16 +7,16 @@ from manta import Manta
|
|||
from time import sleep
|
||||
|
||||
m = Manta("manta.yaml")
|
||||
print(m.my_lut_ram.read(0))
|
||||
print(m.my_lut_mem.read(0))
|
||||
|
||||
m.my_lut_ram.write(0, 5)
|
||||
m.my_lut_mem.write(0, 5)
|
||||
|
||||
print(m.my_lut_ram.read(0))
|
||||
print(m.my_lut_mem.read(0))
|
||||
|
||||
# for addr in range(m.my_lut_ram.size):
|
||||
# for addr in range(m.my_lut_mem.size):
|
||||
# write_data = randint(0, (2**16)-1)
|
||||
# m.my_lut_ram.write(addr, write_data)
|
||||
# m.my_lut_mem.write(addr, write_data)
|
||||
|
||||
# read_data = m.my_lut_ram.read(addr)
|
||||
# read_data = m.my_lut_mem.read(addr)
|
||||
# print(f"test addr: {addr} with data: {write_data}")
|
||||
# print(f" -> correct data received on readback?: {write_data == read_data}")
|
||||
|
|
@ -26,13 +26,13 @@ module top_level (
|
|||
assign eth_refclk = clk_50mhz;
|
||||
divider d (.clk(clk), .ethclk(clk_50mhz));
|
||||
|
||||
assign led = manta_inst.brx_my_lut_ram_addr;
|
||||
assign led16_r = manta_inst.brx_my_lut_ram_rw;
|
||||
assign led17_r = manta_inst.brx_my_lut_ram_valid;
|
||||
assign led = manta_inst.brx_my_lut_mem_addr;
|
||||
assign led16_r = manta_inst.brx_my_lut_mem_rw;
|
||||
assign led17_r = manta_inst.brx_my_lut_mem_valid;
|
||||
|
||||
ssd ssd (
|
||||
.clk(clk_50mhz),
|
||||
.val( {manta_inst.my_lut_ram_btx_rdata, manta_inst.brx_my_lut_ram_wdata} ),
|
||||
.val( {manta_inst.my_lut_mem_btx_rdata, manta_inst.brx_my_lut_mem_wdata} ),
|
||||
.cat({cg,cf,ce,cd,cc,cb,ca}),
|
||||
.an(an));
|
||||
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
---
|
||||
cores:
|
||||
my_lut_mem:
|
||||
type: lut_mem
|
||||
size: 64
|
||||
|
||||
uart:
|
||||
port: "auto"
|
||||
baudrate: 115200
|
||||
clock_freq: 100000000
|
||||
|
|
@ -3,10 +3,10 @@ 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)
|
||||
for addr in range(m.my_lut_mem.size):
|
||||
write_data = randint(0, (2**16)-1)
|
||||
m.my_lut_mem.write(addr, write_data)
|
||||
|
||||
read_data = m.my_lut_ram.read(addr)
|
||||
read_data = m.my_lut_mem.read(addr)
|
||||
print(f"test addr: {addr} with data: {write_data}")
|
||||
print(f" -> correct data received on readback?: {write_data == read_data}")
|
||||
|
|
@ -19,11 +19,11 @@ module top_level (
|
|||
.rx(uart_txd_in),
|
||||
.tx(uart_rxd_out));
|
||||
|
||||
assign led = manta_inst.brx_my_lut_ram_addr;
|
||||
assign led = manta_inst.brx_my_lut_mem_addr;
|
||||
|
||||
ssd ssd (
|
||||
.clk(clk),
|
||||
.val( {manta_inst.my_lut_ram_btx_rdata, manta_inst.brx_my_lut_ram_wdata} ),
|
||||
.val( {manta_inst.my_lut_mem_btx_rdata, manta_inst.brx_my_lut_mem_wdata} ),
|
||||
.cat({cg,cf,ce,cd,cc,cb,ca}),
|
||||
.an(an));
|
||||
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
---
|
||||
cores:
|
||||
my_lut_ram:
|
||||
type: lut_ram
|
||||
size: 64
|
||||
|
||||
uart:
|
||||
port: "auto"
|
||||
baudrate: 115200
|
||||
clock_freq: 100000000
|
||||
|
|
@ -1,8 +0,0 @@
|
|||
---
|
||||
cores:
|
||||
my_lut_ram:
|
||||
type: lut_ram
|
||||
size: 64
|
||||
|
||||
ethernet:
|
||||
interface: "en8"
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
This playback module was generated with Manta v0.0.5 on 26 Apr 2023 at 12:42:05 by fischerm
|
||||
This playback module was generated with Manta v0.0.5 on 27 Apr 2023 at 11:59:33 by fischerm
|
||||
|
||||
If this breaks or if you've got dank formal verification memes, contact fischerm [at] mit.edu
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
---
|
||||
cores:
|
||||
image_mem:
|
||||
type: block_memory
|
||||
type: block_mem
|
||||
width: 12
|
||||
depth: 16384
|
||||
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
# Internal Dependencies
|
||||
from .verilog_manipulator import *
|
||||
from .uart import *
|
||||
from .ethernet import *
|
||||
from .logic_analyzer import *
|
||||
from .io import *
|
||||
from .block_memory import *
|
||||
from .lut_ram import *
|
||||
from .hdl_utils import *
|
||||
from .uart_iface import *
|
||||
from .ether_iface import *
|
||||
from .la_core import *
|
||||
from .io_core import *
|
||||
from .block_mem_core import *
|
||||
from .lut_mem_core import *
|
||||
|
||||
# External Dependencies
|
||||
from sys import argv
|
||||
|
|
@ -47,10 +47,10 @@ class Manta:
|
|||
elif core["type"] == "io":
|
||||
new_core = IOCore(core, core_name, base_addr, self.interface)
|
||||
|
||||
elif core["type"] == "lut_ram":
|
||||
new_core = LUTRAMCore(core, core_name, base_addr, self.interface)
|
||||
elif core["type"] == "lut_mem":
|
||||
new_core = LUTMemoryCore(core, core_name, base_addr, self.interface)
|
||||
|
||||
elif core["type"] == "block_memory":
|
||||
elif core["type"] == "block_mem":
|
||||
new_core = BlockMemoryCore(core, core_name, base_addr, self.interface)
|
||||
|
||||
else:
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
from .verilog_manipulator import *
|
||||
from ..hdl_utils import *
|
||||
|
||||
import math
|
||||
from math import ceil, log2
|
||||
|
||||
class BlockMemoryCore:
|
||||
def __init__(self, config, name, base_addr, interface):
|
||||
|
|
@ -33,20 +33,20 @@ class BlockMemoryCore:
|
|||
assert isinstance(config["width"], int), "Block Memory core must have integer width."
|
||||
self.width = config["width"]
|
||||
|
||||
self.addr_width = math.ceil(math.log2(self.depth))
|
||||
self.n_brams = math.ceil(self.width / 16)
|
||||
self.addr_width = ceil(log2(self.depth))
|
||||
self.n_brams = ceil(self.width / 16)
|
||||
self.max_addr = self.base_addr + (self.depth * self.n_brams)
|
||||
|
||||
def hdl_inst(self):
|
||||
inst = VerilogManipulator("block_memory/block_memory_inst_tmpl.v")
|
||||
inst = VerilogManipulator("block_mem_core/block_memory_inst_tmpl.v")
|
||||
inst.sub(self.name, "/* INST_NAME */")
|
||||
inst.sub(self.depth, "/* DEPTH */")
|
||||
inst.sub(self.width, "/* WIDTH */")
|
||||
return inst.get_hdl()
|
||||
|
||||
def hdl_def(self):
|
||||
block_memory = VerilogManipulator("block_memory/block_memory.v").get_hdl()
|
||||
dual_port_bram = VerilogManipulator("block_memory/dual_port_bram.v").get_hdl()
|
||||
block_memory = VerilogManipulator("block_mem_core/block_memory.v").get_hdl()
|
||||
dual_port_bram = VerilogManipulator("block_mem_core/dual_port_bram.v").get_hdl()
|
||||
return block_memory + "\n" + dual_port_bram
|
||||
|
||||
def hdl_top_level_ports(self):
|
||||
|
|
@ -1,16 +1,18 @@
|
|||
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
|
||||
from ..hdl_utils import *
|
||||
|
||||
class EthernetInterface:
|
||||
def __init__(self, config):
|
||||
|
||||
# Lazy and selective imports for quick builds!
|
||||
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
|
||||
|
||||
# Warn if unrecognized options have been given
|
||||
for option in config:
|
||||
if option not in ["interface", "host mac", "fpga mac", "ethertype", "tcpreplay", "verbose"]:
|
||||
if option not in ["interface", "host_mac", "fpga_mac", "ethertype", "tcpreplay", "verbose"]:
|
||||
print(f"Warning: Ignoring unrecognized option '{option}' in Ethernet interface.")
|
||||
|
||||
# Obtain interface.
|
||||
|
|
@ -23,17 +25,17 @@ class EthernetInterface:
|
|||
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"]
|
||||
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"]
|
||||
if "fpga_mac" in config:
|
||||
self.fpga_mac = config["fpga_mac"]
|
||||
|
||||
# Obtain Ethertype
|
||||
# - the default ethertype being used is reserved for local
|
||||
|
|
@ -160,25 +162,25 @@ class EthernetInterface:
|
|||
"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"
|
||||
tx = VerilogManipulator("ether_iface/ethernet_rx.v").get_hdl() + "\n"
|
||||
tx += VerilogManipulator("ether_iface/mac_rx.v").get_hdl() + "\n"
|
||||
tx += VerilogManipulator("ether_iface/ether.v").get_hdl() + "\n"
|
||||
tx += VerilogManipulator("ether_iface/bitorder.v").get_hdl() + "\n"
|
||||
tx += VerilogManipulator("ether_iface/firewall.v").get_hdl() + "\n"
|
||||
tx += VerilogManipulator("ether_iface/aggregate.v").get_hdl() + "\n"
|
||||
tx += VerilogManipulator("ether_iface/crc32.v").get_hdl() + "\n"
|
||||
tx += VerilogManipulator("ether_iface/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"
|
||||
tx = VerilogManipulator("ether_iface/ethernet_tx.v").get_hdl() + "\n"
|
||||
tx += VerilogManipulator("ether_iface/mac_tx.v").get_hdl() + "\n"
|
||||
tx += VerilogManipulator("ether_iface/bitorder.v").get_hdl() + "\n"
|
||||
tx += VerilogManipulator("ether_iface/crc32.v").get_hdl() + "\n"
|
||||
return tx
|
||||
|
||||
def rx_hdl_inst(self):
|
||||
rx = VerilogManipulator("ethernet/ethernet_rx_inst_tmpl.v")
|
||||
rx = VerilogManipulator("ether_iface/ethernet_rx_inst_tmpl.v")
|
||||
|
||||
fpga_mac_verilog_literal = "48'h" + self.fpga_mac.replace(":", "_").upper()
|
||||
rx.sub(fpga_mac_verilog_literal, "/* FPGA_MAC */")
|
||||
|
|
@ -189,7 +191,7 @@ class EthernetInterface:
|
|||
return rx.get_hdl()
|
||||
|
||||
def tx_hdl_inst(self):
|
||||
tx = VerilogManipulator("ethernet/ethernet_tx_inst_tmpl.v")
|
||||
tx = VerilogManipulator("ether_iface/ethernet_tx_inst_tmpl.v")
|
||||
|
||||
fpga_mac_verilog_literal = "48'h" + self.fpga_mac.replace(":", "_").upper()
|
||||
tx.sub(fpga_mac_verilog_literal, "/* FPGA_MAC */")
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
from .verilog_manipulator import *
|
||||
from ..hdl_utils import *
|
||||
|
||||
class IOCoreProbe:
|
||||
def __init__(self, name, width, direction, base_addr, interface):
|
||||
|
|
@ -76,7 +76,7 @@ class IOCore:
|
|||
|
||||
|
||||
def hdl_inst(self):
|
||||
inst = VerilogManipulator("io/io_core_inst_tmpl.v")
|
||||
inst = VerilogManipulator("io_core/io_core_inst_tmpl.v")
|
||||
inst.sub(self.name, "/* MODULE_NAME */")
|
||||
inst.sub(self.name + "_inst", "/* INST_NAME */")
|
||||
|
||||
|
|
@ -89,7 +89,7 @@ class IOCore:
|
|||
|
||||
|
||||
def hdl_def(self):
|
||||
io_core = VerilogManipulator("io/io_core_def_tmpl.v")
|
||||
io_core = VerilogManipulator("io_core/io_core_def_tmpl.v")
|
||||
io_core.sub(self.name, "/* MODULE_NAME */")
|
||||
io_core.sub(self.max_addr, "/* MAX_ADDR */")
|
||||
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
from .verilog_manipulator import *
|
||||
from ..hdl_utils import *
|
||||
|
||||
from datetime import datetime
|
||||
from pkg_resources import get_distribution
|
||||
|
|
@ -12,7 +12,7 @@ class LogicAnalyzerCore:
|
|||
self.interface = interface
|
||||
|
||||
# Warn if unrecognized options have been given
|
||||
valid_options = ["type", "sample_depth", "probes", "triggers", "trigger_location", "trigger_mode"]
|
||||
valid_options = ["type", "sample_depth", "probes", "triggers", "trigger_loc", "trigger_mode"]
|
||||
for option in config:
|
||||
if option not in valid_options:
|
||||
print(f"Warning: Ignoring unrecognized option '{option}' in Logic Analyzer core '{self.name}'")
|
||||
|
|
@ -42,17 +42,17 @@ class LogicAnalyzerCore:
|
|||
|
||||
# Add trigger location
|
||||
self.trigger_loc = self.sample_depth // 2
|
||||
if "trigger_location" in config:
|
||||
assert isinstance(config["trigger_location"], int), \
|
||||
if "trigger_loc" in config:
|
||||
assert isinstance(config["trigger_loc"], int), \
|
||||
"Trigger location must be an integer."
|
||||
|
||||
assert config["trigger_location"] >= 0, \
|
||||
assert config["trigger_loc"] >= 0, \
|
||||
"Trigger location cannot be negative."
|
||||
|
||||
assert config["trigger_location"] <= self.sample_depth, \
|
||||
assert config["trigger_loc"] <= self.sample_depth, \
|
||||
"Trigger location cannot exceed sample depth."
|
||||
|
||||
self.trigger_loc = config["trigger_location"]
|
||||
self.trigger_loc = config["trigger_loc"]
|
||||
|
||||
# Add trigger mode
|
||||
self.SINGLE_SHOT = 0
|
||||
|
|
@ -99,7 +99,7 @@ class LogicAnalyzerCore:
|
|||
self.CAPTURED = 4
|
||||
|
||||
def hdl_inst(self):
|
||||
la_inst = VerilogManipulator("logic_analyzer/logic_analyzer_inst_tmpl.v")
|
||||
la_inst = VerilogManipulator("la_core/logic_analyzer_inst_tmpl.v")
|
||||
|
||||
# add module name to instantiation
|
||||
la_inst.sub(self.name, "/* INST_NAME */")
|
||||
|
|
@ -110,7 +110,7 @@ class LogicAnalyzerCore:
|
|||
return la_inst.get_hdl()
|
||||
|
||||
def gen_trigger_block_def(self):
|
||||
trigger_block = VerilogManipulator("logic_analyzer/trigger_block_def_tmpl.v")
|
||||
trigger_block = VerilogManipulator("la_core/trigger_block_def_tmpl.v")
|
||||
|
||||
# add probe ports to module declaration
|
||||
# these ports belong to the logic analyzer, but
|
||||
|
|
@ -124,7 +124,7 @@ class LogicAnalyzerCore:
|
|||
# into each probe
|
||||
trigger_module_insts = []
|
||||
for name, width in self.probes.items():
|
||||
trig_inst = VerilogManipulator("logic_analyzer/trigger_block_inst_tmpl.v")
|
||||
trig_inst = VerilogManipulator("la_core/trigger_block_inst_tmpl.v")
|
||||
trig_inst.sub(width, "/* INPUT_WIDTH */")
|
||||
trig_inst.sub(f"{name}_trigger", "/* NAME */")
|
||||
|
||||
|
|
@ -176,7 +176,7 @@ class LogicAnalyzerCore:
|
|||
return trigger_block.get_hdl()
|
||||
|
||||
def gen_logic_analyzer_def(self):
|
||||
la = VerilogManipulator("logic_analyzer/logic_analyzer_def_tmpl.v")
|
||||
la = VerilogManipulator("la_core/logic_analyzer_def_tmpl.v")
|
||||
|
||||
# add top level probe ports to module declaration
|
||||
ports = la.net_dec(self.probes, "input wire", trailing_comma=True)
|
||||
|
|
@ -213,12 +213,12 @@ class LogicAnalyzerCore:
|
|||
# Return an autogenerated verilog module definition for the core.
|
||||
# load source files
|
||||
hdl = self.gen_logic_analyzer_def() + "\n"
|
||||
hdl += VerilogManipulator("logic_analyzer/logic_analyzer_controller.v").get_hdl() + "\n"
|
||||
hdl += VerilogManipulator("logic_analyzer/logic_analyzer_fsm_registers.v").get_hdl() + "\n"
|
||||
hdl += VerilogManipulator("block_memory/block_memory.v").get_hdl() + "\n"
|
||||
hdl += VerilogManipulator("block_memory/dual_port_bram.v").get_hdl() + "\n"
|
||||
hdl += VerilogManipulator("la_core/logic_analyzer_controller.v").get_hdl() + "\n"
|
||||
hdl += VerilogManipulator("la_core/logic_analyzer_fsm_registers.v").get_hdl() + "\n"
|
||||
hdl += VerilogManipulator("block_mem_core/block_memory.v").get_hdl() + "\n"
|
||||
hdl += VerilogManipulator("block_mem_core/dual_port_bram.v").get_hdl() + "\n"
|
||||
hdl += self.gen_trigger_block_def() + "\n"
|
||||
hdl += VerilogManipulator("logic_analyzer/trigger.v").get_hdl() + "\n"
|
||||
hdl += VerilogManipulator("la_core/trigger.v").get_hdl() + "\n"
|
||||
|
||||
return hdl
|
||||
|
||||
|
|
@ -381,7 +381,7 @@ class LogicAnalyzerCore:
|
|||
f.writelines([f'{s:0{w}b}\n' for s in capture_data])
|
||||
|
||||
def export_playback_module(self, path):
|
||||
playback = VerilogManipulator("logic_analyzer/logic_analyzer_playback_tmpl.v")
|
||||
playback = VerilogManipulator("la_core/logic_analyzer_playback_tmpl.v")
|
||||
|
||||
module_name = f"{self.name}_playback"
|
||||
playback.sub(module_name, "/* MODULE_NAME */")
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
from .verilog_manipulator import *
|
||||
from ..hdl_utils import *
|
||||
|
||||
class LUTRAMCore:
|
||||
class LUTMemoryCore:
|
||||
def __init__(self, config, name, base_addr, interface):
|
||||
self.name = name
|
||||
self.base_addr = base_addr
|
||||
|
|
@ -19,13 +19,13 @@ class LUTRAMCore:
|
|||
self.max_addr = self.base_addr + self.size - 1
|
||||
|
||||
def hdl_inst(self):
|
||||
inst = VerilogManipulator("lut_ram/lut_ram_inst_tmpl.v")
|
||||
inst = VerilogManipulator("lut_mem_core/lut_mem_inst_tmpl.v")
|
||||
inst.sub(self.size, "/* DEPTH */")
|
||||
inst.sub(self.name, "/* INST_NAME */")
|
||||
return inst.get_hdl()
|
||||
|
||||
def hdl_def(self):
|
||||
return VerilogManipulator("lut_ram/lut_ram.v").get_hdl()
|
||||
return VerilogManipulator("lut_mem_core/lut_mem.v").get_hdl()
|
||||
|
||||
def hdl_top_level_ports(self):
|
||||
# no top_level connections since this core just lives on the bus
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
`default_nettype none
|
||||
`timescale 1ns/1ps
|
||||
|
||||
module lut_ram (
|
||||
module lut_mem (
|
||||
input wire clk,
|
||||
|
||||
// input port
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
lut_ram #(.DEPTH(/* DEPTH */)) /* INST_NAME */ (
|
||||
lut_mem #(.DEPTH(/* DEPTH */)) /* INST_NAME */ (
|
||||
.clk(clk),
|
||||
|
||||
.addr_i(),
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
from .verilog_manipulator import *
|
||||
from ..hdl_utils import *
|
||||
|
||||
class UARTInterface:
|
||||
def __init__(self, config):
|
||||
|
|
@ -161,21 +161,21 @@ class UARTInterface:
|
|||
return ["input wire rx", "output reg tx"]
|
||||
|
||||
def rx_hdl_def(self):
|
||||
uart_rx_def = VerilogManipulator("uart/rx_uart.v").get_hdl()
|
||||
bridge_rx_def = VerilogManipulator("uart/bridge_rx.v").get_hdl()
|
||||
uart_rx_def = VerilogManipulator("uart_iface/rx_uart.v").get_hdl()
|
||||
bridge_rx_def = VerilogManipulator("uart_iface/bridge_rx.v").get_hdl()
|
||||
return uart_rx_def + '\n' + bridge_rx_def
|
||||
|
||||
def tx_hdl_def(self):
|
||||
uart_tx_def = VerilogManipulator("uart/uart_tx.v").get_hdl()
|
||||
bridge_tx_def = VerilogManipulator("uart/bridge_tx.v").get_hdl()
|
||||
uart_tx_def = VerilogManipulator("uart_iface/uart_tx.v").get_hdl()
|
||||
bridge_tx_def = VerilogManipulator("uart_iface/bridge_tx.v").get_hdl()
|
||||
return bridge_tx_def + '\n' + uart_tx_def
|
||||
|
||||
def rx_hdl_inst(self):
|
||||
rx = VerilogManipulator("uart/uart_rx_bridge_rx_inst_templ.v")
|
||||
rx = VerilogManipulator("uart_iface/uart_rx_bridge_rx_inst_templ.v")
|
||||
rx.sub(self.clocks_per_baud, "/* CLOCKS_PER_BAUD */")
|
||||
return rx.get_hdl()
|
||||
|
||||
def tx_hdl_inst(self):
|
||||
tx = VerilogManipulator("uart/uart_tx_bridge_tx_inst_templ.v")
|
||||
tx = VerilogManipulator("uart_iface/uart_tx_bridge_tx_inst_templ.v")
|
||||
tx.sub(self.clocks_per_baud, "/* CLOCKS_PER_BAUD */")
|
||||
return tx.get_hdl()
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
---
|
||||
cores:
|
||||
my_lut_ram:
|
||||
type: lut_ram
|
||||
size: 64
|
||||
my_lut_mem:
|
||||
type: lut_mem
|
||||
size: 64
|
||||
|
||||
uart:
|
||||
port: "auto"
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ module bus_fix_tb;
|
|||
logic brx_mem_rw;
|
||||
logic brx_mem_valid;
|
||||
|
||||
lut_ram #(
|
||||
lut_mem #(
|
||||
.DEPTH(32),
|
||||
.BASE_ADDR(0)
|
||||
) ram (
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
`define CP 10
|
||||
`define HCP 5
|
||||
|
||||
module lut_ram_tb;
|
||||
module lut_mem_tb;
|
||||
// https://www.youtube.com/watch?v=WCOAr-96bGc
|
||||
|
||||
//boilerplate
|
||||
|
|
@ -17,7 +17,7 @@ module lut_ram_tb;
|
|||
logic tb_mem_1_rw;
|
||||
logic tb_mem_1_valid;
|
||||
|
||||
lut_ram #(
|
||||
lut_mem #(
|
||||
.DEPTH(8),
|
||||
.BASE_ADDR(0)
|
||||
) mem_1 (
|
||||
|
|
@ -42,7 +42,7 @@ module lut_ram_tb;
|
|||
logic mem_1_mem_2_rw;
|
||||
logic mem_1_mem_2_valid;
|
||||
|
||||
lut_ram #(
|
||||
lut_mem #(
|
||||
.DEPTH(8),
|
||||
.BASE_ADDR(8)
|
||||
) mem_2 (
|
||||
|
|
@ -67,7 +67,7 @@ module lut_ram_tb;
|
|||
logic mem_2_mem_3_rw;
|
||||
logic mem_2_mem_3_valid;
|
||||
|
||||
lut_ram #(
|
||||
lut_mem #(
|
||||
.DEPTH(8),
|
||||
.BASE_ADDR(16)
|
||||
) mem_3 (
|
||||
|
|
@ -98,8 +98,8 @@ module lut_ram_tb;
|
|||
end
|
||||
|
||||
initial begin
|
||||
$dumpfile("lut_ram.vcd");
|
||||
$dumpvars(0, lut_ram_tb);
|
||||
$dumpfile("lut_mem.vcd");
|
||||
$dumpvars(0, lut_mem_tb);
|
||||
|
||||
// setup and reset
|
||||
clk = 0;
|
||||
Loading…
Reference in New Issue