{"id":41555373,"url":"https://github.com/mcleber/verilog_testbench_essentials","last_synced_at":"2026-01-24T05:02:20.539Z","repository":{"id":291660120,"uuid":"978354039","full_name":"mcleber/Verilog_Testbench_Essentials","owner":"mcleber","description":"Creating testbenches in Verilog is an essential practice to verify the functionality of your modules and ensure your design behaves as expected.","archived":false,"fork":false,"pushed_at":"2025-05-07T02:56:55.000Z","size":68,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-05-17T00:14:54.846Z","etag":null,"topics":["learning-verilog","testbench","testbenches","verilog","verilog-hdl","verilog-testbenches"],"latest_commit_sha":null,"homepage":"","language":"Verilog","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mcleber.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-05-05T21:20:10.000Z","updated_at":"2025-05-07T02:56:58.000Z","dependencies_parsed_at":"2025-05-05T22:34:51.895Z","dependency_job_id":"bdfa732a-4bfb-45c3-a225-e416ddbf5142","html_url":"https://github.com/mcleber/Verilog_Testbench_Essentials","commit_stats":null,"previous_names":["mcleber/verilog_testbench_essentials"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/mcleber/Verilog_Testbench_Essentials","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mcleber%2FVerilog_Testbench_Essentials","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mcleber%2FVerilog_Testbench_Essentials/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mcleber%2FVerilog_Testbench_Essentials/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mcleber%2FVerilog_Testbench_Essentials/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mcleber","download_url":"https://codeload.github.com/mcleber/Verilog_Testbench_Essentials/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mcleber%2FVerilog_Testbench_Essentials/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28712841,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-24T05:01:10.984Z","status":"ssl_error","status_checked_at":"2026-01-24T04:59:18.328Z","response_time":89,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["learning-verilog","testbench","testbenches","verilog","verilog-hdl","verilog-testbenches"],"created_at":"2026-01-24T05:02:19.408Z","updated_at":"2026-01-24T05:02:20.525Z","avatar_url":"https://github.com/mcleber.png","language":"Verilog","readme":"# Verilog_Testbench_Essentials\nCreating testbenches in Verilog is an essential practice to verify the functionality of your modules and ensure your design behaves as expected.\n\n## 1. Description\nA testbench is a special Verilog module that is not synthesized but used solely for simulation. It instantiates the Device Under Test (DUT) and provides inputs while observing the outputs to validate the design.\n\n## 2. Repository Structure\n\n- assets/ - Images\n\n- src/ - Verilog source code\n\n- tb/ - Testbench code\n\n## 3. Basic Structure of a Testbench\nA typical Verilog testbench includes the following components:\n\n- Test signal declaration: Signals used to connect the DUT to the testbench.\n\n- DUT instantiation: The actual module being tested.\n\n- Stimulus generation: Provides input signals to the DUT.\n\n- Output monitoring: Observes the behavior of the DUT’s outputs.\n\n- Timing control: In Verilog, simulation uses timing commands such as `#delay`.\n\n## 4. Simple Example: Full Adder Testbench\n\n### Full Adder Module\nAvailable in the `src` directory.\n\n\u003cpre\u003e\n  module full_adder (\n    input A,        // Input bit A\n    input B,        // Input bit B\n    input Cin,      // Carry-in input\n    output Sum,     // Sum output\n    output Cout     // Carry-out output\n);\n    // Assign the sum and carry-out using binary addition\n    assign {Cout, Sum} = A + B + Cin;\nendmodule\n\u003c/pre\u003e\n\n### Full Adder Testbench\nAvailable in the `tb` directory.\n\n\u003cpre\u003e\n  module tb_full_adder;  // Testbench for the full_adder module\n\n    // Declare inputs as registers (reg) and outputs as wires (wire)\n    reg A, B, Cin;       // Inputs to the full adder: A, B, and Carry-in (Cin)\n    wire Sum, Cout;      // Outputs from the full adder: Sum and Carry-out (Cout)\n\n    // Instantiate the Device Under Test (DUT)\n    // 'uut' stands for \"Unit Under Test\"\n    // This connects the testbench signals (A, B, Cin) to the full_adder inputs,\n    // and connects the outputs (Sum, Cout) to wires declared above.\n    full_adder uut (\n        .A(A),       // Connect testbench A to full_adder input A\n        .B(B),       // Connect testbench B to full_adder input B\n        .Cin(Cin),   // Connect testbench Cin to full_adder input Cin\n        .Sum(Sum),   // Connect full_adder output Sum to testbench wire Sum\n        .Cout(Cout)  // Connect full_adder output Cout to testbench wire Cout\n    );\n\n    // Initial block to generate input stimuli\n    initial begin\n        // Initialize all inputs to zero\n        A = 0; B = 0; Cin = 0;\n\n        // Apply various combinations of A, B, and Cin\n        #10 A = 0; B = 0; Cin = 1;\n        #10 A = 0; B = 1; Cin = 0;\n        #10 A = 0; B = 1; Cin = 1;\n        #10 A = 1; B = 0; Cin = 0;\n        #10 A = 1; B = 0; Cin = 1;\n        #10 A = 1; B = 1; Cin = 0;\n        #10 A = 1; B = 1; Cin = 1;\n        #10;  // Wait a little before ending the simulation\n\n        $finish;  // End the simulation\n    end\n\n    // Initial block to monitor the simulation results\n    initial begin\n        // This prints input and output values to the console whenever they change\n        $monitor(\"A=%b, B=%b, Cin=%b -\u003e Sum=%b, Cout=%b\", A, B, Cin, Sum, Cout);\n    end\n\nendmodule\n\u003c/pre\u003e\n\n## 5. Testbench Explanation\nFigure 1 shows a simplified diagram.\n\n![Simplified Diagram](https://github.com/mcleber/Verilog_Testbench_Essentials/blob/main/assets/Simplified_Diagram.jpg)\n\n### Signal Declaration\nIn a testbench, inputs to the DUT are declared as `reg` because they are driven by procedural blocks, while outputs are declared as `wire`.\n\n\u003cpre\u003e\n  reg A, B, Cin;\n  wire Sum, Cout;\n\u003c/pre\u003e\n\n### DUT Instantiation\nThe DUT is instantiated and connected to the declared signals. The instance name is typically `uut` (Unit Under Test).\n\n\u003cpre\u003e\n  full_adder uut (\n    .A(A),\n    .B(B),\n    .Cin(Cin),\n    .Sum(Sum),\n    .Cout(Cout)\n);\n\u003c/pre\u003e\n\n### Stimulus Generator\nThis block drives the input values over simulation time using `#delay` for timing control.\n\n\u003cpre\u003e\n  initial begin\n    A = 0; B = 0; Cin = 0;\n    #10 A = 0; B = 0; Cin = 1;\n    #10 A = 0; B = 1; Cin = 0;\n    #10 A = 0; B = 1; Cin = 1;\n    #10 A = 1; B = 0; Cin = 0;\n    #10 A = 1; B = 0; Cin = 1;\n    #10 A = 1; B = 1; Cin = 0;\n    #10 A = 1; B = 1; Cin = 1;\n    #10;\n    $finish;\nend\n\u003c/pre\u003e\n\n### Output Monitoring\nThe `$monitor` command logs all input and output changes during simulation, providing a detailed trace.\n\n\u003cpre\u003e\n  initial begin\n    $monitor(\"A=%b, B=%b, Cin=%b -\u003e Sum=%b, Cout=%b\", A, B, Cin, Sum, Cout);\nend\n\u003c/pre\u003e\n\n## 6. Running the Simulation\nWith the testbench ready, use simulation tools such as ModelSim, XCELIUM, or Vivado Simulator. Compile and run the simulation to observe the outputs. The results should match the expected truth table of a full adder. Figure 2 shows the simulation waveform from Vivado.\n\n![Vivado Simulation](https://github.com/mcleber/Verilog_Testbench_Essentials/blob/main/assets/Vivado_Simulation.jpg)\n\n## 7. Improving the Testbench\nHere are some ways to enhance your testbench:\n\n- Automatic verification: Use assertions to compare DUT outputs with expected values.\n\n- Randomized testing: Apply random stimuli using $random to check for unexpected behavior.\n\n- Edge case testing: Specifically test boundary values and transitions for robustness.\n\n## 8. Conclusion\nCreating testbenches in Verilog is a fundamental step in digital hardware development. It ensures your designs are functionally correct before moving to synthesis and implementation. With the example above, you can build and simulate any Verilog module using a structured stimulus and monitoring approach.\n\n## 9. Technologies Used\n- HDL: Verilog\n\n- Development Tool: AMD Xilinx Vivado\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmcleber%2Fverilog_testbench_essentials","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmcleber%2Fverilog_testbench_essentials","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmcleber%2Fverilog_testbench_essentials/lists"}