JanusHDL

Your first testbench

Tutorial · 10 minutes

  1. Make a folder and save this as counter.vhd:

    library ieee;
    use ieee.std_logic_1164.all;
    use ieee.numeric_std.all;
    
    entity counter is
      port (clk, rst : in std_logic; q : out unsigned(3 downto 0));
    end entity;
    
    architecture rtl of counter is
      signal n : unsigned(3 downto 0) := (others => '0');
    begin
      process (clk) begin
        if rising_edge(clk) then
          n <= (others => '0') when rst = '1' else n + 1;
        end if;
      end process;
      q <= n;
    end architecture;
  2. And this as counter_tb.vhd:

    library ieee;
    use ieee.std_logic_1164.all;
    use ieee.numeric_std.all;
    
    entity counter_tb is end entity;
    
    architecture sim of counter_tb is
      signal clk, rst : std_logic := '1';
      signal q : unsigned(3 downto 0);
    begin
      clk <= not clk after 5 ns;
      dut : entity work.counter port map (clk, rst, q);
      process begin
        wait for 12 ns;
        rst <= '0';
        wait for 100 ns;
        assert q = 10 report "q is " & to_string(to_integer(q)) severity error;
        report "done: q = " & to_string(to_integer(q));
        std.env.finish;
      end process;
    end architecture;
  3. Run it:

    jhdl counter.vhd counter_tb.vhd --top counter_tb

    JanusHDL analyzes the files in the order given, elaborates counter_tb and runs it. It prints the report with its time and place, and a summary line:

    112 ns (delta 0) counter_tb.vhd:18:12: note: done: q = 10
    simulation of counter_tb ended at 112 ns (stopped); analysis 28 ms, elaboration 1 ms, run 0 ms

    The exit code is 0, or 1 if a report or assertion of severity error or failure came up, so scripts and CI can rely on it.

  4. Record the waveforms and open them:

    jhdl counter.vhd counter_tb.vhd --top counter_tb --wave run.jhw
    jhdlw run.jhw

    Pick signals from the hierarchy on the left. --vcd run.vcd writes a VCD file instead, for other viewers.

  5. A project file lists the files of a bigger design once, with their libraries, in analysis order:

    # project.f
    library work
    counter.vhd
    counter_tb.vhd
    jhdl -f project.f --top counter_tb --cache project.cache

    --cache keeps the analysis and reuses it while no file changes.

Next: the UVVM demo projects.