Skip to content

Add Verilog #338

Open
Open

Description

@kenkit

Please complete the following information about the language:

  • Name:Verilog
  • Website:N.A
  • Language Version:Any

The following are optional, but will help us add the language:

  • Test Frameworks:Install a Verilog Simulator: Download and install Icarus Verilog from the Icarus Verilog website for your operating system. Ensure the installation adds the iverilog and vvp commands to your system's environment path
  • How to install:Ensure you have Node.js installed on your system.
  • How to compile/run:
  • Any comments: (e.g., what's interesting about this language)
    It would be fun solving verilog problems on codewars

  1. Write Your Verilog Code
    Create a Verilog design file (e.g., design.v) and a testbench file (e.g., testbench.v). The testbench should use system tasks like $display or $monitor to output results to standard output, which Node.js will capture.

// testbench.v

module testbench;
  reg a, b;
  wire sum, carry;

  // Instantiate the design under test (DUT)
  half_adder dut (.a(a), .b(b), .sum(sum), .carry(carry));

  initial begin
    // Apply stimulus
    a = 0; b = 0; #10;
    $display("a=%b, b=%b, sum=%b, carry=%b", a, b, sum, carry);
    a = 0; b = 1; #10;
    $display("a=%b, b=%b, sum=%b, carry=%b", a, b, sum, carry);
    a = 1; b = 0; #10;
    $display("a=%b, b=%b, sum=%b, carry=%b", a, b, sum, carry);
    a = 1; b = 1; #10;
    $display("a=%b, b=%b, sum=%b, carry=%b", a, b, sum, carry);
    $finish; // Terminate the simulation
  end
endmodule

// design.v (Half Adder)

module half_adder(a, b, sum, carry);
  input a, b;
  output sum, carry;

  assign sum = a ^ b;
  assign carry = a & b;
endmodule
  1. Create a Node.js Script
    Use Node.js's built-in child_process module to execute the simulation commands.

// run_verilog.js

// run_verilog.js
const { exec } = require('child_process');
const fs = require('fs');

const designFile = 'design.v';
const testbenchFile = 'testbench.v';
const outputFile = 'simulation.out';

// 1. Compile the Verilog files
exec(`iverilog -o ${outputFile} ${designFile} ${testbenchFile}`, (compileError, compileStdout, compileStderr) => {
  if (compileError) {
    console.error(`Compilation error: ${compileError.message}`);
    return;
  }
  if (compileStderr) {
    console.error(`Compilation stderr: ${compileStderr}`);
  }
  console.log('Compilation successful.');

  // 2. Run the simulation executable
  exec(`vvp ${outputFile}`, (runError, runStdout, runStderr) => {
    if (runError) {
      console.error(`Runtime error: ${runError.message}`);
      return;
    }
    if (runStderr) {
      console.error(`Runtime stderr: ${runStderr}`);
    }
    console.log('Simulation Output:');
    console.log(runStdout);

    // Optional: Clean up the generated output file
    fs.unlink(outputFile, (err) => {
        if (err) throw err;
        console.log(`${outputFile} was deleted`);
    });
  });
});
  1. Run the Node.js Script
    Execute your Node.js script from your terminal:
    bash
    node run_verilog.js
    The output in your console will show the results of the Verilog simulation captured by Node.js:
    Compilation successful.
    Simulation Output:
a=0, b=0, sum=0, carry=0
a=0, b=1, sum=1, carry=0
a=1, b=0, sum=1, carry=0
a=1, b=1, sum=0, carry=1

simulation.out was deleted

👍 reaction might help to get this request prioritized.

Activity

  1. kenkit commented on Jan 14, 2026

    @kenkit
    Author

    Aother way to add tests
    //testbench.v

    module testbench;
      reg [3:0] a; reg [3:0] b;
      wire [3:0]sum;wire [3:0]carry;
    
      // Instantiate the design under test (DUT)
      half_adder dut (.a(a[0]), .b(b[0]), .sum(sum[0]), .carry(carry[0]));
      half_adder dut2 (.a(a[1]), .b(b[1]), .sum(sum[1]), .carry(carry[1]));
      half_adder dut3 (.a(a[2]), .b(b[2]), .sum(sum[2]), .carry(carry[2]));
      half_adder dut4 (.a(a[3]), .b(b[3]), .sum(sum[3]), .carry(carry[3]));
    
      initial begin
        // Apply stimulus
    
        a=4'b0011; b=4'b0101; // Test case 1
    
        #1; // Wait for 1 time unit for the combinational logic to settle
        $display("a=%b, b=%b, sum=%b, carry=%b", a, b, sum, carry);
        $finish; // Terminate the simulation
      end
    endmodule

    run_verilog.js

    const { exec } = require('child_process');
    const util = require('util');
    const fs = require('fs').promises;
    
    const execPromise = util.promisify(exec);
    
    async function runSimulation() {
      const designFile = 'design.v';
      const testbenchFile = 'testbench.v';
      const outputFile = 'simulation.out';
    
      const stats = {
        compilation_success: false,
        error: "",
        simulation_output: ""
      };
    
      try {
        // 1. COMPILATION PHASE
        try {
          await execPromise(`iverilog -o ${outputFile} ${designFile} ${testbenchFile}`);
          stats.compilation_success = true;
        } catch (compileErr) {
          // Captures syntax errors
          stats.error = "Compilation Error:\n" + (compileErr.stderr || compileErr.message);
          console.log(JSON.stringify(stats, null, 2));
          return; 
        }
    
        // 2. SIMULATION PHASE (vvp)
        try {
          const { stdout, stderr } = await execPromise(`vvp ${outputFile}`);
          // Filter out the '$finish called at' message
          stats.simulation_output = stdout.split('\n')
                                          .filter(line => !line.includes('testbench.v:18: $finish called at'))
                                          .join('\n').trimEnd();
          
          // Some vvp warnings don't trigger a "catch" but show up in stderr
          if (stderr) {
            stats.error = "Simulation Warning/Error:\n" + stderr;
          }
        } catch (runErr) {
          // Captures runtime crashes (e.g., $finish called with error, or vvp system failure)
          stats.simulation_output = runErr.stdout; // Get whatever was printed before crash
          stats.error = "Runtime Error:\n" + (runErr.stderr || runErr.message);
        }
    
      } finally {
        // 3. CLEANUP
        try { await fs.unlink(outputFile); } catch (e) {}
        console.log(JSON.stringify(stats, null, 2));
      }
    }
    
    runSimulation();

    node run_verilog.js

    {                                                                                                       
       "compilation_success": true,                                                            
       "error": "",                                                                                          
       "simulation_output": "a=0011, b=0101, sum=0110, carry=0001"                                           
     } 
    
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions