From caeb04b455ec57f001f42d0317b1d5734e325335 Mon Sep 17 00:00:00 2001 From: Devesh Date: Mon, 20 Oct 2025 18:32:58 -0700 Subject: [PATCH 1/9] Allow passing custom module name to output_to_verilog --- pyrtl/importexport.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/pyrtl/importexport.py b/pyrtl/importexport.py index 3c29d453..f00f54b0 100644 --- a/pyrtl/importexport.py +++ b/pyrtl/importexport.py @@ -947,7 +947,7 @@ def _name_and_comment(self, name: str, kind="") -> tuple[str, str]: return sanitized_name, comment - def _to_verilog_header(self, file: IO, initialize_registers: bool): + def _to_verilog_header(self, file: IO, initialize_registers: bool, module_name="toplevel"): """Print the header of the verilog implementation.""" print("// Generated automatically via PyRTL", file=file) print("// As one initial test of synthesis, map to FPGA with:", file=file) @@ -958,7 +958,7 @@ def _to_verilog_header(self, file: IO, initialize_registers: bool): self.declared_gates = self.gate_graph.inputs | self.gate_graph.outputs # Module name. - print(f"module toplevel({', '.join(self.io_list)});", file=file) + print(f"module {module_name} ({', '.join(self.io_list)});", file=file) # Declare Inputs and Outputs. print(" input clk;", file=file) @@ -1255,8 +1255,8 @@ def _to_verilog_memories(self, file: IO): def _to_verilog_footer(self, file: IO): print("endmodule", file=file) - def output_to_verilog(self, dest_file: IO, initialize_registers: bool): - self._to_verilog_header(dest_file, initialize_registers) + def output_to_verilog(self, dest_file: IO, initialize_registers: bool, module_name="toplevel"): + self._to_verilog_header(dest_file, initialize_registers, module_name=module_name) self._to_verilog_combinational(dest_file) self._to_verilog_sequential(dest_file) self._to_verilog_memories(dest_file) @@ -1414,6 +1414,7 @@ def output_to_verilog( add_reset: bool | str = True, block: Block = None, initialize_registers: bool = False, + module_name: str = "toplevel", ): """A function to walk the ``block`` and output it in Verilog format to the open file. @@ -1435,7 +1436,7 @@ def output_to_verilog( bitwidth=8, reset_value=4)`` generates Verilog like ``reg[7:0] foo = 8'd4;``. :param block: Block to be walked and exported. Defaults to the :ref:`working_block`. """ - _VerilogOutput(block, add_reset).output_to_verilog(dest_file, initialize_registers) + _VerilogOutput(block, add_reset).output_to_verilog(dest_file, initialize_registers, module_name=module_name) def output_verilog_testbench( From d6e803b4511f258b7061052b3622de89bbbc6611 Mon Sep 17 00:00:00 2001 From: devmam999 <107886293+devmam999@users.noreply.github.com> Date: Fri, 24 Oct 2025 17:38:34 -0700 Subject: [PATCH 2/9] Update module declaration and add module_name option Fix formatting of module declaration and add module_name parameter. --- pyrtl/importexport.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/pyrtl/importexport.py b/pyrtl/importexport.py index f00f54b0..a2de68c9 100644 --- a/pyrtl/importexport.py +++ b/pyrtl/importexport.py @@ -958,7 +958,7 @@ def _to_verilog_header(self, file: IO, initialize_registers: bool, module_name=" self.declared_gates = self.gate_graph.inputs | self.gate_graph.outputs # Module name. - print(f"module {module_name} ({', '.join(self.io_list)});", file=file) + print(f"module {module_name}({', '.join(self.io_list)});", file=file) # Declare Inputs and Outputs. print(" input clk;", file=file) @@ -1447,7 +1447,10 @@ def output_verilog_testbench( cmd: str | None = None, add_reset: bool | str = True, block: Block = None, + module_name: str | None = None, ): + if module_name is None: + module_name = "toplevel" """Output a Verilog testbench for the block/inputs used in the simulation trace. If ``add_reset`` is ``True``, a ``rst`` input wire is added to the instantiated From eab6bab14ea3ce525a54db88dbcdd1a33e5e5bc9 Mon Sep 17 00:00:00 2001 From: Devesh Date: Mon, 27 Oct 2025 17:28:58 -0700 Subject: [PATCH 3/9] made sure the code passed all tests --- adder.v | 18 +++++++++ adder_tb.v | 89 +++++++++++++++++++++++++++++++++++++++++++ pyrtl/importexport.py | 37 +++++++++++++----- test.v | 14 +++++++ 4 files changed, 149 insertions(+), 9 deletions(-) create mode 100644 adder.v create mode 100644 adder_tb.v create mode 100644 test.v diff --git a/adder.v b/adder.v new file mode 100644 index 00000000..99c97783 --- /dev/null +++ b/adder.v @@ -0,0 +1,18 @@ +// Generated automatically via PyRTL +// As one initial test of synthesis, map to FPGA with: +// yosys -p "synth_xilinx -top toplevel" thisfile.v + +module toplevel(clk, rst, a, b, y); + input clk; + input rst; + input[1:0] a; + input[1:0] b; + output[1:0] y; + + // Temporaries + wire[2:0] tmp0; + + // Combinational logic + assign tmp0 = (a + b); + assign y = (tmp0[1:0]); +endmodule diff --git a/adder_tb.v b/adder_tb.v new file mode 100644 index 00000000..ae76b310 --- /dev/null +++ b/adder_tb.v @@ -0,0 +1,89 @@ +module tb(); + reg clk; + reg rst; + + // block Inputs + reg[1:0] a; + reg[1:0] b; + + // block Outputs + wire[1:0] y; + + toplevel block(.clk(clk), .rst(rst), .a(a), .b(b), .y(y)); + + always + #5 clk = ~clk; + + initial begin + $dumpfile ("waveform.vcd"); + $dumpvars; + + clk = 1'd0; + rst = 1'd0; + a = 2'd0; + b = 2'd0; + + #10 + a = 2'd0; + b = 2'd1; + + #10 + a = 2'd0; + b = 2'd2; + + #10 + a = 2'd0; + b = 2'd3; + + #10 + a = 2'd1; + b = 2'd0; + + #10 + a = 2'd1; + b = 2'd1; + + #10 + a = 2'd1; + b = 2'd2; + + #10 + a = 2'd1; + b = 2'd3; + + #10 + a = 2'd2; + b = 2'd0; + + #10 + a = 2'd2; + b = 2'd1; + + #10 + a = 2'd2; + b = 2'd2; + + #10 + a = 2'd2; + b = 2'd3; + + #10 + a = 2'd3; + b = 2'd0; + + #10 + a = 2'd3; + b = 2'd1; + + #10 + a = 2'd3; + b = 2'd2; + + #10 + a = 2'd3; + b = 2'd3; + + #10 + $finish; + end +endmodule diff --git a/pyrtl/importexport.py b/pyrtl/importexport.py index f00f54b0..e2e97379 100644 --- a/pyrtl/importexport.py +++ b/pyrtl/importexport.py @@ -768,10 +768,11 @@ def _extra_checks(self, str): class _VerilogOutput: - def __init__(self, block: Block, add_reset: bool | str): + def __init__(self, block: Block, add_reset: bool | str, module_name="toplevel"): block = working_block(block) self.gate_graph = GateGraph(block) self.add_reset = add_reset + self.module_name = module_name if not isinstance(self.add_reset, bool) and self.add_reset != "asynchronous": msg = ( @@ -947,18 +948,22 @@ def _name_and_comment(self, name: str, kind="") -> tuple[str, str]: return sanitized_name, comment - def _to_verilog_header(self, file: IO, initialize_registers: bool, module_name="toplevel"): + def _to_verilog_header( + self, file: IO, initialize_registers: bool, module_name="toplevel" + ): """Print the header of the verilog implementation.""" print("// Generated automatically via PyRTL", file=file) print("// As one initial test of synthesis, map to FPGA with:", file=file) - print('// yosys -p "synth_xilinx -top toplevel" thisfile.v\n', file=file) + print( + f'// yosys -p "synth_xilinx -top {module_name}" thisfile.v\n', file=file + ) # ``declared_gates`` is the set of Gates with corresponding Verilog reg/wire # declarations. Generated Verilog code can refer to these Gates by name. self.declared_gates = self.gate_graph.inputs | self.gate_graph.outputs # Module name. - print(f"module {module_name} ({', '.join(self.io_list)});", file=file) + print(f"module {self.module_name}({', '.join(self.io_list)});", file=file) # Declare Inputs and Outputs. print(" input clk;", file=file) @@ -1255,8 +1260,12 @@ def _to_verilog_memories(self, file: IO): def _to_verilog_footer(self, file: IO): print("endmodule", file=file) - def output_to_verilog(self, dest_file: IO, initialize_registers: bool, module_name="toplevel"): - self._to_verilog_header(dest_file, initialize_registers, module_name=module_name) + def output_to_verilog( + self, dest_file: IO, initialize_registers: bool, module_name="toplevel" + ): + self._to_verilog_header( + dest_file, initialize_registers, module_name=module_name + ) self._to_verilog_combinational(dest_file) self._to_verilog_sequential(dest_file) self._to_verilog_memories(dest_file) @@ -1269,6 +1278,7 @@ def output_verilog_testbench( toplevel_include: str | None = None, vcd: str = "waveform.vcd", cmd: str | None = None, + module_name: str = "toplevel", ): # Output an include, if given. if toplevel_include: @@ -1309,7 +1319,7 @@ def output_verilog_testbench( print(" integer tb_addr;", file=dest_file) io_list_str = [f".{io}({io})" for io in self.io_list] - print(f" toplevel block({', '.join(io_list_str)});\n", file=dest_file) + print(f" {module_name} block({', '.join(io_list_str)});\n", file=dest_file) # Generate the clock signal. print(" always", file=dest_file) @@ -1435,8 +1445,12 @@ def output_to_verilog( When this argument is ``True``, a register like ``Register(name='foo', bitwidth=8, reset_value=4)`` generates Verilog like ``reg[7:0] foo = 8'd4;``. :param block: Block to be walked and exported. Defaults to the :ref:`working_block`. + :param module_name: Name of the generated Verilog module. Defaults to "toplevel" + if no name is generated. """ - _VerilogOutput(block, add_reset).output_to_verilog(dest_file, initialize_registers, module_name=module_name) + _VerilogOutput(block, add_reset).output_to_verilog( + dest_file, initialize_registers, module_name=module_name + ) def output_verilog_testbench( @@ -1447,7 +1461,10 @@ def output_verilog_testbench( cmd: str | None = None, add_reset: bool | str = True, block: Block = None, + module_name: str | None = None, ): + if module_name is None: + module_name = "toplevel" """Output a Verilog testbench for the block/inputs used in the simulation trace. If ``add_reset`` is ``True``, a ``rst`` input wire is added to the instantiated @@ -1500,9 +1517,11 @@ def output_verilog_testbench( value passed in here should match the argument passed to :func:`output_to_verilog`. :param block: Block containing design to test. Defaults to the :ref:`working_block`. + :param module_name: Name of the generated Verilog module. Defaults to "toplevel" + if no name is generated. """ _VerilogOutput(block, add_reset).output_verilog_testbench( - dest_file, simulation_trace, toplevel_include, vcd, cmd + dest_file, simulation_trace, toplevel_include, vcd, cmd, module_name=module_name ) diff --git a/test.v b/test.v new file mode 100644 index 00000000..7352cbbc --- /dev/null +++ b/test.v @@ -0,0 +1,14 @@ +// Generated automatically via PyRTL +// As one initial test of synthesis, map to FPGA with: +// yosys -p "synth_xilinx -top toplevel" thisfile.v + +module my_module (clk, rst, a, b, y); + input clk; + input rst; + input a; + input b; + output y; + + // Combinational logic + assign y = (a & b); +endmodule From 9ee7b782c039f016d48af7aefedd0a648890394a Mon Sep 17 00:00:00 2001 From: devmam999 Date: Mon, 27 Oct 2025 17:52:16 -0700 Subject: [PATCH 4/9] Fix undefined module_name after merge --- pyrtl/importexport.py | 1 + 1 file changed, 1 insertion(+) diff --git a/pyrtl/importexport.py b/pyrtl/importexport.py index 12cf4cf0..e2e97379 100644 --- a/pyrtl/importexport.py +++ b/pyrtl/importexport.py @@ -1461,6 +1461,7 @@ def output_verilog_testbench( cmd: str | None = None, add_reset: bool | str = True, block: Block = None, + module_name: str | None = None, ): if module_name is None: module_name = "toplevel" From c64298ee465ae24df2424aa4ca26fe42ae4f0d8a Mon Sep 17 00:00:00 2001 From: devmam999 Date: Mon, 3 Nov 2025 16:51:10 -0800 Subject: [PATCH 5/9] module_name is now a class parameter --- adder.v | 18 --------- adder_tb.v | 89 ------------------------------------------- pyrtl/importexport.py | 34 +++++------------ test.v | 14 ------- 4 files changed, 10 insertions(+), 145 deletions(-) delete mode 100644 adder.v delete mode 100644 adder_tb.v delete mode 100644 test.v diff --git a/adder.v b/adder.v deleted file mode 100644 index 99c97783..00000000 --- a/adder.v +++ /dev/null @@ -1,18 +0,0 @@ -// Generated automatically via PyRTL -// As one initial test of synthesis, map to FPGA with: -// yosys -p "synth_xilinx -top toplevel" thisfile.v - -module toplevel(clk, rst, a, b, y); - input clk; - input rst; - input[1:0] a; - input[1:0] b; - output[1:0] y; - - // Temporaries - wire[2:0] tmp0; - - // Combinational logic - assign tmp0 = (a + b); - assign y = (tmp0[1:0]); -endmodule diff --git a/adder_tb.v b/adder_tb.v deleted file mode 100644 index ae76b310..00000000 --- a/adder_tb.v +++ /dev/null @@ -1,89 +0,0 @@ -module tb(); - reg clk; - reg rst; - - // block Inputs - reg[1:0] a; - reg[1:0] b; - - // block Outputs - wire[1:0] y; - - toplevel block(.clk(clk), .rst(rst), .a(a), .b(b), .y(y)); - - always - #5 clk = ~clk; - - initial begin - $dumpfile ("waveform.vcd"); - $dumpvars; - - clk = 1'd0; - rst = 1'd0; - a = 2'd0; - b = 2'd0; - - #10 - a = 2'd0; - b = 2'd1; - - #10 - a = 2'd0; - b = 2'd2; - - #10 - a = 2'd0; - b = 2'd3; - - #10 - a = 2'd1; - b = 2'd0; - - #10 - a = 2'd1; - b = 2'd1; - - #10 - a = 2'd1; - b = 2'd2; - - #10 - a = 2'd1; - b = 2'd3; - - #10 - a = 2'd2; - b = 2'd0; - - #10 - a = 2'd2; - b = 2'd1; - - #10 - a = 2'd2; - b = 2'd2; - - #10 - a = 2'd2; - b = 2'd3; - - #10 - a = 2'd3; - b = 2'd0; - - #10 - a = 2'd3; - b = 2'd1; - - #10 - a = 2'd3; - b = 2'd2; - - #10 - a = 2'd3; - b = 2'd3; - - #10 - $finish; - end -endmodule diff --git a/pyrtl/importexport.py b/pyrtl/importexport.py index e2e97379..3cfadc36 100644 --- a/pyrtl/importexport.py +++ b/pyrtl/importexport.py @@ -948,14 +948,13 @@ def _name_and_comment(self, name: str, kind="") -> tuple[str, str]: return sanitized_name, comment - def _to_verilog_header( - self, file: IO, initialize_registers: bool, module_name="toplevel" - ): + def _to_verilog_header(self, file: IO, initialize_registers: bool): """Print the header of the verilog implementation.""" print("// Generated automatically via PyRTL", file=file) print("// As one initial test of synthesis, map to FPGA with:", file=file) print( - f'// yosys -p "synth_xilinx -top {module_name}" thisfile.v\n', file=file + f'// yosys -p "synth_xilinx -top {self.module_name}" thisfile.v\n', + file=file, ) # ``declared_gates`` is the set of Gates with corresponding Verilog reg/wire @@ -1260,12 +1259,8 @@ def _to_verilog_memories(self, file: IO): def _to_verilog_footer(self, file: IO): print("endmodule", file=file) - def output_to_verilog( - self, dest_file: IO, initialize_registers: bool, module_name="toplevel" - ): - self._to_verilog_header( - dest_file, initialize_registers, module_name=module_name - ) + def output_to_verilog(self, dest_file: IO, initialize_registers: bool): + self._to_verilog_header(dest_file, initialize_registers) self._to_verilog_combinational(dest_file) self._to_verilog_sequential(dest_file) self._to_verilog_memories(dest_file) @@ -1278,7 +1273,6 @@ def output_verilog_testbench( toplevel_include: str | None = None, vcd: str = "waveform.vcd", cmd: str | None = None, - module_name: str = "toplevel", ): # Output an include, if given. if toplevel_include: @@ -1319,7 +1313,9 @@ def output_verilog_testbench( print(" integer tb_addr;", file=dest_file) io_list_str = [f".{io}({io})" for io in self.io_list] - print(f" {module_name} block({', '.join(io_list_str)});\n", file=dest_file) + print( + f" {self.module_name} block({', '.join(io_list_str)});\n", file=dest_file + ) # Generate the clock signal. print(" always", file=dest_file) @@ -1424,7 +1420,6 @@ def output_to_verilog( add_reset: bool | str = True, block: Block = None, initialize_registers: bool = False, - module_name: str = "toplevel", ): """A function to walk the ``block`` and output it in Verilog format to the open file. @@ -1445,12 +1440,8 @@ def output_to_verilog( When this argument is ``True``, a register like ``Register(name='foo', bitwidth=8, reset_value=4)`` generates Verilog like ``reg[7:0] foo = 8'd4;``. :param block: Block to be walked and exported. Defaults to the :ref:`working_block`. - :param module_name: Name of the generated Verilog module. Defaults to "toplevel" - if no name is generated. """ - _VerilogOutput(block, add_reset).output_to_verilog( - dest_file, initialize_registers, module_name=module_name - ) + _VerilogOutput(block, add_reset).output_to_verilog(dest_file, initialize_registers) def output_verilog_testbench( @@ -1461,10 +1452,7 @@ def output_verilog_testbench( cmd: str | None = None, add_reset: bool | str = True, block: Block = None, - module_name: str | None = None, ): - if module_name is None: - module_name = "toplevel" """Output a Verilog testbench for the block/inputs used in the simulation trace. If ``add_reset`` is ``True``, a ``rst`` input wire is added to the instantiated @@ -1517,11 +1505,9 @@ def output_verilog_testbench( value passed in here should match the argument passed to :func:`output_to_verilog`. :param block: Block containing design to test. Defaults to the :ref:`working_block`. - :param module_name: Name of the generated Verilog module. Defaults to "toplevel" - if no name is generated. """ _VerilogOutput(block, add_reset).output_verilog_testbench( - dest_file, simulation_trace, toplevel_include, vcd, cmd, module_name=module_name + dest_file, simulation_trace, toplevel_include, vcd, cmd ) diff --git a/test.v b/test.v deleted file mode 100644 index 7352cbbc..00000000 --- a/test.v +++ /dev/null @@ -1,14 +0,0 @@ -// Generated automatically via PyRTL -// As one initial test of synthesis, map to FPGA with: -// yosys -p "synth_xilinx -top toplevel" thisfile.v - -module my_module (clk, rst, a, b, y); - input clk; - input rst; - input a; - input b; - output y; - - // Combinational logic - assign y = (a & b); -endmodule From 6113e6d771d437f7d7cd81b2929e7e65217195e9 Mon Sep 17 00:00:00 2001 From: devmam999 Date: Wed, 5 Nov 2025 14:59:59 -0800 Subject: [PATCH 6/9] Added module_name as a parameter to a few functions as necessary --- pyrtl/importexport.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/pyrtl/importexport.py b/pyrtl/importexport.py index 3cfadc36..d79b4bbd 100644 --- a/pyrtl/importexport.py +++ b/pyrtl/importexport.py @@ -1420,6 +1420,7 @@ def output_to_verilog( add_reset: bool | str = True, block: Block = None, initialize_registers: bool = False, + module_name: str = "toplevel", ): """A function to walk the ``block`` and output it in Verilog format to the open file. @@ -1440,8 +1441,12 @@ def output_to_verilog( When this argument is ``True``, a register like ``Register(name='foo', bitwidth=8, reset_value=4)`` generates Verilog like ``reg[7:0] foo = 8'd4;``. :param block: Block to be walked and exported. Defaults to the :ref:`working_block`. + :param module_name: name of the module. Defaults to toplevel + if the user puts nothing. """ - _VerilogOutput(block, add_reset).output_to_verilog(dest_file, initialize_registers) + _VerilogOutput(block, add_reset, module_name=module_name).output_to_verilog( + dest_file, initialize_registers + ) def output_verilog_testbench( @@ -1452,6 +1457,7 @@ def output_verilog_testbench( cmd: str | None = None, add_reset: bool | str = True, block: Block = None, + module_name: str = "toplevel", ): """Output a Verilog testbench for the block/inputs used in the simulation trace. @@ -1505,8 +1511,10 @@ def output_verilog_testbench( value passed in here should match the argument passed to :func:`output_to_verilog`. :param block: Block containing design to test. Defaults to the :ref:`working_block`. + :param module_name: Name of the module the user chooses. Defaults to toplevel + if nothing is inputted. """ - _VerilogOutput(block, add_reset).output_verilog_testbench( + _VerilogOutput(block, add_reset, module_name=module_name).output_verilog_testbench( dest_file, simulation_trace, toplevel_include, vcd, cmd ) From b18009c03e7defc9b73a546b6e86acfa56d65c2f Mon Sep 17 00:00:00 2001 From: devmam999 <107886293+devmam999@users.noreply.github.com> Date: Mon, 10 Nov 2025 16:19:24 -0800 Subject: [PATCH 7/9] Added a test for my change --- tests/test_importexport.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/tests/test_importexport.py b/tests/test_importexport.py index 04793e96..7ff17fb8 100644 --- a/tests/test_importexport.py +++ b/tests/test_importexport.py @@ -2265,6 +2265,20 @@ def test_bench_with_same_io_name(self): self.check_io(pyrtl.Input, ["G1", "G2", "G3"]) self.check_io(pyrtl.Output, ["tmp3", "G4"]) +class TestOutputVerilog(unittest.TestCase): + def test_custom_module_name(self): + import io, pyrtl + pyrtl.reset_working_block() + a, b = pyrtl.Input(1, 'a'), pyrtl.Input(1, 'b') + out = pyrtl.Output(name='out') + out <<= a & b + + buf = io.StringIO() + pyrtl.output_to_verilog(buf, module_name='custom_top') + text = buf.getvalue() + + self.assertIn('module custom_top', text) + self.assertNotIn('module toplevel', text) if __name__ == "__main__": unittest.main() From 52d3f43d2ebb058ba4b8a512d927f118c668f4c0 Mon Sep 17 00:00:00 2001 From: devmam999 <107886293+devmam999@users.noreply.github.com> Date: Wed, 12 Nov 2025 16:32:33 -0800 Subject: [PATCH 8/9] Fixed issues and improved placement of my tests --- tests/test_importexport.py | 39 +++++++++++++++++++++++++------------- 1 file changed, 26 insertions(+), 13 deletions(-) diff --git a/tests/test_importexport.py b/tests/test_importexport.py index 7ff17fb8..5df00399 100644 --- a/tests/test_importexport.py +++ b/tests/test_importexport.py @@ -1305,6 +1305,17 @@ def test_bit_slice_inputs(self): # only has one user and just passes through ``c``, because that user is a # bit-slice. self.assertTrue("assign tmp3 = c" in buffer.getvalue()) + def test_custom_module_name(self): + a, b = pyrtl.Input(1, 'a'), pyrtl.Input(1, 'b') + out = pyrtl.Output(name='out') + out <<= a & b + + buf = io.StringIO() + pyrtl.output_to_verilog(buf, module_name='custom_top') + text = buf.getvalue() + + self.assertIn('module custom_top', text) + self.assertNotIn('module toplevel', text) verilog_input_counter = """\ @@ -1650,6 +1661,21 @@ def test_only_initialize_memblocks(self): pyrtl.output_verilog_testbench(buffer, add_reset=False) # The testbench should not touch the RomBlock. self.assertTrue("my_rom" not in buffer.getvalue()) + def test_custom_module_name_testbench(self): + # Minimal design + a, b = pyrtl.Input(1, "a"), pyrtl.Input(1, "b") + out = pyrtl.Output(1, "out") + out <<= a & b + + buf = io.StringIO() + # Generate a testbench with a custom module name + pyrtl.output_verilog_testbench(buf, module_name="custom_tb") + text = buf.getvalue() + + # Verify the custom module name is used + self.assertIn("custom_tb block(", text) + self.assertNotIn("toplevel block(", text) + firrtl_output_concat_test = """\ @@ -2265,20 +2291,7 @@ def test_bench_with_same_io_name(self): self.check_io(pyrtl.Input, ["G1", "G2", "G3"]) self.check_io(pyrtl.Output, ["tmp3", "G4"]) -class TestOutputVerilog(unittest.TestCase): - def test_custom_module_name(self): - import io, pyrtl - pyrtl.reset_working_block() - a, b = pyrtl.Input(1, 'a'), pyrtl.Input(1, 'b') - out = pyrtl.Output(name='out') - out <<= a & b - - buf = io.StringIO() - pyrtl.output_to_verilog(buf, module_name='custom_top') - text = buf.getvalue() - self.assertIn('module custom_top', text) - self.assertNotIn('module toplevel', text) if __name__ == "__main__": unittest.main() From c252752e0f3f2d6743b7669dc8ac4fe3a54ab763 Mon Sep 17 00:00:00 2001 From: devmam999 Date: Sat, 15 Nov 2025 15:27:51 -0800 Subject: [PATCH 9/9] Fixed formatting errors --- tests/test_importexport.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/tests/test_importexport.py b/tests/test_importexport.py index 14b0ee0f..98bedcaf 100644 --- a/tests/test_importexport.py +++ b/tests/test_importexport.py @@ -1308,17 +1308,18 @@ def test_bit_slice_inputs(self): # only has one user and just passes through ``c``, because that user is a # bit-slice. self.assertTrue("assign tmp3 = c" in buffer.getvalue()) + def test_custom_module_name(self): - a, b = pyrtl.Input(1, 'a'), pyrtl.Input(1, 'b') - out = pyrtl.Output(name='out') + a, b = pyrtl.Input(1, "a"), pyrtl.Input(1, "b") + out = pyrtl.Output(name="out") out <<= a & b buf = io.StringIO() - pyrtl.output_to_verilog(buf, module_name='custom_top') + pyrtl.output_to_verilog(buf, module_name="custom_top") text = buf.getvalue() - self.assertIn('module custom_top', text) - self.assertNotIn('module toplevel', text) + self.assertIn("module custom_top", text) + self.assertNotIn("module toplevel", text) verilog_input_counter = """\ @@ -1664,6 +1665,7 @@ def test_only_initialize_memblocks(self): pyrtl.output_verilog_testbench(buffer, add_reset=False) # The testbench should not touch the RomBlock. self.assertTrue("my_rom" not in buffer.getvalue()) + def test_custom_module_name_testbench(self): # Minimal design a, b = pyrtl.Input(1, "a"), pyrtl.Input(1, "b") @@ -1680,7 +1682,6 @@ def test_custom_module_name_testbench(self): self.assertNotIn("toplevel block(", text) - firrtl_output_concat_test = """\ circuit Example : module Example : @@ -2295,6 +2296,5 @@ def test_bench_with_same_io_name(self): self.check_io(pyrtl.Output, ["tmp3", "G4"]) - if __name__ == "__main__": unittest.main()