add logic analyzer playback module auto-generation
This commit is contained in:
parent
9d8836bda3
commit
7c1e4fc2c0
|
|
@ -12,3 +12,4 @@ with open("capture.pkl", "rb") as f:
|
|||
|
||||
m.my_logic_analyzer.export_vcd(capture, "capture.vcd")
|
||||
m.my_logic_analyzer.export_mem(capture, "capture.mem")
|
||||
m.my_logic_analyzer.export_playback_module("sim/playback.v")
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
This playback module was generated with Manta v0.0.0 on 15 Apr 2023 at 20:50:31 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!
|
||||
|
||||
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));
|
||||
|
||||
*/
|
||||
|
||||
|
||||
module my_logic_analyzer_playback (
|
||||
input wire clk,
|
||||
|
||||
input wire enable,
|
||||
output reg done,
|
||||
|
||||
output reg larry,
|
||||
output reg curly,
|
||||
output reg moe,
|
||||
output reg [3:0] shemp);
|
||||
|
||||
parameter MEM_FILE = "";
|
||||
localparam SAMPLE_DEPTH = 4096;
|
||||
localparam TOTAL_PROBE_WIDTH = 7;
|
||||
|
||||
reg [TOTAL_PROBE_WIDTH-1:0] capture [SAMPLE_DEPTH-1:0];
|
||||
reg [$clog2(SAMPLE_DEPTH)-1:0] addr;
|
||||
reg [TOTAL_PROBE_WIDTH-1:0] sample;
|
||||
|
||||
assign done = (addr >= SAMPLE_DEPTH);
|
||||
|
||||
initial begin
|
||||
$display("Loading capture from %s", MEM_FILE);
|
||||
$readmemb(MEM_FILE, capture, 0, SAMPLE_DEPTH-1);
|
||||
addr = 0;
|
||||
end
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (enable && !done) begin
|
||||
addr = addr + 1;
|
||||
sample = capture[addr];
|
||||
{shemp, moe, curly, larry} = sample;
|
||||
end
|
||||
end
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
`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,80 +0,0 @@
|
|||
`default_nettype none
|
||||
`timescale 1ns/1ps
|
||||
|
||||
module replay_tb();
|
||||
logic clk;
|
||||
|
||||
always begin
|
||||
#5;
|
||||
clk = !clk;
|
||||
end
|
||||
|
||||
logic larry;
|
||||
logic curly;
|
||||
logic moe;
|
||||
logic [3:0] shemp;
|
||||
my_logic_analyzer_playback playback (
|
||||
.clk(clk),
|
||||
|
||||
.enable(1'b1),
|
||||
.done(),
|
||||
|
||||
.larry(larry),
|
||||
.curly(curly),
|
||||
.moe(moe),
|
||||
.shemp(shemp));
|
||||
|
||||
|
||||
initial begin
|
||||
clk = 0;
|
||||
$dumpfile("replay_tb.vcd");
|
||||
$dumpvars(0, replay_tb);
|
||||
|
||||
#(4500*5);
|
||||
$finish();
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
||||
|
||||
|
||||
module my_logic_analyzer_playback (
|
||||
input wire clk,
|
||||
|
||||
input wire enable,
|
||||
output reg done,
|
||||
|
||||
output reg larry,
|
||||
output reg curly,
|
||||
output reg moe,
|
||||
output reg [3:0] shemp);
|
||||
|
||||
localparam FILENAME = "capture.mem";
|
||||
localparam SAMPLE_DEPTH = 4096;
|
||||
localparam TOTAL_PROBE_WIDTH = 7;
|
||||
|
||||
reg [TOTAL_PROBE_WIDTH-1:0] capture [SAMPLE_DEPTH-1:0];
|
||||
reg [$clog2(SAMPLE_DEPTH)-1:0] addr;
|
||||
reg [TOTAL_PROBE_WIDTH-1:0] sample;
|
||||
|
||||
assign done = (addr >= SAMPLE_DEPTH);
|
||||
|
||||
initial begin
|
||||
$display("Loading capture from %s", FILENAME);
|
||||
$readmemb(FILENAME, capture);
|
||||
addr = 0;
|
||||
end
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (enable && !done) begin
|
||||
addr = addr + 1;
|
||||
sample = capture[addr];
|
||||
larry = sample[0];
|
||||
curly = sample[1];
|
||||
moe = sample[2];
|
||||
shemp = sample[6:3];
|
||||
end
|
||||
end
|
||||
endmodule
|
||||
|
||||
`default_nettype wire
|
||||
|
|
@ -4,7 +4,7 @@ from sys import argv
|
|||
import os
|
||||
from datetime import datetime
|
||||
|
||||
version = "0.0.0"
|
||||
version = "v0.0.0"
|
||||
|
||||
class VerilogManipulator:
|
||||
def __init__(self, filepath=None):
|
||||
|
|
@ -685,8 +685,38 @@ class LogicAnalyzerCore:
|
|||
w = self.total_probe_width
|
||||
f.writelines([f'{s:0{w}b}\n' for s in capture_data])
|
||||
|
||||
def export_mem_loader(self):
|
||||
pass
|
||||
def export_playback_module(self, path):
|
||||
playback = VerilogManipulator("logic_analyzer_playback_tmpl.v")
|
||||
|
||||
module_name = f"{self.name}_playback"
|
||||
playback.sub(module_name, "/* MODULE_NAME */")
|
||||
|
||||
playback.sub(version, "/* VERSION */")
|
||||
|
||||
timestamp = datetime.now().strftime("%d %b %Y at %H:%M:%S")
|
||||
playback.sub(timestamp, "/* TIMESTAMP */")
|
||||
|
||||
user = os.environ.get("USER", os.environ.get("USERNAME"))
|
||||
playback.sub(user, "/* USER */")
|
||||
|
||||
ports = [f".{name}({name})" for name in self.probes.keys()]
|
||||
ports = ",\n".join(ports)
|
||||
playback.sub(ports, "/* PORTS */")
|
||||
|
||||
playback.sub(self.sample_depth, "/* SAMPLE_DEPTH */")
|
||||
playback.sub(self.total_probe_width, "/* TOTAL_PROBE_WIDTH */")
|
||||
|
||||
# see the note in generate_logic_analyzer_def about why we do this
|
||||
probes_concat = list(self.probes.keys())[::-1]
|
||||
probes_concat = '{' + ', '.join(probes_concat) + '}'
|
||||
playback.sub(probes_concat, "/* PROBES_CONCAT */")
|
||||
|
||||
|
||||
probe_dec = playback.net_dec(self.probes, "output reg")
|
||||
playback.sub(probe_dec, "/* PROBE_DEC */")
|
||||
|
||||
with open(path, "w") as f:
|
||||
f.write(playback.get_hdl())
|
||||
|
||||
|
||||
def part_select_capture_data(self, capture_data, probe_name):
|
||||
|
|
@ -1030,6 +1060,8 @@ reg {self.cores[-1].name}_btx_valid;\n"""
|
|||
def generate_hdl(self, output_filepath):
|
||||
manta = VerilogManipulator("manta_def_tmpl.v")
|
||||
|
||||
manta.sub(version, "/* VERSION */")
|
||||
|
||||
timestamp = datetime.now().strftime("%d %b %Y at %H:%M:%S")
|
||||
manta.sub(timestamp, "/* TIMESTAMP */")
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
This playback module was generated with Manta /* VERSION */ on /* TIMESTAMP */ by /* USER */
|
||||
|
||||
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!
|
||||
|
||||
/* MODULE_NAME */ #(.MEM_FILE("capture.mem")) /* MODULE_NAME */_inst (
|
||||
.clk(clk),
|
||||
.enable(1'b1),
|
||||
|
||||
/* PORTS */);
|
||||
|
||||
*/
|
||||
|
||||
|
||||
module /* MODULE_NAME */ (
|
||||
input wire clk,
|
||||
|
||||
input wire enable,
|
||||
output reg done,
|
||||
|
||||
/* PROBE_DEC */);
|
||||
|
||||
parameter MEM_FILE = "";
|
||||
localparam SAMPLE_DEPTH = /* SAMPLE_DEPTH */;
|
||||
localparam TOTAL_PROBE_WIDTH = /* TOTAL_PROBE_WIDTH */;
|
||||
|
||||
reg [TOTAL_PROBE_WIDTH-1:0] capture [SAMPLE_DEPTH-1:0];
|
||||
reg [$clog2(SAMPLE_DEPTH)-1:0] addr;
|
||||
reg [TOTAL_PROBE_WIDTH-1:0] sample;
|
||||
|
||||
assign done = (addr >= SAMPLE_DEPTH);
|
||||
|
||||
initial begin
|
||||
$display("Loading capture from %s", MEM_FILE);
|
||||
$readmemb(MEM_FILE, capture, 0, SAMPLE_DEPTH-1);
|
||||
addr = 0;
|
||||
end
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (enable && !done) begin
|
||||
addr = addr + 1;
|
||||
sample = capture[addr];
|
||||
/* PROBES_CONCAT */ = sample;
|
||||
end
|
||||
end
|
||||
endmodule
|
||||
|
|
@ -1,13 +1,12 @@
|
|||
/*
|
||||
This manta definition was generated on /* TIMESTAMP */ by /* USER */
|
||||
This playback module was generated with Manta /* VERSION */ on /* TIMESTAMP */ by /* USER */
|
||||
|
||||
If this breaks or if you've got dank formal verification memes,
|
||||
please contact fischerm [at] mit.edu
|
||||
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!
|
||||
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),
|
||||
|
|
|
|||
Loading…
Reference in New Issue