Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 1 addition & 4 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ __pycache__

# Unit test / coverage reports
.coverage
.tox

# Translations
*.mo
Expand All @@ -46,15 +45,13 @@ docs/_build
# There must be a very good reason for someone to add a verilog file to the repo
.v

# ipynb
ipynb-examples/.ipynb_checkpoints

# VS Code
.vscode

# Python venv
pyvenv.cfg

# Jupyter
.ipynb_checkpoints
.jupyterlite.doit.db
_output
2 changes: 1 addition & 1 deletion docs/export.rst
Original file line number Diff line number Diff line change
Expand Up @@ -28,5 +28,5 @@ Outputting for Visualization
.. autofunction:: pyrtl.output_to_svg
.. autofunction:: pyrtl.block_to_graphviz_string
.. autofunction:: pyrtl.block_to_svg
.. autofunction:: pyrtl.trace_to_html
.. autofunction:: pyrtl.trace_to_json
.. autofunction:: pyrtl.net_graph
4 changes: 2 additions & 2 deletions examples/Makefile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
PYTHON=uv run python3
PY_FILES=$(wildcard *.py)
PYTHON=uv run
PY_FILES=$(wildcard example*.py) introduction-to-hardware.py
IPYNB_FILES=$(addprefix ../ipynb-examples/, $(PY_FILES:.py=.ipynb))

all: $(IPYNB_FILES)
Expand Down
4 changes: 1 addition & 3 deletions examples/example8-verilog.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,7 @@
{"x": random.randrange(2), "y": random.randrange(2), "cin": random.randrange(2)}
)
# Only display the `Input` and `Output` `WireVectors` for clarity.
input_vectors = pyrtl.working_block().wirevector_subset(pyrtl.Input)
output_vectors = pyrtl.working_block().wirevector_subset(pyrtl.Output)
sim.tracer.render_trace(trace_list=[*input_vectors, *output_vectors], symbol_len=2)
sim.tracer.render_trace(trace_list=["x", "y", "cin", "sum", "cout"], symbol_len=2)

# ## Exporting to Verilog
#
Expand Down
4 changes: 1 addition & 3 deletions ipynb-examples/example8-verilog.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -149,9 +149,7 @@
},
"outputs": [],
"source": [
"input_vectors = pyrtl.working_block().wirevector_subset(pyrtl.Input)\n",
"output_vectors = pyrtl.working_block().wirevector_subset(pyrtl.Output)\n",
"sim.tracer.render_trace(trace_list=[*input_vectors, *output_vectors], symbol_len=2)\n"
"sim.tracer.render_trace(trace_list=[\"x\", \"y\", \"cin\", \"sum\", \"cout\"], symbol_len=2)\n"
]
},
{
Expand Down
173 changes: 0 additions & 173 deletions ipynb-examples/renderer-demo.ipynb

This file was deleted.

4 changes: 2 additions & 2 deletions pyrtl/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@
output_to_svg,
block_to_graphviz_string,
block_to_svg,
trace_to_html,
trace_to_json,
net_graph,
)

Expand Down Expand Up @@ -236,7 +236,7 @@
"output_to_svg",
"block_to_graphviz_string",
"block_to_svg",
"trace_to_html",
"trace_to_json",
"net_graph",
# importexport
"input_from_verilog",
Expand Down
81 changes: 42 additions & 39 deletions pyrtl/simulation.py
Original file line number Diff line number Diff line change
Expand Up @@ -1030,6 +1030,34 @@ def make_split(source, split_length, split_start_bit, split_res_start_bit):
#


def val_to_str(
value: int,
wire: WireVector,
repr_func: Callable[[int], str],
repr_per_name: dict[str, Callable[[int], str]],
) -> str:
"""Return a string representing 'value'.

:param value: The value to convert to string.
:param wire: Wire that produced this value.
:param repr_func: function to use for representing the current_val; examples are
'hex', 'oct', 'bin', 'str' (for decimal), or the function returned by
:func:`enum_name`. Defaults to 'hex'.
:param repr_per_name: Map from signal name to a function that takes in the signal's
value and returns a user-defined representation. If a signal name is not found
in the map, the argument `repr_func` will be used instead.

:return: a string representing 'value'.
"""
func = repr_per_name.get(wire.name)
if func is None:
func = repr_func

if func is val_to_signed_integer:
return str(val_to_signed_integer(value=value, bitwidth=wire.bitwidth))
return str(func(value))


class WaveRenderer:
"""Render a SimulationTrace to the terminal.

Expand Down Expand Up @@ -1077,37 +1105,6 @@ def render_ruler_segment(
# Pad major_tick out to segment_size.
return major_tick.ljust(cycle_len * segment_size)

def val_to_str(
self,
value: int,
wire: WireVector,
repr_func: Callable[[int], str],
repr_per_name: dict[str, Callable[[int], str]],
) -> str:
"""Return a string representing 'value'.

:param value: The value to convert to string.
:param wire: Wire that produced this value.
:param repr_func: function to use for representing the current_val; examples are
'hex', 'oct', 'bin', 'str' (for decimal), or the function returned by
:func:`enum_name`. Defaults to 'hex'.
:param repr_per_name: Map from signal name to a function that takes in the
signal's value and returns a user-defined representation. If a signal name
is not found in the map, the argument `repr_func` will be used instead.

:return: a string representing 'value'.
"""
f = repr_per_name.get(wire.name)

def invoke_f(f, value):
if f is val_to_signed_integer:
return str(val_to_signed_integer(value=value, bitwidth=wire.bitwidth))
return str(f(value))

if f is not None:
return invoke_f(f, value)
return invoke_f(repr_func, value)

def render_val(
self,
w: WireVector,
Expand Down Expand Up @@ -1180,7 +1177,7 @@ def render_val(
out += self.constants._bus_start
# Display the current non-zero value.
out += (
self.val_to_str(current_val, w, repr_func, repr_per_name)
val_to_str(current_val, w, repr_func, repr_per_name)
.rstrip("L")
.ljust(symbol_len)[:symbol_len]
)
Expand Down Expand Up @@ -1767,15 +1764,23 @@ def render_trace(
display,
)

from pyrtl.visualization import trace_to_html
from pyrtl.visualization import trace_to_json

display(
HTML(
trace_to_html(self, trace_list=trace_list, sortkey=_trace_sort_key)
'<script type="WaveDrom">'
+ trace_to_json(
self,
trace_list=trace_list,
sortkey=_trace_sort_key,
repr_func=repr_func,
repr_per_name=repr_per_name,
)
+ "</script>\n"
),
HTML("""
<script src="https://cdnjs.cloudflare.com/ajax/libs/wavedrom/1.6.2/skins/default.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/wavedrom/1.6.2/wavedrom.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/wavedrom@3/skins/default.js"></script>
<script src="https://cdn.jsdelivr.net/npm/wavedrom@3/wavedrom.min.js"></script>
"""),
# Wait for WaveDrom to load, polling every 100ms.
Javascript("""
Expand Down Expand Up @@ -1880,9 +1885,7 @@ def formatted_trace_line(wire, trace):
trace = self.trace[trace_name]
current_symbol_len = max(
len(
renderer.val_to_str(
v, self._wires[trace_name], repr_func, repr_per_name
)
val_to_str(v, self._wires[trace_name], repr_func, repr_per_name)
)
for v in trace
)
Expand Down
Loading
Loading